From 93c7913fc232cde2c8d42571e066d74b2ce8f1a3 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Thu, 19 Feb 2009 10:57:30 -0800 Subject: [PATCH] auto import from //branches/cupcake/...@132276 --- android/Android.mk | 1 + android/android_audio_output.cpp | 8 +++ android/android_audio_output.h | 1 + android/author/android_audio_input.cpp | 42 +++++++++--- android/author/android_audio_input.h | 2 + android/author/android_camera_input.cpp | 8 +-- android/author/authordriver.cpp | 33 ++++----- android/playerdriver.cpp | 80 ++++++++++++++++++++-- fileformats/mp4/composer/src/mpeg4file.cpp | 7 +- nodes/pvamrencnode/src/pvmf_amrenc_node.cpp | 18 +++++ nodes/pvavcencnode/src/pvmf_avcenc_node.cpp | 18 +++++ .../pvmediainputnode/src/pvmf_media_input_node.cpp | 10 ++- nodes/pvmp4ffcomposernode/src/pvmp4ffcn_node.cpp | 49 ++----------- .../src/pvmf_omx_videodec_node.cpp | 46 ++++++------- .../src/pvmf_omx_videoenc_node.cpp | 15 +++- nodes/pvvideoencnode/src/pvmf_videoenc_node.cpp | 21 +++++- oscl/oscl/osclerror/src/oscl_error.cpp | 10 ++- 17 files changed, 254 insertions(+), 115 deletions(-) diff --git a/android/Android.mk b/android/Android.mk index 970fe270..2b4a9255 100644 --- a/android/Android.mk +++ b/android/Android.mk @@ -19,6 +19,7 @@ LOCAL_C_INCLUDES := $(PV_INCLUDES) \ $(PV_TOP)/engines/common/include \ $(PV_TOP)/fileformats/mp4/parser/include \ $(PV_TOP)/pvmi/media_io/pvmiofileoutput/include \ + $(PV_TOP)/pvmi/pvmf/include \ $(PV_TOP)/nodes/pvmediaoutputnode/include \ $(PV_TOP)/nodes/pvmediainputnode/include \ $(PV_TOP)/nodes/pvmp4ffcomposernode/include \ diff --git a/android/android_audio_output.cpp b/android/android_audio_output.cpp index 9e609743..1b8a0211 100644 --- a/android/android_audio_output.cpp +++ b/android/android_audio_output.cpp @@ -137,6 +137,14 @@ PVMFCommandId AndroidAudioOutput::Stop(const OsclAny* aContext) return AndroidAudioMIO::Stop(aContext); } +PVMFCommandId AndroidAudioOutput::Pause(const OsclAny* aContext) +{ + // request output thread to exit + LOGV("Pause(%p)", aContext); + iAudioThreadSem->Signal(); + return AndroidAudioMIO::Pause(aContext); +} + #if 0 PVMFCommandId AndroidAudioOutput::Reset(const OsclAny* aContext) { diff --git a/android/android_audio_output.h b/android/android_audio_output.h index 87bad1d7..1d6b9b14 100644 --- a/android/android_audio_output.h +++ b/android/android_audio_output.h @@ -48,6 +48,7 @@ public: // FIXME: see comment in AndroidAudioOutput::Stop() implementation virtual PVMFCommandId Stop(const OsclAny* aContext=NULL); + virtual PVMFCommandId Pause(const OsclAny* aContext=NULL); // virtual PVMFCommandId Reset(const OsclAny* aContext=NULL); private: diff --git a/android/author/android_audio_input.cpp b/android/author/android_audio_input.cpp index 3f1336a4..c9ce3088 100644 --- a/android/author/android_audio_input.cpp +++ b/android/author/android_audio_input.cpp @@ -71,6 +71,8 @@ AndroidAudioInput::AndroidAudioInput() iAudioNumChannelsValid=false; iAudioSamplingRateValid=false; iExitAudioThread=false; + iAudioThreadStarted=false; + iAudioThreadRunning=false; iCommandCounter=0; iCommandResponseQueue.reserve(5); @@ -796,14 +798,18 @@ PVMFStatus AndroidAudioInput::DoStart() } // wait for thread to set up AudioRecord + LOGV("wait for thread to start"); while (!iAudioThreadStarted) iAudioThreadStartCV->wait(*iAudioThreadStartLock); status_t startResult = iAudioThreadStartResult; iAudioThreadStartLock->unlock(); + LOGV("thread start with result = %d", iAudioThreadStartResult); - if (startResult != NO_ERROR) + if (startResult != NO_ERROR) { + LOGE("Audio thread failed to start: %d", startResult); return PVMFFailure; // thread failed to set up AudioRecord + } iState = STATE_STARTED; @@ -822,15 +828,17 @@ int AndroidAudioInput::start_audin_thread_func(TOsclThreadFuncArg arg) PVMFStatus AndroidAudioInput::DoPause() { LOGV("DoPause"); - iExitAudioThread = true; iState = STATE_PAUSED; + stopAudioThread(); return PVMFSuccess; } PVMFStatus AndroidAudioInput::DoReset() { LOGV("DoReset"); - iExitAudioThread = true; + iDataEventCounter = 0; + iState = STATE_IDLE; + stopAudioThread(); return PVMFSuccess; } @@ -849,14 +857,24 @@ PVMFStatus AndroidAudioInput::DoFlush() PVMFStatus AndroidAudioInput::DoStop() { LOGV("DoStop"); - iExitAudioThread = true; iDataEventCounter = 0; iState = STATE_STOPPED; - iAudioThreadSem->Signal(); - iAudioThreadTermSem->Wait(); + stopAudioThread(); return PVMFSuccess; } +void AndroidAudioInput::stopAudioThread() +{ + if (iAudioThreadRunning) { + LOGV("signal thread to stop"); + iExitAudioThread = true; + iAudioThreadSem->Signal(); + iAudioThreadTermSem->Wait(); + iExitAudioThread = false; + LOGV("thread stopped"); + } +} + //////////////////////////////////////////////////////////////////////////// PVMFStatus AndroidAudioInput::DoRead() { @@ -914,18 +932,21 @@ int AndroidAudioInput::audin_thread_func() { iAudioThreadStartLock->lock(); LOGV("create AudioRecord %p", this); - android::AudioRecord - * record = new android::AudioRecord( + android::AudioRecord* record = new android::AudioRecord( android::AudioRecord::DEFAULT_INPUT, iAudioSamplingRate, android::AudioSystem::PCM_16_BIT, iAudioNumChannels, 4*kBufferSize/iAudioNumChannels/sizeof(int16)); LOGV("AudioRecord created %p, this %p", record, this); status_t res = record->initCheck(); - if (res == NO_ERROR) + LOGV_IF(res != NO_ERROR, "initCheck() error %d", res); + if (res == NO_ERROR) { res = record->start(); - + LOGV_IF(res != NO_ERROR, "start() error %d", res); + } + iAudioThreadStartResult = res; iAudioThreadStarted = true; + iAudioThreadRunning = true; iAudioThreadStartCV->signal(); iAudioThreadStartLock->unlock(); @@ -981,6 +1002,7 @@ int AndroidAudioInput::audin_thread_func() { LOGV("delete record %p, this %p", record, this); delete record; + iAudioThreadRunning = false; iAudioThreadTermSem->Signal(); return 0; } diff --git a/android/author/android_audio_input.h b/android/author/android_audio_input.h index 2b96d667..8a8c1094 100644 --- a/android/author/android_audio_input.h +++ b/android/author/android_audio_input.h @@ -294,6 +294,7 @@ private: PVMFStatus DoFlush(); PVMFStatus DoStop(); PVMFStatus DoRead(); + void stopAudioThread(); /** * Allocate a specified number of key-value pairs and set the keys @@ -421,6 +422,7 @@ private: Condition *iAudioThreadStartCV; volatile status_t iAudioThreadStartResult; volatile bool iAudioThreadStarted; + volatile bool iAudioThreadRunning; }; }; // namespace android diff --git a/android/author/android_camera_input.cpp b/android/author/android_camera_input.cpp index 66d09f07..4505d63d 100644 --- a/android/author/android_camera_input.cpp +++ b/android/author/android_camera_input.cpp @@ -1115,12 +1115,12 @@ PVMFStatus AndroidCameraInput::postWriteAsync(const sp& frame) } // if first event, set timestamp to zero - uint32 timeStamp = 0; + uint32 timeStamp; if (iDataEventCounter == 0) { - iStartTickCount = OsclTickCount::TickCount(); + iStartTickCount = systemTime(SYSTEM_TIME_MONOTONIC) / 1000000; + timeStamp = 0; } else { - timeStamp = OsclTickCount::TicksToMsec( - OsclTickCount::TickCount()-iStartTickCount); + timeStamp = (systemTime(SYSTEM_TIME_MONOTONIC) / 1000000) - iStartTickCount; } // get memory offset for frame buffer diff --git a/android/author/authordriver.cpp b/android/author/authordriver.cpp index 581cfb4c..ad063e47 100644 --- a/android/author/authordriver.cpp +++ b/android/author/authordriver.cpp @@ -191,14 +191,12 @@ void AuthorDriver::FinishNonAsyncCommand(author_command *ac) // when a command has been enqueued for us). void AuthorDriver::Run() { - author_command *ac; - - ac = dequeueCommand(); + author_command* ac = dequeueCommand(); if (ac == NULL) { - // assert? + LOGE("Unexpected NULL command"); + OSCL_LEAVE(PVMFErrArgument); return; } - switch(ac->which) { case AUTHOR_INIT: handleInit(ac); @@ -260,7 +258,8 @@ void AuthorDriver::Run() case AUTHOR_QUIT: handleQuit(ac); return; default: - assert(0); + LOGE("Unknown author command: %d", ac->which); + OSCL_LEAVE(PVMFErrArgument); break; } @@ -570,12 +569,10 @@ void AuthorDriver::handleClose(author_command *ac) void AuthorDriver::handleReset(author_command *ac) { LOGV("handleReset"); + removeConfigRefs(ac); int error = 0; OSCL_TRY(error, mAuthor->Reset(ac)); OSCL_FIRST_CATCH_ANY(error, commandFailed(ac)); - - // remove references to configs - removeConfigRefs(ac); } void AuthorDriver::handleRemoveVideoSource(author_command *ac) @@ -687,7 +684,7 @@ int AuthorDriver::authorThread() sched->StartScheduler(mSyncSem); LOGV("Delete Author"); PVAuthorEngineFactory::DeleteAuthor(mAuthor); - + mAuthor = NULL; // Let the destructor know that we're out mSyncStatus = OK; @@ -812,21 +809,15 @@ void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse) void AuthorDriver::HandleErrorEvent(const PVAsyncErrorEvent& aEvent) { - printf("HandleErrorEvent\n"); + LOGE("HandleErrorEvent(%d)", aEvent.GetEventType()); + + // FIXME: + // Send error event to client via callback } void AuthorDriver::HandleInformationalEvent(const PVAsyncInformationalEvent& aEvent) { - PVInterface* iface = (PVInterface*)(aEvent.GetEventExtensionInterface()); - - if (iface == NULL) - return; - - switch(aEvent.GetEventType()) { - case PVMFInfoPositionStatus: - default: - break; - } + LOGV("HandleInformationalEvent(%d)", aEvent.GetEventType()); } status_t AuthorDriver::getMaxAmplitude(int *max) diff --git a/android/playerdriver.cpp b/android/playerdriver.cpp index 5a87d53a..14f4b105 100644 --- a/android/playerdriver.cpp +++ b/android/playerdriver.cpp @@ -55,6 +55,7 @@ #include "android_audio_output.h" #include "android_audio_stream.h" #include "pv_media_output_node_factory.h" +#include "pvmf_format_type.h" // for PVMFFormatType #include "pvmf_node_interface.h" #include "pvmf_source_context_data.h" #include "pvmf_download_data_source.h" @@ -81,6 +82,69 @@ static const char* MIO_LIBRARY_NAME = "libopencorehw.so"; static const char* VIDEO_MIO_FACTORY_NAME = "createVideoMio"; typedef AndroidSurfaceOutput* (*VideoMioFactory)(); +namespace { + +// Checks if the buffer size is valid and adjusts it to contain only the +// buffering percentage. The buffer's data format varies depending on the nature +// of the connection (HTTP vs RTSP). +// +// For HTTP the event's buffer format is: +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | buffering percent | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// For RTSP the event's buffer format is: +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |0 0 0 0 0 0 0 1|0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | buffering percent | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// TODO: Fix this once PV settles on one format to report the +// buffering progress. +// +// @param format Of the connection. +// @param[inout] buffer Pointer to the start of the buffering status data. On +// return points to the 1st byte of percentage value. +// @param[inout] size Of the buffer, on exit contains the size of the buffering +// percentage int. +// @return true If the format of the connection supports buffering update +// events and if the buffer size is valid. false otherwise. +bool CheckAndAdjustBufferingStatusBuf(const PVMFFormatType format, + const uint8 **buffer, + int *size) +{ + if (*buffer == NULL) { + LOGE("Invalid buffer: NULL"); + return false; + } + if (format == PVMF_DATA_SOURCE_RTSP_URL) { + if (8 != *size) { + LOGE("Invalid rtsp buffer size %d != 8", *size); + return false; + } + *buffer += 4; + *size = 4; + } else if (format == PVMF_DATA_SOURCE_HTTP_URL) { + if (4 != *size) { + LOGE("Invalid http buffer size %d != 4", *size); + return false; + } + } else { + // I don't think we use PVMF_DATA_SOURCE_MS_HTTP_STREAMING_URL or + // PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL. + LOGE("Bad source format %d", format); + return false; + } + return true; +} + +} // anonymous namespace + class PlayerDriver : public OsclActiveObject, public PVCommandStatusObserver, @@ -1087,9 +1151,18 @@ void PlayerDriver::HandleInformationalEvent(const PVAsyncInformationalEvent& aEv case PVMFInfoBufferingStatus: { - uint8 *localBuf = aEvent.GetLocalBuffer(); - if (localBuf != NULL) { - uint32 bufPercent; + const uint8 *localBuf = aEvent.GetLocalBuffer(); + int localBufSize = aEvent.GetLocalBufferSize(); + // Note in PV 2.0 GetDataSourceFormatType() returns a const + // char* which is the MIME type. + PVMFFormatType source_format = mDataSource->GetDataSourceFormatType(); + + if (CheckAndAdjustBufferingStatusBuf(source_format, &localBuf, &localBufSize)) { + uint32 bufPercent = 0; + + // TODO: The PVEvent class should expose a memcopy method + // that does bound checking instead of having clients reaching + // for its internal buffer. oscl_memcpy(&bufPercent, localBuf, sizeof(uint32)); LOGV("PVMFInfoBufferingStatus(%u)", bufPercent); mPvPlayer->sendEvent(MEDIA_BUFFERING_UPDATE, bufPercent); @@ -1447,4 +1520,3 @@ status_t PVPlayer::setLooping(int loop) } }; // namespace android - diff --git a/fileformats/mp4/composer/src/mpeg4file.cpp b/fileformats/mp4/composer/src/mpeg4file.cpp index 485d88d1..5589abbd 100644 --- a/fileformats/mp4/composer/src/mpeg4file.cpp +++ b/fileformats/mp4/composer/src/mpeg4file.cpp @@ -163,7 +163,7 @@ PVA_FF_Mpeg4File::~PVA_FF_Mpeg4File() } - if (_oInterLeaveEnabled) + if (_oInterLeaveEnabled && _pInterLeaveBufferVec != NULL) { // delete all interleave buffers int32 size = _pInterLeaveBufferVec->size(); @@ -1429,6 +1429,11 @@ PVA_FF_Mpeg4File::setVideoParams(uint32 trackID, PVA_FF_TrackAtom *trackAtom; trackAtom = _pmovieAtom->getMediaTrack(trackID); trackAtom->setVideoParams(frame_width, frame_height); + + // set the video width and height in "tkhd" atom + // we should have called "tkhdAtom->setVideoWidthHeight()" + // if it exists. + trackAtom->setVideoWidthHeight(frame_width, frame_height); return; } diff --git a/nodes/pvamrencnode/src/pvmf_amrenc_node.cpp b/nodes/pvamrencnode/src/pvmf_amrenc_node.cpp index e103de4e..47ecb232 100644 --- a/nodes/pvamrencnode/src/pvmf_amrenc_node.cpp +++ b/nodes/pvamrencnode/src/pvmf_amrenc_node.cpp @@ -124,6 +124,17 @@ PvmfAmrEncNode::~PvmfAmrEncNode() while (!iOutPort.empty()) iOutPort.Erase(&iOutPort.front()); + // Clean up command queues. + while (!iCmdQueue.empty()) + { + CommandComplete(iCmdQueue, iCmdQueue[0], PVMFFailure); + } + + while (!iCurrentCmd.empty()) + { + CommandComplete(iCurrentCmd, iCurrentCmd[0], PVMFFailure); + } + Cancel(); SetState(EPVMFNodeIdle); ThreadLogoff(); @@ -1099,6 +1110,13 @@ void PvmfAmrEncNode::FlushComplete() for (i = 0; i < iOutPort.size(); i++) iOutPort[i]->ResumeInput(); + // When the current cmd queue is empty, simply return. + if (iCurrentCmd.empty()) + { + LOG_ERR((0, "PvmfAmrEncNode::FlushComplete: Error - iCurrentCmd is empty")); + return; + } + CommandComplete(iCurrentCmd, iCurrentCmd.front(), status); if (!iCmdQueue.empty()) diff --git a/nodes/pvavcencnode/src/pvmf_avcenc_node.cpp b/nodes/pvavcencnode/src/pvmf_avcenc_node.cpp index c3eeb457..a65932a2 100644 --- a/nodes/pvavcencnode/src/pvmf_avcenc_node.cpp +++ b/nodes/pvavcencnode/src/pvmf_avcenc_node.cpp @@ -225,6 +225,17 @@ PVMFAvcEncNode::~PVMFAvcEncNode() while (!iInPort.empty()) iInPort.Erase(&iInPort.front()); while (!iOutPort.empty()) iOutPort.Erase(&iOutPort.front()); + // Clean up command queues + while (!iCmdQueue.empty()) + { + CommandComplete(iCmdQueue, iCmdQueue[0], PVMFFailure); + } + + while (!iCurrentCmd.empty()) + { + CommandComplete(iCurrentCmd, iCurrentCmd[0], PVMFFailure); + } + Cancel(); SetState(EPVMFNodeIdle); ThreadLogoff(); @@ -1495,6 +1506,13 @@ void PVMFAvcEncNode::FlushComplete() for (i = 0; i < iOutPort.size(); i++) iOutPort[i]->ResumeInput(); + // When the current cmd queue is empty, simply return. + if (iCurrentCmd.empty()) + { + LOG_ERR((0, "PVMFAvcEncNode::FlushComplete: Error - iCurrentCmd is empty")); + return; + } + // Flush is complete. Go to prepared state. SetState(EPVMFNodePrepared); CommandComplete(iCurrentCmd, iCurrentCmd.front(), PVMFSuccess); diff --git a/nodes/pvmediainputnode/src/pvmf_media_input_node.cpp b/nodes/pvmediainputnode/src/pvmf_media_input_node.cpp index 4cf831e0..0dc2a830 100644 --- a/nodes/pvmediainputnode/src/pvmf_media_input_node.cpp +++ b/nodes/pvmediainputnode/src/pvmf_media_input_node.cpp @@ -504,12 +504,10 @@ PvmfMediaInputNode::~PvmfMediaInputNode() while (!iCurrentCommand.empty()) { CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure); -// iCurrentCommand.Erase(&iCurrentCommand.front()); } while (!iInputCommands.empty()) { CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure); -// iInputCommands.Erase(&iInputCommands.front()); } } @@ -1067,6 +1065,14 @@ void PvmfMediaInputNode::FlushComplete() return; } + // When the current cmd queue is empty, simply return. + if (iCurrentCommand.empty()) + { + PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, + (0, "PvmfMediaInputNode::FlushComplete: Error - iCurrentCommand is empty")); + return; + } + //Flush is complete. PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PvmfMediaInputNode::FlushComplete: Done")); diff --git a/nodes/pvmp4ffcomposernode/src/pvmp4ffcn_node.cpp b/nodes/pvmp4ffcomposernode/src/pvmp4ffcn_node.cpp index a7ff697e..e809d39f 100644 --- a/nodes/pvmp4ffcomposernode/src/pvmp4ffcn_node.cpp +++ b/nodes/pvmp4ffcomposernode/src/pvmp4ffcn_node.cpp @@ -193,13 +193,11 @@ PVMp4FFComposerNode::~PVMp4FFComposerNode() while (!iCmdQueue.empty()) { CommandComplete(iCmdQueue, iCmdQueue[0], PVMFFailure); - iCmdQueue.Erase(&iCmdQueue.front()); } while (!iCurrentCmd.empty()) { CommandComplete(iCurrentCmd, iCurrentCmd[0], PVMFFailure); - iCmdQueue.Erase(&iCurrentCmd.front()); } iNodeEndOfDataReached = false; @@ -1555,10 +1553,11 @@ void PVMp4FFComposerNode::FlushComplete() for (i = 0; i < iInPorts.size(); i++) iInPorts[i]->ResumeInput(); + // When the current cmd queue is empty, simply return. if (iCurrentCmd.empty()) { LOG_ERR((0, "PVMp4FFComposerNode::FlushComplete: Error - iCurrentCmd is empty")); - status = PVMFFailure; + return; } CommandComplete(iCurrentCmd, iCurrentCmd[0], status); @@ -1787,7 +1786,7 @@ PVMFStatus PVMp4FFComposerNode::ProcessIncomingMsg(PVMFPortInterface* aPort) OsclRefCounterMemFrag memFrag; uint32 numFrags = mediaDataPtr->getNumFragments(); uint32 timestamp = mediaDataPtr->getTimestamp(); - iSyncSample = mediaDataPtr->getMarkerInfo(); //gives the I frame info + iSyncSample = (mediaDataPtr->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT); //gives the I frame info Oscl_Vector pFrame; //vector to store the nals in the particular case of AVC for (uint32 i = 0; (i < numFrags) && status == PVMFSuccess; i++) @@ -1931,46 +1930,8 @@ PVMFStatus PVMp4FFComposerNode::AddMemFragToTrack(Oscl_VectorSetLastTS(aTimestamp); } - // FIXME: - // - // First of all, this parsing logic should not be here, since composer does not need - // to parse the output stream and encoder should tell composer what type of picture - // is coming - // - // Second, this parsing code is looking for the PTYPE or PLUSPTYPE field through - // all the bits in the output picture, and there is no error handling here - // - // The big assumption is that anything is not marked as I-frame, it is a P-frame. - switch (aFormat) - { - case PVMF_H264_MP4: - { - if (iSyncSample) //iSyncSample is obtained from the marker info - codeType = 0; //to identify the I Frame in the case of AVC - } - break; - case PVMF_M4V: - for (i = 0; i < aFrame.size(); i++) - { - data = OSCL_REINTERPRET_CAST(uint8*, aFrame[i].ptr); - if (data[4] <= 0x3F) - codeType = 0; // I-frame - } - - break; - case PVMF_H263: - for (i = 0; i < aFrame.size(); i++) - { - data = OSCL_REINTERPRET_CAST(uint8*, aFrame[i].ptr); - bool isIFrameFromPTypeField = ((data[4] & 0x02) == 0x00); // PTYPE field must contain a single 0 bit - bool isExtendedPicCodingType = ((data[4] & 0x1C) == 0x1C) && ((data[5] & 0x80) == 0x80); - bool isIFrameFromPlusPTypeField = ((data[7] & 0x1C) == 0x00); // PLUSPTYPE field must contain three 0 bits - if ((isExtendedPicCodingType && isIFrameFromPlusPTypeField) || - (!isExtendedPicCodingType && isIFrameFromPTypeField)) { - codeType = 0; // I-frame - } - } - break; + if (iSyncSample) { + codeType = 0; } // Format: mtb (1) | layer_id (3) | coding_type (2) | ref_select_code (2) diff --git a/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp b/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp index 0fb59829..b076e164 100644 --- a/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp +++ b/nodes/pvomxvideodecnode/src/pvmf_omx_videodec_node.cpp @@ -15,6 +15,7 @@ * and limitations under the License. * ------------------------------------------------------------------- */ + #include "pvmf_omx_videodec_node.h" #include "pvlogger.h" #include "oscl_error_codes.h" @@ -36,6 +37,14 @@ #include "pv_omxcore.h" #include "pv_omxmastercore.h" +#if OMX_DEBUG_LOG +#include +#undef LOG_TAG +#define LOG_TAG "OMXD" +#undef PVLOGGER_LOGMSG +#define PVLOGGER_LOGMSG(IL, LOGGER, LEVEL, MESSAGE) JJLOGE MESSAGE +#define JJLOGE(id, ...) LOGE(__VA_ARGS__) +#endif static const OMX_U32 OMX_SPEC_VERSION = 0x00000101; #define CONFIG_VERSION_SIZE(param) \ @@ -6124,29 +6133,18 @@ void PVMFOMXVideoDecNode::DoCancelAllCommands(PVMFOMXVideoDecNodeCommand& aCmd) { CommandComplete(iCurrentCommand, iCurrentCommand[0], PVMFErrCancelled); } - } - //next cancel all queued commands - // Create a temporary queue for pending commands - // Copy the pending commands to the new queue - PVMFOMXVideoDecNodeCmdQ iTempPendingCmds; - for(int i=0; i< iInputCommands.size(); i++) + // next cancel all queued commands before this one + for(int i=0; i< iInputCommands.size();) { - PVMFOMXVideoDecNodeCommand* cmd = iInputCommands.FindById(i); - PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXVideoDecNode::DoCancelAllCommands CancelAllCmd ID %d InputCmd ID %d", aCmd.iId , cmd->iId)); - if ((aCmd.iId > cmd->iId) && ((aCmd.iId - cmd->iId ) < 0x80000000)) - iTempPendingCmds.StoreL(*cmd); - } - for(int i=0; i< iTempPendingCmds.size(); i++) - { - // Get the queue from the top - PVMFOMXVideoDecNodeCommand* cmd = iTempPendingCmds.FindById(i); - PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXVideoDecNode::DoCancelAllCommands Cancel Cmd ID %d", cmd->iId)); - //cancel the queued command - CommandComplete(iInputCommands, *cmd, PVMFErrCancelled); + PVMFOMXVideoDecNodeCommand* cmd = &iInputCommands[i]; + if ((aCmd.iId <= cmd->iId) && ((cmd->iId - aCmd.iId) < 0x80000000)) { + ++i; + } else { + CommandComplete(iInputCommands, *cmd, PVMFErrCancelled); + } } - iTempPendingCmds.clear(); if (iResetInProgress && !iResetMsgSent) { @@ -8470,10 +8468,8 @@ bool PVMFOMXVideoDecNode::VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* return true; } - - - - - - +#if OMX_DEBUG_LOG +#undef PVLOGGER_LOGMSG +#define PVLOGGER_LOGMSG(IL, LOGGER, LEVEL, MESSAGE) OSCL_UNUSED_ARG(LOGGER); +#endif diff --git a/nodes/pvomxvideoencnode/src/pvmf_omx_videoenc_node.cpp b/nodes/pvomxvideoencnode/src/pvmf_omx_videoenc_node.cpp index 7d12693c..0de720fb 100644 --- a/nodes/pvomxvideoencnode/src/pvmf_omx_videoenc_node.cpp +++ b/nodes/pvomxvideoencnode/src/pvmf_omx_videoenc_node.cpp @@ -437,6 +437,17 @@ PVMFOMXVideoEncNode::~PVMFOMXVideoEncNode() while (!iOutPort.empty()) iOutPort.Erase(&iOutPort.front()); + // Clean up command queues + while (!iCmdQueue.empty()) + { + CommandComplete(iCmdQueue, iCmdQueue[0], PVMFFailure); + } + + while (!iCurrentCmd.empty()) + { + CommandComplete(iCurrentCmd, iCurrentCmd[0], PVMFFailure); + } + Cancel(); SetState(EPVMFNodeIdle); ThreadLogoff(); @@ -4306,6 +4317,9 @@ OMX_ERRORTYPE PVMFOMXVideoEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETY // NOTE: we had to wait until now to wrap the buffer data because we only know // now where the actual data is located (based on buffer offset) OsclSharedPtr MediaDataOut = WrapOutputBuffer(pBufdata, (uint32) (aBuffer->nFilledLen), pContext); + if (aBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME) { + MediaDataOut->setMarkerInfo(PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT); + } // if you can't get the MediaDataOut, release the buffer back to the pool if (MediaDataOut.GetRep() == NULL) @@ -5616,4 +5630,3 @@ PVMFStatus PVMFOMXVideoEncNode::SendEndOfTrackCommand() return PVMFSuccess; } - diff --git a/nodes/pvvideoencnode/src/pvmf_videoenc_node.cpp b/nodes/pvvideoencnode/src/pvmf_videoenc_node.cpp index 417db400..1878ad27 100644 --- a/nodes/pvvideoencnode/src/pvmf_videoenc_node.cpp +++ b/nodes/pvvideoencnode/src/pvmf_videoenc_node.cpp @@ -187,6 +187,18 @@ PVMFVideoEncNode::~PVMFVideoEncNode() while (!iOutPort.empty()) iOutPort.Erase(&iOutPort.front()); + // Clean up command queues + while (!iCmdQueue.empty()) + { + CommandComplete(iCmdQueue, iCmdQueue[0], PVMFFailure); + } + + while (!iCurrentCmd.empty()) + { + CommandComplete(iCurrentCmd, iCurrentCmd[0], PVMFFailure); + } + + Cancel(); SetState(EPVMFNodeIdle); ThreadLogoff(); @@ -1379,6 +1391,13 @@ void PVMFVideoEncNode::FlushComplete() for (i = 0; i < iOutPort.size(); i++) iOutPort[i]->ResumeInput(); + // When the current cmd queue is empty, simply return. + if (iCurrentCmd.empty()) + { + LOG_ERR((0, "PVMp4FFComposerNode::FlushComplete: Error - iCurrentCmd is empty")); + return; + } + // Flush is complete. Go to prepared state. SetState(EPVMFNodePrepared); CommandComplete(iCurrentCmd, iCurrentCmd.front(), PVMFSuccess); @@ -1980,4 +1999,4 @@ void PVMFVideoEncNode::LogDiagnostics() oscl_memset(&iStats, 0, sizeof(PVVideoEncNodeStats)); #endif -} \ No newline at end of file +} diff --git a/oscl/oscl/osclerror/src/oscl_error.cpp b/oscl/oscl/osclerror/src/oscl_error.cpp index cfb3af13..6f26757f 100644 --- a/oscl/oscl/osclerror/src/oscl_error.cpp +++ b/oscl/oscl/osclerror/src/oscl_error.cpp @@ -17,6 +17,9 @@ */ +#define LOG_TAG "OsclErrorTrap" +#include + #include "oscl_error.h" #include "oscl_assert.h" #include "oscl_error_trapcleanup.h" @@ -176,6 +179,7 @@ OSCL_EXPORT_REF void OsclError::Leave(int32 aReason) if (errortrap) errortrap->iTrapStack->Leaving(); + //LOGE("Leave: aReason=%d", aReason); PVError_DoLeave(); } @@ -200,8 +204,9 @@ OSCL_EXPORT_REF void OsclError::Panic(const char acategory[], int32 areason) { //the application will exit. Log to stderr because pvlogger is not //available in this library. - fprintf(stderr, "OsclError::Panic!! Category %s reason %d\n", acategory, areason); - + LOGE("Panic!! Category %s reason %d\n", acategory, areason); + *(char*) 0 = 0; +#if 0 //set the global panic info if errortrap is installed. remember it may //not be installed under symbian GUI so be tolerant. int32 error; @@ -217,6 +222,7 @@ OSCL_EXPORT_REF void OsclError::Panic(const char acategory[], int32 areason) } PVError_DoPanic(); +#endif } -- 2.11.0