| /* ------------------------------------------------------------------ |
| * 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_avcenc_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 avc component AO |
| OMX_ERRORTYPE AvcEncOmxComponentFactory(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); |
| |
| |
| OmxComponentAvcEncAO* pOpenmaxAOType; |
| OMX_ERRORTYPE Status; |
| |
| // move InitAvcOmxComponentFields content to actual constructor |
| |
| pOpenmaxAOType = (OmxComponentAvcEncAO*) OSCL_NEW(OmxComponentAvcEncAO, ()); |
| |
| 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 AvcEncOmxComponentDestructor(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 |
| OmxComponentAvcEncAO* pOpenmaxAOType = (OmxComponentAvcEncAO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate; |
| |
| // clean up decoder, OMX component stuff |
| pOpenmaxAOType->DestroyComponent(); |
| |
| // destroy the AO class |
| OSCL_DELETE(pOpenmaxAOType); |
| |
| return OMX_ErrorNone; |
| } |
| |
| #if DYNAMIC_LOAD_OMX_AVCENC_COMPONENT |
| |
| class AvcEncOmxSharedLibraryInterface: public OsclSharedLibraryInterface, |
| public OmxSharedLibraryInterface |
| |
| { |
| public: |
| static AvcEncOmxSharedLibraryInterface *Instance() |
| { |
| static AvcEncOmxSharedLibraryInterface omxinterface; |
| return &omxinterface; |
| }; |
| |
| OsclAny *QueryOmxComponentInterface(const OsclUuid& aOmxTypeId, const OsclUuid& aInterfaceId) |
| { |
| if (PV_OMX_AVCENC_UUID == aOmxTypeId) |
| { |
| if (PV_OMX_CREATE_INTERFACE == aInterfaceId) |
| { |
| return ((OsclAny*)(&AvcEncOmxComponentFactory)); |
| } |
| else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId) |
| { |
| return ((OsclAny*)(&AvcEncOmxComponentDestructor)); |
| } |
| } |
| return NULL; |
| }; |
| |
| OsclAny *SharedLibraryLookup(const OsclUuid& aInterfaceId) |
| { |
| if (aInterfaceId == PV_OMX_SHARED_INTERFACE) |
| { |
| return OSCL_STATIC_CAST(OmxSharedLibraryInterface*, this); |
| } |
| return NULL; |
| }; |
| |
| private: |
| AvcEncOmxSharedLibraryInterface() {}; |
| }; |
| |
| // function to obtain the interface object from the shared library |
| extern "C" |
| { |
| OSCL_EXPORT_REF OsclAny* PVGetInterface() |
| { |
| return AvcEncOmxSharedLibraryInterface::Instance(); |
| } |
| } |
| |
| #endif |
| |
| |
| OMX_ERRORTYPE OmxComponentAvcEncAO::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 = OmxComponentAvcEncAO::BaseComponentProxySendCommand; |
| iOmxComponent.GetParameter = OmxComponentAvcEncAO::BaseComponentProxyGetParameter; |
| iOmxComponent.SetParameter = OmxComponentAvcEncAO::BaseComponentProxySetParameter; |
| iOmxComponent.GetConfig = OmxComponentAvcEncAO::BaseComponentProxyGetConfig; |
| iOmxComponent.SetConfig = OmxComponentAvcEncAO::BaseComponentProxySetConfig; |
| iOmxComponent.GetExtensionIndex = OmxComponentAvcEncAO::BaseComponentProxyGetExtensionIndex; |
| iOmxComponent.GetState = OmxComponentAvcEncAO::BaseComponentProxyGetState; |
| iOmxComponent.UseBuffer = OmxComponentAvcEncAO::BaseComponentProxyUseBuffer; |
| iOmxComponent.AllocateBuffer = OmxComponentAvcEncAO::BaseComponentProxyAllocateBuffer; |
| iOmxComponent.FreeBuffer = OmxComponentAvcEncAO::BaseComponentProxyFreeBuffer; |
| iOmxComponent.EmptyThisBuffer = OmxComponentAvcEncAO::BaseComponentProxyEmptyThisBuffer; |
| iOmxComponent.FillThisBuffer = OmxComponentAvcEncAO::BaseComponentProxyFillThisBuffer; |
| |
| #else |
| iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_FALSE; |
| |
| iOmxComponent.SendCommand = OmxComponentAvcEncAO::BaseComponentSendCommand; |
| iOmxComponent.GetParameter = OmxComponentAvcEncAO::BaseComponentGetParameter; |
| iOmxComponent.SetParameter = OmxComponentAvcEncAO::BaseComponentSetParameter; |
| iOmxComponent.GetConfig = OmxComponentAvcEncAO::BaseComponentGetConfig; |
| iOmxComponent.SetConfig = OmxComponentAvcEncAO::BaseComponentSetConfig; |
| iOmxComponent.GetExtensionIndex = OmxComponentAvcEncAO::BaseComponentGetExtensionIndex; |
| iOmxComponent.GetState = OmxComponentAvcEncAO::BaseComponentGetState; |
| iOmxComponent.UseBuffer = OmxComponentAvcEncAO::BaseComponentUseBuffer; |
| iOmxComponent.AllocateBuffer = OmxComponentAvcEncAO::BaseComponentAllocateBuffer; |
| iOmxComponent.FreeBuffer = OmxComponentAvcEncAO::BaseComponentFreeBuffer; |
| iOmxComponent.EmptyThisBuffer = OmxComponentAvcEncAO::BaseComponentEmptyThisBuffer; |
| iOmxComponent.FillThisBuffer = OmxComponentAvcEncAO::BaseComponentFillThisBuffer; |
| #endif |
| |
| iOmxComponent.SetCallbacks = OmxComponentAvcEncAO::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 input raw port */ //OMX_PARAM_PORTDEFINITIONTYPE |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"raw"; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE; |
| |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16); |
| 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_AVCENC; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountMin = 1; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize = INPUT_BUFFER_SIZE_AVCENC; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE; |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE; |
| |
| |
| /** Domain specific section for output avc port */ |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"video/avc"; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatUnused; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16); |
| 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_AVCENC; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountMin = 1; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferSize = OUTPUT_BUFFER_SIZE_AVCENC; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE; |
| |
| |
| //OMX_VIDEO_PARAM_AVCTYPE //Default values for avc video output param port |
| oscl_memset(&ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc, 0, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); |
| SetHeader(&ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); |
| |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.eProfile = OMX_VIDEO_AVCProfileBaseline; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.eLevel = OMX_VIDEO_AVCLevel1b; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.nPFrames = 0xFFFFFFFF; //Default value |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.nBFrames = 0; //No support for B frames |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; |
| |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.nRefFrames = 1; //Only support this value |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.bEnableFMO = OMX_FALSE; //Default value is false |
| |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.bFrameMBsOnly = OMX_TRUE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.bMBAFF = OMX_FALSE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.bEntropyCodingCABAC = OMX_FALSE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.bWeightedPPrediction = OMX_FALSE; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc.bDirect8x8Inference = OMX_FALSE; |
| |
| |
| //OMX_VIDEO_PARAM_PROFILELEVELTYPE structure |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.nProfileIndex = 0; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.eProfile = OMX_VIDEO_AVCProfileBaseline; |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.eLevel = OMX_VIDEO_AVCLevel1b; |
| |
| |
| iPortTypesParam.nPorts = 2; |
| iPortTypesParam.nStartPortNumber = 0; |
| |
| pInPort = (ComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| pOutPort = (ComponentPortType*) ipPorts[OMX_PORT_OUTPUTPORT_INDEX]; |
| |
| pInPort->ActualNumPortFormatsSupported = 4; |
| |
| //OMX_VIDEO_PARAM_PORTFORMATTYPE INPUT PORT SETTINGS |
| //On input port for index 0 |
| SetHeader(&pInPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); |
| pInPort->VideoParam[0].nPortIndex = OMX_PORT_INPUTPORT_INDEX; |
| pInPort->VideoParam[0].nIndex = 0; |
| pInPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingUnused; |
| pInPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatYUV420Planar; |
| pInPort->VideoParam[0].xFramerate = (15 << 16); |
| |
| //On input port for index 1 |
| SetHeader(&pInPort->VideoParam[1], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); |
| pInPort->VideoParam[1].nPortIndex = OMX_PORT_INPUTPORT_INDEX; |
| pInPort->VideoParam[1].nIndex = 1; |
| pInPort->VideoParam[1].eCompressionFormat = OMX_VIDEO_CodingUnused; |
| pInPort->VideoParam[1].eColorFormat = OMX_COLOR_Format24bitRGB888; |
| pInPort->VideoParam[1].xFramerate = (15 << 16); |
| |
| //On input port for index 2 |
| SetHeader(&pInPort->VideoParam[2], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); |
| pInPort->VideoParam[2].nPortIndex = OMX_PORT_INPUTPORT_INDEX; |
| pInPort->VideoParam[2].nIndex = 2; |
| pInPort->VideoParam[2].eCompressionFormat = OMX_VIDEO_CodingUnused; |
| pInPort->VideoParam[2].eColorFormat = OMX_COLOR_Format12bitRGB444; |
| pInPort->VideoParam[2].xFramerate = (15 << 16); |
| |
| //On input port for index 3 |
| SetHeader(&pInPort->VideoParam[3], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); |
| pInPort->VideoParam[3].nPortIndex = OMX_PORT_INPUTPORT_INDEX; |
| pInPort->VideoParam[3].nIndex = 3; |
| pInPort->VideoParam[3].eCompressionFormat = OMX_VIDEO_CodingUnused; |
| pInPort->VideoParam[3].eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; |
| pInPort->VideoParam[3].xFramerate = (15 << 16); |
| |
| pOutPort->ActualNumPortFormatsSupported = 1; |
| |
| //OMX_VIDEO_PARAM_PORTFORMATTYPE OUTPUT PORT SETTINGS |
| //On output port for index 0 |
| SetHeader(&pOutPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); |
| pOutPort->VideoParam[0].nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoParam[0].nIndex = 0; |
| pOutPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatUnused; |
| pOutPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingAVC; |
| pOutPort->VideoParam[0].xFramerate = (15 << 16); |
| |
| |
| //OMX_CONFIG_ROTATIONTYPE SETTINGS ON INPUT PORT |
| SetHeader(&pInPort->VideoOrientationType, sizeof(OMX_CONFIG_ROTATIONTYPE)); |
| pInPort->VideoOrientationType.nPortIndex = OMX_PORT_INPUTPORT_INDEX; |
| pInPort->VideoOrientationType.nRotation = -1; //For all the YUV formats that are other than RGB |
| |
| |
| //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE settings of output port |
| oscl_memset(&pOutPort->VideoErrorCorrection, 0, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); |
| SetHeader(&pOutPort->VideoErrorCorrection, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); |
| pOutPort->VideoErrorCorrection.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoErrorCorrection.bEnableDataPartitioning = OMX_FALSE; |
| |
| |
| //OMX_VIDEO_PARAM_BITRATETYPE settings of output port |
| SetHeader(&pOutPort->VideoRateType, sizeof(OMX_VIDEO_PARAM_BITRATETYPE)); |
| pOutPort->VideoRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoRateType.eControlRate = OMX_Video_ControlRateConstant; |
| pOutPort->VideoRateType.nTargetBitrate = 64000; |
| |
| |
| //OMX_CONFIG_FRAMERATETYPE default seetings (specified in khronos conformance test) |
| SetHeader(&pOutPort->VideoConfigFrameRateType, sizeof(OMX_CONFIG_FRAMERATETYPE)); |
| pOutPort->VideoConfigFrameRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoConfigFrameRateType.xEncodeFramerate = (15 << 16); |
| |
| //OMX_VIDEO_CONFIG_BITRATETYPE default settings (specified in khronos conformance test) |
| SetHeader(&pOutPort->VideoConfigBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE)); |
| pOutPort->VideoConfigBitRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoConfigBitRateType.nEncodeBitrate = 64000; |
| |
| |
| //OMX_VIDEO_PARAM_QUANTIZATIONTYPE settings of output port |
| SetHeader(&pOutPort->VideoQuantType, sizeof(OMX_VIDEO_PARAM_QUANTIZATIONTYPE)); |
| pOutPort->VideoQuantType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoQuantType.nQpI = 0; //Not required by encoder |
| pOutPort->VideoQuantType.nQpP = 0; //Default is 0 |
| pOutPort->VideoQuantType.nQpB = 0; //Not required by encoder |
| |
| |
| //OMX_VIDEO_PARAM_VBSMCTYPE settings of output port |
| oscl_memset(&pOutPort->VideoBlockMotionSize, 0, sizeof(OMX_VIDEO_PARAM_VBSMCTYPE)); |
| SetHeader(&pOutPort->VideoBlockMotionSize, sizeof(OMX_VIDEO_PARAM_VBSMCTYPE)); |
| pOutPort->VideoBlockMotionSize.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoBlockMotionSize.b16x16 = OMX_TRUE; //Encoder only support this mode |
| |
| |
| //OMX_VIDEO_PARAM_MOTIONVECTORTYPE settings of output port |
| oscl_memset(&pOutPort->VideoMotionVector, 0, sizeof(OMX_VIDEO_PARAM_MOTIONVECTORTYPE)); |
| SetHeader(&pOutPort->VideoMotionVector, sizeof(OMX_VIDEO_PARAM_MOTIONVECTORTYPE)); |
| pOutPort->VideoMotionVector.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoMotionVector.eAccuracy = OMX_Video_MotionVectorQuarterPel; |
| pOutPort->VideoMotionVector.bUnrestrictedMVs = OMX_TRUE; //Only support true |
| pOutPort->VideoMotionVector.sXSearchRange = 16; |
| pOutPort->VideoMotionVector.sYSearchRange = 16; |
| |
| |
| //OMX_VIDEO_PARAM_INTRAREFRESHTYPE settings of output port |
| oscl_memset(&pOutPort->VideoIntraRefresh, 0, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE)); |
| SetHeader(&pOutPort->VideoIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE)); |
| pOutPort->VideoIntraRefresh.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; |
| pOutPort->VideoIntraRefresh.nCirMBs = 0; |
| |
| //OMX_VIDEO_PARAM_AVCSLICEFMO settings on output port |
| oscl_memset(&pOutPort->AvcSliceFMO, 0, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); |
| SetHeader(&pOutPort->AvcSliceFMO, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); |
| pOutPort->AvcSliceFMO.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->AvcSliceFMO.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; |
| pOutPort->AvcSliceFMO.nNumSliceGroups = 1; |
| pOutPort->AvcSliceFMO.nSliceGroupMapType = 1; //Only support map type of 1 |
| |
| |
| //OMX_CONFIG_INTRAREFRESHVOPTYPE settings of output port |
| oscl_memset(&pOutPort->VideoIFrame, 0, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE)); |
| SetHeader(&pOutPort->VideoIFrame, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE)); |
| pOutPort->VideoIFrame.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX; |
| pOutPort->VideoIFrame.IntraRefreshVOP = OMX_FALSE; |
| |
| |
| //Construct the encoder object |
| if (ipAvcEncoderObject) |
| { |
| OSCL_DELETE(ipAvcEncoderObject); |
| ipAvcEncoderObject = NULL; |
| } |
| |
| ipAvcEncoderObject = OSCL_NEW(AvcEncoder_OMX, ()); |
| |
| #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(). |
| */ |
| |
| OMX_ERRORTYPE OmxComponentAvcEncAO::DestroyComponent() |
| { |
| if (OMX_FALSE != iIsInit) |
| { |
| ComponentDeInit(); |
| } |
| |
| //Destroy the base class now |
| DestroyBaseComponent(); |
| |
| if (ipAvcEncoderObject) |
| { |
| OSCL_DELETE(ipAvcEncoderObject); |
| ipAvcEncoderObject = NULL; |
| } |
| |
| if (ipAppPriv) |
| { |
| ipAppPriv->CompHandle = NULL; |
| |
| oscl_free(ipAppPriv); |
| ipAppPriv = NULL; |
| } |
| |
| return OMX_ErrorNone; |
| } |
| |
| |
| void OmxComponentAvcEncAO::ProcessData() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ProcessData IN")); |
| |
| QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue; |
| QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue; |
| |
| ComponentPortType* pInPort = ipPorts[OMX_PORT_INPUTPORT_INDEX]; |
| ComponentPortType* pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]; |
| |
| OMX_U8* pOutBuffer; |
| OMX_U32 OutputLength; |
| AVCEnc_Status EncodeReturn = AVCENC_SUCCESS; |
| OMX_COMPONENTTYPE* pHandle = &iOmxComponent; |
| |
| 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, "OmxComponentAvcEncAO : ProcessData OUT output buffer unavailable")); |
| return; |
| } |
| |
| ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue); |
| ipOutputBuffer->nFilledLen = 0; |
| iNewOutBufRequired = OMX_FALSE; |
| |
| |
| /* If some output data was left to be send from the last processing due to |
| * unavailability of required number of output buffers, |
| * copy it now and send back before processing new input frame */ |
| if (iInternalOutBufFilledLen > 0) |
| { |
| if (OMX_FALSE == CopyDataToOutputBuffer()) |
| { |
| //We fell short of output buffers, exit now and wait for some more buffers to get queued |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ProcessData OUT output buffer unavailable")); |
| return; |
| } |
| else |
| { |
| //Attach the end of frame flag while sending out the last piece of output buffer |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; |
| if (OMX_TRUE == iSyncFlag) |
| { |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| iSyncFlag = OMX_FALSE; |
| } |
| ReturnOutputBuffer(ipOutputBuffer, pOutPort); |
| |
| //Dequeue new output buffer to continue encoding the next frame |
| if (0 == (GetQueueNumElem(pOutputQueue))) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ProcessData OUT output buffer unavailable")); |
| return; |
| } |
| |
| ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue); |
| ipOutputBuffer->nFilledLen = 0; |
| iNewOutBufRequired = OMX_FALSE; |
| } |
| } |
| } |
| |
| /* 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 |
| |
| //Call the encoder only if there is some data to encode |
| if (iInputCurrLength > 0) |
| { |
| pOutBuffer = ipOutputBuffer->pBuffer; |
| OutputLength = ipOutputBuffer->nAllocLen; |
| |
| //Output buffer is passed as a short pointer |
| EncodeReturn = ipAvcEncoderObject->AvcEncodeVideo(pOutBuffer, |
| &OutputLength, |
| &iBufferOverRun, |
| &ipInternalOutBuffer, |
| ipFrameDecodeBuffer, |
| &iInputCurrLength, |
| iFrameTimestamp, |
| &iOutputTimeStamp, |
| &iSyncFlag); |
| |
| |
| //Chk whether output data has been generated or not |
| if (OutputLength > 0) |
| { |
| //offset not required in our case, set it to zero |
| ipOutputBuffer->nOffset = 0; |
| ipOutputBuffer->nTimeStamp = iOutputTimeStamp; |
| |
| if (OMX_FALSE == iBufferOverRun) |
| { |
| //No internal buffer is maintained |
| ipOutputBuffer->nFilledLen = OutputLength; |
| } |
| else |
| { |
| iInternalOutBufFilledLen = OutputLength; |
| iBufferOverRun = OMX_FALSE; |
| CopyDataToOutputBuffer(); |
| |
| } //else loop of if (OMX_FALSE == iMantainOutInternalBuffer) |
| } //if (OutputLength > 0) loop |
| |
| |
| //If encoder returned error in case of frame skip/corrupt frame, report it to the client via a callback |
| if ((AVCENC_FAIL == EncodeReturn) && (OMX_FALSE == iEndofStream)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : Frame skipped, ProcessData ErrorStreamCorrupt callback send")); |
| |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventError, |
| OMX_ErrorStreamCorrupt, |
| 0, |
| NULL); |
| } |
| |
| |
| //Return the input buffer that has been consumed fully |
| if (0 == iInputCurrLength) |
| { |
| ipInputBuffer->nFilledLen = 0; |
| ReturnInputBuffer(ipInputBuffer, pInPort); |
| ipInputBuffer = NULL; |
| |
| iIsInputBufferEnded = OMX_TRUE; |
| iInputCurrLength = 0; |
| } |
| |
| iFrameCount++; |
| } |
| |
| |
| /* 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) || (AVCENC_FAIL == EncodeReturn)) && |
| (0 == iInternalOutBufFilledLen)) |
| { |
| |
| (*(ipCallbacks->EventHandler)) |
| (pHandle, |
| iCallbackData, |
| OMX_EventBufferFlag, |
| 1, |
| OMX_BUFFERFLAG_EOS, |
| NULL); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ProcessData EOS callback sent")); |
| |
| |
| //Mark this flag false once the callback has been send back |
| iEndofStream = OMX_FALSE; |
| |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS; |
| if (OMX_TRUE == iSyncFlag) |
| { |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| iSyncFlag = OMX_FALSE; |
| } |
| ReturnOutputBuffer(ipOutputBuffer, pOutPort); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ProcessData OUT")); |
| return; |
| } |
| |
| } |
| |
| //Send the output buffer back after decode |
| if ((ipOutputBuffer->nFilledLen > 0) && (OMX_FALSE == iNewOutBufRequired)) |
| { |
| //Attach the end of frame flag while sending out the last piece of output buffer |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; |
| if (OMX_TRUE == iSyncFlag) |
| { |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| iSyncFlag = OMX_FALSE; |
| } |
| 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)) |
| { |
| RunIfNotReady(); |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ProcessData OUT")); |
| } |
| |
| |
| OMX_BOOL OmxComponentAvcEncAO::CopyDataToOutputBuffer() |
| { |
| ComponentPortType* pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]; |
| QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue; |
| |
| while (iInternalOutBufFilledLen > 0) |
| { |
| if (ipOutputBuffer->nAllocLen >= iInternalOutBufFilledLen) |
| { |
| //Pack the whole data into the output buffer Alloc length data in one buffer and return it |
| oscl_memcpy(ipOutputBuffer->pBuffer, ipInternalOutBuffer, iInternalOutBufFilledLen); |
| ipOutputBuffer->nFilledLen = iInternalOutBufFilledLen; |
| |
| } |
| else |
| { |
| oscl_memcpy(ipOutputBuffer->pBuffer, ipInternalOutBuffer, ipOutputBuffer->nAllocLen); |
| ipOutputBuffer->nFilledLen = ipOutputBuffer->nAllocLen; |
| } |
| |
| iInternalOutBufFilledLen -= ipOutputBuffer->nFilledLen; |
| ipInternalOutBuffer += ipOutputBuffer->nFilledLen; |
| |
| |
| if (0 != iInternalOutBufFilledLen) |
| { |
| //Mark the sync Flag in every piece of IDR NAL |
| if (OMX_TRUE == iSyncFlag) |
| { |
| ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| } |
| //Return the partial output buffer and try to fetch a new output buffer for filling the remaining data |
| ReturnOutputBuffer(ipOutputBuffer, pOutPort); |
| |
| //Check whether a new output buffer is available or not |
| if (0 == (GetQueueNumElem(pOutputQueue))) |
| { |
| return OMX_FALSE; |
| } |
| |
| ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue); |
| ipOutputBuffer->nFilledLen = 0; |
| ipOutputBuffer->nTimeStamp = iOutputTimeStamp; |
| ipOutputBuffer->nOffset = 0; |
| iNewOutBufRequired = OMX_FALSE; |
| } |
| } //while (iInternalOutBufFilledLen > 0) |
| |
| return OMX_TRUE; |
| |
| } |
| |
| |
| //Not implemented & supported in case of base profile components |
| |
| void OmxComponentAvcEncAO::ComponentGetRolesOfComponent(OMX_STRING* aRoleString) |
| { |
| *aRoleString = (OMX_STRING)"video_encoder.avc"; |
| } |
| |
| |
| //Component constructor |
| OmxComponentAvcEncAO::OmxComponentAvcEncAO() |
| { |
| ipAvcEncoderObject = NULL; |
| ipInternalOutBuffer = NULL; |
| iInternalOutBufFilledLen = 0; |
| iSyncFlag = OMX_FALSE; |
| iBufferOverRun = OMX_FALSE; |
| |
| if (!IsAdded()) |
| { |
| AddToScheduler(); |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : constructed")); |
| } |
| |
| |
| //Active object destructor |
| OmxComponentAvcEncAO::~OmxComponentAvcEncAO() |
| { |
| if (IsAdded()) |
| { |
| RemoveFromScheduler(); |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : destructed")); |
| } |
| |
| |
| OMX_ERRORTYPE OmxComponentAvcEncAO::SetConfig( |
| OMX_IN OMX_HANDLETYPE hComponent, |
| OMX_IN OMX_INDEXTYPE nIndex, |
| OMX_IN OMX_PTR pComponentConfigStructure) |
| { |
| OSCL_UNUSED_ARG(hComponent); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig IN")); |
| |
| OMX_U32 PortIndex; |
| |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| OMX_CONFIG_INTRAREFRESHVOPTYPE* pAvcIFrame; |
| OMX_VIDEO_CONFIG_BITRATETYPE* pBitRateType; |
| OMX_CONFIG_FRAMERATETYPE* pFrameRateType; |
| |
| |
| |
| if (NULL == pComponentConfigStructure) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error bad parameter")); |
| return OMX_ErrorBadParameter; |
| } |
| |
| switch (nIndex) |
| { |
| case OMX_IndexConfigVideoIntraVOPRefresh: |
| { |
| pAvcIFrame = (OMX_CONFIG_INTRAREFRESHVOPTYPE*) pComponentConfigStructure; |
| PortIndex = pAvcIFrame->nPortIndex; |
| |
| if (PortIndex != iCompressedFormatPortNum) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error invalid port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| /*Check Structure Header*/ |
| ErrorType = CheckHeader(pAvcIFrame, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error param check failed")); |
| return ErrorType; |
| } |
| |
| //Call the RequestI frame routine of the encoder in case of setconfig call |
| if (OMX_TRUE == pAvcIFrame->IntraRefreshVOP) |
| { |
| ipAvcEncoderObject->AvcRequestIFrame(); |
| |
| } |
| } |
| break; |
| |
| case OMX_IndexConfigVideoBitrate: |
| { |
| pBitRateType = (OMX_VIDEO_CONFIG_BITRATETYPE*) pComponentConfigStructure; |
| PortIndex = pBitRateType->nPortIndex; |
| |
| if (PortIndex != iCompressedFormatPortNum) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error invalid port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| /*Check Structure Header*/ |
| ErrorType = CheckHeader(pBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error param check failed")); |
| return ErrorType; |
| } |
| |
| //Call the corresponding routine of the encoder in case of setconfig call |
| if (OMX_FALSE == (ipAvcEncoderObject->AvcUpdateBitRate(pBitRateType->nEncodeBitrate))) |
| { |
| return OMX_ErrorBadParameter; |
| |
| } |
| |
| ipPorts[PortIndex]->VideoConfigBitRateType.nEncodeBitrate = pBitRateType->nEncodeBitrate; |
| } |
| break; |
| |
| case OMX_IndexConfigVideoFramerate: |
| { |
| pFrameRateType = (OMX_CONFIG_FRAMERATETYPE*) pComponentConfigStructure; |
| PortIndex = pFrameRateType->nPortIndex; |
| |
| if (PortIndex != iCompressedFormatPortNum) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error invalid port index")); |
| return OMX_ErrorBadPortIndex; |
| } |
| |
| /*Check Structure Header*/ |
| ErrorType = CheckHeader(pFrameRateType, sizeof(OMX_CONFIG_FRAMERATETYPE)); |
| if (ErrorType != OMX_ErrorNone) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error param check failed")); |
| return ErrorType; |
| } |
| |
| //Call the corresponding routine of the encoder in case of setconfig call |
| if (OMX_FALSE == (ipAvcEncoderObject->AvcUpdateFrameRate(pFrameRateType->xEncodeFramerate))) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| |
| ipPorts[PortIndex]->VideoConfigFrameRateType.xEncodeFramerate = pFrameRateType->xEncodeFramerate; |
| } |
| break; |
| |
| default: |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error Unsupported Index")); |
| return OMX_ErrorUnsupportedIndex; |
| } |
| break; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig OUT")); |
| return OMX_ErrorNone; |
| |
| } |
| |
| |
| |
| /** The Initialization function |
| */ |
| OMX_ERRORTYPE OmxComponentAvcEncAO::ComponentInit() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ComponentInit IN")); |
| |
| OMX_ERRORTYPE Status = OMX_ErrorNone; |
| |
| if (OMX_TRUE == iIsInit) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ComponentInit error incorrect operation")); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| iIsInit = OMX_TRUE; |
| |
| |
| if (!iCodecReady) |
| { |
| iCodecReady = OMX_TRUE; |
| } |
| |
| //Verify the parameters and return failure in case they cannot be supported by our encoder |
| OMX_VIDEO_PARAM_AVCTYPE* pAvcParam = (OMX_VIDEO_PARAM_AVCTYPE*) & ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc; |
| OMX_VIDEO_PARAM_AVCSLICEFMO* pAvcSliceFMO = (OMX_VIDEO_PARAM_AVCSLICEFMO*) & ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->AvcSliceFMO; |
| |
| //FMO enabled is not supported in the encoder |
| if ((pAvcParam->nBFrames > 0) || |
| (0 == (pAvcParam->nAllowedPictureTypes & |
| (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP))) || |
| (OMX_FALSE == pAvcParam->bFrameMBsOnly) || |
| (OMX_TRUE == pAvcParam->bMBAFF) || |
| (OMX_TRUE == pAvcParam->bEntropyCodingCABAC) || |
| (OMX_TRUE == pAvcParam->bWeightedPPrediction) || |
| (OMX_TRUE == pAvcParam->bDirect8x8Inference) || |
| (OMX_TRUE == pAvcParam->bEnableFMO) || |
| (1 != pAvcSliceFMO->nSliceGroupMapType)) |
| { |
| return OMX_ErrorUnsupportedSetting; |
| } |
| |
| |
| //Library init routine |
| Status = ipAvcEncoderObject->AvcEncInit( |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video, |
| ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoOrientationType, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoAvc, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoRateType, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoQuantType, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMotionVector, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoIntraRefresh, |
| ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoBlockMotionSize); |
| |
| iInputCurrLength = 0; |
| |
| //Used in dynamic port reconfiguration |
| iFrameCount = 0; |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ComponentInit OUT")); |
| |
| return Status; |
| |
| } |
| |
| /** This function is called upon a transition to the idle or invalid state. |
| * Also it is called by the ComponentDestructor() function |
| */ |
| OMX_ERRORTYPE OmxComponentAvcEncAO::ComponentDeInit() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ComponentDeInit IN")); |
| |
| OMX_ERRORTYPE Status = OMX_ErrorNone; |
| |
| iIsInit = OMX_FALSE; |
| |
| if (iCodecReady) |
| { |
| Status = ipAvcEncoderObject->AvcEncDeinit(); |
| iCodecReady = OMX_FALSE; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : ComponentDeInit OUT")); |
| |
| return Status; |
| |
| } |
| |
| /* A component specific routine called from BufferMgmtWithoutMarker */ |
| void OmxComponentAvcEncAO::ProcessInBufferFlag() |
| { |
| iIsInputBufferEnded = OMX_FALSE; |
| } |