aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Sparks <>2009-04-01 11:10:21 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-04-01 11:10:21 -0700
commit9b3c56ac71d2b119228599496a93c40d4d9753e3 (patch)
treea49db5a5b3c63b89bda8bcab44841487de6b9cb9
parentf94a5e933cbcce72d7031543b08a4e2b78316cbd (diff)
downloadopencore-9b3c56ac71d2b119228599496a93c40d4d9753e3.tar.gz
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.cpp63
-rw-r--r--android/android_surface_output.h4
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;