summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/ACodec.cpp
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-05-06 16:54:30 -0700
committerLajos Molnar <lajos@google.com>2015-05-07 13:59:14 -0700
commitdd248abd2c3e5e82b0049d40c7e9fb741fd4540c (patch)
tree587db89588821d9e49f445cd4822ee7e33eb8077 /media/libstagefright/ACodec.cpp
parentf52b2284405ec1d8941334718f580157417f9d60 (diff)
downloadframeworks_av-dd248abd2c3e5e82b0049d40c7e9fb741fd4540c.zip
frameworks_av-dd248abd2c3e5e82b0049d40c7e9fb741fd4540c.tar.gz
frameworks_av-dd248abd2c3e5e82b0049d40c7e9fb741fd4540c.tar.bz2
stagefright: allow connecting to surfaces that attach buffers
Now that consumers can attach buffers to BufferQueues, we cannot assert if an unknown buffer is dequeud, or if a buffer is dequeued from a BufferQueue multiple times. Also, when attaching to such surfaces, allocation must be enabled as attach will lock for a free buffer slot. Bug: 20885565 Change-Id: Ied466c5a848facf3149ad8bf0d18a0095da21e40
Diffstat (limited to 'media/libstagefright/ACodec.cpp')
-rw-r--r--media/libstagefright/ACodec.cpp64
1 files changed, 49 insertions, 15 deletions
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 5475a4a..006f07d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -610,6 +610,9 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
return err;
}
+ // need to enable allocation when attaching
+ surface->getIGraphicBufferProducer()->allowAllocation(true);
+
// for meta data mode, we move dequeud buffers to the new surface.
// for non-meta mode, we must move all registered buffers
for (size_t i = 0; i < buffers.size(); ++i) {
@@ -1046,26 +1049,57 @@ ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
return NULL;
}
- if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
- ALOGE("dequeueBuffer failed.");
- return NULL;
- }
+ do {
+ if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
+ ALOGE("dequeueBuffer failed.");
+ return NULL;
+ }
+
+ bool stale = false;
+ for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
+ BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
+
+ if (info->mGraphicBuffer != NULL &&
+ info->mGraphicBuffer->handle == buf->handle) {
+ // Since consumers can attach buffers to BufferQueues, it is possible
+ // that a known yet stale buffer can return from a surface that we
+ // once used. We can simply ignore this as we have already dequeued
+ // this buffer properly. NOTE: this does not eliminate all cases,
+ // e.g. it is possible that we have queued the valid buffer to the
+ // NW, and a stale copy of the same buffer gets dequeued - which will
+ // be treated as the valid buffer by ACodec.
+ if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
+ ALOGI("dequeued stale buffer %p. discarding", buf);
+ stale = true;
+ break;
+ }
+ ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
+ info->mStatus = BufferInfo::OWNED_BY_US;
+
+ return info;
+ }
+ }
+
+ // It is also possible to receive a previously unregistered buffer
+ // in non-meta mode. These should be treated as stale buffers. The
+ // same is possible in meta mode, in which case, it will be treated
+ // as a normal buffer, which is not desirable.
+ // TODO: fix this.
+ if (!stale && !mStoreMetaDataInOutputBuffers) {
+ ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
+ stale = true;
+ }
+ if (stale) {
+ // TODO: detach stale buffer, but there is no API yet to do it.
+ buf = NULL;
+ }
+ } while (buf == NULL);
+ // get oldest undequeued buffer
BufferInfo *oldest = NULL;
for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
BufferInfo *info =
&mBuffers[kPortIndexOutput].editItemAt(i);
-
- if (info->mGraphicBuffer != NULL &&
- info->mGraphicBuffer->handle == buf->handle) {
- CHECK_EQ((int)info->mStatus,
- (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
-
- info->mStatus = BufferInfo::OWNED_BY_US;
-
- return info;
- }
-
if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
(oldest == NULL ||
// avoid potential issues from counter rolling over