blob: a4530b4f8baf029b4b2a307381798a22a4351e6b [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 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 "omx_aacenc_component.h"
#if PROXY_INTERFACE
#include "omx_proxy_interface.h"
#endif
// This function is called by OMX_GetHandle and it creates an instance of the aac component AO
OMX_ERRORTYPE AacEncOmxComponentFactory(OMX_OUT OMX_HANDLETYPE* pHandle, OMX_IN OMX_PTR pAppData, OMX_PTR pProxy, OMX_STRING aOmxLibName, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
{
OSCL_UNUSED_ARG(aOmxLibName);
OSCL_UNUSED_ARG(aOmxLib);
OSCL_UNUSED_ARG(aOsclUuid);
OSCL_UNUSED_ARG(aRefCount);
OmxComponentAacEncoderAO* pOpenmaxAOType;
OMX_ERRORTYPE Status;
// move InitAacOmxComponentFields content to actual constructor
pOpenmaxAOType = (OmxComponentAacEncoderAO*) OSCL_NEW(OmxComponentAacEncoderAO, ());
if (NULL == pOpenmaxAOType)
{
return OMX_ErrorInsufficientResources;
}
//Call the construct component to initialize OMX types
Status = pOpenmaxAOType->ConstructComponent(pAppData, pProxy);
*pHandle = pOpenmaxAOType->GetOmxHandle();
return Status;
///////////////////////////////////////////////////////////////////////////////////////
}
// This function is called by OMX_FreeHandle when component AO needs to be destroyed
OMX_ERRORTYPE AacEncOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
{
OSCL_UNUSED_ARG(aOmxLib);
OSCL_UNUSED_ARG(aOsclUuid);
OSCL_UNUSED_ARG(aRefCount);
// get pointer to component AO
OmxComponentAacEncoderAO* pOpenmaxAOType = (OmxComponentAacEncoderAO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate;
// clean up encoder, OMX component stuff
pOpenmaxAOType->DestroyComponent();
// destroy the AO class
OSCL_DELETE(pOpenmaxAOType);
return OMX_ErrorNone;
}
#if DYNAMIC_LOAD_OMX_AACENC_COMPONENT
class AacEncOmxSharedLibraryInterface: public OsclSharedLibraryInterface,
public OmxSharedLibraryInterface
{
public:
static AacEncOmxSharedLibraryInterface *Instance()
{
static AacEncOmxSharedLibraryInterface omxinterface;
return &omxinterface;
};
OsclAny *QueryOmxComponentInterface(const OsclUuid& aOmxTypeId, const OsclUuid& aInterfaceId)
{
if (PV_OMX_AACENC_UUID == aOmxTypeId)
{
if (PV_OMX_CREATE_INTERFACE == aInterfaceId)
{
return ((OsclAny*)(&AacEncOmxComponentFactory));
}
else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId)
{
return ((OsclAny*)(&AacEncOmxComponentDestructor));
}
}
return NULL;
};
OsclAny *SharedLibraryLookup(const OsclUuid& aInterfaceId)
{
if (aInterfaceId == PV_OMX_SHARED_INTERFACE)
{
return OSCL_STATIC_CAST(OmxSharedLibraryInterface*, this);
}
return NULL;
};
private:
AacEncOmxSharedLibraryInterface() {};
};
// function to obtain the interface object from the shared library
extern "C"
{
OSCL_EXPORT_REF OsclAny* PVGetInterface()
{
return AacEncOmxSharedLibraryInterface::Instance();
}
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
OMX_ERRORTYPE OmxComponentAacEncoderAO::ConstructComponent(OMX_PTR pAppData, OMX_PTR pProxy)
{
ComponentPortType* pInPort, *pOutPort;
OMX_ERRORTYPE Status;
iNumPorts = 2;
iCompressedFormatPortNum = OMX_PORT_OUTPUTPORT_INDEX;
iOmxComponent.nSize = sizeof(OMX_COMPONENTTYPE);
iOmxComponent.pComponentPrivate = (OMX_PTR) this; // pComponentPrivate points to THIS component AO class
ipComponentProxy = pProxy;
iOmxComponent.pApplicationPrivate = pAppData; // init the App data
#if PROXY_INTERFACE
iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE;
iOmxComponent.SendCommand = OmxComponentAacEncoderAO::BaseComponentProxySendCommand;
iOmxComponent.GetParameter = OmxComponentAacEncoderAO::BaseComponentProxyGetParameter;
iOmxComponent.SetParameter = OmxComponentAacEncoderAO::BaseComponentProxySetParameter;
iOmxComponent.GetConfig = OmxComponentAacEncoderAO::BaseComponentProxyGetConfig;
iOmxComponent.SetConfig = OmxComponentAacEncoderAO::BaseComponentProxySetConfig;
iOmxComponent.GetExtensionIndex = OmxComponentAacEncoderAO::BaseComponentProxyGetExtensionIndex;
iOmxComponent.GetState = OmxComponentAacEncoderAO::BaseComponentProxyGetState;
iOmxComponent.UseBuffer = OmxComponentAacEncoderAO::BaseComponentProxyUseBuffer;
iOmxComponent.AllocateBuffer = OmxComponentAacEncoderAO::BaseComponentProxyAllocateBuffer;
iOmxComponent.FreeBuffer = OmxComponentAacEncoderAO::BaseComponentProxyFreeBuffer;
iOmxComponent.EmptyThisBuffer = OmxComponentAacEncoderAO::BaseComponentProxyEmptyThisBuffer;
iOmxComponent.FillThisBuffer = OmxComponentAacEncoderAO::BaseComponentProxyFillThisBuffer;
#else
iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_FALSE;
iOmxComponent.SendCommand = OmxComponentAacEncoderAO::BaseComponentSendCommand;
iOmxComponent.GetParameter = OmxComponentAacEncoderAO::BaseComponentGetParameter;
iOmxComponent.SetParameter = OmxComponentAacEncoderAO::BaseComponentSetParameter;
iOmxComponent.GetConfig = OmxComponentAacEncoderAO::BaseComponentGetConfig;
iOmxComponent.SetConfig = OmxComponentAacEncoderAO::BaseComponentSetConfig;
iOmxComponent.GetExtensionIndex = OmxComponentAacEncoderAO::BaseComponentGetExtensionIndex;
iOmxComponent.GetState = OmxComponentAacEncoderAO::BaseComponentGetState;
iOmxComponent.UseBuffer = OmxComponentAacEncoderAO::BaseComponentUseBuffer;
iOmxComponent.AllocateBuffer = OmxComponentAacEncoderAO::BaseComponentAllocateBuffer;
iOmxComponent.FreeBuffer = OmxComponentAacEncoderAO::BaseComponentFreeBuffer;
iOmxComponent.EmptyThisBuffer = OmxComponentAacEncoderAO::BaseComponentEmptyThisBuffer;
iOmxComponent.FillThisBuffer = OmxComponentAacEncoderAO::BaseComponentFillThisBuffer;
#endif
iOmxComponent.SetCallbacks = OmxComponentAacEncoderAO::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;
iPVCapabilityFlags.iOMXComponentSupportsPartialFrames = OMX_TRUE;
iPVCapabilityFlags.iOMXComponentNeedsNALStartCode = OMX_FALSE;
iPVCapabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
if (ipAppPriv)
{
oscl_free(ipAppPriv);
ipAppPriv = NULL;
}
ipAppPriv = (ComponentPrivateType*) oscl_malloc(sizeof(ComponentPrivateType));
if (NULL == ipAppPriv)
{
return OMX_ErrorInsufficientResources;
}
//Construct base class now
Status = ConstructBaseComponent(pAppData);
if (OMX_ErrorNone != Status)
{
return Status;
}
/** Domain specific section for the ports */
/* Input port is raw/pcm for AAC encoder */
ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainAudio;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.audio.cMIMEType = (OMX_STRING)"raw";
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_CodingPCM;
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_ENC;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize = INPUT_BUFFER_SIZE_AAC_ENC;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
/* Output port is aac format for AAC encoder */
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainAudio;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.audio.cMIMEType = (OMX_STRING)"audio/mpeg";
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_CodingAAC;
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_ENC;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferSize = OUTPUT_BUFFER_SIZE_AAC_ENC;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
//Default values for PCM input audio param port
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.nChannels = 2;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.eNumData = OMX_NumericalDataSigned;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.bInterleaved = OMX_TRUE;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.nBitPerSample = 16;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.nSamplingRate = 44100;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.ePCMMode = OMX_AUDIO_PCMModeLinear;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
//Default values for AAC output audio param port
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nChannels = 2;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nSampleRate = 48000;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nBitRate = 128000;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nAudioBandWidth = 0;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nFrameLength = 0;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nAACtools = OMX_AUDIO_AACToolAll;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nAACERtools = OMX_AUDIO_AACERNone;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.eAACProfile = OMX_AUDIO_AACObjectLC;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS;
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.eChannelMode = OMX_AUDIO_ChannelModeStereo;
iPortTypesParam.nPorts = 2;
iPortTypesParam.nStartPortNumber = 0;
pInPort = (ComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX];
pOutPort = (ComponentPortType*) 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_CodingPCM;
SetHeader(&pOutPort->AudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
pOutPort->AudioParam.nPortIndex = 1;
pOutPort->AudioParam.nIndex = 0;
pOutPort->AudioParam.eEncoding = OMX_AUDIO_CodingAAC;
if (ipAacEnc)
{
OSCL_DELETE(ipAacEnc);
ipAacEnc = NULL;
}
ipAacEnc = OSCL_NEW(OmxAacEncoder, ());
if (NULL == ipAacEnc)
{
return OMX_ErrorInsufficientResources;
}
iOutputFrameLength = OUTPUTBUFFER_SIZE;
#if PROXY_INTERFACE
((ProxyApplication_OMX*)ipComponentProxy)->ComponentSendCommand = BaseComponentSendCommand;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetParameter = BaseComponentGetParameter;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetParameter = BaseComponentSetParameter;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetConfig = BaseComponentGetConfig;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetConfig = BaseComponentSetConfig;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetExtensionIndex = BaseComponentGetExtensionIndex;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetState = BaseComponentGetState;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentUseBuffer = BaseComponentUseBuffer;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentAllocateBuffer = BaseComponentAllocateBuffer;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentFreeBuffer = BaseComponentFreeBuffer;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentEmptyThisBuffer = BaseComponentEmptyThisBuffer;
((ProxyApplication_OMX*)ipComponentProxy)->ComponentFillThisBuffer = BaseComponentFillThisBuffer;
#endif
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 OmxComponentAacEncoderAO::DestroyComponent()
{
if (iIsInit != OMX_FALSE)
{
ComponentDeInit();
}
//Destroy the base class now
DestroyBaseComponent();
if (ipAacEnc)
{
OSCL_DELETE(ipAacEnc);
ipAacEnc = NULL;
}
if (ipAppPriv)
{
ipAppPriv->CompHandle = NULL;
oscl_free(ipAppPriv);
ipAppPriv = NULL;
}
return OMX_ErrorNone;
}
/* This routine will extract the input timestamp from the input buffer */
void OmxComponentAacEncoderAO::SyncWithInputTimestamp()
{
iCurrentFrameTS.SetFromInputTimestamp(iFrameTimestamp);
}
void OmxComponentAacEncoderAO::ProcessData()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ProcessData IN"));
QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
ComponentPortType* pInPort = (ComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX];
ComponentPortType* pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
OMX_COMPONENTTYPE* pHandle = &iOmxComponent;
OMX_U8* pOutBuffer;
OMX_U32 OutputLength;
OMX_S32 EncodeReturn;
OMX_U32 TempInputBufferSize = (2 * sizeof(uint8) * (ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize));
if ((!iIsInputBufferEnded) || iEndofStream)
{
//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, "OmxComponentAacEncoderAO : ProcessData OUT output buffer unavailable"));
return;
}
ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
ipOutputBuffer->nFilledLen = 0;
iNewOutBufRequired = OMX_FALSE;
//Set the current timestamp to the output buffer timestamp
ipOutputBuffer->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)
{
ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
ipOutputBuffer->pMarkData = ipMark->pMarkData;
ipMark = NULL;
}
if (ipTargetComponent != NULL)
{
ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
ipOutputBuffer->pMarkData = iTargetMarkData;
ipTargetComponent = NULL;
}
//Mark buffer code ends here
if ((iTempInputBufferLength > 0) &&
((iInputCurrLength + iTempInputBufferLength) <= TempInputBufferSize))
{
oscl_memcpy(&ipTempInputBuffer[iTempInputBufferLength], ipFrameDecodeBuffer, iInputCurrLength);
iInputCurrLength += iTempInputBufferLength;
iTempInputBufferLength = 0;
ipFrameDecodeBuffer = ipTempInputBuffer;
}
if ((iInputCurrLength >= iInputFrameLength) || (OMX_TRUE == iEndofStream))
{
pOutBuffer = &ipOutputBuffer->pBuffer[ipOutputBuffer->nFilledLen];
OutputLength = 0;
EncodeReturn = ipAacEnc->AacEncodeFrame(pOutBuffer,
&OutputLength,
ipFrameDecodeBuffer,
iInputCurrLength);
ipOutputBuffer->nFilledLen += OutputLength;
ipOutputBuffer->nOffset = 0;
if (OutputLength > 0)
{
iCurrentFrameTS.UpdateTimestamp((iInputFrameLength >> 1));
}
/* 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 == OutputLength) || (OMX_TRUE != EncodeReturn))
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ProcessData EOS callback send"));
(*(ipCallbacks->EventHandler))
(pHandle,
iCallbackData,
OMX_EventBufferFlag,
1,
OMX_BUFFERFLAG_EOS,
NULL);
iEndofStream = OMX_FALSE;
ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
ReturnOutputBuffer(ipOutputBuffer, pOutPort);
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ProcessData OUT"));
return;
}
}
if (OMX_TRUE == EncodeReturn)
{
if (iInputCurrLength >= iInputFrameLength)
{
iInputCurrLength -= iInputFrameLength;
}
else
{
iInputCurrLength = 0;
}
if (0 == iInputCurrLength)
{
if (ipInputBuffer)
{
//Input bytes consumed now, return the buffer
ipInputBuffer->nFilledLen = 0;
ReturnInputBuffer(ipInputBuffer, pInPort);
ipInputBuffer = NULL;
}
iIsInputBufferEnded = OMX_TRUE;
}
else if (iInputCurrLength >= iInputFrameLength)
{
//Do not return the input buffer in case it has more than one frame data to encode
ipFrameDecodeBuffer += iInputFrameLength;
}
else
{
/* If there are some remainder bytes out of the last buffer, copy into a temp buffer
* to be used in next decode cycle and return the existing input buffer*/
oscl_memmove(ipTempInputBuffer, &ipFrameDecodeBuffer[iInputFrameLength], iInputCurrLength);
iTempInputBufferLength = iInputCurrLength;
if (ipInputBuffer)
{
ipInputBuffer->nFilledLen = 0;
ReturnInputBuffer(ipInputBuffer, pInPort);
ipInputBuffer = NULL;
}
iIsInputBufferEnded = OMX_TRUE;
iInputCurrLength = 0;
}
}
//In case of error, discard the bitstream and report data corruption error via callback
else
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ProcessData ErrorStreamCorrupt callback send"));
if (ipInputBuffer)
{
ipInputBuffer->nFilledLen = 0;
ReturnInputBuffer(ipInputBuffer, pInPort);
ipInputBuffer = NULL;
}
iIsInputBufferEnded = OMX_TRUE;
iInputCurrLength = 0;
(*(ipCallbacks->EventHandler))
(pHandle,
iCallbackData,
OMX_EventError,
OMX_ErrorStreamCorrupt,
0,
NULL);
}
}
else
{
oscl_memmove(ipTempInputBuffer, &ipFrameDecodeBuffer[iInputFrameLength], iInputCurrLength);
iTempInputBufferLength = iInputCurrLength;
if (ipInputBuffer)
{
ipInputBuffer->nFilledLen = 0;
ReturnInputBuffer(ipInputBuffer, pInPort);
ipInputBuffer = NULL;
}
iIsInputBufferEnded = OMX_TRUE;
iInputCurrLength = 0;
}
/* Send the output buffer back when it has become full*/
if ((ipOutputBuffer->nAllocLen - ipOutputBuffer->nFilledLen) < (iOutputFrameLength))
{
//Attach the end of frame flag while sending out the output buffer
ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
ReturnOutputBuffer(ipOutputBuffer, 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 (((iInputCurrLength != 0) || (GetQueueNumElem(pInputQueue) > 0))
&& ((GetQueueNumElem(pOutputQueue) > 0) || (OMX_FALSE == iNewOutBufRequired)))
{
RunIfNotReady();
}
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ProcessData OUT"));
return;
}
//Not implemented & supported in case of base profile components
void OmxComponentAacEncoderAO::ComponentGetRolesOfComponent(OMX_STRING* aRoleString)
{
*aRoleString = (OMX_STRING)"audio_encoder.aac";
}
//Component constructor
OmxComponentAacEncoderAO::OmxComponentAacEncoderAO()
{
ipAacEnc = NULL;
iInputFrameLength = 0;
iOutputFrameLength = 0;
if (!IsAdded())
{
AddToScheduler();
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : constructed"));
}
//Active object destructor
OmxComponentAacEncoderAO::~OmxComponentAacEncoderAO()
{
if (IsAdded())
{
RemoveFromScheduler();
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : destructed"));
}
/** The Initialization function
*/
OMX_ERRORTYPE OmxComponentAacEncoderAO::ComponentInit()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ComponentInit IN"));
OMX_BOOL Status = OMX_TRUE;
if (OMX_TRUE == iIsInit)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ComponentInit error incorrect operation"));
return OMX_ErrorIncorrectStateOperation;
}
iIsInit = OMX_TRUE;
//aac encoder lib init
if (!iCodecReady)
{
Status = ipAacEnc->AacEncInit(ipPorts[OMX_PORT_INPUTPORT_INDEX]->AudioPcmMode,
ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam,
&iInputFrameLength);
iCodecReady = OMX_TRUE;
iCurrentFrameTS.SetParameters(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AudioAacParam.nSampleRate, (iInputFrameLength >> 1));
}
iInputCurrLength = 0;
if (OMX_TRUE == Status)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ComponentInit OUT"));
return OMX_ErrorNone;
}
else
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : Error ComponentInit, OUT"));
return OMX_ErrorInvalidComponent;
}
}
/** This function is called upon a transition to the idle or invalid state.
* Also it is called by the ComponentDestructor() function
*/
OMX_ERRORTYPE OmxComponentAacEncoderAO::ComponentDeInit()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ComponentDeInit IN"));
iIsInit = OMX_FALSE;
if (iCodecReady)
{
ipAacEnc->AacEncDeinit();
iCodecReady = OMX_FALSE;
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAacEncoderAO : ComponentDeInit OUT"));
return OMX_ErrorNone;
}
/* A component specific routine called from BufferMgmtWithoutMarker */
void OmxComponentAacEncoderAO::ProcessInBufferFlag()
{
iIsInputBufferEnded = OMX_FALSE;
}