GraphicBufferSource.cpp revision c93a13669ce1b5a9e6527b4c86c9d8f5e92be828
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <inttypes.h>
18
19#define LOG_TAG "GraphicBufferSource"
20//#define LOG_NDEBUG 0
21#include <utils/Log.h>
22
23#include "GraphicBufferSource.h"
24
25#include <OMX_Core.h>
26#include <OMX_IndexExt.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
29
30#include <media/hardware/MetadataBufferType.h>
31#include <ui/GraphicBuffer.h>
32#include <gui/BufferItem.h>
33#include <HardwareAPI.h>
34
35#include <inttypes.h>
36#include "FrameDropper.h"
37
38namespace android {
39
40static const bool EXTRA_CHECK = true;
41
42GraphicBufferSource::PersistentProxyListener::PersistentProxyListener(
43        const wp<IGraphicBufferConsumer> &consumer,
44        const wp<ConsumerListener>& consumerListener) :
45    mConsumerListener(consumerListener),
46    mConsumer(consumer) {}
47
48GraphicBufferSource::PersistentProxyListener::~PersistentProxyListener() {}
49
50void GraphicBufferSource::PersistentProxyListener::onFrameAvailable(
51        const BufferItem& item) {
52    sp<ConsumerListener> listener(mConsumerListener.promote());
53    if (listener != NULL) {
54        listener->onFrameAvailable(item);
55    } else {
56        sp<IGraphicBufferConsumer> consumer(mConsumer.promote());
57        if (consumer == NULL) {
58            return;
59        }
60        BufferItem bi;
61        status_t err = consumer->acquireBuffer(&bi, 0);
62        if (err != OK) {
63            ALOGE("PersistentProxyListener: acquireBuffer failed (%d)", err);
64            return;
65        }
66
67        err = consumer->detachBuffer(bi.mBuf);
68        if (err != OK) {
69            ALOGE("PersistentProxyListener: detachBuffer failed (%d)", err);
70            return;
71        }
72
73        err = consumer->attachBuffer(&bi.mBuf, bi.mGraphicBuffer);
74        if (err != OK) {
75            ALOGE("PersistentProxyListener: attachBuffer failed (%d)", err);
76            return;
77        }
78
79        err = consumer->releaseBuffer(bi.mBuf, 0,
80                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, bi.mFence);
81        if (err != OK) {
82            ALOGE("PersistentProxyListener: releaseBuffer failed (%d)", err);
83        }
84    }
85}
86
87void GraphicBufferSource::PersistentProxyListener::onFrameReplaced(
88        const BufferItem& item) {
89    sp<ConsumerListener> listener(mConsumerListener.promote());
90    if (listener != NULL) {
91        listener->onFrameReplaced(item);
92    }
93}
94
95void GraphicBufferSource::PersistentProxyListener::onBuffersReleased() {
96    sp<ConsumerListener> listener(mConsumerListener.promote());
97    if (listener != NULL) {
98        listener->onBuffersReleased();
99    }
100}
101
102void GraphicBufferSource::PersistentProxyListener::onSidebandStreamChanged() {
103    sp<ConsumerListener> listener(mConsumerListener.promote());
104    if (listener != NULL) {
105        listener->onSidebandStreamChanged();
106    }
107}
108
109GraphicBufferSource::GraphicBufferSource(
110        OMXNodeInstance* nodeInstance,
111        uint32_t bufferWidth,
112        uint32_t bufferHeight,
113        uint32_t bufferCount,
114        const sp<IGraphicBufferConsumer> &consumer) :
115    mInitCheck(UNKNOWN_ERROR),
116    mNodeInstance(nodeInstance),
117    mExecuting(false),
118    mSuspended(false),
119    mIsPersistent(false),
120    mConsumer(consumer),
121    mNumFramesAvailable(0),
122    mNumBufferAcquired(0),
123    mEndOfStream(false),
124    mEndOfStreamSent(false),
125    mMaxTimestampGapUs(-1ll),
126    mPrevOriginalTimeUs(-1ll),
127    mPrevModifiedTimeUs(-1ll),
128    mSkipFramesBeforeNs(-1ll),
129    mRepeatAfterUs(-1ll),
130    mRepeatLastFrameGeneration(0),
131    mRepeatLastFrameTimestamp(-1ll),
132    mLatestBufferId(-1),
133    mLatestBufferFrameNum(0),
134    mLatestBufferUseCount(0),
135    mLatestBufferFence(Fence::NO_FENCE),
136    mRepeatBufferDeferred(false),
137    mTimePerCaptureUs(-1ll),
138    mTimePerFrameUs(-1ll),
139    mPrevCaptureUs(-1ll),
140    mPrevFrameUs(-1ll) {
141
142    ALOGV("GraphicBufferSource w=%u h=%u c=%u",
143            bufferWidth, bufferHeight, bufferCount);
144
145    if (bufferWidth == 0 || bufferHeight == 0) {
146        ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight);
147        mInitCheck = BAD_VALUE;
148        return;
149    }
150
151    if (mConsumer == NULL) {
152        String8 name("GraphicBufferSource");
153
154        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
155        mConsumer->setConsumerName(name);
156
157        // query consumer usage bits from encoder, but always add HW_VIDEO_ENCODER
158        // for backward compatibility.
159        uint32_t usageBits;
160        status_t err = mNodeInstance->getParameter(
161                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &usageBits, sizeof(usageBits));
162        if (err != OK) {
163            usageBits = 0;
164        }
165        usageBits |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
166        mConsumer->setConsumerUsageBits(usageBits);
167
168        mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount);
169        if (mInitCheck != NO_ERROR) {
170            ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
171                    bufferCount, mInitCheck);
172            return;
173        }
174    } else {
175        mIsPersistent = true;
176    }
177    mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
178    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
179    // reference once the ctor ends, as that would cause the refcount of 'this'
180    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
181    // that's what we create.
182    wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this);
183    sp<IConsumerListener> proxy;
184    if (!mIsPersistent) {
185        proxy = new BufferQueue::ProxyConsumerListener(listener);
186    } else {
187        proxy = new PersistentProxyListener(mConsumer, listener);
188    }
189
190    mInitCheck = mConsumer->consumerConnect(proxy, false);
191    if (mInitCheck != NO_ERROR) {
192        ALOGE("Error connecting to BufferQueue: %s (%d)",
193                strerror(-mInitCheck), mInitCheck);
194        return;
195    }
196
197    CHECK(mInitCheck == NO_ERROR);
198}
199
200GraphicBufferSource::~GraphicBufferSource() {
201    if (mLatestBufferId >= 0) {
202        releaseBuffer(
203                mLatestBufferId, mLatestBufferFrameNum,
204                mBufferSlot[mLatestBufferId], mLatestBufferFence);
205    }
206    if (mNumBufferAcquired != 0) {
207        ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired);
208    }
209    if (mConsumer != NULL && !mIsPersistent) {
210        status_t err = mConsumer->consumerDisconnect();
211        if (err != NO_ERROR) {
212            ALOGW("consumerDisconnect failed: %d", err);
213        }
214    }
215}
216
217void GraphicBufferSource::omxExecuting() {
218    Mutex::Autolock autoLock(mMutex);
219    ALOGV("--> executing; avail=%zu, codec vec size=%zd",
220            mNumFramesAvailable, mCodecBuffers.size());
221    CHECK(!mExecuting);
222    mExecuting = true;
223
224    // Start by loading up as many buffers as possible.  We want to do this,
225    // rather than just submit the first buffer, to avoid a degenerate case:
226    // if all BQ buffers arrive before we start executing, and we only submit
227    // one here, the other BQ buffers will just sit until we get notified
228    // that the codec buffer has been released.  We'd then acquire and
229    // submit a single additional buffer, repeatedly, never using more than
230    // one codec buffer simultaneously.  (We could instead try to submit
231    // all BQ buffers whenever any codec buffer is freed, but if we get the
232    // initial conditions right that will never be useful.)
233    while (mNumFramesAvailable) {
234        if (!fillCodecBuffer_l()) {
235            ALOGV("stop load with frames available (codecAvail=%d)",
236                    isCodecBufferAvailable_l());
237            break;
238        }
239    }
240
241    ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable);
242
243    // If EOS has already been signaled, and there are no more frames to
244    // submit, try to send EOS now as well.
245    if (mEndOfStream && mNumFramesAvailable == 0) {
246        submitEndOfInputStream_l();
247    }
248
249    if (mRepeatAfterUs > 0ll && mLooper == NULL) {
250        mReflector = new AHandlerReflector<GraphicBufferSource>(this);
251
252        mLooper = new ALooper;
253        mLooper->registerHandler(mReflector);
254        mLooper->start();
255
256        if (mLatestBufferId >= 0) {
257            sp<AMessage> msg =
258                new AMessage(kWhatRepeatLastFrame, mReflector);
259
260            msg->setInt32("generation", ++mRepeatLastFrameGeneration);
261            msg->post(mRepeatAfterUs);
262        }
263    }
264}
265
266void GraphicBufferSource::omxIdle() {
267    ALOGV("omxIdle");
268
269    Mutex::Autolock autoLock(mMutex);
270
271    if (mExecuting) {
272        // We are only interested in the transition from executing->idle,
273        // not loaded->idle.
274        mExecuting = false;
275    }
276}
277
278void GraphicBufferSource::omxLoaded(){
279    Mutex::Autolock autoLock(mMutex);
280    if (!mExecuting) {
281        // This can happen if something failed very early.
282        ALOGW("Dropped back down to Loaded without Executing");
283    }
284
285    if (mLooper != NULL) {
286        mLooper->unregisterHandler(mReflector->id());
287        mReflector.clear();
288
289        mLooper->stop();
290        mLooper.clear();
291    }
292
293    ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d",
294            mNumFramesAvailable, mEndOfStream, mEndOfStreamSent);
295
296    // Codec is no longer executing.  Discard all codec-related state.
297    mCodecBuffers.clear();
298    // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries
299    //       are null; complain if not
300
301    mExecuting = false;
302}
303
304void GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
305    Mutex::Autolock autoLock(mMutex);
306
307    if (mExecuting) {
308        // This should never happen -- buffers can only be allocated when
309        // transitioning from "loaded" to "idle".
310        ALOGE("addCodecBuffer: buffer added while executing");
311        return;
312    }
313
314    ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p",
315            header, header->nAllocLen, header->pBuffer);
316    CodecBuffer codecBuffer;
317    codecBuffer.mHeader = header;
318    mCodecBuffers.add(codecBuffer);
319}
320
321void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) {
322    Mutex::Autolock autoLock(mMutex);
323    if (!mExecuting) {
324        return;
325    }
326
327    int cbi = findMatchingCodecBuffer_l(header);
328    if (cbi < 0) {
329        // This should never happen.
330        ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header);
331        if (fenceFd >= 0) {
332            ::close(fenceFd);
333        }
334        return;
335    }
336
337    ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p",
338            header, header->nAllocLen, header->nFilledLen,
339            header->pBuffer);
340    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
341
342    // header->nFilledLen may not be the original value, so we can't compare
343    // that to zero to see of this was the EOS buffer.  Instead we just
344    // see if the GraphicBuffer reference was null, which should only ever
345    // happen for EOS.
346    if (codecBuffer.mGraphicBuffer == NULL) {
347        if (!(mEndOfStream && mEndOfStreamSent)) {
348            // This can happen when broken code sends us the same buffer
349            // twice in a row.
350            ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer "
351                    "(buffer emptied twice?)");
352        }
353        // No GraphicBuffer to deal with, no additional input or output is
354        // expected, so just return.
355        if (fenceFd >= 0) {
356            ::close(fenceFd);
357        }
358        return;
359    }
360
361    if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) {
362        // Pull the graphic buffer handle back out of the buffer, and confirm
363        // that it matches expectations.
364        OMX_U8* data = header->pBuffer;
365        MetadataBufferType type = *(MetadataBufferType *)data;
366        if (type == kMetadataBufferTypeGrallocSource
367                && header->nAllocLen >= sizeof(VideoGrallocMetadata)) {
368            VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data;
369            if (grallocMeta.pHandle != codecBuffer.mGraphicBuffer->handle) {
370                // should never happen
371                ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p",
372                        grallocMeta.pHandle, codecBuffer.mGraphicBuffer->handle);
373                CHECK(!"codecBufferEmptied: mismatched buffer");
374            }
375        } else if (type == kMetadataBufferTypeANWBuffer
376                && header->nAllocLen >= sizeof(VideoNativeMetadata)) {
377            VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data;
378            if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) {
379                // should never happen
380                ALOGE("codecBufferEmptied: buffer is %p, expected %p",
381                        nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer());
382                CHECK(!"codecBufferEmptied: mismatched buffer");
383            }
384        }
385    }
386
387    // Find matching entry in our cached copy of the BufferQueue slots.
388    // If we find a match, release that slot.  If we don't, the BufferQueue
389    // has dropped that GraphicBuffer, and there's nothing for us to release.
390    int id = codecBuffer.mBuf;
391    sp<Fence> fence = new Fence(fenceFd);
392    if (mBufferSlot[id] != NULL &&
393        mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
394        ALOGV("cbi %d matches bq slot %d, handle=%p",
395                cbi, id, mBufferSlot[id]->handle);
396
397        if (id == mLatestBufferId) {
398            CHECK_GT(mLatestBufferUseCount--, 0);
399        } else {
400            releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence);
401        }
402    } else {
403        ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d",
404                cbi);
405        // we will not reuse codec buffer, so there is no need to wait for fence
406    }
407
408    // Mark the codec buffer as available by clearing the GraphicBuffer ref.
409    codecBuffer.mGraphicBuffer = NULL;
410
411    if (mNumFramesAvailable) {
412        // Fill this codec buffer.
413        CHECK(!mEndOfStreamSent);
414        ALOGV("buffer freed, %zu frames avail (eos=%d)",
415                mNumFramesAvailable, mEndOfStream);
416        fillCodecBuffer_l();
417    } else if (mEndOfStream) {
418        // No frames available, but EOS is pending, so use this buffer to
419        // send that.
420        ALOGV("buffer freed, EOS pending");
421        submitEndOfInputStream_l();
422    } else if (mRepeatBufferDeferred) {
423        bool success = repeatLatestBuffer_l();
424        if (success) {
425            ALOGV("deferred repeatLatestBuffer_l SUCCESS");
426        } else {
427            ALOGV("deferred repeatLatestBuffer_l FAILURE");
428        }
429        mRepeatBufferDeferred = false;
430    }
431
432    return;
433}
434
435void GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) {
436    Mutex::Autolock autoLock(mMutex);
437
438    if (mMaxTimestampGapUs > 0ll
439            && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
440        ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp);
441        if (index >= 0) {
442            ALOGV("OUT timestamp: %lld -> %lld",
443                    static_cast<long long>(header->nTimeStamp),
444                    static_cast<long long>(mOriginalTimeUs[index]));
445            header->nTimeStamp = mOriginalTimeUs[index];
446            mOriginalTimeUs.removeItemsAt(index);
447        } else {
448            // giving up the effort as encoder doesn't appear to preserve pts
449            ALOGW("giving up limiting timestamp gap (pts = %lld)",
450                    header->nTimeStamp);
451            mMaxTimestampGapUs = -1ll;
452        }
453        if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) {
454            // something terribly wrong must have happened, giving up...
455            ALOGE("mOriginalTimeUs has too many entries (%zu)",
456                    mOriginalTimeUs.size());
457            mMaxTimestampGapUs = -1ll;
458        }
459    }
460}
461
462void GraphicBufferSource::suspend(bool suspend) {
463    Mutex::Autolock autoLock(mMutex);
464
465    if (suspend) {
466        mSuspended = true;
467
468        while (mNumFramesAvailable > 0) {
469            BufferItem item;
470            status_t err = mConsumer->acquireBuffer(&item, 0);
471
472            if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
473                // shouldn't happen.
474                ALOGW("suspend: frame was not available");
475                break;
476            } else if (err != OK) {
477                ALOGW("suspend: acquireBuffer returned err=%d", err);
478                break;
479            }
480
481            ++mNumBufferAcquired;
482            --mNumFramesAvailable;
483
484            releaseBuffer(item.mBuf, item.mFrameNumber,
485                    item.mGraphicBuffer, item.mFence);
486        }
487        return;
488    }
489
490    mSuspended = false;
491
492    if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) {
493        if (repeatLatestBuffer_l()) {
494            ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS");
495
496            mRepeatBufferDeferred = false;
497        } else {
498            ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE");
499        }
500    }
501}
502
503bool GraphicBufferSource::fillCodecBuffer_l() {
504    CHECK(mExecuting && mNumFramesAvailable > 0);
505
506    if (mSuspended) {
507        return false;
508    }
509
510    int cbi = findAvailableCodecBuffer_l();
511    if (cbi < 0) {
512        // No buffers available, bail.
513        ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu",
514                mNumFramesAvailable);
515        return false;
516    }
517
518    ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu",
519            mNumFramesAvailable);
520    BufferItem item;
521    status_t err = mConsumer->acquireBuffer(&item, 0);
522    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
523        // shouldn't happen
524        ALOGW("fillCodecBuffer_l: frame was not available");
525        return false;
526    } else if (err != OK) {
527        // now what? fake end-of-stream?
528        ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err);
529        return false;
530    }
531
532    mNumBufferAcquired++;
533    mNumFramesAvailable--;
534
535    // If this is the first time we're seeing this buffer, add it to our
536    // slot table.
537    if (item.mGraphicBuffer != NULL) {
538        ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
539        mBufferSlot[item.mBuf] = item.mGraphicBuffer;
540    }
541
542    err = UNKNOWN_ERROR;
543
544    // only submit sample if start time is unspecified, or sample
545    // is queued after the specified start time
546    bool dropped = false;
547    if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) {
548        // if start time is set, offset time stamp by start time
549        if (mSkipFramesBeforeNs > 0) {
550            item.mTimestamp -= mSkipFramesBeforeNs;
551        }
552
553        int64_t timeUs = item.mTimestamp / 1000;
554        if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) {
555            ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs));
556            // set err to OK so that the skipped frame can still be saved as the lastest frame
557            err = OK;
558            dropped = true;
559        } else {
560            err = submitBuffer_l(item, cbi);
561        }
562    }
563
564    if (err != OK) {
565        ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
566        releaseBuffer(item.mBuf, item.mFrameNumber, item.mGraphicBuffer, item.mFence);
567    } else {
568        ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
569        setLatestBuffer_l(item, dropped);
570    }
571
572    return true;
573}
574
575bool GraphicBufferSource::repeatLatestBuffer_l() {
576    CHECK(mExecuting && mNumFramesAvailable == 0);
577
578    if (mLatestBufferId < 0 || mSuspended) {
579        return false;
580    }
581    if (mBufferSlot[mLatestBufferId] == NULL) {
582        // This can happen if the remote side disconnects, causing
583        // onBuffersReleased() to NULL out our copy of the slots.  The
584        // buffer is gone, so we have nothing to show.
585        //
586        // To be on the safe side we try to release the buffer.
587        ALOGD("repeatLatestBuffer_l: slot was NULL");
588        mConsumer->releaseBuffer(
589                mLatestBufferId,
590                mLatestBufferFrameNum,
591                EGL_NO_DISPLAY,
592                EGL_NO_SYNC_KHR,
593                mLatestBufferFence);
594        mLatestBufferId = -1;
595        mLatestBufferFrameNum = 0;
596        mLatestBufferFence = Fence::NO_FENCE;
597        return false;
598    }
599
600    int cbi = findAvailableCodecBuffer_l();
601    if (cbi < 0) {
602        // No buffers available, bail.
603        ALOGV("repeatLatestBuffer_l: no codec buffers.");
604        return false;
605    }
606
607    BufferItem item;
608    item.mBuf = mLatestBufferId;
609    item.mFrameNumber = mLatestBufferFrameNum;
610    item.mTimestamp = mRepeatLastFrameTimestamp;
611    item.mFence = mLatestBufferFence;
612
613    status_t err = submitBuffer_l(item, cbi);
614
615    if (err != OK) {
616        return false;
617    }
618
619    ++mLatestBufferUseCount;
620
621    /* repeat last frame up to kRepeatLastFrameCount times.
622     * in case of static scene, a single repeat might not get rid of encoder
623     * ghosting completely, refresh a couple more times to get better quality
624     */
625    if (--mRepeatLastFrameCount > 0) {
626        mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
627
628        if (mReflector != NULL) {
629            sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
630            msg->setInt32("generation", ++mRepeatLastFrameGeneration);
631            msg->post(mRepeatAfterUs);
632        }
633    }
634
635    return true;
636}
637
638void GraphicBufferSource::setLatestBuffer_l(
639        const BufferItem &item, bool dropped) {
640    ALOGV("setLatestBuffer_l");
641
642    if (mLatestBufferId >= 0) {
643        if (mLatestBufferUseCount == 0) {
644            releaseBuffer(mLatestBufferId, mLatestBufferFrameNum,
645                    mBufferSlot[mLatestBufferId], mLatestBufferFence);
646            // mLatestBufferFence will be set to new fence just below
647        }
648    }
649
650    mLatestBufferId = item.mBuf;
651    mLatestBufferFrameNum = item.mFrameNumber;
652    mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
653
654    mLatestBufferUseCount = dropped ? 0 : 1;
655    mRepeatBufferDeferred = false;
656    mRepeatLastFrameCount = kRepeatLastFrameCount;
657    mLatestBufferFence = item.mFence;
658
659    if (mReflector != NULL) {
660        sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
661        msg->setInt32("generation", ++mRepeatLastFrameGeneration);
662        msg->post(mRepeatAfterUs);
663    }
664}
665
666status_t GraphicBufferSource::signalEndOfInputStream() {
667    Mutex::Autolock autoLock(mMutex);
668    ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d",
669            mExecuting, mNumFramesAvailable, mEndOfStream);
670
671    if (mEndOfStream) {
672        ALOGE("EOS was already signaled");
673        return INVALID_OPERATION;
674    }
675
676    // Set the end-of-stream flag.  If no frames are pending from the
677    // BufferQueue, and a codec buffer is available, and we're executing,
678    // we initiate the EOS from here.  Otherwise, we'll let
679    // codecBufferEmptied() (or omxExecuting) do it.
680    //
681    // Note: if there are no pending frames and all codec buffers are
682    // available, we *must* submit the EOS from here or we'll just
683    // stall since no future events are expected.
684    mEndOfStream = true;
685
686    if (mExecuting && mNumFramesAvailable == 0) {
687        submitEndOfInputStream_l();
688    }
689
690    return OK;
691}
692
693int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) {
694    int64_t timeUs = item.mTimestamp / 1000;
695
696    if (mTimePerCaptureUs > 0ll) {
697        // Time lapse or slow motion mode
698        if (mPrevCaptureUs < 0ll) {
699            // first capture
700            mPrevCaptureUs = timeUs;
701            mPrevFrameUs = timeUs;
702        } else {
703            // snap to nearest capture point
704            int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs)
705                    / mTimePerCaptureUs;
706            if (nFrames <= 0) {
707                // skip this frame as it's too close to previous capture
708                ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
709                return -1;
710            }
711            mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs;
712            mPrevFrameUs += mTimePerFrameUs * nFrames;
713        }
714
715        ALOGV("timeUs %lld, captureUs %lld, frameUs %lld",
716                static_cast<long long>(timeUs),
717                static_cast<long long>(mPrevCaptureUs),
718                static_cast<long long>(mPrevFrameUs));
719
720        return mPrevFrameUs;
721    } else if (mMaxTimestampGapUs > 0ll) {
722        /* Cap timestamp gap between adjacent frames to specified max
723         *
724         * In the scenario of cast mirroring, encoding could be suspended for
725         * prolonged periods. Limiting the pts gap to workaround the problem
726         * where encoder's rate control logic produces huge frames after a
727         * long period of suspension.
728         */
729
730        int64_t originalTimeUs = timeUs;
731        if (mPrevOriginalTimeUs >= 0ll) {
732            if (originalTimeUs < mPrevOriginalTimeUs) {
733                // Drop the frame if it's going backward in time. Bad timestamp
734                // could disrupt encoder's rate control completely.
735                ALOGW("Dropping frame that's going backward in time");
736                return -1;
737            }
738            int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
739            timeUs = (timestampGapUs < mMaxTimestampGapUs ?
740                    timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
741        }
742        mPrevOriginalTimeUs = originalTimeUs;
743        mPrevModifiedTimeUs = timeUs;
744        mOriginalTimeUs.add(timeUs, originalTimeUs);
745        ALOGV("IN  timestamp: %lld -> %lld",
746            static_cast<long long>(originalTimeUs),
747            static_cast<long long>(timeUs));
748    }
749
750    return timeUs;
751}
752
753status_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) {
754    ALOGV("submitBuffer_l cbi=%d", cbi);
755
756    int64_t timeUs = getTimestamp(item);
757    if (timeUs < 0ll) {
758        return UNKNOWN_ERROR;
759    }
760
761    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
762    codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf];
763    codecBuffer.mBuf = item.mBuf;
764    codecBuffer.mFrameNumber = item.mFrameNumber;
765
766    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
767    sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer;
768    status_t err = mNodeInstance->emptyGraphicBuffer(
769            header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs,
770            item.mFence->isValid() ? item.mFence->dup() : -1);
771    if (err != OK) {
772        ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err);
773        codecBuffer.mGraphicBuffer = NULL;
774        return err;
775    }
776
777    ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p",
778            header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle);
779    return OK;
780}
781
782void GraphicBufferSource::submitEndOfInputStream_l() {
783    CHECK(mEndOfStream);
784    if (mEndOfStreamSent) {
785        ALOGV("EOS already sent");
786        return;
787    }
788
789    int cbi = findAvailableCodecBuffer_l();
790    if (cbi < 0) {
791        ALOGV("submitEndOfInputStream_l: no codec buffers available");
792        return;
793    }
794
795    // We reject any additional incoming graphic buffers, so there's no need
796    // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as
797    // in-use.
798    CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
799
800    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
801    status_t err = mNodeInstance->emptyGraphicBuffer(
802            header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
803            0 /* timestamp */, -1 /* fenceFd */);
804    if (err != OK) {
805        ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
806    } else {
807        ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d",
808                header, cbi);
809        mEndOfStreamSent = true;
810    }
811}
812
813int GraphicBufferSource::findAvailableCodecBuffer_l() {
814    CHECK(mCodecBuffers.size() > 0);
815
816    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
817        if (mCodecBuffers[i].mGraphicBuffer == NULL) {
818            return i;
819        }
820    }
821    return -1;
822}
823
824int GraphicBufferSource::findMatchingCodecBuffer_l(
825        const OMX_BUFFERHEADERTYPE* header) {
826    for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
827        if (mCodecBuffers[i].mHeader == header) {
828            return i;
829        }
830    }
831    return -1;
832}
833
834/*
835 * Releases an acquired buffer back to the consumer for either persistent
836 * or non-persistent surfaces.
837 *
838 * id: buffer slot to release (in persistent case the id might be changed)
839 * frameNum: frame number of the frame being released
840 * buffer: GraphicBuffer pointer to release (note this must not be & as we
841 *         will clear the original mBufferSlot in persistent case)
842 * fence: fence of the frame being released
843 */
844void GraphicBufferSource::releaseBuffer(
845        int &id, uint64_t frameNum,
846        const sp<GraphicBuffer> buffer, const sp<Fence> &fence) {
847    if (mIsPersistent) {
848        mConsumer->detachBuffer(id);
849        mBufferSlot[id] = NULL;
850
851        mConsumer->attachBuffer(&id, buffer);
852        mConsumer->releaseBuffer(
853                id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
854    } else {
855        mConsumer->releaseBuffer(
856                id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
857    }
858    mNumBufferAcquired--;
859}
860
861// BufferQueue::ConsumerListener callback
862void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
863    Mutex::Autolock autoLock(mMutex);
864
865    ALOGV("onFrameAvailable exec=%d avail=%zu",
866            mExecuting, mNumFramesAvailable);
867
868    if (mEndOfStream || mSuspended) {
869        if (mEndOfStream) {
870            // This should only be possible if a new buffer was queued after
871            // EOS was signaled, i.e. the app is misbehaving.
872
873            ALOGW("onFrameAvailable: EOS is set, ignoring frame");
874        } else {
875            ALOGV("onFrameAvailable: suspended, ignoring frame");
876        }
877
878        BufferItem item;
879        status_t err = mConsumer->acquireBuffer(&item, 0);
880        if (err == OK) {
881            mNumBufferAcquired++;
882
883            // If this is the first time we're seeing this buffer, add it to our
884            // slot table.
885            if (item.mGraphicBuffer != NULL) {
886                ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf);
887                mBufferSlot[item.mBuf] = item.mGraphicBuffer;
888            }
889
890            releaseBuffer(item.mBuf, item.mFrameNumber,
891                    item.mGraphicBuffer, item.mFence);
892        }
893        return;
894    }
895
896    mNumFramesAvailable++;
897
898    mRepeatBufferDeferred = false;
899    ++mRepeatLastFrameGeneration;
900
901    if (mExecuting) {
902        fillCodecBuffer_l();
903    }
904}
905
906// BufferQueue::ConsumerListener callback
907void GraphicBufferSource::onBuffersReleased() {
908    Mutex::Autolock lock(mMutex);
909
910    uint64_t slotMask;
911    if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) {
912        ALOGW("onBuffersReleased: unable to get released buffer set");
913        slotMask = 0xffffffffffffffffULL;
914    }
915
916    ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask);
917
918    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
919        if ((slotMask & 0x01) != 0) {
920            mBufferSlot[i] = NULL;
921        }
922        slotMask >>= 1;
923    }
924}
925
926// BufferQueue::ConsumerListener callback
927void GraphicBufferSource::onSidebandStreamChanged() {
928    ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
929}
930
931status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(
932        int64_t repeatAfterUs) {
933    Mutex::Autolock autoLock(mMutex);
934
935    if (mExecuting || repeatAfterUs <= 0ll) {
936        return INVALID_OPERATION;
937    }
938
939    mRepeatAfterUs = repeatAfterUs;
940
941    return OK;
942}
943
944status_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) {
945    Mutex::Autolock autoLock(mMutex);
946
947    if (mExecuting || maxGapUs <= 0ll) {
948        return INVALID_OPERATION;
949    }
950
951    mMaxTimestampGapUs = maxGapUs;
952
953    return OK;
954}
955
956status_t GraphicBufferSource::setMaxFps(float maxFps) {
957    Mutex::Autolock autoLock(mMutex);
958
959    if (mExecuting) {
960        return INVALID_OPERATION;
961    }
962
963    mFrameDropper = new FrameDropper();
964    status_t err = mFrameDropper->setMaxFrameRate(maxFps);
965    if (err != OK) {
966        mFrameDropper.clear();
967        return err;
968    }
969
970    return OK;
971}
972
973void GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) {
974    Mutex::Autolock autoLock(mMutex);
975
976    mSkipFramesBeforeNs =
977            (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
978}
979
980status_t GraphicBufferSource::setTimeLapseUs(int64_t* data) {
981    Mutex::Autolock autoLock(mMutex);
982
983    if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) {
984        return INVALID_OPERATION;
985    }
986
987    mTimePerFrameUs = data[0];
988    mTimePerCaptureUs = data[1];
989
990    return OK;
991}
992
993void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
994    switch (msg->what()) {
995        case kWhatRepeatLastFrame:
996        {
997            Mutex::Autolock autoLock(mMutex);
998
999            int32_t generation;
1000            CHECK(msg->findInt32("generation", &generation));
1001
1002            if (generation != mRepeatLastFrameGeneration) {
1003                // stale
1004                break;
1005            }
1006
1007            if (!mExecuting || mNumFramesAvailable > 0) {
1008                break;
1009            }
1010
1011            bool success = repeatLatestBuffer_l();
1012
1013            if (success) {
1014                ALOGV("repeatLatestBuffer_l SUCCESS");
1015            } else {
1016                ALOGV("repeatLatestBuffer_l FAILURE");
1017                mRepeatBufferDeferred = true;
1018            }
1019            break;
1020        }
1021
1022        default:
1023            TRESPASS();
1024    }
1025}
1026
1027}  // namespace android
1028