GraphicBufferSource.cpp revision a5750e0dad9e90f2195ce36f2c4457fa04b2b83e
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 17db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <inttypes.h> 18db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn 19f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#define LOG_TAG "GraphicBufferSource" 20ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden//#define LOG_NDEBUG 0 21f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <utils/Log.h> 22f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 235e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include "GraphicBufferSource.h" 24f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 25f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <OMX_Core.h> 26f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h> 27a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber#include <media/stagefright/foundation/AMessage.h> 28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 295e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h> 30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h> 31f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 322475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza#include <inttypes.h> 332475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza 34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android { 35f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 36f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true; 37f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 39f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance, 400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount) : 41f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck(UNKNOWN_ERROR), 42f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNodeInstance(nodeInstance), 43f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting(false), 44e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended(false), 45f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable(0), 46f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream(false), 47a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mEndOfStreamSent(false), 4894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs(-1ll), 4994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs(-1ll), 5094ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs(-1ll), 5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs(-1ll), 5284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber mRepeatAfterUs(-1ll), 53a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatLastFrameGeneration(0), 5494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp(-1ll), 55a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferId(-1), 56a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferFrameNum(0), 57a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferUseCount(0), 582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mRepeatBufferDeferred(false), 592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs(-1ll), 602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs(-1ll), 612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs(-1ll), 622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs(-1ll) { 63f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 650c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 66f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 67f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 680c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 69f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 70f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 71f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 72f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 730c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden String8 name("GraphicBufferSource"); 740c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 755205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza BufferQueue::createBufferQueue(&mProducer, &mConsumer); 765205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->setConsumerName(name); 775205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); 785205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER | 79f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden GRALLOC_USAGE_HW_TEXTURE); 80f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 815205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount); 820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 830c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferCount, mInitCheck); 850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return; 860c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 870c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 88f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 89f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 90f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 91f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 92910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 93910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); 94f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 955205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mInitCheck = mConsumer->consumerConnect(proxy, false); 960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 97f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 99f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 100f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 101f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 103f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 104f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 105f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 106f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("~GraphicBufferSource"); 1075205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer != NULL) { 1085205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->consumerDisconnect(); 1090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 1100c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 1110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 112f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 113f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 117a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> executing; avail=%zu, codec vec size=%zd", 118f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 119f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 121f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 126f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 127f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 128f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 130f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 1310c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 1320c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 1330c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 1340c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 1350c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 1360c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 137f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 138f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 139a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable); 140f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 141f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 142f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 143f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 144f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 145f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 147a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mRepeatAfterUs > 0ll && mLooper == NULL) { 148a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector = new AHandlerReflector<GraphicBufferSource>(this); 149a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 150a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper = new ALooper; 151a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->registerHandler(mReflector); 152a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->start(); 153a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 154a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferId >= 0) { 155a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = 156a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber new AMessage(kWhatRepeatLastFrame, mReflector->id()); 157a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 158a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 159a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 160a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 161a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 162f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 163f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 164ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() { 165ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber ALOGV("omxIdle"); 166ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 167ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber Mutex::Autolock autoLock(mMutex); 168ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 169ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber if (mExecuting) { 170ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // We are only interested in the transition from executing->idle, 171ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // not loaded->idle. 172892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber mExecuting = false; 173ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber } 174ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber} 175ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 176ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 177f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 178ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 179ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 180ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 181ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 183a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLooper != NULL) { 184a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->unregisterHandler(mReflector->id()); 185a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector.clear(); 186a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 187a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->stop(); 188a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper.clear(); 189a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 190a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 191a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d", 192f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 193f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 194f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 195f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 196f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 199f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 200f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 201f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 207f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 208f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 209f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 210f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 211f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 212db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p", 213f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 214f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 215f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) { 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 222892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber if (!mExecuting) { 223892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber return; 224892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber } 225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 228f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 233db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p", 234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 239f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 240f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 241f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 242f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 2435572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden if (!(mEndOfStream && mEndOfStreamSent)) { 2445572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // This can happen when broken code sends us the same buffer 2455572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // twice in a row. 2465572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 2475572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden "(buffer emptied twice?)"); 2485572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden } 249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 254f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (EXTRA_CHECK) { 255f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 256f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 257f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 258f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden buffer_handle_t bufferHandle; 259f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t)); 260f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferHandle != codecBuffer.mGraphicBuffer->handle) { 261f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // should never happen 262f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 263f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden bufferHandle, codecBuffer.mGraphicBuffer->handle); 264f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!"codecBufferEmptied: mismatched buffer"); 265f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 266f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 267f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 268f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 269f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 270f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 271d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar int id = codecBuffer.mBuf; 272d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 273d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 274d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 275d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 276d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 277a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (id == mLatestSubmittedBufferId) { 278a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK_GT(mLatestSubmittedBufferUseCount--, 0); 279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 2805205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer(id, codecBuffer.mFrameNumber, 281a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 282a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 283d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 284f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 287f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 288f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 289f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 292f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 2930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 294a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("buffer freed, %zu frames avail (eos=%d)", 2950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 296f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 298f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 299f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 302a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 303a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber bool success = repeatLatestSubmittedBuffer_l(); 304a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 305a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("deferred repeatLatestSubmittedBuffer_l SUCCESS"); 306a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 307a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("deferred repeatLatestSubmittedBuffer_l FAILURE"); 308a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 309a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 311a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 312f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 313f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 314f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 31594ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 31694ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 31794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 31894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mMaxTimestampGapUs > 0ll 31994ee4b708acfa941581160b267afb79192b1d816Chong Zhang && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 32094ee4b708acfa941581160b267afb79192b1d816Chong Zhang ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 32194ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (index >= 0) { 32294ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGV("OUT timestamp: %lld -> %lld", 323a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(header->nTimeStamp), 324a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mOriginalTimeUs[index])); 32594ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp = mOriginalTimeUs[index]; 32694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.removeItemsAt(index); 32794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } else { 32894ee4b708acfa941581160b267afb79192b1d816Chong Zhang // giving up the effort as encoder doesn't appear to preserve pts 32994ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGW("giving up limiting timestamp gap (pts = %lld)", 33094ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp); 33194ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 33294ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 33394ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 33494ee4b708acfa941581160b267afb79192b1d816Chong Zhang // something terribly wrong must have happened, giving up... 335a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("mOriginalTimeUs has too many entries (%zu)", 33694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.size()); 33794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 33894ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 33994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 34094ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 34194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 342e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 343e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 344e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 345e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 346e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 347e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 348e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 349e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber BufferQueue::BufferItem item; 3505205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 351e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 352e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 353e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 354e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 355e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 356e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 357e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 358e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 359e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 360e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 361e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 362e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 3635205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, 364e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 365e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 366e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 367e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 368e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 369e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 370a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 371a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (repeatLatestSubmittedBuffer_l()) { 373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l SUCCESS"); 374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 376a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 377a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l FAILURE"); 378a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 379a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 380e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 381e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 3820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 383f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 3840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 385e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 386e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 387e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 388e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 389f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 390f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 392a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 3940c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 3950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 397a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 3980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 3990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden BufferQueue::BufferItem item; 4005205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 4010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 4020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 4030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 4040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 4050c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 4060c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 4070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 4080c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 4090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 412f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // Wait for it to become available. 414d76442421eadfa73f2f3a9e50f6caf65b0dd1ce9Mathias Agopian err = item.mFence->waitForever("GraphicBufferSource::fillCodecBuffer_l"); 4150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 4160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("failed to wait for buffer fence: %d", err); 4170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // keep going 4180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 4210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 4220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 4230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf); 4240c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferSlot[item.mBuf] = item.mGraphicBuffer; 4250c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 4260c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = UNKNOWN_ERROR; 42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // only submit sample if start time is unspecified, or sample 43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // is queued after the specified start time 43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if start time is set, offset time stamp by start time 43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs > 0) { 43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang item.mTimestamp -= mSkipFramesBeforeNs; 43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = submitBuffer_l(item, cbi); 43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4390c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 4400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf); 4415205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, 442d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 4430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 4440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi); 445a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber setLatestSubmittedBuffer_l(item); 446a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 447a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 448a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 449a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 450a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 451a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberbool GraphicBufferSource::repeatLatestSubmittedBuffer_l() { 452a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 453a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 454a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferId < 0 || mSuspended) { 455a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 456a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 457bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden if (mBufferSlot[mLatestSubmittedBufferId] == NULL) { 458bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 459bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 460bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 461bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 462bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 463bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden ALOGD("repeatLatestSubmittedBuffer_l: slot was NULL"); 4645205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 465bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferId, 466bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferFrameNum, 467bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 468bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 469bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden Fence::NO_FENCE); 470bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferId = -1; 471bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden mLatestSubmittedBufferFrameNum = 0; 472bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 473bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 474a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 475a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 476a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 477a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("repeatLatestSubmittedBuffer_l: no codec buffers."); 479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 481a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 482a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber BufferQueue::BufferItem item; 483a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber item.mBuf = mLatestSubmittedBufferId; 484a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber item.mFrameNumber = mLatestSubmittedBufferFrameNum; 48594ee4b708acfa941581160b267afb79192b1d816Chong Zhang item.mTimestamp = mRepeatLastFrameTimestamp; 486a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 487a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 488a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 489a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 490a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 491f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 493a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mLatestSubmittedBufferUseCount; 494a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 49594ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* repeat last frame up to kRepeatLastFrameCount times. 49694ee4b708acfa941581160b267afb79192b1d816Chong Zhang * in case of static scene, a single repeat might not get rid of encoder 49794ee4b708acfa941581160b267afb79192b1d816Chong Zhang * ghosting completely, refresh a couple more times to get better quality 49894ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 49994ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (--mRepeatLastFrameCount > 0) { 50094ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 50194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 50294ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mReflector != NULL) { 50394ee4b708acfa941581160b267afb79192b1d816Chong Zhang sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id()); 50494ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->setInt32("generation", ++mRepeatLastFrameGeneration); 50594ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->post(mRepeatAfterUs); 50694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 50794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 50894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 5090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 510f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 511f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 512a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::setLatestSubmittedBuffer_l( 513a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber const BufferQueue::BufferItem &item) { 514a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("setLatestSubmittedBuffer_l"); 515a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 516a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferId >= 0) { 517a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLatestSubmittedBufferUseCount == 0) { 5185205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 519a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferId, 520a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferFrameNum, 521a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber EGL_NO_DISPLAY, 522a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber EGL_NO_SYNC_KHR, 523a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Fence::NO_FENCE); 524a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 525a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 526a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 527a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferId = item.mBuf; 528a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferFrameNum = item.mFrameNumber; 52994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 53094ee4b708acfa941581160b267afb79192b1d816Chong Zhang 531a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLatestSubmittedBufferUseCount = 1; 532a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 53394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameCount = kRepeatLastFrameCount; 534a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 535a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 536a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id()); 537a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 538a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 539a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 540a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 541a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 542ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 543f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 544a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 545ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 546ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 547ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 548ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 549ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 550ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 551f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 552f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 553f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 554f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 555f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 556f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 557f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 558f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 559f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 560f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 561f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 562f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 563f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 564f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 565ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 566ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 567f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 568f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 56994ee4b708acfa941581160b267afb79192b1d816Chong Zhangint64_t GraphicBufferSource::getTimestamp(const BufferQueue::BufferItem &item) { 57094ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timeUs = item.mTimestamp / 1000; 57194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 5722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mTimePerCaptureUs > 0ll) { 5732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // Time lapse or slow motion mode 5742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mPrevCaptureUs < 0ll) { 5752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // first capture 5762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = timeUs; 5772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs = timeUs; 5782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else { 5792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // snap to nearest capture point 5802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 5812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang / mTimePerCaptureUs; 5822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (nFrames <= 0) { 5832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // skip this frame as it's too close to previous capture 584a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 5852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return -1; 5862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 5872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 5882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs += mTimePerFrameUs * nFrames; 5892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 5902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 5912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 592a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs), 593a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevCaptureUs), 594a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevFrameUs)); 5952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 5962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return mPrevFrameUs; 5972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else if (mMaxTimestampGapUs > 0ll) { 59894ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* Cap timestamp gap between adjacent frames to specified max 59994ee4b708acfa941581160b267afb79192b1d816Chong Zhang * 60094ee4b708acfa941581160b267afb79192b1d816Chong Zhang * In the scenario of cast mirroring, encoding could be suspended for 60194ee4b708acfa941581160b267afb79192b1d816Chong Zhang * prolonged periods. Limiting the pts gap to workaround the problem 60294ee4b708acfa941581160b267afb79192b1d816Chong Zhang * where encoder's rate control logic produces huge frames after a 60394ee4b708acfa941581160b267afb79192b1d816Chong Zhang * long period of suspension. 60494ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 60594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 60694ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t originalTimeUs = timeUs; 60794ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mPrevOriginalTimeUs >= 0ll) { 60894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (originalTimeUs < mPrevOriginalTimeUs) { 60994ee4b708acfa941581160b267afb79192b1d816Chong Zhang // Drop the frame if it's going backward in time. Bad timestamp 61094ee4b708acfa941581160b267afb79192b1d816Chong Zhang // could disrupt encoder's rate control completely. 611b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang ALOGW("Dropping frame that's going backward in time"); 61294ee4b708acfa941581160b267afb79192b1d816Chong Zhang return -1; 61394ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 61494ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 61594ee4b708acfa941581160b267afb79192b1d816Chong Zhang timeUs = (timestampGapUs < mMaxTimestampGapUs ? 61694ee4b708acfa941581160b267afb79192b1d816Chong Zhang timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 61794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 61894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs = originalTimeUs; 61994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs = timeUs; 62094ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.add(timeUs, originalTimeUs); 621a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("IN timestamp: %lld -> %lld", 622a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(originalTimeUs), 623a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs)); 62494ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 62594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 62694ee4b708acfa941581160b267afb79192b1d816Chong Zhang return timeUs; 62794ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 62894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 629d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l( 630d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar const BufferQueue::BufferItem &item, int cbi) { 631f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 632b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 633b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang int64_t timeUs = getTimestamp(item); 634b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang if (timeUs < 0ll) { 635b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang return UNKNOWN_ERROR; 636b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang } 637b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 638f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 639d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf]; 640d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mBuf = item.mBuf; 641d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 642f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 643f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 644f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t)); 645f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 646f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_U32 type = kMetadataBufferTypeGrallocSource; 647f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle; 648f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(data, &type, 4); 649f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memcpy(data + 4, &handle, sizeof(buffer_handle_t)); 650f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 651f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden status_t err = mNodeInstance->emptyDirectBuffer(header, 0, 652f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME, 65394ee4b708acfa941581160b267afb79192b1d816Chong Zhang timeUs); 654f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 655f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err); 656f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 657f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 658f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 659f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 660f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p", 661f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->pBuffer, handle); 662f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 663f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 664f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 665f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 666f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 667f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 668f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 669f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 670f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 671f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 672f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 673f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 674f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 675f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 676f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 677f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 678f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 679f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 680f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 681f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 682f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 683f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 684f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (EXTRA_CHECK) { 685f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Guard against implementations that don't check nFilledLen. 686f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden size_t fillLen = 4 + sizeof(buffer_handle_t); 687f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(header->nAllocLen >= fillLen); 688f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 689f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden memset(data, 0xcd, fillLen); 690f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 691f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 692f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden uint64_t timestamp = 0; // does this matter? 693f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 694f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0, 695f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 696f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden timestamp); 697f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 698f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 699f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 700f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 701f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 7020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 703f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 704f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 705f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 706f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 707f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 708f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 709f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 710f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 711f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 712f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 713f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 714f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 715f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 716f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 717f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 720f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 721f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 722f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 723f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 724f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 725f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 726f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 727f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 728f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onFrameAvailable() { 729f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 730f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 731a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("onFrameAvailable exec=%d avail=%zu", 7320c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 733f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 734e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 735e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 736e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 737e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 738e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 739e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 740e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 741e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 742e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 743f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 744f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden BufferQueue::BufferItem item; 7455205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 746f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 74749270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // If this is the first time we're seeing this buffer, add it to our 74849270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // slot table. 74949270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang if (item.mGraphicBuffer != NULL) { 7502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf); 75149270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang mBufferSlot[item.mBuf] = item.mGraphicBuffer; 75249270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang } 7535205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, 754d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 755f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 756f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 757f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 760f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 761a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 762a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 763a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 764f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 765f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 766f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 771f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 772f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7732475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza uint64_t slotMask; 7745205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 775f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 7762475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza slotMask = 0xffffffffffffffffULL; 777f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 778f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7792475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 780f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 781f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 782f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 783f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 784f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 785f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 786f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 787f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 788f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7898dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback 7908dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() { 7918dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 7928dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall} 7938dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall 794a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 795a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 796a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 797a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 798a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 799a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 800a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 801a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 802a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 803a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 804a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 805a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 806a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 80794ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 80894ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 80994ee4b708acfa941581160b267afb79192b1d816Chong Zhang 81094ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mExecuting || maxGapUs <= 0ll) { 81194ee4b708acfa941581160b267afb79192b1d816Chong Zhang return INVALID_OPERATION; 81294ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 81394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 81494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = maxGapUs; 81594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 81694ee4b708acfa941581160b267afb79192b1d816Chong Zhang return OK; 81794ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 81872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 81972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 82072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mMutex); 82172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 82272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs = 82372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 82472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 82572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhangstatus_t GraphicBufferSource::setTimeLapseUs(int64_t* data) { 8272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang Mutex::Autolock autoLock(mMutex); 8282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) { 8302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return INVALID_OPERATION; 8312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 8322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs = data[0]; 8342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs = data[1]; 8352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return OK; 8372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang} 8382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 839a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 840a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 841a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 842a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 843a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 844a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 845a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 846a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 847a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 848a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 849a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 850a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 851a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 852a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 853a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 854a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 855a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 856a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 857a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber bool success = repeatLatestSubmittedBuffer_l(); 858a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 859a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 860a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("repeatLatestSubmittedBuffer_l SUCCESS"); 861a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 862a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGV("repeatLatestSubmittedBuffer_l FAILURE"); 863a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 864a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 865a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 866a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 867a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 868a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 869a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 870a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 871a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 872a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 873f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 874