diff options
author | Dave Sparks <> | 2009-04-01 11:10:21 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-01 11:10:21 -0700 |
commit | 9b3c56ac71d2b119228599496a93c40d4d9753e3 (patch) | |
tree | a49db5a5b3c63b89bda8bcab44841487de6b9cb9 | |
parent | f94a5e933cbcce72d7031543b08a4e2b78316cbd (diff) | |
download | opencore-9b3c56ac71d2b119228599496a93c40d4d9753e3.tar.gz |
AI 144029: Don't send write complete until frame is no longer displayedandroid-sdk-1.5_r3android-sdk-1.5_r1android-sdk-1.5-preandroid-1.5r4android-1.5r3android-1.5r2android-1.5cupcake-releasecupcake
We seem to be overwriting video frames while they are being displayed.
This change holds back an acknowledgement for the frame currently
displayed until the next one is received. The final frame is released
when EOS, stop, reset, flush, or cancel command is received.
BUG=1749950
Automated import of CL 144029
-rw-r--r-- | android/android_surface_output.cpp | 63 | ||||
-rw-r--r-- | android/android_surface_output.h | 4 |
2 files changed, 43 insertions, 24 deletions
diff --git a/android/android_surface_output.cpp b/android/android_surface_output.cpp index ba606fd49..b8edb1821 100644 --- a/android/android_surface_output.cpp +++ b/android/android_surface_output.cpp @@ -48,6 +48,7 @@ OSCL_EXPORT_REF AndroidSurfaceOutput::AndroidSurfaceOutput() : mEmulation = false; mPvPlayer = NULL; mEmulation = false; + iEosReceived = false; } status_t AndroidSurfaceOutput::set(PVPlayer* pvPlayer, const sp<ISurface>& surface, bool emulation) @@ -95,6 +96,28 @@ bool AndroidSurfaceOutput::checkVideoParameterFlags() return (iVideoParameterFlags & VIDEO_PARAMETERS_MASK) == VIDEO_PARAMETERS_VALID; } +/* + * process the write response queue by sending writeComplete to the peer + * (nominally the decoder node). + * + * numFramesToHold is the number of frames to be held in the MIO. During + * playback, we hold the last frame which is used by SurfaceFlinger + * to composite the final output. + */ +void AndroidSurfaceOutput::processWriteResponseQueue(int numFramesToHold) +{ + LOGV("processWriteResponseQueue: queued = %d, numFramesToHold = %d", + iWriteResponseQueue.size(), numFramesToHold); + while (iWriteResponseQueue.size() > numFramesToHold) { + if (iPeer) { + iPeer->writeComplete(iWriteResponseQueue[0].iStatus, + iWriteResponseQueue[0].iCmdId, + (OsclAny*)iWriteResponseQueue[0].iContext); + } + iWriteResponseQueue.erase(&iWriteResponseQueue[0]); + } +} + void AndroidSurfaceOutput::Cleanup() //cleanup all allocated memory and release resources. { @@ -104,12 +127,7 @@ void AndroidSurfaceOutput::Cleanup() iObserver->RequestCompleted(PVMFCmdResp(iCommandResponseQueue[0].iCmdId, iCommandResponseQueue[0].iContext, iCommandResponseQueue[0].iStatus)); iCommandResponseQueue.erase(&iCommandResponseQueue[0]); } - while (!iWriteResponseQueue.empty()) - { - if (iPeer) - iPeer->writeComplete(iWriteResponseQueue[0].iStatus,iWriteResponseQueue[0].iCmdId,(OsclAny*)iWriteResponseQueue[0].iContext); - iWriteResponseQueue.erase(&iWriteResponseQueue[0]); - } + processWriteResponseQueue(0); // We'll close frame buf and delete here for now. closeFrameBuf(); @@ -251,9 +269,10 @@ PVMFCommandId AndroidSurfaceOutput:: Init(const OsclAny* aContext) return cmdid; } -PVMFCommandId AndroidSurfaceOutput:: Reset(const OsclAny* aContext) +PVMFCommandId AndroidSurfaceOutput::Reset(const OsclAny* aContext) { - // Do nothing for now. + iEosReceived = false; + processWriteResponseQueue(0); PVMFCommandId cmdid=iCommandCounter++; return cmdid; } @@ -261,6 +280,7 @@ PVMFCommandId AndroidSurfaceOutput:: Reset(const OsclAny* aContext) PVMFCommandId AndroidSurfaceOutput::Start(const OsclAny* aContext) { + iEosReceived = false; PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Start() called")); PVMFCommandId cmdid=iCommandCounter++; @@ -333,6 +353,7 @@ PVMFCommandId AndroidSurfaceOutput::Flush(const OsclAny* aContext) case STATE_STARTED: iState=STATE_INITIALIZED; + processWriteResponseQueue(0); status=PVMFSuccess; break; @@ -356,6 +377,7 @@ PVMFCommandId AndroidSurfaceOutput::DiscardData(const OsclAny* aContext) //needed here. PVMFStatus status=PVMFSuccess; + processWriteResponseQueue(0); CommandResponse resp(status,cmdid,aContext); QueueCommandResponse(resp); @@ -373,6 +395,7 @@ PVMFCommandId AndroidSurfaceOutput::DiscardData(PVMFTimestamp aTimestamp, const //this component doesn't buffer data, so there's nothing //needed here. + processWriteResponseQueue(0); PVMFStatus status=PVMFSuccess; CommandResponse resp(status,cmdid,aContext); @@ -384,8 +407,6 @@ PVMFCommandId AndroidSurfaceOutput::Stop(const OsclAny* aContext) { PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Stop() called")); - printf("AndroidSurfaceOutput::Stop Received %x\n", 0); - PVMFCommandId cmdid=iCommandCounter++; PVMFStatus status=PVMFFailure; @@ -403,6 +424,7 @@ PVMFCommandId AndroidSurfaceOutput::Stop(const OsclAny* aContext) #endif iState=STATE_INITIALIZED; + processWriteResponseQueue(0); status=PVMFSuccess; break; @@ -539,6 +561,7 @@ PVMFCommandId AndroidSurfaceOutput::writeAsync(uint8 aFormatType, int32 aFormatI switch(aFormatIndex) { case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM: + iEosReceived = true; break; default: break; @@ -681,14 +704,7 @@ void AndroidSurfaceOutput::cancelAllCommands() //in this implementaiton, the write commands are executed immediately //when received so it isn't really possible to cancel. //just report completion immediately. - - for (uint32 i=0;i<iWriteResponseQueue.size();i++) - { - //report completion - if (iPeer) - iPeer->writeComplete(iWriteResponseQueue[i].iStatus,iWriteResponseQueue[i].iCmdId,(OsclAny*)iWriteResponseQueue[i].iContext); - iWriteResponseQueue.erase(&iWriteResponseQueue[i]); - } + processWriteResponseQueue(0); } void AndroidSurfaceOutput::setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver) @@ -855,12 +871,11 @@ void AndroidSurfaceOutput::Run() } //send async write completion - while (!iWriteResponseQueue.empty()) - { - //report write complete - if (iPeer) - iPeer->writeComplete(iWriteResponseQueue[0].iStatus,iWriteResponseQueue[0].iCmdId,(OsclAny*)iWriteResponseQueue[0].iContext); - iWriteResponseQueue.erase(&iWriteResponseQueue[0]); + if (iEosReceived) { + LOGV("Flushing buffers after EOS"); + processWriteResponseQueue(0); + } else { + processWriteResponseQueue(1); } } diff --git a/android/android_surface_output.h b/android/android_surface_output.h index 74e459ee8..7c88fd616 100644 --- a/android/android_surface_output.h +++ b/android/android_surface_output.h @@ -120,6 +120,8 @@ public: void deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer); + void processWriteResponseQueue(int numFramesToHold); + PVMFCommandId Init(const OsclAny* aContext=NULL); PVMFCommandId Reset(const OsclAny* aContext=NULL); @@ -270,6 +272,8 @@ protected: Oscl_File iOutputFile; bool iFileOpened; + bool iEosReceived; + // Video parameters uint32 iVideoParameterFlags; OSCL_HeapString<OsclMemAllocator> iVideoFormatString; |