From 6a286120be5a298a3a5712db3ea723f8b039618a Mon Sep 17 00:00:00 2001 From: Gloria Wang Date: Wed, 3 Mar 2010 16:22:43 -0800 Subject: QUalcomm H.264 encoder support. --- nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp | 421 ++++++++++++++------------- 1 file changed, 226 insertions(+), 195 deletions(-) diff --git a/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp b/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp index 341677ed8..960714fbe 100644 --- a/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp +++ b/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp @@ -2539,7 +2539,7 @@ bool PVMFOMXEncNode::SetMP4EncoderParameters() Mpeg4Type.nIDCVLCThreshold = 0; Mpeg4Type.bACPred = OMX_TRUE; Mpeg4Type.nMaxPacketSize = iVideoEncodeParam.iPacketSize; - Mpeg4Type.nTimeIncRes = 1000; // (in relation to (should be higher than) frame rate ) + Mpeg4Type.nTimeIncRes = 60; // (in relation to (should be higher than) frame rate ) Mpeg4Type.nHeaderExtension = 0; Mpeg4Type.bReversibleVLC = ((iVideoEncodeParam.iRVLCEnable == true) ? OMX_TRUE : OMX_FALSE); @@ -3010,8 +3010,8 @@ bool PVMFOMXEncNode::SetH264EncoderParameters() H264Type.bEnableFMO = OMX_FALSE; H264Type.bEnableASO = OMX_FALSE; H264Type.bEnableRS = OMX_FALSE; - H264Type.eProfile = OMX_VIDEO_AVCProfileBaseline; - H264Type.eLevel = OMX_VIDEO_AVCLevel1b; +// H264Type.eProfile = OMX_VIDEO_AVCProfileBaseline; +// H264Type.eLevel = OMX_VIDEO_AVCLevel1b; H264Type.bFrameMBsOnly = OMX_TRUE; H264Type.bMBAFF = OMX_FALSE; H264Type.bEntropyCodingCABAC = OMX_FALSE; @@ -3044,7 +3044,7 @@ bool PVMFOMXEncNode::SetH264EncoderParameters() //Set the parameters now BitRateType.nPortIndex = iOutputPortIndex; - BitRateType.eControlRate = static_cast(iVideoEncodeParam.iRateControlType); + BitRateType.eControlRate = OMX_Video_ControlRateDisable; //static_cast(iVideoEncodeParam.iRateControlType); BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0]; Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType); if (OMX_ErrorNone != Err) @@ -4694,14 +4694,9 @@ OMX_ERRORTYPE PVMFOMXEncNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aCom ReportInfoEvent(PVMFInfoProcessingFailure, NULL); } - else if (aData1 == (OMX_U32) OMX_ErrorInvalidState) - { - PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState", iNodeTypeId)); - HandleComponentStateChange(OMX_StateInvalid); - } else { + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::EventHandlerProcessing: OMX_EventError", iNodeTypeId)); // for now, any error from the component will be reported as error @@ -4961,46 +4956,6 @@ void PVMFOMXEncNode::HandleComponentStateChange(OMX_U32 encoder_state) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::HandleComponentStateChange: OMX_StateInvalid reached", iNodeTypeId)); - //Clearup encoder - DeleteOMXEncoder(); - - if (iCurrentCommand.size() > 0) - {//can NOT be CANCEL or CANCEL_ALL. Just to cmd completion for the rest - if (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET) - { - //delete all ports and notify observer. - if (iInPort) - { - OSCL_DELETE(((PVMFOMXEncPort*)iInPort)); - iInPort = NULL; - } - - if (iOutPort) - { - OSCL_DELETE(((PVMFOMXEncPort*)iOutPort)); - iOutPort = NULL; - } - - iDataIn.Unbind(); - - // Reset the metadata key list - iAvailableMetadataKeys.clear(); - - iEndOfDataReached = false; - iIsEOSSentToComponent = false; - iIsEOSReceivedFromComponent = false; - - iProcessingState = EPVMFOMXEncNodeProcessingState_Idle; - //logoff & go back to Created state. - SetState(EPVMFNodeIdle); - CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess); - } - else - { - SetState(EPVMFNodeError); - CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource); - } - } break; }//end of case OMX_StateInvalid @@ -5095,7 +5050,7 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC // address of the mempool buffer (so that it can be released) OsclAny *pContext = (OsclAny*) aBuffer->pAppPrivate; - + uint32 nal_size= 0; // check for EOS flag if ((aBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { @@ -5114,7 +5069,7 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC uint8* pData = (uint8*)aBuffer->pBuffer + aBuffer->nOffset; uint8* pTemp; uint32 size = aBuffer->nFilledLen; - if (AVCAnnexBGetNALUnit(pData, &pTemp, (int32*)&size, true)) + if (AVCAnnexBGetNALUnit(pData, &pTemp, (int32*)&size, false)) { iFirstNALStartCodeSize = (uint32)pTemp - (uint32)pData; } @@ -5122,6 +5077,7 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC { iFirstNALStartCodeSize = 0; } + nal_size = size; } /* the case in which a buffer simply containing a start code is sent */ @@ -5255,18 +5211,35 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC if (aBuffer->nFilledLen <= (capacity - length)) { iSPSs[iNumSPSs].ptr = destptr; - iSPSs[iNumSPSs++].len = aBuffer->nFilledLen; + iSPSs[iNumSPSs++].len = nal_size;//aBuffer->nFilledLen; - oscl_memcpy(destptr, pBufdata, aBuffer->nFilledLen); // copy SPS into iParamSet memfragment - length += aBuffer->nFilledLen; + oscl_memcpy(destptr, pBufdata, nal_size); // copy SPS into iParamSet memfragment + length += nal_size; iParamSet.getMemFrag().len = length; // update length + destptr += nal_size; } - + uint8* pData = (uint8*)aBuffer->pBuffer + nal_size +iFirstNALStartCodeSize; + uint32 size = aBuffer->nFilledLen -(nal_size +iFirstNALStartCodeSize) ; + AVCAnnexBGetNALUnit(pData, &bitstream, (int32*)&size, false) ; + nal_size = size; + nal_type = bitstream[0] & 0x1F; + if (nal_type == 0x08) // PPS type NAL + { + if (aBuffer->nFilledLen <= (capacity - length)) + { + iPPSs[iNumPPSs].ptr = destptr; + iPPSs[iNumPPSs++].len = nal_size;//aBuffer->nFilledLen; + + oscl_memcpy(destptr, bitstream, nal_size); // copy PPS into iParamSet memfragment + length += nal_size;//aBuffer->nFilledLen; + iParamSet.getMemFrag().len = length; // update length + } // release the OMX buffer iOutBufMemoryPool->deallocate(pContext); return OMX_ErrorNone; } + } else if (nal_type == 0x08) // PPS type NAL { @@ -5675,6 +5648,7 @@ OsclSharedPtr PVMFOMXEncNode::WrapOutputBuffer(uint8 *pData, { // skip start code pData += iFirstNALStartCodeSize; + aDataLen -= iFirstNALStartCodeSize; } memFrag.ptr = pData; @@ -5889,7 +5863,7 @@ void PVMFOMXEncNode::DoPrepare(PVMFOMXEncNodeCommand& aCmd) { // try to create component err = OMX_MasterGetHandle(&iOMXEncoder, (OMX_STRING) CompOfRole[ii], (OMX_PTR) this, (OMX_CALLBACKTYPE *) & iCallbacks); - + // if successful, no need to continue if ((err == OMX_ErrorNone) && (iOMXEncoder != NULL)) { oscl_strncpy((OMX_STRING)CompName, (OMX_STRING) CompOfRole[ii], PV_OMX_MAX_COMPONENT_NAME_LENGTH); @@ -5898,22 +5872,16 @@ void PVMFOMXEncNode::DoPrepare(PVMFOMXEncNodeCommand& aCmd) (0, "PVMFOMXEncNode-%s::DoPrepare(): Got Component %s handle ", iNodeTypeId, CompOfRole[ii])); LOGE("PVMFOMXEncNode-%s::DoPrepare(): Got Component %s handle ", iNodeTypeId, CompOfRole[ii]); - if ((CheckComponentForMultRoles((OMX_STRING)CompName, (OMX_STRING)CompOfRole[ii])) && - (CheckComponentCapabilities(&iOutFormat))) - { - // Found a component and it passed all tests. Break out of the loop - break; - } + break; } - - // Component failed negotiations - if (iOMXEncoder != NULL) + else { - OMX_MasterFreeHandle(iOMXEncoder); - iOMXEncoder = NULL; + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, + (0, "PVMFOMXEncNode-%s::DoPrepare(): Cannot get component %s handle, try another component if available", iNodeTypeId, CompOfRole[ii])); + LOGE("PVMFOMXEncNode-%s::DoPrepare(): Cannot get component %s handle, try another component if available", iNodeTypeId, CompOfRole[ii]); } - } + } // whether successful or not, need to free CompOfRoles for (ii = 0; ii < num_comps; ii++) { @@ -5941,12 +5909,123 @@ void PVMFOMXEncNode::DoPrepare(PVMFOMXEncNodeCommand& aCmd) return; } + + if (!iOMXEncoder) { CommandComplete(iInputCommands, aCmd, PVMFErrNoResources); return; } + + // find out how many roles the component supports + OMX_U32 NumRoles; + err = OMX_MasterGetRolesOfComponent((OMX_STRING)CompName, &NumRoles, NULL); + if (err != OMX_ErrorNone) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXEncNode-%s::DoPrepare() Problem getting component roles", iNodeTypeId)); + + CommandComplete(iInputCommands, aCmd, PVMFErrResource); + return; + } + + // if the component supports multiple roles, call OMX_SetParameter + if (NumRoles > 1) + { + OMX_PARAM_COMPONENTROLETYPE RoleParam; + CONFIG_SIZE_AND_VERSION(RoleParam); + oscl_strncpy((OMX_STRING)RoleParam.cRole, (OMX_STRING)Role, OMX_MAX_STRINGNAME_SIZE); + err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamStandardComponentRole, &RoleParam); + if (err != OMX_ErrorNone) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXEncNode-%s::DoPrepare() Problem setting component role", iNodeTypeId)); + + CommandComplete(iInputCommands, aCmd, PVMFErrResource); + return; + } + } + + + // GET CAPABILITY FLAGS FROM PV COMPONENT, IF this fails, use defaults + PV_OMXComponentCapabilityFlagsType Cap_flags; + err = OMX_GetParameter(iOMXEncoder, (OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX, &Cap_flags); + if (err != OMX_ErrorNone) + { + SetDefaultCapabilityFlags(); + } + else + { + iIsOMXComponentMultiThreaded = (OMX_TRUE == Cap_flags.iIsOMXComponentMultiThreaded) ? true : false; + iOMXComponentSupportsExternalInputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalInputBufferAlloc) ? true : false; + iOMXComponentSupportsExternalOutputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalOutputBufferAlloc) ? true : false; + iOMXComponentSupportsMovableInputBuffers = (OMX_TRUE == Cap_flags.iOMXComponentSupportsMovableInputBuffers) ? true : false; + iOMXComponentSupportsPartialFrames = (OMX_TRUE == Cap_flags.iOMXComponentSupportsPartialFrames) ? true : false; + iOMXComponentUsesNALStartCodes = (OMX_TRUE == Cap_flags.iOMXComponentUsesNALStartCodes) ? true : false; + iOMXComponentCanHandleIncompleteFrames = (OMX_TRUE == Cap_flags.iOMXComponentCanHandleIncompleteFrames) ? true : false; + iOMXComponentUsesFullAVCFrames = (OMX_TRUE == Cap_flags.iOMXComponentUsesFullAVCFrames) ? true : false; + } + + /* iOMXComponentUsesNALStartCodes: The component inserts start codes before NALs + + iOMXComponentUsesFullAVCFrames + && !iOMXComponentUsesNALStartCodes: The component outputs full frames, and stores NAL start codes using the + OMX ExtraData structure in the output buffer + iOMXComponentUsesFullAVCFrames + && iOMXComponentUsesNALStartCodes: The component outputs full frames, and delimits NALs by their start codes + + iOutFormat == PVMF_MIME_H264_VIDEO_RAW + && !iOMXComponentUsesNALStartCodes: The node inserts the start codes and hides them / exposes them when needed + + iOutFormat == PVMF_MIME_H264_VIDEO_RAW + && !iOMXComponentUsesNALStartCodes + && iOMXComponentUsesFullAVCFrames: This is an invalid combination. If the node wants raw output, and the component + uses full frames, and no start codes, then there is no way to detect the + NAL boundaries. + + */ + + if (iOutFormat == PVMF_MIME_H264_VIDEO_RAW && + iOMXComponentUsesFullAVCFrames && !iOMXComponentUsesNALStartCodes) + { + // This is an invalid combination (see above). Therefore, return an error. + + + PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXEncNode-%s::DoPrepare() Component cannot support %s format", iNodeTypeId, PVMF_MIME_H264_VIDEO_RAW)); + + CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported); + return; + } + + + // find out about parameters + if ((iOutFormat == PVMF_MIME_AMR_IETF) || (iOutFormat == PVMF_MIME_AMRWB_IETF) || (iOutFormat == PVMF_MIME_AMR_IF2) || + (iOutFormat == PVMF_MIME_ADIF) || (iOutFormat == PVMF_MIME_ADTS) || (iOutFormat == PVMF_MIME_MPEG4_AUDIO)) + { + if (!NegotiateAudioComponentParameters()) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXEncNode-%s::DoPrepare() Cannot get component parameters", iNodeTypeId)); + + CommandComplete(iInputCommands, aCmd, PVMFErrNoResources); + return; + } + } + else + { + + if (!NegotiateVideoComponentParameters()) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXEncNode-%s::DoPrepare() Cannot get component parameters", iNodeTypeId)); + + CommandComplete(iInputCommands, aCmd, PVMFErrNoResources); + return; + } + } + // create active objects to handle callbacks in case of multithreaded implementation // NOTE: CREATE THE THREADSAFE CALLBACK AOs REGARDLESS OF WHETHER MULTITHREADED COMPONENT OR NOT @@ -6533,7 +6612,26 @@ void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd) err = OMX_GetState(iOMXEncoder, &sState); if (err != OMX_ErrorNone) { - sState = OMX_StateInvalid; + //Error condition report + PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXEncNode-%s::DoReset(): Can't get State of encoder!", iNodeTypeId)); + if (iResetInProgress) + { + // cmd is in current q + iResetInProgress = false; + if ((iCurrentCommand.size() > 0) && + (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET) + ) + { + CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource); + } + + } + else + { + CommandComplete(iInputCommands, aCmd, PVMFErrResource); + } + return; } if (sState == OMX_StateLoaded) @@ -6547,9 +6645,47 @@ void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd) (0, "PVMFOMXEncNode-%s::DoReset() OMX comp is in loaded state. Wait for official callback to change variables etc.", iNodeTypeId)); return; } + else + { + //delete all ports and notify observer. + if (iInPort) + { + OSCL_DELETE(((PVMFOMXEncPort*)iInPort)); + iInPort = NULL; + } + + if (iOutPort) + { + OSCL_DELETE(((PVMFOMXEncPort*)iOutPort)); + iOutPort = NULL; + } + + iDataIn.Unbind(); + + + // Reset the metadata key list + iAvailableMetadataKeys.clear(); + + iEndOfDataReached = false; + iIsEOSSentToComponent = false; + iIsEOSReceivedFromComponent = false; + + + iProcessingState = EPVMFOMXEncNodeProcessingState_Idle; + //logoff & go back to Created state. + SetState(EPVMFNodeIdle); + + CommandComplete(iInputCommands, aCmd, PVMFSuccess); + + //CommandComplete(iInputCommands, aCmd, PVMFErrResource); + return; + } } - else if (sState == OMX_StateIdle) + + if (sState == OMX_StateIdle) { + + //this command is asynchronous. move the command from //the input command queue to the current command, where //it will remain until it is completed. @@ -6670,7 +6806,7 @@ void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd) return; } - else if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause)) + if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause)) { //this command is asynchronous. move the command from //the input command queue to the current command, where @@ -6747,16 +6883,29 @@ void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd) iProcessingState = EPVMFOMXEncNodeProcessingState_Stopping; } return; + } else { //Error condition report PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::DoReset(): Encoder is not in the Idle state! %d", iNodeTypeId, sState )); - //do it here rather than relying on DTOR to avoid node reinit problems. - DeleteOMXEncoder(); - //still return success. - }//end of if (sState == OMX_StateLoaded) + (0, "PVMFOMXEncNode-%s::DoReset(): Encoder is not in the Idle state!", iNodeTypeId)); + if (iResetInProgress) + { + iResetInProgress = false; + if ((iCurrentCommand.size() > 0) && + (iCurrentCommand.front().iCmd == PVMFOMXEncNodeCommand::PVOMXENC_NODE_CMD_RESET) + ) + { + CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrInvalidState); + } + } + else + { + CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState); + } + break; + }//end of if (sState == OMX_StateIdle) }//end of if (iOMXEncoder != NULL) //delete all ports and notify observer. @@ -10039,121 +10188,3 @@ uint32 PVMFOMXEncNode::ConvertOMXTicksIntoTimestamp(const OMX_TICKS &src) return (uint32) current_ts; } - -//////////////////////////////////////////////////////////////////////////////// -bool PVMFOMXEncNode::CheckComponentForMultRoles(OMX_STRING aCompName, OMX_STRING aRole) -{ - OMX_ERRORTYPE err = OMX_ErrorNone; - - // find out how many roles the component supports - OMX_U32 NumRoles; - err = OMX_MasterGetRolesOfComponent(aCompName, &NumRoles, NULL); - if (err != OMX_ErrorNone) - { - PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::CheckComponentForMultRoles() Problem getting component roles", iNodeTypeId)); - - return false; - } - - // if the component supports multiple roles, call OMX_SetParameter - if (NumRoles > 1) - { - OMX_PARAM_COMPONENTROLETYPE RoleParam; - CONFIG_SIZE_AND_VERSION(RoleParam); - oscl_strncpy((OMX_STRING)RoleParam.cRole, aRole, OMX_MAX_STRINGNAME_SIZE); - err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamStandardComponentRole, &RoleParam); - if (err != OMX_ErrorNone) - { - PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::CheckComponentForMultRoles() Problem setting component role", iNodeTypeId)); - - return false; - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool PVMFOMXEncNode::CheckComponentCapabilities(PVMFFormatType* aOutFormat) -{ - OMX_ERRORTYPE err = OMX_ErrorNone; - - // GET CAPABILITY FLAGS FROM PV COMPONENT, IF this fails, use defaults - PV_OMXComponentCapabilityFlagsType Cap_flags; - err = OMX_GetParameter(iOMXEncoder, (OMX_INDEXTYPE) PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX, &Cap_flags); - if (err != OMX_ErrorNone) - { - SetDefaultCapabilityFlags(); - } - else - { - iIsOMXComponentMultiThreaded = (OMX_TRUE == Cap_flags.iIsOMXComponentMultiThreaded) ? true : false; - iOMXComponentSupportsExternalInputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalInputBufferAlloc) ? true : false; - iOMXComponentSupportsExternalOutputBufferAlloc = (OMX_TRUE == Cap_flags.iOMXComponentSupportsExternalOutputBufferAlloc) ? true : false; - iOMXComponentSupportsMovableInputBuffers = (OMX_TRUE == Cap_flags.iOMXComponentSupportsMovableInputBuffers) ? true : false; - iOMXComponentSupportsPartialFrames = (OMX_TRUE == Cap_flags.iOMXComponentSupportsPartialFrames) ? true : false; - iOMXComponentUsesNALStartCodes = (OMX_TRUE == Cap_flags.iOMXComponentUsesNALStartCodes) ? true : false; - iOMXComponentCanHandleIncompleteFrames = (OMX_TRUE == Cap_flags.iOMXComponentCanHandleIncompleteFrames) ? true : false; - iOMXComponentUsesFullAVCFrames = (OMX_TRUE == Cap_flags.iOMXComponentUsesFullAVCFrames) ? true : false; - } - - /* iOMXComponentUsesNALStartCodes: The component inserts start codes before NALs - - iOMXComponentUsesFullAVCFrames - && !iOMXComponentUsesNALStartCodes: The component outputs full frames, and stores NAL start codes using the - OMX ExtraData structure in the output buffer - - iOMXComponentUsesFullAVCFrames - && iOMXComponentUsesNALStartCodes: The component outputs full frames, and delimits NALs by their start codes - - aOutFormat == PVMF_MIME_H264_VIDEO_RAW - && !iOMXComponentUsesNALStartCodes: The node inserts the start codes and hides them / exposes them when needed - - aOutFormat == PVMF_MIME_H264_VIDEO_RAW - && !iOMXComponentUsesNALStartCodes - && iOMXComponentUsesFullAVCFrames: This is an invalid combination. If the node wants raw output, and the component - uses full frames, and no start codes, then there is no way to detect the - NAL boundaries. - */ - - if (*aOutFormat == PVMF_MIME_H264_VIDEO_RAW && - iOMXComponentUsesFullAVCFrames && !iOMXComponentUsesNALStartCodes) - { - // This is an invalid combination (see above). Therefore, return an error. - - - PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Component cannot support %s format", iNodeTypeId, PVMF_MIME_H264_VIDEO_RAW)); - - return false; - } - - // find out about parameters - if (aOutFormat->isAudio()) - { - if (!NegotiateAudioComponentParameters()) - { - PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Cannot get component parameters", iNodeTypeId)); - - return false; - } - } - else - { - - if (!NegotiateVideoComponentParameters()) - { - PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "PVMFOMXEncNode-%s::CheckComponentCapabilities() Cannot get component parameters", iNodeTypeId)); - - return false; - } - } - - return true; -} - - -- cgit v1.2.3