GraphicBufferSource.cpp revision 15ab4996019387f27a48b81cb4774c21502bc0e5
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> 318ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza#include <gui/BufferItem.h> 32054219874873b41f1c815552987c10465c34ba2bLajos Molnar#include <HardwareAPI.h> 33f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 342475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza#include <inttypes.h> 3537b2b389139ed638831e49708c947863eef631efRonghua Wu#include "FrameDropper.h" 362475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza 37f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android { 38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 39f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true; 40f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 41f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 42d291c222357303b9611cab89d0c3b047584ef377Chong ZhangGraphicBufferSource::GraphicBufferSource( 43d291c222357303b9611cab89d0c3b047584ef377Chong Zhang OMXNodeInstance* nodeInstance, 44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferWidth, 45d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferHeight, 46d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferCount, 47d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<IGraphicBufferConsumer> &consumer) : 48f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck(UNKNOWN_ERROR), 49f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNodeInstance(nodeInstance), 50f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting(false), 51e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended(false), 52d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent(false), 53d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer(consumer), 54f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable(0), 55f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream(false), 56a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mEndOfStreamSent(false), 5794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs(-1ll), 5894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs(-1ll), 5994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs(-1ll), 6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs(-1ll), 6184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber mRepeatAfterUs(-1ll), 62a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatLastFrameGeneration(0), 6394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp(-1ll), 6437b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId(-1), 6537b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum(0), 6637b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount(0), 6715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence(Fence::NO_FENCE), 682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mRepeatBufferDeferred(false), 692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs(-1ll), 702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs(-1ll), 712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs(-1ll), 72054219874873b41f1c815552987c10465c34ba2bLajos Molnar mPrevFrameUs(-1ll) { 73f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 740c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 750c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 76f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 77f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 780c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 79f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 80f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 81f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 82f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 83d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer == NULL) { 84d291c222357303b9611cab89d0c3b047584ef377Chong Zhang String8 name("GraphicBufferSource"); 850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 86d291c222357303b9611cab89d0c3b047584ef377Chong Zhang BufferQueue::createBufferQueue(&mProducer, &mConsumer); 87d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setConsumerName(name); 88d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER); 89d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount); 90d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mInitCheck != NO_ERROR) { 91d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 92d291c222357303b9611cab89d0c3b047584ef377Chong Zhang bufferCount, mInitCheck); 93d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return; 94d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 95d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 96d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent = true; 970c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 98d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); 99f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 100f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 101f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 102f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 103910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 104910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); 105f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1065205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mInitCheck = mConsumer->consumerConnect(proxy, false); 1070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 108f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 1090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 110f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 111f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 112f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 117f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("~GraphicBufferSource"); 118d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer != NULL && !mIsPersistent) { 1195205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->consumerDisconnect(); 1200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 1210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 1220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 126f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 127f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 128a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> executing; avail=%zu, codec vec size=%zd", 129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 130f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 131f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 132f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 133f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 134f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 135f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 136f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 137f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 138f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 139f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 140f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 141f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 1420c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 1430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 1440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 1450c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 1460c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 1470c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 148f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 150a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable); 151f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 152f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 153f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 154f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 155f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 156f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 157a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 158a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mRepeatAfterUs > 0ll && mLooper == NULL) { 159a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector = new AHandlerReflector<GraphicBufferSource>(this); 160a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 161a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper = new ALooper; 162a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->registerHandler(mReflector); 163a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->start(); 164a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 16537b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 166a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = 1671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatRepeatLastFrame, mReflector); 168a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 169a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 170a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 171a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 172a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 173f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 174f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 175ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() { 176ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber ALOGV("omxIdle"); 177ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 178ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber Mutex::Autolock autoLock(mMutex); 179ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 180ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber if (mExecuting) { 181ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // We are only interested in the transition from executing->idle, 182ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // not loaded->idle. 183892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber mExecuting = false; 184ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber } 185ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber} 186ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 187ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 188f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 189ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 190ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 191ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 192ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 193f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 194a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLooper != NULL) { 195a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->unregisterHandler(mReflector->id()); 196a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector.clear(); 197a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 198a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->stop(); 199a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper.clear(); 200a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 201a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 202a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d", 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 207f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 208f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 209f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 210f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 211f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 212f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 213f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 214f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 215f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 222f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 223db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p", 224f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 228f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 23015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) { 231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 232892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber if (!mExecuting) { 233892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber return; 234892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber } 235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 239f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 24015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 24115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 24215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 243f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 244f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 245f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 246db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p", 247f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 248f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 254f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 255f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 2565572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden if (!(mEndOfStream && mEndOfStreamSent)) { 2575572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // This can happen when broken code sends us the same buffer 2585572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // twice in a row. 2595572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 2605572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden "(buffer emptied twice?)"); 2615572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden } 262f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 263f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 26415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 26515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 26615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 267f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 268f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 269f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 270054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) { 271f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 272f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 273f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 274512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar MetadataBufferType type = *(MetadataBufferType *)data; 275054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (type == kMetadataBufferTypeGrallocSource 276054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { 277054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data; 278054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (grallocMeta.hHandle != codecBuffer.mGraphicBuffer->handle) { 279512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 280512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 281054219874873b41f1c815552987c10465c34ba2bLajos Molnar grallocMeta.hHandle, codecBuffer.mGraphicBuffer->handle); 282512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 283512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 284054219874873b41f1c815552987c10465c34ba2bLajos Molnar } else if (type == kMetadataBufferTypeANWBuffer 285054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 286054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data; 287054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) { 288512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 289512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer is %p, expected %p", 290054219874873b41f1c815552987c10465c34ba2bLajos Molnar nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer()); 291512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 292512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 293f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 294f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 295f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 296f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 298f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 299d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar int id = codecBuffer.mBuf; 30015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar sp<Fence> fence = new Fence(fenceFd); 301d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 302d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 303d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 304d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 305d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 30637b2b389139ed638831e49708c947863eef631efRonghua Wu if (id == mLatestBufferId) { 30737b2b389139ed638831e49708c947863eef631efRonghua Wu CHECK_GT(mLatestBufferUseCount--, 0); 308a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 309d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mIsPersistent) { 310d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->detachBuffer(id); 311d291c222357303b9611cab89d0c3b047584ef377Chong Zhang int outSlot; 312d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->attachBuffer(&outSlot, mBufferSlot[id]); 313d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(outSlot, 0, 31415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 315d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 316d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(id, codecBuffer.mFrameNumber, 31715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 318d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 319a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 320d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 321f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 322f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 32315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // we will not reuse codec buffer, so there is no need to wait for fence 324f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 325f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 326f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 327f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 328f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 329f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 330f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 3310c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 332a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("buffer freed, %zu frames avail (eos=%d)", 3330c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 334f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 335f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 336f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 337f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 338f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 339f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 340a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 34137b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 342a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 34337b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l SUCCESS"); 344a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 34537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l FAILURE"); 346a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 347a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 349a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 35394ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 35494ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 35594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 35694ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mMaxTimestampGapUs > 0ll 35794ee4b708acfa941581160b267afb79192b1d816Chong Zhang && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 35894ee4b708acfa941581160b267afb79192b1d816Chong Zhang ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 35994ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (index >= 0) { 36094ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGV("OUT timestamp: %lld -> %lld", 361a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(header->nTimeStamp), 362a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mOriginalTimeUs[index])); 36394ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp = mOriginalTimeUs[index]; 36494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.removeItemsAt(index); 36594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } else { 36694ee4b708acfa941581160b267afb79192b1d816Chong Zhang // giving up the effort as encoder doesn't appear to preserve pts 36794ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGW("giving up limiting timestamp gap (pts = %lld)", 36894ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp); 36994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 37094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 37194ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 37294ee4b708acfa941581160b267afb79192b1d816Chong Zhang // something terribly wrong must have happened, giving up... 373a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("mOriginalTimeUs has too many entries (%zu)", 37494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.size()); 37594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 37694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 37794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 37894ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 37994ee4b708acfa941581160b267afb79192b1d816Chong Zhang 380e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 381e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 382e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 383e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 384e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 385e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 386e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 3878ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 3885205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 389e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 390e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 391e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 392e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 393e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 394e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 395e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 396e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 397e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 398e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 399e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 400e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 401d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mIsPersistent) { 402d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->detachBuffer(item.mBuf); 403d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer); 404d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(item.mBuf, 0, 40515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 406d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 407d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, 408d291c222357303b9611cab89d0c3b047584ef377Chong Zhang EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 409d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 410e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 411e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 412e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 413e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 414e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 415a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 416a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 41737b2b389139ed638831e49708c947863eef631efRonghua Wu if (repeatLatestBuffer_l()) { 41837b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS"); 419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 420a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 421a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 42237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE"); 423a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 424a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 425e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 426e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4270c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 428f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 4290c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 430e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 431e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 432e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 433e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 434f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 435f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 436f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 437a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 438f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 4390c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 4400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 441f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 442a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 4430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 4448ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 4455205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 4460c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 4470c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 4480c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 4490c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 4500c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 4510c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 4520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 4530c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 4540c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 455f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4560c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 457f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 4580c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 4590c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 4600c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 4610c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf); 4620c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferSlot[item.mBuf] = item.mGraphicBuffer; 4630c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 4640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 46572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = UNKNOWN_ERROR; 46672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // only submit sample if start time is unspecified, or sample 46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // is queued after the specified start time 46937b2b389139ed638831e49708c947863eef631efRonghua Wu bool dropped = false; 47072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 47172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if start time is set, offset time stamp by start time 47272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs > 0) { 47372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang item.mTimestamp -= mSkipFramesBeforeNs; 47472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 47537b2b389139ed638831e49708c947863eef631efRonghua Wu 47637b2b389139ed638831e49708c947863eef631efRonghua Wu int64_t timeUs = item.mTimestamp / 1000; 47737b2b389139ed638831e49708c947863eef631efRonghua Wu if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) { 47837b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs)); 47937b2b389139ed638831e49708c947863eef631efRonghua Wu // set err to OK so that the skipped frame can still be saved as the lastest frame 48037b2b389139ed638831e49708c947863eef631efRonghua Wu err = OK; 48137b2b389139ed638831e49708c947863eef631efRonghua Wu dropped = true; 48237b2b389139ed638831e49708c947863eef631efRonghua Wu } else { 48337b2b389139ed638831e49708c947863eef631efRonghua Wu err = submitBuffer_l(item, cbi); 48437b2b389139ed638831e49708c947863eef631efRonghua Wu } 48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 48672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4870c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 4880c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf); 489d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mIsPersistent) { 490d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->detachBuffer(item.mBuf); 491d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer); 492d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(item.mBuf, 0, 49315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 494d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 495d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, 49615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 497d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 49815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // item.mFence is released at the end of this method 4990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 5000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi); 50137b2b389139ed638831e49708c947863eef631efRonghua Wu setLatestBuffer_l(item, dropped); 502a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 503a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 504a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 505a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 506a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 50737b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() { 508a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 509a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 51037b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId < 0 || mSuspended) { 511a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 512a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 51337b2b389139ed638831e49708c947863eef631efRonghua Wu if (mBufferSlot[mLatestBufferId] == NULL) { 514bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 515bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 516bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 517bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 518bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 51937b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGD("repeatLatestBuffer_l: slot was NULL"); 5205205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 52137b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId, 52237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum, 523bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 524bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 52515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence); 52637b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = -1; 52737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = 0; 52815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = Fence::NO_FENCE; 529bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 530bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 531a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 532a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 533a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 534a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 53537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l: no codec buffers."); 536a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 537a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 538a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 5398ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 54037b2b389139ed638831e49708c947863eef631efRonghua Wu item.mBuf = mLatestBufferId; 54137b2b389139ed638831e49708c947863eef631efRonghua Wu item.mFrameNumber = mLatestBufferFrameNum; 54294ee4b708acfa941581160b267afb79192b1d816Chong Zhang item.mTimestamp = mRepeatLastFrameTimestamp; 54315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence = mLatestBufferFence; 544a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 545a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 546a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 547a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 548a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 549f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 550f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 55137b2b389139ed638831e49708c947863eef631efRonghua Wu ++mLatestBufferUseCount; 552a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 55394ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* repeat last frame up to kRepeatLastFrameCount times. 55494ee4b708acfa941581160b267afb79192b1d816Chong Zhang * in case of static scene, a single repeat might not get rid of encoder 55594ee4b708acfa941581160b267afb79192b1d816Chong Zhang * ghosting completely, refresh a couple more times to get better quality 55694ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 55794ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (--mRepeatLastFrameCount > 0) { 55894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 55994ee4b708acfa941581160b267afb79192b1d816Chong Zhang 56094ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mReflector != NULL) { 5611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 56294ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->setInt32("generation", ++mRepeatLastFrameGeneration); 56394ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->post(mRepeatAfterUs); 56494ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 56594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 56694ee4b708acfa941581160b267afb79192b1d816Chong Zhang 5670c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 568f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 569f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 57037b2b389139ed638831e49708c947863eef631efRonghua Wuvoid GraphicBufferSource::setLatestBuffer_l( 5718ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza const BufferItem &item, bool dropped) { 57237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("setLatestBuffer_l"); 573a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 57437b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 57537b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferUseCount == 0) { 576d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mIsPersistent) { 577d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->detachBuffer(mLatestBufferId); 578d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 579d291c222357303b9611cab89d0c3b047584ef377Chong Zhang int outSlot; 580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->attachBuffer(&outSlot, mBufferSlot[mLatestBufferId]); 581d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 582d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(outSlot, 0, 58315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, mLatestBufferFence); 584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 585d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer( 586d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mLatestBufferId, mLatestBufferFrameNum, 58715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, mLatestBufferFence); 588d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 58915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // mLatestBufferFence will be set to new fence just below 590a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 591a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 592a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 59337b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = item.mBuf; 59437b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = item.mFrameNumber; 59594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 59694ee4b708acfa941581160b267afb79192b1d816Chong Zhang 59737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount = dropped ? 0 : 1; 598a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 59994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameCount = kRepeatLastFrameCount; 60015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = item.mFence; 601a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 602a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 6031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 604a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 605a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 606a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 607a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 608a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 609ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 610f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 611a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 612ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 613ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 614ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 615ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 616ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 617ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 618f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 619f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 620f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 621f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 622f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 623f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 624f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 625f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 626f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 627f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 628f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 629f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 630f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 631f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 632ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 633ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 634f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 635f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6368ed8ceda7cfe29e8417142ef460cd70060204459Dan Stozaint64_t GraphicBufferSource::getTimestamp(const BufferItem &item) { 63794ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timeUs = item.mTimestamp / 1000; 63894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 6392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mTimePerCaptureUs > 0ll) { 6402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // Time lapse or slow motion mode 6412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mPrevCaptureUs < 0ll) { 6422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // first capture 6432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = timeUs; 6442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs = timeUs; 6452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else { 6462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // snap to nearest capture point 6472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 6482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang / mTimePerCaptureUs; 6492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (nFrames <= 0) { 6502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // skip this frame as it's too close to previous capture 651a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 6522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return -1; 6532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 6542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 6552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs += mTimePerFrameUs * nFrames; 6562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 6572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 6582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 659a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs), 660a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevCaptureUs), 661a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevFrameUs)); 6622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 6632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return mPrevFrameUs; 6642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else if (mMaxTimestampGapUs > 0ll) { 66594ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* Cap timestamp gap between adjacent frames to specified max 66694ee4b708acfa941581160b267afb79192b1d816Chong Zhang * 66794ee4b708acfa941581160b267afb79192b1d816Chong Zhang * In the scenario of cast mirroring, encoding could be suspended for 66894ee4b708acfa941581160b267afb79192b1d816Chong Zhang * prolonged periods. Limiting the pts gap to workaround the problem 66994ee4b708acfa941581160b267afb79192b1d816Chong Zhang * where encoder's rate control logic produces huge frames after a 67094ee4b708acfa941581160b267afb79192b1d816Chong Zhang * long period of suspension. 67194ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 67294ee4b708acfa941581160b267afb79192b1d816Chong Zhang 67394ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t originalTimeUs = timeUs; 67494ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mPrevOriginalTimeUs >= 0ll) { 67594ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (originalTimeUs < mPrevOriginalTimeUs) { 67694ee4b708acfa941581160b267afb79192b1d816Chong Zhang // Drop the frame if it's going backward in time. Bad timestamp 67794ee4b708acfa941581160b267afb79192b1d816Chong Zhang // could disrupt encoder's rate control completely. 678b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang ALOGW("Dropping frame that's going backward in time"); 67994ee4b708acfa941581160b267afb79192b1d816Chong Zhang return -1; 68094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 68194ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 68294ee4b708acfa941581160b267afb79192b1d816Chong Zhang timeUs = (timestampGapUs < mMaxTimestampGapUs ? 68394ee4b708acfa941581160b267afb79192b1d816Chong Zhang timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 68494ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 68594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs = originalTimeUs; 68694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs = timeUs; 68794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.add(timeUs, originalTimeUs); 688a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("IN timestamp: %lld -> %lld", 689a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(originalTimeUs), 690a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs)); 69194ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 69294ee4b708acfa941581160b267afb79192b1d816Chong Zhang 69394ee4b708acfa941581160b267afb79192b1d816Chong Zhang return timeUs; 69494ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 69594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 69615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) { 697f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 698b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 699b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang int64_t timeUs = getTimestamp(item); 700b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang if (timeUs < 0ll) { 701b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang return UNKNOWN_ERROR; 702b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang } 703b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 704f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 705d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf]; 706d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mBuf = item.mBuf; 707d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 708f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 709f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 710054219874873b41f1c815552987c10465c34ba2bLajos Molnar sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; 711054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 71215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs, 71315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence->isValid() ? item.mFence->dup() : -1); 714f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 715054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); 716f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 717f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 720054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", 721054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); 722f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 723f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 724f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 725f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 726f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 727f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 728f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 729f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 730f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 731f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 732f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 733f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 734f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 735f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 736f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 737f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 738f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 739f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 740f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 741f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 742f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 743f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 744054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 745054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 74615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 0 /* timestamp */, -1 /* fenceFd */); 747f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 748f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 749f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 750f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 751f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 7520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 753f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 754f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 755f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 756f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 757f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 760f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 761f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 762f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 763f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 764f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 765f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 766f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 771f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 772f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 773f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 774f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 775f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 776f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 777f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 77804f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { 779f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 780f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 781a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("onFrameAvailable exec=%d avail=%zu", 7820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 783f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 784e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 785e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 786e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 787e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 788e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 789e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 790e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 791e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 792e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 793f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7948ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 7955205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 796f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 79749270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // If this is the first time we're seeing this buffer, add it to our 79849270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // slot table. 79949270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang if (item.mGraphicBuffer != NULL) { 8002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf); 80149270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang mBufferSlot[item.mBuf] = item.mGraphicBuffer; 80249270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang } 803d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 804d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mIsPersistent) { 805d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->detachBuffer(item.mBuf); 806d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer); 807d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(item.mBuf, 0, 80815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 809d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 810d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, 811d291c222357303b9611cab89d0c3b047584ef377Chong Zhang EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence); 812d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 813f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 814f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 815f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 816f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 817f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 818f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 819a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 820a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 821a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 822f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 823f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 824f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 825f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 826f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 827f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 828f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 829f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 830f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 8312475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza uint64_t slotMask; 8325205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 833f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 8342475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza slotMask = 0xffffffffffffffffULL; 835f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 836f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 8372475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 838f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 839f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 840f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 841f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 842f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 843f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 844f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 845f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 846f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 8478dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback 8488dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() { 8498dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 8508dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall} 8518dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall 852a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 853a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 854a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 855a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 856a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 857a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 858a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 859a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 860a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 861a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 862a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 863a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 864a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 86594ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 86694ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 86794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 86894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mExecuting || maxGapUs <= 0ll) { 86994ee4b708acfa941581160b267afb79192b1d816Chong Zhang return INVALID_OPERATION; 87094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 87194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 87294ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = maxGapUs; 87394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 87494ee4b708acfa941581160b267afb79192b1d816Chong Zhang return OK; 87594ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 87672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 87737b2b389139ed638831e49708c947863eef631efRonghua Wustatus_t GraphicBufferSource::setMaxFps(float maxFps) { 87837b2b389139ed638831e49708c947863eef631efRonghua Wu Mutex::Autolock autoLock(mMutex); 87937b2b389139ed638831e49708c947863eef631efRonghua Wu 88037b2b389139ed638831e49708c947863eef631efRonghua Wu if (mExecuting) { 88137b2b389139ed638831e49708c947863eef631efRonghua Wu return INVALID_OPERATION; 88237b2b389139ed638831e49708c947863eef631efRonghua Wu } 88337b2b389139ed638831e49708c947863eef631efRonghua Wu 88437b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper = new FrameDropper(); 88537b2b389139ed638831e49708c947863eef631efRonghua Wu status_t err = mFrameDropper->setMaxFrameRate(maxFps); 88637b2b389139ed638831e49708c947863eef631efRonghua Wu if (err != OK) { 88737b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper.clear(); 88837b2b389139ed638831e49708c947863eef631efRonghua Wu return err; 88937b2b389139ed638831e49708c947863eef631efRonghua Wu } 89037b2b389139ed638831e49708c947863eef631efRonghua Wu 89137b2b389139ed638831e49708c947863eef631efRonghua Wu return OK; 89237b2b389139ed638831e49708c947863eef631efRonghua Wu} 89337b2b389139ed638831e49708c947863eef631efRonghua Wu 89472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 89572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mMutex); 89672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 89772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs = 89872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 89972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 90072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhangstatus_t GraphicBufferSource::setTimeLapseUs(int64_t* data) { 9022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang Mutex::Autolock autoLock(mMutex); 9032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 9042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) { 9052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return INVALID_OPERATION; 9062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 9072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 9082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs = data[0]; 9092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs = data[1]; 9102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 9112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return OK; 9122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang} 9132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 914a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 915a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 916a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 917a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 918a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 919a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 920a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 921a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 922a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 923a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 924a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 925a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 926a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 927a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 928a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 929a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 930a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 931a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 93237b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 933a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 934a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 93537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l SUCCESS"); 936a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 93737b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l FAILURE"); 938a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 939a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 940a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 941a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 942a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 943a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 944a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 945a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 946a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 947a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 948f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 949