summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioTrack.cpp19
-rw-r--r--media/libmedia/IDrm.cpp154
-rw-r--r--media/libmedia/IMediaHTTPConnection.cpp9
-rw-r--r--media/libstagefright/ACodec.cpp15
-rw-r--r--media/libstagefright/FrameRenderTracker.cpp21
-rw-r--r--media/libstagefright/MediaCodec.cpp6
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp104
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.h8
8 files changed, 232 insertions, 104 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 81ae6d7..b5d7614 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -986,15 +986,18 @@ status_t AudioTrack::getPosition(uint32_t *position)
}
if (mOutput != AUDIO_IO_HANDLE_NONE) {
- uint32_t halFrames;
- AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
+ uint32_t halFrames; // actually unused
+ (void) AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
+ // FIXME: on getRenderPosition() error, we return OK with frame position 0.
}
// FIXME: dspFrames may not be zero in (mState == STATE_STOPPED || mState == STATE_FLUSHED)
// due to hardware latency. We leave this behavior for now.
*position = dspFrames;
} else {
if (mCblk->mFlags & CBLK_INVALID) {
- restoreTrack_l("getPosition");
+ (void) restoreTrack_l("getPosition");
+ // FIXME: for compatibility with the Java API we ignore the restoreTrack_l()
+ // error here (e.g. DEAD_OBJECT) and return OK with the last recorded server position.
}
// IAudioTrack::stop() isn't synchronous; we don't know when presentation completes
@@ -2080,7 +2083,8 @@ status_t AudioTrack::restoreTrack_l(const char *from)
AudioSystem::clearAudioConfigCache();
if (isOffloadedOrDirect_l() || mDoNotReconnect) {
- // FIXME re-creation of offloaded tracks is not yet implemented
+ // FIXME re-creation of offloaded and direct tracks is not yet implemented;
+ // reconsider enabling for linear PCM encodings when position can be preserved.
return DEAD_OBJECT;
}
@@ -2203,7 +2207,12 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)
}
if (mCblk->mFlags & CBLK_INVALID) {
- restoreTrack_l("getTimestamp");
+ const status_t status = restoreTrack_l("getTimestamp");
+ if (status != OK) {
+ // per getTimestamp() API doc in header, we return DEAD_OBJECT here,
+ // recommending that the track be recreated.
+ return DEAD_OBJECT;
+ }
}
// The presented frame count must always lag behind the consumed frame count.
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index 714a0b3..b1ad0c5 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -67,7 +67,10 @@ struct BpDrm : public BpInterface<IDrm> {
virtual status_t initCheck() const {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- remote()->transact(INIT_CHECK, data, &reply);
+ status_t status = remote()->transact(INIT_CHECK, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -77,7 +80,11 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.write(uuid, 16);
data.writeString8(mimeType);
- remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
+ status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
+ if (status != OK) {
+ ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
+ return false;
+ }
return reply.readInt32() != 0;
}
@@ -87,7 +94,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.write(uuid, 16);
- remote()->transact(CREATE_PLUGIN, data, &reply);
+ status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -95,7 +105,10 @@ struct BpDrm : public BpInterface<IDrm> {
virtual status_t destroyPlugin() {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- remote()->transact(DESTROY_PLUGIN, data, &reply);
+ status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -104,7 +117,10 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- remote()->transact(OPEN_SESSION, data, &reply);
+ status_t status = remote()->transact(OPEN_SESSION, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, sessionId);
return reply.readInt32();
@@ -115,7 +131,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, sessionId);
- remote()->transact(CLOSE_SESSION, data, &reply);
+ status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -140,7 +159,11 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeString8(optionalParameters.keyAt(i));
data.writeString8(optionalParameters.valueAt(i));
}
- remote()->transact(GET_KEY_REQUEST, data, &reply);
+
+ status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, request);
defaultUrl = reply.readString8();
@@ -156,7 +179,12 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, sessionId);
writeVector(data, response);
- remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
+
+ status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
+ if (status != OK) {
+ return status;
+ }
+
readVector(reply, keySetId);
return reply.readInt32();
@@ -167,7 +195,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, keySetId);
- remote()->transact(REMOVE_KEYS, data, &reply);
+ status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -179,7 +210,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, sessionId);
writeVector(data, keySetId);
- remote()->transact(RESTORE_KEYS, data, &reply);
+ status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -190,7 +224,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, sessionId);
- remote()->transact(QUERY_KEY_STATUS, data, &reply);
+ status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
infoMap.clear();
size_t count = reply.readInt32();
@@ -211,7 +248,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeString8(certType);
data.writeString8(certAuthority);
- remote()->transact(GET_PROVISION_REQUEST, data, &reply);
+ status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, request);
defaultUrl = reply.readString8();
@@ -226,7 +266,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, response);
- remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
+ status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, certificate);
readVector(reply, wrappedKey);
@@ -238,7 +281,10 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- remote()->transact(UNPROVISION_DEVICE, data, &reply);
+ status_t status = remote()->transact(UNPROVISION_DEVICE, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -247,7 +293,10 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- remote()->transact(GET_SECURE_STOPS, data, &reply);
+ status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
secureStops.clear();
uint32_t count = reply.readInt32();
@@ -264,7 +313,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, ssid);
- remote()->transact(GET_SECURE_STOP, data, &reply);
+ status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, secureStop);
return reply.readInt32();
@@ -275,7 +327,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, ssRelease);
- remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
+ status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -284,7 +339,10 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
+ status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -294,7 +352,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.writeString8(name);
- remote()->transact(GET_PROPERTY_STRING, data, &reply);
+ status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
+ if (status != OK) {
+ return status;
+ }
value = reply.readString8();
return reply.readInt32();
@@ -305,7 +366,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.writeString8(name);
- remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
+ status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, value);
return reply.readInt32();
@@ -317,7 +381,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeString8(name);
data.writeString8(value);
- remote()->transact(SET_PROPERTY_STRING, data, &reply);
+ status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -329,7 +396,10 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeString8(name);
writeVector(data, value);
- remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
+ status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -342,7 +412,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, sessionId);
data.writeString8(algorithm);
- remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
+ status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -353,7 +426,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, sessionId);
data.writeString8(algorithm);
- remote()->transact(SET_MAC_ALGORITHM, data, &reply);
+ status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
@@ -370,7 +446,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, input);
writeVector(data, iv);
- remote()->transact(ENCRYPT, data, &reply);
+ status_t status = remote()->transact(ENCRYPT, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, output);
return reply.readInt32();
@@ -389,7 +468,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, input);
writeVector(data, iv);
- remote()->transact(DECRYPT, data, &reply);
+ status_t status = remote()->transact(DECRYPT, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, output);
return reply.readInt32();
@@ -406,7 +488,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, keyId);
writeVector(data, message);
- remote()->transact(SIGN, data, &reply);
+ status_t status = remote()->transact(SIGN, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, signature);
return reply.readInt32();
@@ -425,7 +510,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, message);
writeVector(data, signature);
- remote()->transact(VERIFY, data, &reply);
+ status_t status = remote()->transact(VERIFY, data, &reply);
+ if (status != OK) {
+ return status;
+ }
match = (bool)reply.readInt32();
return reply.readInt32();
}
@@ -443,7 +531,10 @@ struct BpDrm : public BpInterface<IDrm> {
writeVector(data, message);
writeVector(data, wrappedKey);
- remote()->transact(SIGN_RSA, data, &reply);
+ status_t status = remote()->transact(SIGN_RSA, data, &reply);
+ if (status != OK) {
+ return status;
+ }
readVector(reply, signature);
return reply.readInt32();
@@ -453,7 +544,10 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(listener));
- remote()->transact(SET_LISTENER, data, &reply);
+ status_t status = remote()->transact(SET_LISTENER, data, &reply);
+ if (status != OK) {
+ return status;
+ }
return reply.readInt32();
}
diff --git a/media/libmedia/IMediaHTTPConnection.cpp b/media/libmedia/IMediaHTTPConnection.cpp
index 7e89d7f..0dda0be 100644
--- a/media/libmedia/IMediaHTTPConnection.cpp
+++ b/media/libmedia/IMediaHTTPConnection.cpp
@@ -107,7 +107,14 @@ struct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> {
return UNKNOWN_ERROR;
}
- size_t len = reply.readInt32();
+ int32_t lenOrErrorCode = reply.readInt32();
+
+ // Negative values are error codes
+ if (lenOrErrorCode < 0) {
+ return lenOrErrorCode;
+ }
+
+ size_t len = lenOrErrorCode;
if (len > size) {
ALOGE("requested %zu, got %zu", size, len);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 527e9cd..478a0f5 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1271,8 +1271,12 @@ void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Inf
// unlink untracked frames
for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
it != done.cend(); ++it) {
- if (it->getIndex() >= 0) {
- mBuffers[kPortIndexOutput].editItemAt(it->getIndex()).mRenderInfo = NULL;
+ ssize_t index = it->getIndex();
+ if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
+ mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
+ } else if (index >= 0) {
+ // THIS SHOULD NEVER HAPPEN
+ ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
}
}
@@ -1467,12 +1471,13 @@ status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
::close(info->mFenceFd);
}
- mRenderTracker.untrackFrame(info->mRenderInfo);
- info->mRenderInfo = NULL;
+ if (portIndex == kPortIndexOutput) {
+ mRenderTracker.untrackFrame(info->mRenderInfo, i);
+ info->mRenderInfo = NULL;
+ }
// remove buffer even if mOMX->freeBuffer fails
mBuffers[portIndex].removeAt(i);
-
return err;
}
diff --git a/media/libstagefright/FrameRenderTracker.cpp b/media/libstagefright/FrameRenderTracker.cpp
index ebd2197..917870f 100644
--- a/media/libstagefright/FrameRenderTracker.cpp
+++ b/media/libstagefright/FrameRenderTracker.cpp
@@ -149,14 +149,21 @@ std::list<FrameRenderTracker::Info> FrameRenderTracker::checkFencesAndGetRendere
return done;
}
-void FrameRenderTracker::untrackFrame(const FrameRenderTracker::Info *info) {
- if (info != NULL) {
- for (std::list<Info>::iterator it = mRenderQueue.begin();
- it != mRenderQueue.end(); ++it) {
- if (&*it == info) {
- mRenderQueue.erase(it);
- return;
+void FrameRenderTracker::untrackFrame(const FrameRenderTracker::Info *info, ssize_t index) {
+ if (info == NULL && index == SSIZE_MAX) {
+ // nothing to do
+ return;
+ }
+
+ for (std::list<Info>::iterator it = mRenderQueue.begin();
+ it != mRenderQueue.end(); ) {
+ if (&*it == info) {
+ mRenderQueue.erase(it++);
+ } else {
+ if (it->mIndex > index) {
+ --(it->mIndex);
}
+ ++it;
}
}
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e5b7202..b576cd9 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1160,6 +1160,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case CodecBase::kWhatComponentConfigured:
{
+ if (mState == UNINITIALIZED || mState == INITIALIZED) {
+ // In case a kWhatError message came in and replied with error,
+ // we log a warning and ignore.
+ ALOGW("configure interrupted by error, current state %d", mState);
+ break;
+ }
CHECK_EQ(mState, CONFIGURING);
// reset input surface flag
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index ac6bf0d..31c6975 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -118,6 +118,7 @@ GraphicBufferSource::GraphicBufferSource(
mIsPersistent(false),
mConsumer(consumer),
mNumFramesAvailable(0),
+ mNumBufferAcquired(0),
mEndOfStream(false),
mEndOfStreamSent(false),
mMaxTimestampGapUs(-1ll),
@@ -185,7 +186,14 @@ GraphicBufferSource::GraphicBufferSource(
}
GraphicBufferSource::~GraphicBufferSource() {
- ALOGV("~GraphicBufferSource");
+ if (mLatestBufferId >= 0) {
+ releaseBuffer(
+ mLatestBufferId, mLatestBufferFrameNum,
+ mBufferSlot[mLatestBufferId], mLatestBufferFence);
+ }
+ if (mNumBufferAcquired != 0) {
+ ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired);
+ }
if (mConsumer != NULL && !mIsPersistent) {
status_t err = mConsumer->consumerDisconnect();
if (err != NO_ERROR) {
@@ -377,17 +385,7 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int f
if (id == mLatestBufferId) {
CHECK_GT(mLatestBufferUseCount--, 0);
} else {
- if (mIsPersistent) {
- mConsumer->detachBuffer(id);
- int outSlot;
- mConsumer->attachBuffer(&outSlot, mBufferSlot[id]);
- mConsumer->releaseBuffer(outSlot, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
- mBufferSlot[id] = NULL;
- } else {
- mConsumer->releaseBuffer(id, codecBuffer.mFrameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
- }
+ releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence);
}
} else {
ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d",
@@ -468,18 +466,11 @@ void GraphicBufferSource::suspend(bool suspend) {
break;
}
+ ++mNumBufferAcquired;
--mNumFramesAvailable;
- if (mIsPersistent) {
- mConsumer->detachBuffer(item.mBuf);
- mBufferSlot[item.mBuf] = NULL;
- mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer);
- mConsumer->releaseBuffer(item.mBuf, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
- } else {
- mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
- }
+ releaseBuffer(item.mBuf, item.mFrameNumber,
+ item.mGraphicBuffer, item.mFence);
}
return;
}
@@ -526,6 +517,7 @@ bool GraphicBufferSource::fillCodecBuffer_l() {
return false;
}
+ mNumBufferAcquired++;
mNumFramesAvailable--;
// If this is the first time we're seeing this buffer, add it to our
@@ -559,17 +551,7 @@ bool GraphicBufferSource::fillCodecBuffer_l() {
if (err != OK) {
ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
- if (mIsPersistent) {
- mConsumer->detachBuffer(item.mBuf);
- mBufferSlot[item.mBuf] = NULL;
- mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer);
- mConsumer->releaseBuffer(item.mBuf, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
- } else {
- mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
- }
- // item.mFence is released at the end of this method
+ releaseBuffer(item.mBuf, item.mFrameNumber, item.mGraphicBuffer, item.mFence);
} else {
ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
setLatestBuffer_l(item, dropped);
@@ -647,19 +629,8 @@ void GraphicBufferSource::setLatestBuffer_l(
if (mLatestBufferId >= 0) {
if (mLatestBufferUseCount == 0) {
- if (mIsPersistent) {
- mConsumer->detachBuffer(mLatestBufferId);
-
- int outSlot;
- mConsumer->attachBuffer(&outSlot, mBufferSlot[mLatestBufferId]);
- mConsumer->releaseBuffer(outSlot, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, mLatestBufferFence);
- mBufferSlot[mLatestBufferId] = NULL;
- } else {
- mConsumer->releaseBuffer(
- mLatestBufferId, mLatestBufferFrameNum,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, mLatestBufferFence);
- }
+ releaseBuffer(mLatestBufferId, mLatestBufferFrameNum,
+ mBufferSlot[mLatestBufferId], mLatestBufferFence);
// mLatestBufferFence will be set to new fence just below
}
}
@@ -848,6 +819,33 @@ int GraphicBufferSource::findMatchingCodecBuffer_l(
return -1;
}
+/*
+ * Releases an acquired buffer back to the consumer for either persistent
+ * or non-persistent surfaces.
+ *
+ * id: buffer slot to release (in persistent case the id might be changed)
+ * frameNum: frame number of the frame being released
+ * buffer: GraphicBuffer pointer to release (note this must not be & as we
+ * will clear the original mBufferSlot in persistent case)
+ * fence: fence of the frame being released
+ */
+void GraphicBufferSource::releaseBuffer(
+ int &id, uint64_t frameNum,
+ const sp<GraphicBuffer> buffer, const sp<Fence> &fence) {
+ if (mIsPersistent) {
+ mConsumer->detachBuffer(id);
+ mBufferSlot[id] = NULL;
+
+ mConsumer->attachBuffer(&id, buffer);
+ mConsumer->releaseBuffer(
+ id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
+ } else {
+ mConsumer->releaseBuffer(
+ id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
+ }
+ mNumBufferAcquired--;
+}
+
// BufferQueue::ConsumerListener callback
void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
Mutex::Autolock autoLock(mMutex);
@@ -868,6 +866,8 @@ void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
BufferItem item;
status_t err = mConsumer->acquireBuffer(&item, 0);
if (err == OK) {
+ mNumBufferAcquired++;
+
// If this is the first time we're seeing this buffer, add it to our
// slot table.
if (item.mGraphicBuffer != NULL) {
@@ -875,16 +875,8 @@ void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
mBufferSlot[item.mBuf] = item.mGraphicBuffer;
}
- if (mIsPersistent) {
- mConsumer->detachBuffer(item.mBuf);
- mBufferSlot[item.mBuf] = NULL;
- mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer);
- mConsumer->releaseBuffer(item.mBuf, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
- } else {
- mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
- }
+ releaseBuffer(item.mBuf, item.mFrameNumber,
+ item.mGraphicBuffer, item.mFence);
}
return;
}
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 2a8c218..3f64088 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -228,6 +228,11 @@ private:
// doing anything if we don't have a codec buffer available.
void submitEndOfInputStream_l();
+ // Release buffer to the consumer
+ void releaseBuffer(
+ int &id, uint64_t frameNum,
+ const sp<GraphicBuffer> buffer, const sp<Fence> &fence);
+
void setLatestBuffer_l(const BufferItem &item, bool dropped);
bool repeatLatestBuffer_l();
int64_t getTimestamp(const BufferItem &item);
@@ -257,6 +262,9 @@ private:
// forwarded to the codec.
size_t mNumFramesAvailable;
+ // Number of frames acquired from consumer (debug only)
+ int32_t mNumBufferAcquired;
+
// Set to true if we want to send end-of-stream after we run out of
// frames in BufferQueue.
bool mEndOfStream;