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_base.h"
     19 #include "OMX_Types.h"
     20 #include "pv_omxdefs.h"
     21 #include "omx_avc_component.h"
     22 
     23 #if PROXY_INTERFACE
     24 #include "omx_proxy_interface.h"
     25 #endif
     26 
     27 // Use default DLL entry point
     28 #ifndef OSCL_DLL_H_INCLUDED
     29 #include "oscl_dll.h"
     30 #endif
     31 
     32 OSCL_DLL_ENTRY_POINT_DEFAULT()
     33 
     34 // This function is called by OMX_GetHandle and it creates an instance of the avc component AO
     35 OSCL_EXPORT_REF OMX_ERRORTYPE AvcOmxComponentFactory(OMX_OUT OMX_HANDLETYPE* pHandle, OMX_IN  OMX_PTR pAppData, OMX_IN OMX_PTR pProxy , OMX_STRING aOmxLibName, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
     36 {
     37     OSCL_UNUSED_ARG(aOmxLibName);
     38     OSCL_UNUSED_ARG(aOmxLib);
     39     OSCL_UNUSED_ARG(aOsclUuid);
     40     OSCL_UNUSED_ARG(aRefCount);
     41 
     42     OpenmaxAvcAO* pOpenmaxAOType;
     43     OMX_ERRORTYPE Status;
     44 
     45     // move InitAvcOmxComponentFields content to actual constructor
     46 
     47     pOpenmaxAOType = (OpenmaxAvcAO*) OSCL_NEW(OpenmaxAvcAO, ());
     48 
     49     if (NULL == pOpenmaxAOType)
     50     {
     51         return OMX_ErrorInsufficientResources;
     52     }
     53 
     54     //Call the construct component to initialize OMX types
     55     Status = pOpenmaxAOType->ConstructComponent(pAppData, pProxy);
     56 
     57     *pHandle = pOpenmaxAOType->GetOmxHandle();
     58 
     59     return Status;
     60     ///////////////////////////////////////////////////////////////////////////////////////
     61 }
     62 
     63 // This function is called by OMX_FreeHandle when component AO needs to be destroyed
     64 OSCL_EXPORT_REF OMX_ERRORTYPE AvcOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
     65 {
     66     OSCL_UNUSED_ARG(aOmxLib);
     67     OSCL_UNUSED_ARG(aOsclUuid);
     68     OSCL_UNUSED_ARG(aRefCount);
     69 
     70     // get pointer to component AO
     71     OpenmaxAvcAO* pOpenmaxAOType = (OpenmaxAvcAO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate;
     72 
     73     // clean up decoder, OMX component stuff
     74     pOpenmaxAOType->DestroyComponent();
     75 
     76     // destroy the AO class
     77     OSCL_DELETE(pOpenmaxAOType);
     78 
     79     return OMX_ErrorNone;
     80 }
     81 
     82 #if DYNAMIC_LOAD_OMX_AVC_COMPONENT
     83 class OsclSharedLibraryInterface;
     84 class AvcOmxSharedLibraryInterface: public OsclSharedLibraryInterface,
     85         public OmxSharedLibraryInterface
     86 
     87 {
     88     public:
     89         OsclAny *QueryOmxComponentInterface(const OsclUuid& aOmxTypeId, const OsclUuid& aInterfaceId)
     90         {
     91             if (PV_OMX_AVCDEC_UUID == aOmxTypeId)
     92             {
     93                 if (PV_OMX_CREATE_INTERFACE == aInterfaceId)
     94                 {
     95                     return ((OsclAny*)(&AvcOmxComponentFactory));
     96                 }
     97                 else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId)
     98                 {
     99                     return ((OsclAny*)(&AvcOmxComponentDestructor));
    100                 }
    101             }
    102             return NULL;
    103         };
    104         OsclAny *SharedLibraryLookup(const OsclUuid& aInterfaceId)
    105         {
    106             if (aInterfaceId == PV_OMX_SHARED_INTERFACE)
    107             {
    108                 return OSCL_STATIC_CAST(OmxSharedLibraryInterface*, this);
    109             }
    110             return NULL;
    111         };
    112 
    113         AvcOmxSharedLibraryInterface() {};
    114 };
    115 
    116 // function to obtain the interface object from the shared library
    117 extern "C"
    118 {
    119     OSCL_EXPORT_REF OsclAny* PVGetInterface()
    120     {
    121         return (OsclAny*) OSCL_NEW(AvcOmxSharedLibraryInterface, ());
    122     }
    123 
    124     OSCL_EXPORT_REF void PVReleaseInterface(OsclSharedLibraryInterface* aInstance)
    125     {
    126         AvcOmxSharedLibraryInterface* module = (AvcOmxSharedLibraryInterface*)aInstance;
    127         OSCL_DELETE(module);
    128     }
    129 }
    130 
    131 #endif
    132 
    133 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    134 OMX_ERRORTYPE OpenmaxAvcAO::ConstructComponent(OMX_PTR pAppData, OMX_PTR pProxy)
    135 {
    136     ComponentPortType* pInPort, *pOutPort;
    137     OMX_ERRORTYPE Status;
    138 
    139     iNumPorts = 2;
    140     iOmxComponent.nSize = sizeof(OMX_COMPONENTTYPE);
    141     iOmxComponent.pComponentPrivate = (OMX_PTR) this;  // pComponentPrivate points to THIS component AO class
    142     ipComponentProxy = pProxy;
    143     iOmxComponent.pApplicationPrivate = pAppData; // init the App data
    144 
    145     iNumNALs = 0;
    146     iCurrNAL = 0;
    147     iNALOffset = 0;
    148     oscl_memset(iNALSizeArray, 0, MAX_NAL_PER_FRAME * sizeof(uint32));
    149 
    150 
    151 #if PROXY_INTERFACE
    152     iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE;
    153 
    154     iOmxComponent.SendCommand = OpenmaxAvcAO::BaseComponentProxySendCommand;
    155     iOmxComponent.GetParameter = OpenmaxAvcAO::BaseComponentProxyGetParameter;
    156     iOmxComponent.SetParameter = OpenmaxAvcAO::BaseComponentProxySetParameter;
    157     iOmxComponent.GetConfig = OpenmaxAvcAO::BaseComponentProxyGetConfig;
    158     iOmxComponent.SetConfig = OpenmaxAvcAO::BaseComponentProxySetConfig;
    159     iOmxComponent.GetExtensionIndex = OpenmaxAvcAO::BaseComponentProxyGetExtensionIndex;
    160     iOmxComponent.GetState = OpenmaxAvcAO::BaseComponentProxyGetState;
    161     iOmxComponent.UseBuffer = OpenmaxAvcAO::BaseComponentProxyUseBuffer;
    162     iOmxComponent.AllocateBuffer = OpenmaxAvcAO::BaseComponentProxyAllocateBuffer;
    163     iOmxComponent.FreeBuffer = OpenmaxAvcAO::BaseComponentProxyFreeBuffer;
    164     iOmxComponent.EmptyThisBuffer = OpenmaxAvcAO::BaseComponentProxyEmptyThisBuffer;
    165     iOmxComponent.FillThisBuffer = OpenmaxAvcAO::BaseComponentProxyFillThisBuffer;
    166 
    167 #else
    168     iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_FALSE;
    169 
    170     iOmxComponent.SendCommand = OpenmaxAvcAO::BaseComponentSendCommand;
    171     iOmxComponent.GetParameter = OpenmaxAvcAO::BaseComponentGetParameter;
    172     iOmxComponent.SetParameter = OpenmaxAvcAO::BaseComponentSetParameter;
    173     iOmxComponent.GetConfig = OpenmaxAvcAO::BaseComponentGetConfig;
    174     iOmxComponent.SetConfig = OpenmaxAvcAO::BaseComponentSetConfig;
    175     iOmxComponent.GetExtensionIndex = OpenmaxAvcAO::BaseComponentGetExtensionIndex;
    176     iOmxComponent.GetState = OpenmaxAvcAO::BaseComponentGetState;
    177     iOmxComponent.UseBuffer = OpenmaxAvcAO::BaseComponentUseBuffer;
    178     iOmxComponent.AllocateBuffer = OpenmaxAvcAO::BaseComponentAllocateBuffer;
    179     iOmxComponent.FreeBuffer = OpenmaxAvcAO::BaseComponentFreeBuffer;
    180     iOmxComponent.EmptyThisBuffer = OpenmaxAvcAO::BaseComponentEmptyThisBuffer;
    181     iOmxComponent.FillThisBuffer = OpenmaxAvcAO::BaseComponentFillThisBuffer;
    182 #endif
    183 
    184     iOmxComponent.SetCallbacks = OpenmaxAvcAO::BaseComponentSetCallbacks;
    185     iOmxComponent.nVersion.s.nVersionMajor = SPECVERSIONMAJOR;
    186     iOmxComponent.nVersion.s.nVersionMinor = SPECVERSIONMINOR;
    187     iOmxComponent.nVersion.s.nRevision = SPECREVISION;
    188     iOmxComponent.nVersion.s.nStep = SPECSTEP;
    189 
    190     // PV capability
    191 #ifdef TEST_FULL_AVC_FRAME_MODE
    192     iPVCapabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
    193     iPVCapabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
    194     iPVCapabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; // since we need copying for frame assembly in streaming case
    195     iPVCapabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE;
    196     iPVCapabilityFlags.iOMXComponentUsesNALStartCodes = OMX_FALSE;
    197     iPVCapabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
    198     iPVCapabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE;
    199 #elif TEST_FULL_AVC_FRAME_MODE_SC
    200     iPVCapabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
    201     iPVCapabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
    202     iPVCapabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; // since we need copying for frame assembly in streaming case
    203     iPVCapabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE;
    204     iPVCapabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE;
    205     iPVCapabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
    206     iPVCapabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE;
    207 #else
    208     iPVCapabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
    209     iPVCapabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
    210     iPVCapabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
    211     iPVCapabilityFlags.iOMXComponentSupportsPartialFrames = OMX_TRUE;
    212     iPVCapabilityFlags.iOMXComponentUsesNALStartCodes = OMX_FALSE;
    213     iPVCapabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
    214     iPVCapabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_FALSE;
    215 #endif
    216 
    217     if (ipAppPriv)
    218     {
    219         oscl_free(ipAppPriv);
    220         ipAppPriv = NULL;
    221     }
    222 
    223     ipAppPriv = (ComponentPrivateType*) oscl_malloc(sizeof(ComponentPrivateType));
    224     if (NULL == ipAppPriv)
    225     {
    226         return OMX_ErrorInsufficientResources;
    227     }
    228 
    229     //Construct base class now
    230     Status = ConstructBaseComponent(pAppData);
    231 
    232     if (OMX_ErrorNone != Status)
    233     {
    234         return Status;
    235     }
    236 
    237     /** Domain specific section for the ports. */
    238     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    239     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo;
    240     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"video/Avc";
    241     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0;
    242     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE;
    243     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
    244     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatUnused;
    245     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176;
    246     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144;
    247     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000;
    248     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16);
    249     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDir = OMX_DirInput;
    250     //Set to a default value, will change later during setparameter call
    251     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_INPUT_BUFFER_AVC;
    252     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
    253     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize = INPUT_BUFFER_SIZE_AVC;
    254     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
    255     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
    256 
    257     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
    258     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo;
    259     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"raw";
    260     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0;
    261     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE;
    262     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
    263     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
    264     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176;
    265     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nStride = 176;
    266     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144;
    267     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nSliceHeight = 144;
    268     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000;
    269     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16);
    270     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDir = OMX_DirOutput;
    271     //Set to a default value, will change later during setparameter call
    272     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_OUTPUT_BUFFER_AVC
    273             ;
    274     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
    275     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferSize = OUTPUT_BUFFER_SIZE_AVC; //just use QCIF (as default)
    276     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
    277     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
    278 
    279     //Default values for Avc video param port
    280     ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoAvc.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    281     ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoAvc.eProfile = OMX_VIDEO_AVCProfileBaseline;
    282     ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoAvc.eLevel = OMX_VIDEO_AVCLevel1;
    283 
    284     ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    285     ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.nProfileIndex = 0;
    286     ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.eProfile = OMX_VIDEO_AVCProfileBaseline;
    287     ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.eLevel = OMX_VIDEO_AVCLevel1;
    288 
    289     iPortTypesParam.nPorts = 2;
    290     iPortTypesParam.nStartPortNumber = 0;
    291 
    292     pInPort = (ComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX];
    293     pOutPort = (ComponentPortType*) ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
    294 
    295     pInPort->ActualNumPortFormatsSupported = 1;
    296 
    297     //OMX_VIDEO_PARAM_PORTFORMATTYPE INPUT PORT SETTINGS
    298     //On input port for index 0
    299     SetHeader(&pInPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
    300     pInPort->VideoParam[0].nPortIndex = 0;
    301     pInPort->VideoParam[0].nIndex = 0;
    302     pInPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingAVC;
    303     pInPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatUnused;
    304 
    305     pOutPort->ActualNumPortFormatsSupported = 1;
    306 
    307     //OMX_VIDEO_PARAM_PORTFORMATTYPE OUTPUT PORT SETTINGS
    308     //On output port for index 0
    309     SetHeader(&pOutPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
    310     pOutPort->VideoParam[0].nPortIndex = 1;
    311     pOutPort->VideoParam[0].nIndex = 0;
    312     pOutPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingUnused;
    313     pOutPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatYUV420Planar;
    314 
    315     oscl_strncpy((OMX_STRING)iComponentRole, (OMX_STRING)"video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
    316 
    317     iDecodeReturn = OMX_FALSE;
    318 
    319     if (ipAvcDec)
    320     {
    321         OSCL_DELETE(ipAvcDec);
    322         ipAvcDec = NULL;
    323     }
    324 
    325     ipAvcDec = OSCL_NEW(AvcDecoder_OMX, ());
    326     if (ipAvcDec == NULL)
    327     {
    328         return OMX_ErrorInsufficientResources;
    329     }
    330 
    331     oscl_memset(ipAvcDec, 0, sizeof(AvcDecoder_OMX));
    332 
    333 #if PROXY_INTERFACE
    334 
    335     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSendCommand = BaseComponentSendCommand;
    336     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetParameter = BaseComponentGetParameter;
    337     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetParameter = BaseComponentSetParameter;
    338     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetConfig = BaseComponentGetConfig;
    339     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetConfig = BaseComponentSetConfig;
    340     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetExtensionIndex = BaseComponentGetExtensionIndex;
    341     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetState = BaseComponentGetState;
    342     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentUseBuffer = BaseComponentUseBuffer;
    343     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentAllocateBuffer = BaseComponentAllocateBuffer;
    344     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFreeBuffer = BaseComponentFreeBuffer;
    345     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentEmptyThisBuffer = BaseComponentEmptyThisBuffer;
    346     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFillThisBuffer = BaseComponentFillThisBuffer;
    347 
    348 #endif
    349 
    350     return OMX_ErrorNone;
    351 }
    352 
    353 
    354 /** This function is called by the omx core when the component
    355     * is disposed by the IL client with a call to FreeHandle().
    356     * \param Component, the component to be disposed
    357     */
    358 
    359 OMX_ERRORTYPE OpenmaxAvcAO::DestroyComponent()
    360 {
    361     if (iIsInit != OMX_FALSE)
    362     {
    363         ComponentDeInit();
    364     }
    365 
    366     //Destroy the base class now
    367     DestroyBaseComponent();
    368 
    369     if (ipAvcDec)
    370     {
    371         OSCL_DELETE(ipAvcDec);
    372         ipAvcDec = NULL;
    373     }
    374 
    375     if (ipAppPriv)
    376     {
    377         ipAppPriv->CompHandle = NULL;
    378 
    379         oscl_free(ipAppPriv);
    380         ipAppPriv = NULL;
    381     }
    382 
    383     return OMX_ErrorNone;
    384 }
    385 
    386 
    387 /* This function will be called in case of buffer management without marker bit present
    388  * The purpose is to copy the current input buffer into a big temporary buffer, so that
    389  * an incomplete/partial frame is never passed to the decoder library for decode
    390  */
    391 void OpenmaxAvcAO::ComponentBufferMgmtWithoutMarker()
    392 {
    393     //This common routine has been written in the base class
    394     TempInputBufferMgmtWithoutMarker();
    395 }
    396 
    397 OMX_BOOL OpenmaxAvcAO::ParseFullAVCFramesIntoNALs(OMX_BUFFERHEADERTYPE* aInputBuffer)
    398 {
    399     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ParseFullAVCFramesIntoNALs IN"));
    400 
    401     ipInputBuffer = aInputBuffer;
    402 
    403     if (iNumInputBuffer == 0)
    404     {
    405         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : ParseFullAVCFramesIntoNALs ERROR"));
    406         return OMX_FALSE;
    407     }
    408 
    409     if (iPVCapabilityFlags.iOMXComponentUsesNALStartCodes && !(ipInputBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA))
    410     {
    411         OMX_U32 offset = ipInputBuffer->nOffset;
    412         OMX_U32 length = ipInputBuffer->nFilledLen;
    413         OMX_U8* pBuffer = ipInputBuffer->pBuffer + offset;
    414         OMX_U8* pTemp;
    415         int32 nalSize;
    416 
    417         iNumNALs = 0;
    418 
    419         while (length > 0)
    420         {
    421             if (AVCDEC_SUCCESS != ipAvcDec->GetNextFullNAL_OMX(&pTemp, &nalSize, pBuffer, &length))
    422             {
    423                 break;
    424             }
    425 
    426             pBuffer += nalSize + (int32)(pTemp - pBuffer);
    427 
    428             iNALSizeArray[iNumNALs] = nalSize;
    429 
    430             iNumNALs++;
    431         }
    432 
    433         if (iNumNALs > 0)
    434         {
    435             iCurrNAL = 0;
    436             iNALOffset = ipInputBuffer->nOffset + NAL_START_CODE_SIZE;
    437             ipFrameDecodeBuffer = ipInputBuffer->pBuffer + iNALOffset;
    438             iInputCurrLength = iNALSizeArray[iCurrNAL];
    439             iNALOffset += (iInputCurrLength + NAL_START_CODE_SIZE); // offset for next NAL
    440             //capture the timestamp to be send to the corresponding output buffer
    441             iFrameTimestamp = ipInputBuffer->nTimeStamp;
    442         }
    443         else
    444         {
    445             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : ParseFullAVCFramesIntoNALs ERROR"));
    446             return OMX_FALSE;
    447         }
    448     }
    449     // may be a full frame, or may incomplete, therefore don't check for OMX_BUFFERFLAG_ENDOFFRAME
    450     else if (ipInputBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA)
    451     {
    452         // get extra data from end of buffer
    453         OMX_OTHER_EXTRADATATYPE *pExtra;
    454         OMX_U32 offset = ipInputBuffer->nOffset + ipInputBuffer->nFilledLen;
    455         OMX_U32 allocLen = ipInputBuffer->nAllocLen;
    456         OMX_U8* pTemp = ipInputBuffer->pBuffer + offset;
    457 
    458         // align
    459         pExtra = (OMX_OTHER_EXTRADATATYPE *)(((OMX_U32) pTemp + 3) & ~3);
    460         offset += (OMX_U32) pExtra - (OMX_U32) pTemp;
    461 
    462         while (pExtra->eType != OMX_ExtraDataNone)
    463         {
    464             if (pExtra->eType == OMX_ExtraDataNALSizeArray)
    465             {
    466                 oscl_memcpy(iNALSizeArray, ((OMX_U8*)pExtra + 20), pExtra->nDataSize);
    467                 iNumNALs = pExtra->nDataSize >> 2;
    468                 iCurrNAL = 0;
    469                 iNALOffset = ipInputBuffer->nOffset;
    470                 break;
    471             }
    472 
    473             offset += pExtra->nSize;
    474             if (offset > (allocLen - 20))
    475             {
    476                 // corrupt data
    477                 break;
    478             }
    479             else
    480             {
    481                 pExtra = (OMX_OTHER_EXTRADATATYPE *)((OMX_U8*)pExtra + pExtra->nSize);
    482             }
    483         }
    484 
    485         if (pExtra->eType != OMX_ExtraDataNALSizeArray)
    486         {
    487             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : ParseFullAVCFramesIntoNALs ERROR"));
    488             return OMX_FALSE;
    489         }
    490 
    491         ipFrameDecodeBuffer = ipInputBuffer->pBuffer + iNALOffset;
    492         iInputCurrLength = iNALSizeArray[iCurrNAL];
    493         iNALOffset += iInputCurrLength; // offset for next NAL
    494         //capture the timestamp to be send to the corresponding output buffer
    495         iFrameTimestamp = ipInputBuffer->nTimeStamp;
    496     }
    497     else if (ipInputBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
    498     {
    499         iInputCurrLength = ipInputBuffer->nFilledLen;
    500         ipFrameDecodeBuffer = ipInputBuffer->pBuffer + ipInputBuffer->nOffset;
    501         //capture the timestamp to be send to the corresponding output buffer
    502         iFrameTimestamp = ipInputBuffer->nTimeStamp;
    503     }
    504     else
    505     {
    506         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : ParseFullAVCFramesIntoNALs ERROR"));
    507         return OMX_FALSE;
    508     }
    509 
    510     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ParseFullAVCFramesIntoNALs OUT"));
    511     return OMX_TRUE;
    512 }
    513 
    514 
    515 void OpenmaxAvcAO::ProcessData()
    516 {
    517     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ProcessData IN"));
    518     if (!iEndOfFrameFlag)
    519     {
    520         DecodeWithoutMarker();
    521     }
    522     else
    523     {
    524         DecodeWithMarker();
    525     }
    526     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ProcessData OUT"));
    527 }
    528 
    529 
    530 /* Decoding function for input buffers without end of frame flag marked */
    531 void OpenmaxAvcAO::DecodeWithoutMarker()
    532 {
    533     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker IN"));
    534 
    535     QueueType*              pInputQueue  = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
    536     QueueType*              pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
    537     ComponentPortType*  pOutPort =     ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
    538     OMX_COMPONENTTYPE *     pHandle =      &iOmxComponent;
    539 
    540     OMX_U8*                 pOutBuffer;
    541     OMX_U32                 OutputLength;
    542     OMX_U8*                 pTempInBuffer;
    543     OMX_U32                 TempInLength;
    544     OMX_BOOL                MarkerFlag = OMX_FALSE;
    545     OMX_TICKS               TempTimestamp;
    546     OMX_BOOL                ResizeNeeded = OMX_FALSE;
    547 
    548     OMX_U32 TempInputBufferSize = (2 * sizeof(uint8) * (ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize));
    549     OMX_U32 CurrWidth =  ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth;
    550     OMX_U32 CurrHeight = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight;
    551 
    552 
    553     if ((!iIsInputBufferEnded) || ((iEndofStream) || (0 != iTempInputBufferLength)))
    554     {
    555         //Check whether prev output bufer has been released or not
    556         if (OMX_TRUE == iNewOutBufRequired)
    557         {
    558             //Check whether a new output buffer is available or not
    559             if (0 == (GetQueueNumElem(pOutputQueue)))
    560             {
    561                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker OUT output buffer unavailable"));
    562                 //Store the mark data for output buffer, as it will be overwritten next time
    563                 if (NULL != ipTargetComponent)
    564                 {
    565                     ipTempTargetComponent = ipTargetComponent;
    566                     iTempTargetMarkData = iTargetMarkData;
    567                     iMarkPropagate = OMX_TRUE;
    568                 }
    569                 return;
    570             }
    571 
    572             ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
    573             if (NULL == ipOutputBuffer)
    574             {
    575                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker Error, output buffer dequeue returned NULL, OUT"));
    576                 return;
    577             }
    578 
    579             //Do not proceed if the output buffer can't fit the YUV data
    580             if ((ipOutputBuffer->nAllocLen < (OMX_U32)(((CurrWidth + 15)&(~15)) *((CurrHeight + 15)&(~15)) * 3 / 2)) && (OMX_TRUE == ipAvcDec->iAvcActiveFlag))
    581             {
    582                 ipOutputBuffer->nFilledLen = 0;
    583                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    584                 ipOutputBuffer = NULL;
    585                 return;
    586             }
    587             ipOutputBuffer->nFilledLen = 0;
    588             iNewOutBufRequired = OMX_FALSE;
    589         }
    590 
    591 
    592         /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer
    593          * command and hMarkTargetComponent as given by the specifications
    594          */
    595         if (NULL != ipMark)
    596         {
    597             ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
    598             ipOutputBuffer->pMarkData = ipMark->pMarkData;
    599             ipMark = NULL;
    600         }
    601 
    602         if ((OMX_TRUE == iMarkPropagate) && (ipTempTargetComponent != ipTargetComponent))
    603         {
    604             ipOutputBuffer->hMarkTargetComponent = ipTempTargetComponent;
    605             ipOutputBuffer->pMarkData = iTempTargetMarkData;
    606             ipTempTargetComponent = NULL;
    607             iMarkPropagate = OMX_FALSE;
    608         }
    609         else if (ipTargetComponent != NULL)
    610         {
    611             ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
    612             ipOutputBuffer->pMarkData = iTargetMarkData;
    613             ipTargetComponent = NULL;
    614             iMarkPropagate = OMX_FALSE;
    615         }
    616         //Mark buffer code ends here
    617 
    618         pOutBuffer = ipOutputBuffer->pBuffer;
    619         OutputLength = 0;
    620 
    621         pTempInBuffer = ipTempInputBuffer + iTempConsumedLength;
    622         TempInLength = iTempInputBufferLength;
    623 
    624         //Output buffer is passed as a short pointer
    625         iDecodeReturn = ipAvcDec->AvcDecodeVideo_OMX(pOutBuffer, (OMX_U32*) & OutputLength,
    626                         &(pTempInBuffer),
    627                         &TempInLength,
    628                         &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam),
    629                         &iFrameCount,
    630                         MarkerFlag, &TempTimestamp, &ResizeNeeded);
    631 
    632         ipOutputBuffer->nFilledLen = OutputLength;
    633 
    634         //offset not required in our case, set it to zero
    635         ipOutputBuffer->nOffset = 0;
    636 
    637         //Set the timestamp equal to the input buffer timestamp
    638         ipOutputBuffer->nTimeStamp = iFrameTimestamp;
    639 
    640         iTempConsumedLength += (iTempInputBufferLength - TempInLength);
    641         iTempInputBufferLength = TempInLength;
    642 
    643         //If decoder returned error, report it to the client via a callback
    644         if (!iDecodeReturn && OMX_FALSE == ipAvcDec->iAvcActiveFlag)
    645         {
    646             // initialization error
    647             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker ErrorBadParameter callback send"));
    648 
    649             (*(ipCallbacks->EventHandler))
    650             (pHandle,
    651              iCallbackData,
    652              OMX_EventError,
    653              OMX_ErrorBadParameter,
    654              0,
    655              NULL);
    656         }
    657         else if (!iDecodeReturn && OMX_FALSE == iEndofStream)
    658         {
    659             // decoding error
    660             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker ErrorStreamCorrupt callback send"));
    661 
    662             (*(ipCallbacks->EventHandler))
    663             (pHandle,
    664              iCallbackData,
    665              OMX_EventError,
    666              OMX_ErrorStreamCorrupt,
    667              0,
    668              NULL);
    669         }
    670 
    671 
    672         //Do not decode if big buffer is less than half the size
    673         if (TempInLength < (TempInputBufferSize >> 1))
    674         {
    675             iIsInputBufferEnded = OMX_TRUE;
    676             iNewInBufferRequired = OMX_TRUE;
    677         }
    678 
    679         if (ResizeNeeded == OMX_TRUE)
    680         {
    681             OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*) ipAppPriv->CompHandle;
    682 
    683             iResizePending = OMX_TRUE;
    684             (*(ipCallbacks->EventHandler))
    685             (pHandle,
    686              iCallbackData,
    687              OMX_EventPortSettingsChanged, //The command was completed
    688              OMX_PORT_OUTPUTPORT_INDEX,
    689              0,
    690              NULL);
    691         }
    692 
    693         /* If EOS flag has come from the client & there are no more
    694          * input buffers to decode, send the callback to the client
    695          */
    696         if (OMX_TRUE == iEndofStream)
    697         {
    698             if ((0 == iTempInputBufferLength) && !iDecodeReturn)
    699             {
    700                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker EOS callback send"));
    701 
    702                 (*(ipCallbacks->EventHandler))
    703                 (pHandle,
    704                  iCallbackData,
    705                  OMX_EventBufferFlag,
    706                  1,
    707                  OMX_BUFFERFLAG_EOS,
    708                  NULL);
    709 
    710                 iNewInBufferRequired = OMX_TRUE;
    711                 iEndofStream = OMX_FALSE;
    712 
    713                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
    714 
    715                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    716                 ipOutputBuffer = NULL;
    717 
    718                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker OUT"));
    719 
    720                 return;
    721             }
    722         }
    723 
    724         //Send the output buffer back when it has some data in it
    725         if (ipOutputBuffer->nFilledLen > 0)
    726         {
    727             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    728             ipOutputBuffer = NULL;
    729         }
    730 
    731         /* If there is some more processing left with current buffers, re-schedule the AO
    732          * Do not go for more than one round of processing at a time.
    733          * This may block the AO longer than required.
    734          */
    735         if ((ResizeNeeded == OMX_FALSE) && ((TempInLength != 0) || (GetQueueNumElem(pInputQueue) > 0))
    736                 && ((GetQueueNumElem(pOutputQueue) > 0) || (OMX_FALSE == iNewOutBufRequired)))
    737         {
    738             RunIfNotReady();
    739         }
    740     }
    741 
    742     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker OUT"));
    743     return;
    744 }
    745 
    746 
    747 /* Decoding function for input buffers with end of frame flag marked */
    748 void OpenmaxAvcAO::DecodeWithMarker()
    749 {
    750     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker IN"));
    751 
    752     OMX_COMPONENTTYPE  *pHandle = &iOmxComponent;
    753     QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
    754     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
    755 
    756     ComponentPortType*  pInPort = ipPorts[OMX_PORT_INPUTPORT_INDEX];
    757     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
    758 
    759     OMX_U8*                 pOutBuffer;
    760     OMX_U32                 OutputLength;
    761     OMX_BOOL                MarkerFlag = OMX_TRUE;
    762     OMX_BOOL                Status;
    763     OMX_BOOL                ResizeNeeded = OMX_FALSE;
    764 
    765     OMX_U32 CurrWidth =  ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth;
    766     OMX_U32 CurrHeight = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight;
    767 
    768     if ((!iIsInputBufferEnded) || (iEndofStream))
    769     {
    770         //Check whether prev output bufer has been released or not
    771         if (OMX_TRUE == iNewOutBufRequired)
    772         {
    773             //Check whether a new output buffer is available or not
    774             if (0 == (GetQueueNumElem(pOutputQueue)))
    775             {
    776                 iNewInBufferRequired = OMX_FALSE;
    777                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker OUT output buffer unavailable"));
    778                 return;
    779             }
    780 
    781             ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
    782             if (NULL == ipOutputBuffer)
    783             {
    784                 iNewInBufferRequired = OMX_FALSE;
    785                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker Error, output buffer dequeue returned NULL, OUT"));
    786                 return;
    787             }
    788 
    789             //Do not proceed if the output buffer can't fit the YUV data
    790             if ((ipOutputBuffer->nAllocLen < (OMX_U32)(((CurrWidth + 15)&(~15)) *((CurrHeight + 15)&(~15)) * 3 / 2)) && (OMX_TRUE == ipAvcDec->iAvcActiveFlag))
    791             {
    792                 ipOutputBuffer->nFilledLen = 0;
    793                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    794                 ipOutputBuffer = NULL;
    795                 return;
    796             }
    797             ipOutputBuffer->nFilledLen = 0;
    798             iNewOutBufRequired = OMX_FALSE;
    799         }
    800 
    801         /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer
    802          * command and hMarkTargetComponent as given by the specifications
    803          */
    804         if (NULL != ipMark)
    805         {
    806             ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
    807             ipOutputBuffer->pMarkData = ipMark->pMarkData;
    808             ipMark = NULL;
    809         }
    810 
    811         if (NULL != ipTargetComponent)
    812         {
    813             ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
    814             ipOutputBuffer->pMarkData = iTargetMarkData;
    815             ipTargetComponent = NULL;
    816 
    817         }
    818         //Mark buffer code ends here
    819 
    820         pOutBuffer = ipOutputBuffer->pBuffer;
    821         OutputLength = 0;
    822 
    823         if (iInputCurrLength > 0)
    824         {
    825             //Store the input timestamp into a temp variable
    826             ipAvcDec->CurrInputTimestamp = iFrameTimestamp;
    827 
    828             //Output buffer is passed as a short pointer
    829             iDecodeReturn = ipAvcDec->AvcDecodeVideo_OMX(pOutBuffer, (OMX_U32*) & OutputLength,
    830                             &(ipFrameDecodeBuffer),
    831                             &(iInputCurrLength),
    832                             &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam),
    833                             &iFrameCount,
    834                             MarkerFlag,
    835                             &(ipOutputBuffer->nTimeStamp), &ResizeNeeded);
    836 
    837             ipOutputBuffer->nFilledLen = OutputLength;
    838             //offset not required in our case, set it to zero
    839             ipOutputBuffer->nOffset = 0;
    840 
    841             if (ResizeNeeded == OMX_TRUE)
    842             {
    843                 OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*) ipAppPriv->CompHandle;
    844 
    845                 // set the flag. Do not process any more frames until
    846                 // IL Client sends PortDisable event (thus starting the procedure for
    847                 // dynamic port reconfiguration)
    848                 iResizePending = OMX_TRUE;
    849 
    850                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : Sending the PortSettings Changed Callback"));
    851 
    852                 (*(ipCallbacks->EventHandler))
    853                 (pHandle,
    854                  iCallbackData,
    855                  OMX_EventPortSettingsChanged, //The command was completed
    856                  OMX_PORT_OUTPUTPORT_INDEX,
    857                  0,
    858                  NULL);
    859             }
    860 
    861 
    862             //If decoder returned error, report it to the client via a callback
    863             if (!iDecodeReturn && OMX_FALSE == ipAvcDec->iAvcActiveFlag)
    864             {
    865                 // initialization error
    866                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithoutMarker ErrorBadParameter callback send"));
    867 
    868                 (*(ipCallbacks->EventHandler))
    869                 (pHandle,
    870                  iCallbackData,
    871                  OMX_EventError,
    872                  OMX_ErrorBadParameter,
    873                  0,
    874                  NULL);
    875             }
    876             else if (!iDecodeReturn && OMX_FALSE == iEndofStream)
    877             {
    878                 // decode error
    879                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker ErrorStreamCorrupt callback send"));
    880 
    881                 (*(ipCallbacks->EventHandler))
    882                 (pHandle,
    883                  iCallbackData,
    884                  OMX_EventError,
    885                  OMX_ErrorStreamCorrupt,
    886                  0,
    887                  NULL);
    888             }
    889 
    890 
    891             if (0 == iInputCurrLength)
    892             {
    893                 if (iPVCapabilityFlags.iOMXComponentUsesFullAVCFrames)
    894                 {
    895                     iCurrNAL++;
    896 
    897                     if (iCurrNAL < iNumNALs)
    898                     {
    899                         ipFrameDecodeBuffer = ipInputBuffer->pBuffer + iNALOffset;
    900                         iInputCurrLength = iNALSizeArray[iCurrNAL];
    901 
    902                         if (iPVCapabilityFlags.iOMXComponentUsesNALStartCodes)
    903                         {
    904                             iNALOffset += (iInputCurrLength + NAL_START_CODE_SIZE); // offset for next NAL
    905                         }
    906                         else
    907                         {
    908                             iNALOffset += iInputCurrLength; // offset for next NAL
    909                         }
    910 
    911                         iNewInBufferRequired = OMX_FALSE;
    912                     }
    913                     else
    914                     {
    915                         ipInputBuffer->nFilledLen = 0;
    916                         ReturnInputBuffer(ipInputBuffer, pInPort);
    917                         iNewInBufferRequired = OMX_TRUE;
    918                         iIsInputBufferEnded = OMX_TRUE;
    919                         ipInputBuffer = NULL;
    920                     }
    921                 }
    922                 else
    923                 {
    924                     ipInputBuffer->nFilledLen = 0;
    925                     ReturnInputBuffer(ipInputBuffer, pInPort);
    926                     iNewInBufferRequired = OMX_TRUE;
    927                     iIsInputBufferEnded = OMX_TRUE;
    928                     ipInputBuffer = NULL;
    929                 }
    930             }
    931             else
    932             {
    933                 iNewInBufferRequired = OMX_FALSE;
    934             }
    935         }
    936         else if (iEndofStream == OMX_FALSE)
    937         {
    938             // it's possible that after partial frame assembly, the input buffer still remains empty (due to
    939             // client erroneously sending such buffers). This may cause error in processing/returning buffers
    940             // This code adds robustness in the sense that it returns such buffer to the client
    941 
    942             ipInputBuffer->nFilledLen = 0;
    943             ReturnInputBuffer(ipInputBuffer, pInPort);
    944             ipInputBuffer = NULL;
    945             iNewInBufferRequired = OMX_TRUE;
    946             iIsInputBufferEnded = OMX_TRUE;
    947         }
    948 
    949 
    950         /* If EOS flag has come from the client & there are no more
    951          * input buffers to decode, send the callback to the client*/
    952         if (OMX_TRUE == iEndofStream)
    953         {
    954             if (!iDecodeReturn)
    955             {
    956                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker EOS callback send"));
    957 
    958                 (*(ipCallbacks->EventHandler))
    959                 (pHandle,
    960                  iCallbackData,
    961                  OMX_EventBufferFlag,
    962                  1,
    963                  OMX_BUFFERFLAG_EOS,
    964                  NULL);
    965 
    966                 iNewInBufferRequired = OMX_TRUE;
    967                 iEndofStream = OMX_FALSE;
    968 
    969                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
    970                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    971                 ipOutputBuffer = NULL;
    972 
    973                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker OUT"));
    974 
    975                 return;
    976             }
    977             else if (iDecodeReturn)
    978             {
    979                 Status = ipAvcDec->FlushOutput_OMX(pOutBuffer, &OutputLength, &(ipOutputBuffer->nTimeStamp), pOutPort->PortParam.format.video.nFrameWidth, pOutPort->PortParam.format.video.nFrameHeight);
    980                 ipOutputBuffer->nFilledLen = OutputLength;
    981 
    982                 ipOutputBuffer->nOffset = 0;
    983 
    984                 if (OMX_FALSE != Status)
    985                 {
    986                     ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    987                     ipOutputBuffer = NULL;
    988 
    989                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker OUT"));
    990                     RunIfNotReady();
    991                     return;
    992                 }
    993                 else
    994                 {
    995                     iDecodeReturn = OMX_FALSE;
    996                     RunIfNotReady();
    997                 }
    998             }
    999         }
   1000 
   1001         //Send the output buffer back when it has some data in it
   1002         if (ipOutputBuffer->nFilledLen > 0)
   1003         {
   1004             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
   1005             ipOutputBuffer = NULL;
   1006         }
   1007 
   1008 
   1009         /* If there is some more processing left with current buffers, re-schedule the AO
   1010          * Do not go for more than one round of processing at a time.
   1011          * This may block the AO longer than required.
   1012          */
   1013         if ((ResizeNeeded == OMX_FALSE) && ((iInputCurrLength != 0) || (GetQueueNumElem(pInputQueue) > 0))
   1014                 && ((GetQueueNumElem(pOutputQueue) > 0) || (OMX_FALSE == iNewOutBufRequired)))
   1015         {
   1016             RunIfNotReady();
   1017         }
   1018     }
   1019 
   1020     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : DecodeWithMarker OUT"));
   1021     return;
   1022 }
   1023 
   1024 
   1025 void OpenmaxAvcAO::ComponentGetRolesOfComponent(OMX_STRING* aRoleString)
   1026 {
   1027     *aRoleString = (OMX_STRING)"video_decoder.avc";
   1028 }
   1029 
   1030 
   1031 
   1032 //Component object constructor
   1033 OpenmaxAvcAO::OpenmaxAvcAO()
   1034 {
   1035     ipAvcDec = NULL;
   1036 
   1037     if (!IsAdded())
   1038     {
   1039         AddToScheduler();
   1040     }
   1041     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : constructed"));
   1042 }
   1043 
   1044 
   1045 //Component object destructor
   1046 OpenmaxAvcAO::~OpenmaxAvcAO()
   1047 {
   1048     if (IsAdded())
   1049     {
   1050         RemoveFromScheduler();
   1051     }
   1052 
   1053     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : destructed"));
   1054 }
   1055 
   1056 
   1057 /** The Initialization function
   1058  */
   1059 OMX_ERRORTYPE OpenmaxAvcAO::ComponentInit()
   1060 {
   1061     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ComponentInit IN"));
   1062 
   1063     OMX_ERRORTYPE Status = OMX_ErrorNone;
   1064 
   1065     if (OMX_TRUE == iIsInit)
   1066     {
   1067         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ComponentInit error incorrect operation"));
   1068         return OMX_ErrorIncorrectStateOperation;
   1069     }
   1070     iIsInit = OMX_TRUE;
   1071 
   1072     //avc lib init
   1073     if (!iCodecReady)
   1074     {
   1075         Status = ipAvcDec->AvcDecInit_OMX();
   1076         iCodecReady = OMX_TRUE;
   1077     }
   1078 
   1079     iInputCurrLength = 0;
   1080     iNumNALs = 0;
   1081     iCurrNAL = 0;
   1082     iNALOffset = 0;
   1083     oscl_memset(iNALSizeArray, 0, MAX_NAL_PER_FRAME * sizeof(uint32));
   1084     //Used in dynamic port reconfiguration
   1085     iFrameCount = 0;
   1086     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ComponentInit OUT"));
   1087 
   1088     return Status;
   1089 
   1090 }
   1091 
   1092 /** This function is called upon a transition to the idle or invalid state.
   1093  *  Also it is called by the AvcComponentDestructor() function
   1094  */
   1095 OMX_ERRORTYPE OpenmaxAvcAO::ComponentDeInit()
   1096 {
   1097     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ComponentDeInit IN"));
   1098 
   1099     OMX_ERRORTYPE Status = OMX_ErrorNone;
   1100 
   1101     iIsInit = OMX_FALSE;
   1102 
   1103     if (iCodecReady)
   1104     {
   1105         Status = ipAvcDec->AvcDecDeinit_OMX();
   1106         iCodecReady = OMX_FALSE;
   1107     }
   1108 
   1109     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAvcAO : ComponentDeInit OUT"));
   1110 
   1111     return Status;
   1112 
   1113 }
   1114 
   1115 
   1116 OMX_ERRORTYPE OpenmaxAvcAO::GetConfig(
   1117     OMX_IN  OMX_HANDLETYPE hComponent,
   1118     OMX_IN  OMX_INDEXTYPE nIndex,
   1119     OMX_INOUT OMX_PTR pComponentConfigStructure)
   1120 {
   1121     OSCL_UNUSED_ARG(hComponent);
   1122     OSCL_UNUSED_ARG(nIndex);
   1123     OSCL_UNUSED_ARG(pComponentConfigStructure);
   1124     return OMX_ErrorNotImplemented;
   1125 }
   1126 
   1127 /* This routine will reset the decoder library and some of the associated flags*/
   1128 void OpenmaxAvcAO::ResetComponent()
   1129 {
   1130     // reset decoder
   1131     if (ipAvcDec)
   1132     {
   1133         ipAvcDec->ResetDecoder();
   1134     }
   1135 
   1136 }
   1137