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 "pv_omxdefs.h"
     20 #include "omx_mpeg4_component.h"
     21 
     22 #if PROXY_INTERFACE
     23 #include "omx_proxy_interface.h"
     24 #endif
     25 
     26 // Use default DLL entry point
     27 #ifndef OSCL_DLL_H_INCLUDED
     28 #include "oscl_dll.h"
     29 #endif
     30 
     31 OSCL_DLL_ENTRY_POINT_DEFAULT()
     32 
     33 static const uint32 mask[33] =
     34 {
     35     0x00000000, 0x00000001, 0x00000003, 0x00000007,
     36     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
     37     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
     38     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
     39     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
     40     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
     41     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
     42     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
     43     0xffffffff
     44 };
     45 
     46 // This function is called by OMX_GetHandle and it creates an instance of the mpeg4 component AO
     47 OSCL_EXPORT_REF OMX_ERRORTYPE Mpeg4OmxComponentFactory(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)
     48 {
     49     OSCL_UNUSED_ARG(aOmxLibName);
     50     OSCL_UNUSED_ARG(aOmxLib);
     51     OSCL_UNUSED_ARG(aOsclUuid);
     52     OSCL_UNUSED_ARG(aRefCount);
     53 
     54 
     55     OpenmaxMpeg4AO* pOpenmaxAOType;
     56     OMX_ERRORTYPE Status;
     57 
     58     // move InitMpeg4OmxComponentFields content to actual constructor
     59 
     60     pOpenmaxAOType = (OpenmaxMpeg4AO*) OSCL_NEW(OpenmaxMpeg4AO, ());
     61 
     62     if (NULL == pOpenmaxAOType)
     63     {
     64         return OMX_ErrorInsufficientResources;
     65     }
     66 
     67     // set decoding mode to H263
     68     pOpenmaxAOType->SetDecoderMode(MODE_MPEG4);
     69 
     70     //Call the construct component to initialize OMX types
     71     Status = pOpenmaxAOType->ConstructComponent(pAppData, pProxy);
     72 
     73     *pHandle = pOpenmaxAOType->GetOmxHandle();
     74 
     75     return Status;
     76     ///////////////////////////////////////////////////////////////////////////////////////
     77 }
     78 
     79 // This function is called by OMX_FreeHandle when component AO needs to be destroyed
     80 OSCL_EXPORT_REF OMX_ERRORTYPE Mpeg4OmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
     81 {
     82     OSCL_UNUSED_ARG(aOmxLib);
     83     OSCL_UNUSED_ARG(aOsclUuid);
     84     OSCL_UNUSED_ARG(aRefCount);
     85 
     86     // get pointer to component AO
     87     OpenmaxMpeg4AO* pOpenmaxAOType = (OpenmaxMpeg4AO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate;
     88 
     89     // clean up decoder, OMX component stuff
     90     pOpenmaxAOType->DestroyComponent();
     91 
     92     // destroy the AO class
     93     OSCL_DELETE(pOpenmaxAOType);
     94 
     95     return OMX_ErrorNone;
     96 }
     97 
     98 // This function is called by OMX_GetHandle and it creates an instance of the h263 component AO
     99 OSCL_EXPORT_REF OMX_ERRORTYPE H263OmxComponentFactory(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)
    100 {
    101     OSCL_UNUSED_ARG(aOmxLibName);
    102     OSCL_UNUSED_ARG(aOmxLib);
    103     OSCL_UNUSED_ARG(aOsclUuid);
    104     OSCL_UNUSED_ARG(aRefCount);
    105 
    106     OpenmaxMpeg4AO* pOpenmaxAOType;
    107     OMX_ERRORTYPE Status;
    108 
    109     // move InitMpeg4OmxComponentFields content to actual constructor
    110 
    111     pOpenmaxAOType = (OpenmaxMpeg4AO*) OSCL_NEW(OpenmaxMpeg4AO, ());
    112 
    113     if (NULL == pOpenmaxAOType)
    114     {
    115         return OMX_ErrorInsufficientResources;
    116     }
    117 
    118     // set decoding mode to H263
    119     pOpenmaxAOType->SetDecoderMode(MODE_H263);
    120 
    121     //Call the construct component to initialize OMX types
    122     Status = pOpenmaxAOType->ConstructComponent(pAppData, pProxy);
    123 
    124     *pHandle = pOpenmaxAOType->GetOmxHandle();
    125 
    126     return Status;
    127     ///////////////////////////////////////////////////////////////////////////////////////
    128 }
    129 
    130 // This function is called by OMX_FreeHandle when component AO needs to be destroyed
    131 OSCL_EXPORT_REF OMX_ERRORTYPE H263OmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
    132 {
    133     OSCL_UNUSED_ARG(aOmxLib);
    134     OSCL_UNUSED_ARG(aOsclUuid);
    135     OSCL_UNUSED_ARG(aRefCount);
    136 
    137     // get pointer to component AO
    138     OpenmaxMpeg4AO* pOpenmaxAOType = (OpenmaxMpeg4AO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate;
    139 
    140     // clean up decoder, OMX component stuff
    141     pOpenmaxAOType->DestroyComponent();
    142 
    143     // destroy the AO class
    144     OSCL_DELETE(pOpenmaxAOType);
    145 
    146     return OMX_ErrorNone;
    147 }
    148 
    149 #if (DYNAMIC_LOAD_OMX_M4V_COMPONENT || DYNAMIC_LOAD_OMX_H263_COMPONENT)
    150 class Mpeg4H263OmxSharedLibraryInterface: public OsclSharedLibraryInterface,
    151         public OmxSharedLibraryInterface
    152 
    153 {
    154     public:
    155         OsclAny *QueryOmxComponentInterface(const OsclUuid& aOmxTypeId, const OsclUuid& aInterfaceId)
    156         {
    157             if (PV_OMX_M4VDEC_UUID == aOmxTypeId)
    158             {
    159                 if (PV_OMX_CREATE_INTERFACE == aInterfaceId)
    160                 {
    161                     return ((OsclAny*)(&Mpeg4OmxComponentFactory));
    162                 }
    163                 else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId)
    164                 {
    165                     return ((OsclAny*)(&Mpeg4OmxComponentDestructor));
    166                 }
    167             }
    168             else if (PV_OMX_H263DEC_UUID == aOmxTypeId)
    169             {
    170                 if (PV_OMX_CREATE_INTERFACE == aInterfaceId)
    171                 {
    172                     return ((OsclAny*)(&H263OmxComponentFactory));
    173                 }
    174                 else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId)
    175                 {
    176                     return ((OsclAny*)(&H263OmxComponentDestructor));
    177                 }
    178             }
    179             return NULL;
    180         };
    181         OsclAny *SharedLibraryLookup(const OsclUuid& aInterfaceId)
    182         {
    183             if (aInterfaceId == PV_OMX_SHARED_INTERFACE)
    184             {
    185                 return OSCL_STATIC_CAST(OmxSharedLibraryInterface*, this);
    186             }
    187             return NULL;
    188         };
    189         Mpeg4H263OmxSharedLibraryInterface() {};
    190 };
    191 
    192 // function to obtain the interface object from the shared library
    193 extern "C"
    194 {
    195     OSCL_EXPORT_REF OsclAny* PVGetInterface()
    196     {
    197         return (OsclAny*) OSCL_NEW(Mpeg4H263OmxSharedLibraryInterface, ());
    198     }
    199 
    200     OSCL_EXPORT_REF void PVReleaseInterface(OsclSharedLibraryInterface* aInstance)
    201     {
    202         Mpeg4H263OmxSharedLibraryInterface* module = (Mpeg4H263OmxSharedLibraryInterface*)aInstance;
    203         OSCL_DELETE(module);
    204     }
    205 }
    206 
    207 #endif
    208 
    209 void OpenmaxMpeg4AO::SetDecoderMode(int mode)
    210 {
    211     iDecMode = mode;
    212 }
    213 
    214 
    215 
    216 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    217 
    218 OMX_ERRORTYPE OpenmaxMpeg4AO::ConstructComponent(OMX_PTR pAppData, OMX_PTR pProxy)
    219 {
    220     ComponentPortType *pInPort, *pOutPort;
    221     OMX_ERRORTYPE Status;
    222 
    223     iNumPorts = 2;
    224     iOmxComponent.nSize = sizeof(OMX_COMPONENTTYPE);
    225     iOmxComponent.pComponentPrivate = (OMX_PTR) this;  // pComponentPrivate points to THIS component AO class
    226     ipComponentProxy = pProxy;
    227     iOmxComponent.pApplicationPrivate = pAppData; // init the App data
    228 
    229 
    230 #if PROXY_INTERFACE
    231     iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE;
    232 
    233     iOmxComponent.SendCommand = OpenmaxMpeg4AO::BaseComponentProxySendCommand;
    234     iOmxComponent.GetParameter = OpenmaxMpeg4AO::BaseComponentProxyGetParameter;
    235     iOmxComponent.SetParameter = OpenmaxMpeg4AO::BaseComponentProxySetParameter;
    236     iOmxComponent.GetConfig = OpenmaxMpeg4AO::BaseComponentProxyGetConfig;
    237     iOmxComponent.SetConfig = OpenmaxMpeg4AO::BaseComponentProxySetConfig;
    238     iOmxComponent.GetExtensionIndex = OpenmaxMpeg4AO::BaseComponentProxyGetExtensionIndex;
    239     iOmxComponent.GetState = OpenmaxMpeg4AO::BaseComponentProxyGetState;
    240     iOmxComponent.UseBuffer = OpenmaxMpeg4AO::BaseComponentProxyUseBuffer;
    241     iOmxComponent.AllocateBuffer = OpenmaxMpeg4AO::BaseComponentProxyAllocateBuffer;
    242     iOmxComponent.FreeBuffer = OpenmaxMpeg4AO::BaseComponentProxyFreeBuffer;
    243     iOmxComponent.EmptyThisBuffer = OpenmaxMpeg4AO::BaseComponentProxyEmptyThisBuffer;
    244     iOmxComponent.FillThisBuffer = OpenmaxMpeg4AO::BaseComponentProxyFillThisBuffer;
    245 
    246 #else
    247     iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_FALSE;
    248 
    249     iOmxComponent.SendCommand = OpenmaxMpeg4AO::BaseComponentSendCommand;
    250     iOmxComponent.GetParameter = OpenmaxMpeg4AO::BaseComponentGetParameter;
    251     iOmxComponent.SetParameter = OpenmaxMpeg4AO::BaseComponentSetParameter;
    252     iOmxComponent.GetConfig = OpenmaxMpeg4AO::BaseComponentGetConfig;
    253     iOmxComponent.SetConfig = OpenmaxMpeg4AO::BaseComponentSetConfig;
    254     iOmxComponent.GetExtensionIndex = OpenmaxMpeg4AO::BaseComponentGetExtensionIndex;
    255     iOmxComponent.GetState = OpenmaxMpeg4AO::BaseComponentGetState;
    256     iOmxComponent.UseBuffer = OpenmaxMpeg4AO::BaseComponentUseBuffer;
    257     iOmxComponent.AllocateBuffer = OpenmaxMpeg4AO::BaseComponentAllocateBuffer;
    258     iOmxComponent.FreeBuffer = OpenmaxMpeg4AO::BaseComponentFreeBuffer;
    259     iOmxComponent.EmptyThisBuffer = OpenmaxMpeg4AO::BaseComponentEmptyThisBuffer;
    260     iOmxComponent.FillThisBuffer = OpenmaxMpeg4AO::BaseComponentFillThisBuffer;
    261 #endif
    262 
    263     iOmxComponent.SetCallbacks = OpenmaxMpeg4AO::BaseComponentSetCallbacks;
    264     iOmxComponent.nVersion.s.nVersionMajor = SPECVERSIONMAJOR;
    265     iOmxComponent.nVersion.s.nVersionMinor = SPECVERSIONMINOR;
    266     iOmxComponent.nVersion.s.nRevision = SPECREVISION;
    267     iOmxComponent.nVersion.s.nStep = SPECSTEP;
    268 
    269     // PV capability
    270     iPVCapabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
    271     iPVCapabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
    272     iPVCapabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
    273     iPVCapabilityFlags.iOMXComponentSupportsPartialFrames = OMX_TRUE;
    274     iPVCapabilityFlags.iOMXComponentUsesNALStartCodes = OMX_FALSE;
    275     iPVCapabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
    276     iPVCapabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_FALSE;
    277 
    278     if (ipAppPriv)
    279     {
    280         oscl_free(ipAppPriv);
    281         ipAppPriv = NULL;
    282     }
    283 
    284     ipAppPriv = (ComponentPrivateType*) oscl_malloc(sizeof(ComponentPrivateType));
    285 
    286     if (NULL == ipAppPriv)
    287     {
    288         return OMX_ErrorInsufficientResources;
    289     }
    290 
    291     //Construct base class now
    292     Status = ConstructBaseComponent(pAppData);
    293 
    294     if (OMX_ErrorNone != Status)
    295     {
    296         return Status;
    297     }
    298 
    299     /** Domain specific section for the ports. */
    300     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    301     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo;
    302     if (iDecMode == MODE_MPEG4)
    303     {
    304         ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"video/mpeg4";
    305         ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
    306 
    307     }
    308     else if (iDecMode == MODE_H263)
    309     {
    310         ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"video/h263";
    311         ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
    312 
    313     }
    314 
    315     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0;
    316     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE;
    317 
    318     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatUnused;
    319     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176;
    320     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144;
    321     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000;
    322     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16);
    323     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDir = OMX_DirInput;
    324     //Set to a default value, will change later during setparameter call
    325     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_INPUT_BUFFER_MP4;
    326     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
    327     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize = INPUT_BUFFER_SIZE_MP4;
    328     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
    329     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
    330 
    331 
    332     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
    333     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo;
    334     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"raw";
    335     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0;
    336     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE;
    337     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
    338     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
    339     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176; //320; //176;
    340     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nStride = 176;
    341     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144; //240; //144;
    342     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nSliceHeight = 144;
    343     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000;
    344     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16);
    345     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDir = OMX_DirOutput;
    346     //Set to a default value, will change later during setparameter call
    347     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_OUTPUT_BUFFER_MP4;
    348     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
    349     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferSize = OUTPUT_BUFFER_SIZE_MP4;
    350     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
    351     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
    352 
    353     if (iDecMode == MODE_MPEG4)
    354     {
    355         //Default values for mpeg4 video param port
    356         ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoMpeg4.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    357         ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoMpeg4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
    358         ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoMpeg4.eLevel = OMX_VIDEO_MPEG4Level3;
    359 
    360         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    361         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.nProfileIndex = 0;
    362         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
    363         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.eLevel = OMX_VIDEO_MPEG4Level3;
    364         oscl_strncpy((OMX_STRING)iComponentRole, (OMX_STRING)"video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
    365     }
    366     else if (iDecMode == MODE_H263)
    367     {
    368         //Default values for h263 video param port
    369         ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoH263.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    370         ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoH263.eProfile = (OMX_VIDEO_H263PROFILETYPE) (OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2);
    371         ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoH263.eLevel = OMX_VIDEO_H263Level45;
    372 
    373         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
    374         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.nProfileIndex = 0;
    375         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.eProfile = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2;
    376         ipPorts[OMX_PORT_INPUTPORT_INDEX]->ProfileLevel.eLevel = OMX_VIDEO_H263Level45;
    377         oscl_strncpy((OMX_STRING)iComponentRole, (OMX_STRING)"video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
    378 
    379     }
    380 
    381     iPortTypesParam.nPorts = 2;
    382     iPortTypesParam.nStartPortNumber = 0;
    383 
    384     pInPort = (ComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX];
    385     pOutPort = (ComponentPortType*) ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
    386 
    387     pInPort->ActualNumPortFormatsSupported = 1;
    388 
    389     //OMX_VIDEO_PARAM_PORTFORMATTYPE INPUT PORT SETTINGS
    390     //On input port for index 0
    391     SetHeader(&pInPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
    392     pInPort->VideoParam[0].nPortIndex = 0;
    393     pInPort->VideoParam[0].nIndex = 0;
    394 
    395     if (iDecMode == MODE_MPEG4)
    396     {
    397         pInPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingMPEG4;
    398 
    399     }
    400     else if (iDecMode == MODE_H263)
    401     {
    402         pInPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingH263;
    403     }
    404 
    405     pInPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatUnused;
    406 
    407     pOutPort->ActualNumPortFormatsSupported = 1;
    408 
    409     //OMX_VIDEO_PARAM_PORTFORMATTYPE OUTPUT PORT SETTINGS
    410     //On output port for index 0
    411     SetHeader(&pOutPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
    412     pOutPort->VideoParam[0].nPortIndex = 1;
    413     pOutPort->VideoParam[0].nIndex = 0;
    414     pOutPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingUnused;
    415     pOutPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatYUV420Planar;
    416 
    417 
    418     iUseExtTimestamp = OMX_TRUE;
    419 
    420 
    421     if (ipMpegDecoderObject)
    422     {
    423         OSCL_DELETE(ipMpegDecoderObject);
    424         ipMpegDecoderObject = NULL;
    425     }
    426     ipMpegDecoderObject = OSCL_NEW(Mpeg4Decoder_OMX, ());
    427     oscl_memset(ipMpegDecoderObject, 0, sizeof(Mpeg4Decoder_OMX));
    428 
    429 #if PROXY_INTERFACE
    430 
    431     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSendCommand = BaseComponentSendCommand;
    432     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetParameter = BaseComponentGetParameter;
    433     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetParameter = BaseComponentSetParameter;
    434     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetConfig = BaseComponentGetConfig;
    435     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetConfig = BaseComponentSetConfig;
    436     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetExtensionIndex = BaseComponentGetExtensionIndex;
    437     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetState = BaseComponentGetState;
    438     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentUseBuffer = BaseComponentUseBuffer;
    439     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentAllocateBuffer = BaseComponentAllocateBuffer;
    440     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFreeBuffer = BaseComponentFreeBuffer;
    441     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentEmptyThisBuffer = BaseComponentEmptyThisBuffer;
    442     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFillThisBuffer = BaseComponentFillThisBuffer;
    443 
    444 #endif
    445 
    446     return OMX_ErrorNone;
    447 }
    448 
    449 
    450 /** This function is called by the omx core when the component
    451     * is disposed by the IL client with a call to FreeHandle().
    452     */
    453 
    454 OMX_ERRORTYPE OpenmaxMpeg4AO::DestroyComponent()
    455 {
    456     if (OMX_FALSE != iIsInit)
    457     {
    458         ComponentDeInit();
    459     }
    460 
    461     //Destroy the base class now
    462     DestroyBaseComponent();
    463 
    464     if (ipMpegDecoderObject)
    465     {
    466         OSCL_DELETE(ipMpegDecoderObject);
    467         ipMpegDecoderObject = NULL;
    468     }
    469 
    470     if (ipAppPriv)
    471     {
    472         ipAppPriv->CompHandle = NULL;
    473 
    474         oscl_free(ipAppPriv);
    475         ipAppPriv = NULL;
    476     }
    477 
    478     return OMX_ErrorNone;
    479 }
    480 
    481 
    482 
    483 /* This function will be called in case of buffer management without marker bit present
    484  * The purpose is to copy the current input buffer into a big temporary buffer, so that
    485  * an incomplete/partial frame is never passed to the decoder library for decode
    486  */
    487 void OpenmaxMpeg4AO::ComponentBufferMgmtWithoutMarker()
    488 {
    489     //This common routine has been written in the base class
    490     TempInputBufferMgmtWithoutMarker();
    491 }
    492 
    493 
    494 void OpenmaxMpeg4AO::ProcessData()
    495 {
    496     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ProcessData IN"));
    497     if (!iEndOfFrameFlag)
    498     {
    499         DecodeWithoutMarker();
    500     }
    501     else
    502     {
    503         DecodeWithMarker();
    504     }
    505 
    506     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ProcessData OUT"));
    507 }
    508 
    509 
    510 void OpenmaxMpeg4AO::DecodeWithoutMarker()
    511 {
    512     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker IN"));
    513 
    514     QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
    515     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
    516     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
    517     OMX_COMPONENTTYPE  *pHandle = &iOmxComponent;
    518 
    519     OMX_U8*                 pOutBuffer;
    520     OMX_U32                 OutputLength;
    521     OMX_U8*                 pTempInBuffer;
    522     OMX_U32                 TempInLength;
    523     OMX_BOOL                DecodeReturn;
    524     OMX_BOOL                MarkerFlag = OMX_FALSE;
    525     OMX_BOOL                ResizeNeeded = OMX_FALSE;
    526 
    527     OMX_U32 TempInputBufferSize = (2 * sizeof(uint8) * (ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize));
    528 
    529     OMX_U32 CurrWidth =  ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth;
    530     OMX_U32 CurrHeight = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight;
    531 
    532     if ((!iIsInputBufferEnded) || iEndofStream)
    533     {
    534         //Check whether a new output buffer is available or not
    535         if (0 == (GetQueueNumElem(pOutputQueue)))
    536         {
    537             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker OUT output buffer unavailable"));
    538             //Store the mark data for output buffer, as it will be overwritten next time
    539             if (NULL != ipTargetComponent)
    540             {
    541                 ipTempTargetComponent = ipTargetComponent;
    542                 iTempTargetMarkData = iTargetMarkData;
    543                 iMarkPropagate = OMX_TRUE;
    544             }
    545             return;
    546         }
    547 
    548         ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
    549         if (NULL == ipOutputBuffer)
    550         {
    551             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker Error, output buffer dequeue returned NULL, OUT"));
    552             return;
    553         }
    554 
    555         //Do not proceed if the output buffer can't fit the YUV data
    556         if ((ipOutputBuffer->nAllocLen < (OMX_U32)((((CurrWidth + 15) >> 4) << 4) *(((CurrHeight + 15) >> 4) << 4) * 3 / 2)) && (OMX_TRUE == ipMpegDecoderObject->Mpeg4InitCompleteFlag))
    557         {
    558             ipOutputBuffer->nFilledLen = 0;
    559             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    560             ipOutputBuffer = NULL;
    561             return;
    562         }
    563 
    564         ipOutputBuffer->nFilledLen = 0;
    565 
    566 
    567         /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer
    568          * command and hMarkTargetComponent as given by the specifications
    569          */
    570         if (ipMark != NULL)
    571         {
    572             ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
    573             ipOutputBuffer->pMarkData = ipMark->pMarkData;
    574             ipMark = NULL;
    575         }
    576 
    577         if ((OMX_TRUE == iMarkPropagate) && (ipTempTargetComponent != ipTargetComponent))
    578         {
    579             ipOutputBuffer->hMarkTargetComponent = ipTempTargetComponent;
    580             ipOutputBuffer->pMarkData = iTempTargetMarkData;
    581             ipTempTargetComponent = NULL;
    582             iMarkPropagate = OMX_FALSE;
    583         }
    584         else if (ipTargetComponent != NULL)
    585         {
    586             ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
    587             ipOutputBuffer->pMarkData = iTargetMarkData;
    588             ipTargetComponent = NULL;
    589             iMarkPropagate = OMX_FALSE;
    590 
    591         }
    592         //Mark buffer code ends here
    593 
    594         pOutBuffer = ipOutputBuffer->pBuffer;
    595         OutputLength = 0;
    596 
    597         pTempInBuffer = ipTempInputBuffer + iTempConsumedLength;
    598         TempInLength = iTempInputBufferLength;
    599 
    600         //Output buffer is passed as a short pointer
    601         DecodeReturn = ipMpegDecoderObject->Mp4DecodeVideo(pOutBuffer, (OMX_U32*) & OutputLength,
    602                        &(pTempInBuffer),
    603                        &TempInLength,
    604                        &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam),
    605                        &iFrameCount,
    606                        MarkerFlag,
    607                        &ResizeNeeded);
    608 
    609         ipOutputBuffer->nFilledLen = OutputLength;
    610 
    611         //offset not required in our case, set it to zero
    612         ipOutputBuffer->nOffset = 0;
    613 
    614         //If decoder returned error, report it to the client via a callback
    615         if (!DecodeReturn && OMX_FALSE == ipMpegDecoderObject->Mpeg4InitCompleteFlag)
    616         {
    617             // initialization error, stop playback
    618             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker ErrorBadParameter callback send"));
    619 
    620             (*(ipCallbacks->EventHandler))
    621             (pHandle,
    622              iCallbackData,
    623              OMX_EventError,
    624              OMX_ErrorBadParameter,
    625              0,
    626              NULL);
    627         }
    628         else if (!DecodeReturn && OMX_FALSE == iEndofStream)
    629         {
    630             // decoding error
    631             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker ErrorStreamCorrupt callback send"));
    632 
    633             (*(ipCallbacks->EventHandler))
    634             (pHandle,
    635              iCallbackData,
    636              OMX_EventError,
    637              OMX_ErrorStreamCorrupt,
    638              0,
    639              NULL);
    640         }
    641 
    642 
    643         if (ResizeNeeded == OMX_TRUE)
    644         {
    645             // send port settings changed event
    646             OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*) ipAppPriv->CompHandle;
    647 
    648             // set the flag to disable further processing until Client reacts to this
    649             //  by doing dynamic port reconfiguration
    650             iResizePending = OMX_TRUE;
    651 
    652             (*(ipCallbacks->EventHandler))
    653             (pHandle,
    654              iCallbackData,
    655              OMX_EventPortSettingsChanged, //The command was completed
    656              OMX_PORT_OUTPUTPORT_INDEX,
    657              0,
    658              NULL);
    659 
    660         }
    661         //Set the timestamp equal to the input buffer timestamp
    662         ipOutputBuffer->nTimeStamp = iFrameTimestamp;
    663 
    664         iTempConsumedLength += (iTempInputBufferLength - TempInLength);
    665         iTempInputBufferLength = TempInLength;
    666 
    667         //Do not decode if big buffer is less than half the size
    668         if (TempInLength < (TempInputBufferSize >> 1))
    669         {
    670             iIsInputBufferEnded = OMX_TRUE;
    671             iNewInBufferRequired = OMX_TRUE;
    672         }
    673 
    674 
    675         /* If EOS flag has come from the client & there are no more
    676          * input buffers to decode, send the callback to the client
    677          */
    678         if (OMX_TRUE == iEndofStream)
    679         {
    680             if ((0 == iTempInputBufferLength) || (!DecodeReturn))
    681             {
    682                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker EOS callback send"));
    683 
    684                 (*(ipCallbacks->EventHandler))
    685                 (pHandle,
    686                  iCallbackData,
    687                  OMX_EventBufferFlag,
    688                  1,
    689                  OMX_BUFFERFLAG_EOS,
    690                  NULL);
    691 
    692                 iNewInBufferRequired = OMX_TRUE;
    693                 iEndofStream = OMX_FALSE;
    694 
    695                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
    696                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    697                 ipOutputBuffer = NULL;
    698 
    699                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker OUT"));
    700 
    701                 return;
    702             }
    703         }
    704 
    705         //Send the output buffer back after decode
    706         ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    707         ipOutputBuffer = NULL;
    708 
    709         /* If there is some more processing left with current buffers, re-schedule the AO
    710          * Do not go for more than one round of processing at a time.
    711          * This may block the AO longer than required.
    712          */
    713         if ((TempInLength != 0 || GetQueueNumElem(pInputQueue) > 0) && (GetQueueNumElem(pOutputQueue) > 0) && (ResizeNeeded == OMX_FALSE))
    714         {
    715             RunIfNotReady();
    716         }
    717     }
    718 
    719     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker OUT"));
    720     return;
    721 }
    722 
    723 
    724 void OpenmaxMpeg4AO::DecodeWithMarker()
    725 {
    726     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker IN"));
    727 
    728     QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
    729     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
    730 
    731     ComponentPortType*  pInPort = ipPorts[OMX_PORT_INPUTPORT_INDEX];
    732     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
    733 
    734     OMX_U8*                 pOutBuffer;
    735     OMX_U32                 OutputLength;
    736     OMX_BOOL                DecodeReturn = OMX_FALSE;
    737     OMX_BOOL                MarkerFlag = OMX_TRUE;
    738     OMX_COMPONENTTYPE *     pHandle = &iOmxComponent;
    739     OMX_BOOL                ResizeNeeded = OMX_FALSE;
    740 
    741     OMX_U32 CurrWidth =  ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth;
    742     OMX_U32 CurrHeight = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight;
    743 
    744     if ((!iIsInputBufferEnded) || (iEndofStream))
    745     {
    746         //Check whether a new output buffer is available or not
    747         if (0 == (GetQueueNumElem(pOutputQueue)))
    748         {
    749             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker OUT output buffer unavailable"));
    750             iNewInBufferRequired = OMX_FALSE;
    751             return;
    752         }
    753 
    754         ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
    755         if (NULL == ipOutputBuffer)
    756         {
    757             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker Error, output buffer dequeue returned NULL, OUT"));
    758             iNewInBufferRequired = OMX_FALSE;
    759             return;
    760         }
    761 
    762         //Do not proceed if the output buffer can't fit the YUV data
    763         if ((ipOutputBuffer->nAllocLen < (OMX_U32)((((CurrWidth + 15) >> 4) << 4) *(((CurrHeight + 15) >> 4) << 4) * 3 / 2)) && (OMX_TRUE == ipMpegDecoderObject->Mpeg4InitCompleteFlag))
    764         {
    765             ipOutputBuffer->nFilledLen = 0;
    766             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    767             ipOutputBuffer = NULL;
    768             return;
    769         }
    770         ipOutputBuffer->nFilledLen = 0;
    771 
    772         /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer
    773          * command and hMarkTargetComponent as given by the specifications
    774          */
    775         if (ipMark != NULL)
    776         {
    777             ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
    778             ipOutputBuffer->pMarkData = ipMark->pMarkData;
    779             ipMark = NULL;
    780         }
    781 
    782         if (ipTargetComponent != NULL)
    783         {
    784             ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
    785             ipOutputBuffer->pMarkData = iTargetMarkData;
    786             ipTargetComponent = NULL;
    787 
    788         }
    789         //Mark buffer code ends here
    790 
    791         if (iInputCurrLength > 0)
    792         {
    793             pOutBuffer = ipOutputBuffer->pBuffer;
    794             OutputLength = 0;
    795 
    796             //Output buffer is passed as a short pointer
    797             DecodeReturn = ipMpegDecoderObject->Mp4DecodeVideo(pOutBuffer, (OMX_U32*) & OutputLength,
    798                            &(ipFrameDecodeBuffer),
    799                            &(iInputCurrLength),
    800                            &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam),
    801                            &iFrameCount,
    802                            MarkerFlag,
    803                            &ResizeNeeded);
    804 
    805             ipOutputBuffer->nFilledLen = OutputLength;
    806             //offset not required in our case, set it to zero
    807             ipOutputBuffer->nOffset = 0;
    808 
    809             //If decoder returned error, report it to the client via a callback
    810             if (!DecodeReturn && OMX_FALSE == ipMpegDecoderObject->Mpeg4InitCompleteFlag)
    811             {
    812                 // initialization error, stop playback
    813                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithoutMarker ErrorBadParameter callback send"));
    814 
    815                 (*(ipCallbacks->EventHandler))
    816                 (pHandle,
    817                  iCallbackData,
    818                  OMX_EventError,
    819                  OMX_ErrorBadParameter,
    820                  0,
    821                  NULL);
    822             }
    823             else if (!DecodeReturn && OMX_FALSE == iEndofStream)
    824             {
    825                 // decode error
    826                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker ErrorStreamCorrupt callback send"));
    827 
    828                 (*(ipCallbacks->EventHandler))
    829                 (pHandle,
    830                  iCallbackData,
    831                  OMX_EventError,
    832                  OMX_ErrorStreamCorrupt,
    833                  0,
    834                  NULL);
    835             }
    836 
    837             if (ResizeNeeded == OMX_TRUE)
    838             {
    839                 // send port settings changed event
    840                 OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*) ipAppPriv->CompHandle;
    841 
    842                 iResizePending = OMX_TRUE;
    843                 (*(ipCallbacks->EventHandler))
    844                 (pHandle,
    845                  iCallbackData,
    846                  OMX_EventPortSettingsChanged, //The command was completed
    847                  OMX_PORT_OUTPUTPORT_INDEX,
    848                  0,
    849                  NULL);
    850 
    851             }
    852             //Set the timestamp equal to the input buffer timestamp
    853             if (OMX_TRUE == iUseExtTimestamp)
    854             {
    855                 ipOutputBuffer->nTimeStamp = iFrameTimestamp;
    856             }
    857 
    858             /* Discard the input frame if it is with the marker bit & decoder fails*/
    859             if (iInputCurrLength == 0 || !DecodeReturn)
    860             {
    861                 ipInputBuffer->nFilledLen = 0;
    862                 ReturnInputBuffer(ipInputBuffer, pInPort);
    863                 ipInputBuffer = NULL;
    864                 iNewInBufferRequired = OMX_TRUE;
    865                 iIsInputBufferEnded = OMX_TRUE;
    866                 iUseExtTimestamp = OMX_TRUE;
    867                 iInputCurrLength = 0;
    868             }
    869             else
    870             {
    871                 iNewInBufferRequired = OMX_FALSE;
    872                 iIsInputBufferEnded = OMX_FALSE;
    873                 iUseExtTimestamp = OMX_FALSE;
    874             }
    875         }
    876         else if (iEndofStream == OMX_FALSE)
    877         {
    878             // it's possible that after partial frame assembly, the input buffer still remains empty (due to
    879             // client erroneously sending such buffers). This code adds robustness in the sense that it returns such buffer to the client
    880 
    881             ipInputBuffer->nFilledLen = 0;
    882             ReturnInputBuffer(ipInputBuffer, pInPort);
    883             ipInputBuffer = NULL;
    884             iNewInBufferRequired = OMX_TRUE;
    885             iIsInputBufferEnded = OMX_TRUE;
    886             iUseExtTimestamp = OMX_TRUE;
    887         }
    888 
    889 
    890 
    891 
    892         /* If EOS flag has come from the client & there are no more
    893          * input buffers to decode, send the callback to the client
    894          */
    895         if (OMX_TRUE == iEndofStream)
    896         {
    897             if (!DecodeReturn)
    898             {
    899                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker EOS callback send"));
    900 
    901                 (*(ipCallbacks->EventHandler))
    902                 (pHandle,
    903                  iCallbackData,
    904                  OMX_EventBufferFlag,
    905                  1,
    906                  OMX_BUFFERFLAG_EOS,
    907                  NULL);
    908 
    909                 iNewInBufferRequired = OMX_TRUE;
    910                 //Mark this flag false once the callback has been send back
    911                 iEndofStream = OMX_FALSE;
    912 
    913                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
    914                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    915                 ipOutputBuffer = NULL;
    916 
    917                 if ((iNumInputBuffer != 0) && (NULL != ipInputBuffer))
    918                 {
    919                     ReturnInputBuffer(ipInputBuffer, pInPort);
    920                     ipInputBuffer = NULL;
    921                     iIsInputBufferEnded = OMX_TRUE;
    922                     iInputCurrLength = 0;
    923                 }
    924 
    925                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker OUT"));
    926                 return;
    927             }
    928 
    929         }
    930 
    931         //Send the output buffer back after decode
    932         ReturnOutputBuffer(ipOutputBuffer, pOutPort);
    933         ipOutputBuffer = NULL;
    934 
    935 
    936         /* If there is some more processing left with current buffers, re-schedule the AO
    937          * Do not go for more than one round of processing at a time.
    938          * This may block the AO longer than required.
    939          */
    940         if ((iInputCurrLength != 0 || GetQueueNumElem(pInputQueue) > 0)
    941                 && (GetQueueNumElem(pOutputQueue) > 0) && (ResizeNeeded == OMX_FALSE))
    942         {
    943             RunIfNotReady();
    944         }
    945     }
    946 
    947     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : DecodeWithMarker OUT"));
    948     return;
    949 }
    950 
    951 
    952 //Not implemented & supported in case of base profile components
    953 
    954 void OpenmaxMpeg4AO::ComponentGetRolesOfComponent(OMX_STRING* aRoleString)
    955 {
    956     *aRoleString = (OMX_STRING)"video_decoder.mpeg4";
    957 }
    958 
    959 
    960 //Component constructor
    961 OpenmaxMpeg4AO::OpenmaxMpeg4AO()
    962 {
    963     iUseExtTimestamp = OMX_TRUE;
    964     ipMpegDecoderObject = NULL;
    965 
    966     if (!IsAdded())
    967     {
    968         AddToScheduler();
    969     }
    970 
    971     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : constructed"));
    972 }
    973 
    974 
    975 //Active object destructor
    976 OpenmaxMpeg4AO::~OpenmaxMpeg4AO()
    977 {
    978     if (IsAdded())
    979     {
    980         RemoveFromScheduler();
    981     }
    982 
    983     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : destructed"));
    984 }
    985 
    986 
    987 /** The Initialization function
    988  */
    989 OMX_ERRORTYPE OpenmaxMpeg4AO::ComponentInit()
    990 {
    991     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ComponentInit IN"));
    992 
    993     OMX_ERRORTYPE Status = OMX_ErrorNone;
    994 
    995     if (OMX_TRUE == iIsInit)
    996     {
    997         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ComponentInit error incorrect operation"));
    998         return OMX_ErrorIncorrectStateOperation;
    999     }
   1000     iIsInit = OMX_TRUE;
   1001 
   1002 
   1003     if (!iCodecReady)
   1004     {
   1005         //Call the init routine here in case of H263 mode, without waiting for buffers
   1006 
   1007         if (iDecMode == MODE_H263)
   1008         {
   1009             OMX_S32 Width, Height, Size = 0;
   1010             OMX_U8* Buff = NULL;
   1011 
   1012             //Pass dummy pointers during initializations
   1013             if (OMX_TRUE != ipMpegDecoderObject->InitializeVideoDecode(&Width, &Height, &Buff, &Size, iDecMode))
   1014             {
   1015                 Status = OMX_ErrorInsufficientResources;
   1016             }
   1017 
   1018             ipMpegDecoderObject->Mpeg4InitCompleteFlag = OMX_TRUE;
   1019         }
   1020         else
   1021         {
   1022             //mp4 lib init
   1023             Status = ipMpegDecoderObject->Mp4DecInit();
   1024         }
   1025 
   1026         iCodecReady = OMX_TRUE;
   1027     }
   1028 
   1029     iUseExtTimestamp = OMX_TRUE;
   1030     iInputCurrLength = 0;
   1031 
   1032     //Used in dynamic port reconfiguration
   1033     iFrameCount = 0;
   1034     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ComponentInit OUT"));
   1035 
   1036     return Status;
   1037 
   1038 }
   1039 
   1040 /** This function is called upon a transition to the idle or invalid state.
   1041  *  Also it is called by the ComponentDestructor() function
   1042  */
   1043 OMX_ERRORTYPE OpenmaxMpeg4AO::ComponentDeInit()
   1044 {
   1045     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ComponentDeInit IN"));
   1046 
   1047     OMX_ERRORTYPE Status = OMX_ErrorNone;
   1048 
   1049     iIsInit = OMX_FALSE;
   1050 
   1051     if (iCodecReady)
   1052     {
   1053         Status = ipMpegDecoderObject->Mp4DecDeinit();
   1054         iCodecReady = OMX_FALSE;
   1055     }
   1056 
   1057     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxMpeg4AO : ComponentDeInit OUT"));
   1058 
   1059     return Status;
   1060 
   1061 }
   1062 
   1063 OMX_ERRORTYPE OpenmaxMpeg4AO::GetConfig(
   1064     OMX_IN  OMX_HANDLETYPE hComponent,
   1065     OMX_IN  OMX_INDEXTYPE nIndex,
   1066     OMX_INOUT OMX_PTR pComponentConfigStructure)
   1067 {
   1068     OSCL_UNUSED_ARG(hComponent);
   1069     OSCL_UNUSED_ARG(nIndex);
   1070     OSCL_UNUSED_ARG(pComponentConfigStructure);
   1071     return OMX_ErrorNotImplemented;
   1072 }
   1073 
   1074 
   1075 OMX_ERRORTYPE OpenmaxMpeg4AO::ReAllocatePartialAssemblyBuffers(OMX_BUFFERHEADERTYPE* aInputBufferHdr)
   1076 {
   1077 
   1078     // check if there is enough data in the buffer to read the information that we need
   1079     if (aInputBufferHdr->nFilledLen >= MINIMUM_H263_SHORT_HEADER_SIZE)
   1080     {
   1081         OMX_U8 *pInputBuffer = (aInputBufferHdr->pBuffer + aInputBufferHdr->nOffset);
   1082 
   1083         if (MODE_H263 == iDecMode)
   1084         {
   1085             OMX_BOOL Status = OMX_TRUE;
   1086 
   1087             Status = DecodeH263Header(pInputBuffer, &iInputCurrBufferSize);
   1088 
   1089             // Re-allocate the partial frame buffer in case the stream is not corrupted,
   1090             // otherwise leave the buffer size as it is
   1091             if (OMX_TRUE == Status)
   1092             {
   1093                 if (NULL != ipInputCurrBuffer)
   1094                 {
   1095                     ipInputCurrBuffer = (OMX_U8*) oscl_realloc(ipInputCurrBuffer, iInputCurrBufferSize);
   1096                     if (NULL == ipInputCurrBuffer)
   1097                     {
   1098                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : DoStateSet error insufficient resources"));
   1099                         return OMX_ErrorInsufficientResources;
   1100                     }
   1101                 }
   1102 
   1103                 //Used when the buffers are not marked with EndOfFrame flag
   1104                 if (NULL != ipTempInputBuffer)
   1105                 {
   1106                     ipTempInputBuffer = (OMX_U8*) oscl_realloc(ipTempInputBuffer, iInputCurrBufferSize);
   1107                     if (NULL == ipTempInputBuffer)
   1108                     {
   1109                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : DoStateSet error insufficient resources"));
   1110                         return OMX_ErrorInsufficientResources;
   1111                     }
   1112                 }
   1113             }
   1114         }
   1115 
   1116         return OMX_ErrorNone;
   1117     }
   1118     else
   1119     {
   1120         return OMX_ErrorInsufficientResources;
   1121     }
   1122 
   1123 }
   1124 
   1125 OMX_BOOL OpenmaxMpeg4AO::DecodeH263Header(OMX_U8* aInputBuffer,
   1126         OMX_U32* aBufferSize)
   1127 {
   1128     uint32 codeword;
   1129     int32   extended_PTYPE = 0;
   1130     int32 UFEP = 0;
   1131     int32 custom_PFMT = 0;
   1132 
   1133     //Reset the data bit position to the start of the stream
   1134     iH263DataBitPos = 0;
   1135     iH263BitPos = 0;
   1136     //BitBuf contains the first 4 bytes of the aInputBuffer
   1137     iH263BitBuf = (aInputBuffer[0] << 24) | (aInputBuffer[1] << 16) | (aInputBuffer[2] << 8) | aInputBuffer[3];
   1138 
   1139     ReadBits(aInputBuffer, 22, &codeword);
   1140     if (codeword !=  0x20)
   1141     {
   1142         return OMX_FALSE;
   1143     }
   1144 
   1145     ReadBits(aInputBuffer, 8, &codeword);
   1146 
   1147     ReadBits(aInputBuffer, 1, &codeword);
   1148     if (codeword == 0) return OMX_FALSE;
   1149 
   1150     ReadBits(aInputBuffer, 1, &codeword);
   1151     if (codeword == 1) return OMX_FALSE;
   1152 
   1153     ReadBits(aInputBuffer, 1, &codeword);
   1154     if (codeword == 1) return OMX_FALSE;
   1155 
   1156     ReadBits(aInputBuffer, 1, &codeword);
   1157     if (codeword == 1) return OMX_FALSE;
   1158 
   1159     ReadBits(aInputBuffer, 1, &codeword);
   1160     if (codeword == 1) return OMX_FALSE;
   1161 
   1162     /* source format */
   1163     ReadBits(aInputBuffer, 3, &codeword);
   1164     switch (codeword)
   1165     {
   1166         case 1:
   1167             *aBufferSize = 32000;
   1168             break;
   1169 
   1170         case 2:
   1171             *aBufferSize = 32000;
   1172             break;
   1173 
   1174         case 3:
   1175             *aBufferSize = 128000;
   1176             break;
   1177 
   1178         case 4:
   1179             *aBufferSize = 256000;
   1180             break;
   1181 
   1182         case 5:
   1183             *aBufferSize = 512000;
   1184             break;
   1185 
   1186         case 7:
   1187             extended_PTYPE = 1;
   1188             break;
   1189         default:
   1190             /* Msg("H.263 source format not legal\n"); */
   1191             return OMX_FALSE;
   1192     }
   1193 
   1194     if (extended_PTYPE == 0)
   1195     {
   1196         return OMX_TRUE;
   1197     }
   1198 
   1199     /* source format */
   1200     ReadBits(aInputBuffer, 3, &codeword);
   1201     UFEP = codeword;
   1202     if (UFEP == 1)
   1203     {
   1204         ReadBits(aInputBuffer, 3, &codeword);
   1205         switch (codeword)
   1206         {
   1207             case 1:
   1208                 *aBufferSize = 32000;
   1209                 break;
   1210 
   1211             case 2:
   1212                 *aBufferSize = 32000;
   1213                 break;
   1214 
   1215             case 3:
   1216                 *aBufferSize = 128000;
   1217                 break;
   1218 
   1219             case 4:
   1220                 *aBufferSize = 256000;
   1221                 break;
   1222 
   1223             case 5:
   1224                 *aBufferSize = 512000;
   1225                 break;
   1226 
   1227             case 6:
   1228                 custom_PFMT = 1;
   1229                 break;
   1230             default:
   1231                 /* Msg("H.263 source format not legal\n"); */
   1232                 return OMX_FALSE;
   1233         }
   1234         if (custom_PFMT == 0)
   1235         {
   1236             return OMX_TRUE;
   1237         }
   1238 
   1239 
   1240         ReadBits(aInputBuffer, 1, &codeword);
   1241         ReadBits(aInputBuffer, 1, &codeword);
   1242         if (codeword) return OMX_FALSE;
   1243         ReadBits(aInputBuffer, 1, &codeword);
   1244         if (codeword) return OMX_FALSE;
   1245         ReadBits(aInputBuffer, 1, &codeword);
   1246         if (codeword) return OMX_FALSE;
   1247         ReadBits(aInputBuffer, 3, &codeword);
   1248         ReadBits(aInputBuffer, 3, &codeword);
   1249         if (codeword) return OMX_FALSE;             /* RPS, ISD, AIV */
   1250         ReadBits(aInputBuffer, 1, &codeword);
   1251         ReadBits(aInputBuffer, 4, &codeword);
   1252         if (codeword != 8) return OMX_FALSE;
   1253     }
   1254 
   1255     if (UFEP == 0 || UFEP == 1)
   1256     {
   1257         ReadBits(aInputBuffer, 3, &codeword);
   1258         if (codeword > 1) return OMX_FALSE;
   1259         ReadBits(aInputBuffer, 1, &codeword);
   1260         if (codeword) return OMX_FALSE;
   1261         ReadBits(aInputBuffer, 1, &codeword);
   1262         if (codeword) return OMX_FALSE;
   1263         ReadBits(aInputBuffer, 1, &codeword);
   1264         ReadBits(aInputBuffer, 3, &codeword);
   1265         if (codeword != 1) return OMX_FALSE;
   1266     }
   1267     else
   1268     {
   1269         return OMX_FALSE;
   1270     }
   1271 
   1272     ReadBits(aInputBuffer, 1, &codeword);
   1273     if (codeword) return OMX_FALSE; /* CPM */
   1274     if (custom_PFMT == 1 && UFEP == 1)
   1275     {
   1276         OMX_U32 DisplayWidth, Width, DisplayHeight, Height, Resolution;
   1277 
   1278         ReadBits(aInputBuffer, 4, &codeword);
   1279         if (codeword == 0) return OMX_FALSE;
   1280         if (codeword == 0xf)
   1281         {
   1282             ReadBits(aInputBuffer, 8, &codeword);
   1283             ReadBits(aInputBuffer, 8, &codeword);
   1284         }
   1285         ReadBits(aInputBuffer, 9, &codeword);
   1286         DisplayWidth = (codeword + 1) << 2;
   1287         Width = (DisplayWidth + 15) & -16;
   1288 
   1289         ReadBits(aInputBuffer, 1, &codeword);
   1290         if (codeword != 1) return OMX_FALSE;
   1291         ReadBits(aInputBuffer, 9, &codeword);
   1292         if (codeword == 0) return OMX_FALSE;
   1293         DisplayHeight = codeword << 2;
   1294         Height = (DisplayHeight + 15) & -16;
   1295 
   1296         Resolution = Width * Height;
   1297 
   1298         if (Resolution <= 25344)        //25344 = 176x144 (QCIF)
   1299         {
   1300             *aBufferSize = 32000;
   1301         }
   1302         else if (Resolution <= 101376)  //101376 = 352x288 (CIF)
   1303         {
   1304             *aBufferSize = 128000;
   1305         }
   1306         else if (Resolution <= 405504)  //405504 = 704*576 (4CIF)
   1307         {
   1308             *aBufferSize = 256000;
   1309         }
   1310         else                            //1408x1152 (16CIF)
   1311         {
   1312             //This is the max buffer size that we want to allocate
   1313             *aBufferSize = 512000;
   1314         }
   1315     }
   1316 
   1317     return OMX_TRUE;
   1318 }
   1319 
   1320 
   1321 void OpenmaxMpeg4AO::ReadBits(OMX_U8* aStream,           /* Input Stream */
   1322                               uint8 aNumBits,                     /* nr of bits to read */
   1323                               uint32* aOutData                 /* output target */
   1324                              )
   1325 {
   1326     uint8 *bits;
   1327     uint32 dataBitPos = iH263DataBitPos;
   1328     uint32 bitPos = iH263BitPos;
   1329     uint32 dataBytePos;
   1330 
   1331     if (aNumBits > (32 - bitPos))    /* not enough bits */
   1332     {
   1333         dataBytePos = dataBitPos >> 3;    /* Byte Aligned Position */
   1334         bitPos = dataBitPos & 7; /* update bit position */
   1335         bits = &aStream[dataBytePos];
   1336         iH263BitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
   1337     }
   1338 
   1339     iH263DataBitPos += aNumBits;
   1340     iH263BitPos      = (unsigned char)(bitPos + aNumBits);
   1341 
   1342     *aOutData = (iH263BitBuf >> (32 - iH263BitPos)) & mask[(uint16)aNumBits];
   1343 
   1344     return;
   1345 }
   1346 
   1347