aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CleanSpec.mk49
-rw-r--r--nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp441
2 files changed, 265 insertions, 225 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 000000000..b84e1b65e
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp b/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp
index 960714fbe..d345e9a0a 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 = 60; // (in relation to (should be higher than) frame rate )
+ Mpeg4Type.nTimeIncRes = 1000; // (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 = OMX_Video_ControlRateDisable; //static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
+ BitRateType.eControlRate = static_cast<OMX_VIDEO_CONTROLRATETYPE>(iVideoEncodeParam.iRateControlType);
BitRateType.nTargetBitrate = iVideoEncodeParam.iBitRate[0];
Err = OMX_SetParameter(iOMXEncoder, OMX_IndexParamVideoBitrate, &BitRateType);
if (OMX_ErrorNone != Err)
@@ -4694,9 +4694,14 @@ 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
@@ -4956,6 +4961,46 @@ 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
@@ -5050,7 +5095,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))
{
@@ -5069,7 +5114,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, false))
+ if (AVCAnnexBGetNALUnit(pData, &pTemp, (int32*)&size, true))
{
iFirstNALStartCodeSize = (uint32)pTemp - (uint32)pData;
}
@@ -5077,7 +5122,6 @@ 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 */
@@ -5207,42 +5251,46 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC
if (nal_type == 0x07) // SPS type NAL
{
+ int32 nal_size = aBuffer->nFilledLen;
+ AVCAnnexBGetNALUnit(aBuffer->pBuffer, &bitstream, (int32*)&nal_size, false);
// can the SPS fit into the buffer
if (aBuffer->nFilledLen <= (capacity - length))
{
iSPSs[iNumSPSs].ptr = destptr;
- iSPSs[iNumSPSs++].len = nal_size;//aBuffer->nFilledLen;
+ iSPSs[iNumSPSs++].len = nal_size;
- oscl_memcpy(destptr, pBufdata, nal_size); // copy SPS into iParamSet memfragment
- length += nal_size;
+ oscl_memcpy(destptr, pBufdata, nal_size); // copy SPS into iParamSet memfragment
+ length += nal_size;
iParamSet.getMemFrag().len = length; // update length
destptr += nal_size;
+ if (nal_size < aBuffer->nFilledLen) {
+ LOGD("SPS and PPS are located within a single output buffer");
+ 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;
+ oscl_memcpy(destptr, bitstream, nal_size); // copy PPS into iParamSet memfragment$
+ length += nal_size;
+ iParamSet.getMemFrag().len = length; // update length
+ }
+ }
+ }
}
- 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
{
-
+ LOGD("SPS and PPS are located in separate output buffers");
// can the PPS fit into the buffer?
if (aBuffer->nFilledLen <= (capacity - length))
{
@@ -5863,7 +5911,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);
@@ -5872,16 +5920,22 @@ 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]);
- break;
+ 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;
+ }
}
- else
+
+ // Component failed negotiations
+ if (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]);
+ OMX_MasterFreeHandle(iOMXEncoder);
+ iOMXEncoder = NULL;
}
-
}
+
// whether successful or not, need to free CompOfRoles
for (ii = 0; ii < num_comps; ii++)
{
@@ -5909,123 +5963,12 @@ 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
@@ -6612,26 +6555,7 @@ void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd)
err = OMX_GetState(iOMXEncoder, &sState);
if (err != OMX_ErrorNone)
{
- //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;
+ sState = OMX_StateInvalid;
}
if (sState == OMX_StateLoaded)
@@ -6645,47 +6569,9 @@ 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;
- }
}
-
- if (sState == OMX_StateIdle)
+ else 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.
@@ -6806,7 +6692,7 @@ void PVMFOMXEncNode::DoReset(PVMFOMXEncNodeCommand& aCmd)
return;
}
- if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
+ else if ((sState == OMX_StateExecuting) || (sState == OMX_StatePause))
{
//this command is asynchronous. move the command from
//the input command queue to the current command, where
@@ -6883,29 +6769,16 @@ 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!", 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)
+ (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)
}//end of if (iOMXEncoder != NULL)
//delete all ports and notify observer.
@@ -10188,3 +10061,121 @@ 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;
+}
+
+