GraphicBufferSource.cpp revision 9700f5fe4b3becfe858cbf5aa7964296975081bb
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 41ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong ZhangGraphicBufferSource::PersistentProxyListener::PersistentProxyListener( 42ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const wp<IGraphicBufferConsumer> &consumer, 43ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const wp<ConsumerListener>& consumerListener) : 44ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang mConsumerListener(consumerListener), 45ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang mConsumer(consumer) {} 46ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 47ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong ZhangGraphicBufferSource::PersistentProxyListener::~PersistentProxyListener() {} 48ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 49ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onFrameAvailable( 50ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const BufferItem& item) { 51ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 52ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 53ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onFrameAvailable(item); 54ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } else { 55ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<IGraphicBufferConsumer> consumer(mConsumer.promote()); 56ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (consumer == NULL) { 57ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 58ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 59ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang BufferItem bi; 60ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang status_t err = consumer->acquireBuffer(&bi, 0); 61ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 62ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: acquireBuffer failed (%d)", err); 63ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 64ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 65ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 66ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang err = consumer->detachBuffer(bi.mBuf); 67ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 68ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: detachBuffer failed (%d)", err); 69ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 70ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 71ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 72ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang err = consumer->attachBuffer(&bi.mBuf, bi.mGraphicBuffer); 73ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 74ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: attachBuffer failed (%d)", err); 75ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 76ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 77ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 78ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang err = consumer->releaseBuffer(bi.mBuf, 0, 79ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, bi.mFence); 80ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 81ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: releaseBuffer failed (%d)", err); 82ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 83ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 84ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 85ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 86ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onFrameReplaced( 87ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const BufferItem& item) { 88ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 89ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 90ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onFrameReplaced(item); 91ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 92ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 93ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 94ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onBuffersReleased() { 95ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 96ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 97ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onBuffersReleased(); 98ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 99ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 100ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 101ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onSidebandStreamChanged() { 102ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 103ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 104ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onSidebandStreamChanged(); 105ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 106ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 107f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 108d291c222357303b9611cab89d0c3b047584ef377Chong ZhangGraphicBufferSource::GraphicBufferSource( 109d291c222357303b9611cab89d0c3b047584ef377Chong Zhang OMXNodeInstance* nodeInstance, 110d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferWidth, 111d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferHeight, 112d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferCount, 113d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<IGraphicBufferConsumer> &consumer) : 114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck(UNKNOWN_ERROR), 115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNodeInstance(nodeInstance), 116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting(false), 117e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended(false), 118d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent(false), 119d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer(consumer), 120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable(0), 1219700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired(0), 122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream(false), 123a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mEndOfStreamSent(false), 12494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs(-1ll), 12594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs(-1ll), 12694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs(-1ll), 12772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs(-1ll), 12884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber mRepeatAfterUs(-1ll), 129a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatLastFrameGeneration(0), 13094ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp(-1ll), 13137b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId(-1), 13237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum(0), 13337b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount(0), 13415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence(Fence::NO_FENCE), 1352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mRepeatBufferDeferred(false), 1362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs(-1ll), 1372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs(-1ll), 1382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs(-1ll), 139054219874873b41f1c815552987c10465c34ba2bLajos Molnar mPrevFrameUs(-1ll) { 140f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1410c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 1420c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 143f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 144f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 1450c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 146f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 147f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 148f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 150d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer == NULL) { 151d291c222357303b9611cab89d0c3b047584ef377Chong Zhang String8 name("GraphicBufferSource"); 1520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 153d291c222357303b9611cab89d0c3b047584ef377Chong Zhang BufferQueue::createBufferQueue(&mProducer, &mConsumer); 154d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setConsumerName(name); 155d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER); 156d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount); 157d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mInitCheck != NO_ERROR) { 158d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 159d291c222357303b9611cab89d0c3b047584ef377Chong Zhang bufferCount, mInitCheck); 160d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return; 161d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 162d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 163d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent = true; 1640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 165d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); 166f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 167f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 168f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 169f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 170910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 171ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<IConsumerListener> proxy; 172ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (!mIsPersistent) { 173ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang proxy = new BufferQueue::ProxyConsumerListener(listener); 174ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } else { 175ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang proxy = new PersistentProxyListener(mConsumer, listener); 176ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 177f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1785205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mInitCheck = mConsumer->consumerConnect(proxy, false); 1790c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 180f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 1810c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 183f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 184f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 186f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 187f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 188f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 1899700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mLatestBufferId >= 0) { 1909700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer( 1919700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mLatestBufferId, mLatestBufferFrameNum, 1929700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 1939700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 1949700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mNumBufferAcquired != 0) { 1959700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired); 1969700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 197d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer != NULL && !mIsPersistent) { 1985205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->consumerDisconnect(); 1990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 2000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 2010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 207a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> executing; avail=%zu, codec vec size=%zd", 208f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 209f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 210f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 211f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 212f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 213f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 214f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 215f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 2210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 2220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 2230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 2240c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 2250c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 2260c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 228f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 229a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable); 230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 233f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 236a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 237a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mRepeatAfterUs > 0ll && mLooper == NULL) { 238a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector = new AHandlerReflector<GraphicBufferSource>(this); 239a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 240a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper = new ALooper; 241a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->registerHandler(mReflector); 242a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->start(); 243a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 24437b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 245a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = 2461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatRepeatLastFrame, mReflector); 247a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 248a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 249a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 250a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 251a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 254ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() { 255ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber ALOGV("omxIdle"); 256ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 257ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber Mutex::Autolock autoLock(mMutex); 258ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 259ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber if (mExecuting) { 260ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // We are only interested in the transition from executing->idle, 261ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // not loaded->idle. 262892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber mExecuting = false; 263ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber } 264ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber} 265ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 266ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 267f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 268ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 269ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 270ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 271ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 272f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 273a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLooper != NULL) { 274a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->unregisterHandler(mReflector->id()); 275a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector.clear(); 276a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 277a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->stop(); 278a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper.clear(); 279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 280a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 281a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d", 282f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 283f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 284f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 287f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 288f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 289f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 292f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 293f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 294f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 295f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 296f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 298f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 299f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 302db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p", 303f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 304f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 305f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 306f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 307f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 308f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 30915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) { 310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 311892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber if (!mExecuting) { 312892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber return; 313892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber } 314f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 315f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 316f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 317f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 318f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 31915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 32015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 32115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 322f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 323f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 324f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 325db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p", 326f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 327f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 328f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 329f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 330f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 331f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 332f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 333f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 334f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 3355572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden if (!(mEndOfStream && mEndOfStreamSent)) { 3365572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // This can happen when broken code sends us the same buffer 3375572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // twice in a row. 3385572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 3395572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden "(buffer emptied twice?)"); 3405572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden } 341f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 34315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 34415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 34515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 349054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) { 350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 353512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar MetadataBufferType type = *(MetadataBufferType *)data; 354054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (type == kMetadataBufferTypeGrallocSource 355054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { 356054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data; 3579847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar if (grallocMeta.pHandle != codecBuffer.mGraphicBuffer->handle) { 358512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 359512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 3609847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar grallocMeta.pHandle, codecBuffer.mGraphicBuffer->handle); 361512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 362512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 363054219874873b41f1c815552987c10465c34ba2bLajos Molnar } else if (type == kMetadataBufferTypeANWBuffer 364054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 365054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data; 366054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) { 367512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 368512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer is %p, expected %p", 369054219874873b41f1c815552987c10465c34ba2bLajos Molnar nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer()); 370512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 371512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 372f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 373f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 374f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 375f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 376f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 377f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 378d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar int id = codecBuffer.mBuf; 37915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar sp<Fence> fence = new Fence(fenceFd); 380d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 381d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 382d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 383d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 384d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 38537b2b389139ed638831e49708c947863eef631efRonghua Wu if (id == mLatestBufferId) { 38637b2b389139ed638831e49708c947863eef631efRonghua Wu CHECK_GT(mLatestBufferUseCount--, 0); 387a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 3889700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence); 389a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 390d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 392f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 39315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // we will not reuse codec buffer, so there is no need to wait for fence 394f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 395f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 397f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 398f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 399f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 400f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 4010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 402a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("buffer freed, %zu frames avail (eos=%d)", 4030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 404f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 405f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 406f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 407f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 408f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 409f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 410a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 41137b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 412a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 41337b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l SUCCESS"); 414a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 41537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l FAILURE"); 416a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 417a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 420f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 421f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 42394ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 42494ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 42594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 42694ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mMaxTimestampGapUs > 0ll 42794ee4b708acfa941581160b267afb79192b1d816Chong Zhang && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 42894ee4b708acfa941581160b267afb79192b1d816Chong Zhang ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 42994ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (index >= 0) { 43094ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGV("OUT timestamp: %lld -> %lld", 431a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(header->nTimeStamp), 432a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mOriginalTimeUs[index])); 43394ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp = mOriginalTimeUs[index]; 43494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.removeItemsAt(index); 43594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } else { 43694ee4b708acfa941581160b267afb79192b1d816Chong Zhang // giving up the effort as encoder doesn't appear to preserve pts 43794ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGW("giving up limiting timestamp gap (pts = %lld)", 43894ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp); 43994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 44094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 44194ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 44294ee4b708acfa941581160b267afb79192b1d816Chong Zhang // something terribly wrong must have happened, giving up... 443a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("mOriginalTimeUs has too many entries (%zu)", 44494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.size()); 44594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 44694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 44794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 44894ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 44994ee4b708acfa941581160b267afb79192b1d816Chong Zhang 450e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 451e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 452e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 453e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 454e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 455e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 456e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 4578ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 4585205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 459e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 460e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 461e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 462e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 463e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 464e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 465e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 466e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 467e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 468e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4699700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ++mNumBufferAcquired; 470e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 471e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4729700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(item.mBuf, item.mFrameNumber, 4739700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 474e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 475e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 476e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 477e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 478e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 48137b2b389139ed638831e49708c947863eef631efRonghua Wu if (repeatLatestBuffer_l()) { 48237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS"); 483a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 484a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 485a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 48637b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE"); 487a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 488a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 489e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 490e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4910c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 4930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 494e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 495e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 496e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 497e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 498f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 499f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 500f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 501a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 502f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 5030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 5040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 505f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 506a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 5070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 5088ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 5095205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 5100c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 5110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 5120c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 5130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 5140c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 5150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 5160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 5170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 5180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 519f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 5209700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 5210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 522f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 5230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 5240c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 5250c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 5260c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf); 5270c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mBufferSlot[item.mBuf] = item.mGraphicBuffer; 5280c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 5290c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 53072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = UNKNOWN_ERROR; 53172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 53272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // only submit sample if start time is unspecified, or sample 53372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // is queued after the specified start time 53437b2b389139ed638831e49708c947863eef631efRonghua Wu bool dropped = false; 53572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if start time is set, offset time stamp by start time 53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs > 0) { 53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang item.mTimestamp -= mSkipFramesBeforeNs; 53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 54037b2b389139ed638831e49708c947863eef631efRonghua Wu 54137b2b389139ed638831e49708c947863eef631efRonghua Wu int64_t timeUs = item.mTimestamp / 1000; 54237b2b389139ed638831e49708c947863eef631efRonghua Wu if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) { 54337b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs)); 54437b2b389139ed638831e49708c947863eef631efRonghua Wu // set err to OK so that the skipped frame can still be saved as the lastest frame 54537b2b389139ed638831e49708c947863eef631efRonghua Wu err = OK; 54637b2b389139ed638831e49708c947863eef631efRonghua Wu dropped = true; 54737b2b389139ed638831e49708c947863eef631efRonghua Wu } else { 54837b2b389139ed638831e49708c947863eef631efRonghua Wu err = submitBuffer_l(item, cbi); 54937b2b389139ed638831e49708c947863eef631efRonghua Wu } 55072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 55172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 5530c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf); 5549700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(item.mBuf, item.mFrameNumber, item.mGraphicBuffer, item.mFence); 5550c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 5560c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi); 55737b2b389139ed638831e49708c947863eef631efRonghua Wu setLatestBuffer_l(item, dropped); 558a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 559a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 560a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 561a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 562a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 56337b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() { 564a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 565a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 56637b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId < 0 || mSuspended) { 567a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 568a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 56937b2b389139ed638831e49708c947863eef631efRonghua Wu if (mBufferSlot[mLatestBufferId] == NULL) { 570bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 571bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 572bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 573bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 574bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 57537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGD("repeatLatestBuffer_l: slot was NULL"); 5765205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 57737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId, 57837b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum, 579bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 580bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 58115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence); 58237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = -1; 58337b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = 0; 58415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = Fence::NO_FENCE; 585bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 586bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 587a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 588a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 589a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 590a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 59137b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l: no codec buffers."); 592a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 593a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 594a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 5958ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 59637b2b389139ed638831e49708c947863eef631efRonghua Wu item.mBuf = mLatestBufferId; 59737b2b389139ed638831e49708c947863eef631efRonghua Wu item.mFrameNumber = mLatestBufferFrameNum; 59894ee4b708acfa941581160b267afb79192b1d816Chong Zhang item.mTimestamp = mRepeatLastFrameTimestamp; 59915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence = mLatestBufferFence; 600a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 601a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 602a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 603a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 604a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 605f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 606f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 60737b2b389139ed638831e49708c947863eef631efRonghua Wu ++mLatestBufferUseCount; 608a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 60994ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* repeat last frame up to kRepeatLastFrameCount times. 61094ee4b708acfa941581160b267afb79192b1d816Chong Zhang * in case of static scene, a single repeat might not get rid of encoder 61194ee4b708acfa941581160b267afb79192b1d816Chong Zhang * ghosting completely, refresh a couple more times to get better quality 61294ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 61394ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (--mRepeatLastFrameCount > 0) { 61494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 61594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 61694ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mReflector != NULL) { 6171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 61894ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->setInt32("generation", ++mRepeatLastFrameGeneration); 61994ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->post(mRepeatAfterUs); 62094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 62194ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 62294ee4b708acfa941581160b267afb79192b1d816Chong Zhang 6230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 624f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 625f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 62637b2b389139ed638831e49708c947863eef631efRonghua Wuvoid GraphicBufferSource::setLatestBuffer_l( 6278ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza const BufferItem &item, bool dropped) { 62837b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("setLatestBuffer_l"); 629a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 63037b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 63137b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferUseCount == 0) { 6329700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, 6339700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 63415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // mLatestBufferFence will be set to new fence just below 635a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 636a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 637a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 63837b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = item.mBuf; 63937b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = item.mFrameNumber; 64094ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 64194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 64237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount = dropped ? 0 : 1; 643a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 64494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameCount = kRepeatLastFrameCount; 64515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = item.mFence; 646a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 647a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 6481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 649a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 650a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 651a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 652a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 653a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 654ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 655f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 656a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 657ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 658ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 659ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 660ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 661ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 662ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 663f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 664f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 665f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 666f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 667f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 668f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 669f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 670f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 671f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 672f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 673f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 674f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 675f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 676f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 677ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 678ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 679f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 680f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6818ed8ceda7cfe29e8417142ef460cd70060204459Dan Stozaint64_t GraphicBufferSource::getTimestamp(const BufferItem &item) { 68294ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timeUs = item.mTimestamp / 1000; 68394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 6842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mTimePerCaptureUs > 0ll) { 6852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // Time lapse or slow motion mode 6862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mPrevCaptureUs < 0ll) { 6872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // first capture 6882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = timeUs; 6892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs = timeUs; 6902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else { 6912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // snap to nearest capture point 6922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 6932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang / mTimePerCaptureUs; 6942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (nFrames <= 0) { 6952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // skip this frame as it's too close to previous capture 696a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 6972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return -1; 6982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 6992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 7002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs += mTimePerFrameUs * nFrames; 7012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 7022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 7032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 704a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs), 705a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevCaptureUs), 706a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevFrameUs)); 7072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 7082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return mPrevFrameUs; 7092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else if (mMaxTimestampGapUs > 0ll) { 71094ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* Cap timestamp gap between adjacent frames to specified max 71194ee4b708acfa941581160b267afb79192b1d816Chong Zhang * 71294ee4b708acfa941581160b267afb79192b1d816Chong Zhang * In the scenario of cast mirroring, encoding could be suspended for 71394ee4b708acfa941581160b267afb79192b1d816Chong Zhang * prolonged periods. Limiting the pts gap to workaround the problem 71494ee4b708acfa941581160b267afb79192b1d816Chong Zhang * where encoder's rate control logic produces huge frames after a 71594ee4b708acfa941581160b267afb79192b1d816Chong Zhang * long period of suspension. 71694ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 71794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 71894ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t originalTimeUs = timeUs; 71994ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mPrevOriginalTimeUs >= 0ll) { 72094ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (originalTimeUs < mPrevOriginalTimeUs) { 72194ee4b708acfa941581160b267afb79192b1d816Chong Zhang // Drop the frame if it's going backward in time. Bad timestamp 72294ee4b708acfa941581160b267afb79192b1d816Chong Zhang // could disrupt encoder's rate control completely. 723b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang ALOGW("Dropping frame that's going backward in time"); 72494ee4b708acfa941581160b267afb79192b1d816Chong Zhang return -1; 72594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 72694ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 72794ee4b708acfa941581160b267afb79192b1d816Chong Zhang timeUs = (timestampGapUs < mMaxTimestampGapUs ? 72894ee4b708acfa941581160b267afb79192b1d816Chong Zhang timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 72994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 73094ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs = originalTimeUs; 73194ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs = timeUs; 73294ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.add(timeUs, originalTimeUs); 733a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("IN timestamp: %lld -> %lld", 734a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(originalTimeUs), 735a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs)); 73694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 73794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 73894ee4b708acfa941581160b267afb79192b1d816Chong Zhang return timeUs; 73994ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 74094ee4b708acfa941581160b267afb79192b1d816Chong Zhang 74115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) { 742f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 743b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 744b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang int64_t timeUs = getTimestamp(item); 745b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang if (timeUs < 0ll) { 746b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang return UNKNOWN_ERROR; 747b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang } 748b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 749f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 750d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf]; 751d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mBuf = item.mBuf; 752d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 753f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 754f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 755054219874873b41f1c815552987c10465c34ba2bLajos Molnar sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; 756054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 75715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs, 75815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence->isValid() ? item.mFence->dup() : -1); 759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 760054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); 761f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 762f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 763f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 764f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 765054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", 766054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); 767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 771f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 772f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 773f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 774f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 775f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 776f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 777f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 778f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 779f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 780f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 781f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 782f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 783f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 784f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 785f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 786f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 787f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 788f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 789054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 790054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 79115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 0 /* timestamp */, -1 /* fenceFd */); 792f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 793f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 794f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 795f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 796f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 7970c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 798f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 799f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 800f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 801f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 802f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 803f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 804f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 805f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 806f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 807f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 808f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 809f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 810f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 811f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 812f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 813f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 814f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 815f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 816f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 817f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 818f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 819f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 820f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 821f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 8229700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang/* 8239700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * Releases an acquired buffer back to the consumer for either persistent 8249700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * or non-persistent surfaces. 8259700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * 8269700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * id: buffer slot to release (in persistent case the id might be changed) 8279700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * frameNum: frame number of the frame being released 8289700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * buffer: GraphicBuffer pointer to release (note this must not be & as we 8299700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * will clear the original mBufferSlot in persistent case) 8309700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * fence: fence of the frame being released 8319700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang */ 8329700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhangvoid GraphicBufferSource::releaseBuffer( 8339700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang int &id, uint64_t frameNum, 8349700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang const sp<GraphicBuffer> buffer, const sp<Fence> &fence) { 8359700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mIsPersistent) { 8369700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->detachBuffer(id); 8379700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[id] = NULL; 8389700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 8399700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->attachBuffer(&id, buffer); 8409700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->releaseBuffer( 8419700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 8429700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } else { 8439700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->releaseBuffer( 8449700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 8459700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 8469700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired--; 8479700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang} 8489700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 849f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 85004f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { 851f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 852f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 853a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("onFrameAvailable exec=%d avail=%zu", 8540c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 855f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 856e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 857e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 858e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 859e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 860e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 861e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 862e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 863e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 864e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 865f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 8668ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 8675205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 868f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 8699700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 8709700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 87149270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // If this is the first time we're seeing this buffer, add it to our 87249270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // slot table. 87349270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang if (item.mGraphicBuffer != NULL) { 8742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf); 87549270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang mBufferSlot[item.mBuf] = item.mGraphicBuffer; 87649270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang } 877d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 8789700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(item.mBuf, item.mFrameNumber, 8799700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 880f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 881f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 882f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 883f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 884f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 885f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 886a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 887a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 888a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 889f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 890f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 891f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 892f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 893f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 894f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 895f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 897f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 8982475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza uint64_t slotMask; 8995205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 900f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 9012475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza slotMask = 0xffffffffffffffffULL; 902f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 903f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9042475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 905f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 906f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 907f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 908f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 909f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 910f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 911f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 912f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 913f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9148dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback 9158dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() { 9168dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 9178dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall} 9188dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall 919a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 920a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 921a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 922a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 923a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 924a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 925a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 926a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 927a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 928a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 929a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 930a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 931a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 93294ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 93394ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 93494ee4b708acfa941581160b267afb79192b1d816Chong Zhang 93594ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mExecuting || maxGapUs <= 0ll) { 93694ee4b708acfa941581160b267afb79192b1d816Chong Zhang return INVALID_OPERATION; 93794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 93894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 93994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = maxGapUs; 94094ee4b708acfa941581160b267afb79192b1d816Chong Zhang 94194ee4b708acfa941581160b267afb79192b1d816Chong Zhang return OK; 94294ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 94372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 94437b2b389139ed638831e49708c947863eef631efRonghua Wustatus_t GraphicBufferSource::setMaxFps(float maxFps) { 94537b2b389139ed638831e49708c947863eef631efRonghua Wu Mutex::Autolock autoLock(mMutex); 94637b2b389139ed638831e49708c947863eef631efRonghua Wu 94737b2b389139ed638831e49708c947863eef631efRonghua Wu if (mExecuting) { 94837b2b389139ed638831e49708c947863eef631efRonghua Wu return INVALID_OPERATION; 94937b2b389139ed638831e49708c947863eef631efRonghua Wu } 95037b2b389139ed638831e49708c947863eef631efRonghua Wu 95137b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper = new FrameDropper(); 95237b2b389139ed638831e49708c947863eef631efRonghua Wu status_t err = mFrameDropper->setMaxFrameRate(maxFps); 95337b2b389139ed638831e49708c947863eef631efRonghua Wu if (err != OK) { 95437b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper.clear(); 95537b2b389139ed638831e49708c947863eef631efRonghua Wu return err; 95637b2b389139ed638831e49708c947863eef631efRonghua Wu } 95737b2b389139ed638831e49708c947863eef631efRonghua Wu 95837b2b389139ed638831e49708c947863eef631efRonghua Wu return OK; 95937b2b389139ed638831e49708c947863eef631efRonghua Wu} 96037b2b389139ed638831e49708c947863eef631efRonghua Wu 96172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 96272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mMutex); 96372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 96472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs = 96572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 96672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 96772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhangstatus_t GraphicBufferSource::setTimeLapseUs(int64_t* data) { 9692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang Mutex::Autolock autoLock(mMutex); 9702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 9712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) { 9722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return INVALID_OPERATION; 9732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 9742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 9752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs = data[0]; 9762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs = data[1]; 9772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 9782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return OK; 9792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang} 9802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 981a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 982a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 983a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 984a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 985a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 986a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 987a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 988a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 989a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 990a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 991a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 992a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 993a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 994a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 995a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 996a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 997a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 998a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 99937b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 1000a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1001a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 100237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l SUCCESS"); 1003a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 100437b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l FAILURE"); 1005a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 1006a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1007a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1008a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1009a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1010a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 1011a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 1012a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1013a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1014a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1015f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 1016