summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/omx
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp40
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.h5
-rw-r--r--media/libstagefright/omx/OMX.cpp2
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp19
-rw-r--r--media/libstagefright/omx/tests/OMXHarness.cpp7
5 files changed, 60 insertions, 13 deletions
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index cf43e94..b8970ad 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -148,6 +148,18 @@ void GraphicBufferSource::omxExecuting() {
}
}
+void GraphicBufferSource::omxIdle() {
+ ALOGV("omxIdle");
+
+ Mutex::Autolock autoLock(mMutex);
+
+ if (mExecuting) {
+ // We are only interested in the transition from executing->idle,
+ // not loaded->idle.
+ mExecuting = false;
+ }
+}
+
void GraphicBufferSource::omxLoaded(){
Mutex::Autolock autoLock(mMutex);
if (!mExecuting) {
@@ -194,7 +206,9 @@ void GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
Mutex::Autolock autoLock(mMutex);
- CHECK(mExecuting); // could this happen if app stop()s early?
+ if (!mExecuting) {
+ return;
+ }
int cbi = findMatchingCodecBuffer_l(header);
if (cbi < 0) {
@@ -213,7 +227,12 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
// see if the GraphicBuffer reference was null, which should only ever
// happen for EOS.
if (codecBuffer.mGraphicBuffer == NULL) {
- CHECK(mEndOfStream && mEndOfStreamSent);
+ if (!(mEndOfStream && mEndOfStreamSent)) {
+ // This can happen when broken code sends us the same buffer
+ // twice in a row.
+ ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer "
+ "(buffer emptied twice?)");
+ }
// No GraphicBuffer to deal with, no additional input or output is
// expected, so just return.
return;
@@ -384,6 +403,23 @@ bool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
if (mLatestSubmittedBufferId < 0 || mSuspended) {
return false;
}
+ if (mBufferSlot[mLatestSubmittedBufferId] == NULL) {
+ // This can happen if the remote side disconnects, causing
+ // onBuffersReleased() to NULL out our copy of the slots. The
+ // buffer is gone, so we have nothing to show.
+ //
+ // To be on the safe side we try to release the buffer.
+ ALOGD("repeatLatestSubmittedBuffer_l: slot was NULL");
+ mBufferQueue->releaseBuffer(
+ mLatestSubmittedBufferId,
+ mLatestSubmittedBufferFrameNum,
+ EGL_NO_DISPLAY,
+ EGL_NO_SYNC_KHR,
+ Fence::NO_FENCE);
+ mLatestSubmittedBufferId = -1;
+ mLatestSubmittedBufferFrameNum = 0;
+ return false;
+ }
int cbi = findAvailableCodecBuffer_l();
if (cbi < 0) {
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 244a843..9e5eee6 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -69,6 +69,11 @@ public:
// sitting in the BufferQueue, this will send them to the codec.
void omxExecuting();
+ // This is called when OMX transitions to OMX_StateIdle, indicating that
+ // the codec is meant to return all buffers back to the client for them
+ // to be freed. Do NOT submit any more buffers to the component.
+ void omxIdle();
+
// This is called when OMX transitions to OMX_StateLoaded, indicating that
// we are shutting down.
void omxLoaded();
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 84a0e10..274f2eb 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -479,7 +479,7 @@ OMX_ERRORTYPE OMX::OnFillBufferDone(
OMX::node_id OMX::makeNodeID(OMXNodeInstance *instance) {
// mLock is already held.
- node_id node = (node_id)++mNodeCounter;
+ node_id node = (node_id)(uintptr_t)++mNodeCounter;
mNodeIDToInstance.add(node, instance);
return node;
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 46e5d71..5f104fc 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -243,13 +243,18 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {
status_t OMXNodeInstance::sendCommand(
OMX_COMMANDTYPE cmd, OMX_S32 param) {
const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
- if (bufferSource != NULL
- && cmd == OMX_CommandStateSet
- && param == OMX_StateLoaded) {
- // Initiating transition from Executing -> Loaded
- // Buffers are about to be freed.
- bufferSource->omxLoaded();
- setGraphicBufferSource(NULL);
+ if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
+ if (param == OMX_StateIdle) {
+ // Initiating transition from Executing -> Idle
+ // ACodec is waiting for all buffers to be returned, do NOT
+ // submit any more buffers to the codec.
+ bufferSource->omxIdle();
+ } else if (param == OMX_StateLoaded) {
+ // Initiating transition from Idle/Executing -> Loaded
+ // Buffers are about to be freed.
+ bufferSource->omxLoaded();
+ setGraphicBufferSource(NULL);
+ }
// fall through
}
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 4bee808..44e4f9d 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "OMXHarness"
+#include <inttypes.h>
#include <utils/Log.h>
#include "OMXHarness.h"
@@ -711,11 +712,11 @@ status_t Harness::testSeek(
int64_t bufferTimeUs;
CHECK(buffer->meta_data()->findInt64(kKeyTime, &bufferTimeUs));
if (!CloseEnough(bufferTimeUs, actualSeekTimeUs)) {
- printf("\n * Attempted seeking to %lld us (%.2f secs)",
+ printf("\n * Attempted seeking to %" PRId64 " us (%.2f secs)",
requestedSeekTimeUs, requestedSeekTimeUs / 1E6);
- printf("\n * Nearest keyframe is at %lld us (%.2f secs)",
+ printf("\n * Nearest keyframe is at %" PRId64 " us (%.2f secs)",
actualSeekTimeUs, actualSeekTimeUs / 1E6);
- printf("\n * Returned buffer was at %lld us (%.2f secs)\n\n",
+ printf("\n * Returned buffer was at %" PRId64 " us (%.2f secs)\n\n",
bufferTimeUs, bufferTimeUs / 1E6);
buffer->release();