1f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden/*
2f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Copyright (C) 2013 The Android Open Source Project
3f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
4f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
5f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * you may not use this file except in compliance with the License.
6f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * You may obtain a copy of the License at
7f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
8f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
9f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden *
10f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * Unless required by applicable law or agreed to in writing, software
11f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
12f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * See the License for the specific language governing permissions and
14f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden * limitations under the License.
15f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden */
16f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
17db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <inttypes.h>
18db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn
19f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#define LOG_TAG "GraphicBufferSource"
20b3921125a9904fc3fb3eecca421bc418e273f3cdYin-Chia Yeh//#define LOG_NDEBUG 0
21f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <utils/Log.h>
22f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
23b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar#define STRINGIFY_ENUMS // for asString in HardwareAPI.h/VideoAPI.h
24b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
25255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/stagefright/omx/GraphicBufferSource.h>
26255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/stagefright/omx/FrameDropper.h>
27255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/stagefright/omx/OMXUtils.h>
28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h>
29a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber#include <media/stagefright/foundation/AMessage.h>
30b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar#include <media/stagefright/foundation/ColorUtils.h>
3143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#include <media/stagefright/foundation/FileDescriptor.h>
32f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
335e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h>
34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h>
358ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza#include <gui/BufferItem.h>
36255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/hardware/HardwareAPI.h>
37255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_Component.h>
38255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_IndexExt.h>
39255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/OMXBuffer.h>
40f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
412475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza#include <inttypes.h>
422475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza
4343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#include <functional>
4443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#include <memory>
4522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa#include <cmath>
4643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
47f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddennamespace android {
48f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
4943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar/**
5043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * A copiable object managing a buffer in the buffer cache managed by the producer. This object
5143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * holds a reference to the buffer, and maintains which buffer slot it belongs to (if any), and
5243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * whether it is still in a buffer slot. It also maintains whether there are any outstanging acquire
5343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * references to it (by buffers acquired from the slot) mainly so that we can keep a debug
5443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * count of how many buffers we need to still release back to the producer.
5543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar */
5643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstruct GraphicBufferSource::CachedBuffer {
5743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
5843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Token that is used to track acquire counts (as opposed to all references to this object).
5943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
6043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    struct Acquirable { };
6143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
6243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
6343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Create using a buffer cached in a slot.
6443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
6543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CachedBuffer(slot_id slot, const sp<GraphicBuffer> &graphicBuffer)
6643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        : mIsCached(true),
6743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mSlot(slot),
6843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mGraphicBuffer(graphicBuffer),
6943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mAcquirable(std::make_shared<Acquirable>()) {
7043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
7143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
7243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
7343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Returns the cache slot that this buffer is cached in, or -1 if it is no longer cached.
7443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     *
7543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * This assumes that -1 slot id is invalid; though, it is just a benign collision used for
7643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * debugging. This object explicitly manages whether it is still cached.
7743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
7843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    slot_id getSlot() const {
7943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mIsCached ? mSlot : -1;
8043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
8143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
8243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
8343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Returns the cached buffer.
8443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
8543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<GraphicBuffer> getGraphicBuffer() const {
8643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mGraphicBuffer;
8743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
8843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
8943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
9043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Checks whether this buffer is still in the buffer cache.
9143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
9243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    bool isCached() const {
9343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mIsCached;
9443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
9543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
9643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
9743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Checks whether this buffer has an acquired reference.
9843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
9943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    bool isAcquired() const {
10043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mAcquirable.use_count() > 1;
10143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
10243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
10343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
10443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Gets and returns a shared acquired reference.
10543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
10643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<Acquirable> getAcquirable() {
10743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mAcquirable;
10843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
10943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
11043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarprivate:
11143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    friend void GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t);
11243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
11343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
11443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * This method to be called when the buffer is no longer in the buffer cache.
11543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Called from discardBufferAtSlotIndex_l.
11643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
11743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    void onDroppedFromCache() {
11843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        CHECK_DBG(mIsCached);
11943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mIsCached = false;
12043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
12143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
12243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    bool mIsCached;
12343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    slot_id mSlot;
12443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<GraphicBuffer> mGraphicBuffer;
12543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<Acquirable> mAcquirable;
12643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar};
12743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
12843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar/**
12943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * A copiable object managing a buffer acquired from the producer. This must always be a cached
13043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * buffer. This objects also manages its acquire fence and any release fences that may be returned
13143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * by the encoder for this buffer (this buffer may be queued to the encoder multiple times).
13243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * If no release fences are added by the encoder, the acquire fence is returned as the release
13343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * fence for this - as it is assumed that noone waited for the acquire fence. Otherwise, it is
13443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * assumed that the encoder has waited for the acquire fence (or returned it as the release
13543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * fence).
13643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar */
13743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstruct GraphicBufferSource::AcquiredBuffer {
13843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    AcquiredBuffer(
13943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            const std::shared_ptr<CachedBuffer> &buffer,
14043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            std::function<void(AcquiredBuffer *)> onReleased,
14143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            const sp<Fence> &acquireFence)
14243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        : mBuffer(buffer),
14343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mAcquirable(buffer->getAcquirable()),
14443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mAcquireFence(acquireFence),
14543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mGotReleaseFences(false),
14643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar          mOnReleased(onReleased) {
14743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
14843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
14943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
15043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Adds a release fence returned by the encoder to this object. If this is called with an
15143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * valid file descriptor, it is added to the list of release fences. These are returned to the
15243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * producer on release() as a merged fence. Regardless of the validity of the file descriptor,
15343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * we take note that a release fence was attempted to be added and the acquire fence can now be
15443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * assumed as acquired.
15543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
15643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    void addReleaseFenceFd(int fenceFd) {
15743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // save all release fences - these will be propagated to the producer if this buffer is
15843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // ever released to it
15943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (fenceFd >= 0) {
16043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mReleaseFenceFds.push_back(fenceFd);
16143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
16243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mGotReleaseFences = true;
16343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
16443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
16543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
16643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Returns the acquire fence file descriptor associated with this object.
16743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
16843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int getAcquireFenceFd() {
16943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mAcquireFence == nullptr || !mAcquireFence->isValid()) {
17043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return -1;
17143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
17243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mAcquireFence->dup();
17343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
17443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
17543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
17643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Returns whether the buffer is still in the buffer cache.
17743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
17843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    bool isCached() const {
17943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mBuffer->isCached();
18043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
18143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
18243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
18343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Returns the acquired buffer.
18443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
18543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<GraphicBuffer> getGraphicBuffer() const {
18643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mBuffer->getGraphicBuffer();
18743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
18843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
18943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
19043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Returns the slot that this buffer is cached at, or -1 otherwise.
19143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     *
19243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * This assumes that -1 slot id is invalid; though, it is just a benign collision used for
19343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * debugging. This object explicitly manages whether it is still cached.
19443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
19543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    slot_id getSlot() const {
19643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return mBuffer->getSlot();
19743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
19843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
19943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
20043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Creates and returns a release fence object from the acquire fence and/or any release fences
20143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * added. If no release fences were added (even if invalid), returns the acquire fence.
20243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Otherwise, it returns a merged fence from all the valid release fences added.
20343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
20443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<Fence> getReleaseFence() {
20543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // If did not receive release fences, we assume this buffer was not consumed (it was
20643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // discarded or dropped). In this case release the acquire fence as the release fence.
20743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // We do this here to avoid a dup, close and recreation of the Fence object.
20843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (!mGotReleaseFences) {
20943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return mAcquireFence;
21043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
21143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        sp<Fence> ret = getReleaseFence(0, mReleaseFenceFds.size());
21243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // clear fds as fence took ownership of them
21343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mReleaseFenceFds.clear();
21443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return ret;
21543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
21643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
21743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // this video buffer is no longer referenced by the codec (or kept for later encoding)
21843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // it is now safe to release to the producer
21943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ~AcquiredBuffer() {
22043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        //mAcquirable.clear();
22143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mOnReleased(this);
22243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // mOnRelease method should call getReleaseFence() that releases all fds but just in case
22343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW_IF(!mReleaseFenceFds.empty(), "release fences were not obtained, closing fds");
22443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        for (int fildes : mReleaseFenceFds) {
22543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ::close(fildes);
22643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            TRESPASS_DBG();
22743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
22843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
22943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
23043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarprivate:
23143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<GraphicBufferSource::CachedBuffer> mBuffer;
23243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<GraphicBufferSource::CachedBuffer::Acquirable> mAcquirable;
23343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<Fence> mAcquireFence;
23443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    Vector<int> mReleaseFenceFds;
23543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    bool mGotReleaseFences;
23643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::function<void(AcquiredBuffer *)> mOnReleased;
23743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
23843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
23943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * Creates and returns a release fence from 0 or more release fence file descriptors in from
24043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * the specified range in the array.
24143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     *
24243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * @param start start index
24343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * @param num   number of release fds to merge
24443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
24543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<Fence> getReleaseFence(size_t start, size_t num) const {
24643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (num == 0) {
24743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return Fence::NO_FENCE;
24843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        } else if (num == 1) {
24943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return new Fence(mReleaseFenceFds[start]);
25043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        } else {
25143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return Fence::merge("GBS::AB",
25243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                getReleaseFence(start, num >> 1),
25343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                getReleaseFence(start + (num >> 1), num - (num >> 1)));
25443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
25543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
25643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar};
25743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
258addf2cbb120346ae42e78fa739245a353db5edadChong ZhangGraphicBufferSource::GraphicBufferSource() :
259f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mInitCheck(UNKNOWN_ERROR),
26043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mNumAvailableUnacquiredBuffers(0),
26143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mNumOutstandingAcquires(0),
26243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mEndOfStream(false),
26343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mEndOfStreamSent(false),
26443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLastDataspace(HAL_DATASPACE_UNKNOWN),
265f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting(false),
266e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    mSuspended(false),
267f72cefddf378909f360998852e41f49042711299Hangyu Kuang    mLastFrameTimestampUs(-1),
268764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mStopTimeUs(-1),
269764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mLastActionTimeUs(-1ll),
27072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mSkipFramesBeforeNs(-1ll),
27143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatIntervalUs(-1ll),
272a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mRepeatLastFrameGeneration(0),
27343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mOutstandingFrameRepeatCount(0),
27443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatBlockedOnCodecBuffer(false),
27522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mFps(-1.0),
27622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mCaptureFps(-1.0),
27722dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mBaseCaptureUs(-1ll),
27822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mBaseFrameUs(-1ll),
27922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mFrameCount(0),
2802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mPrevCaptureUs(-1ll),
28161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    mPrevFrameUs(-1ll),
282d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    mInputBufferTimeOffsetUs(0ll) {
283addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    ALOGV("GraphicBufferSource");
284f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
285addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    String8 name("GraphicBufferSource");
286f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
287addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
288addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mConsumer->setConsumerName(name);
289c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // reference once the ctor ends, as that would cause the refcount of 'this'
292f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
293f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that's what we create.
294addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    wp<BufferQueue::ConsumerListener> listener =
295addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            static_cast<BufferQueue::ConsumerListener*>(this);
296addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IConsumerListener> proxy =
297addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            new BufferQueue::ProxyConsumerListener(listener);
298f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
2995205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mInitCheck = mConsumer->consumerConnect(proxy, false);
3000c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (mInitCheck != NO_ERROR) {
301f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("Error connecting to BufferQueue: %s (%d)",
3020c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden                strerror(-mInitCheck), mInitCheck);
303f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
304f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
305f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
30643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    memset(&mDefaultColorAspectsPacked, 0, sizeof(mDefaultColorAspectsPacked));
307dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar
3080c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    CHECK(mInitCheck == NO_ERROR);
309f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
311f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() {
312addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    ALOGV("~GraphicBufferSource");
31343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    {
31443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // all acquired buffers must be freed with the mutex locked otherwise our debug assertion
31543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // may trigger
31643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        Mutex::Autolock autoLock(mMutex);
31743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mAvailableBuffers.clear();
31843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mSubmittedCodecBuffers.clear();
31943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mBuffer.reset();
3209700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang    }
32143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
32243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mNumOutstandingAcquires != 0) {
32343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("potential buffer leak: acquired=%d", mNumOutstandingAcquires);
32443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        TRESPASS_DBG();
3259700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang    }
326addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (mConsumer != NULL) {
3275205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        status_t err = mConsumer->consumerDisconnect();
3280c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        if (err != NO_ERROR) {
3290c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            ALOGW("consumerDisconnect failed: %d", err);
3300c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        }
331f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
332f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
333f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong ZhangStatus GraphicBufferSource::onOmxExecuting() {
335f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
33643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("--> executing; available=%zu, submittable=%zd",
33743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mAvailableBuffers.size(), mFreeCodecBuffers.size());
338f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(!mExecuting);
339f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = true;
34043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLastDataspace = HAL_DATASPACE_UNKNOWN;
341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("clearing last dataSpace");
342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
343f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Start by loading up as many buffers as possible.  We want to do this,
344f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // rather than just submit the first buffer, to avoid a degenerate case:
345f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // if all BQ buffers arrive before we start executing, and we only submit
346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one here, the other BQ buffers will just sit until we get notified
347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that the codec buffer has been released.  We'd then acquire and
348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit a single additional buffer, repeatedly, never using more than
349f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one codec buffer simultaneously.  (We could instead try to submit
350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // all BQ buffers whenever any codec buffer is freed, but if we get the
351f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // initial conditions right that will never be useful.)
35243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    while (haveAvailableBuffers_l()) {
3530c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        if (!fillCodecBuffer_l()) {
35443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGV("stop load with available=%zu+%d",
35543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
3560c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            break;
3570c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        }
358f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
359f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
36043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("done loading initial frames, available=%zu+%d",
36143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
362f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
363f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // If EOS has already been signaled, and there are no more frames to
364f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit, try to send EOS now as well.
36543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mStopTimeUs == -1 && mEndOfStream && !haveAvailableBuffers_l()) {
366f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
367f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
368a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
36943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFrameRepeatIntervalUs > 0ll && mLooper == NULL) {
370a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mReflector = new AHandlerReflector<GraphicBufferSource>(this);
371a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper = new ALooper;
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->registerHandler(mReflector);
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->start();
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
37643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mLatestBuffer.mBuffer != nullptr) {
37743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            queueFrameRepeat_l();
378a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
379a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3806d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
3816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
382f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
383f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong ZhangStatus GraphicBufferSource::onOmxIdle() {
385ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    ALOGV("omxIdle");
386ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
387ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    Mutex::Autolock autoLock(mMutex);
388ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
389ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    if (mExecuting) {
390ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        // We are only interested in the transition from executing->idle,
391ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        // not loaded->idle.
392892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber        mExecuting = false;
393ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    }
3946d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
395ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber}
396ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
3976d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong ZhangStatus GraphicBufferSource::onOmxLoaded(){
398f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
399a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mLooper != NULL) {
400a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->unregisterHandler(mReflector->id());
401a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mReflector.clear();
402a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
403a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->stop();
404a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper.clear();
405a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
406a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
40743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("--> loaded; available=%zu+%d eos=%d eosSent=%d acquired=%d",
40843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers,
40943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mEndOfStream, mEndOfStreamSent, mNumOutstandingAcquires);
410f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
411addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // Codec is no longer executing.  Releasing all buffers to bq.
41243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFreeCodecBuffers.clear();
41343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mSubmittedCodecBuffers.clear();
41443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLatestBuffer.mBuffer.reset();
415addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mOMXNode.clear();
416f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = false;
417addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
4186d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
420f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
42143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos MolnarStatus GraphicBufferSource::onInputBufferAdded(codec_buffer_id bufferId) {
422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting) {
425f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen -- buffers can only be allocated when
426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // transitioning from "loaded" to "idle".
427f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("addCodecBuffer: buffer added while executing");
4286d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return Status::fromServiceSpecificError(INVALID_OPERATION);
429f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
430f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
43143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("addCodecBuffer: bufferId=%u", bufferId);
4326cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang
43343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFreeCodecBuffers.push_back(bufferId);
4346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
435f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
436f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
43743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos MolnarStatus GraphicBufferSource::onInputBufferEmptied(codec_buffer_id bufferId, int fenceFd) {
438f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
43943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    FileDescriptor::Autoclose fence(fenceFd);
440f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
44143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t cbi = mSubmittedCodecBuffers.indexOfKey(bufferId);
442f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
443f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen.
44443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGE("onInputBufferEmptied: buffer not recognized (bufferId=%u)", bufferId);
4456d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return Status::fromServiceSpecificError(BAD_VALUE);
446f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
447f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
44843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<AcquiredBuffer> buffer = mSubmittedCodecBuffers.valueAt(cbi);
44943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
45043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // Move buffer to available buffers
45143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mSubmittedCodecBuffers.removeItemsAt(cbi);
45243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFreeCodecBuffers.push_back(bufferId);
453f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
454f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // header->nFilledLen may not be the original value, so we can't compare
455f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that to zero to see of this was the EOS buffer.  Instead we just
45643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // see if there is a null AcquiredBuffer, which should only ever happen for EOS.
45743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (buffer == nullptr) {
4585572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden        if (!(mEndOfStream && mEndOfStreamSent)) {
45943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            // This can happen when broken code sends us the same buffer twice in a row.
46043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGE("onInputBufferEmptied: non-EOS null buffer (bufferId=%u)", bufferId);
46143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        } else {
46243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGV("onInputBufferEmptied: EOS null buffer (bufferId=%u@%zd)", bufferId, cbi);
46315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
46443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // No GraphicBuffer to deal with, no additional input or output is expected, so just return.
4656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return Status::fromServiceSpecificError(BAD_VALUE);
466f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
467f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
46843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!mExecuting) {
46943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // this is fine since this could happen when going from Idle to Loaded
47043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: no longer executing (bufferId=%u@%zd)", bufferId, cbi);
47143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return Status::fromServiceSpecificError(OK);
472f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
473f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
47443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("onInputBufferEmptied: bufferId=%d@%zd [slot=%d, useCount=%ld, handle=%p] acquired=%d",
47543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            bufferId, cbi, buffer->getSlot(), buffer.use_count(), buffer->getGraphicBuffer()->handle,
47643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mNumOutstandingAcquires);
477f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
47843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    buffer->addReleaseFenceFd(fence.release());
47943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // release codec reference for video buffer just in case remove does not it
48043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    buffer.reset();
48143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
48243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (haveAvailableBuffers_l()) {
483f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Fill this codec buffer.
4840c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        CHECK(!mEndOfStreamSent);
48543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: buffer freed, feeding codec (available=%zu+%d, eos=%d)",
48643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
487f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
488764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    } else if (mEndOfStream && mStopTimeUs == -1) {
489764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // No frames available, but EOS is pending and no stop time, so use this buffer to
490f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // send that.
49143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: buffer freed, submitting EOS");
492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
49343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else if (mFrameRepeatBlockedOnCodecBuffer) {
49437b2b389139ed638831e49708c947863eef631efRonghua Wu        bool success = repeatLatestBuffer_l();
49543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: completing deferred repeatLatestBuffer_l %s",
49643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                success ? "SUCCESS" : "FAILURE");
49743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mFrameRepeatBlockedOnCodecBuffer = false;
498f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
499a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
50043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // releaseReleasableBuffers_l();
5016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
502e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber}
503e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
50443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::onDataspaceChanged_l(
50543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        android_dataspace dataspace, android_pixel_format pixelFormat) {
50643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGD("got buffer with new dataSpace #%x", dataspace);
50743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLastDataspace = dataspace;
508b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
50943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (ColorUtils::convertDataSpaceToV0(dataspace)) {
51043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mOMXNode->dispatchDataSpaceChanged(mLastDataspace, mDefaultColorAspectsPacked, pixelFormat);
511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5140c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() {
51543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK(mExecuting && haveAvailableBuffers_l());
5160c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden
51743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFreeCodecBuffers.empty()) {
518f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No buffers available, bail.
51943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("fillCodecBuffer_l: no codec buffers, available=%zu+%d",
52043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
5210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        return false;
5220c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
523f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
52443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    VideoBuffer item;
52543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mAvailableBuffers.empty()) {
52643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("fillCodecBuffer_l: acquiring available buffer, available=%zu+%d",
52743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
52843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (acquireBuffer_l(&item) != OK) {
52943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGE("fillCodecBuffer_l: failed to acquire available buffer");
53043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return false;
53143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
53243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
53343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("fillCodecBuffer_l: getting available buffer, available=%zu+%d",
53443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
53543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        item = *mAvailableBuffers.begin();
53643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mAvailableBuffers.erase(mAvailableBuffers.begin());
5370c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
538f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
53943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int64_t itemTimeUs = item.mTimestampNs / 1000;
540f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
541764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Process ActionItem in the Queue if there is any. If a buffer's timestamp
542764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // is smaller than the first action's timestamp, no action need to be performed.
543764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // If buffer's timestamp is larger or equal than the last action's timestamp,
544764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // only the last action needs to be performed as all the acitions before the
545764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // the action are overridden by the last action. For the other cases, traverse
546764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // the Queue to find the newest action that with timestamp smaller or equal to
547764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // the buffer's timestamp. For example, an action queue like
548384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang    // [pause 1us], [resume 2us], [pause 3us], [resume 4us], [pause 5us].... Upon
549764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // receiving a buffer with timestamp 3.5us, only the action [pause, 3us] needs
550764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // to be handled and [pause, 1us], [resume 2us] will be discarded.
551764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    bool done = false;
55221bafd5a325aac30406fbb5dcff18812e0f44a45Hangyu Kuang    bool seeStopAction = false;
553764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (!mActionQueue.empty()) {
554764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // First scan to check if bufferTimestamp is smaller than first action's timestamp.
555764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ActionItem nextAction = *(mActionQueue.begin());
556764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (itemTimeUs < nextAction.mActionTimeUs) {
557764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGV("No action. buffer timestamp %lld us < action timestamp: %lld us",
558764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
559764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            // All the actions are ahead. No action need to perform now.
560764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            // Release the buffer if is in suspended state, or process the buffer
561764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            // if not in suspended state.
562764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            done = true;
563764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
564764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
565764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (!done) {
566384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang            // Find the newest action that with timestamp smaller than itemTimeUs. Then
567384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang            // remove all the actions before and include the newest action.
568764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            List<ActionItem>::iterator it = mActionQueue.begin();
56943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            while (it != mActionQueue.end() && it->mActionTimeUs <= itemTimeUs
57043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    && nextAction.mAction != ActionItem::STOP) {
571764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                nextAction = *it;
572764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                ++it;
573764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
574384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang            mActionQueue.erase(mActionQueue.begin(), it);
575764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
576764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            CHECK(itemTimeUs >= nextAction.mActionTimeUs);
577764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            switch (nextAction.mAction) {
578764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                case ActionItem::PAUSE:
579764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                {
580764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mSuspended = true;
581764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("RUNNING/PAUSE -> PAUSE at buffer %lld us  PAUSE Time: %lld us",
582764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                            (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
583764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    break;
584764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
585764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                case ActionItem::RESUME:
586764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                {
587764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mSuspended = false;
588764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("PAUSE/RUNNING -> RUNNING at buffer %lld us  RESUME Time: %lld us",
589764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                            (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
590764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    break;
591764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
592764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                case ActionItem::STOP:
593764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                {
594764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("RUNNING/PAUSE -> STOP at buffer %lld us  STOP Time: %lld us",
595764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                            (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
596764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    // Clear the whole ActionQueue as recording is done
597764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mActionQueue.clear();
59821bafd5a325aac30406fbb5dcff18812e0f44a45Hangyu Kuang                    seeStopAction = true;
599764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    break;
600764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
601764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                default:
60243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    TRESPASS_DBG("Unknown action type");
60343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // return true here because we did consume an available buffer, so the
60443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // loop in onOmxExecuting will eventually terminate even if we hit this.
605764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    return false;
606764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
607764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
608764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
609764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
61043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (seeStopAction) {
61143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // Clear all the buffers before setting mEndOfStream and signal EndOfInputStream.
61243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        releaseAllAvailableBuffers_l();
61343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mEndOfStream = true;
61443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        submitEndOfInputStream_l();
615764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        return true;
616764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
617764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
61843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mSuspended) {
61943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return true;
620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
62243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int err = UNKNOWN_ERROR;
62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // only submit sample if start time is unspecified, or sample
62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // is queued after the specified start time
62643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mSkipFramesBeforeNs < 0ll || item.mTimestampNs >= mSkipFramesBeforeNs) {
62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if start time is set, offset time stamp by start time
62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mSkipFramesBeforeNs > 0) {
62943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            item.mTimestampNs -= mSkipFramesBeforeNs;
63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
63137b2b389139ed638831e49708c947863eef631efRonghua Wu
63243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        int64_t timeUs = item.mTimestampNs / 1000;
63337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) {
63437b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs));
63537b2b389139ed638831e49708c947863eef631efRonghua Wu            // set err to OK so that the skipped frame can still be saved as the lastest frame
63637b2b389139ed638831e49708c947863eef631efRonghua Wu            err = OK;
63737b2b389139ed638831e49708c947863eef631efRonghua Wu        } else {
63843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            err = submitBuffer_l(item); // this takes shared ownership of the acquired buffer on succeess
63937b2b389139ed638831e49708c947863eef631efRonghua Wu        }
64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6420c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (err != OK) {
64343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("submitBuffer_l failed, will release bq slot %d", item.mBuffer->getSlot());
64443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return true;
6450c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    } else {
646addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // Don't set the last buffer id if we're not repeating,
647addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // we'll be holding on to the last buffer for nothing.
64843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mFrameRepeatIntervalUs > 0ll) {
649addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            setLatestBuffer_l(item);
650addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        }
65143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("buffer submitted [slot=%d, useCount=%ld] acquired=%d",
65243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                item.mBuffer->getSlot(), item.mBuffer.use_count(), mNumOutstandingAcquires);
653fd871c72839d694df9743d28f6e339289ac5c533Hangyu Kuang        mLastFrameTimestampUs = itemTimeUs;
654a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
655a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
656a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    return true;
657a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
658a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
65937b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() {
66043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK(mExecuting && !haveAvailableBuffers_l());
661a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
66243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mLatestBuffer.mBuffer == nullptr || mSuspended) {
663bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        return false;
664bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden    }
665a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
66643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFreeCodecBuffers.empty()) {
667a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        // No buffers available, bail.
66837b2b389139ed638831e49708c947863eef631efRonghua Wu        ALOGV("repeatLatestBuffer_l: no codec buffers.");
669a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
670a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
671a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
67243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!mLatestBuffer.mBuffer->isCached()) {
67343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("repeatLatestBuffer_l: slot was discarded, but repeating our own reference");
67443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
675a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
67643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // it is ok to update the timestamp of latest buffer as it is only used for submission
67743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = submitBuffer_l(mLatestBuffer);
678a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err != OK) {
679a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
680f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
681f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
68294ee4b708acfa941581160b267afb79192b1d816Chong Zhang    /* repeat last frame up to kRepeatLastFrameCount times.
68394ee4b708acfa941581160b267afb79192b1d816Chong Zhang     * in case of static scene, a single repeat might not get rid of encoder
68494ee4b708acfa941581160b267afb79192b1d816Chong Zhang     * ghosting completely, refresh a couple more times to get better quality
68594ee4b708acfa941581160b267afb79192b1d816Chong Zhang     */
68643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (--mOutstandingFrameRepeatCount > 0) {
68743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // set up timestamp for repeat frame
68843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
68943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        queueFrameRepeat_l();
69094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
69194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6920c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    return true;
693f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
694f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
69543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::setLatestBuffer_l(const VideoBuffer &item) {
69643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLatestBuffer = item;
697a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
69843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("setLatestBuffer_l: [slot=%d, useCount=%ld]",
69943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mLatestBuffer.mBuffer->getSlot(), mLatestBuffer.mBuffer.use_count());
70094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
70143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mOutstandingFrameRepeatCount = kRepeatLastFrameCount;
70243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // set up timestamp for repeat frame
70343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
70443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    queueFrameRepeat_l();
70543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
706fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang
70743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::queueFrameRepeat_l() {
70843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatBlockedOnCodecBuffer = false;
709a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
710a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mReflector != NULL) {
7111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
712a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        msg->setInt32("generation", ++mRepeatLastFrameGeneration);
71343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        msg->post(mFrameRepeatIntervalUs);
714a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
715a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
716a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
71743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarbool GraphicBufferSource::calculateCodecTimestamp_l(
71843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        nsecs_t bufferTimeNs, int64_t *codecTimeUs) {
71943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int64_t timeUs = bufferTimeNs / 1000;
72061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    timeUs += mInputBufferTimeOffsetUs;
72194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
72222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (mCaptureFps > 0.
72322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            && (mFps > 2 * mCaptureFps
72422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            || mCaptureFps > 2 * mFps)) {
7252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        // Time lapse or slow motion mode
7262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (mPrevCaptureUs < 0ll) {
7272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            // first capture
72822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevCaptureUs = mBaseCaptureUs = timeUs;
729bd83e4b3e77b31e089832bcfbebde086392216c9Hangyu Kuang            // adjust the first sample timestamp.
73022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevFrameUs = mBaseFrameUs =
73122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                    std::llround((timeUs * mCaptureFps) / mFps);
73222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mFrameCount = 0;
7332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        } else {
7342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            // snap to nearest capture point
73522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            int64_t nFrames = std::llround(
736780882de33d5e91596a31b17ae050d448dd01443Pawin Vongmasa                    (timeUs - mPrevCaptureUs) * mCaptureFps / 1000000);
7372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            if (nFrames <= 0) {
7382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                // skip this frame as it's too close to previous capture
739a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
7406d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                return false;
7412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            }
74222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mFrameCount += nFrames;
74322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevCaptureUs = mBaseCaptureUs + std::llround(
744780882de33d5e91596a31b17ae050d448dd01443Pawin Vongmasa                    mFrameCount * 1000000 / mCaptureFps);
74522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevFrameUs = mBaseFrameUs + std::llround(
746780882de33d5e91596a31b17ae050d448dd01443Pawin Vongmasa                    mFrameCount * 1000000 / mFps);
7472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
7482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
7492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        ALOGV("timeUs %lld, captureUs %lld, frameUs %lld",
750a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(timeUs),
751a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(mPrevCaptureUs),
752a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(mPrevFrameUs));
75361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    } else {
75443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (timeUs <= mPrevFrameUs) {
75543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            // Drop the frame if it's going backward in time. Bad timestamp
75643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            // could disrupt encoder's rate control completely.
75761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGW("Dropping frame that's going backward in time");
7586d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return false;
75961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
76061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
76143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mPrevFrameUs = timeUs;
76294ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
76394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
76443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    *codecTimeUs = mPrevFrameUs;
7656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return true;
76694ee4b708acfa941581160b267afb79192b1d816Chong Zhang}
76794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
76843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const VideoBuffer &item) {
76943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK(!mFreeCodecBuffers.empty());
77043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
77143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
77243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("submitBuffer_l [slot=%d, bufferId=%d]", item.mBuffer->getSlot(), codecBufferId);
773b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang
7743604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang    int64_t codecTimeUs;
77543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!calculateCodecTimestamp_l(item.mTimestampNs, &codecTimeUs)) {
776b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang        return UNKNOWN_ERROR;
777b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang    }
778b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang
77943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if ((android_dataspace)item.mDataspace != mLastDataspace) {
78043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        onDataspaceChanged_l(
78143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                item.mDataspace,
78243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                (android_pixel_format)item.mBuffer->getGraphicBuffer()->format);
78343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
7846cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang
78543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<AcquiredBuffer> buffer = item.mBuffer;
78643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // use a GraphicBuffer for now as OMXNodeInstance is using GraphicBuffers to hold references
78743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // and it requires this graphic buffer to be able to hold its reference
78843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // and thus we would need to create a new GraphicBuffer from an ANWBuffer separate from the
78943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // acquired GraphicBuffer.
79043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // TODO: this can be reworked globally to use ANWBuffer references
79143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<GraphicBuffer> graphicBuffer = buffer->getGraphicBuffer();
7923fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    status_t err = mOMXNode->emptyBuffer(
79343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME, graphicBuffer, codecTimeUs,
79443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            buffer->getAcquireFenceFd());
7956cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang
796f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
7976cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ALOGW("WARNING: emptyGraphicBuffer failed: 0x%x", err);
798f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
799f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
800f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
801195f1ed9563ea2264dbca8c783695d9741dab3d8Lajos Molnar    mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
802195f1ed9563ea2264dbca8c783695d9741dab3d8Lajos Molnar
80343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, buffer);
80443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("emptyGraphicBuffer succeeded, bufferId=%u@%zd bufhandle=%p",
80543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            codecBufferId, cbix, graphicBuffer->handle);
806f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
807f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
808f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
809f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() {
810f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mEndOfStream);
811f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStreamSent) {
812f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("EOS already sent");
813f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
814f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
815f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
81643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFreeCodecBuffers.empty()) {
817f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("submitEndOfInputStream_l: no codec buffers available");
818f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
819f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
82043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
821f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
82243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // We reject any additional incoming graphic buffers. There is no acquired buffer used for EOS
82343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = mOMXNode->emptyBuffer(
82443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
825f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
826f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
827f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else {
828195f1ed9563ea2264dbca8c783695d9741dab3d8Lajos Molnar        mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
82943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, nullptr);
83043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("submitEndOfInputStream_l: buffer submitted, bufferId=%u@%zd", codecBufferId, cbix);
8310c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        mEndOfStreamSent = true;
8321f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar
8331f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar        // no need to hold onto any buffers for frame repeating
8341f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar        ++mRepeatLastFrameGeneration;
8351f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar        mLatestBuffer.mBuffer.reset();
836f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
837f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
838f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
83943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstatus_t GraphicBufferSource::acquireBuffer_l(VideoBuffer *ab) {
84043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    BufferItem bi;
84143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = mConsumer->acquireBuffer(&bi, 0);
842addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
843addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // shouldn't happen
84443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("acquireBuffer_l: frame was not available");
845addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
846addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    } else if (err != OK) {
84743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("acquireBuffer_l: failed with err=%d", err);
848addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
849addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
85043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    --mNumAvailableUnacquiredBuffers;
851addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
85243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // Manage our buffer cache.
85343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<CachedBuffer> buffer;
85443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t bsi = mBufferSlots.indexOfKey(bi.mSlot);
85543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (bi.mGraphicBuffer != NULL) {
85643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // replace/initialize slot with new buffer
85743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("acquireBuffer_l: %s buffer slot %d", bsi < 0 ? "setting" : "UPDATING", bi.mSlot);
85843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (bsi >= 0) {
85943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            discardBufferAtSlotIndex_l(bsi);
86043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        } else {
86143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            bsi = mBufferSlots.add(bi.mSlot, nullptr);
86243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
86343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        buffer = std::make_shared<CachedBuffer>(bi.mSlot, bi.mGraphicBuffer);
86443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mBufferSlots.replaceValueAt(bsi, buffer);
86543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
86643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        buffer = mBufferSlots.valueAt(bsi);
86743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
86843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int64_t frameNum = bi.mFrameNumber;
86943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
87043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<AcquiredBuffer> acquiredBuffer =
87143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        std::make_shared<AcquiredBuffer>(
87243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                buffer,
87343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                [frameNum, this](AcquiredBuffer *buffer){
87443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // AcquiredBuffer's destructor should always be called when mMutex is locked.
87543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // If we had a reentrant mutex, we could just lock it again to ensure this.
87643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    if (mMutex.tryLock() == 0) {
87743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        TRESPASS_DBG();
87843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        mMutex.unlock();
87943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    }
88043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
88143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // we can release buffers immediately if not using adapters
88243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // alternately, we could add them to mSlotsToRelease, but we would
88343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // somehow need to propagate frame number to that queue
88443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    if (buffer->isCached()) {
88543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        --mNumOutstandingAcquires;
88643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        mConsumer->releaseBuffer(
88743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                buffer->getSlot(), frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
88843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                buffer->getReleaseFence());
88943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    }
89043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                },
89143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                bi.mFence);
89243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    VideoBuffer videoBuffer{acquiredBuffer, bi.mTimestamp, bi.mDataSpace};
89343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    *ab = videoBuffer;
89443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ++mNumOutstandingAcquires;
89543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    return OK;
8969700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang}
8979700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang
898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
89943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::onFrameAvailable(const BufferItem& item __unused) {
900f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
901f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
90243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("onFrameAvailable: executing=%d available=%zu+%d",
90343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
90443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ++mNumAvailableUnacquiredBuffers;
905e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
90643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // For BufferQueue we cannot acquire a buffer if we cannot immediately feed it to the codec
90702cccfd9e790ba8758aba2b4f2a600a7d8fd1566Lajos Molnar    // UNLESS we are discarding this buffer (acquiring and immediately releasing it), which makes
90843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // this an ugly logic.
90943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // NOTE: We could also rely on our debug counter but that is meant only as a debug counter.
91043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!areWeDiscardingAvailableBuffers_l() && mFreeCodecBuffers.empty()) {
91143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // we may not be allowed to acquire a possibly encodable buffer, so just note that
91243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // it is available
91343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onFrameAvailable: cannot acquire buffer right now, do it later");
914f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
91543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
91602cccfd9e790ba8758aba2b4f2a600a7d8fd1566Lajos Molnar        return;
917f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
918f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
91943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    VideoBuffer buffer;
92043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = acquireBuffer_l(&buffer);
92143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (err != OK) {
92243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGE("onFrameAvailable: acquireBuffer returned err=%d", err);
92343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
92443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        onBufferAcquired_l(buffer);
92543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
92643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
927f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
92843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarbool GraphicBufferSource::areWeDiscardingAvailableBuffers_l() {
92943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    return mEndOfStreamSent // already sent EOS to codec
93043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            || mOMXNode == nullptr // there is no codec connected
93143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            || (mSuspended && mActionQueue.empty()) // we are suspended and not waiting for
93243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                                    // any further action
93343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            || !mExecuting;
93443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
935a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
93643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::onBufferAcquired_l(const VideoBuffer &buffer) {
93743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mEndOfStreamSent) {
93843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // This should only be possible if a new buffer was queued after
93943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // EOS was signaled, i.e. the app is misbehaving.
94043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("onFrameAvailable: EOS is sent, ignoring frame");
94143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else if (mOMXNode == NULL || (mSuspended && mActionQueue.empty())) {
94243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // FIXME: if we are suspended but have a resume queued we will stop repeating the last
94343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // frame. Is that the desired behavior?
94443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onFrameAvailable: suspended, ignoring frame");
94543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
94643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
94743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mAvailableBuffers.push_back(buffer);
94843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mExecuting) {
94943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            fillCodecBuffer_l();
95043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
951f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
952f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
953f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
954f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
955f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() {
956f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock lock(mMutex);
957f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
9582475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza    uint64_t slotMask;
9591357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar    uint64_t releaseMask;
9601357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar    if (mConsumer->getReleasedBuffers(&releaseMask) != NO_ERROR) {
9612475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza        slotMask = 0xffffffffffffffffULL;
9621357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar        ALOGW("onBuffersReleased: unable to get released buffer set");
9631357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar    } else {
9641357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar        slotMask = releaseMask;
9651357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar        ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask);
966f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
967f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
9681357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar    AString unpopulated;
969f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
970f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if ((slotMask & 0x01) != 0) {
9711357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar            if (!discardBufferInSlot_l(i)) {
9721357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar                if (!unpopulated.empty()) {
9731357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar                    unpopulated.append(", ");
9741357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar                }
9751357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar                unpopulated.append(i);
9761357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar            }
977f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
978f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        slotMask >>= 1;
979f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
9801357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar    if (!unpopulated.empty()) {
9811357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar        ALOGW("released unpopulated slots: [%s]", unpopulated.c_str());
9821357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar    }
983f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
984f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
9851357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnarbool GraphicBufferSource::discardBufferInSlot_l(GraphicBufferSource::slot_id i) {
98643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t bsi = mBufferSlots.indexOfKey(i);
98743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (bsi < 0) {
9881357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar        return false;
98943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
99043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        discardBufferAtSlotIndex_l(bsi);
99143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mBufferSlots.removeItemsAt(bsi);
9921357839f7c4548ce7809e8deb194097e54fd5dd6Lajos Molnar        return true;
99343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
99443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
99543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
99643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t bsi) {
99743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    const std::shared_ptr<CachedBuffer>& buffer = mBufferSlots.valueAt(bsi);
99843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // use -2 if there is no latest buffer, and -1 if it is no longer cached
99943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    slot_id latestBufferSlot =
100043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mBuffer == nullptr ? -2 : mLatestBuffer.mBuffer->getSlot();
100143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("releasing acquired buffer: [slot=%d, useCount=%ld], latest: [slot=%d]",
100243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mBufferSlots.keyAt(bsi), buffer.use_count(), latestBufferSlot);
100343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mBufferSlots.valueAt(bsi)->onDroppedFromCache();
100443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
100543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // If the slot of an acquired buffer is discarded, that buffer will not have to be
100643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // released to the producer, so account it here. However, it is possible that the
100743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // acquired buffer has already been discarded so check if it still is.
100843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (buffer->isAcquired()) {
100943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        --mNumOutstandingAcquires;
101043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
101143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
101243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // clear the buffer reference (not technically needed as caller either replaces or deletes
101343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // it; done here for safety).
101443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mBufferSlots.editValueAt(bsi).reset();
101543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK_DBG(buffer == nullptr);
101643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
101743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
101843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::releaseAllAvailableBuffers_l() {
101943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mAvailableBuffers.clear();
102043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    while (mNumAvailableUnacquiredBuffers > 0) {
102143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        VideoBuffer item;
102243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (acquireBuffer_l(&item) != OK) {
102343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGW("releaseAllAvailableBuffers: failed to acquire available unacquired buffer");
102443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            break;
102543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
102643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
102743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
102843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
10298dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback
10308dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() {
10318dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall    ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
10328dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall}
10338dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall
1034d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::configure(
1035d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        const sp<IOmxNodeWrapper>& omxNode,
1036d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int32_t dataSpace,
1037d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int32_t bufferCount,
1038d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        uint32_t frameWidth,
1039d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        uint32_t frameHeight,
1040d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        uint32_t consumerUsage) {
1041addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (omxNode == NULL) {
1042d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return BAD_VALUE;
1043addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
1044addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1045addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1046addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // Call setMaxAcquiredBufferCount without lock.
1047addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // setMaxAcquiredBufferCount could call back to onBuffersReleased
1048addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // if the buffer count change results in releasing of existing buffers,
1049addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // which would lead to deadlock.
1050d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    status_t err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
1051addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != NO_ERROR) {
1052addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
1053d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                bufferCount, err);
1054d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return err;
1055addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
1056addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1057addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    {
1058addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        Mutex::Autolock autoLock(mMutex);
1059addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mOMXNode = omxNode;
1060addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1061d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        err = mConsumer->setDefaultBufferSize(frameWidth, frameHeight);
1062addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        if (err != NO_ERROR) {
1063addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            ALOGE("Unable to set BQ default buffer size to %ux%u: %d",
1064d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                    frameWidth, frameHeight, err);
1065d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return err;
1066addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        }
1067addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1068addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
1069addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mConsumer->setConsumerUsageBits(consumerUsage);
1070addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1071addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // Sets the default buffer data space
107243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
1073addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
107443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLastDataspace = (android_dataspace)dataSpace;
1075addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1076addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mExecuting = false;
1077addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mSuspended = false;
1078addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mEndOfStream = false;
1079addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mEndOfStreamSent = false;
1080addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mSkipFramesBeforeNs = -1ll;
108143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mFrameRepeatIntervalUs = -1ll;
1082addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mRepeatLastFrameGeneration = 0;
108343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mOutstandingFrameRepeatCount = 0;
108443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mBuffer.reset();
108543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mFrameRepeatBlockedOnCodecBuffer = false;
108622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFps = -1.0;
108722dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mCaptureFps = -1.0;
108822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mBaseCaptureUs = -1ll;
108922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mBaseFrameUs = -1ll;
1090addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mPrevCaptureUs = -1ll;
1091addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mPrevFrameUs = -1ll;
109222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFrameCount = 0;
1093addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mInputBufferTimeOffsetUs = 0;
1094764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mStopTimeUs = -1;
1095764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mActionQueue.clear();
1096addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
1097addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1098d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
109957fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar}
110057fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
1101d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
1102764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    ALOGV("setSuspend=%d at time %lld us", suspend, (long long)suspendStartTimeUs);
11036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
11046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    Mutex::Autolock autoLock(mMutex);
11056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1106764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (mStopTimeUs != -1) {
1107764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGE("setSuspend failed as STOP action is pending");
1108d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1109764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
11106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1111764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Push the action to the queue.
1112764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (suspendStartTimeUs != -1) {
1113764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // suspendStartTimeUs must be smaller or equal to current systemTime.
1114764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        int64_t currentSystemTimeUs = systemTime() / 1000;
1115764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (suspendStartTimeUs > currentSystemTimeUs) {
1116764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("setSuspend failed. %lld is larger than current system time %lld us",
1117764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    (long long)suspendStartTimeUs, (long long)currentSystemTimeUs);
1118d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return INVALID_OPERATION;
1119764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
1120764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mLastActionTimeUs != -1 && suspendStartTimeUs < mLastActionTimeUs) {
1121764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
1122764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    (long long)suspendStartTimeUs, (long long)mLastActionTimeUs);
1123d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return INVALID_OPERATION;
1124764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
1125764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mLastActionTimeUs = suspendStartTimeUs;
1126764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ActionItem action;
1127764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        action.mAction = suspend ? ActionItem::PAUSE : ActionItem::RESUME;
1128764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        action.mActionTimeUs = suspendStartTimeUs;
1129764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGV("Push %s action into actionQueue", suspend ? "PAUSE" : "RESUME");
1130764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mActionQueue.push_back(action);
1131764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    } else {
1132764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (suspend) {
1133764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            mSuspended = true;
113443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            releaseAllAvailableBuffers_l();
1135d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return OK;
1136764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        } else {
1137764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            mSuspended = false;
113843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            if (mExecuting && !haveAvailableBuffers_l()
113943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    && mFrameRepeatBlockedOnCodecBuffer) {
1140764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                if (repeatLatestBuffer_l()) {
1141764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS");
114243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    mFrameRepeatBlockedOnCodecBuffer = false;
1143764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                } else {
1144764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE");
1145764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
1146764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
11476d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
11486d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1149d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
11506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
11516d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1152d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
11536d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    ALOGV("setRepeatPreviousFrameDelayUs: delayUs=%lld", (long long)repeatAfterUs);
11546d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1155a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    Mutex::Autolock autoLock(mMutex);
1156a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1157a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mExecuting || repeatAfterUs <= 0ll) {
1158d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1159a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
1160a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
116143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatIntervalUs = repeatAfterUs;
1162d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
1163a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
116472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1165d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
116661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    Mutex::Autolock autoLock(mMutex);
116761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
116861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    // timeOffsetUs must be negative for adjustment.
116961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (timeOffsetUs >= 0ll) {
1170d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
117161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
117261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
117361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    mInputBufferTimeOffsetUs = timeOffsetUs;
1174d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
117561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang}
117661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
1177d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setMaxFps(float maxFps) {
11786d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    ALOGV("setMaxFps: maxFps=%lld", (long long)maxFps);
11796d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
118037b2b389139ed638831e49708c947863eef631efRonghua Wu    Mutex::Autolock autoLock(mMutex);
118137b2b389139ed638831e49708c947863eef631efRonghua Wu
118237b2b389139ed638831e49708c947863eef631efRonghua Wu    if (mExecuting) {
1183d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
118437b2b389139ed638831e49708c947863eef631efRonghua Wu    }
118537b2b389139ed638831e49708c947863eef631efRonghua Wu
118637b2b389139ed638831e49708c947863eef631efRonghua Wu    mFrameDropper = new FrameDropper();
118737b2b389139ed638831e49708c947863eef631efRonghua Wu    status_t err = mFrameDropper->setMaxFrameRate(maxFps);
118837b2b389139ed638831e49708c947863eef631efRonghua Wu    if (err != OK) {
118937b2b389139ed638831e49708c947863eef631efRonghua Wu        mFrameDropper.clear();
1190d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return err;
119137b2b389139ed638831e49708c947863eef631efRonghua Wu    }
119237b2b389139ed638831e49708c947863eef631efRonghua Wu
1193d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
119437b2b389139ed638831e49708c947863eef631efRonghua Wu}
119537b2b389139ed638831e49708c947863eef631efRonghua Wu
1196d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
11976d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    ALOGV("setStartTimeUs: skipFramesBeforeUs=%lld", (long long)skipFramesBeforeUs);
11986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
119972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    Mutex::Autolock autoLock(mMutex);
120072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
120172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mSkipFramesBeforeNs =
120272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
12036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1204d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
120572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
120672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1207d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
1208764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    ALOGV("setStopTimeUs: %lld us", (long long)stopTimeUs);
1209764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    Mutex::Autolock autoLock(mMutex);
1210764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1211764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (mStopTimeUs != -1) {
1212764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // Ignore if stop time has already been set
1213d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return OK;
1214764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1215764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1216764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // stopTimeUs must be smaller or equal to current systemTime.
1217764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    int64_t currentSystemTimeUs = systemTime() / 1000;
1218764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (stopTimeUs > currentSystemTimeUs) {
1219764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGE("setStopTimeUs failed. %lld is larger than current system time %lld us",
1220764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            (long long)stopTimeUs, (long long)currentSystemTimeUs);
1221d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1222764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1223764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (mLastActionTimeUs != -1 && stopTimeUs < mLastActionTimeUs) {
1224764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
1225764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            (long long)stopTimeUs, (long long)mLastActionTimeUs);
1226d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1227764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1228764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mLastActionTimeUs = stopTimeUs;
1229764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    ActionItem action;
1230764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    action.mAction = ActionItem::STOP;
1231764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    action.mActionTimeUs = stopTimeUs;
1232764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mActionQueue.push_back(action);
1233764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mStopTimeUs = stopTimeUs;
1234d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
1235764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang}
1236764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1237f72cefddf378909f360998852e41f49042711299Hangyu Kuangstatus_t GraphicBufferSource::getStopTimeOffsetUs(int64_t *stopTimeOffsetUs) {
1238f72cefddf378909f360998852e41f49042711299Hangyu Kuang    ALOGV("getStopTimeOffsetUs");
1239f72cefddf378909f360998852e41f49042711299Hangyu Kuang    Mutex::Autolock autoLock(mMutex);
1240f72cefddf378909f360998852e41f49042711299Hangyu Kuang    if (mStopTimeUs == -1) {
1241f72cefddf378909f360998852e41f49042711299Hangyu Kuang        ALOGW("Fail to return stopTimeOffsetUs as stop time is not set");
1242f72cefddf378909f360998852e41f49042711299Hangyu Kuang        return INVALID_OPERATION;
1243f72cefddf378909f360998852e41f49042711299Hangyu Kuang    }
1244cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang    *stopTimeOffsetUs =
1245cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang        mLastFrameTimestampUs == -1 ? 0 : mStopTimeUs - mLastFrameTimestampUs;
1246f72cefddf378909f360998852e41f49042711299Hangyu Kuang    return OK;
1247f72cefddf378909f360998852e41f49042711299Hangyu Kuang}
1248f72cefddf378909f360998852e41f49042711299Hangyu Kuang
124922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasastatus_t GraphicBufferSource::setTimeLapseConfig(double fps, double captureFps) {
125022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    ALOGV("setTimeLapseConfig: fps=%lg, captureFps=%lg",
125122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            fps, captureFps);
12522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    Mutex::Autolock autoLock(mMutex);
12532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
125422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (mExecuting || !(fps > 0) || !(captureFps > 0)) {
1255d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
12562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
12572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
125822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mFps = fps;
125922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mCaptureFps = captureFps;
12602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
1261d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
12622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang}
12632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
1264d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
1265dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar    Mutex::Autolock autoLock(mMutex);
126643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mDefaultColorAspectsPacked = aspectsPacked;
1267d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    ColorAspects colorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
1268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))",
1269d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mRange, asString(colorAspects.mRange),
1270d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mPrimaries, asString(colorAspects.mPrimaries),
1271d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mMatrixCoeffs, asString(colorAspects.mMatrixCoeffs),
1272d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mTransfer, asString(colorAspects.mTransfer));
12736d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1274d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
12756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
12766d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1277d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::signalEndOfInputStream() {
12786d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    Mutex::Autolock autoLock(mMutex);
127943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("signalEndOfInputStream: executing=%d available=%zu+%d eos=%d",
128043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
12816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
12826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mEndOfStream) {
12836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        ALOGE("EOS was already signaled");
1284d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
12856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
12866d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
12876d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Set the end-of-stream flag.  If no frames are pending from the
12886d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // BufferQueue, and a codec buffer is available, and we're executing,
1289764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // and there is no stop timestamp, we initiate the EOS from here.
1290764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Otherwise, we'll let codecBufferEmptied() (or omxExecuting) do it.
12916d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    //
12926d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Note: if there are no pending frames and all codec buffers are
12936d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // available, we *must* submit the EOS from here or we'll just
12946d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // stall since no future events are expected.
12956d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mEndOfStream = true;
12966d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
129743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mStopTimeUs == -1 && mExecuting && !haveAvailableBuffers_l()) {
12986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        submitEndOfInputStream_l();
12996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
13006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1301d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
1302dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar}
1303dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar
1304a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
1305a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    switch (msg->what()) {
1306a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        case kWhatRepeatLastFrame:
1307a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        {
1308a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            Mutex::Autolock autoLock(mMutex);
1309a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1310a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            int32_t generation;
1311a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            CHECK(msg->findInt32("generation", &generation));
1312a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1313a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (generation != mRepeatLastFrameGeneration) {
1314a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                // stale
1315a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                break;
1316a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
1317a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
131843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            if (!mExecuting || haveAvailableBuffers_l()) {
1319a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                break;
1320a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
1321a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
132237b2b389139ed638831e49708c947863eef631efRonghua Wu            bool success = repeatLatestBuffer_l();
1323a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (success) {
132437b2b389139ed638831e49708c947863eef631efRonghua Wu                ALOGV("repeatLatestBuffer_l SUCCESS");
1325a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            } else {
132637b2b389139ed638831e49708c947863eef631efRonghua Wu                ALOGV("repeatLatestBuffer_l FAILURE");
132743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mFrameRepeatBlockedOnCodecBuffer = true;
1328a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
1329a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            break;
1330a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1331a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1332a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        default:
1333a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            TRESPASS();
1334a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
1335a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
1336a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1337f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}  // namespace android
1338