GraphicBufferSource.cpp revision a5750e0dad9e90f2195ce36f2c4457fa04b2b83e
1f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden/*
2f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Copyright (C) 2013 The Android Open Source Project
3f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
4f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
5f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * you may not use this file except in compliance with the License.
6f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * You may obtain a copy of the License at
7f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
8f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
9f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
10f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Unless required by applicable law or agreed to in writing, software
11f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
12f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * See the License for the specific language governing permissions and
14f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * limitations under the License.
15f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden */
16f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
17db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <inttypes.h>
18db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn
19f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#define LOG_TAG "GraphicBufferSource"
20ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden//#define LOG_NDEBUG 0
21f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <utils/Log.h>
22f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
235e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include "GraphicBufferSource.h"
24f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
25f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <OMX_Core.h>
26f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h>
27a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
295e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h>
30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h>
31f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
322475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza#include <inttypes.h>
332475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza
34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android {
35f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
36f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const bool EXTRA_CHECK = true;
37f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
38f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
39f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount) :
41f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mInitCheck(UNKNOWN_ERROR),
42f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mNodeInstance(nodeInstance),
43f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting(false),
44e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    mSuspended(false),
45f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mNumFramesAvailable(0),
46f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mEndOfStream(false),
47a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mEndOfStreamSent(false),
4894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mMaxTimestampGapUs(-1ll),
4994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mPrevOriginalTimeUs(-1ll),
5094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mPrevModifiedTimeUs(-1ll),
5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mSkipFramesBeforeNs(-1ll),
5284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    mRepeatAfterUs(-1ll),
53a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mRepeatLastFrameGeneration(0),
5494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mRepeatLastFrameTimestamp(-1ll),
55a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mLatestSubmittedBufferId(-1),
56a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mLatestSubmittedBufferFrameNum(0),
57a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mLatestSubmittedBufferUseCount(0),
582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mRepeatBufferDeferred(false),
592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mTimePerCaptureUs(-1ll),
602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mTimePerFrameUs(-1ll),
612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mPrevCaptureUs(-1ll),
622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mPrevFrameUs(-1ll) {
63f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    ALOGV("GraphicBufferSource w=%u h=%u c=%u",
650c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            bufferWidth, bufferHeight, bufferCount);
66f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
67f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferWidth == 0 || bufferHeight == 0) {
680c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight);
69f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        mInitCheck = BAD_VALUE;
70f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
71f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
72f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
730c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    String8 name("GraphicBufferSource");
740c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden
755205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
765205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mConsumer->setConsumerName(name);
775205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
785205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
79f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            GRALLOC_USAGE_HW_TEXTURE);
80f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
815205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount);
820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (mInitCheck != NO_ERROR) {
830c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden                bufferCount, mInitCheck);
850c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        return;
860c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
870c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden
88f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
89f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // reference once the ctor ends, as that would cause the refcount of 'this'
90f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
91f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that's what we create.
92910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian    wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this);
93910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian    sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
94f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
955205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mInitCheck = mConsumer->consumerConnect(proxy, false);
960c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (mInitCheck != NO_ERROR) {
97f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("Error connecting to BufferQueue: %s (%d)",
980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden                strerror(-mInitCheck), mInitCheck);
99f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
100f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
101f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
1020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    CHECK(mInitCheck == NO_ERROR);
103f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
104f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
105f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() {
106f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("~GraphicBufferSource");
1075205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    if (mConsumer != NULL) {
1085205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        status_t err = mConsumer->consumerDisconnect();
1090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        if (err != NO_ERROR) {
1100c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            ALOGW("consumerDisconnect failed: %d", err);
1110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        }
112f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
113f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::omxExecuting() {
116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
117a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("--> executing; avail=%zu, codec vec size=%zd",
118f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mNumFramesAvailable, mCodecBuffers.size());
119f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(!mExecuting);
120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = true;
121f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Start by loading up as many buffers as possible.  We want to do this,
123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // rather than just submit the first buffer, to avoid a degenerate case:
124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // if all BQ buffers arrive before we start executing, and we only submit
125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one here, the other BQ buffers will just sit until we get notified
126f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that the codec buffer has been released.  We'd then acquire and
127f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit a single additional buffer, repeatedly, never using more than
128f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one codec buffer simultaneously.  (We could instead try to submit
129f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // all BQ buffers whenever any codec buffer is freed, but if we get the
130f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // initial conditions right that will never be useful.)
1310c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    while (mNumFramesAvailable) {
1320c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        if (!fillCodecBuffer_l()) {
1330c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            ALOGV("stop load with frames available (codecAvail=%d)",
1340c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden                    isCodecBufferAvailable_l());
1350c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            break;
1360c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        }
137f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
138f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
139a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable);
140f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
141f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // If EOS has already been signaled, and there are no more frames to
142f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit, try to send EOS now as well.
143f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStream && mNumFramesAvailable == 0) {
144f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
145f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
147a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mRepeatAfterUs > 0ll && mLooper == NULL) {
148a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mReflector = new AHandlerReflector<GraphicBufferSource>(this);
149a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
150a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper = new ALooper;
151a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->registerHandler(mReflector);
152a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->start();
153a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
154a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (mLatestSubmittedBufferId >= 0) {
155a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            sp<AMessage> msg =
156a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                new AMessage(kWhatRepeatLastFrame, mReflector->id());
157a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
158a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            msg->setInt32("generation", ++mRepeatLastFrameGeneration);
159a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            msg->post(mRepeatAfterUs);
160a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
161a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
162f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
163f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
164ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Hubervoid GraphicBufferSource::omxIdle() {
165ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    ALOGV("omxIdle");
166ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
167ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    Mutex::Autolock autoLock(mMutex);
168ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
169ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    if (mExecuting) {
170ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        // We are only interested in the transition from executing->idle,
171ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        // not loaded->idle.
172892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber        mExecuting = false;
173ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    }
174ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber}
175ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
176ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid GraphicBufferSource::omxLoaded(){
177f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
178ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden    if (!mExecuting) {
179ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden        // This can happen if something failed very early.
180ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden        ALOGW("Dropped back down to Loaded without Executing");
181ba812e3b3ca0a0c9459fe29bbc211c9a73313b8bAndy McFadden    }
182f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
183a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mLooper != NULL) {
184a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->unregisterHandler(mReflector->id());
185a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mReflector.clear();
186a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
187a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->stop();
188a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper.clear();
189a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
190a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
191a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d",
192f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mNumFramesAvailable, mEndOfStream, mEndOfStreamSent);
193f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
194f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Codec is no longer executing.  Discard all codec-related state.
195f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mCodecBuffers.clear();
196f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries
197f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    //       are null; complain if not
198f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
199f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = false;
200f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
201f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
202f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
203f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
204f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
205f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting) {
206f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen -- buffers can only be allocated when
207f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // transitioning from "loaded" to "idle".
208f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("addCodecBuffer: buffer added while executing");
209f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
210f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
211f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
212db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn    ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p",
213f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header, header->nAllocLen, header->pBuffer);
214f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer codecBuffer;
215f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    codecBuffer.mHeader = header;
216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mCodecBuffers.add(codecBuffer);
217f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
218f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
219f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
220f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
221f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
222892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber    if (!mExecuting) {
223892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber        return;
224892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber    }
225f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
226f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int cbi = findMatchingCodecBuffer_l(header);
227f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
228f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen.
229f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header);
230f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
231f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
232f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
233db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn    ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p",
234f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header, header->nAllocLen, header->nFilledLen,
235f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header->pBuffer);
236f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
237f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
238f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // header->nFilledLen may not be the original value, so we can't compare
239f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that to zero to see of this was the EOS buffer.  Instead we just
240f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // see if the GraphicBuffer reference was null, which should only ever
241f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // happen for EOS.
242f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (codecBuffer.mGraphicBuffer == NULL) {
2435572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden        if (!(mEndOfStream && mEndOfStreamSent)) {
2445572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden            // This can happen when broken code sends us the same buffer
2455572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden            // twice in a row.
2465572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden            ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer "
2475572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden                    "(buffer emptied twice?)");
2485572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden        }
249f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No GraphicBuffer to deal with, no additional input or output is
250f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // expected, so just return.
251f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
252f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
253f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
254f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (EXTRA_CHECK) {
255f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Pull the graphic buffer handle back out of the buffer, and confirm
256f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // that it matches expectations.
257f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U8* data = header->pBuffer;
258f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        buffer_handle_t bufferHandle;
259f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t));
260f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (bufferHandle != codecBuffer.mGraphicBuffer->handle) {
261f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            // should never happen
262f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p",
263f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                    bufferHandle, codecBuffer.mGraphicBuffer->handle);
264f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            CHECK(!"codecBufferEmptied: mismatched buffer");
265f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
266f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
267f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
268f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Find matching entry in our cached copy of the BufferQueue slots.
269f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // If we find a match, release that slot.  If we don't, the BufferQueue
270f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // has dropped that GraphicBuffer, and there's nothing for us to release.
271d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    int id = codecBuffer.mBuf;
272d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    if (mBufferSlot[id] != NULL &&
273d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
274d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        ALOGV("cbi %d matches bq slot %d, handle=%p",
275d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                cbi, id, mBufferSlot[id]->handle);
276d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar
277a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (id == mLatestSubmittedBufferId) {
278a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            CHECK_GT(mLatestSubmittedBufferUseCount--, 0);
279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        } else {
2805205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza            mConsumer->releaseBuffer(id, codecBuffer.mFrameNumber,
281a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
282a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
283d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    } else {
284f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d",
285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                cbi);
286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
287f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
288f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Mark the codec buffer as available by clearing the GraphicBuffer ref.
289f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    codecBuffer.mGraphicBuffer = NULL;
290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mNumFramesAvailable) {
292f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Fill this codec buffer.
2930c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        CHECK(!mEndOfStreamSent);
294a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("buffer freed, %zu frames avail (eos=%d)",
2950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden                mNumFramesAvailable, mEndOfStream);
296f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else if (mEndOfStream) {
298f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No frames available, but EOS is pending, so use this buffer to
299f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // send that.
300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("buffer freed, EOS pending");
301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
302a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    } else if (mRepeatBufferDeferred) {
303a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        bool success = repeatLatestSubmittedBuffer_l();
304a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (success) {
305a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGV("deferred repeatLatestSubmittedBuffer_l SUCCESS");
306a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        } else {
307a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGV("deferred repeatLatestSubmittedBuffer_l FAILURE");
308a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
309a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mRepeatBufferDeferred = false;
310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
311a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
312f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return;
313f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
314f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
31594ee4b708acfa941581160b267afb79192b1d816Chong Zhangvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) {
31694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    Mutex::Autolock autoLock(mMutex);
31794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
31894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    if (mMaxTimestampGapUs > 0ll
31994ee4b708acfa941581160b267afb79192b1d816Chong Zhang            && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
32094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp);
32194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (index >= 0) {
32294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGV("OUT timestamp: %lld -> %lld",
323a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                    static_cast<long long>(header->nTimeStamp),
324a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                    static_cast<long long>(mOriginalTimeUs[index]));
32594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            header->nTimeStamp = mOriginalTimeUs[index];
32694ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mOriginalTimeUs.removeItemsAt(index);
32794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        } else {
32894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            // giving up the effort as encoder doesn't appear to preserve pts
32994ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGW("giving up limiting timestamp gap (pts = %lld)",
33094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    header->nTimeStamp);
33194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mMaxTimestampGapUs = -1ll;
33294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
33394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) {
33494ee4b708acfa941581160b267afb79192b1d816Chong Zhang            // something terribly wrong must have happened, giving up...
335a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGE("mOriginalTimeUs has too many entries (%zu)",
33694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    mOriginalTimeUs.size());
33794ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mMaxTimestampGapUs = -1ll;
33894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
33994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
34094ee4b708acfa941581160b267afb79192b1d816Chong Zhang}
34194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
342e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Hubervoid GraphicBufferSource::suspend(bool suspend) {
343e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    Mutex::Autolock autoLock(mMutex);
344e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
345e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (suspend) {
346e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        mSuspended = true;
347e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
348e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        while (mNumFramesAvailable > 0) {
349e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            BufferQueue::BufferItem item;
3505205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza            status_t err = mConsumer->acquireBuffer(&item, 0);
351e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
352e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
353e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                // shouldn't happen.
354e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                ALOGW("suspend: frame was not available");
355e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                break;
356e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            } else if (err != OK) {
357e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                ALOGW("suspend: acquireBuffer returned err=%d", err);
358e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                break;
359e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            }
360e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
361e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            --mNumFramesAvailable;
362e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
3635205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza            mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
364e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
365e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        }
366e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        return;
367e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
368e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
369e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    mSuspended = false;
370a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
371a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) {
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (repeatLatestSubmittedBuffer_l()) {
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l SUCCESS");
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatBufferDeferred = false;
376a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        } else {
377a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l FAILURE");
378a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
379a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
380e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber}
381e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
3820c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() {
383f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mExecuting && mNumFramesAvailable > 0);
3840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden
385e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (mSuspended) {
386e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        return false;
387e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
388e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
389f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int cbi = findAvailableCodecBuffer_l();
390f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
391f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No buffers available, bail.
392a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu",
393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                mNumFramesAvailable);
3940c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        return false;
3950c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
397a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu",
3980c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            mNumFramesAvailable);
3990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    BufferQueue::BufferItem item;
4005205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    status_t err = mConsumer->acquireBuffer(&item, 0);
4010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
4020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        // shouldn't happen
4030c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGW("fillCodecBuffer_l: frame was not available");
4040c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        return false;
4050c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    } else if (err != OK) {
4060c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        // now what? fake end-of-stream?
4070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err);
4080c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        return false;
4090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
4110c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    mNumFramesAvailable--;
412f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
4130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    // Wait for it to become available.
414d76442421eadfa73f2f3a9e50f6caf65b0dd1ce9Mathias Agopian    err = item.mFence->waitForever("GraphicBufferSource::fillCodecBuffer_l");
4150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (err != OK) {
4160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGW("failed to wait for buffer fence: %d", err);
4170c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        // keep going
4180c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
4200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    // If this is the first time we're seeing this buffer, add it to our
4210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    // slot table.
4220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (item.mGraphicBuffer != NULL) {
4230c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
4240c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        mBufferSlot[item.mBuf] = item.mGraphicBuffer;
4250c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
4260c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden
42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    err = UNKNOWN_ERROR;
42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // only submit sample if start time is unspecified, or sample
43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // is queued after the specified start time
43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) {
43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if start time is set, offset time stamp by start time
43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mSkipFramesBeforeNs > 0) {
43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            item.mTimestamp -= mSkipFramesBeforeNs;
43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = submitBuffer_l(item, cbi);
43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4390c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (err != OK) {
4400c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
4415205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
442d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
4430c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    } else {
4440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
445a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        setLatestSubmittedBuffer_l(item);
446a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
447a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
448a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    return true;
449a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
450a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
451a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberbool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
452a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    CHECK(mExecuting && mNumFramesAvailable == 0);
453a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
454a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mLatestSubmittedBufferId < 0 || mSuspended) {
455a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
456a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
457bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden    if (mBufferSlot[mLatestSubmittedBufferId] == NULL) {
458bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        // This can happen if the remote side disconnects, causing
459bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        // onBuffersReleased() to NULL out our copy of the slots.  The
460bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        // buffer is gone, so we have nothing to show.
461bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        //
462bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        // To be on the safe side we try to release the buffer.
463bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        ALOGD("repeatLatestSubmittedBuffer_l: slot was NULL");
4645205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        mConsumer->releaseBuffer(
465bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden                mLatestSubmittedBufferId,
466bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden                mLatestSubmittedBufferFrameNum,
467bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden                EGL_NO_DISPLAY,
468bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden                EGL_NO_SYNC_KHR,
469bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden                Fence::NO_FENCE);
470bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        mLatestSubmittedBufferId = -1;
471bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        mLatestSubmittedBufferFrameNum = 0;
472bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        return false;
473bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden    }
474a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
475a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    int cbi = findAvailableCodecBuffer_l();
476a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (cbi < 0) {
477a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        // No buffers available, bail.
478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        ALOGV("repeatLatestSubmittedBuffer_l: no codec buffers.");
479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
481a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
482a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    BufferQueue::BufferItem item;
483a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    item.mBuf = mLatestSubmittedBufferId;
484a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    item.mFrameNumber = mLatestSubmittedBufferFrameNum;
48594ee4b708acfa941581160b267afb79192b1d816Chong Zhang    item.mTimestamp = mRepeatLastFrameTimestamp;
486a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
487a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    status_t err = submitBuffer_l(item, cbi);
488a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
489a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err != OK) {
490a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
491f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
493a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    ++mLatestSubmittedBufferUseCount;
494a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
49594ee4b708acfa941581160b267afb79192b1d816Chong Zhang    /* repeat last frame up to kRepeatLastFrameCount times.
49694ee4b708acfa941581160b267afb79192b1d816Chong Zhang     * in case of static scene, a single repeat might not get rid of encoder
49794ee4b708acfa941581160b267afb79192b1d816Chong Zhang     * ghosting completely, refresh a couple more times to get better quality
49894ee4b708acfa941581160b267afb79192b1d816Chong Zhang     */
49994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    if (--mRepeatLastFrameCount > 0) {
50094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
50194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
50294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (mReflector != NULL) {
50394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
50494ee4b708acfa941581160b267afb79192b1d816Chong Zhang            msg->setInt32("generation", ++mRepeatLastFrameGeneration);
50594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            msg->post(mRepeatAfterUs);
50694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
50794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
50894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5090c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    return true;
510f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
511f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
512a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::setLatestSubmittedBuffer_l(
513a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        const BufferQueue::BufferItem &item) {
514a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    ALOGV("setLatestSubmittedBuffer_l");
515a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
516a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mLatestSubmittedBufferId >= 0) {
517a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (mLatestSubmittedBufferUseCount == 0) {
5185205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza            mConsumer->releaseBuffer(
519a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    mLatestSubmittedBufferId,
520a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    mLatestSubmittedBufferFrameNum,
521a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    EGL_NO_DISPLAY,
522a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    EGL_NO_SYNC_KHR,
523a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    Fence::NO_FENCE);
524a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
525a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
526a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
527a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mLatestSubmittedBufferId = item.mBuf;
528a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mLatestSubmittedBufferFrameNum = item.mFrameNumber;
52994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
53094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
531a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mLatestSubmittedBufferUseCount = 1;
532a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mRepeatBufferDeferred = false;
53394ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mRepeatLastFrameCount = kRepeatLastFrameCount;
534a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
535a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mReflector != NULL) {
536a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
537a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        msg->setInt32("generation", ++mRepeatLastFrameGeneration);
538a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        msg->post(mRepeatAfterUs);
539a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
540a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
541a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
542ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenstatus_t GraphicBufferSource::signalEndOfInputStream() {
543f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
544a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d",
545ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden            mExecuting, mNumFramesAvailable, mEndOfStream);
546ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
547ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    if (mEndOfStream) {
548ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        ALOGE("EOS was already signaled");
549ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        return INVALID_OPERATION;
550ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    }
551f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
552f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Set the end-of-stream flag.  If no frames are pending from the
553f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // BufferQueue, and a codec buffer is available, and we're executing,
554f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // we initiate the EOS from here.  Otherwise, we'll let
555f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // codecBufferEmptied() (or omxExecuting) do it.
556f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    //
557f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Note: if there are no pending frames and all codec buffers are
558f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // available, we *must* submit the EOS from here or we'll just
559f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // stall since no future events are expected.
560f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mEndOfStream = true;
561f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
562f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting && mNumFramesAvailable == 0) {
563f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
564f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
565ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
566ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    return OK;
567f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
568f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
56994ee4b708acfa941581160b267afb79192b1d816Chong Zhangint64_t GraphicBufferSource::getTimestamp(const BufferQueue::BufferItem &item) {
57094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    int64_t timeUs = item.mTimestamp / 1000;
57194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (mTimePerCaptureUs > 0ll) {
5732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        // Time lapse or slow motion mode
5742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (mPrevCaptureUs < 0ll) {
5752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            // first capture
5762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mPrevCaptureUs = timeUs;
5772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mPrevFrameUs = timeUs;
5782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        } else {
5792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            // snap to nearest capture point
5802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs)
5812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    / mTimePerCaptureUs;
5822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            if (nFrames <= 0) {
5832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                // skip this frame as it's too close to previous capture
584a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
5852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                return -1;
5862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            }
5872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs;
5882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mPrevFrameUs += mTimePerFrameUs * nFrames;
5892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
5902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        ALOGV("timeUs %lld, captureUs %lld, frameUs %lld",
592a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(timeUs),
593a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(mPrevCaptureUs),
594a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(mPrevFrameUs));
5952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        return mPrevFrameUs;
5972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    } else if (mMaxTimestampGapUs > 0ll) {
59894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        /* Cap timestamp gap between adjacent frames to specified max
59994ee4b708acfa941581160b267afb79192b1d816Chong Zhang         *
60094ee4b708acfa941581160b267afb79192b1d816Chong Zhang         * In the scenario of cast mirroring, encoding could be suspended for
60194ee4b708acfa941581160b267afb79192b1d816Chong Zhang         * prolonged periods. Limiting the pts gap to workaround the problem
60294ee4b708acfa941581160b267afb79192b1d816Chong Zhang         * where encoder's rate control logic produces huge frames after a
60394ee4b708acfa941581160b267afb79192b1d816Chong Zhang         * long period of suspension.
60494ee4b708acfa941581160b267afb79192b1d816Chong Zhang         */
60594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
60694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        int64_t originalTimeUs = timeUs;
60794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (mPrevOriginalTimeUs >= 0ll) {
60894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            if (originalTimeUs < mPrevOriginalTimeUs) {
60994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                // Drop the frame if it's going backward in time. Bad timestamp
61094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                // could disrupt encoder's rate control completely.
611b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang                ALOGW("Dropping frame that's going backward in time");
61294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                return -1;
61394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            }
61494ee4b708acfa941581160b267afb79192b1d816Chong Zhang            int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
61594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            timeUs = (timestampGapUs < mMaxTimestampGapUs ?
61694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
61794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
61894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        mPrevOriginalTimeUs = originalTimeUs;
61994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        mPrevModifiedTimeUs = timeUs;
62094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        mOriginalTimeUs.add(timeUs, originalTimeUs);
621a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("IN  timestamp: %lld -> %lld",
622a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            static_cast<long long>(originalTimeUs),
623a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            static_cast<long long>(timeUs));
62494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
62594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
62694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    return timeUs;
62794ee4b708acfa941581160b267afb79192b1d816Chong Zhang}
62894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
629d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(
630d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        const BufferQueue::BufferItem &item, int cbi) {
631f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("submitBuffer_l cbi=%d", cbi);
632b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang
633b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang    int64_t timeUs = getTimestamp(item);
634b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang    if (timeUs < 0ll) {
635b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang        return UNKNOWN_ERROR;
636b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang    }
637b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang
638f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
639d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf];
640d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    codecBuffer.mBuf = item.mBuf;
641d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    codecBuffer.mFrameNumber = item.mFrameNumber;
642f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
643f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
644f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t));
645f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_U8* data = header->pBuffer;
646f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const OMX_U32 type = kMetadataBufferTypeGrallocSource;
647f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle;
648f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    memcpy(data, &type, 4);
649f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    memcpy(data + 4, &handle, sizeof(buffer_handle_t));
650f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
651f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err = mNodeInstance->emptyDirectBuffer(header, 0,
652f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME,
65394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            timeUs);
654f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
655f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err);
656f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        codecBuffer.mGraphicBuffer = NULL;
657f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
658f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
659f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
660f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p",
661f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            header, header->pBuffer, handle);
662f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
663f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
664f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
665f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() {
666f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mEndOfStream);
667f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStreamSent) {
668f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("EOS already sent");
669f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
670f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
671f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
672f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    int cbi = findAvailableCodecBuffer_l();
673f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
674f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("submitEndOfInputStream_l: no codec buffers available");
675f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
676f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
677f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
678f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // We reject any additional incoming graphic buffers, so there's no need
679f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as
680f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // in-use.
681f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
682f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
683f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
684f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (EXTRA_CHECK) {
685f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Guard against implementations that don't check nFilledLen.
686f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        size_t fillLen = 4 + sizeof(buffer_handle_t);
687f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        CHECK(header->nAllocLen >= fillLen);
688f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U8* data = header->pBuffer;
689f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        memset(data, 0xcd, fillLen);
690f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
691f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
692f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    uint64_t timestamp = 0; // does this matter?
693f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
694f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0,
695f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
696f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            timestamp);
697f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
698f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
699f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else {
700f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d",
701f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                header, cbi);
7020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        mEndOfStreamSent = true;
703f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
704f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
705f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
706f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findAvailableCodecBuffer_l() {
707f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mCodecBuffers.size() > 0);
708f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
709f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
710f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (mCodecBuffers[i].mGraphicBuffer == NULL) {
711f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return i;
712f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
713f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
714f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return -1;
715f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
716f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
717f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenint GraphicBufferSource::findMatchingCodecBuffer_l(
718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        const OMX_BUFFERHEADERTYPE* header) {
719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
720f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (mCodecBuffers[i].mHeader == header) {
721f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return i;
722f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
723f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
724f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return -1;
725f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
726f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
727f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
728f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onFrameAvailable() {
729f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
730f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
731a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("onFrameAvailable exec=%d avail=%zu",
7320c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            mExecuting, mNumFramesAvailable);
733f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
734e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (mEndOfStream || mSuspended) {
735e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        if (mEndOfStream) {
736e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            // This should only be possible if a new buffer was queued after
737e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            // EOS was signaled, i.e. the app is misbehaving.
738e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
739e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            ALOGW("onFrameAvailable: EOS is set, ignoring frame");
740e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        } else {
741e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            ALOGV("onFrameAvailable: suspended, ignoring frame");
742e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        }
743f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
744f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        BufferQueue::BufferItem item;
7455205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        status_t err = mConsumer->acquireBuffer(&item, 0);
746f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if (err == OK) {
74749270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang            // If this is the first time we're seeing this buffer, add it to our
74849270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang            // slot table.
74949270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang            if (item.mGraphicBuffer != NULL) {
7502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf);
75149270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang                mBufferSlot[item.mBuf] = item.mGraphicBuffer;
75249270665e7a20cd120724fc388da8b166ff0b4f1Chong Zhang            }
7535205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza            mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
754d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
755f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
756f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
757f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mNumFramesAvailable++;
760f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
761a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mRepeatBufferDeferred = false;
762a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    ++mRepeatLastFrameGeneration;
763a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
764f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting) {
765f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
766f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
767f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
768f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
769f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
770f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() {
771f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock lock(mMutex);
772f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
7732475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza    uint64_t slotMask;
7745205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) {
775f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("onBuffersReleased: unable to get released buffer set");
7762475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza        slotMask = 0xffffffffffffffffULL;
777f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
778f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
7792475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza    ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask);
780f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
781f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
782f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if ((slotMask & 0x01) != 0) {
783f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mBufferSlot[i] = NULL;
784f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
785f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        slotMask >>= 1;
786f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
787f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
788f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
7898dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback
7908dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() {
7918dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall    ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
7928dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall}
7938dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall
794a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(
795a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        int64_t repeatAfterUs) {
796a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    Mutex::Autolock autoLock(mMutex);
797a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
798a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mExecuting || repeatAfterUs <= 0ll) {
799a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return INVALID_OPERATION;
800a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
801a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
802a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mRepeatAfterUs = repeatAfterUs;
803a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
804a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    return OK;
805a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
806a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
80794ee4b708acfa941581160b267afb79192b1d816Chong Zhangstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) {
80894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    Mutex::Autolock autoLock(mMutex);
80994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
81094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    if (mExecuting || maxGapUs <= 0ll) {
81194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        return INVALID_OPERATION;
81294ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
81394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
81494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    mMaxTimestampGapUs = maxGapUs;
81594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
81694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    return OK;
81794ee4b708acfa941581160b267afb79192b1d816Chong Zhang}
81872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
81972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) {
82072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    Mutex::Autolock autoLock(mMutex);
82172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
82272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mSkipFramesBeforeNs =
82372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
82472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
82572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhangstatus_t GraphicBufferSource::setTimeLapseUs(int64_t* data) {
8272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    Mutex::Autolock autoLock(mMutex);
8282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
8292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) {
8302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        return INVALID_OPERATION;
8312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
8322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
8332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mTimePerFrameUs = data[0];
8342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mTimePerCaptureUs = data[1];
8352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
8362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    return OK;
8372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang}
8382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
839a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
840a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    switch (msg->what()) {
841a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        case kWhatRepeatLastFrame:
842a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        {
843a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            Mutex::Autolock autoLock(mMutex);
844a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
845a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            int32_t generation;
846a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            CHECK(msg->findInt32("generation", &generation));
847a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
848a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (generation != mRepeatLastFrameGeneration) {
849a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                // stale
850a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                break;
851a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
852a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
853a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (!mExecuting || mNumFramesAvailable > 0) {
854a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                break;
855a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
856a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
857a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            bool success = repeatLatestSubmittedBuffer_l();
858a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
859a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (success) {
860a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                ALOGV("repeatLatestSubmittedBuffer_l SUCCESS");
861a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            } else {
862a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                ALOGV("repeatLatestSubmittedBuffer_l FAILURE");
863a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mRepeatBufferDeferred = true;
864a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
865a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            break;
866a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
867a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
868a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        default:
869a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            TRESPASS();
870a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
871a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
872a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
873f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}  // namespace android
874