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), 14237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount(0), 14315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence(Fence::NO_FENCE), 1442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mRepeatBufferDeferred(false), 1452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerCaptureUs(-1ll), 1462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mTimePerFrameUs(-1ll), 1472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs(-1ll), 148054219874873b41f1c815552987c10465c34ba2bLajos Molnar mPrevFrameUs(-1ll) { 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) { 400d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 401d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 402d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 40337b2b389139ed638831e49708c947863eef631efRonghua Wu if (id == mLatestBufferId) { 40437b2b389139ed638831e49708c947863eef631efRonghua Wu CHECK_GT(mLatestBufferUseCount--, 0); 405a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 4069700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence); 407a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 408d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 409f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 41115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // we will not reuse codec buffer, so there is no need to wait for fence 412f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 413f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 414f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 415f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 416f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 417f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 4190c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 420a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("buffer freed, %zu frames avail (eos=%d)", 4210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 425f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 427f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 428a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 42937b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 430a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 43137b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l SUCCESS"); 432a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 43337b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l FAILURE"); 434a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 435a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 436f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 437a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 438f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 439f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 44194ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 44294ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 44394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 44494ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mMaxTimestampGapUs > 0ll 44594ee4b708acfa941581160b267afb79192b1d816Chong Zhang && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 44694ee4b708acfa941581160b267afb79192b1d816Chong Zhang ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 44794ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (index >= 0) { 44894ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGV("OUT timestamp: %lld -> %lld", 449a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(header->nTimeStamp), 450a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mOriginalTimeUs[index])); 45194ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp = mOriginalTimeUs[index]; 45294ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.removeItemsAt(index); 45394ee4b708acfa941581160b267afb79192b1d816Chong Zhang } else { 45494ee4b708acfa941581160b267afb79192b1d816Chong Zhang // giving up the effort as encoder doesn't appear to preserve pts 45594ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGW("giving up limiting timestamp gap (pts = %lld)", 45694ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp); 45794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 45894ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 45994ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 46094ee4b708acfa941581160b267afb79192b1d816Chong Zhang // something terribly wrong must have happened, giving up... 461a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("mOriginalTimeUs has too many entries (%zu)", 46294ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.size()); 46394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 46494ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46694ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 46794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 468e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 469e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 470e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 471e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 472e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 473e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 474e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 4758ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 4765205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 477e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 478e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 479e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 480e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 481e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 482e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 483e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 484e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 485e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 486e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4879700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ++mNumBufferAcquired; 488e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 489e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 490a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, 4919700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 492e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 493e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 494e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 495e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 496e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 497a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 498a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 49937b2b389139ed638831e49708c947863eef631efRonghua Wu if (repeatLatestBuffer_l()) { 50037b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS"); 501a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 502a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 503a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 50437b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE"); 505a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 506a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 507e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 508e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid GraphicBufferSource::onDataSpaceChanged_l( 510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace dataSpace, android_pixel_format pixelFormat) { 511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("got buffer with new dataSpace #%x", dataSpace); 512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mLastDataSpace = dataSpace; 513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (ColorUtils::convertDataSpaceToV0(dataSpace)) { 515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ColorAspects aspects = mColorAspects; // initially requested aspects 516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // request color aspects to encode 518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_INDEXTYPE index; 519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = mNodeInstance->getExtensionIndex( 520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "OMX.google.android.index.describeColorAspects", &index); 521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // V0 dataspace 523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams params; 524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(¶ms); 525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexInput; 526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nDataSpace = mLastDataSpace; 527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPixelFormat = pixelFormat; 528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bDataSpaceChanged = OMX_TRUE; 529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects = mColorAspects; 530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = mNodeInstance->getConfig(index, ¶ms, sizeof(params)); 532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects = params.sAspects; 534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("Codec resolved it to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mRange, asString(params.sAspects.mRange), 536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects = aspects; 542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = OK; 543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bDataSpaceChanged = OMX_FALSE; 545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar for (int triesLeft = 2; --triesLeft >= 0; ) { 546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = mNodeInstance->setConfig(index, ¶ms, sizeof(params)); 547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = mNodeInstance->getConfig(index, ¶ms, sizeof(params)); 549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem( 551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects, aspects)) { 552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // if we can't set or get color aspects, still communicate dataspace to client 553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar break; 554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 556b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(triesLeft == 0, "Codec repeatedly changed requested ColorAspects."); 557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("Set color aspects to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 564b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer), 565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // signal client that the dataspace has changed; this will update the output format 568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // TODO: we should tie this to an output buffer somehow, and signal the change 569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // just before the output buffer is returned to the client, but there are many 570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // ways this could fail (e.g. flushing), and we are not yet supporting this scenario. 571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mNodeInstance->signalEvent( 573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_EventDataSpaceChanged, dataSpace, 574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (aspects.mRange << 24) | (aspects.mPrimaries << 16) 575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar | (aspects.mMatrixCoeffs << 8) | aspects.mTransfer); 576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 577b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5790c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 580f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 5810c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 582e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 583e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 584e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 585e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 586f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 587f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 588f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 589a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 590f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 5910c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 5920c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 593f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 594a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 5950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 5968ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 5975205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 5980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 5990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 6000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 6010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 6020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 6030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 6040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 6050c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 6060c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 607f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6089700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 6090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 610f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 6120c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 6130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 614a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mSlot); 615a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mBufferSlot[item.mSlot] = item.mGraphicBuffer; 6160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 6170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (item.mDataSpace != mLastDataSpace) { 619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar onDataSpaceChanged_l( 620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar item.mDataSpace, (android_pixel_format)mBufferSlot[item.mSlot]->getPixelFormat()); 621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = UNKNOWN_ERROR; 62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // only submit sample if start time is unspecified, or sample 62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // is queued after the specified start time 62837b2b389139ed638831e49708c947863eef631efRonghua Wu bool dropped = false; 62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if start time is set, offset time stamp by start time 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs > 0) { 63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang item.mTimestamp -= mSkipFramesBeforeNs; 63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63437b2b389139ed638831e49708c947863eef631efRonghua Wu 63537b2b389139ed638831e49708c947863eef631efRonghua Wu int64_t timeUs = item.mTimestamp / 1000; 63637b2b389139ed638831e49708c947863eef631efRonghua Wu if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) { 63737b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs)); 63837b2b389139ed638831e49708c947863eef631efRonghua Wu // set err to OK so that the skipped frame can still be saved as the lastest frame 63937b2b389139ed638831e49708c947863eef631efRonghua Wu err = OK; 64037b2b389139ed638831e49708c947863eef631efRonghua Wu dropped = true; 64137b2b389139ed638831e49708c947863eef631efRonghua Wu } else { 64237b2b389139ed638831e49708c947863eef631efRonghua Wu err = submitBuffer_l(item, cbi); 64337b2b389139ed638831e49708c947863eef631efRonghua Wu } 64472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6460c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 647a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("submitBuffer_l failed, releasing bq slot %d", item.mSlot); 648a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, item.mGraphicBuffer, item.mFence); 6490c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 650a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("buffer submitted (bq %d, cbi %d)", item.mSlot, cbi); 65137b2b389139ed638831e49708c947863eef631efRonghua Wu setLatestBuffer_l(item, dropped); 652a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 653a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 654a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 655a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 656a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 65737b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() { 658a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 659a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 66037b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId < 0 || mSuspended) { 661a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 662a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 66337b2b389139ed638831e49708c947863eef631efRonghua Wu if (mBufferSlot[mLatestBufferId] == NULL) { 664bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 665bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 666bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 667bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 668bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 66937b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGD("repeatLatestBuffer_l: slot was NULL"); 6705205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 67137b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId, 67237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum, 673bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 674bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 67515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence); 67637b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = -1; 67737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = 0; 67815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = Fence::NO_FENCE; 679bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 680bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 681a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 682a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 683a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 684a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 68537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l: no codec buffers."); 686a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 687a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 688a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 6898ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 690a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos item.mSlot = mLatestBufferId; 69137b2b389139ed638831e49708c947863eef631efRonghua Wu item.mFrameNumber = mLatestBufferFrameNum; 69294ee4b708acfa941581160b267afb79192b1d816Chong Zhang item.mTimestamp = mRepeatLastFrameTimestamp; 69315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence = mLatestBufferFence; 694a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 695a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 696a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 697a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 698a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 699f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 700f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 70137b2b389139ed638831e49708c947863eef631efRonghua Wu ++mLatestBufferUseCount; 702a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 70394ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* repeat last frame up to kRepeatLastFrameCount times. 70494ee4b708acfa941581160b267afb79192b1d816Chong Zhang * in case of static scene, a single repeat might not get rid of encoder 70594ee4b708acfa941581160b267afb79192b1d816Chong Zhang * ghosting completely, refresh a couple more times to get better quality 70694ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 70794ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (--mRepeatLastFrameCount > 0) { 70894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 70994ee4b708acfa941581160b267afb79192b1d816Chong Zhang 71094ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mReflector != NULL) { 7111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 71294ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->setInt32("generation", ++mRepeatLastFrameGeneration); 71394ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->post(mRepeatAfterUs); 71494ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 71594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 71694ee4b708acfa941581160b267afb79192b1d816Chong Zhang 7170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 72037b2b389139ed638831e49708c947863eef631efRonghua Wuvoid GraphicBufferSource::setLatestBuffer_l( 7218ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza const BufferItem &item, bool dropped) { 72237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("setLatestBuffer_l"); 723a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 72437b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 72537b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferUseCount == 0) { 7269700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, 7279700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 72815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // mLatestBufferFence will be set to new fence just below 729a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 730a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 731a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 732a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mLatestBufferId = item.mSlot; 73337b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = item.mFrameNumber; 73494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 73594ee4b708acfa941581160b267afb79192b1d816Chong Zhang 73637b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount = dropped ? 0 : 1; 737a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 73894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameCount = kRepeatLastFrameCount; 73915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = item.mFence; 740a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 741a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 7421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 743a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 744a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 745a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 746a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 747a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 748ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 749f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 750a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 751ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 752ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 753ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 754ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 755ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 756ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 757f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 760f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 761f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 762f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 763f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 764f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 765f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 766f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 771ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 772ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 773f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 774f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7758ed8ceda7cfe29e8417142ef460cd70060204459Dan Stozaint64_t GraphicBufferSource::getTimestamp(const BufferItem &item) { 77694ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timeUs = item.mTimestamp / 1000; 77794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 7782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mTimePerCaptureUs > 0ll) { 7792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // Time lapse or slow motion mode 7802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mPrevCaptureUs < 0ll) { 7812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // first capture 7822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = timeUs; 7832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs = timeUs; 7842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else { 7852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // snap to nearest capture point 7862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 7872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang / mTimePerCaptureUs; 7882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (nFrames <= 0) { 7892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // skip this frame as it's too close to previous capture 790a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 7912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return -1; 7922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 7932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 7942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs += mTimePerFrameUs * nFrames; 7952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 7962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 7972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 798a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs), 799a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevCaptureUs), 800a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevFrameUs)); 8012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return mPrevFrameUs; 8032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else if (mMaxTimestampGapUs > 0ll) { 80494ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* Cap timestamp gap between adjacent frames to specified max 80594ee4b708acfa941581160b267afb79192b1d816Chong Zhang * 80694ee4b708acfa941581160b267afb79192b1d816Chong Zhang * In the scenario of cast mirroring, encoding could be suspended for 80794ee4b708acfa941581160b267afb79192b1d816Chong Zhang * prolonged periods. Limiting the pts gap to workaround the problem 80894ee4b708acfa941581160b267afb79192b1d816Chong Zhang * where encoder's rate control logic produces huge frames after a 80994ee4b708acfa941581160b267afb79192b1d816Chong Zhang * long period of suspension. 81094ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 81194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 81294ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t originalTimeUs = timeUs; 81394ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mPrevOriginalTimeUs >= 0ll) { 81494ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (originalTimeUs < mPrevOriginalTimeUs) { 81594ee4b708acfa941581160b267afb79192b1d816Chong Zhang // Drop the frame if it's going backward in time. Bad timestamp 81694ee4b708acfa941581160b267afb79192b1d816Chong Zhang // could disrupt encoder's rate control completely. 817b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang ALOGW("Dropping frame that's going backward in time"); 81894ee4b708acfa941581160b267afb79192b1d816Chong Zhang return -1; 81994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 82094ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 82194ee4b708acfa941581160b267afb79192b1d816Chong Zhang timeUs = (timestampGapUs < mMaxTimestampGapUs ? 82294ee4b708acfa941581160b267afb79192b1d816Chong Zhang timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 82394ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 82494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs = originalTimeUs; 82594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs = timeUs; 82694ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.add(timeUs, originalTimeUs); 827a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("IN timestamp: %lld -> %lld", 828a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(originalTimeUs), 829a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs)); 83094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 83194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 83294ee4b708acfa941581160b267afb79192b1d816Chong Zhang return timeUs; 83394ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 83494ee4b708acfa941581160b267afb79192b1d816Chong Zhang 83515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) { 836f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 837b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 838b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang int64_t timeUs = getTimestamp(item); 839b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang if (timeUs < 0ll) { 840b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang return UNKNOWN_ERROR; 841b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang } 842b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 843f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 844a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos codecBuffer.mGraphicBuffer = mBufferSlot[item.mSlot]; 845a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos codecBuffer.mSlot = item.mSlot; 846d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 847f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 848f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 849054219874873b41f1c815552987c10465c34ba2bLajos Molnar sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; 850054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 85115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs, 85215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence->isValid() ? item.mFence->dup() : -1); 853f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 854054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); 855f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 856f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 857f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 858f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 859054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", 860054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); 861f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 862f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 863f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 864f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 865f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 866f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 867f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 868f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 869f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 870f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 871f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 872f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 873f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 874f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 875f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 876f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 877f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 878f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 879f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 880f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 881f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 882f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 883054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 884054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 88515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 0 /* timestamp */, -1 /* fenceFd */); 886f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 887f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 888f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 889f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 890f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 8910c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 892f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 893f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 894f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 895f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 897f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 899f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 900f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 901f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 902f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 903f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 904f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 905f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 906f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 907f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 908f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 909f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 910f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 911f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 912f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 913f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 914f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 915f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9169700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang/* 9179700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * Releases an acquired buffer back to the consumer for either persistent 9189700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * or non-persistent surfaces. 9199700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * 9209700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * id: buffer slot to release (in persistent case the id might be changed) 9219700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * frameNum: frame number of the frame being released 9229700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * buffer: GraphicBuffer pointer to release (note this must not be & as we 9239700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * will clear the original mBufferSlot in persistent case) 9249700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * fence: fence of the frame being released 9259700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang */ 9269700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhangvoid GraphicBufferSource::releaseBuffer( 9279700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang int &id, uint64_t frameNum, 9289700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang const sp<GraphicBuffer> buffer, const sp<Fence> &fence) { 9299700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mIsPersistent) { 9309700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->detachBuffer(id); 9319700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[id] = NULL; 9329700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 933264bac95912efe121d6a60026612617f04f42966Lajos Molnar if (mConsumer->attachBuffer(&id, buffer) == OK) { 934264bac95912efe121d6a60026612617f04f42966Lajos Molnar mConsumer->releaseBuffer( 935264bac95912efe121d6a60026612617f04f42966Lajos Molnar id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 936264bac95912efe121d6a60026612617f04f42966Lajos Molnar } 9379700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } else { 9389700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->releaseBuffer( 9399700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 9409700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 941264bac95912efe121d6a60026612617f04f42966Lajos Molnar id = -1; // invalidate id 9429700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired--; 9439700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang} 9449700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 945f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 94604f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { 947f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 948f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 949a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("onFrameAvailable exec=%d avail=%zu", 9500c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 951f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 952e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 953e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 954e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 955e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 956e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 957e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 958e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 959e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 960e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 961f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9628ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 9635205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 964f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 9659700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 9669700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 96749270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // If this is the first time we're seeing this buffer, add it to our 96849270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // slot table. 96949270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang if (item.mGraphicBuffer != NULL) { 970a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mSlot); 971a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mBufferSlot[item.mSlot] = item.mGraphicBuffer; 97249270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang } 973d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 974a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, 9759700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 976f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 977f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 978f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 979f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 980f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 981f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 982a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 983a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 984a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 985f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 986f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 987f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 988f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 989f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 990f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 991f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 992f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 993f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9942475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza uint64_t slotMask; 9955205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 996f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 9972475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza slotMask = 0xffffffffffffffffULL; 998f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 999f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10002475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 1001f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1002f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 1003f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 1004f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 1005f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1006f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 1007f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1008f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 1009f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10108dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback 10118dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() { 10128dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 10138dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall} 10148dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall 101557fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnarvoid GraphicBufferSource::setDefaultDataSpace(android_dataspace dataSpace) { 1016b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // no need for mutex as we are not yet running 101757fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar ALOGD("setting dataspace: %#x", dataSpace); 101857fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mConsumer->setDefaultBufferDataSpace(dataSpace); 101957fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mLastDataSpace = dataSpace; 102057fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar} 102157fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar 1022a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 1023a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 1024a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 1025a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1026a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 1027a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 1028a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1029a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1030a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 1031a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1032a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 1033a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1034a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 103594ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 103694ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 103794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 103894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mExecuting || maxGapUs <= 0ll) { 103994ee4b708acfa941581160b267afb79192b1d816Chong Zhang return INVALID_OPERATION; 104094ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 104194ee4b708acfa941581160b267afb79192b1d816Chong Zhang 104294ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = maxGapUs; 104394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 104494ee4b708acfa941581160b267afb79192b1d816Chong Zhang return OK; 104594ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 104672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 104737b2b389139ed638831e49708c947863eef631efRonghua Wustatus_t GraphicBufferSource::setMaxFps(float maxFps) { 104837b2b389139ed638831e49708c947863eef631efRonghua Wu Mutex::Autolock autoLock(mMutex); 104937b2b389139ed638831e49708c947863eef631efRonghua Wu 105037b2b389139ed638831e49708c947863eef631efRonghua Wu if (mExecuting) { 105137b2b389139ed638831e49708c947863eef631efRonghua Wu return INVALID_OPERATION; 105237b2b389139ed638831e49708c947863eef631efRonghua Wu } 105337b2b389139ed638831e49708c947863eef631efRonghua Wu 105437b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper = new FrameDropper(); 105537b2b389139ed638831e49708c947863eef631efRonghua Wu status_t err = mFrameDropper->setMaxFrameRate(maxFps); 105637b2b389139ed638831e49708c947863eef631efRonghua Wu if (err != OK) { 105737b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper.clear(); 105837b2b389139ed638831e49708c947863eef631efRonghua Wu return err; 105937b2b389139ed638831e49708c947863eef631efRonghua Wu } 106037b2b389139ed638831e49708c947863eef631efRonghua Wu 106137b2b389139ed638831e49708c947863eef631efRonghua Wu return OK; 106237b2b389139ed638831e49708c947863eef631efRonghua Wu} 106337b2b389139ed638831e49708c947863eef631efRonghua Wu 106472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 106572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mMutex); 106672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 106772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs = 106872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 106972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 107072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1071dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnarstatus_t GraphicBufferSource::setTimeLapseConfig(const TimeLapseConfig &config) { 10722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang Mutex::Autolock autoLock(mMutex); 10732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1074dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar if (mExecuting || config.mTimePerFrameUs <= 0ll || config.mTimePerCaptureUs <= 0ll) { 10752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return INVALID_OPERATION; 10762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 10772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1078dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mTimePerFrameUs = config.mTimePerFrameUs; 1079dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mTimePerCaptureUs = config.mTimePerCaptureUs; 10802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 10812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return OK; 10822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang} 10832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1084dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnarvoid GraphicBufferSource::setColorAspects(const ColorAspects &aspects) { 1085dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar Mutex::Autolock autoLock(mMutex); 1086dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mColorAspects = aspects; 1087b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))", 1088b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 1089b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 1090b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 1091b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer)); 1092dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar} 1093dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar 1094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 1095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 1096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 1097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 1098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 1099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 1101a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 1102a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1103a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 1104a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 1105a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1106a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1107a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1108a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 1109a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1110a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1111a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 111237b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 1113a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1114a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 111537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l SUCCESS"); 1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 111737b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l FAILURE"); 1118a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 1119a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1120a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1121a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1122a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1123a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 1124a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 1125a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1126a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1127a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1128f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 1129