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