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 23b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar#define STRINGIFY_ENUMS // for asString in HardwareAPI.h/VideoAPI.h 24b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 255e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include "GraphicBufferSource.h" 26b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar#include "OMXUtils.h" 27f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <OMX_Core.h> 29c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar#include <OMX_IndexExt.h> 30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h> 31a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber#include <media/stagefright/foundation/AMessage.h> 32b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar#include <media/stagefright/foundation/ColorUtils.h> 33f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 345e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h> 35f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h> 368ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza#include <gui/BufferItem.h> 37054219874873b41f1c815552987c10465c34ba2bLajos Molnar#include <HardwareAPI.h> 38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 392475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza#include <inttypes.h> 4037b2b389139ed638831e49708c947863eef631efRonghua Wu#include "FrameDropper.h" 412475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza 42f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android { 43f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 44f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true; 45f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 46b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatic const OMX_U32 kPortIndexInput = 0; 47b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 48ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong ZhangGraphicBufferSource::PersistentProxyListener::PersistentProxyListener( 49ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const wp<IGraphicBufferConsumer> &consumer, 50ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const wp<ConsumerListener>& consumerListener) : 51ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang mConsumerListener(consumerListener), 52ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang mConsumer(consumer) {} 53ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 54ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong ZhangGraphicBufferSource::PersistentProxyListener::~PersistentProxyListener() {} 55ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 56ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onFrameAvailable( 57ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const BufferItem& item) { 58ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 59ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 60ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onFrameAvailable(item); 61ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } else { 62ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<IGraphicBufferConsumer> consumer(mConsumer.promote()); 63ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (consumer == NULL) { 64ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 65ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 66ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang BufferItem bi; 67ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang status_t err = consumer->acquireBuffer(&bi, 0); 68ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 69ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: acquireBuffer failed (%d)", err); 70ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 71ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 72ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 73a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos err = consumer->detachBuffer(bi.mSlot); 74ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 75ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: detachBuffer failed (%d)", err); 76ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 77ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 78ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 79a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos err = consumer->attachBuffer(&bi.mSlot, bi.mGraphicBuffer); 80ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 81ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: attachBuffer failed (%d)", err); 82ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang return; 83ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 84ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 85a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos err = consumer->releaseBuffer(bi.mSlot, 0, 86ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, bi.mFence); 87ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (err != OK) { 88ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang ALOGE("PersistentProxyListener: releaseBuffer failed (%d)", err); 89ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 90ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 91ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 92ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 93ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onFrameReplaced( 94ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang const BufferItem& item) { 95ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 96ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 97ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onFrameReplaced(item); 98ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 99ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 100ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 101ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onBuffersReleased() { 102ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 103ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 104ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onBuffersReleased(); 105ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 106ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 107ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang 108ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhangvoid GraphicBufferSource::PersistentProxyListener::onSidebandStreamChanged() { 109ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<ConsumerListener> listener(mConsumerListener.promote()); 110ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (listener != NULL) { 111ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang listener->onSidebandStreamChanged(); 112ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 113ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang} 114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 115d291c222357303b9611cab89d0c3b047584ef377Chong ZhangGraphicBufferSource::GraphicBufferSource( 116d291c222357303b9611cab89d0c3b047584ef377Chong Zhang OMXNodeInstance* nodeInstance, 117d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferWidth, 118d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferHeight, 119d291c222357303b9611cab89d0c3b047584ef377Chong Zhang uint32_t bufferCount, 12049605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar uint32_t consumerUsage, 121d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<IGraphicBufferConsumer> &consumer) : 122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck(UNKNOWN_ERROR), 123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNodeInstance(nodeInstance), 124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting(false), 125e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended(false), 12657fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mLastDataSpace(HAL_DATASPACE_UNKNOWN), 127d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent(false), 128d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer(consumer), 129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable(0), 1309700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired(0), 131f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream(false), 132a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mEndOfStreamSent(false), 13394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs(-1ll), 13494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs(-1ll), 13594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs(-1ll), 13672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs(-1ll), 13784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber mRepeatAfterUs(-1ll), 138a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatLastFrameGeneration(0), 13994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp(-1ll), 14037b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId(-1), 14137b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum(0), 14215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence(Fence::NO_FENCE), 1432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mRepeatBufferDeferred(false), 1442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs(-1ll), 1452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs(-1ll), 1462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs(-1ll), 14761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mPrevFrameUs(-1ll), 14861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mInputBufferTimeOffsetUs(0ll) { 149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1500c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 1510c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 152f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 153f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 1540c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 155f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 156f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 157f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 158f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 159d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer == NULL) { 160d291c222357303b9611cab89d0c3b047584ef377Chong Zhang String8 name("GraphicBufferSource"); 1610c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 162d291c222357303b9611cab89d0c3b047584ef377Chong Zhang BufferQueue::createBufferQueue(&mProducer, &mConsumer); 163d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setConsumerName(name); 164c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 16549605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar // use consumer usage bits queried from encoder, but always add HW_VIDEO_ENCODER 166c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar // for backward compatibility. 16749605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER; 16849605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar mConsumer->setConsumerUsageBits(consumerUsage); 169c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 170d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount); 171d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mInitCheck != NO_ERROR) { 172d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 173d291c222357303b9611cab89d0c3b047584ef377Chong Zhang bufferCount, mInitCheck); 174d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return; 175d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 176d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 177d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent = true; 1780c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 179d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); 180f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 181f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 183f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 184910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 185ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<IConsumerListener> proxy; 186ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (!mIsPersistent) { 187ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang proxy = new BufferQueue::ProxyConsumerListener(listener); 188ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } else { 189ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang proxy = new PersistentProxyListener(mConsumer, listener); 190ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 191f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1925205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mInitCheck = mConsumer->consumerConnect(proxy, false); 1930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 194f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 1950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 196f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 199dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar memset(&mColorAspects, 0, sizeof(mColorAspects)); 200dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar 2010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 2059700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mLatestBufferId >= 0) { 2069700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer( 2079700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mLatestBufferId, mLatestBufferFrameNum, 2089700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 2099700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 2109700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mNumBufferAcquired != 0) { 2119700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired); 2129700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 213d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer != NULL && !mIsPersistent) { 2145205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->consumerDisconnect(); 2150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 2160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 2170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 222f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 223a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> executing; avail=%zu, codec vec size=%zd", 224f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 227b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mLastDataSpace = HAL_DATASPACE_UNKNOWN; 228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("clearing last dataSpace"); 229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 233f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 2390c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 2400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 2410c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 2420c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 2430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 2440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 245f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 246f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 247a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable); 248f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 254a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 255a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mRepeatAfterUs > 0ll && mLooper == NULL) { 256a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector = new AHandlerReflector<GraphicBufferSource>(this); 257a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 258a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper = new ALooper; 259a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->registerHandler(mReflector); 260a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->start(); 261a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 26237b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 263a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = 2641d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatRepeatLastFrame, mReflector); 265a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 266a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 267a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 268a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 269a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 270f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 271f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 272ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() { 273ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber ALOGV("omxIdle"); 274ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 275ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber Mutex::Autolock autoLock(mMutex); 276ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 277ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber if (mExecuting) { 278ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // We are only interested in the transition from executing->idle, 279ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // not loaded->idle. 280892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber mExecuting = false; 281ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber } 282ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber} 283ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 284ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 286ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 287ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 288ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 289ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 291a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLooper != NULL) { 292a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->unregisterHandler(mReflector->id()); 293a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector.clear(); 294a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 295a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->stop(); 296a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper.clear(); 297a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 298a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 299a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d", 300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 302f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 303f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 304f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 305f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 306f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 307f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 308f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 309f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 311f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 312f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 313f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 314f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 315f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 316f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 317f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 318f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 319f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 320db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p", 321f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 322f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 323f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 324f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 325f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 326f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 32715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) { 328f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 329892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber if (!mExecuting) { 330892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber return; 331892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber } 332f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 333f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 334f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 335f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 336f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 33715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 33815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 33915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 340f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 341f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 343db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p", 344f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 345f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 349f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 3535572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden if (!(mEndOfStream && mEndOfStreamSent)) { 3545572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // This can happen when broken code sends us the same buffer 3555572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // twice in a row. 3565572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 3575572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden "(buffer emptied twice?)"); 3585572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden } 359f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 360f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 36115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 36215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 36315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 364f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 365f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 366f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 367054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) { 368f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 369f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 370f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 371512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar MetadataBufferType type = *(MetadataBufferType *)data; 372054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (type == kMetadataBufferTypeGrallocSource 373054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { 374054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data; 3759847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar if (grallocMeta.pHandle != codecBuffer.mGraphicBuffer->handle) { 376512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 377512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 3789847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar grallocMeta.pHandle, codecBuffer.mGraphicBuffer->handle); 379512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 380512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 381054219874873b41f1c815552987c10465c34ba2bLajos Molnar } else if (type == kMetadataBufferTypeANWBuffer 382054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 383054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data; 384054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) { 385512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 386512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer is %p, expected %p", 387054219874873b41f1c815552987c10465c34ba2bLajos Molnar nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer()); 388512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 389512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 390f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 392f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 394f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 395f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 396a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos int id = codecBuffer.mSlot; 39715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar sp<Fence> fence = new Fence(fenceFd); 398d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 399d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 400fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang mBufferUseCount[id]--; 401d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 402fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ALOGV("codecBufferEmptied: slot=%d, cbi=%d, useCount=%d, handle=%p", 403fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang id, cbi, mBufferUseCount[id], mBufferSlot[id]->handle); 404fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang 405fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang if (mBufferUseCount[id] < 0) { 406fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ALOGW("mBufferUseCount for bq slot %d < 0 (=%d)", id, mBufferUseCount[id]); 407fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang mBufferUseCount[id] = 0; 408fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang } 409fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang if (id != mLatestBufferId && mBufferUseCount[id] == 0) { 4109700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence); 411a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 412d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 413f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 414f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 41515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // we will not reuse codec buffer, so there is no need to wait for fence 416f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 417f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 420f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 421f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 4230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 424a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("buffer freed, %zu frames avail (eos=%d)", 4250c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 427f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 428f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 429f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 430f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 431f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 432a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 43337b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 434a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 43537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l SUCCESS"); 436a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 43737b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l FAILURE"); 438a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 439a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 441a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 442f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 443f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 444f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 44594ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 44694ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 44794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 44894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mMaxTimestampGapUs > 0ll 44994ee4b708acfa941581160b267afb79192b1d816Chong Zhang && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 45094ee4b708acfa941581160b267afb79192b1d816Chong Zhang ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 45194ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (index >= 0) { 45294ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGV("OUT timestamp: %lld -> %lld", 453a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(header->nTimeStamp), 454a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mOriginalTimeUs[index])); 45594ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp = mOriginalTimeUs[index]; 45694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.removeItemsAt(index); 45794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } else { 45894ee4b708acfa941581160b267afb79192b1d816Chong Zhang // giving up the effort as encoder doesn't appear to preserve pts 45994ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGW("giving up limiting timestamp gap (pts = %lld)", 46094ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp); 46194ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 46294ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46394ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 46494ee4b708acfa941581160b267afb79192b1d816Chong Zhang // something terribly wrong must have happened, giving up... 465a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("mOriginalTimeUs has too many entries (%zu)", 46694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.size()); 46794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 46894ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 47094ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 47194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 472e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 473e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 474e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 475e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 476e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 477e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 478e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 4798ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 4805205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 481e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 482e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 483e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 484e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 485e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 486e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 487e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 488e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 489e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 490e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4919700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ++mNumBufferAcquired; 492e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 493e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 494a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, 4959700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 496e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 497e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 498e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 499e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 500e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 501a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 502a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 50337b2b389139ed638831e49708c947863eef631efRonghua Wu if (repeatLatestBuffer_l()) { 50437b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS"); 505a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 506a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 507a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 50837b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE"); 509a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 510a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 511e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 512e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid GraphicBufferSource::onDataSpaceChanged_l( 514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace dataSpace, android_pixel_format pixelFormat) { 515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("got buffer with new dataSpace #%x", dataSpace); 516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mLastDataSpace = dataSpace; 517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (ColorUtils::convertDataSpaceToV0(dataSpace)) { 519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ColorAspects aspects = mColorAspects; // initially requested aspects 520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // request color aspects to encode 522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_INDEXTYPE index; 523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = mNodeInstance->getExtensionIndex( 524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "OMX.google.android.index.describeColorAspects", &index); 525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // V0 dataspace 527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams params; 528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(¶ms); 529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexInput; 530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nDataSpace = mLastDataSpace; 531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPixelFormat = pixelFormat; 532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bDataSpaceChanged = OMX_TRUE; 533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects = mColorAspects; 534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = mNodeInstance->getConfig(index, ¶ms, sizeof(params)); 536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects = params.sAspects; 538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("Codec resolved it to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mRange, asString(params.sAspects.mRange), 540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects = aspects; 546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = OK; 547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bDataSpaceChanged = OMX_FALSE; 549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar for (int triesLeft = 2; --triesLeft >= 0; ) { 550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = mNodeInstance->setConfig(index, ¶ms, sizeof(params)); 551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = mNodeInstance->getConfig(index, ¶ms, sizeof(params)); 553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem( 555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects, aspects)) { 556b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // if we can't set or get color aspects, still communicate dataspace to client 557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar break; 558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(triesLeft == 0, "Codec repeatedly changed requested ColorAspects."); 561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 564b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("Set color aspects to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer), 569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // signal client that the dataspace has changed; this will update the output format 572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // TODO: we should tie this to an output buffer somehow, and signal the change 573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // just before the output buffer is returned to the client, but there are many 574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // ways this could fail (e.g. flushing), and we are not yet supporting this scenario. 575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mNodeInstance->signalEvent( 577b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_EventDataSpaceChanged, dataSpace, 578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (aspects.mRange << 24) | (aspects.mPrimaries << 16) 579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar | (aspects.mMatrixCoeffs << 8) | aspects.mTransfer); 580b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 581b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 582b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5830c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 584f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 5850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 586e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 587e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 588e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 589e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 590f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 591f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 592f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 593a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 594f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 5950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 5960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 597f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 598a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 5990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 6008ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 6015205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 6020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 6030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 6040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 6050c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 6060c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 6070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 6080c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 6090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 6100c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 611f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6129700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 6130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 614f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 6160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 6170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 618a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mSlot); 619a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mBufferSlot[item.mSlot] = item.mGraphicBuffer; 620fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang mBufferUseCount[item.mSlot] = 0; 6210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 6220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (item.mDataSpace != mLastDataSpace) { 624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar onDataSpaceChanged_l( 625b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar item.mDataSpace, (android_pixel_format)mBufferSlot[item.mSlot]->getPixelFormat()); 626b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = UNKNOWN_ERROR; 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // only submit sample if start time is unspecified, or sample 63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // is queued after the specified start time 63337b2b389139ed638831e49708c947863eef631efRonghua Wu bool dropped = false; 63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if start time is set, offset time stamp by start time 63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs > 0) { 63772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang item.mTimestamp -= mSkipFramesBeforeNs; 63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63937b2b389139ed638831e49708c947863eef631efRonghua Wu 64037b2b389139ed638831e49708c947863eef631efRonghua Wu int64_t timeUs = item.mTimestamp / 1000; 64137b2b389139ed638831e49708c947863eef631efRonghua Wu if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) { 64237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs)); 64337b2b389139ed638831e49708c947863eef631efRonghua Wu // set err to OK so that the skipped frame can still be saved as the lastest frame 64437b2b389139ed638831e49708c947863eef631efRonghua Wu err = OK; 64537b2b389139ed638831e49708c947863eef631efRonghua Wu dropped = true; 64637b2b389139ed638831e49708c947863eef631efRonghua Wu } else { 64737b2b389139ed638831e49708c947863eef631efRonghua Wu err = submitBuffer_l(item, cbi); 64837b2b389139ed638831e49708c947863eef631efRonghua Wu } 64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6510c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 652a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("submitBuffer_l failed, releasing bq slot %d", item.mSlot); 653a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, item.mGraphicBuffer, item.mFence); 6540c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 655a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("buffer submitted (bq %d, cbi %d)", item.mSlot, cbi); 65637b2b389139ed638831e49708c947863eef631efRonghua Wu setLatestBuffer_l(item, dropped); 657a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 658a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 659a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 660a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 661a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 66237b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() { 663a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 664a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 66537b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId < 0 || mSuspended) { 666a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 667a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 66837b2b389139ed638831e49708c947863eef631efRonghua Wu if (mBufferSlot[mLatestBufferId] == NULL) { 669bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 670bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 671bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 672bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 673bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 67437b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGD("repeatLatestBuffer_l: slot was NULL"); 6755205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 67637b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId, 67737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum, 678bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 679bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 68015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence); 68137b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = -1; 68237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = 0; 68315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = Fence::NO_FENCE; 684bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 685bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 686a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 687a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 688a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 689a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 69037b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l: no codec buffers."); 691a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 692a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 693a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 6948ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 695a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos item.mSlot = mLatestBufferId; 69637b2b389139ed638831e49708c947863eef631efRonghua Wu item.mFrameNumber = mLatestBufferFrameNum; 69794ee4b708acfa941581160b267afb79192b1d816Chong Zhang item.mTimestamp = mRepeatLastFrameTimestamp; 69815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence = mLatestBufferFence; 699a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 700a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 701a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 702a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 703a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 704f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 705f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 706fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ++mBufferUseCount[item.mSlot]; 707a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 70894ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* repeat last frame up to kRepeatLastFrameCount times. 70994ee4b708acfa941581160b267afb79192b1d816Chong Zhang * in case of static scene, a single repeat might not get rid of encoder 71094ee4b708acfa941581160b267afb79192b1d816Chong Zhang * ghosting completely, refresh a couple more times to get better quality 71194ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 71294ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (--mRepeatLastFrameCount > 0) { 71394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 71494ee4b708acfa941581160b267afb79192b1d816Chong Zhang 71594ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mReflector != NULL) { 7161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 71794ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->setInt32("generation", ++mRepeatLastFrameGeneration); 71894ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->post(mRepeatAfterUs); 71994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 72094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 72194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 7220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 723f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 724f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 72537b2b389139ed638831e49708c947863eef631efRonghua Wuvoid GraphicBufferSource::setLatestBuffer_l( 7268ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza const BufferItem &item, bool dropped) { 72737b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 728fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang if (mBufferUseCount[mLatestBufferId] == 0) { 7299700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, 7309700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 73115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // mLatestBufferFence will be set to new fence just below 732a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 733a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 734a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 735a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mLatestBufferId = item.mSlot; 73637b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = item.mFrameNumber; 73794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 73894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 739fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang if (!dropped) { 740fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ++mBufferUseCount[item.mSlot]; 741fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang } 742fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang 743fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ALOGV("setLatestBuffer_l: slot=%d, useCount=%d", 744fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang item.mSlot, mBufferUseCount[item.mSlot]); 745fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang 746a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 74794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameCount = kRepeatLastFrameCount; 74815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = item.mFence; 749a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 750a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 7511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 752a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 753a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 754a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 755a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 756a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 757ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 759a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 760ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 761ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 762ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 763ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 764ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 765ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 766f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 771f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 772f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 773f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 774f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 775f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 776f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 777f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 778f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 779f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 780ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 781ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 782f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 783f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7848ed8ceda7cfe29e8417142ef460cd70060204459Dan Stozaint64_t GraphicBufferSource::getTimestamp(const BufferItem &item) { 78594ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timeUs = item.mTimestamp / 1000; 78661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang timeUs += mInputBufferTimeOffsetUs; 78794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 7885a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang if (mTimePerCaptureUs > 0ll 7895a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang && (mTimePerCaptureUs > 2 * mTimePerFrameUs 7905a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang || mTimePerFrameUs > 2 * mTimePerCaptureUs)) { 7912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // Time lapse or slow motion mode 7922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mPrevCaptureUs < 0ll) { 7932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // first capture 7942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = timeUs; 7952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs = timeUs; 7962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else { 7972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // snap to nearest capture point 7982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 7992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang / mTimePerCaptureUs; 8002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (nFrames <= 0) { 8012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // skip this frame as it's too close to previous capture 802a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 8032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return -1; 8042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 8052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 8062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs += mTimePerFrameUs * nFrames; 8072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 8082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 810a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs), 811a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevCaptureUs), 812a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevFrameUs)); 8132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return mPrevFrameUs; 81561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } else { 81694ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t originalTimeUs = timeUs; 81761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (originalTimeUs <= mPrevOriginalTimeUs) { 81894ee4b708acfa941581160b267afb79192b1d816Chong Zhang // Drop the frame if it's going backward in time. Bad timestamp 81994ee4b708acfa941581160b267afb79192b1d816Chong Zhang // could disrupt encoder's rate control completely. 82061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang ALOGW("Dropping frame that's going backward in time"); 82161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return -1; 82261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 82361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 82461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (mMaxTimestampGapUs > 0ll) { 82561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang //TODO: Fix the case when mMaxTimestampGapUs and mTimePerCaptureUs are both set. 82661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 82761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang /* Cap timestamp gap between adjacent frames to specified max 82861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * 82961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * In the scenario of cast mirroring, encoding could be suspended for 83061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * prolonged periods. Limiting the pts gap to workaround the problem 83161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * where encoder's rate control logic produces huge frames after a 83261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * long period of suspension. 83361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang */ 83461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (mPrevOriginalTimeUs >= 0ll) { 83561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 83661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang timeUs = (timestampGapUs < mMaxTimestampGapUs ? 83794ee4b708acfa941581160b267afb79192b1d816Chong Zhang timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 83861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 839718ae52c24b243d19d91dd97c2f6ea37d3524df0Chong Zhang mOriginalTimeUs.add(timeUs, originalTimeUs); 840718ae52c24b243d19d91dd97c2f6ea37d3524df0Chong Zhang ALOGV("IN timestamp: %lld -> %lld", 841718ae52c24b243d19d91dd97c2f6ea37d3524df0Chong Zhang static_cast<long long>(originalTimeUs), 842718ae52c24b243d19d91dd97c2f6ea37d3524df0Chong Zhang static_cast<long long>(timeUs)); 84394ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 84461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 84594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs = originalTimeUs; 84694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs = timeUs; 84794ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 84894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 84994ee4b708acfa941581160b267afb79192b1d816Chong Zhang return timeUs; 85094ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 85194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 85215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) { 853fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ALOGV("submitBuffer_l: slot=%d, cbi=%d", item.mSlot, cbi); 854b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 855b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang int64_t timeUs = getTimestamp(item); 856b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang if (timeUs < 0ll) { 857b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang return UNKNOWN_ERROR; 858b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang } 859b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 860f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 861a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos codecBuffer.mGraphicBuffer = mBufferSlot[item.mSlot]; 862a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos codecBuffer.mSlot = item.mSlot; 863d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 864f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 865f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 866054219874873b41f1c815552987c10465c34ba2bLajos Molnar sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; 867054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 86815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs, 86915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence->isValid() ? item.mFence->dup() : -1); 870f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 871054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); 872f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 873f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 874f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 875f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 876054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", 877054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); 878f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 879f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 880f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 881f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 882f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 883f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 884f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 885f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 886f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 887f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 888f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 889f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 890f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 891f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 892f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 893f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 894f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 895f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 897f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 899f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 900054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 901054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 90215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 0 /* timestamp */, -1 /* fenceFd */); 903f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 904f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 905f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 906f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 907f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 9080c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 909f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 910f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 911f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 912f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 913f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 914f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 915f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 916f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 917f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 918f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 919f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 920f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 921f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 922f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 923f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 924f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 925f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 926f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 927f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 928f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 929f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 930f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 931f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 932f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9339700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang/* 9349700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * Releases an acquired buffer back to the consumer for either persistent 9359700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * or non-persistent surfaces. 9369700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * 9379700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * id: buffer slot to release (in persistent case the id might be changed) 9389700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * frameNum: frame number of the frame being released 9399700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * buffer: GraphicBuffer pointer to release (note this must not be & as we 9409700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * will clear the original mBufferSlot in persistent case) 9419700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * fence: fence of the frame being released 9429700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang */ 9439700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhangvoid GraphicBufferSource::releaseBuffer( 9449700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang int &id, uint64_t frameNum, 9459700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang const sp<GraphicBuffer> buffer, const sp<Fence> &fence) { 946fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang ALOGV("releaseBuffer: slot=%d", id); 9479700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mIsPersistent) { 9489700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->detachBuffer(id); 9499700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[id] = NULL; 9509700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 951264bac95912efe121d6a60026612617f04f42966Lajos Molnar if (mConsumer->attachBuffer(&id, buffer) == OK) { 952264bac95912efe121d6a60026612617f04f42966Lajos Molnar mConsumer->releaseBuffer( 953264bac95912efe121d6a60026612617f04f42966Lajos Molnar id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 954264bac95912efe121d6a60026612617f04f42966Lajos Molnar } 9559700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } else { 9569700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->releaseBuffer( 9579700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 9589700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 959264bac95912efe121d6a60026612617f04f42966Lajos Molnar id = -1; // invalidate id 9609700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired--; 9619700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang} 9629700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 963f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 96404f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { 965f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 966f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 967a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("onFrameAvailable exec=%d avail=%zu", 9680c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 969f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 970e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 971e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 972e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 973e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 974e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 975e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 976e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 977e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 978e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 979f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9808ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 9815205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 982f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 9839700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 9849700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 98549270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // If this is the first time we're seeing this buffer, add it to our 98649270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // slot table. 98749270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang if (item.mGraphicBuffer != NULL) { 988a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mSlot); 989a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mBufferSlot[item.mSlot] = item.mGraphicBuffer; 990fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang mBufferUseCount[item.mSlot] = 0; 99149270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang } 992d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 993a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, 9949700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 995f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 996f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 997f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 998f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 999f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 1000f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1001a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 1002a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 1003a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1004f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 1005f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 1006f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1007f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 1008f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1009f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 1010f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 1011f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 1012f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10132475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza uint64_t slotMask; 10145205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 1015f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 10162475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza slotMask = 0xffffffffffffffffULL; 1017f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1018f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10192475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 1020f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1021f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 1022f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 1023f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 1024fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang mBufferUseCount[i] = 0; 1025f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1026f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 1027f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1028f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 1029f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10308dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback 10318dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() { 10328dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 10338dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall} 10348dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall 103557fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnarvoid GraphicBufferSource::setDefaultDataSpace(android_dataspace dataSpace) { 1036b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // no need for mutex as we are not yet running 103757fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar ALOGD("setting dataspace: %#x", dataSpace); 103857fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mConsumer->setDefaultBufferDataSpace(dataSpace); 103957fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mLastDataSpace = dataSpace; 104057fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar} 104157fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar 1042a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 1043a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 1044a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 1045a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1046a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 1047a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 1048a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1049a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1050a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 1051a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1052a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 1053a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1054a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 105594ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 105694ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 105794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 105894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mExecuting || maxGapUs <= 0ll) { 105994ee4b708acfa941581160b267afb79192b1d816Chong Zhang return INVALID_OPERATION; 106094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 106194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 106294ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = maxGapUs; 106394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 106494ee4b708acfa941581160b267afb79192b1d816Chong Zhang return OK; 106594ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 106672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 106761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuangstatus_t GraphicBufferSource::setInputBufferTimeOffset(int64_t timeOffsetUs) { 106861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang Mutex::Autolock autoLock(mMutex); 106961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 107061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang // timeOffsetUs must be negative for adjustment. 107161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (timeOffsetUs >= 0ll) { 107261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return INVALID_OPERATION; 107361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 107461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 107561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mInputBufferTimeOffsetUs = timeOffsetUs; 107661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return OK; 107761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang} 107861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 107937b2b389139ed638831e49708c947863eef631efRonghua Wustatus_t GraphicBufferSource::setMaxFps(float maxFps) { 108037b2b389139ed638831e49708c947863eef631efRonghua Wu Mutex::Autolock autoLock(mMutex); 108137b2b389139ed638831e49708c947863eef631efRonghua Wu 108237b2b389139ed638831e49708c947863eef631efRonghua Wu if (mExecuting) { 108337b2b389139ed638831e49708c947863eef631efRonghua Wu return INVALID_OPERATION; 108437b2b389139ed638831e49708c947863eef631efRonghua Wu } 108537b2b389139ed638831e49708c947863eef631efRonghua Wu 108637b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper = new FrameDropper(); 108737b2b389139ed638831e49708c947863eef631efRonghua Wu status_t err = mFrameDropper->setMaxFrameRate(maxFps); 108837b2b389139ed638831e49708c947863eef631efRonghua Wu if (err != OK) { 108937b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper.clear(); 109037b2b389139ed638831e49708c947863eef631efRonghua Wu return err; 109137b2b389139ed638831e49708c947863eef631efRonghua Wu } 109237b2b389139ed638831e49708c947863eef631efRonghua Wu 109337b2b389139ed638831e49708c947863eef631efRonghua Wu return OK; 109437b2b389139ed638831e49708c947863eef631efRonghua Wu} 109537b2b389139ed638831e49708c947863eef631efRonghua Wu 109672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 109772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mMutex); 109872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 109972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs = 110072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 110172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 110272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1103dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnarstatus_t GraphicBufferSource::setTimeLapseConfig(const TimeLapseConfig &config) { 11042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang Mutex::Autolock autoLock(mMutex); 11052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1106dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar if (mExecuting || config.mTimePerFrameUs <= 0ll || config.mTimePerCaptureUs <= 0ll) { 11072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return INVALID_OPERATION; 11082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 11092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1110dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mTimePerFrameUs = config.mTimePerFrameUs; 1111dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mTimePerCaptureUs = config.mTimePerCaptureUs; 11122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 11132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return OK; 11142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang} 11152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1116dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnarvoid GraphicBufferSource::setColorAspects(const ColorAspects &aspects) { 1117dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar Mutex::Autolock autoLock(mMutex); 1118dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mColorAspects = aspects; 1119b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))", 1120b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 1121b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 1122b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 1123b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer)); 1124dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar} 1125dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar 1126a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 1127a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 1128a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 1129a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 1130a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 1131a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1132a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 1133a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 1134a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1135a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 1136a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 1137a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1138a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1139a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1140a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 1141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 114437b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 1145a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 114737b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l SUCCESS"); 1148a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 114937b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l FAILURE"); 1150a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 1151a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1152a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1153a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1154a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1155a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 1156a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 1157a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1158a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1159a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1160f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 1161