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
255e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include "GraphicBufferSource.h"
26f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <media/stagefright/foundation/ADebug.h>
27a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar#include <media/stagefright/foundation/ColorUtils.h>
2943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#include <media/stagefright/foundation/FileDescriptor.h>
30f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
315e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h>
32f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <ui/GraphicBuffer.h>
338ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza#include <gui/BufferItem.h>
34054219874873b41f1c815552987c10465c34ba2bLajos Molnar#include <HardwareAPI.h>
35addf2cbb120346ae42e78fa739245a353db5edadChong Zhang#include "omx/OMXUtils.h"
36addf2cbb120346ae42e78fa739245a353db5edadChong Zhang#include <OMX_Component.h>
37addf2cbb120346ae42e78fa739245a353db5edadChong Zhang#include <OMX_IndexExt.h>
383fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang#include "OMXBuffer.h"
39f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
402475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza#include <inttypes.h>
4137b2b389139ed638831e49708c947863eef631efRonghua Wu#include "FrameDropper.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),
267764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mStopTimeUs(-1),
268764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mLastActionTimeUs(-1ll),
26972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mSkipFramesBeforeNs(-1ll),
27043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatIntervalUs(-1ll),
271a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mRepeatLastFrameGeneration(0),
27243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mOutstandingFrameRepeatCount(0),
27343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatBlockedOnCodecBuffer(false),
27422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mFps(-1.0),
27522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mCaptureFps(-1.0),
27622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mBaseCaptureUs(-1ll),
27722dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mBaseFrameUs(-1ll),
27822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mFrameCount(0),
2792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    mPrevCaptureUs(-1ll),
28061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    mPrevFrameUs(-1ll),
281d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    mInputBufferTimeOffsetUs(0ll) {
282addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    ALOGV("GraphicBufferSource");
283f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
284addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    String8 name("GraphicBufferSource");
285f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
286addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
287addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mConsumer->setConsumerName(name);
288c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
289f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
290f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // reference once the ctor ends, as that would cause the refcount of 'this'
291f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
292f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that's what we create.
293addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    wp<BufferQueue::ConsumerListener> listener =
294addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            static_cast<BufferQueue::ConsumerListener*>(this);
295addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IConsumerListener> proxy =
296addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            new BufferQueue::ProxyConsumerListener(listener);
297f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
2985205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mInitCheck = mConsumer->consumerConnect(proxy, false);
2990c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (mInitCheck != NO_ERROR) {
300f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("Error connecting to BufferQueue: %s (%d)",
3010c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden                strerror(-mInitCheck), mInitCheck);
302f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
303f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
304f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
30543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    memset(&mDefaultColorAspectsPacked, 0, sizeof(mDefaultColorAspectsPacked));
306dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar
3070c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    CHECK(mInitCheck == NO_ERROR);
308f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
309f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
310f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenGraphicBufferSource::~GraphicBufferSource() {
311addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    ALOGV("~GraphicBufferSource");
31243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    {
31343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // all acquired buffers must be freed with the mutex locked otherwise our debug assertion
31443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // may trigger
31543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        Mutex::Autolock autoLock(mMutex);
31643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mAvailableBuffers.clear();
31743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mSubmittedCodecBuffers.clear();
31843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mBuffer.reset();
3199700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang    }
32043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
32143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mNumOutstandingAcquires != 0) {
32243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("potential buffer leak: acquired=%d", mNumOutstandingAcquires);
32343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        TRESPASS_DBG();
3249700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang    }
325addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (mConsumer != NULL) {
3265205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        status_t err = mConsumer->consumerDisconnect();
3270c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        if (err != NO_ERROR) {
3280c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            ALOGW("consumerDisconnect failed: %d", err);
3290c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        }
330f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
331f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
332f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3336d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong ZhangStatus GraphicBufferSource::onOmxExecuting() {
334f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
33543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("--> executing; available=%zu, submittable=%zd",
33643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mAvailableBuffers.size(), mFreeCodecBuffers.size());
337f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(!mExecuting);
338f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = true;
33943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLastDataspace = HAL_DATASPACE_UNKNOWN;
340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("clearing last dataSpace");
341f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
342f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Start by loading up as many buffers as possible.  We want to do this,
343f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // rather than just submit the first buffer, to avoid a degenerate case:
344f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // if all BQ buffers arrive before we start executing, and we only submit
345f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one here, the other BQ buffers will just sit until we get notified
346f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that the codec buffer has been released.  We'd then acquire and
347f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit a single additional buffer, repeatedly, never using more than
348f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // one codec buffer simultaneously.  (We could instead try to submit
349f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // all BQ buffers whenever any codec buffer is freed, but if we get the
350f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // initial conditions right that will never be useful.)
35143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    while (haveAvailableBuffers_l()) {
3520c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        if (!fillCodecBuffer_l()) {
35343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGV("stop load with available=%zu+%d",
35443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
3550c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            break;
3560c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        }
357f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
358f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
35943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("done loading initial frames, available=%zu+%d",
36043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
361f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
362f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // If EOS has already been signaled, and there are no more frames to
363f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // submit, try to send EOS now as well.
36443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mStopTimeUs == -1 && mEndOfStream && !haveAvailableBuffers_l()) {
365f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
366f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
367a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
36843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFrameRepeatIntervalUs > 0ll && mLooper == NULL) {
369a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mReflector = new AHandlerReflector<GraphicBufferSource>(this);
370a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
371a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper = new ALooper;
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->registerHandler(mReflector);
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->start();
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
37543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mLatestBuffer.mBuffer != nullptr) {
37643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            queueFrameRepeat_l();
377a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
378a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3796d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
3806d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
381f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
382f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong ZhangStatus GraphicBufferSource::onOmxIdle() {
384ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    ALOGV("omxIdle");
385ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
386ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    Mutex::Autolock autoLock(mMutex);
387ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
388ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    if (mExecuting) {
389ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        // We are only interested in the transition from executing->idle,
390ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        // not loaded->idle.
391892e1b9ab055075ba9036fb7dd6404e9e0f2677aAndreas Huber        mExecuting = false;
392ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    }
3936d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
394ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber}
395ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber
3966d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong ZhangStatus GraphicBufferSource::onOmxLoaded(){
397f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
398a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mLooper != NULL) {
399a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->unregisterHandler(mReflector->id());
400a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mReflector.clear();
401a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
402a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper->stop();
403a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        mLooper.clear();
404a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
405a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
40643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("--> loaded; available=%zu+%d eos=%d eosSent=%d acquired=%d",
40743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers,
40843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mEndOfStream, mEndOfStreamSent, mNumOutstandingAcquires);
409f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
410addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // Codec is no longer executing.  Releasing all buffers to bq.
41143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFreeCodecBuffers.clear();
41243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mSubmittedCodecBuffers.clear();
41343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLatestBuffer.mBuffer.reset();
414addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mOMXNode.clear();
415f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mExecuting = false;
416addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
4176d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
42043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos MolnarStatus GraphicBufferSource::onInputBufferAdded(codec_buffer_id bufferId) {
421f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mExecuting) {
424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen -- buffers can only be allocated when
425f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // transitioning from "loaded" to "idle".
426f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("addCodecBuffer: buffer added while executing");
4276d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return Status::fromServiceSpecificError(INVALID_OPERATION);
428f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
429f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
43043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("addCodecBuffer: bufferId=%u", bufferId);
4316cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang
43243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFreeCodecBuffers.push_back(bufferId);
4336d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
434f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
435f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
43643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos MolnarStatus GraphicBufferSource::onInputBufferEmptied(codec_buffer_id bufferId, int fenceFd) {
437f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
43843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    FileDescriptor::Autoclose fence(fenceFd);
439f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
44043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t cbi = mSubmittedCodecBuffers.indexOfKey(bufferId);
441f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (cbi < 0) {
442f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // This should never happen.
44343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGE("onInputBufferEmptied: buffer not recognized (bufferId=%u)", bufferId);
4446d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return Status::fromServiceSpecificError(BAD_VALUE);
445f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
446f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
44743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<AcquiredBuffer> buffer = mSubmittedCodecBuffers.valueAt(cbi);
44843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
44943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // Move buffer to available buffers
45043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mSubmittedCodecBuffers.removeItemsAt(cbi);
45143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFreeCodecBuffers.push_back(bufferId);
452f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
453f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // header->nFilledLen may not be the original value, so we can't compare
454f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // that to zero to see of this was the EOS buffer.  Instead we just
45543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // see if there is a null AcquiredBuffer, which should only ever happen for EOS.
45643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (buffer == nullptr) {
4575572b3afe3e63110ef9e6d228112ca7cbfac866bAndy McFadden        if (!(mEndOfStream && mEndOfStreamSent)) {
45843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            // This can happen when broken code sends us the same buffer twice in a row.
45943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGE("onInputBufferEmptied: non-EOS null buffer (bufferId=%u)", bufferId);
46043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        } else {
46143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGV("onInputBufferEmptied: EOS null buffer (bufferId=%u@%zd)", bufferId, cbi);
46215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
46343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // No GraphicBuffer to deal with, no additional input or output is expected, so just return.
4646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return Status::fromServiceSpecificError(BAD_VALUE);
465f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
466f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
46743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!mExecuting) {
46843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // this is fine since this could happen when going from Idle to Loaded
46943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: no longer executing (bufferId=%u@%zd)", bufferId, cbi);
47043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return Status::fromServiceSpecificError(OK);
471f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
472f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
47343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("onInputBufferEmptied: bufferId=%d@%zd [slot=%d, useCount=%ld, handle=%p] acquired=%d",
47443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            bufferId, cbi, buffer->getSlot(), buffer.use_count(), buffer->getGraphicBuffer()->handle,
47543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mNumOutstandingAcquires);
476f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
47743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    buffer->addReleaseFenceFd(fence.release());
47843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // release codec reference for video buffer just in case remove does not it
47943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    buffer.reset();
48043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
48143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (haveAvailableBuffers_l()) {
482f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Fill this codec buffer.
4830c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        CHECK(!mEndOfStreamSent);
48443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: buffer freed, feeding codec (available=%zu+%d, eos=%d)",
48543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
486f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        fillCodecBuffer_l();
487764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    } else if (mEndOfStream && mStopTimeUs == -1) {
488764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // No frames available, but EOS is pending and no stop time, so use this buffer to
489f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // send that.
49043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: buffer freed, submitting EOS");
491f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        submitEndOfInputStream_l();
49243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else if (mFrameRepeatBlockedOnCodecBuffer) {
49337b2b389139ed638831e49708c947863eef631efRonghua Wu        bool success = repeatLatestBuffer_l();
49443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onInputBufferEmptied: completing deferred repeatLatestBuffer_l %s",
49543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                success ? "SUCCESS" : "FAILURE");
49643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mFrameRepeatBlockedOnCodecBuffer = false;
497f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
498a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
49943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // releaseReleasableBuffers_l();
5006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return Status::ok();
501e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber}
502e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
50343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::onDataspaceChanged_l(
50443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        android_dataspace dataspace, android_pixel_format pixelFormat) {
50543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGD("got buffer with new dataSpace #%x", dataspace);
50643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLastDataspace = dataspace;
507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
50843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (ColorUtils::convertDataSpaceToV0(dataspace)) {
50943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mOMXNode->dispatchDataSpaceChanged(mLastDataspace, mDefaultColorAspectsPacked, pixelFormat);
510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5130c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFaddenbool GraphicBufferSource::fillCodecBuffer_l() {
51443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK(mExecuting && haveAvailableBuffers_l());
5150c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden
51643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFreeCodecBuffers.empty()) {
517f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // No buffers available, bail.
51843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("fillCodecBuffer_l: no codec buffers, available=%zu+%d",
51943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
5200c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        return false;
5210c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
522f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
52343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    VideoBuffer item;
52443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mAvailableBuffers.empty()) {
52543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("fillCodecBuffer_l: acquiring available buffer, available=%zu+%d",
52643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
52743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (acquireBuffer_l(&item) != OK) {
52843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGE("fillCodecBuffer_l: failed to acquire available buffer");
52943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return false;
53043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
53143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
53243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("fillCodecBuffer_l: getting available buffer, available=%zu+%d",
53343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
53443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        item = *mAvailableBuffers.begin();
53543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mAvailableBuffers.erase(mAvailableBuffers.begin());
5360c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    }
537f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
53843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int64_t itemTimeUs = item.mTimestampNs / 1000;
539f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
540764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Process ActionItem in the Queue if there is any. If a buffer's timestamp
541764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // is smaller than the first action's timestamp, no action need to be performed.
542764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // If buffer's timestamp is larger or equal than the last action's timestamp,
543764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // only the last action needs to be performed as all the acitions before the
544764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // the action are overridden by the last action. For the other cases, traverse
545764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // the Queue to find the newest action that with timestamp smaller or equal to
546764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // the buffer's timestamp. For example, an action queue like
547384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang    // [pause 1us], [resume 2us], [pause 3us], [resume 4us], [pause 5us].... Upon
548764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // receiving a buffer with timestamp 3.5us, only the action [pause, 3us] needs
549764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // to be handled and [pause, 1us], [resume 2us] will be discarded.
550764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    bool done = false;
55121bafd5a325aac30406fbb5dcff18812e0f44a45Hangyu Kuang    bool seeStopAction = false;
552764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (!mActionQueue.empty()) {
553764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // First scan to check if bufferTimestamp is smaller than first action's timestamp.
554764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ActionItem nextAction = *(mActionQueue.begin());
555764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (itemTimeUs < nextAction.mActionTimeUs) {
556764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGV("No action. buffer timestamp %lld us < action timestamp: %lld us",
557764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
558764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            // All the actions are ahead. No action need to perform now.
559764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            // Release the buffer if is in suspended state, or process the buffer
560764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            // if not in suspended state.
561764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            done = true;
562764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
563764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
564764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (!done) {
565384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang            // Find the newest action that with timestamp smaller than itemTimeUs. Then
566384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang            // remove all the actions before and include the newest action.
567764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            List<ActionItem>::iterator it = mActionQueue.begin();
56843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            while (it != mActionQueue.end() && it->mActionTimeUs <= itemTimeUs
56943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    && nextAction.mAction != ActionItem::STOP) {
570764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                nextAction = *it;
571764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                ++it;
572764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
573384cd775be62fff1635a36a7931f361db77220c0Hangyu Kuang            mActionQueue.erase(mActionQueue.begin(), it);
574764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
575764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            CHECK(itemTimeUs >= nextAction.mActionTimeUs);
576764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            switch (nextAction.mAction) {
577764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                case ActionItem::PAUSE:
578764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                {
579764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mSuspended = true;
580764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("RUNNING/PAUSE -> PAUSE at buffer %lld us  PAUSE Time: %lld us",
581764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                            (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
582764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    break;
583764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
584764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                case ActionItem::RESUME:
585764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                {
586764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mSuspended = false;
587764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("PAUSE/RUNNING -> RUNNING at buffer %lld us  RESUME Time: %lld us",
588764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                            (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
589764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    break;
590764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
591764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                case ActionItem::STOP:
592764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                {
593764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("RUNNING/PAUSE -> STOP at buffer %lld us  STOP Time: %lld us",
594764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                            (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
595764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    // Clear the whole ActionQueue as recording is done
596764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mActionQueue.clear();
59721bafd5a325aac30406fbb5dcff18812e0f44a45Hangyu Kuang                    seeStopAction = true;
598764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    break;
599764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
600764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                default:
60143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    TRESPASS_DBG("Unknown action type");
60243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // return true here because we did consume an available buffer, so the
60343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // loop in onOmxExecuting will eventually terminate even if we hit this.
604764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    return false;
605764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
606764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
607764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
608764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
60943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (seeStopAction) {
61043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // Clear all the buffers before setting mEndOfStream and signal EndOfInputStream.
61143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        releaseAllAvailableBuffers_l();
61243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mEndOfStream = true;
61343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        submitEndOfInputStream_l();
614764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        return true;
615764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
616764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
61743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mSuspended) {
61843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return true;
619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
62143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int err = UNKNOWN_ERROR;
62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // only submit sample if start time is unspecified, or sample
62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // is queued after the specified start time
62543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mSkipFramesBeforeNs < 0ll || item.mTimestampNs >= mSkipFramesBeforeNs) {
62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if start time is set, offset time stamp by start time
62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mSkipFramesBeforeNs > 0) {
62843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            item.mTimestampNs -= mSkipFramesBeforeNs;
62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
63037b2b389139ed638831e49708c947863eef631efRonghua Wu
63143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        int64_t timeUs = item.mTimestampNs / 1000;
63237b2b389139ed638831e49708c947863eef631efRonghua Wu        if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) {
63337b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs));
63437b2b389139ed638831e49708c947863eef631efRonghua Wu            // set err to OK so that the skipped frame can still be saved as the lastest frame
63537b2b389139ed638831e49708c947863eef631efRonghua Wu            err = OK;
63637b2b389139ed638831e49708c947863eef631efRonghua Wu        } else {
63743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            err = submitBuffer_l(item); // this takes shared ownership of the acquired buffer on succeess
63837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6410c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    if (err != OK) {
64243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("submitBuffer_l failed, will release bq slot %d", item.mBuffer->getSlot());
64343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        return true;
6440c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    } else {
645addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // Don't set the last buffer id if we're not repeating,
646addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // we'll be holding on to the last buffer for nothing.
64743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mFrameRepeatIntervalUs > 0ll) {
648addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            setLatestBuffer_l(item);
649addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        }
65043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("buffer submitted [slot=%d, useCount=%ld] acquired=%d",
65143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                item.mBuffer->getSlot(), item.mBuffer.use_count(), mNumOutstandingAcquires);
652a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
653a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
654a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    return true;
655a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
656a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
65737b2b389139ed638831e49708c947863eef631efRonghua Wubool GraphicBufferSource::repeatLatestBuffer_l() {
65843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK(mExecuting && !haveAvailableBuffers_l());
659a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
66043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mLatestBuffer.mBuffer == nullptr || mSuspended) {
661bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden        return false;
662bdfd4885aa4d7b3f3f591118927a3f4aec593096Andy McFadden    }
663a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
66443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFreeCodecBuffers.empty()) {
665a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        // No buffers available, bail.
66637b2b389139ed638831e49708c947863eef631efRonghua Wu        ALOGV("repeatLatestBuffer_l: no codec buffers.");
667a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
668a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
669a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
67043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!mLatestBuffer.mBuffer->isCached()) {
67143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("repeatLatestBuffer_l: slot was discarded, but repeating our own reference");
67243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
673a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
67443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // it is ok to update the timestamp of latest buffer as it is only used for submission
67543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = submitBuffer_l(mLatestBuffer);
676a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err != OK) {
677a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return false;
678f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
679f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
68094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    /* repeat last frame up to kRepeatLastFrameCount times.
68194ee4b708acfa941581160b267afb79192b1d816Chong Zhang     * in case of static scene, a single repeat might not get rid of encoder
68294ee4b708acfa941581160b267afb79192b1d816Chong Zhang     * ghosting completely, refresh a couple more times to get better quality
68394ee4b708acfa941581160b267afb79192b1d816Chong Zhang     */
68443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (--mOutstandingFrameRepeatCount > 0) {
68543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // set up timestamp for repeat frame
68643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
68743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        queueFrameRepeat_l();
68894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
68994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6900c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden    return true;
691f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
692f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
69343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::setLatestBuffer_l(const VideoBuffer &item) {
69443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLatestBuffer = item;
695a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
69643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("setLatestBuffer_l: [slot=%d, useCount=%ld]",
69743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mLatestBuffer.mBuffer->getSlot(), mLatestBuffer.mBuffer.use_count());
69894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
69943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mOutstandingFrameRepeatCount = kRepeatLastFrameCount;
70043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // set up timestamp for repeat frame
70143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
70243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    queueFrameRepeat_l();
70343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
704fdeac6c97d87aff25653d42d24d0c18c568c684aChong Zhang
70543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::queueFrameRepeat_l() {
70643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatBlockedOnCodecBuffer = false;
707a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
708a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mReflector != NULL) {
7091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
710a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        msg->setInt32("generation", ++mRepeatLastFrameGeneration);
71143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        msg->post(mFrameRepeatIntervalUs);
712a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
713a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
714a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
71543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarbool GraphicBufferSource::calculateCodecTimestamp_l(
71643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        nsecs_t bufferTimeNs, int64_t *codecTimeUs) {
71743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int64_t timeUs = bufferTimeNs / 1000;
71861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    timeUs += mInputBufferTimeOffsetUs;
71994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
72022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (mCaptureFps > 0.
72122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            && (mFps > 2 * mCaptureFps
72222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            || mCaptureFps > 2 * mFps)) {
7232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        // Time lapse or slow motion mode
7242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (mPrevCaptureUs < 0ll) {
7252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            // first capture
72622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevCaptureUs = mBaseCaptureUs = timeUs;
727bd83e4b3e77b31e089832bcfbebde086392216c9Hangyu Kuang            // adjust the first sample timestamp.
72822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevFrameUs = mBaseFrameUs =
72922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                    std::llround((timeUs * mCaptureFps) / mFps);
73022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mFrameCount = 0;
7312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        } else {
7322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            // snap to nearest capture point
73322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            int64_t nFrames = std::llround(
73422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                    (timeUs - mPrevCaptureUs) * mCaptureFps);
7352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            if (nFrames <= 0) {
7362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                // skip this frame as it's too close to previous capture
737a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
7386d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                return false;
7392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            }
74022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mFrameCount += nFrames;
74122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevCaptureUs = mBaseCaptureUs + std::llround(
74222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                    mFrameCount / mCaptureFps);
74322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mPrevFrameUs = mBaseFrameUs + std::llround(
74422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                    mFrameCount / mFps);
7452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
7462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
7472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        ALOGV("timeUs %lld, captureUs %lld, frameUs %lld",
748a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(timeUs),
749a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(mPrevCaptureUs),
750a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                static_cast<long long>(mPrevFrameUs));
75161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    } else {
75243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (timeUs <= mPrevFrameUs) {
75343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            // Drop the frame if it's going backward in time. Bad timestamp
75443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            // could disrupt encoder's rate control completely.
75561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGW("Dropping frame that's going backward in time");
7566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return false;
75761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
75861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
75943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mPrevFrameUs = timeUs;
76094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
76194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
76243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    *codecTimeUs = mPrevFrameUs;
7636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return true;
76494ee4b708acfa941581160b267afb79192b1d816Chong Zhang}
76594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
76643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstatus_t GraphicBufferSource::submitBuffer_l(const VideoBuffer &item) {
76743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK(!mFreeCodecBuffers.empty());
76843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
76943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
77043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("submitBuffer_l [slot=%d, bufferId=%d]", item.mBuffer->getSlot(), codecBufferId);
771b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang
7723604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang    int64_t codecTimeUs;
77343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!calculateCodecTimestamp_l(item.mTimestampNs, &codecTimeUs)) {
774b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang        return UNKNOWN_ERROR;
775b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang    }
776b63d2433350d56bda9f3477549086c90bb6d535eChong Zhang
77743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if ((android_dataspace)item.mDataspace != mLastDataspace) {
77843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        onDataspaceChanged_l(
77943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                item.mDataspace,
78043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                (android_pixel_format)item.mBuffer->getGraphicBuffer()->format);
78143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
7826cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang
78343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<AcquiredBuffer> buffer = item.mBuffer;
78443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // use a GraphicBuffer for now as OMXNodeInstance is using GraphicBuffers to hold references
78543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // and it requires this graphic buffer to be able to hold its reference
78643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // and thus we would need to create a new GraphicBuffer from an ANWBuffer separate from the
78743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // acquired GraphicBuffer.
78843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // TODO: this can be reworked globally to use ANWBuffer references
78943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    sp<GraphicBuffer> graphicBuffer = buffer->getGraphicBuffer();
7903fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    status_t err = mOMXNode->emptyBuffer(
79143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME, graphicBuffer, codecTimeUs,
79243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            buffer->getAcquireFenceFd());
7936cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang
794f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
7956cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ALOGW("WARNING: emptyGraphicBuffer failed: 0x%x", err);
796f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
797f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
798f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
799195f1ed9563ea2264dbca8c783695d9741dab3d8Lajos Molnar    mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
800195f1ed9563ea2264dbca8c783695d9741dab3d8Lajos Molnar
80143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, buffer);
80243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("emptyGraphicBuffer succeeded, bufferId=%u@%zd bufhandle=%p",
80343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            codecBufferId, cbix, graphicBuffer->handle);
804f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
805f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
806f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
807f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::submitEndOfInputStream_l() {
808f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(mEndOfStream);
809f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (mEndOfStreamSent) {
810f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("EOS already sent");
811f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
812f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
813f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
81443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mFreeCodecBuffers.empty()) {
815f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGV("submitEndOfInputStream_l: no codec buffers available");
816f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return;
817f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
81843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
819f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
82043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // We reject any additional incoming graphic buffers. There is no acquired buffer used for EOS
82143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = mOMXNode->emptyBuffer(
82243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
823f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
824f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
825f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else {
826195f1ed9563ea2264dbca8c783695d9741dab3d8Lajos Molnar        mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
82743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, nullptr);
82843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("submitEndOfInputStream_l: buffer submitted, bufferId=%u@%zd", codecBufferId, cbix);
8290c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden        mEndOfStreamSent = true;
8301f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar
8311f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar        // no need to hold onto any buffers for frame repeating
8321f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar        ++mRepeatLastFrameGeneration;
8331f0fa90d7c345d44b319705602770dcba36ca23bLajos Molnar        mLatestBuffer.mBuffer.reset();
834f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
835f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
836f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
83743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstatus_t GraphicBufferSource::acquireBuffer_l(VideoBuffer *ab) {
83843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    BufferItem bi;
83943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = mConsumer->acquireBuffer(&bi, 0);
840addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
841addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // shouldn't happen
84243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("acquireBuffer_l: frame was not available");
843addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
844addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    } else if (err != OK) {
84543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("acquireBuffer_l: failed with err=%d", err);
846addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
847addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
84843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    --mNumAvailableUnacquiredBuffers;
849addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
85043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // Manage our buffer cache.
85143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<CachedBuffer> buffer;
85243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t bsi = mBufferSlots.indexOfKey(bi.mSlot);
85343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (bi.mGraphicBuffer != NULL) {
85443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // replace/initialize slot with new buffer
85543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("acquireBuffer_l: %s buffer slot %d", bsi < 0 ? "setting" : "UPDATING", bi.mSlot);
85643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (bsi >= 0) {
85743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            discardBufferAtSlotIndex_l(bsi);
85843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        } else {
85943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            bsi = mBufferSlots.add(bi.mSlot, nullptr);
86043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
86143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        buffer = std::make_shared<CachedBuffer>(bi.mSlot, bi.mGraphicBuffer);
86243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mBufferSlots.replaceValueAt(bsi, buffer);
86343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
86443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        buffer = mBufferSlots.valueAt(bsi);
86543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
86643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    int64_t frameNum = bi.mFrameNumber;
86743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
86843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<AcquiredBuffer> acquiredBuffer =
86943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        std::make_shared<AcquiredBuffer>(
87043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                buffer,
87143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                [frameNum, this](AcquiredBuffer *buffer){
87243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // AcquiredBuffer's destructor should always be called when mMutex is locked.
87343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // If we had a reentrant mutex, we could just lock it again to ensure this.
87443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    if (mMutex.tryLock() == 0) {
87543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        TRESPASS_DBG();
87643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        mMutex.unlock();
87743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    }
87843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
87943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // we can release buffers immediately if not using adapters
88043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // alternately, we could add them to mSlotsToRelease, but we would
88143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    // somehow need to propagate frame number to that queue
88243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    if (buffer->isCached()) {
88343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        --mNumOutstandingAcquires;
88443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                        mConsumer->releaseBuffer(
88543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                buffer->getSlot(), frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
88643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                buffer->getReleaseFence());
88743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    }
88843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                },
88943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                bi.mFence);
89043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    VideoBuffer videoBuffer{acquiredBuffer, bi.mTimestamp, bi.mDataSpace};
89143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    *ab = videoBuffer;
89243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ++mNumOutstandingAcquires;
89343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    return OK;
8949700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang}
8959700f5fe4b3becfe858cbf5aa7964296975081bbChong Zhang
896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
89743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::onFrameAvailable(const BufferItem& item __unused) {
898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mMutex);
899f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
90043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("onFrameAvailable: executing=%d available=%zu+%d",
90143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
90243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ++mNumAvailableUnacquiredBuffers;
903e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
90443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // For BufferQueue we cannot acquire a buffer if we cannot immediately feed it to the codec
90502cccfd9e790ba8758aba2b4f2a600a7d8fd1566Lajos Molnar    // UNLESS we are discarding this buffer (acquiring and immediately releasing it), which makes
90643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // this an ugly logic.
90743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // NOTE: We could also rely on our debug counter but that is meant only as a debug counter.
90843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (!areWeDiscardingAvailableBuffers_l() && mFreeCodecBuffers.empty()) {
90943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // we may not be allowed to acquire a possibly encodable buffer, so just note that
91043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // it is available
91143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onFrameAvailable: cannot acquire buffer right now, do it later");
912f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
91343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
91402cccfd9e790ba8758aba2b4f2a600a7d8fd1566Lajos Molnar        return;
915f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
916f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
91743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    VideoBuffer buffer;
91843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    status_t err = acquireBuffer_l(&buffer);
91943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (err != OK) {
92043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGE("onFrameAvailable: acquireBuffer returned err=%d", err);
92143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
92243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        onBufferAcquired_l(buffer);
92343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
92443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
925f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
92643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarbool GraphicBufferSource::areWeDiscardingAvailableBuffers_l() {
92743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    return mEndOfStreamSent // already sent EOS to codec
92843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            || mOMXNode == nullptr // there is no codec connected
92943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            || (mSuspended && mActionQueue.empty()) // we are suspended and not waiting for
93043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                                                    // any further action
93143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            || !mExecuting;
93243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
933a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
93443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::onBufferAcquired_l(const VideoBuffer &buffer) {
93543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mEndOfStreamSent) {
93643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // This should only be possible if a new buffer was queued after
93743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // EOS was signaled, i.e. the app is misbehaving.
93843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("onFrameAvailable: EOS is sent, ignoring frame");
93943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else if (mOMXNode == NULL || (mSuspended && mActionQueue.empty())) {
94043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // FIXME: if we are suspended but have a resume queued we will stop repeating the last
94143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // frame. Is that the desired behavior?
94243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGV("onFrameAvailable: suspended, ignoring frame");
94343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
94443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
94543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mAvailableBuffers.push_back(buffer);
94643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (mExecuting) {
94743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            fillCodecBuffer_l();
94843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
949f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
950f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
951f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
952f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// BufferQueue::ConsumerListener callback
953f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid GraphicBufferSource::onBuffersReleased() {
954f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock lock(mMutex);
955f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
9562475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza    uint64_t slotMask;
9575205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) {
958f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("onBuffersReleased: unable to get released buffer set");
9592475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza        slotMask = 0xffffffffffffffffULL;
960f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
961f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
9622475264264b51a7592c5b2e4cd6cfdaddba16644Dan Stoza    ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask);
963f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
964f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
965f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        if ((slotMask & 0x01) != 0) {
96643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            discardBufferInSlot_l(i);
967f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
968f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        slotMask >>= 1;
969f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
970f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
971f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
97243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::discardBufferInSlot_l(GraphicBufferSource::slot_id i) {
97343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ssize_t bsi = mBufferSlots.indexOfKey(i);
97443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (bsi < 0) {
97543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGW("releasing an unpopulated slot: %d", i);
97643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    } else {
97743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        discardBufferAtSlotIndex_l(bsi);
97843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mBufferSlots.removeItemsAt(bsi);
97943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
98043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
98143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
98243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t bsi) {
98343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    const std::shared_ptr<CachedBuffer>& buffer = mBufferSlots.valueAt(bsi);
98443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // use -2 if there is no latest buffer, and -1 if it is no longer cached
98543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    slot_id latestBufferSlot =
98643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mBuffer == nullptr ? -2 : mLatestBuffer.mBuffer->getSlot();
98743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("releasing acquired buffer: [slot=%d, useCount=%ld], latest: [slot=%d]",
98843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mBufferSlots.keyAt(bsi), buffer.use_count(), latestBufferSlot);
98943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mBufferSlots.valueAt(bsi)->onDroppedFromCache();
99043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
99143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // If the slot of an acquired buffer is discarded, that buffer will not have to be
99243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // released to the producer, so account it here. However, it is possible that the
99343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // acquired buffer has already been discarded so check if it still is.
99443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (buffer->isAcquired()) {
99543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        --mNumOutstandingAcquires;
99643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
99743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
99843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // clear the buffer reference (not technically needed as caller either replaces or deletes
99943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // it; done here for safety).
100043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mBufferSlots.editValueAt(bsi).reset();
100143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    CHECK_DBG(buffer == nullptr);
100243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
100343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
100443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarvoid GraphicBufferSource::releaseAllAvailableBuffers_l() {
100543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mAvailableBuffers.clear();
100643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    while (mNumAvailableUnacquiredBuffers > 0) {
100743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        VideoBuffer item;
100843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        if (acquireBuffer_l(&item) != OK) {
100943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            ALOGW("releaseAllAvailableBuffers: failed to acquire available unacquired buffer");
101043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            break;
101143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
101243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    }
101343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}
101443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
10158dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall// BufferQueue::ConsumerListener callback
10168dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid GraphicBufferSource::onSidebandStreamChanged() {
10178dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall    ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
10188dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall}
10198dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall
1020d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::configure(
1021d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        const sp<IOmxNodeWrapper>& omxNode,
1022d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int32_t dataSpace,
1023d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int32_t bufferCount,
1024d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        uint32_t frameWidth,
1025d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        uint32_t frameHeight,
1026d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        uint32_t consumerUsage) {
1027addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (omxNode == NULL) {
1028d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return BAD_VALUE;
1029addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
1030addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1031addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1032addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // Call setMaxAcquiredBufferCount without lock.
1033addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // setMaxAcquiredBufferCount could call back to onBuffersReleased
1034addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // if the buffer count change results in releasing of existing buffers,
1035addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    // which would lead to deadlock.
1036d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    status_t err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
1037addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != NO_ERROR) {
1038addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
1039d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                bufferCount, err);
1040d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return err;
1041addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
1042addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1043addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    {
1044addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        Mutex::Autolock autoLock(mMutex);
1045addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mOMXNode = omxNode;
1046addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1047d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        err = mConsumer->setDefaultBufferSize(frameWidth, frameHeight);
1048addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        if (err != NO_ERROR) {
1049addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            ALOGE("Unable to set BQ default buffer size to %ux%u: %d",
1050d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                    frameWidth, frameHeight, err);
1051d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return err;
1052addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        }
1053addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1054addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
1055addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mConsumer->setConsumerUsageBits(consumerUsage);
1056addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1057addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        // Sets the default buffer data space
105843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
1059addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
106043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLastDataspace = (android_dataspace)dataSpace;
1061addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1062addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mExecuting = false;
1063addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mSuspended = false;
1064addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mEndOfStream = false;
1065addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mEndOfStreamSent = false;
1066addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mSkipFramesBeforeNs = -1ll;
106743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mFrameRepeatIntervalUs = -1ll;
1068addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mRepeatLastFrameGeneration = 0;
106943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mOutstandingFrameRepeatCount = 0;
107043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mLatestBuffer.mBuffer.reset();
107143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        mFrameRepeatBlockedOnCodecBuffer = false;
107222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFps = -1.0;
107322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mCaptureFps = -1.0;
107422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mBaseCaptureUs = -1ll;
107522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mBaseFrameUs = -1ll;
1076addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mPrevCaptureUs = -1ll;
1077addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mPrevFrameUs = -1ll;
107822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFrameCount = 0;
1079addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mInputBufferTimeOffsetUs = 0;
1080764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mStopTimeUs = -1;
1081764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mActionQueue.clear();
1082addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
1083addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
1084d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
108557fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar}
108657fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
1087d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
1088764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    ALOGV("setSuspend=%d at time %lld us", suspend, (long long)suspendStartTimeUs);
10896d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
10906d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    Mutex::Autolock autoLock(mMutex);
10916d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1092764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (mStopTimeUs != -1) {
1093764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGE("setSuspend failed as STOP action is pending");
1094d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1095764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
10966d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1097764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Push the action to the queue.
1098764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (suspendStartTimeUs != -1) {
1099764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // suspendStartTimeUs must be smaller or equal to current systemTime.
1100764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        int64_t currentSystemTimeUs = systemTime() / 1000;
1101764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (suspendStartTimeUs > currentSystemTimeUs) {
1102764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("setSuspend failed. %lld is larger than current system time %lld us",
1103764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    (long long)suspendStartTimeUs, (long long)currentSystemTimeUs);
1104d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return INVALID_OPERATION;
1105764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
1106764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mLastActionTimeUs != -1 && suspendStartTimeUs < mLastActionTimeUs) {
1107764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
1108764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    (long long)suspendStartTimeUs, (long long)mLastActionTimeUs);
1109d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return INVALID_OPERATION;
1110764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
1111764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mLastActionTimeUs = suspendStartTimeUs;
1112764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ActionItem action;
1113764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        action.mAction = suspend ? ActionItem::PAUSE : ActionItem::RESUME;
1114764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        action.mActionTimeUs = suspendStartTimeUs;
1115764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGV("Push %s action into actionQueue", suspend ? "PAUSE" : "RESUME");
1116764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mActionQueue.push_back(action);
1117764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    } else {
1118764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (suspend) {
1119764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            mSuspended = true;
112043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            releaseAllAvailableBuffers_l();
1121d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            return OK;
1122764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        } else {
1123764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            mSuspended = false;
112443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            if (mExecuting && !haveAvailableBuffers_l()
112543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    && mFrameRepeatBlockedOnCodecBuffer) {
1126764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                if (repeatLatestBuffer_l()) {
1127764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS");
112843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                    mFrameRepeatBlockedOnCodecBuffer = false;
1129764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                } else {
1130764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE");
1131764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                }
1132764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
11336d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
11346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1135d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
11366d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
11376d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1138d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
11396d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    ALOGV("setRepeatPreviousFrameDelayUs: delayUs=%lld", (long long)repeatAfterUs);
11406d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    Mutex::Autolock autoLock(mMutex);
1142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mExecuting || repeatAfterUs <= 0ll) {
1144d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1145a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
1146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
114743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mFrameRepeatIntervalUs = repeatAfterUs;
1148d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
1149a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
115072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1151d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
115261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    Mutex::Autolock autoLock(mMutex);
115361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
115461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    // timeOffsetUs must be negative for adjustment.
115561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (timeOffsetUs >= 0ll) {
1156d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
115761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
115861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
115961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    mInputBufferTimeOffsetUs = timeOffsetUs;
1160d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
116161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang}
116261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
1163d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setMaxFps(float maxFps) {
11646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    ALOGV("setMaxFps: maxFps=%lld", (long long)maxFps);
11656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
116637b2b389139ed638831e49708c947863eef631efRonghua Wu    Mutex::Autolock autoLock(mMutex);
116737b2b389139ed638831e49708c947863eef631efRonghua Wu
116837b2b389139ed638831e49708c947863eef631efRonghua Wu    if (mExecuting) {
1169d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
117037b2b389139ed638831e49708c947863eef631efRonghua Wu    }
117137b2b389139ed638831e49708c947863eef631efRonghua Wu
117237b2b389139ed638831e49708c947863eef631efRonghua Wu    mFrameDropper = new FrameDropper();
117337b2b389139ed638831e49708c947863eef631efRonghua Wu    status_t err = mFrameDropper->setMaxFrameRate(maxFps);
117437b2b389139ed638831e49708c947863eef631efRonghua Wu    if (err != OK) {
117537b2b389139ed638831e49708c947863eef631efRonghua Wu        mFrameDropper.clear();
1176d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return err;
117737b2b389139ed638831e49708c947863eef631efRonghua Wu    }
117837b2b389139ed638831e49708c947863eef631efRonghua Wu
1179d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
118037b2b389139ed638831e49708c947863eef631efRonghua Wu}
118137b2b389139ed638831e49708c947863eef631efRonghua Wu
1182d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
11836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    ALOGV("setStartTimeUs: skipFramesBeforeUs=%lld", (long long)skipFramesBeforeUs);
11846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
118572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    Mutex::Autolock autoLock(mMutex);
118672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
118772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mSkipFramesBeforeNs =
118872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
11896d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1190d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
119172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
119272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1193d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
1194764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    ALOGV("setStopTimeUs: %lld us", (long long)stopTimeUs);
1195764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    Mutex::Autolock autoLock(mMutex);
1196764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1197764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (mStopTimeUs != -1) {
1198764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        // Ignore if stop time has already been set
1199d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return OK;
1200764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1201764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1202764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // stopTimeUs must be smaller or equal to current systemTime.
1203764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    int64_t currentSystemTimeUs = systemTime() / 1000;
1204764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (stopTimeUs > currentSystemTimeUs) {
1205764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGE("setStopTimeUs failed. %lld is larger than current system time %lld us",
1206764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            (long long)stopTimeUs, (long long)currentSystemTimeUs);
1207d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1208764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1209764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (mLastActionTimeUs != -1 && stopTimeUs < mLastActionTimeUs) {
1210764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
1211764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            (long long)stopTimeUs, (long long)mLastActionTimeUs);
1212d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
1213764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1214764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mLastActionTimeUs = stopTimeUs;
1215764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    ActionItem action;
1216764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    action.mAction = ActionItem::STOP;
1217764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    action.mActionTimeUs = stopTimeUs;
1218764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mActionQueue.push_back(action);
1219764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    mStopTimeUs = stopTimeUs;
1220d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
1221764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang}
1222764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
122322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasastatus_t GraphicBufferSource::setTimeLapseConfig(double fps, double captureFps) {
122422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    ALOGV("setTimeLapseConfig: fps=%lg, captureFps=%lg",
122522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            fps, captureFps);
12266d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
12272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    Mutex::Autolock autoLock(mMutex);
12282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
122922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (mExecuting || !(fps > 0) || !(captureFps > 0)) {
1230d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
12312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
12322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
123322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mFps = fps;
123422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    mCaptureFps = captureFps;
12352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
1236d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
12372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang}
12382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
1239d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
1240dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar    Mutex::Autolock autoLock(mMutex);
124143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    mDefaultColorAspectsPacked = aspectsPacked;
1242d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    ColorAspects colorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
1243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))",
1244d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mRange, asString(colorAspects.mRange),
1245d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mPrimaries, asString(colorAspects.mPrimaries),
1246d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mMatrixCoeffs, asString(colorAspects.mMatrixCoeffs),
1247d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            colorAspects.mTransfer, asString(colorAspects.mTransfer));
12486d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1249d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
12506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
12516d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1252d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatus_t GraphicBufferSource::signalEndOfInputStream() {
12536d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    Mutex::Autolock autoLock(mMutex);
125443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    ALOGV("signalEndOfInputStream: executing=%d available=%zu+%d eos=%d",
125543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
12566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
12576d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mEndOfStream) {
12586d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        ALOGE("EOS was already signaled");
1259d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return INVALID_OPERATION;
12606d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
12616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
12626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Set the end-of-stream flag.  If no frames are pending from the
12636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // BufferQueue, and a codec buffer is available, and we're executing,
1264764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // and there is no stop timestamp, we initiate the EOS from here.
1265764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Otherwise, we'll let codecBufferEmptied() (or omxExecuting) do it.
12666d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    //
12676d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Note: if there are no pending frames and all codec buffers are
12686d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // available, we *must* submit the EOS from here or we'll just
12696d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // stall since no future events are expected.
12706d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mEndOfStream = true;
12716d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
127243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    if (mStopTimeUs == -1 && mExecuting && !haveAvailableBuffers_l()) {
12736d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        submitEndOfInputStream_l();
12746d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
12756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
1276d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return OK;
1277dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar}
1278dd81af7ef969981748f35ec839869d34ed0cc768Lajos Molnar
1279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Hubervoid GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
1280a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    switch (msg->what()) {
1281a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        case kWhatRepeatLastFrame:
1282a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        {
1283a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            Mutex::Autolock autoLock(mMutex);
1284a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1285a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            int32_t generation;
1286a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            CHECK(msg->findInt32("generation", &generation));
1287a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1288a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (generation != mRepeatLastFrameGeneration) {
1289a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                // stale
1290a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                break;
1291a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
1292a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
129343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            if (!mExecuting || haveAvailableBuffers_l()) {
1294a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                break;
1295a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
1296a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
129737b2b389139ed638831e49708c947863eef631efRonghua Wu            bool success = repeatLatestBuffer_l();
1298a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (success) {
129937b2b389139ed638831e49708c947863eef631efRonghua Wu                ALOGV("repeatLatestBuffer_l SUCCESS");
1300a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            } else {
130137b2b389139ed638831e49708c947863eef631efRonghua Wu                ALOGV("repeatLatestBuffer_l FAILURE");
130243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mFrameRepeatBlockedOnCodecBuffer = true;
1303a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
1304a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            break;
1305a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1306a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1307a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        default:
1308a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            TRESPASS();
1309a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
1310a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
1311a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1312f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}  // namespace android
1313