diff options
-rw-r--r-- | android/metadatadriver.cpp | 10 | ||||
-rw-r--r-- | codecs_v2/utilities/m4v_config_parser/src/m4v_config_parser.cpp | 63 | ||||
-rw-r--r-- | engines/author/src/pvauthorengine.cpp | 2 | ||||
-rw-r--r-- | fileformats/mp3/parser/src/mp3parser.cpp | 14 | ||||
-rw-r--r-- | nodes/pvaacffparsernode/src/pvmf_aacffparser_node.cpp | 12 | ||||
-rw-r--r-- | nodes/pvamrffparsernode/src/pvmf_amrffparser_node.cpp | 12 | ||||
-rw-r--r-- | nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp | 35 | ||||
-rw-r--r-- | nodes/pvomxaudiodecnode/src/pvmf_omx_audiodec_node.cpp | 6 | ||||
-rw-r--r-- | nodes/pvomxbasedecnode/src/pvmf_omx_basedec_node.cpp | 152 | ||||
-rw-r--r-- | nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp | 384 | ||||
-rw-r--r-- | nodes/pvomxencnode/src/pvmf_omx_enc_node.h | 3 | ||||
-rw-r--r-- | nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp | 6 | ||||
-rw-r--r-- | nodes/pvwavffparsernode/src/pvmf_wavffparser_node.cpp | 6 |
13 files changed, 346 insertions, 359 deletions
diff --git a/android/metadatadriver.cpp b/android/metadatadriver.cpp index 128554f08..8b594425d 100644 --- a/android/metadatadriver.cpp +++ b/android/metadatadriver.cpp @@ -107,7 +107,15 @@ int MetadataDriver::retrieverThread() AddToScheduler(); RunIfNotReady(); OsclExecScheduler *sched = OsclExecScheduler::Current(); - sched->StartScheduler(); + + { + OsclLeaveCode error = OsclErrNone; + OSCL_TRY(error, sched->StartScheduler()); + OSCL_FIRST_CATCH_ANY(error, + // Some AO did a leave, log it + LOGE("Ln %d Player Engine AO did a leave, error=%d", __LINE__, error) + ); + } mSyncSem->Signal(); // Signal that doSetDataSource() is done. OsclScheduler::Cleanup(); diff --git a/codecs_v2/utilities/m4v_config_parser/src/m4v_config_parser.cpp b/codecs_v2/utilities/m4v_config_parser/src/m4v_config_parser.cpp index c06d81389..7ba6e4a70 100644 --- a/codecs_v2/utilities/m4v_config_parser/src/m4v_config_parser.cpp +++ b/codecs_v2/utilities/m4v_config_parser/src/m4v_config_parser.cpp @@ -99,6 +99,23 @@ int16 SearchNextM4VFrame(mp4StreamType *psBits) return status; } +int16 SearchVOLHeader(mp4StreamType *psBits) +{ + uint32 codeword = 0; + int16 status = 0; + do + { + /* Search for VOL_HEADER */ + status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ + if (status != 0) + return MP4_INVALID_VOL_PARAM; + + status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); + } + while ((codeword != VOL_START_CODE) && (status == 0)); + return status; +} + OSCL_EXPORT_REF int16 iGetM4VConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height) { int16 status; @@ -153,7 +170,12 @@ OSCL_EXPORT_REF int16 iDecodeVOLHeader(mp4StreamType *psBits, int32 *width, int3 ReadBits(psBits, 32, &codeword); - if (codeword != VISUAL_OBJECT_START_CODE) return MP4_INVALID_VOL_PARAM; + if (codeword != VISUAL_OBJECT_START_CODE) + { + if (SearchVOLHeader(psBits) != 0) + return MP4_INVALID_VOL_PARAM; + goto decode_vol; + } /* is_visual_object_identifier */ ReadBits(psBits, 1, &codeword); @@ -192,17 +214,8 @@ OSCL_EXPORT_REF int16 iDecodeVOLHeader(mp4StreamType *psBits, int32 *width, int3 } else { - int16 status = 0; - do - { - /* Search for VOL_HEADER */ - status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ - if (status != 0) - return MP4_INVALID_VOL_PARAM; - - status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); - } - while ((codeword != VOL_START_CODE) && (status == 0)); + if (SearchVOLHeader(psBits) != 0) + return MP4_INVALID_VOL_PARAM; goto decode_vol; } /* next_start_code() */ @@ -236,17 +249,8 @@ OSCL_EXPORT_REF int16 iDecodeVOLHeader(mp4StreamType *psBits, int32 *width, int3 } else { - int16 status = 0; - do - { - /* Search for VOL_HEADER */ - status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ - if (status != 0) - return MP4_INVALID_VOL_PARAM; - - status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); - } - while ((codeword != VOL_START_CODE) && (status == 0)); + if (SearchVOLHeader(psBits) != 0) + return MP4_INVALID_VOL_PARAM; goto decode_vol; } } @@ -400,17 +404,8 @@ decode_vol: } else { - int16 status = 0; - do - { - /* Search for VOL_HEADER */ - status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ - if (status != 0) - return MP4_INVALID_VOL_PARAM; - - status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); - } - while ((codeword != VOL_START_CODE) && (status == 0)); + if (SearchVOLHeader(psBits) != 0) + return MP4_INVALID_VOL_PARAM; goto decode_vol; } } diff --git a/engines/author/src/pvauthorengine.cpp b/engines/author/src/pvauthorengine.cpp index e949107d0..4c790bacb 100644 --- a/engines/author/src/pvauthorengine.cpp +++ b/engines/author/src/pvauthorengine.cpp @@ -1469,6 +1469,8 @@ PVMFStatus PVAuthorEngine::DoStop(PVEngineCommand& aCmd) switch (GetPVAEState()) { + case PVAE_STATE_INITIALIZED: + return PVMFSuccess; case PVAE_STATE_RECORDING: case PVAE_STATE_PAUSED: iAuthorClock.Stop(); diff --git a/fileformats/mp3/parser/src/mp3parser.cpp b/fileformats/mp3/parser/src/mp3parser.cpp index a060d79f2..419cabd4c 100644 --- a/fileformats/mp3/parser/src/mp3parser.cpp +++ b/fileformats/mp3/parser/src/mp3parser.cpp @@ -438,7 +438,7 @@ MP3ErrorType MP3Parser::ParseMP3File(PVFile * fpUsed, bool aEnableCRC) // SAVE THE CURRENT FILE POSITION errCode = MP3Utils::SeektoOffset(fp, 0, Oscl_File::SEEKSET); // try to retrieve the file size - if (fp->GetCPM() == NULL && MP3Utils::getCurrentFileSize(fp, iLocalFileSize)) + if (fp->GetFileBufferingCapacity() == 0 && MP3Utils::getCurrentFileSize(fp, iLocalFileSize)) { iLocalFileSizeSet = true; iInitSearchFileSize = OSCL_MIN(iInitSearchFileSize, iLocalFileSize); @@ -758,7 +758,7 @@ MP3ErrorType MP3Parser::ScanMP3File(PVFile * fpUsed, uint32 aFramesToScan) if (fpUsed->Read(pFrameHeader, 1, MP3_FRAME_HEADER_SIZE) != MP3_FRAME_HEADER_SIZE) { - if (fpUsed->GetCPM() == NULL) + if (fpUsed->GetFileBufferingCapacity() == 0) { iDurationScanComplete = true; } @@ -1362,7 +1362,7 @@ uint32 MP3Parser::GetDuration(bool aMetadataDuration) uint32 clipDuration = 0; // local clip playback - if (!fp->GetCPM()) + if (fp->GetFileBufferingCapacity() == 0) { // if scanning is complete, send the clip duration from scan // else if vbri/xing headers exist send duration from that @@ -1795,7 +1795,7 @@ uint32 MP3Parser::SeekToTimestamp(uint32 timestampInMsec) { uint32 SeekPosition = 0; SeekPosition = SeekPointFromTimestamp(timestampInMsec); - if (!((!fp->GetCPM()) && (SeekPosition == iLocalFileSize) && (timestampInMsec == iClipDurationInMsec))) + if (!((fp->GetFileBufferingCapacity() == 0) && (SeekPosition == iLocalFileSize) && (timestampInMsec == iClipDurationInMsec))) { SeekPosition += StartOffset; } @@ -1926,7 +1926,7 @@ uint32 MP3Parser::SeekPointFromTimestamp(uint32 ×tamp) * calculated on the basis of average bit rate **/ int32 avgBR = 0; - if (fp->GetCPM()) + if (fp->GetFileBufferingCapacity() > 0) { avgBR = iAvgBitrateInbps; } @@ -1950,7 +1950,7 @@ uint32 MP3Parser::SeekPointFromTimestamp(uint32 ×tamp) * Since in PD/PS scenarios we might not be having enough data to find the seek point * We can find the seek point when we are resuming the playback **/ - if (seekPoint > 0 && !fp->GetCPM()) + if (seekPoint > 0 && fp->GetFileBufferingCapacity() == 0) { // seek to the reposition point location MP3Utils::SeektoOffset(fp, seekPoint + StartOffset, Oscl_File::SEEKSET); @@ -2015,7 +2015,7 @@ MP3ErrorType MP3Parser::mp3FindSync(uint32 seekPoint, uint32 &syncOffset, PVFile syncOffset = 0; iMaxSyncBufferSize = 627; /* default for 192 kbps, 44.1 kHz */ - if (aFile->GetCPM() != NULL) + if (aFile->GetFileBufferingCapacity() > 0) { iLocalFileSizeSet = (int32)MP3Utils::getCurrentFileSize(aFile, iLocalFileSize); } diff --git a/nodes/pvaacffparsernode/src/pvmf_aacffparser_node.cpp b/nodes/pvaacffparsernode/src/pvmf_aacffparser_node.cpp index aa9a6814b..3a53d1068 100644 --- a/nodes/pvaacffparsernode/src/pvmf_aacffparser_node.cpp +++ b/nodes/pvaacffparsernode/src/pvmf_aacffparser_node.cpp @@ -1239,17 +1239,9 @@ void PVMFAACFFParserNode::DoReset(PVMFAACFFParserNodeCommand& aCmd) iDownloadProgressInterface->cancelResumeNotification(); } - if (iFileHandle != NULL) + if ((iAACParser) && (iCPM)) { - /* Indicates that the init was successfull */ - if ((iCPM)) - { - SendUsageComplete(); - } - else - { - CompleteReset(); - } + SendUsageComplete(); } else { diff --git a/nodes/pvamrffparsernode/src/pvmf_amrffparser_node.cpp b/nodes/pvamrffparsernode/src/pvmf_amrffparser_node.cpp index 4b6dc5989..b4c9ef8e3 100644 --- a/nodes/pvamrffparsernode/src/pvmf_amrffparser_node.cpp +++ b/nodes/pvamrffparsernode/src/pvmf_amrffparser_node.cpp @@ -1655,17 +1655,9 @@ void PVMFAMRFFParserNode::DoReset(PVMFAMRFFNodeCommand& aCmd) iDownloadProgressInterface->cancelResumeNotification(); } MoveCmdToCurrentQueue(aCmd); - if (iFileHandle != NULL) + if ((iAMRParser) && (iCPM)) { - /* Indicates that the init was successfull */ - if ((iCPM)) - { - SendUsageComplete(); - } - else - { - CompleteReset(); - } + SendUsageComplete(); } else { diff --git a/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp b/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp index c9000c6e2..889ae6033 100644 --- a/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp +++ b/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp @@ -4435,14 +4435,36 @@ bool PVMFMP4FFParserNode::RetrieveTrackData(PVMP4FFNodeTrackPortInfo& aTrackPort { status = FindBestThumbnailKeyFrame(trackid, keySampleNum); } - if (PVMFSuccess != status) + if (PVMFSuccess == status) { - // no keyframe exists in the file, hence thumbnail could not - // be retrieved, Treat this as EOS - aTrackPortInfo.iState = PVMP4FFNodeTrackPortInfo::TRACKSTATE_SEND_ENDOFTRACK; - return false; + retval = iMP4FileHandle->getKeyMediaSampleNumAt(trackid, keySampleNum, &iGau); + } + else + { + // No keyframe available. + // Go for the best possible solution if no key frames are available in stss atom. + // Just try to retrieve the first video frame, this could result in a distorted frame + // if first video frame is not a sync sample but it might be still better than no thumbnail. + // Before retrieving the frame just make sure that there are samples in video track, + // if there are no samples in the video track just report failure from here. No thumbnail possible + if (iMP4FileHandle->getSampleCountInTrack(trackid) > 0) + { + // Just retrieve the first video sample + PVMF_MP4FFPARSERNODE_LOGDATATRAFFIC( + (0, "PVMFMP4FFParserNode:RetrieveTrackData - FindBestThumbnailKeyFrame failed, best possible solution fetch the first video sample")); + numsamples = 1; + retval = iMP4FileHandle->getNextBundledAccessUnits(trackid, &numsamples, &iGau); + } + else + { + // no sample in the video track. + PVMF_MP4FFPARSERNODE_LOGDATATRAFFIC( + (0, "PVMFMP4FFParserNode:RetrieveTrackData - FindBestThumbnailKeyFrame failed, No sample in video track just return EndOfTrack")); + aTrackPortInfo.iState = PVMP4FFNodeTrackPortInfo::TRACKSTATE_SEND_ENDOFTRACK; + return false; + } } - retval = iMP4FileHandle->getKeyMediaSampleNumAt(trackid, keySampleNum, &iGau); + if (retval == EVERYTHING_FINE || retval == END_OF_TRACK) { numsamples = 1; @@ -8839,6 +8861,7 @@ PVMFStatus PVMFMP4FFParserNode::FindBestThumbnailKeyFrame(uint32 aId, uint32& aK } else { + PVMF_MP4FFPARSERNODE_LOGDATATRAFFIC((0, "PVMFMP4FFParserNode:FindBestThumbnailKeyFrame - No Samples present in SyncSample Table")); numsamples = 0; aKeyFrameNum = 0; return PVMFFailure; diff --git a/nodes/pvomxaudiodecnode/src/pvmf_omx_audiodec_node.cpp b/nodes/pvomxaudiodecnode/src/pvmf_omx_audiodec_node.cpp index f38e8e906..08cc70b1a 100644 --- a/nodes/pvomxaudiodecnode/src/pvmf_omx_audiodec_node.cpp +++ b/nodes/pvomxaudiodecnode/src/pvmf_omx_audiodec_node.cpp @@ -1959,6 +1959,12 @@ OMX_ERRORTYPE PVMFOMXAudioDecNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE ReportInfoEvent(PVMFInfoProcessingFailure, NULL); } + else if (aData1 == (OMX_U32) OMX_ErrorInvalidState) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXAudioDecNode::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState")); + HandleComponentStateChange(OMX_StateInvalid); + } else { diff --git a/nodes/pvomxbasedecnode/src/pvmf_omx_basedec_node.cpp b/nodes/pvomxbasedecnode/src/pvmf_omx_basedec_node.cpp index fa5864170..9b927ef3b 100644 --- a/nodes/pvomxbasedecnode/src/pvmf_omx_basedec_node.cpp +++ b/nodes/pvomxbasedecnode/src/pvmf_omx_basedec_node.cpp @@ -3575,6 +3575,61 @@ OSCL_EXPORT_REF void PVMFOMXBaseDecNode::HandleComponentStateChange(OMX_U32 deco PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::HandleComponentStateChange: OMX_StateInvalid reached", iName.Str())); + if (iOMXDecoder == NULL) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, + (0, "%s::HandleComponentStateChange: cleanup already done. Do nothing", iName.Str())); + return; + } + + //Cleanup encoder + DeleteOMXBaseDecoder(); + //Stop using OMX component + iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Idle; + + if (iCurrentCommand.size() > 0) + {// CANNOT be CANCEL or CANCEL_ALL. Just to cmd completion for the reset + if (iCurrentCommand.front().iCmd == PVMFOMXBaseDecNodeCommand::PVOMXBASEDEC_NODE_CMD_RESET) + { + //delete all ports and notify observer. + if (iInPort) + { + OSCL_DELETE(((PVMFOMXDecPort*)iInPort)); + iInPort = NULL; + } + + if (iOutPort) + { + OSCL_DELETE(((PVMFOMXDecPort*)iOutPort)); + iOutPort = NULL; + } + + iDataIn.Unbind(); + + // Reset the metadata key list + iAvailableMetadataKeys.clear(); + + iEndOfDataReached = false; + iIsEOSSentToComponent = false; + iIsEOSReceivedFromComponent = false; + + //logoff & go back to Created state. + SetState(EPVMFNodeIdle); + CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess); + } + else + { + SetState(EPVMFNodeError); + CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource); + } + } + else + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, + (0, "%s::HandleComponentStateChange: ERROR state transition event while OMX client does NOT have any pending state transition request", iName.Str())); + SetState(EPVMFNodeError); + ReportErrorEvent(PVMFErrResourceConfiguration); + } break; }//end of case OMX_StateInvalid @@ -4804,26 +4859,7 @@ void PVMFOMXBaseDecNode::DoReset(PVMFOMXBaseDecNodeCommand& aCmd) err = OMX_GetState(iOMXDecoder, &sState); if (err != OMX_ErrorNone) { - //Error condition report - PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "%s::DoReset(): Can't get State of decoder!", iName.Str())); - if (iResetInProgress) - { - // cmd is in current q - iResetInProgress = false; - if ((iCurrentCommand.size() > 0) && - (iCurrentCommand.front().iCmd == PVMFOMXBaseDecNodeCommand::PVOMXBASEDEC_NODE_CMD_RESET) - ) - { - CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrResource); - } - - } - else - { - CommandComplete(iInputCommands, aCmd, PVMFErrResource); - } - return; + sState = OMX_StateInvalid; } if (sState == OMX_StateLoaded) @@ -4837,58 +4873,9 @@ void PVMFOMXBaseDecNode::DoReset(PVMFOMXBaseDecNodeCommand& aCmd) (0, "%s::DoReset() OMX comp is in loaded state. Wait for official callback to change variables etc.", iName.Str())); return; } - else - { - - //CommandComplete(iInputCommands, aCmd, PVMFErrResource); - //delete all ports and notify observer. - if (iInPort) - { - OSCL_DELETE(((PVMFOMXDecPort*)iInPort)); - iInPort = NULL; - } - - if (iOutPort) - { - OSCL_DELETE(((PVMFOMXDecPort*)iOutPort)); - iOutPort = NULL; - } - - iDataIn.Unbind(); - - - // Reset the metadata key list - iAvailableMetadataKeys.clear(); - - iEndOfDataReached = false; - iIsEOSSentToComponent = false; - iIsEOSReceivedFromComponent = false; - - if (iOMXComponentUsesFullAVCFrames) - { - iNALCount = 0; - oscl_memset(iNALSizeArray, 0, sizeof(uint32) * MAX_NAL_PER_FRAME); // 100 is max number of NALs - } - - // reset dynamic port reconfig flags - no point continuing with port reconfig - // if we start again - we'll have to do prepare and send new config etc. - iSecondPortReportedChange = false; - iDynamicReconfigInProgress = false; - - iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Idle; - - SetState(EPVMFNodeIdle); - - CommandComplete(iInputCommands, aCmd, PVMFSuccess); - - 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. @@ -5009,8 +4996,7 @@ void PVMFOMXBaseDecNode::DoReset(PVMFOMXBaseDecNodeCommand& 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 @@ -5086,23 +5072,11 @@ void PVMFOMXBaseDecNode::DoReset(PVMFOMXBaseDecNodeCommand& aCmd) { //Error condition report PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, - (0, "%s::DoReset(): Decoder is not in the Idle state!", iName.Str())); - if (iResetInProgress) - { - iResetInProgress = false; - if ((iCurrentCommand.size() > 0) && - (iCurrentCommand.front().iCmd == PVMFOMXBaseDecNodeCommand::PVOMXBASEDEC_NODE_CMD_RESET) - ) - { - CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrInvalidState); - } - } - else - { - CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState); - } - break; - }//end of if (sState == OMX_StateIdle) + (0, "%s::DoReset(): Decoder is not in the Idle state! %d", iName.Str(), sState)); + //do it here rather than relying on DTOR to avoid node reinit problems. + DeleteOMXBaseDecoder(); + //still return success. + }//end of if (sState == OMX_StateLoaded) }//end of if (iOMXDecoder != NULL) //delete all ports and notify observer. diff --git a/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp b/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp index 6b58a0064..341677ed8 100644 --- a/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp +++ b/nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp @@ -3991,7 +3991,7 @@ bool PVMFOMXEncNode::SendInputBufferToOMXComponent() iDataIn->getFormatSpecificInfo(fsifrag); if(sizeof(OsclAny*) != fsifrag.getMemFrag().len ) { - PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_ERR, + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXEncNode-%s::SendInputBufferToOMXComponent() - ERROR buffer size %d", iNodeTypeId, fsifrag.getMemFrag().len )); return false; } @@ -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 @@ -5844,7 +5889,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); @@ -5853,16 +5898,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++) { @@ -5890,123 +5941,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 @@ -6593,26 +6533,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) @@ -6626,47 +6547,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. @@ -6787,7 +6670,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 @@ -6864,29 +6747,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. @@ -10169,3 +10039,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; +} + + diff --git a/nodes/pvomxencnode/src/pvmf_omx_enc_node.h b/nodes/pvomxencnode/src/pvmf_omx_enc_node.h index e132d883a..31026d4a1 100644 --- a/nodes/pvomxencnode/src/pvmf_omx_enc_node.h +++ b/nodes/pvomxencnode/src/pvmf_omx_enc_node.h @@ -1353,7 +1353,8 @@ class PVMFOMXEncNode uint32 iFrameCounter; - + bool CheckComponentForMultRoles(OMX_STRING aCompName, OMX_STRING aRole); + bool CheckComponentCapabilities(PVMFFormatType* aOutFormat); uint32 iAvgBitrateValue; bool iResetInProgress; diff --git a/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp b/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp index 780665d1c..54a213027 100644 --- a/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp +++ b/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp @@ -1379,6 +1379,12 @@ OMX_ERRORTYPE PVMFOMXVideoDecNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE ReportInfoEvent(PVMFInfoProcessingFailure, NULL); } + else if (aData1 == (OMX_U32) OMX_ErrorInvalidState) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, + (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState")); + HandleComponentStateChange(OMX_StateInvalid); + } else { diff --git a/nodes/pvwavffparsernode/src/pvmf_wavffparser_node.cpp b/nodes/pvwavffparsernode/src/pvmf_wavffparser_node.cpp index 1b288e50d..81be8aee1 100644 --- a/nodes/pvwavffparsernode/src/pvmf_wavffparser_node.cpp +++ b/nodes/pvwavffparsernode/src/pvmf_wavffparser_node.cpp @@ -1840,7 +1840,7 @@ PVMFStatus PVMFWAVFFParserNode::GetMediaPresentationInfo(PVMFMediaPresentationIn uint32 duration_sec = wavinfo.NumSamples / wavinfo.SampleRate; uint32 duration_msec = wavinfo.NumSamples % wavinfo.SampleRate; - uint32 duration = (duration_msec * 1000) / wavinfo.NumSamples + duration_sec * 1000 ; + uint32 duration = (duration_msec * 1000) / wavinfo.SampleRate + duration_sec * 1000 ; aInfo.setDurationValue(duration); // Current version of WAV parser is limited to 1 channel @@ -1998,7 +1998,7 @@ void PVMFWAVFFParserNode::DoSetDataSourcePosition(PVMFWAVFFNodeCommand& aCmd) // see if targetNPT is greater than or equal to clip duration. uint32 duration_sec = wavinfo.NumSamples / wavinfo.SampleRate; uint32 duration_msec = wavinfo.NumSamples % wavinfo.SampleRate; - uint32 duration = (duration_msec * 1000) / wavinfo.NumSamples + duration_sec * 1000 ; + uint32 duration = (duration_msec * 1000) / wavinfo.SampleRate + duration_sec * 1000 ; uint32 tempTargetNPT = targetNPT; if (tempTargetNPT >= duration) { @@ -2581,7 +2581,7 @@ PVMFStatus PVMFWAVFFParserNode::DoGetNodeMetadataValue(PVMFWAVFFNodeCommand& aCm { uint32 duration_sec = wavinfo.NumSamples / wavinfo.SampleRate; uint32 duration_msec = wavinfo.NumSamples % wavinfo.SampleRate; - uint32 duration = (duration_msec * 1000) / wavinfo.NumSamples + duration_sec * 1000 ; + uint32 duration = (duration_msec * 1000) / wavinfo.SampleRate + duration_sec * 1000 ; KeyVal.value.uint32_value = duration; } // Set the length and capacity |