GraphicBufferSource.cpp revision 61fcfd1b0b58dff9284ede8dc49749ca7395856d
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), 14861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mPrevFrameUs(-1ll), 14961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mInputBufferTimeOffsetUs(0ll) { 150f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1510c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("GraphicBufferSource w=%u h=%u c=%u", 1520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden bufferWidth, bufferHeight, bufferCount); 153f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 154f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (bufferWidth == 0 || bufferHeight == 0) { 1550c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 156f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mInitCheck = BAD_VALUE; 157f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 158f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 159f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 160d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer == NULL) { 161d291c222357303b9611cab89d0c3b047584ef377Chong Zhang String8 name("GraphicBufferSource"); 1620c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 163d291c222357303b9611cab89d0c3b047584ef377Chong Zhang BufferQueue::createBufferQueue(&mProducer, &mConsumer); 164d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setConsumerName(name); 165c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 16649605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar // use consumer usage bits queried from encoder, but always add HW_VIDEO_ENCODER 167c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar // for backward compatibility. 16849605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER; 16949605e8ab171a2b1f474645d632d3982f5f7b8e6Lajos Molnar mConsumer->setConsumerUsageBits(consumerUsage); 170c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 171d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount); 172d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mInitCheck != NO_ERROR) { 173d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 174d291c222357303b9611cab89d0c3b047584ef377Chong Zhang bufferCount, mInitCheck); 175d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return; 176d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 177d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 178d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mIsPersistent = true; 1790c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 180d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); 181f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note that we can't create an sp<...>(this) in a ctor that will not keep a 182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // reference once the ctor ends, as that would cause the refcount of 'this' 183f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 184f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that's what we create. 185910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 186ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang sp<IConsumerListener> proxy; 187ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang if (!mIsPersistent) { 188ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang proxy = new BufferQueue::ProxyConsumerListener(listener); 189ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } else { 190ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang proxy = new PersistentProxyListener(mConsumer, listener); 191ffd8cbb288f096b53df0392bf40d99b89e34bea7Chong Zhang } 192f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1935205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mInitCheck = mConsumer->consumerConnect(proxy, false); 1940c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (mInitCheck != NO_ERROR) { 195f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("Error connecting to BufferQueue: %s (%d)", 1960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden strerror(-mInitCheck), mInitCheck); 197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 199f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 200dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar memset(&mColorAspects, 0, sizeof(mColorAspects)); 201dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar 2020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(mInitCheck == NO_ERROR); 203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() { 2069700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mLatestBufferId >= 0) { 2079700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer( 2089700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mLatestBufferId, mLatestBufferFrameNum, 2099700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 2109700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 2119700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mNumBufferAcquired != 0) { 2129700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired); 2139700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 214d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (mConsumer != NULL && !mIsPersistent) { 2155205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->consumerDisconnect(); 2160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != NO_ERROR) { 2170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("consumerDisconnect failed: %d", err); 2180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 222f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() { 223f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 224a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> executing; avail=%zu, codec vec size=%zd", 225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mCodecBuffers.size()); 226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(!mExecuting); 227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = true; 228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mLastDataSpace = HAL_DATASPACE_UNKNOWN; 229b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("clearing last dataSpace"); 230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Start by loading up as many buffers as possible. We want to do this, 232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // rather than just submit the first buffer, to avoid a degenerate case: 233f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // if all BQ buffers arrive before we start executing, and we only submit 234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one here, the other BQ buffers will just sit until we get notified 235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that the codec buffer has been released. We'd then acquire and 236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit a single additional buffer, repeatedly, never using more than 237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // one codec buffer simultaneously. (We could instead try to submit 238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // all BQ buffers whenever any codec buffer is freed, but if we get the 239f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // initial conditions right that will never be useful.) 2400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden while (mNumFramesAvailable) { 2410c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (!fillCodecBuffer_l()) { 2420c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGV("stop load with frames available (codecAvail=%d)", 2430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden isCodecBufferAvailable_l()); 2440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden break; 2450c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 246f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 247f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 248a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable); 249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If EOS has already been signaled, and there are no more frames to 251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // submit, try to send EOS now as well. 252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStream && mNumFramesAvailable == 0) { 253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 254f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 255a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 256a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mRepeatAfterUs > 0ll && mLooper == NULL) { 257a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector = new AHandlerReflector<GraphicBufferSource>(this); 258a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 259a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper = new ALooper; 260a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->registerHandler(mReflector); 261a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->start(); 262a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 26337b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 264a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber sp<AMessage> msg = 2651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatRepeatLastFrame, mReflector); 266a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 267a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 268a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 269a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 270a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 271f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 272f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 273ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() { 274ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber ALOGV("omxIdle"); 275ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 276ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber Mutex::Autolock autoLock(mMutex); 277ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 278ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber if (mExecuting) { 279ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // We are only interested in the transition from executing->idle, 280ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber // not loaded->idle. 281892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber mExecuting = false; 282ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber } 283ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber} 284ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber 285ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){ 286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 287ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden if (!mExecuting) { 288ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden // This can happen if something failed very early. 289ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden ALOGW("Dropped back down to Loaded without Executing"); 290ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden } 291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 292a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mLooper != NULL) { 293a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->unregisterHandler(mReflector->id()); 294a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mReflector.clear(); 295a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 296a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper->stop(); 297a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mLooper.clear(); 298a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 299a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 300a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d", 301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 302f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 303f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Codec is no longer executing. Discard all codec-related state. 304f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.clear(); 305f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 306f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // are null; complain if not 307f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 308f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mExecuting = false; 309f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 311f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 312f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 313f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 314f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 315f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen -- buffers can only be allocated when 316f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // transitioning from "loaded" to "idle". 317f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("addCodecBuffer: buffer added while executing"); 318f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 319f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 320f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 321db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p", 322f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->pBuffer); 323f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer codecBuffer; 324f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mHeader = header; 325f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mCodecBuffers.add(codecBuffer); 326f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 327f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 32815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) { 329f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 330892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber if (!mExecuting) { 331892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber return; 332892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber } 333f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 334f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findMatchingCodecBuffer_l(header); 335f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 336f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // This should never happen. 337f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 33815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 33915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 34015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 341f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 343f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 344db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p", 345f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, header->nAllocLen, header->nFilledLen, 346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header->pBuffer); 347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 349f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // header->nFilledLen may not be the original value, so we can't compare 350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that to zero to see of this was the EOS buffer. Instead we just 351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // see if the GraphicBuffer reference was null, which should only ever 352f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // happen for EOS. 353f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (codecBuffer.mGraphicBuffer == NULL) { 3545572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden if (!(mEndOfStream && mEndOfStreamSent)) { 3555572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // This can happen when broken code sends us the same buffer 3565572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden // twice in a row. 3575572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 3585572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden "(buffer emptied twice?)"); 3595572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden } 360f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No GraphicBuffer to deal with, no additional input or output is 361f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // expected, so just return. 36215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar if (fenceFd >= 0) { 36315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar ::close(fenceFd); 36415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar } 365f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 366f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 367f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 368054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) { 369f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Pull the graphic buffer handle back out of the buffer, and confirm 370f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // that it matches expectations. 371f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_U8* data = header->pBuffer; 372512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar MetadataBufferType type = *(MetadataBufferType *)data; 373054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (type == kMetadataBufferTypeGrallocSource 374054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { 375054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data; 3769847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar if (grallocMeta.pHandle != codecBuffer.mGraphicBuffer->handle) { 377512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 378512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 3799847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar grallocMeta.pHandle, codecBuffer.mGraphicBuffer->handle); 380512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 381512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 382054219874873b41f1c815552987c10465c34ba2bLajos Molnar } else if (type == kMetadataBufferTypeANWBuffer 383054219874873b41f1c815552987c10465c34ba2bLajos Molnar && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 384054219874873b41f1c815552987c10465c34ba2bLajos Molnar VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data; 385054219874873b41f1c815552987c10465c34ba2bLajos Molnar if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) { 386512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar // should never happen 387512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar ALOGE("codecBufferEmptied: buffer is %p, expected %p", 388054219874873b41f1c815552987c10465c34ba2bLajos Molnar nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer()); 389512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar CHECK(!"codecBufferEmptied: mismatched buffer"); 390512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar } 391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 392f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 394f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Find matching entry in our cached copy of the BufferQueue slots. 395f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // If we find a match, release that slot. If we don't, the BufferQueue 396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // has dropped that GraphicBuffer, and there's nothing for us to release. 397a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos int id = codecBuffer.mSlot; 39815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar sp<Fence> fence = new Fence(fenceFd); 399d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar if (mBufferSlot[id] != NULL && 400d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 401d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar ALOGV("cbi %d matches bq slot %d, handle=%p", 402d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar cbi, id, mBufferSlot[id]->handle); 403d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar 40437b2b389139ed638831e49708c947863eef631efRonghua Wu if (id == mLatestBufferId) { 40537b2b389139ed638831e49708c947863eef631efRonghua Wu CHECK_GT(mLatestBufferUseCount--, 0); 406a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 4079700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence); 408a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 409d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar } else { 410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 411f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden cbi); 41215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // we will not reuse codec buffer, so there is no need to wait for fence 413f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 414f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 415f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Mark the codec buffer as available by clearing the GraphicBuffer ref. 416f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 417f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mNumFramesAvailable) { 419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Fill this codec buffer. 4200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden CHECK(!mEndOfStreamSent); 421a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("buffer freed, %zu frames avail (eos=%d)", 4220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable, mEndOfStream); 423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else if (mEndOfStream) { 425f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No frames available, but EOS is pending, so use this buffer to 426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // send that. 427f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("buffer freed, EOS pending"); 428f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 429a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else if (mRepeatBufferDeferred) { 43037b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 431a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 43237b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l SUCCESS"); 433a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 43437b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("deferred repeatLatestBuffer_l FAILURE"); 435a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 436a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 437f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 438a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 439f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 441f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 44294ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 44394ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 44494ee4b708acfa941581160b267afb79192b1d816Chong Zhang 44594ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mMaxTimestampGapUs > 0ll 44694ee4b708acfa941581160b267afb79192b1d816Chong Zhang && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 44794ee4b708acfa941581160b267afb79192b1d816Chong Zhang ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 44894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (index >= 0) { 44994ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGV("OUT timestamp: %lld -> %lld", 450a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(header->nTimeStamp), 451a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mOriginalTimeUs[index])); 45294ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp = mOriginalTimeUs[index]; 45394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.removeItemsAt(index); 45494ee4b708acfa941581160b267afb79192b1d816Chong Zhang } else { 45594ee4b708acfa941581160b267afb79192b1d816Chong Zhang // giving up the effort as encoder doesn't appear to preserve pts 45694ee4b708acfa941581160b267afb79192b1d816Chong Zhang ALOGW("giving up limiting timestamp gap (pts = %lld)", 45794ee4b708acfa941581160b267afb79192b1d816Chong Zhang header->nTimeStamp); 45894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 45994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46094ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 46194ee4b708acfa941581160b267afb79192b1d816Chong Zhang // something terribly wrong must have happened, giving up... 462a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("mOriginalTimeUs has too many entries (%zu)", 46394ee4b708acfa941581160b267afb79192b1d816Chong Zhang mOriginalTimeUs.size()); 46494ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = -1ll; 46594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 46794ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 46894ee4b708acfa941581160b267afb79192b1d816Chong Zhang 469e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) { 470e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber Mutex::Autolock autoLock(mMutex); 471e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 472e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (suspend) { 473e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = true; 474e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 475e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber while (mNumFramesAvailable > 0) { 4768ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 4775205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 478e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 479e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 480e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // shouldn't happen. 481e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: frame was not available"); 482e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 483e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else if (err != OK) { 484e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("suspend: acquireBuffer returned err=%d", err); 485e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber break; 486e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 487e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 4889700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang ++mNumBufferAcquired; 489e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber --mNumFramesAvailable; 490e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 491a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, 4929700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 493e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 494e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return; 495e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 496e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 497e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber mSuspended = false; 498a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 499a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 50037b2b389139ed638831e49708c947863eef631efRonghua Wu if (repeatLatestBuffer_l()) { 50137b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS"); 502a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 503a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 504a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 50537b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE"); 506a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 507a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 508e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber} 509e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid GraphicBufferSource::onDataSpaceChanged_l( 511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar android_dataspace dataSpace, android_pixel_format pixelFormat) { 512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("got buffer with new dataSpace #%x", dataSpace); 513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mLastDataSpace = dataSpace; 514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (ColorUtils::convertDataSpaceToV0(dataSpace)) { 516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ColorAspects aspects = mColorAspects; // initially requested aspects 517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // request color aspects to encode 519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_INDEXTYPE index; 520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = mNodeInstance->getExtensionIndex( 521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar "OMX.google.android.index.describeColorAspects", &index); 522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // V0 dataspace 524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar DescribeColorAspectsParams params; 525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar InitOMXParams(¶ms); 526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPortIndex = kPortIndexInput; 527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nDataSpace = mLastDataSpace; 528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.nPixelFormat = pixelFormat; 529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bDataSpaceChanged = OMX_TRUE; 530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects = mColorAspects; 531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = mNodeInstance->getConfig(index, ¶ms, sizeof(params)); 533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects = params.sAspects; 535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("Codec resolved it to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mRange, asString(params.sAspects.mRange), 537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects = aspects; 543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = OK; 544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.bDataSpaceChanged = OMX_FALSE; 546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar for (int triesLeft = 2; --triesLeft >= 0; ) { 547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar status_t err = mNodeInstance->setConfig(index, ¶ms, sizeof(params)); 548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err == OK) { 549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err = mNodeInstance->getConfig(index, ¶ms, sizeof(params)); 550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem( 552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar params.sAspects, aspects)) { 553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // if we can't set or get color aspects, still communicate dataspace to client 554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar break; 555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 556b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(triesLeft == 0, "Codec repeatedly changed requested ColorAspects."); 558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("Set color aspects to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 564b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer), 566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar err, asString(err)); 567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // signal client that the dataspace has changed; this will update the output format 569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // TODO: we should tie this to an output buffer somehow, and signal the change 570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // just before the output buffer is returned to the client, but there are many 571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // ways this could fail (e.g. flushing), and we are not yet supporting this scenario. 572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mNodeInstance->signalEvent( 574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar OMX_EventDataSpaceChanged, dataSpace, 575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar (aspects.mRange << 24) | (aspects.mPrimaries << 16) 576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar | (aspects.mMatrixCoeffs << 8) | aspects.mTransfer); 577b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar} 579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 5800c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() { 581f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mExecuting && mNumFramesAvailable > 0); 5820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 583e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mSuspended) { 584e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber return false; 585e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 586e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 587f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 588f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 589f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // No buffers available, bail. 590a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 591f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable); 5920c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 5930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 594f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 595a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 5960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable); 5978ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 5985205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 5990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 6000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // shouldn't happen 6010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: frame was not available"); 6020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 6030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else if (err != OK) { 6040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // now what? fake end-of-stream? 6050c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 6060c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return false; 6070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 608f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6099700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 6100c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mNumFramesAvailable--; 611f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 6120c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // If this is the first time we're seeing this buffer, add it to our 6130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden // slot table. 6140c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (item.mGraphicBuffer != NULL) { 615a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mSlot); 616a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mBufferSlot[item.mSlot] = item.mGraphicBuffer; 6170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } 6180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden 619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (item.mDataSpace != mLastDataSpace) { 620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar onDataSpaceChanged_l( 621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar item.mDataSpace, (android_pixel_format)mBufferSlot[item.mSlot]->getPixelFormat()); 622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = UNKNOWN_ERROR; 62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // only submit sample if start time is unspecified, or sample 62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // is queued after the specified start time 62937b2b389139ed638831e49708c947863eef631efRonghua Wu bool dropped = false; 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if start time is set, offset time stamp by start time 63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mSkipFramesBeforeNs > 0) { 63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang item.mTimestamp -= mSkipFramesBeforeNs; 63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63537b2b389139ed638831e49708c947863eef631efRonghua Wu 63637b2b389139ed638831e49708c947863eef631efRonghua Wu int64_t timeUs = item.mTimestamp / 1000; 63737b2b389139ed638831e49708c947863eef631efRonghua Wu if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) { 63837b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs)); 63937b2b389139ed638831e49708c947863eef631efRonghua Wu // set err to OK so that the skipped frame can still be saved as the lastest frame 64037b2b389139ed638831e49708c947863eef631efRonghua Wu err = OK; 64137b2b389139ed638831e49708c947863eef631efRonghua Wu dropped = true; 64237b2b389139ed638831e49708c947863eef631efRonghua Wu } else { 64337b2b389139ed638831e49708c947863eef631efRonghua Wu err = submitBuffer_l(item, cbi); 64437b2b389139ed638831e49708c947863eef631efRonghua Wu } 64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 64672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6470c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden if (err != OK) { 648a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("submitBuffer_l failed, releasing bq slot %d", item.mSlot); 649a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, item.mGraphicBuffer, item.mFence); 6500c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden } else { 651a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("buffer submitted (bq %d, cbi %d)", item.mSlot, cbi); 65237b2b389139ed638831e49708c947863eef631efRonghua Wu setLatestBuffer_l(item, dropped); 653a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 654a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 655a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return true; 656a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 657a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 65837b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() { 659a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(mExecuting && mNumFramesAvailable == 0); 660a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 66137b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId < 0 || mSuspended) { 662a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 663a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 66437b2b389139ed638831e49708c947863eef631efRonghua Wu if (mBufferSlot[mLatestBufferId] == NULL) { 665bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // This can happen if the remote side disconnects, causing 666bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // onBuffersReleased() to NULL out our copy of the slots. The 667bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // buffer is gone, so we have nothing to show. 668bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // 669bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden // To be on the safe side we try to release the buffer. 67037b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGD("repeatLatestBuffer_l: slot was NULL"); 6715205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza mConsumer->releaseBuffer( 67237b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId, 67337b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum, 674bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_DISPLAY, 675bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden EGL_NO_SYNC_KHR, 67615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence); 67737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferId = -1; 67837b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = 0; 67915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = Fence::NO_FENCE; 680bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden return false; 681bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden } 682a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 683a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int cbi = findAvailableCodecBuffer_l(); 684a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (cbi < 0) { 685a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // No buffers available, bail. 68637b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l: no codec buffers."); 687a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 688a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 689a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 6908ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 691a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos item.mSlot = mLatestBufferId; 69237b2b389139ed638831e49708c947863eef631efRonghua Wu item.mFrameNumber = mLatestBufferFrameNum; 69394ee4b708acfa941581160b267afb79192b1d816Chong Zhang item.mTimestamp = mRepeatLastFrameTimestamp; 69415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence = mLatestBufferFence; 695a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 696a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber status_t err = submitBuffer_l(item, cbi); 697a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 698a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (err != OK) { 699a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return false; 700f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 701f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 70237b2b389139ed638831e49708c947863eef631efRonghua Wu ++mLatestBufferUseCount; 703a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 70494ee4b708acfa941581160b267afb79192b1d816Chong Zhang /* repeat last frame up to kRepeatLastFrameCount times. 70594ee4b708acfa941581160b267afb79192b1d816Chong Zhang * in case of static scene, a single repeat might not get rid of encoder 70694ee4b708acfa941581160b267afb79192b1d816Chong Zhang * ghosting completely, refresh a couple more times to get better quality 70794ee4b708acfa941581160b267afb79192b1d816Chong Zhang */ 70894ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (--mRepeatLastFrameCount > 0) { 70994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 71094ee4b708acfa941581160b267afb79192b1d816Chong Zhang 71194ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mReflector != NULL) { 7121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 71394ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->setInt32("generation", ++mRepeatLastFrameGeneration); 71494ee4b708acfa941581160b267afb79192b1d816Chong Zhang msg->post(mRepeatAfterUs); 71594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 71694ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 71794ee4b708acfa941581160b267afb79192b1d816Chong Zhang 7180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden return true; 719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 720f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 72137b2b389139ed638831e49708c947863eef631efRonghua Wuvoid GraphicBufferSource::setLatestBuffer_l( 7228ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza const BufferItem &item, bool dropped) { 72337b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("setLatestBuffer_l"); 724a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 72537b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferId >= 0) { 72637b2b389139ed638831e49708c947863eef631efRonghua Wu if (mLatestBufferUseCount == 0) { 7279700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, 7289700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[mLatestBufferId], mLatestBufferFence); 72915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar // mLatestBufferFence will be set to new fence just below 730a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 731a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 732a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 733a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mLatestBufferId = item.mSlot; 73437b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferFrameNum = item.mFrameNumber; 73594ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 73694ee4b708acfa941581160b267afb79192b1d816Chong Zhang 73737b2b389139ed638831e49708c947863eef631efRonghua Wu mLatestBufferUseCount = dropped ? 0 : 1; 738a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 73994ee4b708acfa941581160b267afb79192b1d816Chong Zhang mRepeatLastFrameCount = kRepeatLastFrameCount; 74015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar mLatestBufferFence = item.mFence; 741a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 742a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mReflector != NULL) { 7431d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 744a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->setInt32("generation", ++mRepeatLastFrameGeneration); 745a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber msg->post(mRepeatAfterUs); 746a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 747a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 748a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 749ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() { 750f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 751a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 752ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden mExecuting, mNumFramesAvailable, mEndOfStream); 753ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 754ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden if (mEndOfStream) { 755ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden ALOGE("EOS was already signaled"); 756ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return INVALID_OPERATION; 757ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden } 758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Set the end-of-stream flag. If no frames are pending from the 760f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // BufferQueue, and a codec buffer is available, and we're executing, 761f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // we initiate the EOS from here. Otherwise, we'll let 762f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // codecBufferEmptied() (or omxExecuting) do it. 763f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // 764f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // Note: if there are no pending frames and all codec buffers are 765f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // available, we *must* submit the EOS from here or we'll just 766f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // stall since no future events are expected. 767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mEndOfStream = true; 768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting && mNumFramesAvailable == 0) { 770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden submitEndOfInputStream_l(); 771f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 772ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden 773ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden return OK; 774f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 775f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 7768ed8ceda7cfe29e8417142ef460cd70060204459Dan Stozaint64_t GraphicBufferSource::getTimestamp(const BufferItem &item) { 77794ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t timeUs = item.mTimestamp / 1000; 77861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang timeUs += mInputBufferTimeOffsetUs; 77994ee4b708acfa941581160b267afb79192b1d816Chong Zhang 7805a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang if (mTimePerCaptureUs > 0ll 7815a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang && (mTimePerCaptureUs > 2 * mTimePerFrameUs 7825a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang || mTimePerFrameUs > 2 * mTimePerCaptureUs)) { 7832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // Time lapse or slow motion mode 7842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (mPrevCaptureUs < 0ll) { 7852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // first capture 7862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = timeUs; 7872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs = timeUs; 7882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } else { 7892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // snap to nearest capture point 7902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 7912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang / mTimePerCaptureUs; 7922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (nFrames <= 0) { 7932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // skip this frame as it's too close to previous capture 794a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 7952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return -1; 7962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 7972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 7982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang mPrevFrameUs += mTimePerFrameUs * nFrames; 7992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 8002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 802a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(timeUs), 803a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevCaptureUs), 804a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn static_cast<long long>(mPrevFrameUs)); 8052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 8062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return mPrevFrameUs; 80761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } else { 80894ee4b708acfa941581160b267afb79192b1d816Chong Zhang int64_t originalTimeUs = timeUs; 80961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (originalTimeUs <= mPrevOriginalTimeUs) { 81094ee4b708acfa941581160b267afb79192b1d816Chong Zhang // Drop the frame if it's going backward in time. Bad timestamp 81194ee4b708acfa941581160b267afb79192b1d816Chong Zhang // could disrupt encoder's rate control completely. 81261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang ALOGW("Dropping frame that's going backward in time"); 81361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return -1; 81461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 81561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 81661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (mMaxTimestampGapUs > 0ll) { 81761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang //TODO: Fix the case when mMaxTimestampGapUs and mTimePerCaptureUs are both set. 81861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 81961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang /* Cap timestamp gap between adjacent frames to specified max 82061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * 82161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * In the scenario of cast mirroring, encoding could be suspended for 82261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * prolonged periods. Limiting the pts gap to workaround the problem 82361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * where encoder's rate control logic produces huge frames after a 82461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang * long period of suspension. 82561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang */ 82661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (mPrevOriginalTimeUs >= 0ll) { 82761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 82861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang timeUs = (timestampGapUs < mMaxTimestampGapUs ? 82994ee4b708acfa941581160b267afb79192b1d816Chong Zhang timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 83061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mOriginalTimeUs.add(timeUs, originalTimeUs); 83161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang ALOGV("IN timestamp: %lld -> %lld", 83261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang static_cast<long long>(originalTimeUs), 83361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang static_cast<long long>(timeUs)); 83461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 83594ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 83661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 83794ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevOriginalTimeUs = originalTimeUs; 83894ee4b708acfa941581160b267afb79192b1d816Chong Zhang mPrevModifiedTimeUs = timeUs; 83994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 84094ee4b708acfa941581160b267afb79192b1d816Chong Zhang 84194ee4b708acfa941581160b267afb79192b1d816Chong Zhang return timeUs; 84294ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 84394ee4b708acfa941581160b267afb79192b1d816Chong Zhang 84415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) { 845f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitBuffer_l cbi=%d", cbi); 846b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 847b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang int64_t timeUs = getTimestamp(item); 848b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang if (timeUs < 0ll) { 849b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang return UNKNOWN_ERROR; 850b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang } 851b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang 852f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 853a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos codecBuffer.mGraphicBuffer = mBufferSlot[item.mSlot]; 854a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos codecBuffer.mSlot = item.mSlot; 855d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar codecBuffer.mFrameNumber = item.mFrameNumber; 856f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 857f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 858054219874873b41f1c815552987c10465c34ba2bLajos Molnar sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; 859054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 86015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs, 86115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar item.mFence->isValid() ? item.mFence->dup() : -1); 862f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 863054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); 864f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden codecBuffer.mGraphicBuffer = NULL; 865f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return err; 866f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 867f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 868054219874873b41f1c815552987c10465c34ba2bLajos Molnar ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", 869054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); 870f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return OK; 871f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 872f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 873f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() { 874f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mEndOfStream); 875f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mEndOfStreamSent) { 876f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("EOS already sent"); 877f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 878f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 879f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 880f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden int cbi = findAvailableCodecBuffer_l(); 881f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (cbi < 0) { 882f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: no codec buffers available"); 883f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 884f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 885f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 886f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // We reject any additional incoming graphic buffers, so there's no need 887f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 888f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden // in-use. 889f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 890f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 891f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 892054219874873b41f1c815552987c10465c34ba2bLajos Molnar status_t err = mNodeInstance->emptyGraphicBuffer( 893054219874873b41f1c815552987c10465c34ba2bLajos Molnar header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 89415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar 0 /* timestamp */, -1 /* fenceFd */); 895f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err != OK) { 896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 897f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } else { 898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 899f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden header, cbi); 9000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mEndOfStreamSent = true; 901f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 902f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 903f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 904f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() { 905f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden CHECK(mCodecBuffers.size() > 0); 906f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 907f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 908f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mGraphicBuffer == NULL) { 909f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 910f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 911f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 912f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 913f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 914f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 915f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l( 916f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden const OMX_BUFFERHEADERTYPE* header) { 917f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 918f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mCodecBuffers[i].mHeader == header) { 919f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return i; 920f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 921f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 922f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return -1; 923f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 924f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9259700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang/* 9269700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * Releases an acquired buffer back to the consumer for either persistent 9279700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * or non-persistent surfaces. 9289700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * 9299700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * id: buffer slot to release (in persistent case the id might be changed) 9309700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * frameNum: frame number of the frame being released 9319700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * buffer: GraphicBuffer pointer to release (note this must not be & as we 9329700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * will clear the original mBufferSlot in persistent case) 9339700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang * fence: fence of the frame being released 9349700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang */ 9359700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhangvoid GraphicBufferSource::releaseBuffer( 9369700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang int &id, uint64_t frameNum, 9379700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang const sp<GraphicBuffer> buffer, const sp<Fence> &fence) { 9389700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang if (mIsPersistent) { 9399700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->detachBuffer(id); 9409700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mBufferSlot[id] = NULL; 9419700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 942264bac95912efe121d6a60026612617f04f42966Lajos Molnar if (mConsumer->attachBuffer(&id, buffer) == OK) { 943264bac95912efe121d6a60026612617f04f42966Lajos Molnar mConsumer->releaseBuffer( 944264bac95912efe121d6a60026612617f04f42966Lajos Molnar id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 945264bac95912efe121d6a60026612617f04f42966Lajos Molnar } 9469700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } else { 9479700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mConsumer->releaseBuffer( 9489700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 9499700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang } 950264bac95912efe121d6a60026612617f04f42966Lajos Molnar id = -1; // invalidate id 9519700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired--; 9529700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang} 9539700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 954f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 95504f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { 956f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock autoLock(mMutex); 957f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 958a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("onFrameAvailable exec=%d avail=%zu", 9590c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden mExecuting, mNumFramesAvailable); 960f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 961e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream || mSuspended) { 962e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber if (mEndOfStream) { 963e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // This should only be possible if a new buffer was queued after 964e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber // EOS was signaled, i.e. the app is misbehaving. 965e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber 966e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 967e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } else { 968e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber ALOGV("onFrameAvailable: suspended, ignoring frame"); 969e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber } 970f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 9718ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item; 9725205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza status_t err = mConsumer->acquireBuffer(&item, 0); 973f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (err == OK) { 9749700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang mNumBufferAcquired++; 9759700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang 97649270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // If this is the first time we're seeing this buffer, add it to our 97749270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang // slot table. 97849270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang if (item.mGraphicBuffer != NULL) { 979a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mSlot); 980a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos mBufferSlot[item.mSlot] = item.mGraphicBuffer; 98149270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang } 982d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 983a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos releaseBuffer(item.mSlot, item.mFrameNumber, 9849700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang item.mGraphicBuffer, item.mFence); 985f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 986f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden return; 987f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 988f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 989f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mNumFramesAvailable++; 990f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 991a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = false; 992a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ++mRepeatLastFrameGeneration; 993a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 994f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if (mExecuting) { 995f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden fillCodecBuffer_l(); 996f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 997f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 998f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 999f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback 1000f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() { 1001f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden Mutex::Autolock lock(mMutex); 1002f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10032475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza uint64_t slotMask; 10045205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 1005f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden ALOGW("onBuffersReleased: unable to get released buffer set"); 10062475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza slotMask = 0xffffffffffffffffULL; 1007f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1008f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10092475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 1010f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 1011f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 1012f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden if ((slotMask & 0x01) != 0) { 1013f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden mBufferSlot[i] = NULL; 1014f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1015f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden slotMask >>= 1; 1016f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden } 1017f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} 1018f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden 10198dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback 10208dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() { 10218dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 10228dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall} 10238dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall 102457fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnarvoid GraphicBufferSource::setDefaultDataSpace(android_dataspace dataSpace) { 1025b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // no need for mutex as we are not yet running 102657fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar ALOGD("setting dataspace: %#x", dataSpace); 102757fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mConsumer->setDefaultBufferDataSpace(dataSpace); 102857fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar mLastDataSpace = dataSpace; 102957fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar} 103057fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar 1031a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 1032a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int64_t repeatAfterUs) { 1033a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 1034a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1035a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (mExecuting || repeatAfterUs <= 0ll) { 1036a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return INVALID_OPERATION; 1037a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1038a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1039a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatAfterUs = repeatAfterUs; 1040a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1041a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return OK; 1042a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1043a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 104494ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 104594ee4b708acfa941581160b267afb79192b1d816Chong Zhang Mutex::Autolock autoLock(mMutex); 104694ee4b708acfa941581160b267afb79192b1d816Chong Zhang 104794ee4b708acfa941581160b267afb79192b1d816Chong Zhang if (mExecuting || maxGapUs <= 0ll) { 104894ee4b708acfa941581160b267afb79192b1d816Chong Zhang return INVALID_OPERATION; 104994ee4b708acfa941581160b267afb79192b1d816Chong Zhang } 105094ee4b708acfa941581160b267afb79192b1d816Chong Zhang 105194ee4b708acfa941581160b267afb79192b1d816Chong Zhang mMaxTimestampGapUs = maxGapUs; 105294ee4b708acfa941581160b267afb79192b1d816Chong Zhang 105394ee4b708acfa941581160b267afb79192b1d816Chong Zhang return OK; 105494ee4b708acfa941581160b267afb79192b1d816Chong Zhang} 105572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 105661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuangstatus_t GraphicBufferSource::setInputBufferTimeOffset(int64_t timeOffsetUs) { 105761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang Mutex::Autolock autoLock(mMutex); 105861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 105961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang // timeOffsetUs must be negative for adjustment. 106061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang if (timeOffsetUs >= 0ll) { 106161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return INVALID_OPERATION; 106261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 106361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 106461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang mInputBufferTimeOffsetUs = timeOffsetUs; 106561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return OK; 106661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang} 106761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 106837b2b389139ed638831e49708c947863eef631efRonghua Wustatus_t GraphicBufferSource::setMaxFps(float maxFps) { 106937b2b389139ed638831e49708c947863eef631efRonghua Wu Mutex::Autolock autoLock(mMutex); 107037b2b389139ed638831e49708c947863eef631efRonghua Wu 107137b2b389139ed638831e49708c947863eef631efRonghua Wu if (mExecuting) { 107237b2b389139ed638831e49708c947863eef631efRonghua Wu return INVALID_OPERATION; 107337b2b389139ed638831e49708c947863eef631efRonghua Wu } 107437b2b389139ed638831e49708c947863eef631efRonghua Wu 107537b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper = new FrameDropper(); 107637b2b389139ed638831e49708c947863eef631efRonghua Wu status_t err = mFrameDropper->setMaxFrameRate(maxFps); 107737b2b389139ed638831e49708c947863eef631efRonghua Wu if (err != OK) { 107837b2b389139ed638831e49708c947863eef631efRonghua Wu mFrameDropper.clear(); 107937b2b389139ed638831e49708c947863eef631efRonghua Wu return err; 108037b2b389139ed638831e49708c947863eef631efRonghua Wu } 108137b2b389139ed638831e49708c947863eef631efRonghua Wu 108237b2b389139ed638831e49708c947863eef631efRonghua Wu return OK; 108337b2b389139ed638831e49708c947863eef631efRonghua Wu} 108437b2b389139ed638831e49708c947863eef631efRonghua Wu 108572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 108672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mMutex); 108772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 108872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSkipFramesBeforeNs = 108972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 109072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 109172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1092dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnarstatus_t GraphicBufferSource::setTimeLapseConfig(const TimeLapseConfig &config) { 10932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang Mutex::Autolock autoLock(mMutex); 10942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1095dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar if (mExecuting || config.mTimePerFrameUs <= 0ll || config.mTimePerCaptureUs <= 0ll) { 10962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return INVALID_OPERATION; 10972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 10982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1099dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mTimePerFrameUs = config.mTimePerFrameUs; 1100dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mTimePerCaptureUs = config.mTimePerCaptureUs; 11012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 11022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return OK; 11032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang} 11042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 1105dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnarvoid GraphicBufferSource::setColorAspects(const ColorAspects &aspects) { 1106dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar Mutex::Autolock autoLock(mMutex); 1107dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar mColorAspects = aspects; 1108b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))", 1109b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mRange, asString(aspects.mRange), 1110b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mPrimaries, asString(aspects.mPrimaries), 1111b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 1112b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar aspects.mTransfer, asString(aspects.mTransfer)); 1113dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar} 1114dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar 1115a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber switch (msg->what()) { 1117a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber case kWhatRepeatLastFrame: 1118a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber { 1119a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber Mutex::Autolock autoLock(mMutex); 1120a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1121a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int32_t generation; 1122a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber CHECK(msg->findInt32("generation", &generation)); 1123a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1124a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (generation != mRepeatLastFrameGeneration) { 1125a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber // stale 1126a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1127a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1128a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1129a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (!mExecuting || mNumFramesAvailable > 0) { 1130a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1131a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1132a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 113337b2b389139ed638831e49708c947863eef631efRonghua Wu bool success = repeatLatestBuffer_l(); 1134a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1135a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber if (success) { 113637b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l SUCCESS"); 1137a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } else { 113837b2b389139ed638831e49708c947863eef631efRonghua Wu ALOGV("repeatLatestBuffer_l FAILURE"); 1139a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber mRepeatBufferDeferred = true; 1140a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber break; 1142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1144a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber default: 1145a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber TRESPASS(); 1146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber } 1147a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber} 1148a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1149f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden} // namespace android 1150