GraphicBufferSource.cpp revision 910813bd66eaf0f6a72769c9b3fa9830dd100a19
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" 18ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden//#define LOG_NDEBUG 0 19f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <utils/Log.h> 20f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 215e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include "GraphicBufferSource.h" 22f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 23f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <OMX_Core.h> 24f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h> 25f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 265e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h> 27f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h> 28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 29f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android { 30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 31f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true; 32f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 33f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance, 350c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount) : 36f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck(UNKNOWN_ERROR), 37f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNodeInstance(nodeInstance), 38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting(false), 39e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended(false), 40f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable(0), 41f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream(false), 42f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStreamSent(false) { 43f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 450c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 46f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 47f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 480c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 49f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 50f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 51f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 52f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 530c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden String8 name("GraphicBufferSource"); 540c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 555e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian mBufferQueue = new BufferQueue(); 560c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferQueue->setConsumerName(name); 57f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferQueue->setDefaultBufferSize(bufferWidth, bufferHeight); 58f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER | 59f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden GRALLOC_USAGE_HW_TEXTURE); 60f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 610c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mInitCheck = mBufferQueue->setMaxAcquiredBufferCount(bufferCount); 620c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 630c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferCount, mInitCheck); 650c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return; 660c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 670c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 68f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 69f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 70f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 71f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 72910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 73910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); 74f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 755e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian mInitCheck = mBufferQueue->consumerConnect(proxy, false); 760c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 77f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 780c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 79f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 80f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 81f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 83f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 84f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 85f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 86f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("~GraphicBufferSource"); 870c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mBufferQueue != NULL) { 880c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden status_t err = mBufferQueue->consumerDisconnect(); 890c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 900c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 910c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 92f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 93f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 94f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 95f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 96f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 97f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("--> executing; avail=%d, codec vec size=%zd", 98f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 99f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 100f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 101f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 102f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 103f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 104f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 105f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 106f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 107f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 108f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 109f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 110f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 1110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 1120c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 1130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 1140c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 1150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 1160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 117f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 118f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 119f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("done loading initial frames, avail=%d", mNumFramesAvailable); 120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 121f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 126f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 127f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 128ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 130ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 131ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 132ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 133ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 134f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 135ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGV("--> loaded; avail=%d eos=%d eosSent=%d", 136f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 137f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 138f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 139f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 140f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 141f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 142f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 143f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 144f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 145f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 146f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 147f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 148f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 150f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 151f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 152f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 153f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 154f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 155f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 156f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("addCodecBuffer h=%p size=%lu p=%p", 157f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 158f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 159f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 160f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 161f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 162f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 163f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) { 164f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 165f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 166f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting); // could this happen if app stop()s early? 167f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 168f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 169f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 170f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 171f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 172f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 173f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 174f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 175f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied h=%p size=%lu filled=%lu p=%p", 176f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 177f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 178f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 179f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 180f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 181f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 183f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 184f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 1850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mEndOfStream && mEndOfStreamSent); 186f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 187f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 188f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 189f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 190f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 191f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (EXTRA_CHECK) { 192f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 193f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 194f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 195f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden buffer_handle_t bufferHandle; 196f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t)); 197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferHandle != codecBuffer.mGraphicBuffer->handle) { 198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // should never happen 199f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 200f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden bufferHandle, codecBuffer.mGraphicBuffer->handle); 201f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!"codecBufferEmptied: mismatched buffer"); 202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 207f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 208d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar int id = codecBuffer.mBuf; 209d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 210d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 211d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 212d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 213d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 214d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferQueue->releaseBuffer(id, codecBuffer.mFrameNumber, 215d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 216d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 222f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 223f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 224f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 2260c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 2270c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer freed, %d frames avail (eos=%d)", 2280c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 233f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 239e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 240e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 241e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 242e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 243e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 244e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 245e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 246e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber BufferQueue::BufferItem item; 247e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber status_t err = mBufferQueue->acquireBuffer(&item, 0); 248e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 249e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 250e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 251e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 252e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 253e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 254e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 255e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 256e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 257e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 258e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 259e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 260e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber, 261e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 262e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 263e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 264e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 265e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 266e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 267e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 268e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 2690c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 270f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 2710c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 272e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 273e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 274e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 275e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 276f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 277f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 278f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 279f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("fillCodecBuffer_l: no codec buffers, avail now %d", 280f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 2810c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 2820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 283f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 2840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%d", 2850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 2860c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden BufferQueue::BufferItem item; 287656e86250cd68f7f362c50a4bc92a865e9deacbeAndy McFadden status_t err = mBufferQueue->acquireBuffer(&item, 0); 2880c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 2890c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 2900c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 2910c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 2920c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 2930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 2940c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 2950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 2960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 2980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 299f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // Wait for it to become available. 301d76442421eadfa73f2f3a9e50f6caf65b0dd1ce9Mathias Agopian err = item.mFence->waitForever("GraphicBufferSource::fillCodecBuffer_l"); 3020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 3030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("failed to wait for buffer fence: %d", err); 3040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // keep going 3050c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 306f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 3080c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 3090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 3100c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf); 3110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferSlot[item.mBuf] = item.mGraphicBuffer; 3120c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 3130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 314d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar err = submitBuffer_l(item, cbi); 3150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 3160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf); 317d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber, 318d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 3190c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 3200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi); 321f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 322f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 324f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 325f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 326ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 327f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 328ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGV("signalEndOfInputStream: exec=%d avail=%d eos=%d", 329ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 330ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 331ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 332ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 333ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 334ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 335f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 336f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 337f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 338f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 339f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 340f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 341f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 343f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 344f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 345f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 349ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 350ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 353d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l( 354d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar const BufferQueue::BufferItem &item, int cbi) { 355f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 356f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 357d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf]; 358d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mBuf = item.mBuf; 359d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 360f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 361f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 362f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t)); 363f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 364f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_U32 type = kMetadataBufferTypeGrallocSource; 365f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle; 366f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(data, &type, 4); 367f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(data + 4, &handle, sizeof(buffer_handle_t)); 368f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 369f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden status_t err = mNodeInstance->emptyDirectBuffer(header, 0, 370f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME, 371d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar item.mTimestamp / 1000); 372f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 373f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err); 374f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 375f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 376f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 377f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 378f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p", 379f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->pBuffer, handle); 380f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 381f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 382f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 383f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 384f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 385f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 386f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 387f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 388f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 389f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 390f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 392f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 394f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 395f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 397f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 398f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 399f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 400f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 401f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 402f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (EXTRA_CHECK) { 403f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Guard against implementations that don't check nFilledLen. 404f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden size_t fillLen = 4 + sizeof(buffer_handle_t); 405f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(header->nAllocLen >= fillLen); 406f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 407f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memset(data, 0xcd, fillLen); 408f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 409f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden uint64_t timestamp = 0; // does this matter? 411f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 412f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0, 413f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 414f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden timestamp); 415f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 416f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 417f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 4200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 421f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 425f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 427f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 428f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 429f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 430f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 431f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 432f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 433f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 434f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 435f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 436f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 437f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 438f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 439f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 441f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 442f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 443f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 444f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 445f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 446f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onFrameAvailable() { 447f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 448f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4490c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("onFrameAvailable exec=%d avail=%d", 4500c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 451f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 452e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 453e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 454e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 455e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 456e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 457e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 458e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 459e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 460e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 461f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 462f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden BufferQueue::BufferItem item; 463656e86250cd68f7f362c50a4bc92a865e9deacbeAndy McFadden status_t err = mBufferQueue->acquireBuffer(&item, 0); 464f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 465d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber, 466d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 467f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 468f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 469f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 470f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 471f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 472f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 473f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 474f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 475f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 476f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 477f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 478f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 479f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 480f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 481f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 482f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden uint32_t slotMask; 483f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mBufferQueue->getReleasedBuffers(&slotMask) != NO_ERROR) { 484f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 485f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask = 0xffffffff; 486f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 487f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 488f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("onBuffersReleased: 0x%08x", slotMask); 489f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 490f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 491f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 493f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 494f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 495f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 496f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 497f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 498f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 499