Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #ifndef OSCL_BASE_H_INCLUDED
     19 #include "oscl_base.h"
     20 #endif
     21 
     22 #include "mpeg4_dec.h"
     23 #include "oscl_mem.h"
     24 #include "omx_mpeg4_component.h"
     25 
     26 
     27 #define MAX_LAYERS 1
     28 #define PVH263DEFAULTHEIGHT 288
     29 #define PVH263DEFAULTWIDTH 352
     30 
     31 #include <utils/Log.h>
     32 #undef LOG_TAG
     33 #define LOG_TAG "SW_DEC"
     34 // from m4v_config_parser.h
     35 OSCL_IMPORT_REF int16 iGetM4VConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *, int32 *);
     36 
     37 Mpeg4Decoder_OMX::Mpeg4Decoder_OMX()
     38 {
     39     pFrame0 = NULL;
     40     pFrame1 = NULL;
     41 
     42     iDisplay_Width = 0;
     43     iDisplay_Height = 0;
     44 
     45     VO_START_CODE1[0] = 0x00;
     46     VO_START_CODE1[1] = 0x00;
     47     VO_START_CODE1[2] = 0x01;
     48     VO_START_CODE1[3] = 0x00;
     49 
     50     VOSH_START_CODE1[0] = 0x00;
     51     VOSH_START_CODE1[1] = 0x00;
     52     VOSH_START_CODE1[2] = 0x01;
     53     VOSH_START_CODE1[3] = 0xB0;
     54 
     55     VOP_START_CODE1[0] = 0x00;
     56     VOP_START_CODE1[1] = 0x00;
     57     VOP_START_CODE1[2] = 0x01;
     58     VOP_START_CODE1[3] = 0xB6;
     59 
     60     H263_START_CODE1[0] = 0x00;
     61     H263_START_CODE1[1] = 0x00;
     62     H263_START_CODE1[2] = 0x80;
     63 
     64 }
     65 
     66 
     67 /* Initialization routine */
     68 OMX_ERRORTYPE Mpeg4Decoder_OMX::Mp4DecInit()
     69 {
     70     Mpeg4InitCompleteFlag = OMX_FALSE;
     71     return OMX_ErrorNone;
     72 }
     73 
     74 
     75 /*Decode routine */
     76 OMX_BOOL Mpeg4Decoder_OMX::Mp4DecodeVideo(OMX_U8* aOutBuffer, OMX_U32* aOutputLength,
     77         OMX_U8** aInputBuf, OMX_U32* aInBufSize,
     78         OMX_PARAM_PORTDEFINITIONTYPE* aPortParam,
     79         OMX_S32* aFrameCount, OMX_BOOL aMarkerFlag, OMX_BOOL *aResizeFlag)
     80 {
     81     OMX_BOOL Status = OMX_TRUE;
     82     OMX_S32 OldWidth, OldHeight, OldFrameSize;
     83 
     84     OldWidth = aPortParam->format.video.nFrameWidth;
     85     OldHeight = aPortParam->format.video.nFrameHeight;
     86     *aResizeFlag = OMX_FALSE;
     87 
     88 #ifdef _DEBUG
     89     static OMX_U32 FrameCount = 0;
     90 #endif
     91     uint32 UseExtTimestamp = 0;
     92     uint32 TimeStamp;
     93     //OMX_S32 MaxSize = BIT_BUFF_SIZE;
     94     OMX_S32 FrameSize, InputSize, InitSize;
     95     OMX_U8* pTempFrame, *pSrc[3];
     96 
     97     if (Mpeg4InitCompleteFlag == OMX_FALSE)
     98     {
     99         if (!aMarkerFlag)
    100         {
    101             InitSize = GetVideoHeader(0, *aInputBuf, *aInBufSize);
    102         }
    103         else
    104         {
    105             InitSize = *aInBufSize;
    106         }
    107 
    108         if (PV_TRUE != InitializeVideoDecode(&iDisplay_Width, &iDisplay_Height,
    109                                              aInputBuf, (OMX_S32*)aInBufSize, MPEG4_MODE))
    110             return OMX_FALSE;
    111 
    112         Mpeg4InitCompleteFlag = OMX_TRUE;
    113         aPortParam->format.video.nFrameWidth = iDisplay_Width;
    114         aPortParam->format.video.nFrameHeight = iDisplay_Height;
    115 
    116         OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15));
    117         OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15));
    118 
    119 
    120         aPortParam->format.video.nStride = min_stride;
    121         aPortParam->format.video.nSliceHeight = min_sliceheight;
    122 
    123 
    124         // finally, compute the new minimum buffer size.
    125 
    126         // Decoder components always output YUV420 format
    127         aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1;
    128 
    129 
    130         if ((iDisplay_Width != OldWidth) || (iDisplay_Height != OldHeight))
    131             *aResizeFlag = OMX_TRUE;
    132 
    133         *aFrameCount = 1;
    134         *aInBufSize -= InitSize;
    135         return OMX_TRUE;
    136     }
    137 
    138     //MaxSize = *aInBufSize;
    139 
    140     if ((*(OMX_S32*)aInBufSize) <= 0)
    141     {
    142         return OMX_FALSE;
    143     }
    144 
    145     TimeStamp = 0xFFFFFFFF;
    146     InputSize = *aInBufSize;
    147 
    148     // in case of H263, read the 1st frame to find out the sizes (use the m4v_config)
    149     if ((0 == *aFrameCount) && (H263_MODE == CodecMode))
    150     {
    151         int32 aligned_width, aligned_height;
    152         int32 display_width, display_height;
    153 
    154         if (iGetM4VConfigInfo(*aInputBuf, *aInBufSize, &aligned_width, &aligned_height, &display_width, &display_height))
    155         {
    156             return OMX_FALSE;
    157         }
    158 
    159         iDisplay_Width = display_width;
    160         iDisplay_Height = display_height;
    161         aPortParam->format.video.nFrameWidth = iDisplay_Width; // use non 16byte aligned values (display_width) for H263
    162         aPortParam->format.video.nFrameHeight = iDisplay_Height; // like in the case of M4V (PVGetVideoDimensions also returns display_width/height)
    163 
    164         OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15));
    165         OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15));
    166 
    167 
    168         aPortParam->format.video.nStride = min_stride;
    169         aPortParam->format.video.nSliceHeight = min_sliceheight;
    170 
    171         // finally, compute the new minimum buffer size.
    172 
    173         // Decoder components always output YUV420 format
    174         aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1;
    175 
    176 
    177         if ((iDisplay_Width != OldWidth) || (iDisplay_Height != OldHeight))
    178             *aResizeFlag = OMX_TRUE;
    179 
    180         *aFrameCount = 1;
    181         return OMX_TRUE;
    182     }
    183 
    184     Status = (OMX_BOOL) PVDecodeVideoFrame(&VideoCtrl, aInputBuf,
    185                                            &TimeStamp,
    186                                            (int32*)aInBufSize,
    187                                            &UseExtTimestamp,
    188                                            (OMX_U8*) pFrame0);
    189 
    190     if (Status == PV_TRUE)
    191     {
    192 
    193 #ifdef _DEBUG
    194         //printf("Frame number %d\n", ++FrameCount);
    195 #endif
    196         // advance input buffer ptr
    197         *aInputBuf += (InputSize - *aInBufSize);
    198 
    199         pTempFrame = (OMX_U8*) pFrame0;
    200         pFrame0 = (OMX_U8*) pFrame1;
    201         pFrame1 = (OMX_U8*) pTempFrame;
    202 
    203         int32 display_width, display_height;
    204         PVGetVideoDimensions(&VideoCtrl, &display_width, &display_height);
    205         iDisplay_Width = display_width;
    206         iDisplay_Height = display_height;
    207         if ((iDisplay_Width != OldWidth) || (iDisplay_Height != OldHeight))
    208         {
    209 
    210             aPortParam->format.video.nFrameWidth = iDisplay_Width;
    211             aPortParam->format.video.nFrameHeight = iDisplay_Height;
    212 
    213             OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15));
    214             OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15));
    215 
    216 
    217             aPortParam->format.video.nStride = min_stride;
    218             aPortParam->format.video.nSliceHeight = min_sliceheight;
    219 
    220             // finally, compute the new minimum buffer size.
    221 
    222             // Decoder components always output YUV420 format
    223             aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1;
    224 
    225             *aResizeFlag = OMX_TRUE;
    226         }
    227         FrameSize = (((iDisplay_Width + 15) >> 4) << 4) * (((iDisplay_Height + 15) >> 4) << 4);
    228         OldFrameSize = (((OldWidth + 15) >> 4) << 4) * (((OldHeight + 15) >> 4) << 4);
    229 
    230         // THIS SHOULD NEVER HAPPEN, but just in case
    231         // check so to not write a larger output into a smaller buffer
    232         if (FrameSize <= OldFrameSize)
    233         {
    234             *aOutputLength = (FrameSize * 3) >> 1;
    235 
    236             pSrc[0] = VideoCtrl.outputFrame;
    237             pSrc[1] = pSrc[0] + FrameSize;
    238             pSrc[2] = pSrc[0] + FrameSize + FrameSize / 4;
    239 
    240             *aOutputLength = (FrameSize * 3) >> 1;
    241 
    242             oscl_memcpy(aOutBuffer, pSrc[0], FrameSize);
    243             oscl_memcpy(aOutBuffer + FrameSize, pSrc[1], FrameSize >> 2);
    244             oscl_memcpy(aOutBuffer + FrameSize + FrameSize / 4, pSrc[2], FrameSize >> 2);
    245         }
    246         else
    247         {
    248             *aOutputLength = 0;
    249         }
    250 
    251         (*aFrameCount)++;
    252     }
    253     else
    254     {
    255         *aInBufSize = InputSize;
    256         *aOutputLength = 0;
    257     }
    258 
    259     return Status;
    260 }
    261 
    262 OMX_S32 Mpeg4Decoder_OMX::InitializeVideoDecode(
    263     OMX_S32* aWidth, OMX_S32* aHeight, OMX_U8** aBuffer, OMX_S32* aSize, OMX_S32 mode)
    264 {
    265     OMX_U32 VideoDecOutputSize;
    266     OMX_S32 OK = PV_TRUE;
    267     CodecMode = MPEG4_MODE;
    268 
    269     if (mode == MODE_H263)
    270     {
    271         LOGE("PV SW DECODER is used for H.263");
    272         CodecMode = H263_MODE;
    273     }
    274     else
    275     {
    276         LOGE("PV SW DECODER is used for MPEG4");
    277     }
    278 
    279     OK = PVInitVideoDecoder(&VideoCtrl, aBuffer, (int32*) aSize, 1,
    280                             PVH263DEFAULTWIDTH, PVH263DEFAULTHEIGHT, CodecMode);
    281 
    282     if (OK)
    283     {
    284         PVGetVideoDimensions(&VideoCtrl, (int32*) aWidth, (int32*) aHeight);
    285         CodecMode = PVGetDecBitstreamMode(&VideoCtrl);
    286 
    287         if (CodecMode == H263_MODE && (*aWidth == 0 || *aHeight == 0))
    288         {
    289             *aWidth = PVH263DEFAULTWIDTH;
    290             *aHeight = PVH263DEFAULTHEIGHT;
    291         }
    292 
    293         PVSetPostProcType(&VideoCtrl, 0);
    294         VideoDecOutputSize = (((*aWidth + 15) & - 16) * ((*aHeight + 15) & - 16) * 3) / 2;
    295         pFrame0 = (OMX_U8*) oscl_malloc(VideoDecOutputSize);
    296         pFrame1 = (OMX_U8*) oscl_malloc(VideoDecOutputSize);
    297         PVSetReferenceYUV(&VideoCtrl, pFrame1);
    298         return PV_TRUE;
    299     }
    300     else
    301     {
    302         return PV_FALSE;
    303     }
    304 
    305 
    306 }
    307 
    308 OMX_ERRORTYPE Mpeg4Decoder_OMX::Mp4DecDeinit()
    309 {
    310     OMX_BOOL Status;
    311 
    312     if (pFrame0)
    313     {
    314         oscl_free(pFrame0);
    315         pFrame0 = NULL;
    316     }
    317     if (pFrame1)
    318     {
    319         oscl_free(pFrame1);
    320         pFrame1 = NULL;
    321     }
    322 
    323     Status = (OMX_BOOL) PVCleanUpVideoDecoder(&VideoCtrl);
    324     if (Status != OMX_TRUE)
    325     {
    326         return OMX_ErrorUndefined;
    327     }
    328     return OMX_ErrorNone;
    329 }
    330 
    331 OMX_S32 Mpeg4Decoder_OMX::GetVideoHeader(int32 aLayer, uint8* aBuf, int32 aMaxSize)
    332 {
    333     OSCL_UNUSED_ARG(aLayer);
    334 
    335     int32 count = 0;
    336     char my_sc[4];
    337 
    338     uint8 *tmp_bs = aBuf;
    339 
    340     oscl_memcpy(my_sc, tmp_bs, 4);
    341     my_sc[3] &= 0xf0;
    342 
    343     if (aMaxSize >= 4)
    344     {
    345         if (oscl_memcmp(my_sc, VOSH_START_CODE1, 4) && oscl_memcmp(my_sc, VO_START_CODE1, 4))
    346         {
    347             count = 0;
    348             iShortVideoHeader = OMX_TRUE;
    349         }
    350         else
    351         {
    352             count = 0;
    353             iShortVideoHeader = FALSE;
    354             while (oscl_memcmp(tmp_bs + count, VOP_START_CODE1, 4))
    355             {
    356                 count++;
    357                 if (count > 1000)
    358                 {
    359                     iShortVideoHeader = OMX_TRUE;
    360                     break;
    361                 }
    362             }
    363             if (iShortVideoHeader == OMX_TRUE)
    364             {
    365                 count = 0;
    366                 while (oscl_memcmp(tmp_bs + count, H263_START_CODE1, 3))
    367                 {
    368                     count++;
    369                 }
    370             }
    371         }
    372     }
    373     return count;
    374 }
    375 
    376