GraphicBufferSource.cpp revision cf49a51ff59c3cd228d178d23252ac0d39d5a893
1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com/*
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org * Copyright (C) 2013 The Android Open Source Project
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org *
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * you may not use this file except in compliance with the License.
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * You may obtain a copy of the License at
7e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org *
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *      http://www.apache.org/licenses/LICENSE-2.0
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * Unless required by applicable law or agreed to in writing, software
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * See the License for the specific language governing permissions and
144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org * limitations under the License.
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org */
164b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
17fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#define LOG_TAG "GraphicBufferSource"
184b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org//#define LOG_NDEBUG 0
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include <utils/Log.h>
204b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "GraphicBufferSource.h"
224b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
2312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include <OMX_Core.h>
2412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include <media/stagefright/foundation/ADebug.h>
25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include <media/stagefright/foundation/AMessage.h>
264b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include <media/hardware/MetadataBufferType.h>
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include <ui/GraphicBuffer.h>
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace android {
31975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
32975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgstatic const bool EXTRA_CHECK = true;
33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgGraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount) :
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mInitCheck(UNKNOWN_ERROR),
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mNodeInstance(nodeInstance),
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mExecuting(false),
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mSuspended(false),
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mNumFramesAvailable(0),
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mEndOfStream(false),
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mEndOfStreamSent(false),
4409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    mRepeatAfterUs(-1ll),
45e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    mMaxTimestampGapUs(-1ll),
46750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    mPrevOriginalTimeUs(-1ll),
4709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    mPrevModifiedTimeUs(-1ll),
4809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    mRepeatLastFrameGeneration(0),
4909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    mRepeatLastFrameTimestamp(-1ll),
507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    mLatestSubmittedBufferId(-1),
517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    mLatestSubmittedBufferFrameNum(0),
527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    mLatestSubmittedBufferUseCount(0),
537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    mRepeatBufferDeferred(false) {
547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    ALOGV("GraphicBufferSource w=%u h=%u c=%u",
567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org            bufferWidth, bufferHeight, bufferCount);
577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    if (bufferWidth == 0 || bufferHeight == 0) {
597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight);
601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        mInitCheck = BAD_VALUE;
61e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        return;
62fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
63fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
64fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    String8 name("GraphicBufferSource");
65fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
66fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    mBufferQueue = new BufferQueue();
67fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    mBufferQueue->setConsumerName(name);
68fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    mBufferQueue->setDefaultBufferSize(bufferWidth, bufferHeight);
69b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
70fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            GRALLOC_USAGE_HW_TEXTURE);
71fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
72fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    mInitCheck = mBufferQueue->setMaxAcquiredBufferCount(bufferCount);
73fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (mInitCheck != NO_ERROR) {
74fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
75fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                bufferCount, mInitCheck);
76fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        return;
77fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
78fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
79fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
80fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // reference once the ctor ends, as that would cause the refcount of 'this'
81fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
82fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // that's what we create.
83fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this);
84fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
85fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
86fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    mInitCheck = mBufferQueue->consumerConnect(proxy, false);
87fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (mInitCheck != NO_ERROR) {
88e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        ALOGE("Error connecting to BufferQueue: %s (%d)",
89fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                strerror(-mInitCheck), mInitCheck);
90fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        return;
91fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
92fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
93fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CHECK(mInitCheck == NO_ERROR);
94a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
95fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
96fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgGraphicBufferSource::~GraphicBufferSource() {
97fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    ALOGV("~GraphicBufferSource");
98fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (mBufferQueue != NULL) {
99a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        status_t err = mBufferQueue->consumerDisconnect();
100fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (err != NO_ERROR) {
101fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            ALOGW("consumerDisconnect failed: %d", err);
102fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
103fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
104fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
105fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid GraphicBufferSource::omxExecuting() {
107fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Mutex::Autolock autoLock(mMutex);
108fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    ALOGV("--> executing; avail=%d, codec vec size=%zd",
109fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            mNumFramesAvailable, mCodecBuffers.size());
1101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CHECK(!mExecuting);
111d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    mExecuting = true;
112d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
113d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // Start by loading up as many buffers as possible.  We want to do this,
114fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // rather than just submit the first buffer, to avoid a degenerate case:
115fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // if all BQ buffers arrive before we start executing, and we only submit
116fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // one here, the other BQ buffers will just sit until we get notified
117fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // that the codec buffer has been released.  We'd then acquire and
118fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // submit a single additional buffer, repeatedly, never using more than
119fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // one codec buffer simultaneously.  (We could instead try to submit
120fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // all BQ buffers whenever any codec buffer is freed, but if we get the
1211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // initial conditions right that will never be useful.)
122fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    while (mNumFramesAvailable) {
123fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (!fillCodecBuffer_l()) {
124fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            ALOGV("stop load with frames available (codecAvail=%d)",
125fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                    isCodecBufferAvailable_l());
126fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            break;
127fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
128fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
129fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
130fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    ALOGV("done loading initial frames, avail=%d", mNumFramesAvailable);
131fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
132fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // If EOS has already been signaled, and there are no more frames to
133fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // submit, try to send EOS now as well.
134fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (mEndOfStream && mNumFramesAvailable == 0) {
135fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        submitEndOfInputStream_l();
136fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
137fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
138fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (mRepeatAfterUs > 0ll && mLooper == NULL) {
139fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mReflector = new AHandlerReflector<GraphicBufferSource>(this);
140fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
141fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mLooper = new ALooper;
142fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mLooper->registerHandler(mReflector);
143fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mLooper->start();
144fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
145fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        if (mLatestSubmittedBufferId >= 0) {
146fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            sp<AMessage> msg =
147fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                new AMessage(kWhatRepeatLastFrame, mReflector->id());
148fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
149fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            msg->setInt32("generation", ++mRepeatLastFrameGeneration);
150fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            msg->post(mRepeatAfterUs);
151fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        }
152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
154a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid GraphicBufferSource::omxIdle() {
156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ALOGV("omxIdle");
157fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
158fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Mutex::Autolock autoLock(mMutex);
159fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
160fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (mExecuting) {
1615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        // We are only interested in the transition from executing->idle,
162fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        // not loaded->idle.
163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mExecuting = false;
164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
166fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
167fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid GraphicBufferSource::omxLoaded(){
168fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Mutex::Autolock autoLock(mMutex);
169fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (!mExecuting) {
1705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        // This can happen if something failed very early.
171fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        ALOGW("Dropped back down to Loaded without Executing");
1725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    }
173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mLooper != NULL) {
175fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mLooper->unregisterHandler(mReflector->id());
176fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mReflector.clear();
177fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
178fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mLooper->stop();
1795f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        mLooper.clear();
180fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ALOGV("--> loaded; avail=%d eos=%d eosSent=%d",
183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            mNumFramesAvailable, mEndOfStream, mEndOfStreamSent);
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Codec is no longer executing.  Discard all codec-related state.
186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mCodecBuffers.clear();
187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    //       are null; complain if not
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mExecuting = false;
191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Mutex::Autolock autoLock(mMutex);
195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mExecuting) {
1975f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        // This should never happen -- buffers can only be allocated when
198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // transitioning from "loaded" to "idle".
1995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        ALOGE("addCodecBuffer: buffer added while executing");
200fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        return;
201fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
202fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ALOGV("addCodecBuffer h=%p size=%lu p=%p",
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            header, header->nAllocLen, header->pBuffer);
205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    CodecBuffer codecBuffer;
206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    codecBuffer.mHeader = header;
207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mCodecBuffers.add(codecBuffer);
208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2098f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
2118f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    Mutex::Autolock autoLock(mMutex);
2128f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    if (!mExecuting) {
2148f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        return;
2158f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
2168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    int cbi = findMatchingCodecBuffer_l(header);
2188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    if (cbi < 0) {
2198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        // This should never happen.
2208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header);
2218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        return;
2228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
2238f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2248f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    ALOGV("codecBufferEmptied h=%p size=%lu filled=%lu p=%p",
225471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            header, header->nAllocLen, header->nFilledLen,
226471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            header->pBuffer);
227471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
228471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
229471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // header->nFilledLen may not be the original value, so we can't compare
230471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // that to zero to see of this was the EOS buffer.  Instead we just
231471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // see if the GraphicBuffer reference was null, which should only ever
232471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // happen for EOS.
233471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (codecBuffer.mGraphicBuffer == NULL) {
234471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        if (!(mEndOfStream && mEndOfStreamSent)) {
235471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            // This can happen when broken code sends us the same buffer
236471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            // twice in a row.
237471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer "
238471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                    "(buffer emptied twice?)");
2398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        }
2408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        // No GraphicBuffer to deal with, no additional input or output is
2418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        // expected, so just return.
2428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        return;
2438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
2448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    if (EXTRA_CHECK) {
2468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        // Pull the graphic buffer handle back out of the buffer, and confirm
2478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        // that it matches expectations.
2488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        OMX_U8* data = header->pBuffer;
2498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        buffer_handle_t bufferHandle;
2508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t));
2518f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        if (bufferHandle != codecBuffer.mGraphicBuffer->handle) {
2528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org            // should never happen
2538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org            ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p",
2548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                    bufferHandle, codecBuffer.mGraphicBuffer->handle);
2558f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org            CHECK(!"codecBufferEmptied: mismatched buffer");
2568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        }
2578f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
2588f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    // Find matching entry in our cached copy of the BufferQueue slots.
2608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    // If we find a match, release that slot.  If we don't, the BufferQueue
261fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // has dropped that GraphicBuffer, and there's nothing for us to release.
2625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    int id = codecBuffer.mBuf;
263fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (mBufferSlot[id] != NULL &&
264fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("cbi %d matches bq slot %d, handle=%p",
266c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                cbi, id, mBufferSlot[id]->handle);
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (id == mLatestSubmittedBufferId) {
2695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org            CHECK_GT(mLatestSubmittedBufferUseCount--, 0);
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        } else {
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            mBufferQueue->releaseBuffer(id, codecBuffer.mFrameNumber,
272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
273fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        }
2745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    } else {
275fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d",
276fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                cbi);
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Mark the codec buffer as available by clearing the GraphicBuffer ref.
280c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    codecBuffer.mGraphicBuffer = NULL;
2815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mNumFramesAvailable) {
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // Fill this codec buffer.
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        CHECK(!mEndOfStreamSent);
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("buffer freed, %d frames avail (eos=%d)",
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                mNumFramesAvailable, mEndOfStream);
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        fillCodecBuffer_l();
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else if (mEndOfStream) {
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // No frames available, but EOS is pending, so use this buffer to
290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // send that.
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("buffer freed, EOS pending");
292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        submitEndOfInputStream_l();
293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else if (mRepeatBufferDeferred) {
294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        bool success = repeatLatestSubmittedBuffer_l();
295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (success) {
296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            ALOGV("deferred repeatLatestSubmittedBuffer_l SUCCESS");
297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        } else {
298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            ALOGV("deferred repeatLatestSubmittedBuffer_l FAILURE");
299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mRepeatBufferDeferred = false;
301fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
303fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return;
304fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
305fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
306fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) {
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Mutex::Autolock autoLock(mMutex);
308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
309c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (mMaxTimestampGapUs > 0ll
310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp);
312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (index >= 0) {
313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            ALOGV("OUT timestamp: %lld -> %lld",
314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    header->nTimeStamp, mOriginalTimeUs[index]);
315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            header->nTimeStamp = mOriginalTimeUs[index];
3163847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            mOriginalTimeUs.removeItemsAt(index);
3173847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        } else {
3183847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            // giving up the effort as encoder doesn't appear to preserve pts
3193847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            ALOGW("giving up limiting timestamp gap (pts = %lld)",
3203847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                    header->nTimeStamp);
321ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org            mMaxTimestampGapUs = -1ll;
322ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        }
323ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) {
324ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org            // something terribly wrong must have happened, giving up...
325ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org            ALOGE("mOriginalTimeUs has too many entries (%d)",
326ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org                    mOriginalTimeUs.size());
327ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org            mMaxTimestampGapUs = -1ll;
328ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        }
329ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    }
330c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org}
331812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
332fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid GraphicBufferSource::suspend(bool suspend) {
333812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Mutex::Autolock autoLock(mMutex);
334812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
335812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    if (suspend) {
336812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        mSuspended = true;
337812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
338812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        while (mNumFramesAvailable > 0) {
339662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org            BufferQueue::BufferItem item;
340662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org            status_t err = mBufferQueue->acquireBuffer(&item, 0);
341662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
342662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org            if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
343662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                // shouldn't happen.
344662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                ALOGW("suspend: frame was not available");
345662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                break;
346662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org            } else if (err != OK) {
347662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                ALOGW("suspend: acquireBuffer returned err=%d", err);
348662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                break;
349662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org            }
350662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
351c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org            --mNumFramesAvailable;
352837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
353837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org            mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
354837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
355837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        }
356837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        return;
357837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    }
358837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
359837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    mSuspended = false;
360837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
361837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) {
3623847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        if (repeatLatestSubmittedBuffer_l()) {
3633847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l SUCCESS");
3643847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3653847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            mRepeatBufferDeferred = false;
3663847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        } else {
3673847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            ALOGV("suspend/deferred repeatLatestSubmittedBuffer_l FAILURE");
3683847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        }
3693847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
3703847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com}
3713847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3723847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.combool GraphicBufferSource::fillCodecBuffer_l() {
373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CHECK(mExecuting && mNumFramesAvailable > 0);
374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mSuspended) {
376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return false;
3773847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
3783847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3793847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    int cbi = findAvailableCodecBuffer_l();
3803847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    if (cbi < 0) {
381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // No buffers available, bail.
382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("fillCodecBuffer_l: no codec buffers, avail now %d",
383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                mNumFramesAvailable);
3843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        return false;
3853847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
3863847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3873847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%d",
3883847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com            mNumFramesAvailable);
3893847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    BufferQueue::BufferItem item;
3903847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    status_t err = mBufferQueue->acquireBuffer(&item, 0);
3913847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
3923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        // shouldn't happen
3933847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        ALOGW("fillCodecBuffer_l: frame was not available");
3943847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        return false;
395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else if (err != OK) {
3963847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        // now what? fake end-of-stream?
3973847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err);
3983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        return false;
399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
4003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
4013847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    mNumFramesAvailable--;
4023847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
4033847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    // Wait for it to become available.
4043847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    err = item.mFence->waitForever("GraphicBufferSource::fillCodecBuffer_l");
4057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    if (err != OK) {
4067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        ALOGW("failed to wait for buffer fence: %d", err);
4073847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        // keep going
4083847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
4093847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
4103847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    // If this is the first time we're seeing this buffer, add it to our
4113847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    // slot table.
412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (item.mGraphicBuffer != NULL) {
413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mBufferSlot[item.mBuf] = item.mGraphicBuffer;
4153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    err = submitBuffer_l(item, cbi);
418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (err != OK) {
41931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org        ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        setLatestSubmittedBuffer_l(item);
425e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    }
426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return true;
428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgbool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CHECK(mExecuting && mNumFramesAvailable == 0);
432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mLatestSubmittedBufferId < 0 || mSuspended) {
434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return false;
435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mBufferSlot[mLatestSubmittedBufferId] == NULL) {
437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // This can happen if the remote side disconnects, causing
438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // onBuffersReleased() to NULL out our copy of the slots.  The
439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // buffer is gone, so we have nothing to show.
440dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org        //
441dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org        // To be on the safe side we try to release the buffer.
442dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org        ALOGD("repeatLatestSubmittedBuffer_l: slot was NULL");
443dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org        mBufferQueue->releaseBuffer(
444dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org                mLatestSubmittedBufferId,
445dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org                mLatestSubmittedBufferFrameNum,
446dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org                EGL_NO_DISPLAY,
447dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org                EGL_NO_SYNC_KHR,
448dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org                Fence::NO_FENCE);
449dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org        mLatestSubmittedBufferId = -1;
450dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org        mLatestSubmittedBufferFrameNum = 0;
451d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org        return false;
452d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    }
453d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
454d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    int cbi = findAvailableCodecBuffer_l();
455d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    if (cbi < 0) {
4562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        // No buffers available, bail.
457255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        ALOGV("repeatLatestSubmittedBuffer_l: no codec buffers.");
458d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org        return false;
459d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    }
460d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
461d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    BufferQueue::BufferItem item;
462d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    item.mBuf = mLatestSubmittedBufferId;
463d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    item.mFrameNumber = mLatestSubmittedBufferFrameNum;
4647c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    item.mTimestamp = mRepeatLastFrameTimestamp;
4659af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
4667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    status_t err = submitBuffer_l(item, cbi);
4677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4687c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (err != OK) {
4697c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org        return false;
4709af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    }
4717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4727c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    ++mLatestSubmittedBufferUseCount;
4737c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
474b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    /* repeat last frame up to kRepeatLastFrameCount times.
475b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org     * in case of static scene, a single repeat might not get rid of encoder
476b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org     * ghosting completely, refresh a couple more times to get better quality
477b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org     */
478b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    if (--mRepeatLastFrameCount > 0) {
479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (mReflector != NULL) {
482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            msg->setInt32("generation", ++mRepeatLastFrameGeneration);
484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            msg->post(mRepeatAfterUs);
4853847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        }
4863847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
4873847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
488ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    return true;
489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid GraphicBufferSource::setLatestSubmittedBuffer_l(
492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        const BufferQueue::BufferItem &item) {
4933847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    ALOGV("setLatestSubmittedBuffer_l");
4943847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
4953847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    if (mLatestSubmittedBufferId >= 0) {
4963847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        if (mLatestSubmittedBufferUseCount == 0) {
497e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            mBufferQueue->releaseBuffer(
4983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                    mLatestSubmittedBufferId,
4993847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                    mLatestSubmittedBufferFrameNum,
5003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                    EGL_NO_DISPLAY,
5013847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                    EGL_NO_SYNC_KHR,
502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    Fence::NO_FENCE);
503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
506ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    mLatestSubmittedBufferId = item.mBuf;
507ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    mLatestSubmittedBufferFrameNum = item.mFrameNumber;
508ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
509ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
510ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    mLatestSubmittedBufferUseCount = 1;
5113847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    mRepeatBufferDeferred = false;
512ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    mRepeatLastFrameCount = kRepeatLastFrameCount;
513efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
514ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    if (mReflector != NULL) {
515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
516ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        msg->setInt32("generation", ++mRepeatLastFrameGeneration);
517ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        msg->post(mRepeatAfterUs);
518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatus_t GraphicBufferSource::signalEndOfInputStream() {
522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Mutex::Autolock autoLock(mMutex);
523e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    ALOGV("signalEndOfInputStream: exec=%d avail=%d eos=%d",
524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            mExecuting, mNumFramesAvailable, mEndOfStream);
525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mEndOfStream) {
527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGE("EOS was already signaled");
528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return INVALID_OPERATION;
529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
531f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // Set the end-of-stream flag.  If no frames are pending from the
532d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    // BufferQueue, and a codec buffer is available, and we're executing,
533d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    // we initiate the EOS from here.  Otherwise, we'll let
534f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // codecBufferEmptied() (or omxExecuting) do it.
535f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    //
536f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // Note: if there are no pending frames and all codec buffers are
537f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // available, we *must* submit the EOS from here or we'll just
538f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // stall since no future events are expected.
53983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    mEndOfStream = true;
54083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
54183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (mExecuting && mNumFramesAvailable == 0) {
542f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        submitEndOfInputStream_l();
543f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
544f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
545f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    return OK;
546f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org}
547f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
54883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgint64_t GraphicBufferSource::getTimestamp(const BufferQueue::BufferItem &item) {
54983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    int64_t timeUs = item.mTimestamp / 1000;
550f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
551f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    if (mMaxTimestampGapUs > 0ll) {
552f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        /* Cap timestamp gap between adjacent frames to specified max
553f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org         *
554f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org         * In the scenario of cast mirroring, encoding could be suspended for
555f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org         * prolonged periods. Limiting the pts gap to workaround the problem
55628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org         * where encoder's rate control logic produces huge frames after a
55728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org         * long period of suspension.
55883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org         */
55983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
560f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        int64_t originalTimeUs = timeUs;
561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (mPrevOriginalTimeUs >= 0ll) {
562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            if (originalTimeUs < mPrevOriginalTimeUs) {
563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                // Drop the frame if it's going backward in time. Bad timestamp
564d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                // could disrupt encoder's rate control completely.
565d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                ALOGW("Dropping frame that's going backward in time");
566d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                return -1;
567d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org            }
568d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org            int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            timeUs = (timestampGapUs < mMaxTimestampGapUs ?
570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mPrevOriginalTimeUs = originalTimeUs;
573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mPrevModifiedTimeUs = timeUs;
574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        mOriginalTimeUs.add(timeUs, originalTimeUs);
575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("IN  timestamp: %lld -> %lld", originalTimeUs, timeUs);
576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return timeUs;
579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5803847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
5813847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.comstatus_t GraphicBufferSource::submitBuffer_l(
5823847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        const BufferQueue::BufferItem &item, int cbi) {
5833847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    ALOGV("submitBuffer_l cbi=%d", cbi);
5843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
5853847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    int64_t timeUs = getTimestamp(item);
586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (timeUs < 0ll) {
5873847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        return UNKNOWN_ERROR;
5887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    }
5897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
5903847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
5913847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf];
5923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    codecBuffer.mBuf = item.mBuf;
5933847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    codecBuffer.mFrameNumber = item.mFrameNumber;
594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t));
597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    OMX_U8* data = header->pBuffer;
598812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    const OMX_U32 type = kMetadataBufferTypeGrallocSource;
599812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle;
600812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    memcpy(data, &type, 4);
601e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    memcpy(data + 4, &handle, sizeof(buffer_handle_t));
602a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    status_t err = mNodeInstance->emptyDirectBuffer(header, 0,
604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME,
605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            timeUs);
606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (err != OK) {
607a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err);
608e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        codecBuffer.mGraphicBuffer = NULL;
609e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        return err;
610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p",
613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            header, header->pBuffer, handle);
614812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return OK;
615e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
616812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
617e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid GraphicBufferSource::submitEndOfInputStream_l() {
618a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CHECK(mEndOfStream);
619a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mEndOfStreamSent) {
620a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGV("EOS already sent");
621f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        return;
622f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
623f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
624f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    int cbi = findAvailableCodecBuffer_l();
625f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    if (cbi < 0) {
626f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ALOGV("submitEndOfInputStream_l: no codec buffers available");
627f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        return;
628f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
629f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
630f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // We reject any additional incoming graphic buffers, so there's no need
631f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as
632f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // in-use.
633f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
634f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
635f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
636f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    if (EXTRA_CHECK) {
637f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        // Guard against implementations that don't check nFilledLen.
63883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        size_t fillLen = 4 + sizeof(buffer_handle_t);
639a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        CHECK(header->nAllocLen >= fillLen);
640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        OMX_U8* data = header->pBuffer;
641f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        memset(data, 0xcd, fillLen);
6424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    }
643f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
644f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    uint64_t timestamp = 0; // does this matter?
6454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
646f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0,
647a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
648a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            timestamp);
649a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (err != OK) {
650a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
651e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    } else {
652e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d",
653e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                header, cbi);
654e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        mEndOfStreamSent = true;
65549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    }
65649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org}
657e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
65849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgint GraphicBufferSource::findAvailableCodecBuffer_l() {
65949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    CHECK(mCodecBuffers.size() > 0);
66049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
66149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (mCodecBuffers[i].mGraphicBuffer == NULL) {
663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            return i;
664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return -1;
667e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
668e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
669e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgint GraphicBufferSource::findMatchingCodecBuffer_l(
670e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        const OMX_BUFFERHEADERTYPE* header) {
671e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
672a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (mCodecBuffers[i].mHeader == header) {
673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            return i;
674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return -1;
677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
678f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
67971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org// BufferQueue::ConsumerListener callback
68071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid GraphicBufferSource::onFrameAvailable() {
681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Mutex::Autolock autoLock(mMutex);
682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ALOGV("onFrameAvailable exec=%d avail=%d",
684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            mExecuting, mNumFramesAvailable);
685e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    if (mEndOfStream || mSuspended) {
687e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        if (mEndOfStream) {
688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            // This should only be possible if a new buffer was queued after
689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            // EOS was signaled, i.e. the app is misbehaving.
690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
691a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            ALOGW("onFrameAvailable: EOS is set, ignoring frame");
692e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        } else {
693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            ALOGV("onFrameAvailable: suspended, ignoring frame");
694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
696a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        BufferQueue::BufferItem item;
697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        status_t err = mBufferQueue->acquireBuffer(&item, 0);
698a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (err == OK) {
699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            // If this is the first time we're seeing this buffer, add it to our
700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            // slot table.
701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            if (item.mGraphicBuffer != NULL) {
702e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                mBufferSlot[item.mBuf] = item.mGraphicBuffer;
704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            }
705a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
706a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return;
709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mNumFramesAvailable++;
71228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
71328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    mRepeatBufferDeferred = false;
71428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    ++mRepeatLastFrameGeneration;
715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
71671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    if (mExecuting) {
71771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        fillCodecBuffer_l();
718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
72138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org// BufferQueue::ConsumerListener callback
72238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid GraphicBufferSource::onBuffersReleased() {
72338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    Mutex::Autolock lock(mMutex);
72438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
72538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    uint32_t slotMask;
72638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    if (mBufferQueue->getReleasedBuffers(&slotMask) != NO_ERROR) {
72738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org        ALOGW("onBuffersReleased: unable to get released buffer set");
72838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org        slotMask = 0xffffffff;
72938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    }
73038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
73138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    ALOGV("onBuffersReleased: 0x%08x", slotMask);
73238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
73338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
73438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org        if ((slotMask & 0x01) != 0) {
73538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org            mBufferSlot[i] = NULL;
736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
737378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        slotMask >>= 1;
738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
741a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(
742efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org        int64_t repeatAfterUs) {
743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Mutex::Autolock autoLock(mMutex);
744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (mExecuting || repeatAfterUs <= 0ll) {
746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return INVALID_OPERATION;
747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    mRepeatAfterUs = repeatAfterUs;
750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return OK;
752e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatus_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) {
755c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    Mutex::Autolock autoLock(mMutex);
756c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
757e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    if (mExecuting || maxGapUs <= 0ll) {
758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return INVALID_OPERATION;
759a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    mMaxTimestampGapUs = maxGapUs;
762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return OK;
764e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
766378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    switch (msg->what()) {
767378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        case kWhatRepeatLastFrame:
768378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        {
769378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            Mutex::Autolock autoLock(mMutex);
770378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
7717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org            int32_t generation;
7727c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org            CHECK(msg->findInt32("generation", &generation));
7737c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
7747c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org            if (generation != mRepeatLastFrameGeneration) {
775e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                // stale
7767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                break;
7777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org            }
778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            if (!mExecuting || mNumFramesAvailable > 0) {
780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                break;
781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            }
782b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
783b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org            bool success = repeatLatestSubmittedBuffer_l();
784b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
785255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            if (success) {
786b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org                ALOGV("repeatLatestSubmittedBuffer_l SUCCESS");
787255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            } else {
788b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org                ALOGV("repeatLatestSubmittedBuffer_l FAILURE");
789b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org                mRepeatBufferDeferred = true;
790b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org            }
791255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            break;
792b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        }
793255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
794255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        default:
795255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            TRESPASS();
796255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    }
797255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org}
798b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
799255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org}  // namespace android
800255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org