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