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