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 #include "oscl_types.h"
     19 #include "avc_dec.h"
     20 #include "avcdec_int.h"
     21 
     22 
     23 /*************************************/
     24 /* functions needed for video engine */
     25 /*************************************/
     26 
     27 /* These two functions are for callback functions of AvcHandle */
     28 int32 CBAVC_Malloc_OMX(void* aUserData, int32 aSize, int32 aAttribute)
     29 {
     30     OSCL_UNUSED_ARG(aUserData);
     31     OSCL_UNUSED_ARG(aAttribute);
     32     void* pPtr;
     33 
     34     pPtr = oscl_malloc(aSize);
     35     return (int32) pPtr;
     36 }
     37 
     38 void CBAVC_Free_OMX(void* aUserData, int32 aMem)
     39 {
     40     OSCL_UNUSED_ARG(aUserData);
     41     oscl_free((uint8*) aMem);
     42 }
     43 
     44 
     45 AVCDec_Status CBAVCDec_GetData_OMX(void* aUserData, uint8** aBuffer, uint* aSize)
     46 {
     47     OSCL_UNUSED_ARG(aUserData);
     48     OSCL_UNUSED_ARG(aBuffer);
     49     OSCL_UNUSED_ARG(aSize);
     50     return AVCDEC_FAIL;  /* nothing for now */
     51 }
     52 
     53 int32 AvcDecoder_OMX::AllocateBuffer_OMX(void* aUserData, int32 i, uint8** aYuvBuffer)
     54 {
     55     AvcDecoder_OMX* pAvcDecoder_OMX = (AvcDecoder_OMX*)aUserData;
     56 
     57     if (NULL == pAvcDecoder_OMX)
     58     {
     59         return 0;
     60     }
     61 
     62     *aYuvBuffer = pAvcDecoder_OMX->pDpbBuffer + i * pAvcDecoder_OMX->FrameSize;
     63     //Store the input timestamp at the correct index
     64     pAvcDecoder_OMX->DisplayTimestampArray[i] = pAvcDecoder_OMX->CurrInputTimestamp;
     65     return 1;
     66 }
     67 
     68 
     69 void UnbindBuffer_OMX(void* aUserData, int32 i)
     70 {
     71     OSCL_UNUSED_ARG(aUserData);
     72     OSCL_UNUSED_ARG(i);
     73     return;
     74 }
     75 
     76 int32 AvcDecoder_OMX::ActivateSPS_OMX(void* aUserData, uint aSizeInMbs, uint aNumBuffers)
     77 {
     78     AvcDecoder_OMX* pAvcDecoder_OMX = (AvcDecoder_OMX*)aUserData;
     79 
     80     if (NULL == pAvcDecoder_OMX)
     81     {
     82         return 0;
     83     }
     84 
     85     PVAVCDecGetSeqInfo(&(pAvcDecoder_OMX->AvcHandle), &(pAvcDecoder_OMX->SeqInfo));
     86 
     87     if (pAvcDecoder_OMX->pDpbBuffer)
     88     {
     89         oscl_free(pAvcDecoder_OMX->pDpbBuffer);
     90         pAvcDecoder_OMX->pDpbBuffer = NULL;
     91     }
     92 
     93     pAvcDecoder_OMX->FrameSize = (aSizeInMbs << 7) * 3;
     94     pAvcDecoder_OMX->pDpbBuffer = (uint8*) oscl_malloc(aNumBuffers * (pAvcDecoder_OMX->FrameSize));
     95 
     96     return 1;
     97 }
     98 
     99 /* initialize video decoder */
    100 OMX_BOOL AvcDecoder_OMX::InitializeVideoDecode_OMX()
    101 {
    102     /* Initialize AvcHandle */
    103     AvcHandle.AVCObject = NULL;
    104     AvcHandle.userData = (void*)this;
    105     AvcHandle.CBAVC_DPBAlloc = ActivateSPS_OMX;
    106     AvcHandle.CBAVC_FrameBind = AllocateBuffer_OMX;
    107     AvcHandle.CBAVC_FrameUnbind = UnbindBuffer_OMX;
    108     AvcHandle.CBAVC_Malloc = CBAVC_Malloc_OMX;
    109     AvcHandle.CBAVC_Free = CBAVC_Free_OMX;
    110 
    111     return OMX_TRUE;
    112 }
    113 
    114 OMX_BOOL AvcDecoder_OMX::FlushOutput_OMX(OMX_U8* aOutBuffer, OMX_U32* aOutputLength, OMX_TICKS* aOutTimestamp, OMX_S32 OldWidth, OMX_S32 OldHeight)
    115 {
    116     AVCFrameIO Output;
    117     AVCDec_Status Status;
    118     int32 Index, Release, FrameSize;
    119     OMX_S32 OldFrameSize = ((OldWidth + 15) & (~15)) * ((OldHeight + 15) & (~15));
    120 
    121     Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;
    122     Status = PVAVCDecGetOutput(&(AvcHandle), &Index, &Release, &Output);
    123 
    124     if (Status == AVCDEC_FAIL)
    125     {
    126         return OMX_FALSE;
    127     }
    128 
    129     *aOutTimestamp = DisplayTimestampArray[Index];
    130     *aOutputLength = 0; // init to 0
    131 
    132     if (Output.YCbCr[0])
    133     {
    134         FrameSize = Output.pitch * Output.height;
    135         // it should not happen that the frame size is smaller than available buffer size, but check just in case
    136         if (FrameSize <= OldFrameSize)
    137         {
    138             *aOutputLength = (Output.pitch * Output.height * 3) >> 1;
    139 
    140             oscl_memcpy(aOutBuffer, Output.YCbCr[0], FrameSize);
    141             oscl_memcpy(aOutBuffer + FrameSize, Output.YCbCr[1], FrameSize >> 2);
    142             oscl_memcpy(aOutBuffer + FrameSize + FrameSize / 4, Output.YCbCr[2], FrameSize >> 2);
    143         }
    144         // else, the frame length is reported as zero, and there is no copying
    145     }
    146 
    147 
    148     return OMX_TRUE;
    149 }
    150 
    151 
    152 /* Initialization routine */
    153 OMX_ERRORTYPE AvcDecoder_OMX::AvcDecInit_OMX()
    154 {
    155     if (OMX_FALSE == InitializeVideoDecode_OMX())
    156     {
    157         return OMX_ErrorInsufficientResources;
    158     }
    159 
    160     //Set up the cleanup object in order to do clean up work automatically
    161     pCleanObject = OSCL_NEW(AVCCleanupObject_OMX, (&AvcHandle));
    162 
    163     iAvcActiveFlag = OMX_FALSE;
    164 
    165     return OMX_ErrorNone;
    166 }
    167 
    168 
    169 /*Decode routine */
    170 OMX_BOOL AvcDecoder_OMX::AvcDecodeVideo_OMX(OMX_U8* aOutBuffer, OMX_U32* aOutputLength,
    171         OMX_U8** aInputBuf, OMX_U32* aInBufSize,
    172         OMX_PARAM_PORTDEFINITIONTYPE* aPortParam,
    173         OMX_S32* iFrameCount, OMX_BOOL aMarkerFlag, OMX_TICKS* aOutTimestamp, OMX_BOOL *aResizeFlag)
    174 {
    175     AVCDec_Status Status;
    176     OMX_S32 Width, Height;
    177     OMX_S32 crop_top, crop_bottom, crop_right, crop_left;
    178     uint8* pNalBuffer;
    179     int32 NalSize, NalType, NalRefId;
    180     //int32 PicType;
    181     AVCDecObject* pDecVid;
    182 
    183     *aResizeFlag = OMX_FALSE;
    184     OMX_U32 OldWidth, OldHeight;
    185 
    186     OldWidth =  aPortParam->format.video.nFrameWidth;
    187     OldHeight = aPortParam->format.video.nFrameHeight;
    188 
    189 
    190     if (!aMarkerFlag)
    191     {
    192         if (AVCDEC_FAIL == GetNextFullNAL_OMX(&pNalBuffer, &NalSize, *aInputBuf, aInBufSize))
    193         {
    194             Status = (AVCDec_Status) FlushOutput_OMX(aOutBuffer, aOutputLength, aOutTimestamp, OldWidth, OldHeight);
    195 
    196             if (AVCDEC_FAIL != Status)
    197             {
    198                 return OMX_TRUE;
    199             }
    200             else
    201             {
    202                 return OMX_FALSE;
    203             }
    204         }
    205     }
    206     else
    207     {
    208         pNalBuffer = *aInputBuf;
    209         NalSize = *aInBufSize;
    210         //Assuming that the buffer with marker bit contains one full NAL
    211         *aInBufSize = 0;
    212     }
    213 
    214     if (AVCDEC_FAIL == PVAVCDecGetNALType(pNalBuffer, NalSize, &NalType, &NalRefId))
    215     {
    216         return OMX_FALSE;
    217     }
    218 
    219     if (AVC_NALTYPE_SPS == (AVCNalUnitType)NalType)
    220     {
    221         if (PVAVCDecSeqParamSet(&(AvcHandle), pNalBuffer, NalSize) != AVCDEC_SUCCESS)
    222         {
    223             return OMX_FALSE;
    224         }
    225 
    226         pDecVid = (AVCDecObject*) AvcHandle.AVCObject;
    227 
    228         Width = (pDecVid->seqParams[0]->pic_width_in_mbs_minus1 + 1) * 16;
    229         Height = (pDecVid->seqParams[0]->pic_height_in_map_units_minus1 + 1) * 16;
    230 
    231         if (pDecVid->seqParams[0]->frame_cropping_flag)
    232         {
    233             crop_left = 2 * pDecVid->seqParams[0]->frame_crop_left_offset;
    234             crop_right = Width - (2 * pDecVid->seqParams[0]->frame_crop_right_offset + 1);
    235 
    236             if (pDecVid->seqParams[0]->frame_mbs_only_flag)
    237             {
    238                 crop_top = 2 * pDecVid->seqParams[0]->frame_crop_top_offset;
    239                 crop_bottom = Height - (2 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
    240             }
    241             else
    242             {
    243                 crop_top = 4 * pDecVid->seqParams[0]->frame_crop_top_offset;
    244                 crop_bottom = Height - (4 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
    245             }
    246         }
    247         else  /* no cropping flag, just give the first and last pixel */
    248         {
    249             crop_bottom = Height - 1;
    250             crop_right = Width - 1;
    251             crop_top = crop_left = 0;
    252         }
    253 
    254         aPortParam->format.video.nFrameWidth = crop_right - crop_left + 1;
    255         aPortParam->format.video.nFrameHeight = crop_bottom - crop_top + 1;
    256 
    257         OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15));
    258         OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15));
    259 
    260 
    261         aPortParam->format.video.nStride = min_stride;
    262         aPortParam->format.video.nSliceHeight = min_sliceheight;
    263 
    264 
    265         // finally, compute the new minimum buffer size.
    266 
    267         // Decoder components always output YUV420 format
    268         aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1;
    269 
    270 
    271         if ((OldWidth != aPortParam->format.video.nFrameWidth) || (OldHeight !=  aPortParam->format.video.nFrameHeight))
    272             *aResizeFlag = OMX_TRUE;
    273 
    274         (*iFrameCount)++;
    275 
    276     }
    277 
    278     else if (AVC_NALTYPE_PPS == (AVCNalUnitType) NalType)
    279     {
    280         if (PVAVCDecPicParamSet(&(AvcHandle), pNalBuffer, NalSize) != AVCDEC_SUCCESS)
    281         {
    282             return OMX_FALSE;
    283         }
    284     }
    285 
    286     else if (AVC_NALTYPE_SLICE == (AVCNalUnitType) NalType ||
    287              AVC_NALTYPE_IDR == (AVCNalUnitType) NalType)
    288     {
    289 		if (!iAvcActiveFlag)
    290 			iAvcActiveFlag = OMX_TRUE;
    291 
    292         if ((Status = PVAVCDecodeSlice(&(AvcHandle), pNalBuffer, NalSize)) == AVCDEC_PICTURE_OUTPUT_READY)
    293         {
    294             FlushOutput_OMX(aOutBuffer, aOutputLength, aOutTimestamp, OldWidth, OldHeight);
    295 
    296             //Input buffer not consumed yet, do not mark it free.
    297             if (aMarkerFlag)
    298             {
    299                 *aInBufSize = NalSize;
    300             }
    301             else
    302             {
    303                 *aInBufSize += InputBytesConsumed;
    304                 aInputBuf -= InputBytesConsumed;
    305             }
    306         }
    307 
    308         if (Status == AVCDEC_PICTURE_READY)
    309         {
    310             (*iFrameCount)++;
    311         }
    312 
    313         if ((AVCDEC_NO_DATA == Status) || (AVCDEC_PACKET_LOSS == Status) ||
    314                 (AVCDEC_NO_BUFFER == Status) || (AVCDEC_MEMORY_FAIL == Status) ||
    315                 (AVCDEC_FAIL == Status))
    316         {
    317             return OMX_FALSE;
    318         }
    319     }
    320 
    321     else if ((AVCNalUnitType)NalType == AVC_NALTYPE_SEI)
    322     {
    323         if (PVAVCDecSEI(&(AvcHandle), pNalBuffer, NalSize) != AVCDEC_SUCCESS)
    324         {
    325             return OMX_FALSE;
    326         }
    327     }
    328 
    329     else if ((AVCNalUnitType)NalType == AVC_NALTYPE_AUD)
    330     {
    331         //PicType = pNalBuffer[1] >> 5;
    332     }
    333 
    334     else if ((AVCNalUnitType)NalType == AVC_NALTYPE_EOSTREAM || // end of stream
    335              (AVCNalUnitType)NalType == AVC_NALTYPE_EOSEQ || // end of sequence
    336              (AVCNalUnitType)NalType == AVC_NALTYPE_FILL) // filler data
    337     {
    338         return OMX_TRUE;
    339     }
    340 
    341     //else
    342     //{
    343     //printf("\nNAL_type = %d, unsupported nal type or not sure what to do for this type\n", NalType);
    344     //  return OMX_FALSE;
    345     //}
    346     return OMX_TRUE;
    347 
    348 }
    349 
    350 
    351 OMX_ERRORTYPE AvcDecoder_OMX::AvcDecDeinit_OMX()
    352 {
    353     if (pCleanObject)
    354     {
    355         OSCL_DELETE(pCleanObject);
    356         pCleanObject = NULL;
    357     }
    358 
    359     if (pDpbBuffer)
    360     {
    361         oscl_free(pDpbBuffer);
    362         pDpbBuffer = NULL;
    363     }
    364 
    365     return OMX_ErrorNone;
    366 }
    367 
    368 
    369 AVCDec_Status AvcDecoder_OMX::GetNextFullNAL_OMX(uint8** aNalBuffer, int32* aNalSize, OMX_U8* aInputBuf, OMX_U32* aInBufSize)
    370 {
    371     uint8* pBuff = aInputBuf;
    372     OMX_U32 InputSize;
    373 
    374     *aNalSize = *aInBufSize;
    375     InputSize = *aInBufSize;
    376 
    377     AVCDec_Status ret_val = PVAVCAnnexBGetNALUnit(pBuff, aNalBuffer, aNalSize);
    378 
    379     if (ret_val == AVCDEC_FAIL)
    380     {
    381         return AVCDEC_FAIL;
    382     }
    383 
    384     InputBytesConsumed = ((*aNalSize) + (int32)(*aNalBuffer - pBuff));
    385     aInputBuf += InputBytesConsumed;
    386     *aInBufSize = InputSize - InputBytesConsumed;
    387 
    388     return AVCDEC_SUCCESS;
    389 }
    390 
    391 AVCCleanupObject_OMX::~AVCCleanupObject_OMX()
    392 {
    393     PVAVCCleanUpDecoder(ipavcHandle);
    394 
    395 }
    396 
    397 void AvcDecoder_OMX::ResetDecoder()
    398 {
    399     PVAVCDecReset(&(AvcHandle));
    400 }
    401 
    402