GraphicBufferSource.cpp revision 892e1b9ab055075ba9036fb7dd6404e9e0f2677a
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> 25a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber#include <media/stagefright/foundation/AMessage.h> 26f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 275e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h> 28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h> 29f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android { 31f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 32f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true; 33f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 35f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance, 360c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount) : 37f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck(UNKNOWN_ERROR), 38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNodeInstance(nodeInstance), 39f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting(false), 40e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended(false), 41f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable(0), 42f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream(false), 43a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mEndOfStreamSent(false), 44a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs(-1ll), 45a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatLastFrameGeneration(0), 46a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferId(-1), 47a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferFrameNum(0), 48a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferUseCount(0), 49a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred(false) { 50f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 510c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 53f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 54f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 550c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 56f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 57f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 58f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 59f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 600c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden String8 name("GraphicBufferSource"); 610c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 625e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian mBufferQueue = new BufferQueue(); 630c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferQueue->setConsumerName(name); 64f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferQueue->setDefaultBufferSize(bufferWidth, bufferHeight); 65f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER | 66f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden GRALLOC_USAGE_HW_TEXTURE); 67f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 680c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mInitCheck = mBufferQueue->setMaxAcquiredBufferCount(bufferCount); 690c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 700c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 710c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferCount, mInitCheck); 720c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return; 730c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 740c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 75f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 76f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 77f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 78f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 79910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 80910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); 81f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 825e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian mInitCheck = mBufferQueue->consumerConnect(proxy, false); 830c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 84f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 86f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 87f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 88f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 890c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 90f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 91f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 92f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 93f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("~GraphicBufferSource"); 940c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mBufferQueue != NULL) { 950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden status_t err = mBufferQueue->consumerDisconnect(); 960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 970c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 99f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 100f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 101f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 102f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 103f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 104f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("--> executing; avail=%d, codec vec size=%zd", 105f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 106f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 107f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 108f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 109f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 110f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 111f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 112f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 113f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 117f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 1180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 1190c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 1200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 1210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 1220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 1230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 126f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("done loading initial frames, avail=%d", mNumFramesAvailable); 127f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 128f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 130f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 131f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 132f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 133a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 134a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mRepeatAfterUs > 0ll && mLooper == NULL) { 135a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector = new AHandlerReflector<GraphicBufferSource>(this); 136a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 137a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper = new ALooper; 138a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->registerHandler(mReflector); 139a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->start(); 140a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferId >= 0) { 142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = 143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber new AMessage(kWhatRepeatLastFrame, mReflector->id()); 144a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 145a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 147a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 148a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 150f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 151ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() { 152ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber ALOGV("omxIdle"); 153ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 154ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber Mutex::Autolock autoLock(mMutex); 155ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 156ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber if (mExecuting) { 157ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // We are only interested in the transition from executing->idle, 158ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // not loaded->idle. 159892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber mExecuting = false; 160ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber } 161ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber} 162ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 163ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 164f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 165ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 166ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 167ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 168ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 169f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 170a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLooper != NULL) { 171a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->unregisterHandler(mReflector->id()); 172a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector.clear(); 173a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 174a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->stop(); 175a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper.clear(); 176a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 177a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 178ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGV("--> loaded; avail=%d eos=%d eosSent=%d", 179f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 180f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 181f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 183f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 184f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 185f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 186f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 187f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 188f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 189f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 190f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 191f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 192f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 193f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 194f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 195f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 196f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 199f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("addCodecBuffer h=%p size=%lu p=%p", 200f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 201f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) { 207f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 208f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 209892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber if (!mExecuting) { 210892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber return; 211892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber } 212f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 213f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 214f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 215f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied h=%p size=%lu filled=%lu p=%p", 221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 222f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 223f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 224f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 228f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 2305572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden if (!(mEndOfStream && mEndOfStreamSent)) { 2315572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // This can happen when broken code sends us the same buffer 2325572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // twice in a row. 2335572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 2345572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden "(buffer emptied twice?)"); 2355572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden } 236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 239f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 240f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 241f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (EXTRA_CHECK) { 242f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 243f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 244f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 245f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden buffer_handle_t bufferHandle; 246f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t)); 247f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferHandle != codecBuffer.mGraphicBuffer->handle) { 248f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // should never happen 249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden bufferHandle, codecBuffer.mGraphicBuffer->handle); 251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!"codecBufferEmptied: mismatched buffer"); 252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 254f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 255f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 256f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 257f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 258d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar int id = codecBuffer.mBuf; 259d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 260d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 261d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 262d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 263d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 264a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (id == mLatestSubmittedBufferId) { 265a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK_GT(mLatestSubmittedBufferUseCount--, 0); 266a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 267a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mBufferQueue->releaseBuffer(id, codecBuffer.mFrameNumber, 268a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 269a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 270d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 271f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 272f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 273f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 274f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 275f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 276f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 277f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 278f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 279f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 2800c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 2810c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer freed, %d frames avail (eos=%d)", 2820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 283f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 284f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 287f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 288f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 289a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 290a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber bool success = repeatLatestSubmittedBuffer_l(); 291a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 292a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("deferred repeatLatestSubmittedBuffer_l SUCCESS"); 293a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 294a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("deferred repeatLatestSubmittedBuffer_l FAILURE"); 295a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 296a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 298a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 299f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 302e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 303e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 304e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 305e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 306e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 307e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 308e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 309e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber BufferQueue::BufferItem item; 310e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber status_t err = mBufferQueue->acquireBuffer(&item, 0); 311e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 312e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 313e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 314e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 315e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 316e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 317e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 318e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 319e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 320e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 321e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 322e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 323e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber, 324e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 325e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 326e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 327e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 328e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 329e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 330a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 331a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 332a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (repeatLatestSubmittedBuffer_l()) { 333a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l SUCCESS"); 334a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 335a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 336a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 337a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l FAILURE"); 338a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 339a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 340e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 341e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 3420c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 343f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 3440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 345e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 346e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 347e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 348e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 349f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("fillCodecBuffer_l: no codec buffers, avail now %d", 353f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 3540c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 3550c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 356f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3570c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%d", 3580c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 3590c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden BufferQueue::BufferItem item; 360656e86250cd68f7f362c50a4bc92a865e9deacbeAndy McFadden status_t err = mBufferQueue->acquireBuffer(&item, 0); 3610c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 3620c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 3630c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 3640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 3650c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 3660c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 3670c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 3680c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 3690c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 370f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3710c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 372f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3730c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // Wait for it to become available. 374d76442421eadfa73f2f3a9e50f6caf65b0dd1ce9Mathias Agopian err = item.mFence->waitForever("GraphicBufferSource::fillCodecBuffer_l"); 3750c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 3760c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("failed to wait for buffer fence: %d", err); 3770c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // keep going 3780c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 379f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 3800c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 3810c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 3820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 3830c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf); 3840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferSlot[item.mBuf] = item.mGraphicBuffer; 3850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 3860c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 387d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar err = submitBuffer_l(item, cbi); 3880c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 3890c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf); 390d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber, 391d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 3920c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 3930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi); 394a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber setLatestSubmittedBuffer_l(item); 395a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 396a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 397a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 398a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 399a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 400a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberbool GraphicBufferSource::repeatLatestSubmittedBuffer_l() { 401a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 402a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 403a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferId < 0 || mSuspended) { 404a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 405a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 406bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden if (mBufferSlot[mLatestSubmittedBufferId] == NULL) { 407bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 408bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 409bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 410bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 411bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 412bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden ALOGD("repeatLatestSubmittedBuffer_l: slot was NULL"); 413bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mBufferQueue->releaseBuffer( 414bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferId, 415bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferFrameNum, 416bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 417bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 418bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden Fence::NO_FENCE); 419bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferId = -1; 420bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferFrameNum = 0; 421bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 422bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 423a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 424a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 425a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 426a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 427a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("repeatLatestSubmittedBuffer_l: no codec buffers."); 428a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 429a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 430a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 431a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber BufferQueue::BufferItem item; 432a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber item.mBuf = mLatestSubmittedBufferId; 433a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber item.mFrameNumber = mLatestSubmittedBufferFrameNum; 434a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 435a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 436a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 437a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 438a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 439f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 441a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mLatestSubmittedBufferUseCount; 442a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 4430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 444f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 445f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 446a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::setLatestSubmittedBuffer_l( 447a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber const BufferQueue::BufferItem &item) { 448a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("setLatestSubmittedBuffer_l"); 449a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 450a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferId >= 0) { 451a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferUseCount == 0) { 452a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mBufferQueue->releaseBuffer( 453a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferId, 454a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferFrameNum, 455a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber EGL_NO_DISPLAY, 456a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber EGL_NO_SYNC_KHR, 457a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Fence::NO_FENCE); 458a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 459a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 460a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 461a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferId = item.mBuf; 462a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferFrameNum = item.mFrameNumber; 463a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferUseCount = 1; 464a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 465a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 466a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 467a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id()); 468a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 469a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 470a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 471a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 472a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 473ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 474f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 475ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGV("signalEndOfInputStream: exec=%d avail=%d eos=%d", 476ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 477ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 478ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 479ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 480ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 481ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 482f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 483f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 484f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 485f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 486f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 487f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 488f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 489f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 490f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 491f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 493f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 494f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 495f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 496ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 497ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 498f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 499f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 500d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l( 501d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar const BufferQueue::BufferItem &item, int cbi) { 502f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 503f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 504d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf]; 505d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mBuf = item.mBuf; 506d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 507f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 508f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 509f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t)); 510f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 511f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_U32 type = kMetadataBufferTypeGrallocSource; 512f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle; 513f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(data, &type, 4); 514f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(data + 4, &handle, sizeof(buffer_handle_t)); 515f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 516f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden status_t err = mNodeInstance->emptyDirectBuffer(header, 0, 517f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME, 518d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar item.mTimestamp / 1000); 519f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 520f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err); 521f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 522f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 523f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 524f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 525f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p", 526f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->pBuffer, handle); 527f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 528f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 529f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 530f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 531f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 532f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 533f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 534f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 535f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 536f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 537f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 538f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 539f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 540f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 541f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 542f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 543f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 544f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 545f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 546f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 547f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 548f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 549f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (EXTRA_CHECK) { 550f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Guard against implementations that don't check nFilledLen. 551f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden size_t fillLen = 4 + sizeof(buffer_handle_t); 552f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(header->nAllocLen >= fillLen); 553f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 554f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memset(data, 0xcd, fillLen); 555f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 556f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 557f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden uint64_t timestamp = 0; // does this matter? 558f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 559f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0, 560f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 561f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden timestamp); 562f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 563f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 564f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 565f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 566f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 5670c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 568f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 569f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 570f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 571f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 572f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 573f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 574f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 575f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 576f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 577f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 578f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 579f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 580f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 581f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 582f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 583f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 584f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 585f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 586f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 587f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 588f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 589f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 590f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 591f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 592f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 593f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onFrameAvailable() { 594f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 595f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 5960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("onFrameAvailable exec=%d avail=%d", 5970c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 598f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 599e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 600e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 601e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 602e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 603e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 604e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 605e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 606e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 607e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 608f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 609f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden BufferQueue::BufferItem item; 610656e86250cd68f7f362c50a4bc92a865e9deacbeAndy McFadden status_t err = mBufferQueue->acquireBuffer(&item, 0); 611f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 612d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber, 613d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 614f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 615f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 616f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 617f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 618f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 619f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 620a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 621a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 622a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 623f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 624f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 625f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 626f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 627f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 628f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 629f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 630f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 631f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 632f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden uint32_t slotMask; 633f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mBufferQueue->getReleasedBuffers(&slotMask) != NO_ERROR) { 634f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 635f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask = 0xffffffff; 636f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 637f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 638f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("onBuffersReleased: 0x%08x", slotMask); 639f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 640f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 641f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 642f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 643f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 644f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 645f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 646f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 647f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 648a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 649a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 650a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 651a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 652a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 653a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 654a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 655a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 656a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 657a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 658a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 659a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 660a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 661a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 662a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 663a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 664a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 665a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 666a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 667a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 668a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 669a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 670a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 671a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 672a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 673a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 674a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 675a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 676a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 677a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 678a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 679a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber bool success = repeatLatestSubmittedBuffer_l(); 680a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 681a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 682a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("repeatLatestSubmittedBuffer_l SUCCESS"); 683a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 684a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("repeatLatestSubmittedBuffer_l FAILURE"); 685a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 686a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 687a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 688a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 689a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 690a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 691a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 692a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 693a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 694a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 695f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 696