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