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