GraphicBufferSource.cpp revision f779bb50d9746d9526541c3e6dcdf619cac941b7
1f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden/*
2f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Copyright (C) 2013 The Android Open Source Project
3f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
4f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
5f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * you may not use this file except in compliance with the License.
6f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * You may obtain a copy of the License at
7f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
8f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
9f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
10f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Unless required by applicable law or agreed to in writing, software
11f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
12f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * See the License for the specific language governing permissions and
14f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * limitations under the License.
15f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden */
16f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
17f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#define LOG_TAG "GraphicBufferSource"
18f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <utils/Log.h>
19f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
20f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <GraphicBufferSource.h>
21f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
22f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <OMX_Core.h>
23f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h>
24f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
25f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <MetadataBufferType.h>
26f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h>
27f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android {
29f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true;
31f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
32f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
33f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        uint32_t bufferWidth, uint32_t bufferHeight) :
35f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mInitCheck(UNKNOWN_ERROR),
36f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mNodeInstance(nodeInstance),
37f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting(false),
38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mNumFramesAvailable(0),
39f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mEndOfStream(false),
40f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mEndOfStreamSent(false) {
41f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
42f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("GraphicBufferSource w=%u h=%u", bufferWidth, bufferHeight);
43f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
44f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferWidth == 0 || bufferHeight == 0) {
45f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("Invalid dimensions %dx%d", bufferWidth, bufferHeight);
46f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        mInitCheck = BAD_VALUE;
47f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
48f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
49f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
50f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mBufferQueue = new BufferQueue(true);
51f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mBufferQueue->setDefaultBufferSize(bufferWidth, bufferHeight);
52f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mBufferQueue->setSynchronousMode(true);
53f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
54f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            GRALLOC_USAGE_HW_TEXTURE);
55f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
56f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
57f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // reference once the ctor ends, as that would cause the refcount of 'this'
58f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
59f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that's what we create.
60f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    wp<BufferQueue::ConsumerListener> listener;
61f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    listener = static_cast<BufferQueue::ConsumerListener*>(this);
62f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
63f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<BufferQueue::ConsumerListener> proxy;
64f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    proxy = new BufferQueue::ProxyConsumerListener(listener);
65f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
66f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err = mBufferQueue->consumerConnect(proxy);
67f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != NO_ERROR) {
68f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("Error connecting to BufferQueue: %s (%d)",
69f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                strerror(-err), err);
70f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
71f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
72f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
73f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mInitCheck = OK;
74f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
75f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
76f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() {
77f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("~GraphicBufferSource");
78f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err = mBufferQueue->consumerDisconnect();
79f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != NO_ERROR) {
80f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("consumerDisconnect failed: %d", err);
81f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
82f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
83f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
84f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() {
85f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
86f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("--> executing; avail=%d, codec vec size=%zd",
87f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mNumFramesAvailable, mCodecBuffers.size());
88f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(!mExecuting);
89f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = true;
90f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
91f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Start by loading up as many buffers as possible.  We want to do this,
92f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // rather than just submit the first buffer, to avoid a degenerate case:
93f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // if all BQ buffers arrive before we start executing, and we only submit
94f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one here, the other BQ buffers will just sit until we get notified
95f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that the codec buffer has been released.  We'd then acquire and
96f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit a single additional buffer, repeatedly, never using more than
97f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one codec buffer simultaneously.  (We could instead try to submit
98f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // all BQ buffers whenever any codec buffer is freed, but if we get the
99f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // initial conditions right that will never be useful.)
100f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    while (mNumFramesAvailable && isCodecBufferAvailable_l()) {
101f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
102f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
103f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
104f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("done loading initial frames, avail=%d", mNumFramesAvailable);
105f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
106f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // If EOS has already been signaled, and there are no more frames to
107f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit, try to send EOS now as well.
108f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStream && mNumFramesAvailable == 0) {
109f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
110f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
111f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
112f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
113f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxIdling(){
114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("--> idling");
116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (!mExecuting) {
117f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Transition from "loading" to "idling".  Nothing to do.
118f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
119f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
121f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("Dropped down to idle, avail=%d eos=%d eosSent=%d",
122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mNumFramesAvailable, mEndOfStream, mEndOfStreamSent);
123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Codec is no longer executing.  Discard all codec-related state.
125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mCodecBuffers.clear();
126f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries
127f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    //       are null; complain if not
128f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = false;
130f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
131f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
132f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
133f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
134f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
135f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting) {
136f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen -- buffers can only be allocated when
137f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // transitioning from "loaded" to "idle".
138f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("addCodecBuffer: buffer added while executing");
139f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
140f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
141f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
142f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("addCodecBuffer h=%p size=%lu p=%p",
143f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header, header->nAllocLen, header->pBuffer);
144f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer codecBuffer;
145f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    codecBuffer.mHeader = header;
146f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mCodecBuffers.add(codecBuffer);
147f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
148f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
150f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
151f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
152f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mExecuting);  // could this happen if app stop()s early?
153f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
154f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int cbi = findMatchingCodecBuffer_l(header);
155f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
156f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen.
157f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header);
158f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
159f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
160f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
161f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("codecBufferEmptied h=%p size=%lu filled=%lu p=%p",
162f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header, header->nAllocLen, header->nFilledLen,
163f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header->pBuffer);
164f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
165f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
166f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // header->nFilledLen may not be the original value, so we can't compare
167f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that to zero to see of this was the EOS buffer.  Instead we just
168f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // see if the GraphicBuffer reference was null, which should only ever
169f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // happen for EOS.
170f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (codecBuffer.mGraphicBuffer == NULL) {
171f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        CHECK(mEndOfStream);
172f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No GraphicBuffer to deal with, no additional input or output is
173f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // expected, so just return.
174f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
175f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
176f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
177f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (EXTRA_CHECK) {
178f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Pull the graphic buffer handle back out of the buffer, and confirm
179f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // that it matches expectations.
180f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U8* data = header->pBuffer;
181f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        buffer_handle_t bufferHandle;
182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t));
183f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (bufferHandle != codecBuffer.mGraphicBuffer->handle) {
184f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            // should never happen
185f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p",
186f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                    bufferHandle, codecBuffer.mGraphicBuffer->handle);
187f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            CHECK(!"codecBufferEmptied: mismatched buffer");
188f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
189f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
190f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
191f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Find matching entry in our cached copy of the BufferQueue slots.
192f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // If we find a match, release that slot.  If we don't, the BufferQueue
193f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // has dropped that GraphicBuffer, and there's nothing for us to release.
194f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    //
195f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // (We could store "id" in CodecBuffer and avoid the slot search.)
196f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int id;
197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) {
198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (mBufferSlot[id] == NULL) {
199f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            continue;
200f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
201f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGV("cbi %d matches bq slot %d, handle=%p",
204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                    cbi, id, mBufferSlot[id]->handle);
205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mBufferQueue->releaseBuffer(id, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
207f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                    Fence::NO_FENCE);
208f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            break;
209f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
210f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
211f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (id == BufferQueue::NUM_BUFFER_SLOTS) {
212f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d",
213f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                cbi);
214f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
215f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Mark the codec buffer as available by clearing the GraphicBuffer ref.
217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    codecBuffer.mGraphicBuffer = NULL;
218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mNumFramesAvailable) {
220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Fill this codec buffer.
221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        CHECK(!mEndOfStream);
222f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("buffer freed, %d frames avail", mNumFramesAvailable);
223f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
224f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else if (mEndOfStream) {
225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No frames available, but EOS is pending, so use this buffer to
226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // send that.
227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("buffer freed, EOS pending");
228f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return;
231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
233f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t GraphicBufferSource::fillCodecBuffer_l() {
234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mExecuting && mNumFramesAvailable > 0);
235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int cbi = findAvailableCodecBuffer_l();
236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No buffers available, bail.
238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("fillCodecBuffer_l: no codec buffers, avail now %d",
239f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                mNumFramesAvailable);
240f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else {
241f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%d",
242f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                mNumFramesAvailable);
243f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        BufferQueue::BufferItem item;
244f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        status_t err = mBufferQueue->acquireBuffer(&item);
245f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
246f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            // shouldn't happen
247f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGW("fillCodecBuffer_l: frame was not available");
248f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return err;
249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        } else if (err != OK) {
250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            // now what? fake end-of-stream?
251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err);
252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return err;
253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
254f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
255f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        mNumFramesAvailable--;
256f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
257f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Wait for it to become available.
258f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        err = item.mFence->waitForever(1000,
259f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                "GraphicBufferSource::fillCodecBuffer_l");
260f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (err != OK) {
261f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGW("failed to wait for buffer fence: %d", err);
262f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            // keep going
263f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
264f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
265f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // If this is the first time we're seeing this buffer, add it to our
266f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // slot table.
267f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (item.mGraphicBuffer != NULL) {
268f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
269f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mBufferSlot[item.mBuf] = item.mGraphicBuffer;
270f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
271f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
272f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        err = submitBuffer_l(mBufferSlot[item.mBuf], item.mTimestamp, cbi);
273f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (err != OK) {
274f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
275f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY,
276f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                EGL_NO_SYNC_KHR, Fence::NO_FENCE);
277f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        } else {
278f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
279f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
280f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
281f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
282f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
283f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
284f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::signalEndOfInputStream() {
286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
287f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("signalEndOfInputStream: exec=%d avail=%d",
288f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mExecuting, mNumFramesAvailable);
289f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Set the end-of-stream flag.  If no frames are pending from the
291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // BufferQueue, and a codec buffer is available, and we're executing,
292f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // we initiate the EOS from here.  Otherwise, we'll let
293f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // codecBufferEmptied() (or omxExecuting) do it.
294f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    //
295f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Note: if there are no pending frames and all codec buffers are
296f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // available, we *must* submit the EOS from here or we'll just
297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // stall since no future events are expected.
298f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mEndOfStream = true;
299f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting && mNumFramesAvailable == 0) {
301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
302f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
303f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
304f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
305f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t GraphicBufferSource::submitBuffer_l(sp<GraphicBuffer>& graphicBuffer,
306f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        int64_t timestamp, int cbi) {
307f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("submitBuffer_l cbi=%d", cbi);
308f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
309f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    codecBuffer.mGraphicBuffer = graphicBuffer;
310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
311f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
312f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t));
313f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_U8* data = header->pBuffer;
314f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const OMX_U32 type = kMetadataBufferTypeGrallocSource;
315f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle;
316f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    memcpy(data, &type, 4);
317f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    memcpy(data + 4, &handle, sizeof(buffer_handle_t));
318f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
319f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err = mNodeInstance->emptyDirectBuffer(header, 0,
320f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME,
321f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            timestamp);
322f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
323f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err);
324f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        codecBuffer.mGraphicBuffer = NULL;
325f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
326f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
327f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
328f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p",
329f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header, header->pBuffer, handle);
330f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
331f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
332f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
333f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() {
334f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mEndOfStream);
335f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStreamSent) {
336f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("EOS already sent");
337f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
338f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
339f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
340f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int cbi = findAvailableCodecBuffer_l();
341f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("submitEndOfInputStream_l: no codec buffers available");
343f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
344f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
345f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // We reject any additional incoming graphic buffers, so there's no need
347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as
348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // in-use.
349f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (EXTRA_CHECK) {
353f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Guard against implementations that don't check nFilledLen.
354f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        size_t fillLen = 4 + sizeof(buffer_handle_t);
355f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        CHECK(header->nAllocLen >= fillLen);
356f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U8* data = header->pBuffer;
357f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        memset(data, 0xcd, fillLen);
358f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
359f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
360f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    uint64_t timestamp = 0; // does this matter?
361f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
362f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0,
363f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
364f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            timestamp);
365f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
366f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
367f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else {
368f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d",
369f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                header, cbi);
370f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
371f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
372f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
373f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() {
374f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mCodecBuffers.size() > 0);
375f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
376f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
377f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (mCodecBuffers[i].mGraphicBuffer == NULL) {
378f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return i;
379f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
380f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
381f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return -1;
382f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
383f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
384f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l(
385f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        const OMX_BUFFERHEADERTYPE* header) {
386f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
387f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (mCodecBuffers[i].mHeader == header) {
388f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return i;
389f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
390f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return -1;
392f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
394f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
395f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onFrameAvailable() {
396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
397f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
398f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("onFrameAvailable exec=%d avail=%d", mExecuting, mNumFramesAvailable);
399f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
400f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStream) {
401f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should only be possible if a new buffer was queued after
402f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // EOS was signaled, i.e. the app is misbehaving.
403f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("onFrameAvailable: EOS is set, ignoring frame");
404f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
405f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        BufferQueue::BufferItem item;
406f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        status_t err = mBufferQueue->acquireBuffer(&item);
407f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (err == OK) {
408f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY,
409f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                EGL_NO_SYNC_KHR, item.mFence);
410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
411f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
412f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
413f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
414f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mNumFramesAvailable++;
415f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
416f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting) {
417f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
420f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
421f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() {
423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock lock(mMutex);
424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
425f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    uint32_t slotMask;
426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mBufferQueue->getReleasedBuffers(&slotMask) != NO_ERROR) {
427f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("onBuffersReleased: unable to get released buffer set");
428f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        slotMask = 0xffffffff;
429f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
430f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
431f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("onBuffersReleased: 0x%08x", slotMask);
432f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
433f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
434f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if ((slotMask & 0x01) != 0) {
435f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mBufferSlot[i] = NULL;
436f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
437f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        slotMask >>= 1;
438f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
439f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
441f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}  // namespace android
442