| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #include "pv_omxdefs.h" |
| #include "oscl_types.h" |
| |
| #include <string.h> |
| #include "omx_aac_component.h" |
| |
| extern OMX_U32 g_ComponentIndex; // this is determined outside the component |
| |
| #if PROXY_INTERFACE |
| |
| #include "omx_proxy_interface.h" |
| extern ProxyApplication_OMX* pProxyTerm[]; |
| |
| #endif |
| |
| #define OMX_HALFRANGE_THRESHOLD 0x7FFFFFFF |
| |
| #define AAC_MONO_SILENCE_FRAME_SIZE 10 |
| #define AAC_STEREO_SILENCE_FRAME_SIZE 11 |
| |
| static const OMX_U8 AAC_MONO_SILENCE_FRAME[] = {0x01, 0x40, 0x20, 0x06, 0x4F, 0xDE, 0x02, 0x70, 0x0C, 0x1C}; // 10 bytes |
| static const OMX_U8 AAC_STEREO_SILENCE_FRAME[] = {0x21, 0x10, 0x05, 0x00, 0xA0, 0x19, 0x33, 0x87, 0xC0, 0x00, 0x7E}; // 11 bytes) |
| |
| // This function is called by OMX_GetHandle and it creates an instance of the aac component AO |
| OMX_ERRORTYPE AacOmxComponentFactory(OMX_OUT OMX_HANDLETYPE* pHandle, OMX_IN OMX_PTR pAppData) |
| { |
| OpenmaxAacAO* pOpenmaxAOType; |
| OMX_ERRORTYPE Status; |
| |
| // move InitAacOmxComponentFields content to actual constructor |
| |
| pOpenmaxAOType = (OpenmaxAacAO*) OSCL_NEW(OpenmaxAacAO, ()); |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| //Call the construct component to initialize OMX types |
| Status = pOpenmaxAOType->ConstructComponent(pAppData); |
| |
| *pHandle = pOpenmaxAOType->GetOmxHandle(); |
| |
| return Status; |
| /////////////////////////////////////////////////////////////////////////////////////// |
| } |
| |
| // This function is called by OMX_FreeHandle when component AO needs to be destroyed |
| OMX_ERRORTYPE AacOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle) |
| { |
| // get pointer to component AO |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate; |
| |
| // clean up decoder, OMX component stuff |
| pOpenmaxAOType->DestroyComponent(); |
| |
| // destroy the AO class |
| OSCL_DELETE(pOpenmaxAOType); |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| OMX_ERRORTYPE OpenmaxAacAO::ConstructComponent(OMX_PTR pAppData) |
| { |
| AacComponentPortType* pInPort, *pOutPort; |
| OMX_U32 ii; |
| |
| iNumPorts = 2; |
| iOmxComponent.nSize = sizeof(OMX_COMPONENTTYPE); |
| iOmxComponent.pComponentPrivate = (OMX_PTR) this; // pComponentPrivate points to THIS component AO class |
| iOmxComponent.pApplicationPrivate = pAppData; // init the App data |
| |
| |
| #if PROXY_INTERFACE |
| iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; |
| |
| iOmxComponent.SendCommand = WrapperSendCommand; |
| iOmxComponent.GetParameter = WrapperGetParameter; |
| iOmxComponent.SetParameter = WrapperSetParameter; |
| iOmxComponent.GetConfig = WrapperGetConfig; |
| iOmxComponent.SetConfig = WrapperSetConfig; |
| iOmxComponent.GetExtensionIndex = WrapperGetExtensionIndex; |
| iOmxComponent.GetState = WrapperGetState; |
| iOmxComponent.UseBuffer = WrapperUseBuffer; |
| iOmxComponent.AllocateBuffer = WrapperAllocateBuffer; |
| iOmxComponent.FreeBuffer = WrapperFreeBuffer; |
| iOmxComponent.EmptyThisBuffer = WrapperEmptyThisBuffer; |
| iOmxComponent.FillThisBuffer = WrapperFillThisBuffer; |
| |
| #else |
| iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_FALSE; |
| |
| iOmxComponent.SendCommand = OpenmaxAacAO::BaseComponentSendCommand; |
| iOmxComponent.GetParameter = OpenmaxAacAO::BaseComponentGetParameter; |
| iOmxComponent.SetParameter = OpenmaxAacAO::BaseComponentSetParameter; |
| iOmxComponent.GetConfig = OpenmaxAacAO::BaseComponentGetConfig; |
| iOmxComponent.SetConfig = OpenmaxAacAO::BaseComponentSetConfig; |
| iOmxComponent.GetExtensionIndex = OpenmaxAacAO::BaseComponentGetExtensionIndex; |
| iOmxComponent.GetState = OpenmaxAacAO::BaseComponentGetState; |
| iOmxComponent.UseBuffer = OpenmaxAacAO::BaseComponentUseBuffer; |
| iOmxComponent.AllocateBuffer = OpenmaxAacAO::BaseComponentAllocateBuffer; |
| iOmxComponent.FreeBuffer = OpenmaxAacAO::BaseComponentFreeBuffer; |
| iOmxComponent.EmptyThisBuffer = OpenmaxAacAO::BaseComponentEmptyThisBuffer; |
| iOmxComponent.FillThisBuffer = OpenmaxAacAO::BaseComponentFillThisBuffer; |
| #endif |
| |
| iOmxComponent.SetCallbacks = OpenmaxAacAO::BaseComponentSetCallbacks; |
| iOmxComponent.nVersion.s.nVersionMajor = SPECVERSIONMAJOR; |
| iOmxComponent.nVersion.s.nVersionMinor = SPECVERSIONMINOR; |
| iOmxComponent.nVersion.s.nRevision = SPECREVISION; |
| iOmxComponent.nVersion.s.nStep = SPECSTEP; |
| |
| // PV capability |
| iPVCapabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; |
| iPVCapabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; |
| iPVCapabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; |
| |
| if (ipAppPriv) |
| { |
| oscl_free(ipAppPriv); |
| ipAppPriv = NULL; |
| } |
| |
| ipAppPriv = (AacPrivateType*) oscl_malloc(sizeof(AacPrivateType)); |
| if (NULL == ipAppPriv) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| if (iNumPorts) |
| { |
| if (ipPorts) |
| { |
| oscl_free(ipPorts); |
| ipPorts = NULL; |
| } |
| |
| ipPorts = (AacComponentPortType**) oscl_calloc(iNumPorts, sizeof(AacComponentPortType*)); |
| if (!ipPorts) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| ipPorts[ii] = (AacComponentPortType*) oscl_calloc(1, sizeof(AacComponentPortType)); |
| if (!ipPorts[ii]) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| ipPorts[ii]->TransientState = OMX_StateMax; |
| SetHeader(&ipPorts[ii]->PortParam, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); |
| ipPorts[ii]->PortParam.nPortIndex = ii; |
| |
| /** Allocate and initialize buffer Queue */ |
| ipPorts[ii]->pBufferQueue = (QueueType*) oscl_malloc(sizeof(QueueType)); |
| |
| if (NULL == ipPorts[ii]->pBufferQueue) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| QueueInit(ipPorts[ii]->pBufferQueue); |
| |
| ipPorts[ii]->LoadedToIdleFlag = OMX_FALSE; |
| ipPorts[ii]->IdleToLoadedFlag = OMX_FALSE; |
| |
| } |
| |
| AacComponentSetPortFlushFlag(iNumPorts, -1, OMX_FALSE); |
| AacComponentSetNumBufferFlush(iNumPorts, -1, OMX_FALSE); |
| } |
| |
| /** Domain specific section for the ports. */ |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainAudio; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.audio.cMIMEType = "audio/mpeg"; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.audio.pNativeRender = 0; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.audio.bFlagErrorConcealment = OMX_FALSE; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.audio.eEncoding = OMX_AUDIO_CodingAAC; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDir = OMX_DirInput; |
| //Set to a default value, will change later during setparameter call |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_INPUT_BUFFER_AAC; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountMin = 1; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize = INPUT_BUFFER_SIZE_AAC; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE; |
| |
| |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainAudio; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.audio.cMIMEType = "raw"; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.audio.pNativeRender = 0; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.audio.bFlagErrorConcealment = OMX_FALSE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.audio.eEncoding = OMX_AUDIO_CodingPCM; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDir = OMX_DirOutput; |
| //Set to a default value, will change later during setparameter call |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_OUTPUT_BUFFER_AAC; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountMin = 1; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferSize = OUTPUT_BUFFER_SIZE_AAC * 6; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE; |
| |
| //Default values for AAC audio param port |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.nChannels = 2; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.nBitRate = 0; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.nSampleRate = 44100; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.nAudioBandWidth = 0; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.nFrameLength = 2048; // use HE_PS frame size as default |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.eChannelMode = OMX_AUDIO_ChannelModeStereo; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.eAACProfile = OMX_AUDIO_AACObjectHE_PS; //OMX_AUDIO_AACObjectLC; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS; |
| |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nChannels = 2; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.eNumData = OMX_NumericalDataSigned; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.bInterleaved = OMX_TRUE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nBitPerSample = 16; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nSamplingRate = 44100; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.ePCMMode = OMX_AUDIO_PCMModeLinear; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.eChannelMapping[0] = OMX_AUDIO_ChannelLF; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.eChannelMapping[1] = OMX_AUDIO_ChannelRF; |
| |
| iPortTypesParam.nPorts = 2; |
| iPortTypesParam.nStartPortNumber = 0; |
| |
| pInPort = (AacComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| pOutPort = (AacComponentPortType*) ipPorts[OMX_PORT_OUTPUTPORT_INDEX]; |
| |
| SetHeader(&pInPort->AudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); |
| pInPort->AudioParam.nPortIndex = 0; |
| pInPort->AudioParam.nIndex = 0; |
| pInPort->AudioParam.eEncoding = OMX_AUDIO_CodingAAC; |
| |
| SetHeader(&pOutPort->AudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); |
| pOutPort->AudioParam.nPortIndex = 1; |
| pOutPort->AudioParam.nIndex = 0; |
| pOutPort->AudioParam.eEncoding = OMX_AUDIO_CodingPCM; |
| |
| iCodecReady = OMX_FALSE; |
| ipCallbacks = NULL; |
| iCallbackData = NULL; |
| iState = OMX_StateLoaded; |
| ipTempInputBuffer = NULL; |
| iTempInputBufferLength = 0; |
| iNumInputBuffer = 0; |
| iPartialFrameAssembly = OMX_FALSE; |
| iEndofStream = OMX_FALSE; |
| iIsInputBufferEnded = OMX_TRUE; |
| iNewOutBufRequired = OMX_TRUE; |
| iOutputFrameLength = OUTPUT_BUFFER_SIZE_AAC; |
| iRepositionFlag = OMX_FALSE; |
| |
| /* Initialize the asynchronous command Queue */ |
| if (ipCoreDescriptor) |
| { |
| oscl_free(ipCoreDescriptor); |
| ipCoreDescriptor = NULL; |
| } |
| |
| ipCoreDescriptor = (CoreDescriptorType*) oscl_malloc(sizeof(CoreDescriptorType)); |
| if (NULL == ipCoreDescriptor) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| ipCoreDescriptor->pMessageQueue = NULL; |
| ipCoreDescriptor->pMessageQueue = (QueueType*) oscl_malloc(sizeof(QueueType)); |
| if (NULL == ipCoreDescriptor->pMessageQueue) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| QueueInit(ipCoreDescriptor->pMessageQueue); |
| |
| /** Default parameters setting */ |
| iIsInit = OMX_FALSE; |
| iGroupPriority = 0; |
| iGroupID = 0; |
| ipMark = NULL; |
| |
| SetHeader(&iPortTypesParam, sizeof(OMX_PORT_PARAM_TYPE)); |
| |
| iOutBufferCount = 0; |
| iStateTransitionFlag = OMX_FALSE; |
| iFlushPortFlag = OMX_FALSE; |
| iEndOfFrameFlag = OMX_FALSE; |
| iFirstFragment = OMX_FALSE; |
| |
| //Will be used in case of partial frame assembly |
| ipInputCurrBuffer = NULL; |
| ipAppPriv->AacHandle = &iOmxComponent; |
| |
| if (ipAacDec) |
| { |
| OSCL_DELETE(ipAacDec); |
| ipAacDec = NULL; |
| } |
| |
| ipAacDec = OSCL_NEW(OmxAacDecoder, ()); |
| if (NULL == ipAacDec) |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| oscl_memset(ipAacDec, 0, sizeof(OmxAacDecoder)); |
| |
| iSamplesPerFrame = AACDEC_PCM_FRAME_SAMPLE_SIZE; |
| iOutputMilliSecPerFrame = iCurrentFrameTS.GetFrameDuration(); |
| |
| #if PROXY_INTERFACE |
| |
| pProxyTerm[g_ComponentIndex]->ComponentSendCommand = BaseComponentSendCommand; |
| pProxyTerm[g_ComponentIndex]->ComponentGetParameter = BaseComponentGetParameter; |
| pProxyTerm[g_ComponentIndex]->ComponentSetParameter = BaseComponentSetParameter; |
| pProxyTerm[g_ComponentIndex]->ComponentGetConfig = BaseComponentGetConfig; |
| pProxyTerm[g_ComponentIndex]->ComponentSetConfig = BaseComponentSetConfig; |
| pProxyTerm[g_ComponentIndex]->ComponentGetExtensionIndex = BaseComponentGetExtensionIndex; |
| pProxyTerm[g_ComponentIndex]->ComponentGetState = BaseComponentGetState; |
| pProxyTerm[g_ComponentIndex]->ComponentUseBuffer = BaseComponentUseBuffer; |
| pProxyTerm[g_ComponentIndex]->ComponentAllocateBuffer = BaseComponentAllocateBuffer; |
| pProxyTerm[g_ComponentIndex]->ComponentFreeBuffer = BaseComponentFreeBuffer; |
| pProxyTerm[g_ComponentIndex]->ComponentEmptyThisBuffer = BaseComponentEmptyThisBuffer; |
| pProxyTerm[g_ComponentIndex]->ComponentFillThisBuffer = BaseComponentFillThisBuffer; |
| |
| #endif |
| return OMX_ErrorNone; |
| } |
| |
| |
| /********************* |
| * |
| * Component verfication routines |
| * |
| **********************/ |
| |
| void OpenmaxAacAO::SetHeader(OMX_PTR aHeader, OMX_U32 aSize) |
| { |
| OMX_VERSIONTYPE* pVersion = (OMX_VERSIONTYPE*)((OMX_STRING) aHeader + sizeof(OMX_U32)); |
| *((OMX_U32*) aHeader) = aSize; |
| |
| pVersion->s.nVersionMajor = SPECVERSIONMAJOR; |
| pVersion->s.nVersionMinor = SPECVERSIONMINOR; |
| pVersion->s.nRevision = SPECREVISION; |
| pVersion->s.nStep = SPECSTEP; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::CheckHeader(OMX_PTR aHeader, OMX_U32 aSize) |
| { |
| OMX_VERSIONTYPE* pVersion = (OMX_VERSIONTYPE*)((OMX_STRING) aHeader + sizeof(OMX_U32)); |
| |
| if (NULL == aHeader) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| if (*((OMX_U32*) aHeader) != aSize) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| if (pVersion->s.nVersionMajor != SPECVERSIONMAJOR || |
| pVersion->s.nVersionMinor != SPECVERSIONMINOR || |
| pVersion->s.nRevision != SPECREVISION || |
| pVersion->s.nStep != SPECSTEP) |
| { |
| return OMX_ErrorVersionMismatch; |
| } |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| /** |
| * This function verify component state and structure header |
| */ |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentParameterSanityCheck( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_PTR pStructure, |
| OMX_IN size_t size) |
| { |
| |
| if (iState != OMX_StateLoaded && |
| iState != OMX_StateWaitForResources) |
| { |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| if (nPortIndex >= iNumPorts) |
| { |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| return CheckHeader(pStructure, size); |
| } |
| |
| /** |
| * Set/Reset Port Flush Flag |
| */ |
| void OpenmaxAacAO::AacComponentSetPortFlushFlag(OMX_S32 NumPorts, OMX_S32 index, OMX_BOOL value) |
| { |
| OMX_S32 ii; |
| |
| if (-1 == index) |
| { |
| for (ii = 0; ii < NumPorts; ii++) |
| { |
| ipPorts[ii]->IsPortFlushed = value; |
| } |
| } |
| else |
| { |
| ipPorts[index]->IsPortFlushed = value; |
| } |
| |
| } |
| |
| /** |
| * Set Number of Buffer Flushed with the value Specified |
| */ |
| void OpenmaxAacAO::AacComponentSetNumBufferFlush(OMX_S32 NumPorts, OMX_S32 index, OMX_S32 value) |
| { |
| OMX_S32 ii; |
| |
| if (-1 == index) |
| { // For all ComponentPort |
| for (ii = 0; ii < NumPorts; ii++) |
| { |
| ipPorts[ii]->NumBufferFlushed = value; |
| } |
| } |
| else |
| { |
| ipPorts[index]->NumBufferFlushed = value; |
| } |
| } |
| |
| |
| /** This function assembles multiple input buffers into |
| * one frame with the marker flag OMX_BUFFERFLAG_ENDOFFRAME set |
| */ |
| |
| OMX_BOOL OpenmaxAacAO::AacComponentAssemblePartialFrames(OMX_BUFFERHEADERTYPE* aInputBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentAssemblePartialFrames IN")); |
| |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| |
| AacComponentPortType* pInPort = ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| |
| ipAacInputBuffer = aInputBuffer; |
| |
| if (!iPartialFrameAssembly) |
| { |
| if (iNumInputBuffer > 0) |
| { |
| if (ipAacInputBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) |
| { |
| iInputCurrLength = ipAacInputBuffer->nFilledLen; |
| ipFrameDecodeBuffer = ipAacInputBuffer->pBuffer + ipAacInputBuffer->nOffset; |
| //capture the timestamp to be send to the corresponding output buffer |
| iFrameTimestamp = ipAacInputBuffer->nTimeStamp; |
| } |
| else |
| { |
| iInputCurrLength = 0; |
| iPartialFrameAssembly = OMX_TRUE; |
| iFirstFragment = OMX_TRUE; |
| iFrameTimestamp = ipAacInputBuffer->nTimeStamp; |
| ipFrameDecodeBuffer = ipInputCurrBuffer; |
| } |
| |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentAssemblePartialFrames ERROR")); |
| return OMX_FALSE; |
| } |
| |
| } |
| |
| //Assembling of partial frame will be done based on OMX_BUFFERFLAG_ENDOFFRAME flag marked |
| if (iPartialFrameAssembly) |
| { |
| while (iNumInputBuffer > 0) |
| { |
| if (OMX_FALSE == iFirstFragment) |
| { |
| /* If the timestamp of curr fragment doesn't match with previous, |
| * discard the previous fragments & start reconstructing from new |
| */ |
| if (iFrameTimestamp != ipAacInputBuffer->nTimeStamp) |
| { |
| iInputCurrLength = 0; |
| iPartialFrameAssembly = OMX_TRUE; |
| iFirstFragment = OMX_TRUE; |
| iFrameTimestamp = ipAacInputBuffer->nTimeStamp; |
| ipFrameDecodeBuffer = ipInputCurrBuffer; |
| } |
| } |
| |
| if ((ipAacInputBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) != 0) |
| { |
| break; |
| } |
| |
| iInputCurrLength += ipAacInputBuffer->nFilledLen; |
| oscl_memcpy(ipFrameDecodeBuffer, (ipAacInputBuffer->pBuffer + ipAacInputBuffer->nOffset), ipAacInputBuffer->nFilledLen); // copy buffer data |
| ipFrameDecodeBuffer += ipAacInputBuffer->nFilledLen; // move the ptr |
| |
| ipAacInputBuffer->nFilledLen = 0; |
| |
| AacComponentReturnInputBuffer(ipAacInputBuffer, pInPort); |
| |
| iFirstFragment = OMX_FALSE; |
| |
| if (iNumInputBuffer > 0) |
| { |
| ipAacInputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pInputQueue); |
| if (ipAacInputBuffer->nFlags & OMX_BUFFERFLAG_EOS) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentAssemblePartialFrames EndOfStream arrived")); |
| iEndofStream = OMX_TRUE; |
| } |
| } |
| } |
| |
| // if we broke out of the while loop because of lack of buffers, then return and wait for more input buffers |
| if (0 == iNumInputBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentAssemblePartialFrames OUT")); |
| return OMX_FALSE; |
| } |
| else |
| { |
| // we have found the buffer that is the last piece of the frame. |
| // Copy the buffer, but do not release it yet (this will be done after decoding for consistency) |
| |
| iInputCurrLength += ipAacInputBuffer->nFilledLen; |
| oscl_memcpy(ipFrameDecodeBuffer, (ipAacInputBuffer->pBuffer + ipAacInputBuffer->nOffset), ipAacInputBuffer->nFilledLen); // copy buffer data |
| ipFrameDecodeBuffer += ipAacInputBuffer->nFilledLen; // move the ptr |
| |
| ipFrameDecodeBuffer = ipInputCurrBuffer; // reset the pointer back to beginning of assembly buffer |
| iPartialFrameAssembly = OMX_FALSE; // we have finished with assembling the frame, so this is not needed any more |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentAssemblePartialFrames OUT")); |
| return OMX_TRUE; |
| } |
| |
| |
| /** This is the central function for buffers processing and decoding. |
| * It is called through the Run() of active object when the component is in executing state |
| * and is signalled each time a new buffer is available on the given ports |
| * This function will process the input buffers & return output buffers |
| */ |
| |
| void OpenmaxAacAO::AacComponentBufferMgmtFunction() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentBufferMgmtFunction IN")); |
| |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| AacComponentPortType* pInPort = (AacComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| |
| OMX_BOOL PartialFrameReturn, Status; |
| OMX_AUDIO_AACSTREAMFORMATTYPE InFormat = ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.eAACStreamFormat; |
| |
| /* Don't dequeue any further buffer after endofstream buffer has been dequeued |
| * till we send the callback and reset the flag back to false |
| */ |
| if (OMX_FALSE == iEndofStream) |
| { |
| //More than one frame can't be dequeued in case of outbut blocked |
| if ((OMX_TRUE == iIsInputBufferEnded) && (GetQueueNumElem(pInputQueue) > 0)) |
| { |
| ipAacInputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pInputQueue); |
| |
| if (ipAacInputBuffer->nFlags & OMX_BUFFERFLAG_EOS) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentBufferMgmtFunction EndOfStream arrived")); |
| iEndofStream = OMX_TRUE; |
| } |
| |
| if (ipAacInputBuffer->nFilledLen != 0) |
| { |
| if (0 == iFrameCount) |
| { |
| //Set the marker flag (iEndOfFrameFlag) if first frame has the EndOfFrame flag marked. |
| if (ipAacInputBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentBufferMgmtFunction EndOfFrame flag present")); |
| iEndOfFrameFlag = OMX_TRUE; |
| } |
| //Get the initial default value for the milli seconds per frame |
| iOutputMilliSecPerFrame = iCurrentFrameTS.GetFrameDuration(); |
| } |
| |
| /* This condition will be true if OMX_BUFFERFLAG_ENDOFFRAME flag is |
| * not marked in all the input buffers |
| */ |
| if (!iEndOfFrameFlag) |
| { |
| Status = AacBufferMgmtWithoutMarker(ipAacInputBuffer); |
| if (OMX_FALSE == Status) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentBufferMgmtFunction OUT")); |
| return; |
| } |
| |
| } |
| //If OMX_BUFFERFLAG_ENDOFFRAME flag is marked, come here |
| else |
| { |
| PartialFrameReturn = AacComponentAssemblePartialFrames(ipAacInputBuffer); |
| if (OMX_FALSE == PartialFrameReturn) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentBufferMgmtFunction OUT")); |
| return; |
| } |
| iIsInputBufferEnded = OMX_FALSE; |
| } |
| |
| ipTargetComponent = (OMX_COMPONENTTYPE*) ipAacInputBuffer->hMarkTargetComponent; |
| |
| iTargetMarkData = ipAacInputBuffer->pMarkData; |
| if (ipTargetComponent == (OMX_COMPONENTTYPE*) pHandle) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventMark, |
| 1, |
| 0, |
| ipAacInputBuffer->pMarkData); |
| } |
| |
| //Do not check for silence insertion if the clip is repositioned |
| if (OMX_FALSE == iRepositionFlag) |
| { |
| CheckForSilenceInsertion(); |
| } |
| |
| |
| /* Set the current timestamp equal to input buffer timestamp in case of |
| * a) first frame for ADIF format |
| * b) All input frames for other formats |
| * c) First frame after repositioning */ |
| if (OMX_FALSE == iSilenceInsertionInProgress) |
| { |
| if ((0 == iFrameCount) || (iFrameCount > 0 && OMX_AUDIO_AACStreamFormatADIF != InFormat) |
| || (OMX_TRUE == iRepositionFlag)) |
| { |
| iCurrentFrameTS.SetFromInputTimestamp(iFrameTimestamp); |
| |
| //Reset the flag back to false, once timestamp has been updated from input frame |
| if (OMX_TRUE == iRepositionFlag) |
| { |
| iRepositionFlag = OMX_FALSE; |
| } |
| } |
| } |
| |
| } //end braces for if (ipAacInputBuffer->nFilledLen != 0) |
| else |
| { |
| AacComponentReturnInputBuffer(ipAacInputBuffer, pInPort); |
| } |
| |
| } //end braces for if ((OMX_TRUE == iIsInputBufferEnded) && (GetQueueNumElem(pInputQueue) > 0)) |
| } //if (OMX_FALSE == iEndofStream) |
| |
| AacDecode(); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentBufferMgmtFunction OUT")); |
| return; |
| } |
| |
| |
| OMX_BOOL OpenmaxAacAO::AacBufferMgmtWithoutMarker(OMX_BUFFERHEADERTYPE* pAacInputBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacBufferMgmtWithoutMarker IN")); |
| |
| AacComponentPortType* pInPort = (AacComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| |
| ipAacInputBuffer = pAacInputBuffer; |
| |
| /* Assembling of partial frame will be done based on max input buf size |
| * If Flushport flag is true, that means its not a partial frame |
| * but an unconsumed frame, process it independently |
| * Same is true for endofstream condition, process the buffer independently |
| */ |
| if ((ipAacInputBuffer->nFilledLen < ipAacInputBuffer->nAllocLen) |
| && (iEndofStream != OMX_TRUE) && (OMX_FALSE == iFlushPortFlag)) |
| { |
| if (!iPartialFrameAssembly) |
| { |
| iInputCurrLength = 0; |
| ipFrameDecodeBuffer = ipInputCurrBuffer; |
| } |
| |
| while (iNumInputBuffer > 0) |
| { |
| oscl_memcpy(ipFrameDecodeBuffer, (ipAacInputBuffer->pBuffer + ipAacInputBuffer->nOffset), ipAacInputBuffer->nFilledLen); |
| ipFrameDecodeBuffer += ipAacInputBuffer->nFilledLen; // move the ptr |
| |
| iFrameTimestamp = ipAacInputBuffer->nTimeStamp; |
| |
| if (((iInputCurrLength += ipAacInputBuffer->nFilledLen) >= ipAacInputBuffer->nAllocLen) |
| || OMX_TRUE == iEndofStream) |
| { |
| break; |
| } |
| |
| //Set the filled len to zero to indiacte buffer is fully consumed |
| ipAacInputBuffer->nFilledLen = 0; |
| AacComponentReturnInputBuffer(ipAacInputBuffer, pInPort); |
| |
| if (iNumInputBuffer > 0) |
| { |
| ipAacInputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pInputQueue); |
| if (ipAacInputBuffer->nFlags & OMX_BUFFERFLAG_EOS) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacBufferMgmtWithoutMarker EndOfStream arrived")); |
| iEndofStream = OMX_TRUE; |
| } |
| } |
| } |
| |
| if (((iInputCurrLength < ipAacInputBuffer->nAllocLen)) && OMX_TRUE != iEndofStream) |
| { |
| iPartialFrameAssembly = OMX_TRUE; |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacBufferMgmtWithoutMarker OUT")); |
| return OMX_FALSE; |
| } |
| else |
| { |
| ipFrameDecodeBuffer = ipInputCurrBuffer; |
| iPartialFrameAssembly = OMX_FALSE; |
| iIsInputBufferEnded = OMX_FALSE; |
| } |
| } |
| else |
| { |
| if (iNumInputBuffer > 0) |
| { |
| iInputCurrLength = ipAacInputBuffer->nFilledLen; |
| ipFrameDecodeBuffer = ipAacInputBuffer->pBuffer + ipAacInputBuffer->nOffset; |
| iFrameTimestamp = ipAacInputBuffer->nTimeStamp; |
| iIsInputBufferEnded = OMX_FALSE; |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacBufferMgmtWithoutMarker OUT")); |
| return OMX_FALSE; // nothing to decode |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacBufferMgmtWithoutMarker OUT")); |
| return OMX_TRUE; |
| |
| } |
| |
| |
| void OpenmaxAacAO::AacDecode() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacDecodeWithoutMarker IN")); |
| |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue; |
| |
| AacComponentPortType* pInPort = (AacComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| AacComponentPortType* pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]; |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| |
| OMX_U8* pOutBuffer; |
| OMX_U32 OutputLength; |
| OMX_S32 DecodeReturn; |
| OMX_BOOL ResizeNeeded = OMX_FALSE; |
| |
| OMX_U32 TempInputBufferSize = (2 * sizeof(uint8) * (ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize)); |
| |
| |
| if ((!iIsInputBufferEnded) || iEndofStream) |
| { |
| if (OMX_TRUE == iSilenceInsertionInProgress) |
| { |
| DoSilenceInsertion(); |
| //If the flag is still true, come back to this routine again |
| if (OMX_TRUE == iSilenceInsertionInProgress) |
| { |
| return; |
| } |
| } |
| |
| //Check whether prev output bufer has been released or not |
| if (OMX_TRUE == iNewOutBufRequired) |
| { |
| //Check whether a new output buffer is available or not |
| if (0 == (GetQueueNumElem(pOutputQueue))) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacDecodeWithoutMarker OUT output buffer unavailable")); |
| return; |
| } |
| |
| ipAacOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue); |
| ipAacOutputBuffer->nFilledLen = 0; |
| iNewOutBufRequired = OMX_FALSE; |
| |
| //Set the current timestamp to the output buffer timestamp |
| ipAacOutputBuffer->nTimeStamp = iCurrentFrameTS.GetConvertedTs(); |
| } |
| |
| /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer |
| * command and hMarkTargetComponent as given by the specifications |
| */ |
| if (ipMark != NULL) |
| { |
| ipAacOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent; |
| ipAacOutputBuffer->pMarkData = ipMark->pMarkData; |
| ipMark = NULL; |
| } |
| |
| if (ipTargetComponent != NULL) |
| { |
| ipAacOutputBuffer->hMarkTargetComponent = ipTargetComponent; |
| ipAacOutputBuffer->pMarkData = iTargetMarkData; |
| ipTargetComponent = NULL; |
| |
| } |
| //Mark buffer code ends here |
| |
| pOutBuffer = &ipAacOutputBuffer->pBuffer[ipAacOutputBuffer->nFilledLen]; |
| OutputLength = 0; |
| |
| /* Copy the left-over data from last input buffer that is stored in temporary |
| * buffer to the next incoming buffer. |
| */ |
| if (iTempInputBufferLength > 0 && |
| ((iInputCurrLength + iTempInputBufferLength) < TempInputBufferSize)) |
| { |
| oscl_memcpy(&ipTempInputBuffer[iTempInputBufferLength], ipFrameDecodeBuffer, iInputCurrLength); |
| iInputCurrLength += iTempInputBufferLength; |
| iTempInputBufferLength = 0; |
| ipFrameDecodeBuffer = ipTempInputBuffer; |
| } |
| |
| //Output buffer is passed as a short pointer |
| DecodeReturn = ipAacDec->AacDecodeFrames((OMX_S16*) pOutBuffer, |
| (OMX_U32*) & OutputLength, |
| &(ipFrameDecodeBuffer), |
| &iInputCurrLength, |
| &iFrameCount, |
| &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode), |
| &(ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam), |
| &iSamplesPerFrame, |
| &ResizeNeeded); |
| |
| if (ResizeNeeded == OMX_TRUE) |
| { |
| if (0 != OutputLength) |
| { |
| iOutputFrameLength = OutputLength * 2; |
| //In case of mono files keep the frame boundary more because decoder tries to write something beyond that level also |
| if (1 == ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nChannels) |
| { |
| iOutputFrameLength *= 2; |
| } |
| |
| iCurrentFrameTS.SetParameters(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nSamplingRate, iSamplesPerFrame); |
| iOutputMilliSecPerFrame = iCurrentFrameTS.GetFrameDuration(); |
| //Set the current timestamp to the output buffer timestamp for the first output frame |
| //Later it will be done at the time of dequeue |
| //(reason here is that at the time of dequeue, output buffer timestamp was equal to timestamp of config input buffer, not the first input buffer) |
| ipAacOutputBuffer->nTimeStamp = iCurrentFrameTS.GetConvertedTs(); |
| } |
| |
| // send port settings changed event |
| OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*) ipAppPriv->AacHandle; |
| |
| iResizePending = OMX_TRUE; |
| |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventPortSettingsChanged, //The command was completed |
| OMX_PORT_OUTPUTPORT_INDEX, |
| 0, |
| NULL); |
| } |
| |
| |
| //Output length for a buffer of OMX_U8* will be double as that of OMX_S16* |
| ipAacOutputBuffer->nFilledLen += OutputLength * 2; |
| //offset not required in our case, set it to zero |
| ipAacOutputBuffer->nOffset = 0; |
| |
| if (OutputLength > 0) |
| { |
| iCurrentFrameTS.UpdateTimestamp(iSamplesPerFrame); |
| } |
| |
| /* If EOS flag has come from the client & there are no more |
| * input buffers to decode, send the callback to the client |
| */ |
| if (OMX_TRUE == iEndofStream) |
| { |
| if ((0 == iInputCurrLength) || (MP4AUDEC_SUCCESS != DecodeReturn)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacDecodeWithoutMarker EOS callback send")); |
| |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventBufferFlag, |
| 1, |
| OMX_BUFFERFLAG_EOS, |
| NULL); |
| |
| iEndofStream = OMX_FALSE; |
| |
| ipAacOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS; |
| |
| AacComponentReturnOutputBuffer(ipAacOutputBuffer, pOutPort); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacDecodeWithoutMarker OUT")); |
| |
| return; |
| } |
| } |
| |
| |
| if (MP4AUDEC_SUCCESS == DecodeReturn) |
| { |
| ipAacInputBuffer->nFilledLen = iInputCurrLength; |
| } |
| else if (MP4AUDEC_INCOMPLETE_FRAME == DecodeReturn) |
| { |
| /* If decoder returns MP4AUDEC_INCOMPLETE_FRAME, |
| * this indicates the input buffer contains less than a frame data that |
| * can't be processed by the decoder. |
| * Copy it to a temp buffer to be used in next decode call |
| */ |
| oscl_memcpy(ipTempInputBuffer, ipFrameDecodeBuffer, iInputCurrLength); |
| iTempInputBufferLength = iInputCurrLength; |
| ipAacInputBuffer->nFilledLen = 0; |
| iInputCurrLength = 0; |
| } |
| else |
| { |
| //bitstream error, discard the current data as it can't be decoded further |
| ipAacInputBuffer->nFilledLen = 0; |
| |
| //Report it to the client via a callback |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacDecodeWithoutMarker ErrorStreamCorrupt callback send")); |
| |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventError, |
| OMX_ErrorStreamCorrupt, |
| 0, |
| NULL); |
| |
| } |
| |
| //Return the input buffer if it has been consumed fully by the decoder |
| if (0 == ipAacInputBuffer->nFilledLen) |
| { |
| AacComponentReturnInputBuffer(ipAacInputBuffer, pInPort); |
| iIsInputBufferEnded = OMX_TRUE; |
| } |
| |
| //Send the output buffer back when it has become full |
| if (((ipAacOutputBuffer->nAllocLen - ipAacOutputBuffer->nFilledLen) < (iOutputFrameLength)) |
| || (OMX_TRUE == ResizeNeeded)) |
| { |
| AacComponentReturnOutputBuffer(ipAacOutputBuffer, pOutPort); |
| } |
| |
| /* If there is some more processing left with current buffers, re-schedule the AO |
| * Do not go for more than one round of processing at a time. |
| * This may block the AO longer than required. |
| */ |
| if ((ipAacInputBuffer->nFilledLen != 0 || GetQueueNumElem(pInputQueue) > 0) |
| && (GetQueueNumElem(pOutputQueue) > 0) || (OMX_FALSE == iNewOutBufRequired) |
| && (ResizeNeeded == OMX_FALSE)) |
| { |
| RunIfNotReady(); |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacDecodeWithoutMarker OUT")); |
| return; |
| } |
| |
| void OpenmaxAacAO::AacComponentReturnInputBuffer(OMX_BUFFERHEADERTYPE* pAacInputBuffer, AacComponentPortType *pPort) |
| { |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| |
| if (iNumInputBuffer) |
| { |
| iNumInputBuffer--; |
| } |
| |
| //Callback for releasing the input buffer |
| (*(ipCallbacks->EmptyBufferDone)) |
| (pHandle, iCallbackData, pAacInputBuffer); |
| |
| pAacInputBuffer = NULL; |
| |
| } |
| |
| /** |
| * Returns Output Buffer back to the IL client |
| */ |
| void OpenmaxAacAO::AacComponentReturnOutputBuffer(OMX_BUFFERHEADERTYPE* pAacOutputBuffer, |
| AacComponentPortType *pPort) |
| { |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| |
| //Callback for sending back the output buffer |
| (*(ipCallbacks->FillBufferDone)) |
| (pHandle, iCallbackData, pAacOutputBuffer); |
| |
| if (iOutBufferCount) |
| { |
| iOutBufferCount--; |
| } |
| |
| pPort->NumBufferFlushed++; |
| iNewOutBufRequired = OMX_TRUE; |
| } |
| |
| /** The panic function that exits from the application. |
| */ |
| OMX_S32 OpenmaxAacAO::AacComponentPanic() |
| { |
| OSCL_ASSERT(false); |
| OsclError::Panic("PVERROR", OsclErrGeneral); |
| return 0; |
| } |
| |
| |
| /** Flushes all the buffers under processing by the given port. |
| * This function is called due to a state change of the component, typically |
| * @param Component the component which owns the port to be flushed |
| * @param PortIndex the ID of the port to be flushed |
| */ |
| |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentFlushPort(OMX_S32 PortIndex) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentFlushPort IN")); |
| |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue; |
| |
| OMX_BUFFERHEADERTYPE* pOutputBuff; |
| OMX_BUFFERHEADERTYPE* pInputBuff; |
| |
| if (OMX_PORT_INPUTPORT_INDEX == PortIndex || OMX_PORT_ALLPORT_INDEX == PortIndex) |
| { |
| while ((GetQueueNumElem(pInputQueue) > 0)) |
| { |
| pInputBuff = (OMX_BUFFERHEADERTYPE*) DeQueue(pInputQueue); |
| (*(ipCallbacks->EmptyBufferDone)) |
| (pHandle, iCallbackData, pInputBuff); |
| iNumInputBuffer--; |
| } |
| |
| if (ipAacInputBuffer && (OMX_FALSE == iIsInputBufferEnded)) |
| { |
| (*(ipCallbacks->EmptyBufferDone)) |
| (pHandle, iCallbackData, ipAacInputBuffer); |
| iNumInputBuffer--; |
| |
| iIsInputBufferEnded = OMX_TRUE; |
| ipAacDec->iInputUsedLength = 0; |
| } |
| |
| } |
| |
| if (OMX_PORT_OUTPUTPORT_INDEX == PortIndex || OMX_PORT_ALLPORT_INDEX == PortIndex) |
| { |
| if ((OMX_FALSE == iNewOutBufRequired) && (iOutBufferCount > 0)) |
| { |
| if (ipAacOutputBuffer) |
| { |
| (*(ipCallbacks->FillBufferDone)) |
| (pHandle, iCallbackData, ipAacOutputBuffer); |
| iOutBufferCount--; |
| iNewOutBufRequired = OMX_TRUE; |
| } |
| } |
| |
| |
| while ((GetQueueNumElem(pOutputQueue) > 0)) |
| { |
| pOutputBuff = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue); |
| pOutputBuff->nFilledLen = 0; |
| (*(ipCallbacks->FillBufferDone)) |
| (pHandle, iCallbackData, pOutputBuff); |
| iOutBufferCount--; |
| } |
| |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentFlushPort OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| |
| /** This function is called by the omx core when the component |
| * is disposed by the IL client with a call to FreeHandle(). |
| * \param Component, the component to be disposed |
| */ |
| |
| OMX_ERRORTYPE OpenmaxAacAO::DestroyComponent() |
| { |
| OMX_U32 ii; |
| |
| if (iIsInit != OMX_FALSE) |
| { |
| AacComponentDeInit(); |
| } |
| |
| /*Deinitialize and free ports semaphores and Queue*/ |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (ipPorts[ii]->pBufferQueue != NULL) |
| { |
| QueueDeinit(ipPorts[ii]->pBufferQueue); |
| oscl_free(ipPorts[ii]->pBufferQueue); |
| ipPorts[ii]->pBufferQueue = NULL; |
| } |
| /*Free port*/ |
| if (ipPorts[ii] != NULL) |
| { |
| oscl_free(ipPorts[ii]); |
| ipPorts[ii] = NULL; |
| } |
| } |
| |
| if (ipPorts) |
| { |
| oscl_free(ipPorts); |
| ipPorts = NULL; |
| } |
| |
| iState = OMX_StateLoaded; |
| |
| if (ipInputCurrBuffer) |
| { |
| oscl_free(ipInputCurrBuffer); |
| ipInputCurrBuffer = NULL; |
| } |
| |
| if (ipTempInputBuffer) |
| { |
| oscl_free(ipTempInputBuffer); |
| ipTempInputBuffer = NULL; |
| } |
| |
| if (ipAacDec) |
| { |
| OSCL_DELETE(ipAacDec); |
| ipAacDec = NULL; |
| } |
| |
| if (ipCoreDescriptor != NULL) |
| { |
| |
| if (ipCoreDescriptor->pMessageQueue != NULL) |
| { |
| /* De-initialize the asynchronous command queue */ |
| QueueDeinit(ipCoreDescriptor->pMessageQueue); |
| oscl_free(ipCoreDescriptor->pMessageQueue); |
| ipCoreDescriptor->pMessageQueue = NULL; |
| } |
| |
| oscl_free(ipCoreDescriptor); |
| ipCoreDescriptor = NULL; |
| } |
| |
| if (ipAppPriv) |
| { |
| ipAppPriv->AacHandle = NULL; |
| |
| oscl_free(ipAppPriv); |
| ipAppPriv = NULL; |
| } |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| /** |
| * Disable Single Port |
| */ |
| void OpenmaxAacAO::AacComponentDisableSinglePort(OMX_U32 PortIndex) |
| { |
| ipPorts[PortIndex]->PortParam.bEnabled = OMX_FALSE; |
| |
| if (PORT_IS_POPULATED(ipPorts[PortIndex]) && OMX_TRUE == iIsInit) |
| { |
| if (OMX_FALSE == ipPorts[PortIndex]->IdleToLoadedFlag) |
| { |
| iStateTransitionFlag = OMX_TRUE; |
| return; |
| } |
| else |
| { |
| ipPorts[PortIndex]->PortParam.bPopulated = OMX_FALSE; |
| } |
| } |
| |
| ipPorts[PortIndex]->NumBufferFlushed = 0; |
| } |
| |
| |
| /** Disables the specified port. This function is called due to a request by the IL client |
| * @param Component the component which owns the port to be disabled |
| * @param PortIndex the ID of the port to be disabled |
| */ |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentDisablePort(OMX_S32 PortIndex) |
| { |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDisablePort IN")); |
| OMX_U32 ii; |
| |
| if (-1 == PortIndex) |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| ipPorts[ii]->IsPortFlushed = OMX_TRUE; |
| } |
| |
| /*Flush all ports*/ |
| AacComponentFlushPort(PortIndex); |
| |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| ipPorts[ii]->IsPortFlushed = OMX_FALSE; |
| } |
| } |
| else |
| { |
| /*Flush the port specified*/ |
| ipPorts[PortIndex]->IsPortFlushed = OMX_TRUE; |
| AacComponentFlushPort(PortIndex); |
| ipPorts[PortIndex]->IsPortFlushed = OMX_FALSE; |
| } |
| |
| /*Disable ports*/ |
| if (PortIndex != -1) |
| { |
| AacComponentDisableSinglePort(PortIndex); |
| } |
| else |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| AacComponentDisableSinglePort(ii); |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDisablePort OUT")); |
| |
| return OMX_ErrorNone; |
| } |
| |
| /** |
| * Enable Single Port |
| */ |
| void OpenmaxAacAO::AacComponentEnableSinglePort(OMX_U32 PortIndex) |
| { |
| ipPorts[PortIndex]->PortParam.bEnabled = OMX_TRUE; |
| |
| if (!PORT_IS_POPULATED(ipPorts[PortIndex]) && OMX_TRUE == iIsInit) |
| { |
| if (OMX_FALSE == ipPorts[PortIndex]->LoadedToIdleFlag) |
| { |
| iStateTransitionFlag = OMX_TRUE; |
| return; |
| } |
| else |
| { |
| ipPorts[PortIndex]->PortParam.bPopulated = OMX_TRUE; |
| } |
| } |
| } |
| |
| /** Enables the specified port. This function is called due to a request by the IL client |
| * @param Component the component which owns the port to be enabled |
| * @param PortIndex the ID of the port to be enabled |
| */ |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentEnablePort(OMX_S32 PortIndex) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentEnablePort IN")); |
| |
| OMX_U32 ii; |
| |
| /*Enable port/s*/ |
| if (PortIndex != -1) |
| { |
| AacComponentEnableSinglePort(PortIndex); |
| } |
| else |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| AacComponentEnableSinglePort(ii); |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentEnablePort OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| //Not implemented & supported in case of base profile components |
| |
| void OpenmaxAacAO::AacComponentGetRolesOfComponent(OMX_STRING* aRoleString) |
| { |
| *aRoleString = "audio_decoder.aac"; |
| } |
| |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentTunnelRequest( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_U32 nPort, |
| OMX_IN OMX_HANDLETYPE hTunneledComp, |
| OMX_IN OMX_U32 nTunneledPort, |
| OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) |
| { |
| return OMX_ErrorNotImplemented; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentGetConfig( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nIndex, |
| OMX_INOUT OMX_PTR pComponentConfigStructure) |
| { |
| return OMX_ErrorNotImplemented; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentSetConfig( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nIndex, |
| OMX_IN OMX_PTR pComponentConfigStructure) |
| { |
| return OMX_ErrorNotImplemented; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentGetExtensionIndex( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_STRING cParameterName, |
| OMX_OUT OMX_INDEXTYPE* pIndexType) |
| { |
| return OMX_ErrorNotImplemented; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentGetState( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_OUT OMX_STATETYPE* pState) |
| { |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| |
| pOpenmaxAOType->GetState(pState); |
| |
| return OMX_ErrorNone; |
| } |
| |
| void OpenmaxAacAO::GetState(OMX_OUT OMX_STATETYPE* pState) |
| { |
| *pState = iState; |
| } |
| |
| |
| |
| //Active object constructor |
| OpenmaxAacAO::OpenmaxAacAO() : |
| OsclActiveObject(OsclActiveObject::EPriorityNominal, "OMXAacDec") |
| { |
| |
| iLogger = PVLogger::GetLoggerObject("PVMFOMXAudioDecNode"); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : constructed")); |
| |
| //Flag to call BufferMgmtFunction in the Run() when the component state is executing |
| iBufferExecuteFlag = OMX_FALSE; |
| ipAppPriv = NULL; |
| //iLogger = NULL; |
| |
| ipCallbacks = NULL; |
| iCallbackData = NULL; |
| iState = OMX_StateLoaded; |
| |
| |
| ipCoreDescriptor = NULL; |
| iNumInputBuffer = 0; |
| |
| ipFrameDecodeBuffer = NULL; |
| iPartialFrameAssembly = OMX_FALSE; |
| iIsInputBufferEnded = OMX_TRUE; |
| iEndofStream = OMX_FALSE; |
| ipTempInputBuffer = NULL; |
| |
| |
| ipTargetComponent = NULL; |
| iTargetMarkData = NULL; |
| iNewOutBufRequired = OMX_TRUE; |
| |
| iTempConsumedLength = 0; |
| iOutBufferCount = 0; |
| iCodecReady = OMX_FALSE; |
| ipInputCurrBuffer = NULL; |
| iInputCurrLength = 0; |
| iFrameCount = 0; |
| iStateTransitionFlag = OMX_FALSE; |
| iFlushPortFlag = OMX_FALSE; |
| iEndOfFrameFlag = OMX_FALSE; |
| ipAacInputBuffer = NULL; |
| ipAacOutputBuffer = NULL; |
| |
| |
| iFirstFragment = OMX_FALSE; |
| iResizePending = OMX_FALSE; |
| |
| iFrameTimestamp = 0; |
| iSilenceInsertionInProgress = OMX_FALSE; |
| |
| iNumPorts = 0; |
| ipPorts = NULL; |
| |
| //Indicate whether component has been already initialized */ |
| iIsInit = OMX_FALSE; |
| |
| iGroupPriority = 0; |
| iGroupID = 0; |
| |
| ipMark = NULL; |
| |
| ipAacDec = NULL; |
| |
| |
| if (!IsAdded()) |
| { |
| AddToScheduler(); |
| } |
| } |
| |
| |
| //Active object destructor |
| OpenmaxAacAO::~OpenmaxAacAO() |
| { |
| if (IsAdded()) |
| { |
| RemoveFromScheduler(); |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : destructed")); |
| } |
| |
| |
| /** The Initialization function |
| */ |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentInit() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentInit IN")); |
| |
| OMX_BOOL Status = OMX_TRUE; |
| |
| if (OMX_TRUE == iIsInit) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentInit error incorrect operation")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| iIsInit = OMX_TRUE; |
| |
| //aac lib init |
| if (!iCodecReady) |
| { |
| Status = ipAacDec->AacDecInit(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nChannels); |
| iCodecReady = OMX_TRUE; |
| } |
| |
| iInputCurrLength = 0; |
| //Used in dynamic port reconfiguration |
| iFrameCount = 0; |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentInit OUT")); |
| |
| if (OMX_TRUE == Status) |
| { |
| return OMX_ErrorNone; |
| } |
| else |
| { |
| return OMX_ErrorInvalidComponent; |
| } |
| } |
| |
| /** This function is called upon a transition to the idle or invalid state. |
| * Also it is called by the AacComponentDestructor() function |
| */ |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentDeInit() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDeInit IN")); |
| |
| iIsInit = OMX_FALSE; |
| |
| if (iCodecReady) |
| { |
| ipAacDec->AacDecDeinit(); |
| iCodecReady = OMX_FALSE; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDeInit OUT")); |
| |
| return OMX_ErrorNone; |
| |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentGetParameter( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nParamIndex, |
| OMX_INOUT OMX_PTR ComponentParameterStructure) |
| { |
| |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->GetParameter(hComponent, nParamIndex, ComponentParameterStructure); |
| return Status; |
| |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::GetParameter( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nParamIndex, |
| OMX_INOUT OMX_PTR ComponentParameterStructure) |
| |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter IN")); |
| |
| OMX_PRIORITYMGMTTYPE* pPrioMgmt; |
| OMX_PARAM_BUFFERSUPPLIERTYPE* pBufSupply; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDef; |
| OMX_PORT_PARAM_TYPE* pPortDomains; |
| OMX_U32 PortIndex; |
| |
| OMX_AUDIO_PARAM_PORTFORMATTYPE* pAudioPortFormat; |
| OMX_AUDIO_PARAM_PCMMODETYPE* pAudioPcmMode; |
| OMX_AUDIO_PARAM_AACPROFILETYPE* pAudioAac; |
| |
| AacComponentPortType* pComponentPort; |
| |
| if (NULL == ComponentParameterStructure) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error bad parameter")); |
| return OMX_ErrorBadParameter; |
| } |
| |
| switch (nParamIndex) |
| { |
| case OMX_IndexParamPriorityMgmt: |
| { |
| pPrioMgmt = (OMX_PRIORITYMGMTTYPE*) ComponentParameterStructure; |
| SetHeader(pPrioMgmt, sizeof(OMX_PRIORITYMGMTTYPE)); |
| pPrioMgmt->nGroupPriority = iGroupPriority; |
| pPrioMgmt->nGroupID = iGroupID; |
| } |
| break; |
| |
| case OMX_IndexParamAudioInit: |
| { |
| SetHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE)); |
| oscl_memcpy(ComponentParameterStructure, &iPortTypesParam, sizeof(OMX_PORT_PARAM_TYPE)); |
| } |
| break; |
| |
| |
| //Following 3 cases have a single common piece of code to be executed |
| case OMX_IndexParamVideoInit: |
| case OMX_IndexParamImageInit: |
| case OMX_IndexParamOtherInit: |
| { |
| pPortDomains = (OMX_PORT_PARAM_TYPE*) ComponentParameterStructure; |
| SetHeader(pPortDomains, sizeof(OMX_PORT_PARAM_TYPE)); |
| pPortDomains->nPorts = 0; |
| pPortDomains->nStartPortNumber = 0; |
| } |
| break; |
| |
| case OMX_IndexParamAudioPortFormat: |
| { |
| pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*) ComponentParameterStructure; |
| //Added to pass parameter test |
| if (pAudioPortFormat->nIndex > ipPorts[pAudioPortFormat->nPortIndex]->AudioParam.nIndex) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error index out of range")); |
| return OMX_ErrorNoMore; |
| } |
| SetHeader(pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); |
| if (pAudioPortFormat->nPortIndex <= 1) |
| { |
| pComponentPort = (AacComponentPortType*) ipPorts[pAudioPortFormat->nPortIndex]; |
| oscl_memcpy(pAudioPortFormat, &pComponentPort->AudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| } |
| break; |
| |
| case OMX_IndexParamAudioPcm: |
| { |
| pAudioPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE*) ComponentParameterStructure; |
| if (pAudioPcmMode->nPortIndex > 1) |
| { |
| return OMX_ErrorBadPortIndex; |
| } |
| PortIndex = pAudioPcmMode->nPortIndex; |
| oscl_memcpy(pAudioPcmMode, &ipPorts[PortIndex]->AudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); |
| SetHeader(pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); |
| } |
| break; |
| |
| case OMX_IndexParamAudioAac: |
| { |
| pAudioAac = (OMX_AUDIO_PARAM_AACPROFILETYPE*) ComponentParameterStructure; |
| if (pAudioAac->nPortIndex != 0) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| PortIndex = pAudioAac->nPortIndex; |
| oscl_memcpy(pAudioAac, &ipPorts[PortIndex]->AudioAacParam, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE)); |
| SetHeader(pAudioAac, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE)); |
| } |
| break; |
| |
| case OMX_IndexParamPortDefinition: |
| { |
| pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE*) ComponentParameterStructure; |
| PortIndex = pPortDef->nPortIndex; |
| if (PortIndex >= iNumPorts) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| oscl_memcpy(pPortDef, &ipPorts[PortIndex]->PortParam, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); |
| } |
| break; |
| |
| case OMX_IndexParamCompBufferSupplier: |
| { |
| pBufSupply = (OMX_PARAM_BUFFERSUPPLIERTYPE*) ComponentParameterStructure; |
| PortIndex = pBufSupply->nPortIndex; |
| if (PortIndex >= iNumPorts) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| SetHeader(pBufSupply, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); |
| |
| if (OMX_DirInput == ipPorts[PortIndex]->PortParam.eDir) |
| { |
| pBufSupply->eBufferSupplier = OMX_BufferSupplyUnspecified; |
| } |
| else |
| { |
| SetHeader(pBufSupply, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); |
| pBufSupply->eBufferSupplier = OMX_BufferSupplyUnspecified; |
| } |
| } |
| break; |
| |
| case(OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX: |
| { |
| PV_OMXComponentCapabilityFlagsType *pCap_flags = (PV_OMXComponentCapabilityFlagsType *) ComponentParameterStructure; |
| if (NULL == pCap_flags) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error pCap_flags NULL")); |
| return OMX_ErrorBadParameter; |
| } |
| oscl_memcpy(pCap_flags, &iPVCapabilityFlags, sizeof(iPVCapabilityFlags)); |
| |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter error Unsupported Index")); |
| return OMX_ErrorUnsupportedIndex; |
| } |
| break; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : GetParameter OUT")); |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentSetParameter( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nParamIndex, |
| OMX_IN OMX_PTR ComponentParameterStructure) |
| { |
| |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->SetParameter(hComponent, nParamIndex, ComponentParameterStructure); |
| |
| return Status; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::SetParameter( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nParamIndex, |
| OMX_IN OMX_PTR ComponentParameterStructure) |
| |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter IN")); |
| |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| OMX_PRIORITYMGMTTYPE* pPrioMgmt; |
| OMX_AUDIO_PARAM_PORTFORMATTYPE* pAudioPortFormat; |
| OMX_AUDIO_PARAM_PCMMODETYPE* pAudioPcmMode; |
| OMX_AUDIO_PARAM_AACPROFILETYPE* pAudioAac; |
| OMX_PARAM_BUFFERSUPPLIERTYPE* pBufSupply; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDef ; |
| OMX_U32 PortIndex; |
| OMX_PARAM_COMPONENTROLETYPE* pCompRole; |
| |
| AacComponentPortType* pComponentPort; |
| |
| if (NULL == ComponentParameterStructure) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error bad parameter")); |
| return OMX_ErrorBadParameter; |
| } |
| |
| switch (nParamIndex) |
| { |
| case OMX_IndexParamAudioInit: |
| { |
| /*Check Structure Header*/ |
| CheckHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error audio init failed")); |
| return ErrorType; |
| } |
| oscl_memcpy(&iPortTypesParam, ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE)); |
| } |
| break; |
| |
| case OMX_IndexParamAudioPortFormat: |
| { |
| pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*) ComponentParameterStructure; |
| PortIndex = pAudioPortFormat->nPortIndex; |
| /*Check Structure Header and verify component state*/ |
| ErrorType = BaseComponentParameterSanityCheck(hComponent, PortIndex, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error parameter sanity check error")); |
| return ErrorType; |
| } |
| if (PortIndex <= 1) |
| { |
| pComponentPort = (AacComponentPortType*) ipPorts[PortIndex]; |
| oscl_memcpy(&pComponentPort->AudioParam, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| } |
| break; |
| |
| case OMX_IndexParamAudioPcm: |
| { |
| pAudioPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE*) ComponentParameterStructure; |
| PortIndex = pAudioPcmMode->nPortIndex; |
| /*Check Structure Header and verify component State*/ |
| ErrorType = BaseComponentParameterSanityCheck(hComponent, PortIndex, pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); |
| oscl_memcpy(&ipPorts[PortIndex]->AudioPcmMode, pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); |
| } |
| break; |
| |
| case OMX_IndexParamAudioAac: |
| { |
| OMX_BOOL AacPlusFlag = OMX_TRUE; |
| |
| pAudioAac = (OMX_AUDIO_PARAM_AACPROFILETYPE*) ComponentParameterStructure; |
| PortIndex = pAudioAac->nPortIndex; |
| /*Check Structure Header and verify component state*/ |
| ErrorType = BaseComponentParameterSanityCheck(hComponent, PortIndex, pAudioAac, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error parameter sanity check error")); |
| return ErrorType; |
| } |
| oscl_memcpy(&ipPorts[PortIndex]->AudioAacParam, pAudioAac, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE)); |
| |
| if ((ipPorts[PortIndex]->AudioAacParam.eAACProfile == OMX_AUDIO_AACObjectHE) |
| || (ipPorts[PortIndex]->AudioAacParam.eAACProfile == OMX_AUDIO_AACObjectHE_PS)) |
| { |
| AacPlusFlag = OMX_TRUE; |
| } |
| else |
| { |
| AacPlusFlag = OMX_FALSE; |
| } |
| |
| ipAacDec->UpdateAACPlusEnabled(AacPlusFlag); |
| } |
| break; |
| |
| case OMX_IndexParamPriorityMgmt: |
| { |
| if (iState != OMX_StateLoaded && iState != OMX_StateWaitForResources) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error incorrect state error")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| pPrioMgmt = (OMX_PRIORITYMGMTTYPE*) ComponentParameterStructure; |
| if ((ErrorType = CheckHeader(pPrioMgmt, sizeof(OMX_PRIORITYMGMTTYPE))) != OMX_ErrorNone) |
| { |
| break; |
| } |
| iGroupPriority = pPrioMgmt->nGroupPriority; |
| iGroupID = pPrioMgmt->nGroupID; |
| } |
| break; |
| |
| case OMX_IndexParamPortDefinition: |
| { |
| pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE*) ComponentParameterStructure; |
| PortIndex = pPortDef->nPortIndex; |
| |
| ErrorType = BaseComponentParameterSanityCheck(hComponent, PortIndex, pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error parameter sanity check error")); |
| return ErrorType; |
| } |
| |
| ipPorts[PortIndex]->PortParam.nBufferCountActual = pPortDef->nBufferCountActual; |
| ipPorts[PortIndex]->PortParam.nBufferSize = pPortDef->nBufferSize; |
| } |
| break; |
| |
| case OMX_IndexParamCompBufferSupplier: |
| { |
| pBufSupply = (OMX_PARAM_BUFFERSUPPLIERTYPE*) ComponentParameterStructure; |
| PortIndex = pBufSupply->nPortIndex; |
| |
| ErrorType = BaseComponentParameterSanityCheck(hComponent, PortIndex, pBufSupply, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); |
| if (OMX_ErrorIncorrectStateOperation == ErrorType) |
| { |
| if (PORT_IS_ENABLED(ipPorts[pBufSupply->nPortIndex])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error incorrect state error")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| } |
| else if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error parameter sanity check error")); |
| return ErrorType; |
| } |
| |
| if (pBufSupply->eBufferSupplier == OMX_BufferSupplyUnspecified) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| ErrorType = OMX_ErrorNone; |
| } |
| break; |
| |
| case OMX_IndexParamStandardComponentRole: |
| { |
| pCompRole = (OMX_PARAM_COMPONENTROLETYPE*) ComponentParameterStructure; |
| if ((ErrorType = CheckHeader(pCompRole, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) |
| { |
| break; |
| } |
| strcpy((OMX_STRING)iComponentRole, (OMX_STRING)pCompRole->cRole); |
| } |
| break; |
| |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter error bad parameter")); |
| return OMX_ErrorBadParameter; |
| } |
| break; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetParameter OUT")); |
| return ErrorType; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentUseBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_PTR pAppPrivate, |
| OMX_IN OMX_U32 nSizeBytes, |
| OMX_IN OMX_U8* pBuffer) |
| { |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->UseBuffer(hComponent, ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, pBuffer); |
| |
| return Status; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::UseBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_PTR pAppPrivate, |
| OMX_IN OMX_U32 nSizeBytes, |
| OMX_IN OMX_U8* pBuffer) |
| { |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : UseBuffer IN")); |
| AacComponentPortType* pBaseComponentPort; |
| OMX_U32 ii; |
| |
| if (nPortIndex >= iNumPorts) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : UseBuffer error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| pBaseComponentPort = ipPorts[nPortIndex]; |
| |
| if (pBaseComponentPort->TransientState != OMX_StateIdle) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : UseBuffer error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| |
| if (NULL == pBaseComponentPort->pBuffer) |
| { |
| pBaseComponentPort->pBuffer = (OMX_BUFFERHEADERTYPE**) oscl_calloc(pBaseComponentPort->PortParam.nBufferCountActual, sizeof(OMX_BUFFERHEADERTYPE*)); |
| pBaseComponentPort->BufferState = (OMX_U32*) oscl_calloc(pBaseComponentPort->PortParam.nBufferCountActual, sizeof(OMX_U32)); |
| } |
| |
| for (ii = 0; ii < pBaseComponentPort->PortParam.nBufferCountActual; ii++) |
| { |
| if (!(pBaseComponentPort->BufferState[ii] & BUFFER_ALLOCATED) && |
| !(pBaseComponentPort->BufferState[ii] & BUFFER_ASSIGNED)) |
| { |
| pBaseComponentPort->pBuffer[ii] = (OMX_BUFFERHEADERTYPE*) oscl_malloc(sizeof(OMX_BUFFERHEADERTYPE)); |
| if (NULL == pBaseComponentPort->pBuffer[ii]) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : UseBuffer error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| SetHeader(pBaseComponentPort->pBuffer[ii], sizeof(OMX_BUFFERHEADERTYPE)); |
| pBaseComponentPort->pBuffer[ii]->pBuffer = pBuffer; |
| pBaseComponentPort->pBuffer[ii]->nAllocLen = nSizeBytes; |
| pBaseComponentPort->pBuffer[ii]->nFilledLen = 0; |
| pBaseComponentPort->pBuffer[ii]->nOffset = 0; |
| pBaseComponentPort->pBuffer[ii]->nFlags = 0; |
| pBaseComponentPort->pBuffer[ii]->pPlatformPrivate = pBaseComponentPort; |
| pBaseComponentPort->pBuffer[ii]->pAppPrivate = pAppPrivate; |
| pBaseComponentPort->pBuffer[ii]->nTickCount = 0; |
| pBaseComponentPort->pBuffer[ii]->nTimeStamp = 0; |
| *ppBufferHdr = pBaseComponentPort->pBuffer[ii]; |
| if (OMX_DirInput == pBaseComponentPort->PortParam.eDir) |
| { |
| pBaseComponentPort->pBuffer[ii]->nInputPortIndex = nPortIndex; |
| pBaseComponentPort->pBuffer[ii]->nOutputPortIndex = iNumPorts; // here is assigned a non-valid port index |
| } |
| else |
| { |
| pBaseComponentPort->pBuffer[ii]->nOutputPortIndex = nPortIndex; |
| pBaseComponentPort->pBuffer[ii]->nInputPortIndex = iNumPorts; // here is assigned a non-valid port index |
| } |
| pBaseComponentPort->BufferState[ii] |= BUFFER_ASSIGNED; |
| pBaseComponentPort->BufferState[ii] |= HEADER_ALLOCATED; |
| pBaseComponentPort->NumAssignedBuffers++; |
| if (pBaseComponentPort->PortParam.nBufferCountActual == pBaseComponentPort->NumAssignedBuffers) |
| { |
| pBaseComponentPort->PortParam.bPopulated = OMX_TRUE; |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| //Reschedule the AO for a state change (Loaded->Idle) if its pending on buffer allocation |
| RunIfNotReady(); |
| //Set the corresponding flags |
| pBaseComponentPort->LoadedToIdleFlag = OMX_TRUE; |
| pBaseComponentPort->IdleToLoadedFlag = OMX_FALSE; |
| iStateTransitionFlag = OMX_FALSE; |
| } |
| } |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : UseBuffer OUT")); |
| return OMX_ErrorNone; |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : UseBuffer OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentAllocateBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** pBuffer, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_PTR pAppPrivate, |
| OMX_IN OMX_U32 nSizeBytes) |
| { |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->AllocateBuffer(hComponent, pBuffer, nPortIndex, pAppPrivate, nSizeBytes); |
| |
| return Status; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::AllocateBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** pBuffer, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_PTR pAppPrivate, |
| OMX_IN OMX_U32 nSizeBytes) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer IN")); |
| |
| AacComponentPortType* pBaseComponentPort; |
| OMX_U32 ii; |
| |
| if (nPortIndex >= iNumPorts) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| pBaseComponentPort = ipPorts[nPortIndex]; |
| |
| if (pBaseComponentPort->TransientState != OMX_StateIdle) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| |
| if (NULL == pBaseComponentPort->pBuffer) |
| { |
| pBaseComponentPort->pBuffer = (OMX_BUFFERHEADERTYPE**) oscl_calloc(pBaseComponentPort->PortParam.nBufferCountActual, sizeof(OMX_BUFFERHEADERTYPE*)); |
| pBaseComponentPort->BufferState = (OMX_U32*) oscl_calloc(pBaseComponentPort->PortParam.nBufferCountActual, sizeof(OMX_U32)); |
| } |
| |
| for (ii = 0; ii < pBaseComponentPort->PortParam.nBufferCountActual; ii++) |
| { |
| if (!(pBaseComponentPort->BufferState[ii] & BUFFER_ALLOCATED) && |
| !(pBaseComponentPort->BufferState[ii] & BUFFER_ASSIGNED)) |
| { |
| pBaseComponentPort->pBuffer[ii] = (OMX_BUFFERHEADERTYPE*) oscl_malloc(sizeof(OMX_BUFFERHEADERTYPE)); |
| if (NULL == pBaseComponentPort->pBuffer[ii]) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| SetHeader(pBaseComponentPort->pBuffer[ii], sizeof(OMX_BUFFERHEADERTYPE)); |
| /* allocate the buffer */ |
| pBaseComponentPort->pBuffer[ii]->pBuffer = (OMX_BYTE) oscl_malloc(nSizeBytes); |
| if (NULL == pBaseComponentPort->pBuffer[ii]->pBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| pBaseComponentPort->pBuffer[ii]->nAllocLen = nSizeBytes; |
| pBaseComponentPort->pBuffer[ii]->nFlags = 0; |
| pBaseComponentPort->pBuffer[ii]->pPlatformPrivate = pBaseComponentPort; |
| pBaseComponentPort->pBuffer[ii]->pAppPrivate = pAppPrivate; |
| *pBuffer = pBaseComponentPort->pBuffer[ii]; |
| pBaseComponentPort->BufferState[ii] |= BUFFER_ALLOCATED; |
| pBaseComponentPort->BufferState[ii] |= HEADER_ALLOCATED; |
| |
| if (OMX_DirInput == pBaseComponentPort->PortParam.eDir) |
| { |
| pBaseComponentPort->pBuffer[ii]->nInputPortIndex = nPortIndex; |
| // here is assigned a non-valid port index |
| pBaseComponentPort->pBuffer[ii]->nOutputPortIndex = iNumPorts; |
| } |
| else |
| { |
| // here is assigned a non-valid port index |
| pBaseComponentPort->pBuffer[ii]->nInputPortIndex = iNumPorts; |
| pBaseComponentPort->pBuffer[ii]->nOutputPortIndex = nPortIndex; |
| } |
| |
| pBaseComponentPort->NumAssignedBuffers++; |
| |
| if (pBaseComponentPort->PortParam.nBufferCountActual == pBaseComponentPort->NumAssignedBuffers) |
| { |
| pBaseComponentPort->PortParam.bPopulated = OMX_TRUE; |
| |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| //Reschedule the AO for a state change (Loaded->Idle) if its pending on buffer allocation |
| RunIfNotReady(); |
| //Set the corresponding flags |
| pBaseComponentPort->LoadedToIdleFlag = OMX_TRUE; |
| pBaseComponentPort->IdleToLoadedFlag = OMX_FALSE; |
| iStateTransitionFlag = OMX_FALSE; |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer OUT")); |
| return OMX_ErrorNone; |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AllocateBuffer OUT")); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentFreeBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) |
| { |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->FreeBuffer(hComponent, nPortIndex, pBuffer); |
| |
| return Status; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::FreeBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_U32 nPortIndex, |
| OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FreeBuffer IN")); |
| |
| AacComponentPortType* pBaseComponentPort; |
| |
| OMX_U32 ii; |
| OMX_BOOL FoundBuffer; |
| |
| if (nPortIndex >= iNumPorts) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FreeBuffer error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| pBaseComponentPort = ipPorts[nPortIndex]; |
| |
| if (pBaseComponentPort->TransientState != OMX_StateLoaded |
| && pBaseComponentPort->TransientState != OMX_StateInvalid) |
| { |
| |
| (*(ipCallbacks->EventHandler)) |
| (hComponent, |
| iCallbackData, |
| OMX_EventError, /* The command was completed */ |
| OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */ |
| nPortIndex, /* The State has been changed in message->MessageParam2 */ |
| NULL); |
| } |
| |
| for (ii = 0; ii < pBaseComponentPort->PortParam.nBufferCountActual; ii++) |
| { |
| if ((pBaseComponentPort->BufferState[ii] & BUFFER_ALLOCATED) && |
| (pBaseComponentPort->pBuffer[ii]->pBuffer == pBuffer->pBuffer)) |
| { |
| |
| pBaseComponentPort->NumAssignedBuffers--; |
| oscl_free(pBuffer->pBuffer); |
| pBuffer->pBuffer = NULL; |
| |
| if (pBaseComponentPort->BufferState[ii] & HEADER_ALLOCATED) |
| { |
| oscl_free(pBuffer); |
| pBuffer = NULL; |
| } |
| pBaseComponentPort->BufferState[ii] = BUFFER_FREE; |
| break; |
| } |
| else if ((pBaseComponentPort->BufferState[ii] & BUFFER_ASSIGNED) && |
| (pBaseComponentPort->pBuffer[ii] == pBuffer)) |
| { |
| |
| pBaseComponentPort->NumAssignedBuffers--; |
| |
| if (pBaseComponentPort->BufferState[ii] & HEADER_ALLOCATED) |
| { |
| oscl_free(pBuffer); |
| pBuffer = NULL; |
| } |
| |
| pBaseComponentPort->BufferState[ii] = BUFFER_FREE; |
| break; |
| } |
| } |
| |
| FoundBuffer = OMX_FALSE; |
| |
| for (ii = 0; ii < pBaseComponentPort->PortParam.nBufferCountActual; ii++) |
| { |
| if (pBaseComponentPort->BufferState[ii] != BUFFER_FREE) |
| { |
| FoundBuffer = OMX_TRUE; |
| break; |
| } |
| } |
| if (!FoundBuffer) |
| { |
| pBaseComponentPort->PortParam.bPopulated = OMX_FALSE; |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| //Reschedule the AO for a state change (Idle->Loaded) if its pending on buffer de-allocation |
| RunIfNotReady(); |
| //Set the corresponding flags |
| pBaseComponentPort->IdleToLoadedFlag = OMX_TRUE; |
| pBaseComponentPort->LoadedToIdleFlag = OMX_FALSE; |
| iStateTransitionFlag = OMX_FALSE; |
| //Reset the decoding flags while freeing buffers |
| if (OMX_PORT_INPUTPORT_INDEX == nPortIndex) |
| { |
| iIsInputBufferEnded = OMX_TRUE; |
| iTempInputBufferLength = 0; |
| iTempConsumedLength = 0; |
| } |
| else if (OMX_PORT_OUTPUTPORT_INDEX == nPortIndex) |
| { |
| iNewOutBufRequired = OMX_TRUE; |
| } |
| } |
| |
| if (NULL != pBaseComponentPort->pBuffer) |
| { |
| oscl_free(pBaseComponentPort->pBuffer); |
| pBaseComponentPort->pBuffer = NULL; |
| oscl_free(pBaseComponentPort->BufferState); |
| pBaseComponentPort->BufferState = NULL; |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FreeBuffer OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| |
| /** Set Callbacks. It stores in the component private structure the pointers to the user application callbacs |
| * @param hComponent the handle of the component |
| * @param ipCallbacks the OpenMAX standard structure that holds the callback pointers |
| * @param pAppData a pointer to a private structure, not covered by OpenMAX standard, in needed |
| */ |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentSetCallbacks( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_CALLBACKTYPE* pCallbacks, |
| OMX_IN OMX_PTR pAppData) |
| { |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->SetCallbacks(hComponent, pCallbacks, pAppData); |
| |
| return Status; |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::SetCallbacks( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_CALLBACKTYPE* pCallbacks, |
| OMX_IN OMX_PTR pAppData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SetCallbacks")); |
| ipCallbacks = pCallbacks; |
| iCallbackData = pAppData; |
| |
| return OMX_ErrorNone; |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentSendCommand( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_COMMANDTYPE Cmd, |
| OMX_IN OMX_U32 nParam, |
| OMX_IN OMX_PTR pCmdData) |
| { |
| |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->SendCommand(hComponent, Cmd, nParam, pCmdData); |
| |
| return Status; |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::SendCommand( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_COMMANDTYPE Cmd, |
| OMX_IN OMX_S32 nParam, |
| OMX_IN OMX_PTR pCmdData) |
| { |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand IN")); |
| |
| OMX_U32 ii; |
| OMX_ERRORTYPE ErrMsgHandler = OMX_ErrorNone; |
| QueueType* pMessageQueue; |
| CoreMessage* Message = NULL; |
| |
| pMessageQueue = ipCoreDescriptor->pMessageQueue; |
| |
| if (OMX_StateInvalid == iState) |
| { |
| ErrMsgHandler = OMX_ErrorInvalidState; |
| } |
| |
| switch (Cmd) |
| { |
| case OMX_CommandStateSet: |
| { |
| Message = (CoreMessage*) oscl_malloc(sizeof(CoreMessage)); |
| |
| if (NULL == Message) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| Message->pComponent = (OMX_COMPONENTTYPE *) hComponent; |
| Message->MessageType = SENDCOMMAND_MSG_TYPE; |
| Message->MessageParam1 = OMX_CommandStateSet; |
| Message->MessageParam2 = nParam; |
| Message->pCmdData = pCmdData; |
| |
| if ((OMX_StateIdle == nParam) && (OMX_StateLoaded == iState)) |
| { |
| ErrMsgHandler = AacComponentInit(); |
| |
| if (ErrMsgHandler != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error component init")); |
| return OMX_ErrorInsufficientResources; |
| } |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| ipPorts[ii]->TransientState = OMX_StateIdle; |
| } |
| } |
| else if ((OMX_StateLoaded == nParam) && (OMX_StateIdle == iState)) |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (PORT_IS_ENABLED(ipPorts[ii])) |
| { |
| ipPorts[ii]->TransientState = OMX_StateLoaded; |
| } |
| } |
| } |
| else if (OMX_StateInvalid == nParam) |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (PORT_IS_ENABLED(ipPorts[ii])) |
| { |
| ipPorts[ii]->TransientState = OMX_StateInvalid; |
| } |
| } |
| } |
| else if (((OMX_StateIdle == nParam) || (OMX_StatePause == nParam)) |
| && (OMX_StateExecuting == iState)) |
| { |
| iBufferExecuteFlag = OMX_FALSE; |
| } |
| |
| } |
| break; |
| |
| case OMX_CommandFlush: |
| { |
| Message = (CoreMessage*) oscl_malloc(sizeof(CoreMessage)); |
| |
| if (NULL == Message) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| Message->pComponent = (OMX_COMPONENTTYPE *) hComponent; |
| Message->MessageType = SENDCOMMAND_MSG_TYPE; |
| Message->MessageParam1 = OMX_CommandFlush; |
| Message->MessageParam2 = nParam; |
| Message->pCmdData = pCmdData; |
| |
| if ((iState != OMX_StateExecuting) && (iState != OMX_StatePause)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error incorrect state")); |
| ErrMsgHandler = OMX_ErrorIncorrectStateOperation; |
| break; |
| |
| } |
| if ((nParam != -1) && ((OMX_U32) nParam >= iNumPorts)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| //Assume that reposition command has come |
| iRepositionFlag = OMX_TRUE; |
| //Reset the silence insertion logic also |
| iSilenceInsertionInProgress = OMX_FALSE; |
| // reset decoder |
| if (ipAacDec) |
| { |
| ipAacDec->ResetDecoder(); |
| } |
| |
| AacComponentSetPortFlushFlag(iNumPorts, nParam, OMX_TRUE); |
| AacComponentSetNumBufferFlush(iNumPorts, -1, 0); |
| } |
| break; |
| |
| case OMX_CommandPortDisable: |
| { |
| if ((nParam != -1) && ((OMX_U32) nParam >= iNumPorts)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| iResizePending = OMX_FALSE; |
| |
| if (-1 == nParam) |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (!PORT_IS_ENABLED(ipPorts[ii])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error incorrect state")); |
| ErrMsgHandler = OMX_ErrorIncorrectStateOperation; |
| break; |
| } |
| else |
| { |
| ipPorts[ii]->TransientState = OMX_StateLoaded; |
| } |
| } |
| } |
| else |
| { |
| if (!PORT_IS_ENABLED(ipPorts[nParam])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error incorrect state")); |
| ErrMsgHandler = OMX_ErrorIncorrectStateOperation; |
| break; |
| } |
| else |
| { |
| ipPorts[nParam]->TransientState = OMX_StateLoaded; |
| } |
| } |
| |
| Message = (CoreMessage*) oscl_malloc(sizeof(CoreMessage)); |
| if (NULL == Message) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| Message->pComponent = (OMX_COMPONENTTYPE *) hComponent; |
| if (OMX_ErrorNone == ErrMsgHandler) |
| { |
| Message->MessageType = SENDCOMMAND_MSG_TYPE; |
| Message->MessageParam2 = nParam; |
| } |
| else |
| { |
| Message->MessageType = ERROR_MSG_TYPE; |
| Message->MessageParam2 = ErrMsgHandler; |
| } |
| Message->MessageParam1 = OMX_CommandPortDisable; |
| Message->pCmdData = pCmdData; |
| } |
| break; |
| |
| |
| case OMX_CommandPortEnable: |
| { |
| if ((nParam != -1) && ((OMX_U32) nParam >= iNumPorts)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| if (-1 == nParam) |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (PORT_IS_ENABLED(ipPorts[ii])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error incorrect state")); |
| ErrMsgHandler = OMX_ErrorIncorrectStateOperation; |
| break; |
| } |
| else |
| { |
| ipPorts[ii]->TransientState = OMX_StateIdle; |
| } |
| } |
| } |
| else |
| { |
| if (PORT_IS_ENABLED(ipPorts[nParam])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error incorrect state")); |
| ErrMsgHandler = OMX_ErrorIncorrectStateOperation; |
| break; |
| } |
| else |
| { |
| ipPorts[nParam]->TransientState = OMX_StateIdle; |
| } |
| } |
| |
| Message = (CoreMessage*) oscl_malloc(sizeof(CoreMessage)); |
| if (NULL == Message) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| Message->pComponent = (OMX_COMPONENTTYPE *) hComponent; |
| if (OMX_ErrorNone == ErrMsgHandler) |
| { |
| Message->MessageType = SENDCOMMAND_MSG_TYPE; |
| } |
| else |
| { |
| Message->MessageType = ERROR_MSG_TYPE; |
| } |
| |
| Message->MessageParam1 = OMX_CommandPortEnable; |
| Message->MessageParam2 = nParam; |
| Message->pCmdData = pCmdData; |
| } |
| break; |
| |
| |
| case OMX_CommandMarkBuffer: |
| { |
| if ((iState != OMX_StateExecuting) && (iState != OMX_StatePause)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error incorrect state")); |
| ErrMsgHandler = OMX_ErrorIncorrectStateOperation; |
| break; |
| } |
| |
| if ((nParam != -1) && ((OMX_U32) nParam >= iNumPorts)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| Message = (CoreMessage*) oscl_malloc(sizeof(CoreMessage)); |
| if (NULL == Message) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| Message->pComponent = (OMX_COMPONENTTYPE *) hComponent; |
| Message->MessageType = SENDCOMMAND_MSG_TYPE; |
| Message->MessageParam1 = OMX_CommandMarkBuffer; |
| Message->MessageParam2 = nParam; |
| Message->pCmdData = pCmdData; |
| } |
| break; |
| |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand error unsupported index")); |
| ErrMsgHandler = OMX_ErrorUnsupportedIndex; |
| } |
| break; |
| } |
| |
| Queue(pMessageQueue, Message); |
| RunIfNotReady(); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : SendCommand OUT")); |
| return ErrMsgHandler; |
| } |
| |
| |
| /** This is called by the OMX core in its message processing |
| * thread context upon a component request. A request is made |
| * by the component when some asynchronous services are needed: |
| * 1) A SendCommand() is to be processed |
| * 2) An error needs to be notified |
| * \param Message, the message that has been passed to core |
| */ |
| |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentMessageHandler(CoreMessage* Message) |
| { |
| |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| OMX_U32 ii; |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| |
| |
| /** Dealing with a SendCommand call. |
| * -MessageParam1 contains the command to execute |
| * -MessageParam2 contains the parameter of the command |
| * (destination state in case of a state change command). |
| */ |
| |
| OMX_STATETYPE orig_state = iState; |
| if (SENDCOMMAND_MSG_TYPE == Message->MessageType) |
| { |
| switch (Message->MessageParam1) |
| { |
| case OMX_CommandStateSet: |
| { |
| /* Do the actual state change */ |
| ErrorType = AacComponentDoStateSet(Message->MessageParam2); |
| |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| return OMX_ErrorNone; |
| } |
| |
| //Do not send the callback now till the State gets changed |
| if (ErrorType != OMX_ErrorNone) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventError, /* The command was completed */ |
| ErrorType, /* The commands was a OMX_CommandStateSet */ |
| 0, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| else |
| { |
| /* And run the callback */ |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandStateSet, /* The commands was a OMX_CommandStateSet */ |
| Message->MessageParam2, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| } |
| break; |
| |
| case OMX_CommandFlush: |
| { |
| /*Flush ports*/ |
| ErrorType = AacComponentFlushPort(Message->MessageParam2); |
| |
| AacComponentSetNumBufferFlush(iNumPorts, -1, 0); |
| |
| if (ErrorType != OMX_ErrorNone) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventError, /* The command was completed */ |
| ErrorType, /* The commands was a OMX_CommandStateSet */ |
| 0, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| else |
| { |
| if (-1 == Message->MessageParam2) |
| { /*Flush all port*/ |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandFlush, /* The commands was a OMX_CommandStateSet */ |
| ii, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| } |
| else |
| {/*Flush input/output port*/ |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandFlush, /* The commands was a OMX_CommandStateSet */ |
| Message->MessageParam2, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| } |
| AacComponentSetPortFlushFlag(iNumPorts, -1, OMX_FALSE); |
| } |
| break; |
| |
| case OMX_CommandPortDisable: |
| { |
| /** This condition is added to pass the tests, it is not significant for the environment */ |
| ErrorType = AacComponentDisablePort(Message->MessageParam2); |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| return OMX_ErrorNone; |
| } |
| |
| if (ErrorType != OMX_ErrorNone) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventError, /* The command was completed */ |
| ErrorType, /* The commands was a OMX_CommandStateSet */ |
| 0, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| else |
| { |
| if (-1 == Message->MessageParam2) |
| { /*Disable all ports*/ |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandPortDisable, /* The commands was a OMX_CommandStateSet */ |
| ii, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| } |
| else |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandPortDisable, /* The commands was a OMX_CommandStateSet */ |
| Message->MessageParam2, /* The iState has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| } |
| } |
| break; |
| |
| case OMX_CommandPortEnable: |
| { |
| ErrorType = AacComponentEnablePort(Message->MessageParam2); |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| return OMX_ErrorNone; |
| } |
| |
| if (ErrorType != OMX_ErrorNone) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventError, /* The command was completed */ |
| ErrorType, /* The commands was a OMX_CommandStateSet */ |
| 0, /* The State has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| else |
| { |
| if (Message->MessageParam2 != -1) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandPortEnable, /* The commands was a OMX_CommandStateSet */ |
| Message->MessageParam2, /* The State has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| else |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventCmdComplete, /* The command was completed */ |
| OMX_CommandPortEnable, /* The commands was a OMX_CommandStateSet */ |
| ii, /* The State has been changed in Message->MessageParam2 */ |
| NULL); |
| } |
| } |
| } |
| } |
| break; |
| |
| case OMX_CommandMarkBuffer: |
| { |
| ipMark = (OMX_MARKTYPE *)Message->pCmdData; |
| } |
| break; |
| |
| default: |
| { |
| |
| } |
| break; |
| } |
| /* Dealing with an asynchronous error condition |
| */ |
| } |
| |
| if (orig_state != OMX_StateInvalid) |
| { |
| ErrorType = OMX_ErrorNone; |
| } |
| |
| return ErrorType; |
| } |
| |
| /** Changes the state of a component taking proper actions depending on |
| * the transiotion requested |
| * \param Component, the component which state is to be changed |
| * \param aDestinationState the requested target state. |
| */ |
| |
| OMX_ERRORTYPE OpenmaxAacAO::AacComponentDoStateSet(OMX_U32 aDestinationState) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "OpenmaxAacAO : AacComponentDoStateSet IN : iState (%i) aDestinationState (%i)", iState, aDestinationState)); |
| |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| OMX_U32 ii; |
| |
| if (OMX_StateLoaded == aDestinationState) |
| { |
| switch (iState) |
| { |
| case OMX_StateInvalid: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| |
| case OMX_StateWaitForResources: |
| { |
| iState = OMX_StateLoaded; |
| } |
| break; |
| |
| case OMX_StateLoaded: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error same state")); |
| return OMX_ErrorSameState; |
| } |
| break; |
| |
| case OMX_StateIdle: |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (PORT_IS_ENABLED(ipPorts[ii]) && |
| PORT_IS_POPULATED(ipPorts[ii])) |
| { |
| if (OMX_FALSE == ipPorts[ii]->IdleToLoadedFlag) |
| { |
| iStateTransitionFlag = OMX_TRUE; |
| } |
| |
| else |
| { |
| ipPorts[ii]->PortParam.bPopulated = OMX_FALSE; |
| ipPorts[ii]->TransientState = OMX_StateMax; |
| } |
| } |
| } |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet Waiting port to be de-populated")); |
| return OMX_ErrorNone; |
| } |
| |
| iState = OMX_StateLoaded; |
| |
| iNumInputBuffer = 0; |
| iOutBufferCount = 0; |
| iPartialFrameAssembly = OMX_FALSE; |
| iEndofStream = OMX_FALSE; |
| iIsInputBufferEnded = OMX_TRUE; |
| iNewOutBufRequired = OMX_TRUE; |
| iFirstFragment = OMX_FALSE; |
| ipAacDec->iAacInitFlag = 0; |
| |
| AacComponentDeInit(); |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| } |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| if (OMX_StateWaitForResources == aDestinationState) |
| { |
| switch (iState) |
| { |
| case OMX_StateInvalid: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| break; |
| |
| case OMX_StateLoaded: |
| { |
| iState = OMX_StateWaitForResources; |
| } |
| break; |
| |
| case OMX_StateWaitForResources: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error same state")); |
| return OMX_ErrorSameState; |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| } |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| if (OMX_StateIdle == aDestinationState) |
| { |
| switch (iState) |
| { |
| case OMX_StateInvalid: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| break; |
| |
| case OMX_StateWaitForResources: |
| { |
| iState = OMX_StateIdle; |
| } |
| break; |
| |
| case OMX_StateLoaded: |
| { |
| for (ii = 0; ii < iNumPorts; ii++) |
| { |
| if (PORT_IS_ENABLED(ipPorts[ii]) && |
| !PORT_IS_POPULATED(ipPorts[ii])) |
| { |
| if (OMX_FALSE == ipPorts[ii]->LoadedToIdleFlag) |
| { |
| iStateTransitionFlag = OMX_TRUE; |
| } |
| else |
| { |
| ipPorts[ii]->PortParam.bPopulated = OMX_TRUE; |
| ipPorts[ii]->TransientState = OMX_StateMax; |
| } |
| } |
| } |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet Waiting port to be populated")); |
| return OMX_ErrorNone; |
| } |
| |
| iState = OMX_StateIdle; |
| |
| //Used in case of partial frame assembly |
| if (!ipInputCurrBuffer) |
| { |
| //Keep the size of temp buffer double to be on safer side |
| ipInputCurrBuffer = (OMX_U8*) oscl_malloc(10 * sizeof(uint8) * (ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize)); |
| if (NULL == ipInputCurrBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| |
| if (!ipTempInputBuffer) |
| { |
| ipTempInputBuffer = (OMX_U8*) oscl_malloc(10 * sizeof(uint8) * ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize); |
| if (NULL == ipTempInputBuffer) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error insufficient resources")); |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| |
| iTempInputBufferLength = 0; |
| iTempConsumedLength = 0; |
| } |
| break; |
| |
| case OMX_StateIdle: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error same state")); |
| return OMX_ErrorSameState; |
| } |
| break; |
| |
| //Both the below cases have same body |
| case OMX_StateExecuting: |
| case OMX_StatePause: |
| { |
| AacComponentSetNumBufferFlush(iNumPorts, -1, 0); |
| AacComponentSetPortFlushFlag(iNumPorts, -1, OMX_TRUE); |
| |
| AacComponentPortType* pInPort = (AacComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| |
| //Return all the buffers if still occupied |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| |
| while ((iNumInputBuffer > 0) && (GetQueueNumElem(pInputQueue) > 0)) |
| { |
| AacComponentFlushPort(OMX_PORT_INPUTPORT_INDEX); |
| } |
| // if a buffer was previously dequeued, it wasnt freed in above loop. return it now |
| if (iNumInputBuffer > 0) |
| { |
| ipAacInputBuffer->nFilledLen = 0; |
| AacComponentReturnInputBuffer(ipAacInputBuffer, pInPort); |
| iIsInputBufferEnded = OMX_TRUE; |
| } |
| |
| //Mark these flags as true |
| iIsInputBufferEnded = OMX_TRUE; |
| iEndofStream = OMX_FALSE; |
| |
| //Reset the decoder's input buffers/flags |
| iTempInputBufferLength = 0; |
| iTempConsumedLength = 0; |
| |
| //Assume for this state transition that reposition command has come |
| iRepositionFlag = OMX_TRUE; |
| //Reset the silence insertion logic also |
| iSilenceInsertionInProgress = OMX_FALSE; |
| // reset decoder |
| if (ipAacDec) |
| { |
| ipAacDec->ResetDecoder(); |
| } |
| |
| while (iOutBufferCount > 0) |
| { |
| AacComponentFlushPort(OMX_PORT_OUTPUTPORT_INDEX); |
| } |
| |
| AacComponentSetPortFlushFlag(iNumPorts, -1, OMX_FALSE); |
| AacComponentSetNumBufferFlush(iNumPorts, -1, 0); |
| |
| iState = OMX_StateIdle; |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| break; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet OUT")); |
| return ErrorType; |
| } |
| |
| if (OMX_StatePause == aDestinationState) |
| { |
| switch (iState) |
| { |
| case OMX_StateInvalid: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| break; |
| |
| case OMX_StatePause: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error same state")); |
| return OMX_ErrorSameState; |
| } |
| break; |
| |
| //Falling through to the next case |
| case OMX_StateExecuting: |
| case OMX_StateIdle: |
| { |
| iState = OMX_StatePause; |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| break; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| if (OMX_StateExecuting == aDestinationState) |
| { |
| switch (iState) |
| { |
| case OMX_StateInvalid: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| break; |
| |
| case OMX_StateIdle: |
| { |
| iState = OMX_StateExecuting; |
| } |
| break; |
| |
| case OMX_StatePause: |
| { |
| iState = OMX_StateExecuting; |
| /* A trigger to start the processing of buffers when component |
| * transitions to executing from pause, as it is already |
| * holding the required buffers |
| */ |
| RunIfNotReady(); |
| } |
| break; |
| |
| case OMX_StateExecuting: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error same state")); |
| return OMX_ErrorSameState; |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error incorrect state")); |
| return OMX_ErrorIncorrectStateTransition; |
| } |
| break; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| if (OMX_StateInvalid == aDestinationState) |
| { |
| switch (iState) |
| { |
| case OMX_StateInvalid: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| break; |
| |
| default: |
| { |
| iState = OMX_StateInvalid; |
| if (iIsInit != OMX_FALSE) |
| { |
| AacComponentDeInit(); |
| } |
| } |
| break; |
| } |
| |
| if (iIsInit != OMX_FALSE) |
| { |
| AacComponentDeInit(); |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : AacComponentDoStateSet OUT")); |
| return OMX_ErrorNone; |
| } |
| |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentEmptyThisBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) |
| { |
| |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->EmptyThisBuffer(hComponent, pBuffer); |
| |
| return Status; |
| |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::EmptyThisBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) |
| |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer IN")); |
| //Do not queue buffers if component is in invalid state |
| if (OMX_StateInvalid == iState) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| |
| if ((OMX_StateIdle == iState) || (OMX_StatePause == iState) || (OMX_StateExecuting == iState)) |
| { |
| OMX_U32 PortIndex; |
| QueueType* pInputQueue; |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| |
| PortIndex = pBuffer->nInputPortIndex; |
| |
| //Validate the port index & Queue the buffers available only at the input port |
| if (PortIndex >= iNumPorts || |
| ipPorts[PortIndex]->PortParam.eDir != OMX_DirInput) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| //Port should be in enabled state before accepting buffers |
| if (!PORT_IS_ENABLED(ipPorts[PortIndex])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer error incorrect state")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| /* The number of buffers the component can queue at a time |
| * depends upon the number of buffers allocated/assigned on the input port |
| */ |
| if (iNumInputBuffer == (ipPorts[PortIndex]->NumAssignedBuffers)) |
| |
| { |
| RunIfNotReady(); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer error incorrect state")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| //Finally after passing all the conditions, queue the buffer in Input queue |
| pInputQueue = ipPorts[PortIndex]->pBufferQueue; |
| |
| if ((ErrorType = CheckHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer error check header failed")); |
| return ErrorType; |
| } |
| |
| iNumInputBuffer++; |
| Queue(pInputQueue, pBuffer); |
| |
| //Signal the AO about the incoming buffer |
| RunIfNotReady(); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer error incorrect state")); |
| //This macro is not accepted in any other state except the three mentioned above |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : EmptyThisBuffer OUT")); |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| OMX_ERRORTYPE OpenmaxAacAO::BaseComponentFillThisBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) |
| { |
| |
| OpenmaxAacAO* pOpenmaxAOType = (OpenmaxAacAO*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate; |
| OMX_ERRORTYPE Status; |
| |
| if (NULL == pOpenmaxAOType) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| Status = pOpenmaxAOType->FillThisBuffer(hComponent, pBuffer); |
| |
| return Status; |
| } |
| |
| OMX_ERRORTYPE OpenmaxAacAO::FillThisBuffer( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) |
| |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FillThisBuffer IN")); |
| |
| OMX_U32 PortIndex; |
| |
| QueueType* pOutputQueue; |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| |
| PortIndex = pBuffer->nOutputPortIndex; |
| //Validate the port index & Queue the buffers available only at the output port |
| if (PortIndex >= iNumPorts || |
| ipPorts[PortIndex]->PortParam.eDir != OMX_DirOutput) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FillThisBuffer error bad port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| pOutputQueue = ipPorts[PortIndex]->pBufferQueue; |
| if (iState != OMX_StateExecuting && |
| iState != OMX_StatePause && |
| iState != OMX_StateIdle) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FillThisBuffer error invalid state")); |
| return OMX_ErrorInvalidState; |
| } |
| |
| //Port should be in enabled state before accepting buffers |
| if (!PORT_IS_ENABLED(ipPorts[PortIndex])) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FillThisBuffer error incorrect state")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| if ((ErrorType = CheckHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FillThisBuffer error check header failed")); |
| return ErrorType; |
| } |
| |
| //Queue the buffer in output queue |
| Queue(pOutputQueue, pBuffer); |
| iOutBufferCount++; |
| |
| //Signal the AO about the incoming buffer |
| RunIfNotReady(); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : FillThisBuffer OUT")); |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| |
| void OpenmaxAacAO::Run() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : Run IN")); |
| |
| CoreMessage* pCoreMessage; |
| |
| //Execute the commands from the message handler queue |
| if ((GetQueueNumElem(ipCoreDescriptor->pMessageQueue) > 0)) |
| { |
| pCoreMessage = (CoreMessage*) DeQueue(ipCoreDescriptor->pMessageQueue); |
| |
| if (OMX_CommandStateSet == pCoreMessage->MessageParam1) |
| { |
| if (OMX_StateExecuting == pCoreMessage->MessageParam2) |
| { |
| iBufferExecuteFlag = OMX_TRUE; |
| } |
| else |
| { |
| iBufferExecuteFlag = OMX_FALSE; |
| } |
| } |
| |
| AacComponentMessageHandler(pCoreMessage); |
| |
| /* If some allocations/deallocations are required before the state transition |
| * then queue the command again to be executed later on |
| */ |
| if (OMX_TRUE == iStateTransitionFlag) |
| { |
| Queue(ipCoreDescriptor->pMessageQueue, pCoreMessage); |
| // Don't reschedule. Wait for arriving buffers to do it |
| //RunIfNotReady(); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : Run OUT")); |
| return; |
| } |
| |
| else |
| { |
| oscl_free(pCoreMessage); |
| pCoreMessage = NULL; |
| } |
| } |
| |
| /* If the component is in executing state, call the Buffer management function. |
| * Stop calling this function as soon as state transition request is received. |
| */ |
| if ((OMX_TRUE == iBufferExecuteFlag) && (OMX_TRUE != iResizePending)) |
| { |
| AacComponentBufferMgmtFunction(); |
| } |
| |
| //Check for any more commands in the message handler queue & schedule them for later |
| if ((GetQueueNumElem(ipCoreDescriptor->pMessageQueue) > 0)) |
| { |
| RunIfNotReady(); |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : Run OUT")); |
| |
| return; |
| } |
| |
| //Check whether silence insertion is required here or not |
| void OpenmaxAacAO::CheckForSilenceInsertion() |
| { |
| OMX_AUDIO_AACSTREAMFORMATTYPE InFormat = ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam.eAACStreamFormat; |
| uint32 CurrTimestamp, TimestampGap; |
| //Set the flag to false by default |
| iSilenceInsertionInProgress = OMX_FALSE; |
| |
| if (OMX_AUDIO_AACStreamFormatADIF == InFormat) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : CheckForSilenceInsertion OUT - Don't do it for ADIF since there is no timestamp to sync")); |
| return; |
| } |
| |
| CurrTimestamp = iCurrentFrameTS.GetCurrentTimestamp(); |
| TimestampGap = iFrameTimestamp - CurrTimestamp; |
| |
| if ((TimestampGap > OMX_HALFRANGE_THRESHOLD) || (TimestampGap < iOutputMilliSecPerFrame && iFrameCount > 0)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : CheckForSilenceInsertion OUT - No need to insert silence")); |
| return; |
| } |
| |
| //Silence insertion needed, mark the flag to true |
| if (iFrameCount > 0) |
| { |
| iSilenceInsertionInProgress = OMX_TRUE; |
| //Determine the number of silence frames to insert |
| iSilenceFramesNeeded = TimestampGap / iOutputMilliSecPerFrame; |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : CheckForSilenceInsertion OUT - Silence Insertion required here")); |
| } |
| |
| return; |
| } |
| |
| //Perform the silence insertion |
| void OpenmaxAacAO::DoSilenceInsertion() |
| { |
| OMX_S32 NumOfChannels = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode.nChannels; |
| QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue; |
| AacComponentPortType* pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]; |
| |
| OMX_U8* pOutBuffer, *SilenceInputBuffer; |
| OMX_U32 OutputLength, SilenceFrameLength; |
| OMX_S32 DecodeReturn; |
| OMX_BOOL ResizeNeeded = OMX_FALSE; |
| |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : DoSilenceInsertion IN")); |
| |
| while (iSilenceFramesNeeded > 0) |
| { |
| //Check whether prev output bufer has been consumed or not |
| if (OMX_TRUE == iNewOutBufRequired) |
| { |
| //Check whether a new output buffer is available or not |
| if (0 == (GetQueueNumElem(pOutputQueue))) |
| { |
| //Resume Silence insertion next time when component will be called |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : DoSilenceInsertion OUT output buffer unavailable")); |
| iSilenceInsertionInProgress = OMX_TRUE; |
| return; |
| } |
| |
| ipAacOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue); |
| ipAacOutputBuffer->nFilledLen = 0; |
| iNewOutBufRequired = OMX_FALSE; |
| |
| //Set the current timestamp to the output buffer timestamp |
| ipAacOutputBuffer->nTimeStamp = iCurrentFrameTS.GetConvertedTs(); |
| } |
| |
| // Setup the input side for silence frame |
| if (NumOfChannels > 1) |
| { |
| // Stereo silence frame |
| SilenceInputBuffer = (OMX_U8*) AAC_STEREO_SILENCE_FRAME; |
| SilenceFrameLength = AAC_STEREO_SILENCE_FRAME_SIZE; |
| } |
| else |
| { |
| // Mono silence frame |
| SilenceInputBuffer = (OMX_U8*) AAC_MONO_SILENCE_FRAME; |
| SilenceFrameLength = AAC_MONO_SILENCE_FRAME_SIZE; |
| } |
| |
| |
| pOutBuffer = &ipAacOutputBuffer->pBuffer[ipAacOutputBuffer->nFilledLen]; |
| OutputLength = 0; |
| |
| //Decode the silence frame |
| DecodeReturn = ipAacDec->AacDecodeFrames((OMX_S16*) pOutBuffer, |
| (OMX_U32*) & OutputLength, |
| &(SilenceInputBuffer), |
| &SilenceFrameLength, |
| &iFrameCount, |
| &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioPcmMode), |
| &(ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioAacParam), |
| &iSamplesPerFrame, |
| &ResizeNeeded); |
| |
| |
| |
| //Output length for a buffer of OMX_U8* will be double as that of OMX_S16* |
| ipAacOutputBuffer->nFilledLen += OutputLength * 2; |
| //offset not required in our case, set it to zero |
| ipAacOutputBuffer->nOffset = 0; |
| |
| if (OutputLength > 0) |
| { |
| iCurrentFrameTS.UpdateTimestamp(iSamplesPerFrame); |
| } |
| |
| if (MP4AUDEC_SUCCESS != DecodeReturn) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : DoSilenceInsertion - Silence frame decoding error. Skip inserting silence frame and move the timestamp forward")); |
| iCurrentFrameTS.SetFromInputTimestamp(iFrameTimestamp); |
| iSilenceInsertionInProgress = OMX_FALSE; |
| return; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : DoSilenceInsertion - silence frame decoded")); |
| |
| //Send the output buffer back when it has become full |
| if ((ipAacOutputBuffer->nAllocLen - ipAacOutputBuffer->nFilledLen) < iOutputFrameLength) |
| { |
| AacComponentReturnOutputBuffer(ipAacOutputBuffer, pOutPort); |
| } |
| |
| // Decrement the silence frame counter |
| --iSilenceFramesNeeded; |
| } |
| |
| /* Completed Silence insertion successfully, now consider the input buffer already dequeued |
| * for decoding & update the timestamps */ |
| |
| iSilenceInsertionInProgress = OMX_FALSE; |
| iCurrentFrameTS.SetFromInputTimestamp(iFrameTimestamp); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OpenmaxAacAO : DoSilenceInsertion OUT - Done successfully")); |
| |
| return; |
| } |