1033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/* 2033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Copyright 2017, The Android Open Source Project 3033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 4033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Licensed under the Apache License, Version 2.0 (the "License"); 5033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * you may not use this file except in compliance with the License. 6033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * You may obtain a copy of the License at 7033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 8033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * http://www.apache.org/licenses/LICENSE-2.0 9033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 10033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Unless required by applicable law or agreed to in writing, software 11033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * distributed under the License is distributed on an "AS IS" BASIS, 12033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * See the License for the specific language governing permissions and 14033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * limitations under the License. 15033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 16033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 17033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim//#define LOG_NDEBUG 0 18033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define LOG_TAG "CCodecBufferChannel" 19033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/Log.h> 20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <numeric> 22033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <thread> 23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 24033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2AllocatorGralloc.h> 25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h> 26033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2BlockInternal.h> 27a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar#include <C2Config.h> 288b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin#include <C2Debug.h> 29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <android/hardware/cas/native/1.0/IDescrambler.h> 31033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <binder/MemoryDealer.h> 32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <gui/Surface.h> 33033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/openmax/OMX_Core.h> 34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/ABuffer.h> 35b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar#include <media/stagefright/foundation/ALookup.h> 36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/AMessage.h> 37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/AUtils.h> 383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <media/stagefright/foundation/hexdump.h> 39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/MediaCodec.h> 400fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar#include <media/stagefright/MediaCodecConstants.h> 41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/MediaCodecBuffer.h> 42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <system/window.h> 43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "CCodecBufferChannel.h" 45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "Codec2Buffer.h" 46dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim#include "SkipCutBuffer.h" 47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android { 49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing hardware::hidl_handle; 51033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing hardware::hidl_string; 52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing hardware::hidl_vec; 53033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing namespace hardware::cas::V1_0; 54033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing namespace hardware::cas::native::V1_0; 55033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 56033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing CasStatus = hardware::cas::V1_0::Status; 57033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 58033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/** 59033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Base class for representation of buffers at one port. 60033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 61033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass CCodecBufferChannel::Buffers { 62033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 63033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Buffers() = default; 64033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual ~Buffers() = default; 65033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 66033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 67033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Set format for MediaCodec-facing buffers. 68033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 69033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void setFormat(const sp<AMessage> &format) { 70033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(format != nullptr); 71033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mFormat = format; 72033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 73033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 74033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 758c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim * Return a copy of current format. 768c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim */ 778c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim sp<AMessage> dupFormat() { 788c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim return mFormat != nullptr ? mFormat->dup() : nullptr; 798c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim } 808c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim 818c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim /** 82033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Returns true if the buffers are operating under array mode. 83033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 84033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual bool isArrayMode() const { return false; } 85033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 86033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 87033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Fills the vector with MediaCodecBuffer's if in array mode; otherwise, 88033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * no-op. 89033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 90033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual void getArray(Vector<sp<MediaCodecBuffer>> *) const {} 91033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 92033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprotected: 93033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Format to be used for creating MediaCodec-facing buffers. 94033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> mFormat; 95033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 96033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 97033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DISALLOW_EVIL_CONSTRUCTORS(Buffers); 98033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 99033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass CCodecBufferChannel::InputBuffers : public CCodecBufferChannel::Buffers { 101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 102033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim InputBuffers() = default; 103033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual ~InputBuffers() = default; 104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 106033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Set a block pool to obtain input memory blocks. 107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void setPool(const std::shared_ptr<C2BlockPool> &pool) { mPool = pool; } 109033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 111033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Get a new MediaCodecBuffer for input and its corresponding index. 112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Returns false if no new buffer can be obtained at the moment. 113033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 114033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) = 0; 115033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 116033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 117033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Release the buffer obtained from requestNewBuffer() and get the 118e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * associated C2Buffer object back. Returns true if the buffer was on file 119e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * and released successfully. 120033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 121e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim virtual bool releaseBuffer( 122e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) = 0; 123033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 124033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Flush internal state. After this call, no index or buffer previously 126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * returned from requestNewBuffer() is valid. 127033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 128033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual void flush() = 0; 129033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 130033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Return array-backed version of input buffers. The returned object 132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * shall retain the internal state so that it will honor index and 133033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * buffer from previous calls of requestNewBuffer(). 134033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 135033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual std::unique_ptr<InputBuffers> toArrayMode() = 0; 136033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprotected: 138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Pool to obtain blocks for input buffers. 139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2BlockPool> mPool; 140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DISALLOW_EVIL_CONSTRUCTORS(InputBuffers); 143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass CCodecBufferChannel::OutputBuffers : public CCodecBufferChannel::Buffers { 146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim OutputBuffers() = default; 148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual ~OutputBuffers() = default; 149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Register output C2Buffer from the component and obtain corresponding 152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * index and MediaCodecBuffer object. Returns false if registration 153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * fails. 154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual bool registerBuffer( 156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2Buffer> &buffer, 157033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t *index, 158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> *clientBuffer) = 0; 159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Register codec specific data as a buffer to be consistent with 162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * MediaCodec behavior. 163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual bool registerCsd( 165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const C2StreamCsdInfo::output * /* csd */, 166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t * /* index */, 167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> * /* clientBuffer */) = 0; 168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Release the buffer obtained from registerBuffer() and get the 171e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * associated C2Buffer object back. Returns true if the buffer was on file 172e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * and released successfully. 173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 174e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim virtual bool releaseBuffer( 175e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) = 0; 176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Flush internal state. After this call, no index or buffer previously 179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * returned from registerBuffer() is valid. 180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) = 0; 182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Return array-backed version of output buffers. The returned object 185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * shall retain the internal state so that it will honor index and 186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * buffer from previous calls of registerBuffer(). 187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual std::unique_ptr<OutputBuffers> toArrayMode() = 0; 189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 190dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim /** 191dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim * Initialize SkipCutBuffer object. 192dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim */ 193dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim void initSkipCutBuffer( 194dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t delay, int32_t padding, int32_t sampleRate, int32_t channelCount) { 195dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim CHECK(mSkipCutBuffer == nullptr); 196dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mDelay = delay; 197dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mPadding = padding; 198dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mSampleRate = sampleRate; 199dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim setSkipCutBuffer(delay, padding, channelCount); 200dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 201dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 202dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim /** 203dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim * Update the SkipCutBuffer object. No-op if it's never initialized. 204dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim */ 205dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim void updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount) { 206dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (mSkipCutBuffer == nullptr) { 207dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim return; 208dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 209dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t delay = mDelay; 210dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t padding = mPadding; 211dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (sampleRate != mSampleRate) { 212dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim delay = ((int64_t)delay * sampleRate) / mSampleRate; 213dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim padding = ((int64_t)padding * sampleRate) / mSampleRate; 214dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 215dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim setSkipCutBuffer(delay, padding, channelCount); 216dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 217dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 218dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim /** 219dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim * Submit buffer to SkipCutBuffer object, if initialized. 220dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim */ 221dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim void submit(const sp<MediaCodecBuffer> &buffer) { 222dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (mSkipCutBuffer != nullptr) { 223dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mSkipCutBuffer->submit(buffer); 224dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 225dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 226dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 227dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim /** 228dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim * Transfer SkipCutBuffer object to the other Buffers object. 229dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim */ 230dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim void transferSkipCutBuffer(const sp<SkipCutBuffer> &scb) { 231dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mSkipCutBuffer = scb; 232dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 233dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 234dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kimprotected: 235dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim sp<SkipCutBuffer> mSkipCutBuffer; 236dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 238dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t mDelay; 239dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t mPadding; 240dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t mSampleRate; 241dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 242dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim void setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount) { 243dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (mSkipCutBuffer != nullptr) { 244dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim size_t prevSize = mSkipCutBuffer->size(); 245dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (prevSize != 0u) { 246dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim ALOGD("Replacing SkipCutBuffer holding %zu bytes", prevSize); 247dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 248dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 249dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mSkipCutBuffer = new SkipCutBuffer(skip, cut, channelCount); 250dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 251dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers); 253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace { 256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// TODO: get this info from component 25860e4b7347394676287f7686ddced77544a106831Wonsik Kimconst static size_t kMinInputBufferArraySize = 8; 25960e4b7347394676287f7686ddced77544a106831Wonsik Kimconst static size_t kMinOutputBufferArraySize = 16; 2607037093412552e6dd8b5633e5e32a0d34c998d3aPawin Vongmasaconst static size_t kLinearBufferSize = 1048576; 261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 262033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/** 263033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Simple local buffer pool backed by std::vector. 264033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 265033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass LocalBufferPool : public std::enable_shared_from_this<LocalBufferPool> { 266033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Create a new LocalBufferPool object. 269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param poolCapacity max total size of buffers managed by this pool. 271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \return a newly created pool object. 273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim static std::shared_ptr<LocalBufferPool> Create(size_t poolCapacity) { 275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(poolCapacity)); 276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Return an ABuffer object whose size is at least |capacity|. 280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param capacity requested capacity 282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \return nullptr if the pool capacity is reached 283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * an ABuffer object otherwise. 284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<ABuffer> newBuffer(size_t capacity) { 286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutex::Autolock lock(mMutex); 287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto it = std::find_if( 288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mPool.begin(), mPool.end(), 289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [capacity](const std::vector<uint8_t> &vec) { 290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return vec.capacity() >= capacity; 291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (it != mPool.end()) { 293033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this()); 294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mPool.erase(it); 295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return buffer; 296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mUsedSize + capacity > mPoolCapacity) { 298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (!mPool.empty()) { 299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mUsedSize -= mPool.back().capacity(); 300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mPool.pop_back(); 301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mUsedSize + capacity > mPoolCapacity) { 303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu", 304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mUsedSize, capacity, mPoolCapacity); 305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<uint8_t> vec(capacity); 309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mUsedSize += vec.capacity(); 310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new VectorBuffer(std::move(vec), shared_from_this()); 311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * ABuffer backed by std::vector. 316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim class VectorBuffer : public ::android::ABuffer { 318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim public: 319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Construct a VectorBuffer by taking the ownership of supplied vector. 321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param vec backing vector of the buffer. this object takes 323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * ownership at construction. 324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param pool a LocalBufferPool object to return the vector at 325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * destruction. 326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim VectorBuffer(std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool) 328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim : ABuffer(vec.data(), vec.capacity()), 329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mVec(std::move(vec)), 330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mPool(pool) { 331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~VectorBuffer() override { 334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<LocalBufferPool> pool = mPool.lock(); 335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (pool) { 336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // If pool is alive, return the vector back to the pool so that 337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // it can be recycled. 338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim pool->returnVector(std::move(mVec)); 339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim private: 343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<uint8_t> mVec; 344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::weak_ptr<LocalBufferPool> mPool; 345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutex mMutex; 348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t mPoolCapacity; 349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t mUsedSize; 350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::list<std::vector<uint8_t>> mPool; 351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Private constructor to prevent constructing non-managed LocalBufferPool. 354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim explicit LocalBufferPool(size_t poolCapacity) 356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim : mPoolCapacity(poolCapacity), mUsedSize(0) { 357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Take back the ownership of vec from the destructed VectorBuffer and put 361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * it in front of the pool. 362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void returnVector(std::vector<uint8_t> &&vec) { 364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutex::Autolock lock(mMutex); 365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mPool.push_front(std::move(vec)); 366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DISALLOW_EVIL_CONSTRUCTORS(LocalBufferPool); 369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimsp<GraphicBlockBuffer> AllocateGraphicBuffer( 372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<AMessage> &format, 374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t pixelFormat, 375033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const C2MemoryUsage &usage, 376033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<LocalBufferPool> &localBufferPool) { 377033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t width, height; 378033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) { 379033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("format lacks width or height"); 380033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 381033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 382033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 383033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2GraphicBlock> block; 384033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = pool->fetchGraphicBlock( 385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim width, height, pixelFormat, usage, &block); 386033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("fetch graphic block failed: %d", err); 388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return GraphicBlockBuffer::Allocate( 392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim format, 393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim block, 394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [localBufferPool](size_t capacity) { 395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return localBufferPool->newBuffer(capacity); 396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass BuffersArrayImpl; 400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/** 402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Flexible buffer slots implementation. 403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass FlexBuffersImpl { 405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim FlexBuffersImpl() = default; 407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Assign an empty slot for a buffer and return the index. If there's no 410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * empty slot, just add one at the end and return it. 411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 412033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param buffer[in] a new buffer to assign a slot. 413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \return index of the assigned slot. 414033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 415033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t assignSlot(const sp<Codec2Buffer> &buffer) { 416033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < mBuffers.size(); ++i) { 417d15ef3cef65de483190c1bd8458074ce7d064202Praveen Chavan if (mBuffers[i].clientBuffer == nullptr 418033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim && mBuffers[i].compBuffer.expired()) { 419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers[i].clientBuffer = buffer; 420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return i; 421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers.push_back({ buffer, std::weak_ptr<C2Buffer>() }); 424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mBuffers.size() - 1; 425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Release the slot from the client, and get the C2Buffer object back from 429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * the previously assigned buffer. Note that the slot is not completely free 430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * until the returned C2Buffer object is freed. 431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 432e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * \param buffer[in] the buffer previously assigned a slot. 433e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * \param c2buffer[in,out] pointer to C2Buffer to be populated. Ignored 434e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * if null. 435e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * \return true if the buffer is successfully released from a slot 436e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * false otherwise 437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 438e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseSlot(const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) { 439e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim sp<Codec2Buffer> clientBuffer; 440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t index = mBuffers.size(); 441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < mBuffers.size(); ++i) { 442d15ef3cef65de483190c1bd8458074ce7d064202Praveen Chavan if (mBuffers[i].clientBuffer == buffer) { 443e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim clientBuffer = mBuffers[i].clientBuffer; 444d15ef3cef65de483190c1bd8458074ce7d064202Praveen Chavan mBuffers[i].clientBuffer.clear(); 445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim index = i; 446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 449e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (clientBuffer == nullptr) { 450a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim ALOGV("%s: No matching buffer found", __func__); 451e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return false; 452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 453e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim std::shared_ptr<C2Buffer> result = clientBuffer->asC2Buffer(); 454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers[index].compBuffer = result; 455e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (c2buffer) { 456e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim *c2buffer = result; 457e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim } 458e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return true; 459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim friend class BuffersArrayImpl; 463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim struct Entry { 465d15ef3cef65de483190c1bd8458074ce7d064202Praveen Chavan sp<Codec2Buffer> clientBuffer; 466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::weak_ptr<C2Buffer> compBuffer; 467033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<Entry> mBuffers; 469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/** 472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Static buffer slots implementation based on a fixed-size array. 473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass BuffersArrayImpl { 475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Initialize buffer array from the original |impl|. The buffers known by 478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * the client is preserved, and the empty slots are populated so that the 479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * array size is at least |minSize|. 480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param impl[in] FlexBuffersImpl object used so far. 482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param minSize[in] minimum size of the buffer array. 483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param allocate[in] function to allocate a client buffer for an empty slot. 484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 485033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void initialize( 486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const FlexBuffersImpl &impl, 487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t minSize, 488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<sp<Codec2Buffer>()> allocate) { 489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < impl.mBuffers.size(); ++i) { 490d15ef3cef65de483190c1bd8458074ce7d064202Praveen Chavan sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer; 491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool ownedByClient = (clientBuffer != nullptr); 492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!ownedByClient) { 493033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim clientBuffer = allocate(); 494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient }); 496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 497033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = impl.mBuffers.size(); i < minSize; ++i) { 498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers.push_back({ allocate(), std::weak_ptr<C2Buffer>(), false }); 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 501033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Grab a buffer from the underlying array which matches the criteria. 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param index[out] index of the slot. 506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param buffer[out] the matching buffer. 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param match[in] a function to test whether the buffer matches the 508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * criteria or not. 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \return OK if successful, 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * NO_MEMORY if there's no available slot meets the criteria. 511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t grabBuffer( 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t *index, 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> *buffer, 515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<bool(const sp<Codec2Buffer> &)> match = 516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [](const sp<Codec2Buffer> &) { return true; }) { 517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < mBuffers.size(); ++i) { 518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired() 519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim && match(mBuffers[i].clientBuffer)) { 520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers[i].ownedByClient = true; 521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *buffer = mBuffers[i].clientBuffer; 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffer)->meta()->clear(); 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffer)->setRange(0, (*buffer)->capacity()); 524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *index = i; 525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return NO_MEMORY; 529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Return the buffer from the client, and get the C2Buffer object back from 533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * the buffer. Note that the slot is not completely free until the returned 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * C2Buffer object is freed. 535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 536e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * \param buffer[in] the buffer previously grabbed. 537e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * \param c2buffer[in,out] pointer to C2Buffer to be populated. Ignored 538e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * if null. 539e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * \return true if the buffer is successfully returned 540e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim * false otherwise 541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 542e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool returnBuffer(const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) { 543e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim sp<Codec2Buffer> clientBuffer; 544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t index = mBuffers.size(); 545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < mBuffers.size(); ++i) { 546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mBuffers[i].clientBuffer == buffer) { 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!mBuffers[i].ownedByClient) { 548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("Client returned a buffer it does not own according to our record: %zu", i); 549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 550e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim clientBuffer = mBuffers[i].clientBuffer; 551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers[i].ownedByClient = false; 552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim index = i; 553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 556e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (clientBuffer == nullptr) { 557a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim ALOGV("%s: No matching buffer found", __func__); 558e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return false; 559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 56060e4b7347394676287f7686ddced77544a106831Wonsik Kim ALOGV("%s: matching buffer found (index=%zu)", __func__, index); 561e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim std::shared_ptr<C2Buffer> result = clientBuffer->asC2Buffer(); 562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffers[index].compBuffer = result; 563e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (c2buffer) { 564e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim *c2buffer = result; 565e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim } 566e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return true; 567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Populate |array| with the underlying buffer array. 571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 572033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param array[out] an array to be filled with the underlying buffer array. 573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 574033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void getArray(Vector<sp<MediaCodecBuffer>> *array) const { 575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->clear(); 576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (const Entry &entry : mBuffers) { 577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->push(entry.clientBuffer); 578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 582033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * The client abandoned all known buffers, so reclaim the ownership. 583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush() { 585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (Entry &entry : mBuffers) { 586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim entry.ownedByClient = false; 587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 588033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 589033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 590033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 591033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim struct Entry { 592033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<Codec2Buffer> clientBuffer; 593033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::weak_ptr<C2Buffer> compBuffer; 594033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool ownedByClient; 595033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 596033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<Entry> mBuffers; 597033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 598033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass InputBuffersArray : public CCodecBufferChannel::InputBuffers { 600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim InputBuffersArray() = default; 602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~InputBuffersArray() override = default; 603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void initialize( 605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const FlexBuffersImpl &impl, 606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t minSize, 607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<sp<Codec2Buffer>()> allocate) { 608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl.initialize(impl, minSize, allocate); 609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool isArrayMode() const final { return true; } 612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final { 614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 617033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void getArray(Vector<sp<MediaCodecBuffer>> *array) const final { 618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl.getArray(array); 619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override { 622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> c2Buffer; 623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = mImpl.grabBuffer(index, &c2Buffer); 624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err == OK) { 625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2Buffer->setFormat(mFormat); 626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *buffer = c2Buffer; 627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 632e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 633e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override { 634e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return mImpl.returnBuffer(buffer, c2buffer); 635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush() override { 638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl.flush(); 639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim BuffersArrayImpl mImpl; 643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass LinearInputBuffers : public CCodecBufferChannel::InputBuffers { 646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim using CCodecBufferChannel::InputBuffers::InputBuffers; 648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override { 650a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar int32_t capacity = kLinearBufferSize; 6510fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar (void)mFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity); 652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: proper max input size 653033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: read usage from intf 654a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar sp<Codec2Buffer> newBuffer = alloc((size_t)capacity); 655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (newBuffer == nullptr) { 656033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 657033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 658033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *index = mImpl.assignSlot(newBuffer); 659033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *buffer = newBuffer; 660033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 661033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 662033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 663e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 664e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override { 665e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return mImpl.releaseSlot(buffer, c2buffer); 666033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 667033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 668033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush() override { 669033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // This is no-op by default unless we're in array mode where we need to keep 670033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // track of the flushed work. 671033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 672033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 673033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final { 674a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim int32_t capacity = kLinearBufferSize; 675a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim (void)mFormat->findInt32(C2_NAME_STREAM_MAX_BUFFER_SIZE_SETTING, &capacity); 676a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim 677033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<InputBuffersArray> array(new InputBuffersArray); 678748591ac668738ca7fa0655656d45ce4327fd05fWonsik Kim array->setPool(mPool); 679033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->setFormat(mFormat); 680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->initialize( 681033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl, 68260e4b7347394676287f7686ddced77544a106831Wonsik Kim kMinInputBufferArraySize, 683a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim [this, capacity] () -> sp<Codec2Buffer> { return alloc(capacity); }); 684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::move(array); 685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 686033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual sp<Codec2Buffer> alloc(size_t size) const { 688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2LinearBlock> block; 690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = mPool->fetchLinearBlock(size, usage, &block); 692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return LinearBlockBuffer::Allocate(mFormat, block); 697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim FlexBuffersImpl mImpl; 701033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 703033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass EncryptedLinearInputBuffers : public LinearInputBuffers { 704033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim EncryptedLinearInputBuffers( 706033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool secure, 707033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<MemoryDealer> &dealer, 708033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<ICrypto> &crypto, 709033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t heapSeqNum) 710033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim : mUsage({0, 0}), 711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDealer(dealer), 712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCrypto(crypto), 713033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mHeapSeqNum(heapSeqNum) { 714033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (secure) { 715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mUsage = { C2MemoryUsage::READ_PROTECTED, 0 }; 716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 71960e4b7347394676287f7686ddced77544a106831Wonsik Kim for (size_t i = 0; i < kMinInputBufferArraySize; ++i) { 720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IMemory> memory = mDealer->allocate(kLinearBufferSize); 721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (memory == nullptr) { 722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("Failed to allocate memory from dealer: only %zu slots allocated", i); 723033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mMemoryVector.push_back({std::weak_ptr<C2LinearBlock>(), memory}); 726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 727033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~EncryptedLinearInputBuffers() override { 730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> alloc(size_t size) const override { 733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IMemory> memory; 734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (const Entry &entry : mMemoryVector) { 735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (entry.block.expired()) { 736033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memory = entry.memory; 737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (memory == nullptr) { 741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2LinearBlock> block; 745033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = mPool->fetchLinearBlock(size, mUsage, &block); 746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new EncryptedLinearBlockBuffer(mFormat, block, memory, mHeapSeqNum); 751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage mUsage; 755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MemoryDealer> mDealer; 756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<ICrypto> mCrypto; 757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t mHeapSeqNum; 758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim struct Entry { 759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::weak_ptr<C2LinearBlock> block; 760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IMemory> memory; 761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<Entry> mMemoryVector; 763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 765f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kimclass GraphicMetadataInputBuffers : public CCodecBufferChannel::InputBuffers { 766f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kimpublic: 767f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim GraphicMetadataInputBuffers() : mStore(GetCodec2PlatformAllocatorStore()) {} 768f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim ~GraphicMetadataInputBuffers() override = default; 769f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 770f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override { 771f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim std::shared_ptr<C2Allocator> alloc; 772f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc); 773f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (err != C2_OK) { 774f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return false; 775f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 776f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim sp<GraphicMetadataBuffer> newBuffer = new GraphicMetadataBuffer(mFormat, alloc); 777f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (newBuffer == nullptr) { 778f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return false; 779f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 780f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim *index = mImpl.assignSlot(newBuffer); 781f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim *buffer = newBuffer; 782f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return true; 783f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 784f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 785e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 786e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override { 787e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return mImpl.releaseSlot(buffer, c2buffer); 788f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 789f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 790f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim void flush() override { 791f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim // This is no-op by default unless we're in array mode where we need to keep 792f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim // track of the flushed work. 793f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 794f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 795f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final { 796f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim std::shared_ptr<C2Allocator> alloc; 797f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc); 798f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (err != C2_OK) { 799f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return nullptr; 800f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 801f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim std::unique_ptr<InputBuffersArray> array(new InputBuffersArray); 802748591ac668738ca7fa0655656d45ce4327fd05fWonsik Kim array->setPool(mPool); 803f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim array->setFormat(mFormat); 804f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim array->initialize( 805f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim mImpl, 80660e4b7347394676287f7686ddced77544a106831Wonsik Kim kMinInputBufferArraySize, 807f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim [format = mFormat, alloc]() -> sp<Codec2Buffer> { 808f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return new GraphicMetadataBuffer(format, alloc); 809f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim }); 810f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return std::move(array); 811f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 812f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 813f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kimprivate: 814f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim FlexBuffersImpl mImpl; 815f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim std::shared_ptr<C2AllocatorStore> mStore; 816f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim}; 817f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 818033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass GraphicInputBuffers : public CCodecBufferChannel::InputBuffers { 819033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 82060e4b7347394676287f7686ddced77544a106831Wonsik Kim GraphicInputBuffers() 82160e4b7347394676287f7686ddced77544a106831Wonsik Kim : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 4 * 16)) { 82260e4b7347394676287f7686ddced77544a106831Wonsik Kim } 823033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~GraphicInputBuffers() override = default; 824033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 825033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override { 826033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: proper max input size 827033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: read usage from intf 828033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 829033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<GraphicBlockBuffer> newBuffer = AllocateGraphicBuffer( 830033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool); 831033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (newBuffer == nullptr) { 832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 833033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 834033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *index = mImpl.assignSlot(newBuffer); 835033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *buffer = newBuffer; 836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 839e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 840e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override { 841e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return mImpl.releaseSlot(buffer, c2buffer); 842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush() override { 845033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // This is no-op by default unless we're in array mode where we need to keep 846033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // track of the flushed work. 847033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 848033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 849033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final { 850033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<InputBuffersArray> array(new InputBuffersArray); 851748591ac668738ca7fa0655656d45ce4327fd05fWonsik Kim array->setPool(mPool); 852033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->setFormat(mFormat); 853033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->initialize( 854033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl, 85560e4b7347394676287f7686ddced77544a106831Wonsik Kim kMinInputBufferArraySize, 856033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [pool = mPool, format = mFormat, lbp = mLocalBufferPool]() -> sp<Codec2Buffer> { 857033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 858033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return AllocateGraphicBuffer( 859033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim pool, format, HAL_PIXEL_FORMAT_YV12, usage, lbp); 860033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 861033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::move(array); 862033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 863033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 864033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 865033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim FlexBuffersImpl mImpl; 866033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<LocalBufferPool> mLocalBufferPool; 867033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 868033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 869033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass DummyInputBuffers : public CCodecBufferChannel::InputBuffers { 870033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 871033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DummyInputBuffers() = default; 872033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 873033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override { 874033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 875033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 876033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 877e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 878e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &, std::shared_ptr<C2Buffer> *) override { 879e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return false; 880033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 881033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 882033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush() override { 883033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 884033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 885033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final { 886033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 887033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 888033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 889033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool isArrayMode() const final { return true; } 890033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 891033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void getArray(Vector<sp<MediaCodecBuffer>> *array) const final { 892033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->clear(); 893033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 894033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 895033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 896033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass OutputBuffersArray : public CCodecBufferChannel::OutputBuffers { 897033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 898033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim OutputBuffersArray() = default; 899033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~OutputBuffersArray() override = default; 900033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 901033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void initialize( 902033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const FlexBuffersImpl &impl, 903033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t minSize, 904033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<sp<Codec2Buffer>()> allocate) { 905033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl.initialize(impl, minSize, allocate); 906033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 907033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 908033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool isArrayMode() const final { return true; } 909033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 910033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() final { 911033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 912033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 913033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 914033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool registerBuffer( 915033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2Buffer> &buffer, 916033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t *index, 917033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> *clientBuffer) final { 918033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> c2Buffer; 919033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = mImpl.grabBuffer( 920033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim index, 921033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim &c2Buffer, 922033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [buffer](const sp<Codec2Buffer> &clientBuffer) { 923033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return clientBuffer->canCopy(buffer); 924033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 925033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 926033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("grabBuffer failed: %d", err); 927033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 928033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 929033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2Buffer->setFormat(mFormat); 930033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!c2Buffer->copy(buffer)) { 931033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("copy buffer failed"); 932033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 933033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 934dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim submit(c2Buffer); 935033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *clientBuffer = c2Buffer; 936033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 937033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 938033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 939033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool registerCsd( 940033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const C2StreamCsdInfo::output *csd, 941033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t *index, 942033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> *clientBuffer) final { 943033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> c2Buffer; 944033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = mImpl.grabBuffer( 945033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim index, 946033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim &c2Buffer, 947033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [csd](const sp<Codec2Buffer> &clientBuffer) { 948033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return clientBuffer->base() != nullptr 949033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim && clientBuffer->capacity() >= csd->flexCount(); 950033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 951033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 952033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 953033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 954033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memcpy(c2Buffer->base(), csd->m.value, csd->flexCount()); 955033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2Buffer->setRange(0, csd->flexCount()); 956033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2Buffer->setFormat(mFormat); 957033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *clientBuffer = c2Buffer; 958033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 959033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 960033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 961e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 962e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override { 963e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return mImpl.returnBuffer(buffer, c2buffer); 964033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 965033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 966033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override { 967dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim (void)flushedWork; 968033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl.flush(); 969dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (mSkipCutBuffer != nullptr) { 970dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mSkipCutBuffer->clear(); 971dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 972033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 973033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 974033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void getArray(Vector<sp<MediaCodecBuffer>> *array) const final { 975033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl.getArray(array); 976033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 977033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 978033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 979033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim BuffersArrayImpl mImpl; 980033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 981033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 982033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass FlexOutputBuffers : public CCodecBufferChannel::OutputBuffers { 983033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 984033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim using CCodecBufferChannel::OutputBuffers::OutputBuffers; 985033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 986033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool registerBuffer( 987033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2Buffer> &buffer, 988033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t *index, 989033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> *clientBuffer) override { 990033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> newBuffer = wrap(buffer); 991033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim newBuffer->setFormat(mFormat); 992033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *index = mImpl.assignSlot(newBuffer); 993033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *clientBuffer = newBuffer; 994033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 995033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 996033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 997033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool registerCsd( 998033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const C2StreamCsdInfo::output *csd, 999033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t *index, 1000033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> *clientBuffer) final { 10018c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim sp<Codec2Buffer> newBuffer = new LocalLinearBuffer( 10028c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim mFormat, ABuffer::CreateAsCopy(csd->m.value, csd->flexCount())); 1003033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *index = mImpl.assignSlot(newBuffer); 1004033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *clientBuffer = newBuffer; 1005033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 1006033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1007033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1008e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim bool releaseBuffer( 1009e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override { 1010e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return mImpl.releaseSlot(buffer, c2buffer); 1011033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1012033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1013033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void flush( 1014033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::list<std::unique_ptr<C2Work>> &flushedWork) override { 1015033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void) flushedWork; 1016033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // This is no-op by default unless we're in array mode where we need to keep 1017033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // track of the flushed work. 1018033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1019033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1020033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() override { 1021033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray); 1022033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->setFormat(mFormat); 1023dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim array->transferSkipCutBuffer(mSkipCutBuffer); 1024033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->initialize( 1025033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mImpl, 102660e4b7347394676287f7686ddced77544a106831Wonsik Kim kMinOutputBufferArraySize, 1027033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [this]() { return allocateArrayBuffer(); }); 1028033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::move(array); 1029033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1030033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1031033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 1032033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Return an appropriate Codec2Buffer object for the type of buffers. 1033033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 1034033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \param buffer C2Buffer object to wrap. 1035033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 1036033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \return appropriate Codec2Buffer object to wrap |buffer|. 1037033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 1038033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0; 1039033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1040033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /** 1041033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Return an appropriate Codec2Buffer object for the type of buffers, to be 1042033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * used as an empty array buffer. 1043033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 1044033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * \return appropriate Codec2Buffer object which can copy() from C2Buffers. 1045033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 1046033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual sp<Codec2Buffer> allocateArrayBuffer() = 0; 1047033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1048033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 1049033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim FlexBuffersImpl mImpl; 1050033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 1051033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1052033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass LinearOutputBuffers : public FlexOutputBuffers { 1053033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 1054033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim using FlexOutputBuffers::FlexOutputBuffers; 1055033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1056dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim void flush( 1057dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim const std::list<std::unique_ptr<C2Work>> &flushedWork) override { 1058dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (mSkipCutBuffer != nullptr) { 1059dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim mSkipCutBuffer->clear(); 1060dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1061dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim FlexOutputBuffers::flush(flushedWork); 1062dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1063dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 1064033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override { 1065033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (buffer == nullptr) { 10664bf68ce16bfd972d0ab242a27c5c258d7e1eb768Lajos Molnar return new LocalLinearBuffer(mFormat, new ABuffer(0)); 1067033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1068033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (buffer->data().type() != C2BufferData::LINEAR) { 1069033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We expect linear output buffers from the component. 1070033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 1071033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1072033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (buffer->data().linearBlocks().size() != 1u) { 1073033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We expect one and only one linear block from the component. 1074033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return nullptr; 1075033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1076dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim sp<Codec2Buffer> clientBuffer = ConstLinearBlockBuffer::Allocate(mFormat, buffer); 1077dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim submit(clientBuffer); 1078dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim return clientBuffer; 1079033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1080033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1081033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> allocateArrayBuffer() override { 1082033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: proper max output size 1083033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize)); 1084033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1085033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 1086033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1087033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass GraphicOutputBuffers : public FlexOutputBuffers { 1088033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 1089033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim using FlexOutputBuffers::FlexOutputBuffers; 1090033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1091033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override { 1092033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new DummyContainerBuffer(mFormat, buffer); 1093033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1094033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1095033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> allocateArrayBuffer() override { 1096033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new DummyContainerBuffer(mFormat); 1097033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1098033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 1099033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass RawGraphicOutputBuffers : public FlexOutputBuffers { 1101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 1102033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim RawGraphicOutputBuffers() 1103e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 4 * 16)) { 1104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~RawGraphicOutputBuffers() override = default; 1106033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override { 1108e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar if (buffer == nullptr) { 1109e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar return ConstGraphicBlockBuffer::AllocateEmpty( 1110e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar mFormat, 1111e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar [lbp = mLocalBufferPool](size_t capacity) { 1112e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar return lbp->newBuffer(capacity); 1113e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar }); 1114e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar } else { 1115e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar return ConstGraphicBlockBuffer::Allocate( 1116e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar mFormat, 1117e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar buffer, 1118e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar [lbp = mLocalBufferPool](size_t capacity) { 1119e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar return lbp->newBuffer(capacity); 1120e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar }); 1121e87246ce7b1359ca09153607d0af8663c61ede96Lajos Molnar } 1122033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1123033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1124033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Codec2Buffer> allocateArrayBuffer() override { 1125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return ConstGraphicBlockBuffer::AllocateEmpty( 1126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mFormat, 1127033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [lbp = mLocalBufferPool](size_t capacity) { 1128033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return lbp->newBuffer(capacity); 1129033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 1130033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 1133033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<LocalBufferPool> mLocalBufferPool; 1134033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 1135033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1136033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace 1137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodecBufferChannel::QueueGuard::QueueGuard( 1139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CCodecBufferChannel::QueueSync &sync) : mSync(sync) { 1140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_lock<std::mutex> l(mSync.mMutex); 1141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // At this point it's guaranteed that mSync is not under state transition, 1142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // as we are holding its mutex. 1143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mSync.mCount == -1) { 1144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mRunning = false; 1145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ++mSync.mCount; 1147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mRunning = true; 1148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodecBufferChannel::QueueGuard::~QueueGuard() { 1152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mRunning) { 1153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We are not holding mutex at this point so that QueueSync::stop() can 1154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // keep holding the lock until mCount reaches zero. 1155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim --mSync.mCount; 1156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1157033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::QueueSync::start() { 1160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_lock<std::mutex> l(mMutex); 1161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // If stopped, it goes to running state; otherwise no-op. 1162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t expected = -1; 1163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)mCount.compare_exchange_strong(expected, 0); 1164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::QueueSync::stop() { 1167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_lock<std::mutex> l(mMutex); 1168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mCount == -1) { 1169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // no-op 1170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Holding mutex here blocks creation of additional QueueGuard objects, so 1173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // mCount can only decrement. In other words, threads that acquired the lock 1174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // are allowed to finish execution but additional threads trying to acquire 1175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // the lock at this point will block, and then get QueueGuard at STOPPED 1176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // state. 1177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t expected = 0; 1178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (!mCount.compare_exchange_weak(expected, -1)) { 1179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::this_thread::yield(); 1180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodecBufferChannel::CCodecBufferChannel( 1184384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim const std::shared_ptr<CCodecCallback> &callback) 1185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim : mHeapSeqNum(-1), 1186384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCCodecCallback(callback), 1187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mFrameIndex(0u), 11888060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee mFirstValidFrameIndex(0u), 1189c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim mMetaMode(MODE_NONE), 1190c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim mPendingFeed(0) { 1191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodecBufferChannel::~CCodecBufferChannel() { 1194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) { 1195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCrypto->unsetHeap(mHeapSeqNum); 1196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 11990f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasavoid CCodecBufferChannel::setComponent( 12000f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa const std::shared_ptr<Codec2Client::Component> &component) { 1201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mComponent = component; 1202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::setInputSurface( 1205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<InputSurfaceWrapper> &surface) { 1206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("setInputSurface"); 1207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mInputSurface = surface; 1208f61123c4e697e9d1d437b4e318636e5789ea85c0Wonsik Kim return mInputSurface->connect(mComponent); 1209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 12117a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kimstatus_t CCodecBufferChannel::signalEndOfInputStream() { 12127a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim if (mInputSurface == nullptr) { 12137a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return INVALID_OPERATION; 12147a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 12157a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return mInputSurface->signalEndOfInputStream(); 12167a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim} 12177a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim 1218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer) { 1219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int64_t timeUs; 1220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t flags = 0; 1223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t tmp = 0; 1224585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim bool eos = false; 1225033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (buffer->meta()->findInt32("eos", &tmp) && tmp) { 1226585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim eos = true; 1227033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("input EOS"); 1228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (buffer->meta()->findInt32("csd", &tmp) && tmp) { 1230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flags |= C2FrameData::FLAG_CODEC_CONFIG; 1231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("queueInputBuffer: buffer->size() = %zu", buffer->size()); 1233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<C2Work> work(new C2Work); 1234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->input.ordinal.timestamp = timeUs; 1235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->input.ordinal.frameIndex = mFrameIndex++; 1236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->input.buffers.clear(); 123771bf09f2e99c1916e43fd4228889c4edba54c97dWonsik Kim if (buffer->size() > 0u) { 1238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1239e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim std::shared_ptr<C2Buffer> c2buffer; 1240e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (!(*buffers)->releaseBuffer(buffer, &c2buffer)) { 1241033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return -ENOENT; 1242033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1243033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->input.buffers.push_back(c2buffer); 1244585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim } else if (eos) { 1245585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim flags |= C2FrameData::FLAG_END_OF_STREAM; 1246033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1247585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim work->input.flags = (C2FrameData::flags_t)flags; 1248033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: fill info's 1249033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1250033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.clear(); 1251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.emplace_back(new C2Worklet); 1252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::list<std::unique_ptr<C2Work>> items; 1254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim items.push_back(std::move(work)); 1255c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim c2_status_t err = mComponent->queue(&items); 1256585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim 1257585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim if (err == C2_OK && eos && buffer->size() > 0u) { 1258585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim work.reset(new C2Work); 1259585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim work->input.ordinal.timestamp = timeUs; 1260585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim work->input.ordinal.frameIndex = mFrameIndex++; 1261585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim work->input.buffers.clear(); 1262585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim work->input.flags = C2FrameData::FLAG_END_OF_STREAM; 1263585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim 1264585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim items.clear(); 1265585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim items.push_back(std::move(work)); 1266585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim err = mComponent->queue(&items); 1267585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim } 1268585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim 1269c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim feedInputBufferIfAvailableInternal(); 1270c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim return err; 1271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { 1274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim QueueGuard guard(mSync); 1275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!guard.isRunning()) { 1276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("No more buffers should be queued at current state."); 1277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return -ENOSYS; 1278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return queueInputBufferInternal(buffer); 1280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::queueSecureInputBuffer( 1283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key, 1284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern, 1285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 1286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString *errorDetailMsg) { 1287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim QueueGuard guard(mSync); 1288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!guard.isRunning()) { 1289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("No more buffers should be queued at current state."); 1290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return -ENOSYS; 1291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1293033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!hasCryptoOrDescrambler()) { 1294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return -ENOSYS; 1295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get()); 1297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ssize_t result = -1; 1299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mCrypto != nullptr) { 1300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ICrypto::DestinationBuffer destination; 1301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (secure) { 1302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim destination.mType = ICrypto::kDestinationTypeNativeHandle; 1303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim destination.mHandle = encryptedBuffer->handle(); 1304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim destination.mType = ICrypto::kDestinationTypeSharedMemory; 1306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim destination.mSharedMemory = mDecryptDestination; 1307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ICrypto::SourceBuffer source; 1309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encryptedBuffer->fillSourceBuffer(&source); 1310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim result = mCrypto->decrypt( 1311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim key, iv, mode, pattern, source, buffer->offset(), 1312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim subSamples, numSubSamples, destination, errorDetailMsg); 1313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (result < 0) { 1314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return result; 1315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { 1317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encryptedBuffer->copyDecryptedContent(mDecryptDestination, result); 1318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample 1321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // directly, the structure definitions should match as checked in DescramblerImpl.cpp. 1322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hidl_vec<SubSample> hidlSubSamples; 1323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/); 1324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hardware::cas::native::V1_0::SharedBuffer srcBuffer; 1326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encryptedBuffer->fillSourceBuffer(&srcBuffer); 1327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DestinationBuffer dstBuffer; 1329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (secure) { 1330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dstBuffer.type = BufferType::NATIVE_HANDLE; 1331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dstBuffer.secureMemory = hidl_handle(encryptedBuffer->handle()); 1332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dstBuffer.type = BufferType::SHARED_MEMORY; 1334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dstBuffer.nonsecureMemory = srcBuffer; 1335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CasStatus status = CasStatus::OK; 1338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hidl_string detailedError; 1339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto returnVoid = mDescrambler->descramble( 1341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED, 1342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hidlSubSamples, 1343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim srcBuffer, 1344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 0, 1345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dstBuffer, 1346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 0, 1347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim [&status, &result, &detailedError] ( 1348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CasStatus _status, uint32_t _bytesWritten, 1349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const hidl_string& _detailedError) { 1350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status = _status; 1351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim result = (ssize_t)_bytesWritten; 1352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim detailedError = _detailedError; 1353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }); 1354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!returnVoid.isOk() || status != CasStatus::OK || result < 0) { 1356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("descramble failed, trans=%s, status=%d, result=%zd", 1357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim returnVoid.description().c_str(), status, result); 1358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("descramble succeeded, %zd bytes", result); 1362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (dstBuffer.type == BufferType::SHARED_MEMORY) { 1364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encryptedBuffer->copyDecryptedContentFromMemory(result); 1365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffer->setRange(0, result); 1369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return queueInputBufferInternal(buffer); 1370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::feedInputBufferIfAvailable() { 1373a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim QueueGuard guard(mSync); 1374a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim if (!guard.isRunning()) { 1375a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim ALOGV("We're not running --- no input buffer reported"); 1376a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim return; 1377a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim } 1378c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim feedInputBufferIfAvailableInternal(); 1379c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim} 1380c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim 1381c2088887496fa8627e0a2a4e713f413301065516Wonsik Kimvoid CCodecBufferChannel::feedInputBufferIfAvailableInternal() { 1382c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim while (mPendingFeed > 0) { 1383c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim sp<MediaCodecBuffer> inBuffer; 1384c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim size_t index; 1385c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim { 1386c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1387c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim if (!(*buffers)->requestNewBuffer(&index, &inBuffer)) { 1388c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ALOGV("no new buffer available"); 1389c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim break; 1390c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim } 1391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1392c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ALOGV("new input index = %zu", index); 1393c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim mCallback->onInputBufferAvailable(index, inBuffer); 1394c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ALOGV("%s: pending feed -1 from %u", __func__, mPendingFeed.load()); 1395c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim --mPendingFeed; 1396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::renderOutputBuffer( 1400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) { 1401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("renderOutputBuffer"); 1402c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ALOGV("%s: pending feed +1 from %u", __func__, mPendingFeed.load()); 1403c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ++mPendingFeed; 1404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim feedInputBufferIfAvailable(); 1405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Buffer> c2Buffer; 1407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 1409e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (*buffers) { 1410e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim (*buffers)->releaseBuffer(buffer, &c2Buffer); 1411e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim } 1412e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim } 1413e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (!c2Buffer) { 1414e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim return INVALID_OPERATION; 1415033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1416033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1417b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar#if 0 1418b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar const std::vector<std::shared_ptr<const C2Info>> infoParams = c2Buffer->info(); 1419b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ALOGV("queuing gfx buffer with %zu infos", infoParams.size()); 1420b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (const std::shared_ptr<const C2Info> &info : infoParams) { 1421b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar AString res; 1422b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (size_t ix = 0; ix + 3 < info->size(); ix += 4) { 1423b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (ix) res.append(", "); 1424b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar res.append(*((int32_t*)info.get() + (ix / 4))); 1425b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1426b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ALOGV(" [%s]", res.c_str()); 1427b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1428b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar#endif 1429b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::shared_ptr<const C2StreamRotationInfo::output> rotation = 1430b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::static_pointer_cast<const C2StreamRotationInfo::output>( 1431b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar c2Buffer->getInfo(C2StreamRotationInfo::output::PARAM_TYPE)); 1432b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar bool flip = rotation && (rotation->flip & 1); 1433b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar uint32_t quarters = ((rotation ? rotation->value : 0) / 90) & 3; 1434b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar uint32_t transform = 0; 1435b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar switch (quarters) { 1436b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case 0: // no rotation 1437b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar transform = flip ? HAL_TRANSFORM_FLIP_H : 0; 1438b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1439b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case 1: // 90 degrees counter-clockwise 1440b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar transform = flip ? (HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90) 1441b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar : HAL_TRANSFORM_ROT_270; 1442b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1443b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case 2: // 180 degrees 1444b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar transform = flip ? HAL_TRANSFORM_FLIP_V : HAL_TRANSFORM_ROT_180; 1445b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1446b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case 3: // 90 degrees clockwise 1447b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar transform = flip ? (HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90) 1448b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar : HAL_TRANSFORM_ROT_90; 1449b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1450b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1451b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1452b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::shared_ptr<const C2StreamSurfaceScalingInfo::output> surfaceScaling = 1453b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::static_pointer_cast<const C2StreamSurfaceScalingInfo::output>( 1454b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar c2Buffer->getInfo(C2StreamSurfaceScalingInfo::output::PARAM_TYPE)); 1455b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar uint32_t videoScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; 1456b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (surfaceScaling) { 1457b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar videoScalingMode = surfaceScaling->value; 1458b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1459b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1460b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // Use dataspace if component provides it. Otherwise, compose dataspace from color aspects 1461b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::shared_ptr<const C2StreamDataSpaceInfo::output> dataSpaceInfo = 1462b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::static_pointer_cast<const C2StreamDataSpaceInfo::output>( 1463b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar c2Buffer->getInfo(C2StreamDataSpaceInfo::output::PARAM_TYPE)); 1464b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar uint32_t dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0 1465b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (dataSpaceInfo) { 1466b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar dataSpace = dataSpaceInfo->value; 1467b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } else { 1468b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::shared_ptr<const C2StreamColorAspectsInfo::output> colorAspects = 1469b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::static_pointer_cast<const C2StreamColorAspectsInfo::output>( 1470b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar c2Buffer->getInfo(C2StreamColorAspectsInfo::output::PARAM_TYPE)); 1471b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2Color::range_t range = 1472b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar colorAspects == nullptr ? C2Color::RANGE_UNSPECIFIED : colorAspects->range; 1473b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2Color::primaries_t primaries = 1474b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar colorAspects == nullptr ? C2Color::PRIMARIES_UNSPECIFIED : colorAspects->primaries; 1475b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2Color::transfer_t transfer = 1476b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar colorAspects == nullptr ? C2Color::TRANSFER_UNSPECIFIED : colorAspects->transfer; 1477b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2Color::matrix_t matrix = 1478b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar colorAspects == nullptr ? C2Color::MATRIX_UNSPECIFIED : colorAspects->matrix; 1479b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1480b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar switch (range) { 1481b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::RANGE_FULL: dataSpace |= HAL_DATASPACE_RANGE_FULL; break; 1482b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::RANGE_LIMITED: dataSpace |= HAL_DATASPACE_RANGE_LIMITED; break; 1483b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar default: break; 1484b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1485b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1486b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar switch (transfer) { 1487b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_LINEAR: dataSpace |= HAL_DATASPACE_TRANSFER_LINEAR; break; 1488b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_SRGB: dataSpace |= HAL_DATASPACE_TRANSFER_SRGB; break; 1489b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_170M: dataSpace |= HAL_DATASPACE_TRANSFER_SMPTE_170M; break; 1490b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_GAMMA22: dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_2; break; 1491b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_GAMMA28: dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_8; break; 1492b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_ST2084: dataSpace |= HAL_DATASPACE_TRANSFER_ST2084; break; 1493b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::TRANSFER_HLG: dataSpace |= HAL_DATASPACE_TRANSFER_HLG; break; 1494b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar default: break; 1495b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1496b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1497b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar switch (primaries) { 1498b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::PRIMARIES_BT601_525: 1499b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M 1500b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar || matrix == C2Color::MATRIX_BT709) 1501b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ? HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED 1502b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar : HAL_DATASPACE_STANDARD_BT601_525; 1503b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1504b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::PRIMARIES_BT601_625: 1505b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M 1506b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar || matrix == C2Color::MATRIX_BT709) 1507b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ? HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED 1508b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar : HAL_DATASPACE_STANDARD_BT601_625; 1509b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1510b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::PRIMARIES_BT2020: 1511b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar dataSpace |= (matrix == C2Color::MATRIX_BT2020CONSTANT 1512b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ? HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE 1513b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar : HAL_DATASPACE_STANDARD_BT2020); 1514b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1515b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::PRIMARIES_BT470_M: 1516b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar dataSpace |= HAL_DATASPACE_STANDARD_BT470M; 1517b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1518b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar case C2Color::PRIMARIES_BT709: 1519b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar dataSpace |= HAL_DATASPACE_STANDARD_BT709; 1520b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; 1521b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar default: break; 1522b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1523b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1524b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1525b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // convert legacy dataspace values to v0 values 1526b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar const static 1527b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ALookup<android_dataspace, android_dataspace> sLegacyDataSpaceToV0 { 1528b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { 1529b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { HAL_DATASPACE_SRGB, HAL_DATASPACE_V0_SRGB }, 1530b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { HAL_DATASPACE_BT709, HAL_DATASPACE_V0_BT709 }, 1531b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { HAL_DATASPACE_SRGB_LINEAR, HAL_DATASPACE_V0_SRGB_LINEAR }, 1532b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { HAL_DATASPACE_BT601_525, HAL_DATASPACE_V0_BT601_525 }, 1533b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { HAL_DATASPACE_BT601_625, HAL_DATASPACE_V0_BT601_625 }, 1534b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar { HAL_DATASPACE_JFIF, HAL_DATASPACE_V0_JFIF }, 1535b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1536b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }; 1537b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar sLegacyDataSpaceToV0.lookup((android_dataspace_t)dataSpace, (android_dataspace_t*)&dataSpace); 1538b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1539b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // HDR static info 1540b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::shared_ptr<const C2StreamHdrStaticInfo::output> hdrStaticInfo = 1541b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::static_pointer_cast<const C2StreamHdrStaticInfo::output>( 1542b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar c2Buffer->getInfo(C2StreamHdrStaticInfo::output::PARAM_TYPE)); 1543b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 15442cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa { 15452cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa Mutexed<OutputSurface>::Locked output(mOutputSurface); 15462cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa if (output->surface == nullptr) { 15472cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa ALOGE("no surface"); 15482cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa return OK; 15498b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 15508060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee } 1551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks(); 1553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (blocks.size() != 1u) { 1554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("# of graphic blocks expected to be 1, but %zu", blocks.size()); 1555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1557670fbf8f428ba012574f193cbdff15617b0b7950Lajos Molnar const C2ConstGraphicBlock &block = blocks.front(); 1558670fbf8f428ba012574f193cbdff15617b0b7950Lajos Molnar 1559b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // TODO: revisit this after C2Fence implementation. 15608060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee android::IGraphicBufferProducer::QueueBufferInput qbi( 15618060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee timestampNs, 15628060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee false, 1563b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar (android_dataspace_t)dataSpace, 1564a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim Rect(blocks.front().crop().left, 1565a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim blocks.front().crop().top, 1566a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim blocks.front().crop().right(), 1567a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim blocks.front().crop().bottom()), 1568b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar videoScalingMode, 1569b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar transform, 15708060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee Fence::NO_FENCE, 0); 1571b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (hdrStaticInfo) { 1572b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar struct android_smpte2086_metadata smpte2086_meta = { 1573b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .displayPrimaryRed = { 1574b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdrStaticInfo->mastering.red.x, hdrStaticInfo->mastering.red.y 1575b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }, 1576b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .displayPrimaryGreen = { 1577b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdrStaticInfo->mastering.green.x, hdrStaticInfo->mastering.green.y 1578b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }, 1579b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .displayPrimaryBlue = { 1580b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdrStaticInfo->mastering.blue.x, hdrStaticInfo->mastering.blue.y 1581b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }, 1582b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .whitePoint = { 1583b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdrStaticInfo->mastering.white.x, hdrStaticInfo->mastering.white.y 1584b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }, 1585b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .maxLuminance = hdrStaticInfo->mastering.maxLuminance, 1586b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .minLuminance = hdrStaticInfo->mastering.minLuminance, 1587b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }; 1588b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1589b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar struct android_cta861_3_metadata cta861_meta = { 1590b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .maxContentLightLevel = hdrStaticInfo->maxCll, 1591b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar .maxFrameAverageLightLevel = hdrStaticInfo->maxFall, 1592b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }; 1593b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1594b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar HdrMetadata hdr; 1595b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdr.validTypes = HdrMetadata::SMPTE2086 | HdrMetadata::CTA861_3; 1596b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdr.smpte2086 = smpte2086_meta; 1597b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar hdr.cta8613 = cta861_meta; 1598b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar qbi.setHdrMetadata(hdr); 1599b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 16008060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee android::IGraphicBufferProducer::QueueBufferOutput qbo; 16012cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa status_t result = mComponent->queueToOutputSurface(block, qbi, &qbo); 1602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (result != OK) { 1603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("queueBuffer failed: %d", result); 1604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return result; 1605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 16068060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee ALOGV("queue buffer successful"); 1607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1608384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim int64_t mediaTimeUs = 0; 1609384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim (void)buffer->meta()->findInt64("timeUs", &mediaTimeUs); 1610384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCCodecCallback->onOutputFramesRendered(mediaTimeUs, timestampNs); 1611384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 1612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) { 1616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("discardBuffer: %p", buffer.get()); 16178c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim bool released = false; 1618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1620e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (*buffers) { 1621e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim released = (*buffers)->releaseBuffer(buffer, nullptr); 1622e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim } 1623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 1626e76dbb8207011ad23a2e3460c5672e7c250beae9Wonsik Kim if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr)) { 16278c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim released = true; 1628c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ALOGV("%s: pending feed +1 from %u", __func__, mPendingFeed.load()); 1629c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ++mPendingFeed; 1630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1632c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim feedInputBufferIfAvailable(); 16338c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim if (!released) { 16348c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim ALOGD("MediaCodec discarded an unknown buffer"); 16358c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim } 1636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 1640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->clear(); 1641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!(*buffers)->isArrayMode()) { 1644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *buffers = (*buffers)->toArrayMode(); 1645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffers)->getArray(array); 1648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 1651033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim array->clear(); 1652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 1653033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1654033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!(*buffers)->isArrayMode()) { 1655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *buffers = (*buffers)->toArrayMode(); 1656033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1657033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1658033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffers)->getArray(array); 1659033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1660033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1661033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::start( 1662033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) { 1663033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2StreamFormatConfig::input iStreamFormat(0u); 1664033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2StreamFormatConfig::output oStreamFormat(0u); 16650f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa c2_status_t err = mComponent->query( 1666033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { &iStreamFormat, &oStreamFormat }, 1667033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim {}, 1668033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2_DONT_BLOCK, 1669033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim nullptr); 1670033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 1671033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1672033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 16738b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 16748b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // TODO: get this from input format 16750f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa bool secure = mComponent->getName().find(".secure") != std::string::npos; 1676033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 16778b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore(); 1678dacd656e6f8d7b4f273f10737fbb939c963a16aeSungtak Lee int poolMask = property_get_int32( 1679dacd656e6f8d7b4f273f10737fbb939c963a16aeSungtak Lee "debug.stagefright.c2-poolmask", 168000f014cde379a797d0c0dc042b90f001af80b9dfPawin Vongmasa 1 << C2PlatformAllocatorStore::ION | 168100f014cde379a797d0c0dc042b90f001af80b9dfPawin Vongmasa 1 << C2PlatformAllocatorStore::BUFFERQUEUE); 1682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 16838b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (inputFormat != nullptr) { 1684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool graphic = (iStreamFormat.value == C2FormatVideo); 16858b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::shared_ptr<C2BlockPool> pool; 16868b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin { 16878b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin Mutexed<BlockPools>::Locked pools(mBlockPools); 16888b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 16898b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // set default allocator ID. 1690a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar pools->inputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC 16918b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin : C2PlatformAllocatorStore::ION; 16928b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 16938b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // query C2PortAllocatorsTuning::input from component. If an allocator ID is obtained 16948b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // from component, create the input block pool with given ID. Otherwise, use default IDs. 16958b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::vector<std::unique_ptr<C2Param>> params; 16968b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin err = mComponent->query({ }, 16978b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin { C2PortAllocatorsTuning::input::PARAM_TYPE }, 16988b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2_DONT_BLOCK, 16998b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ¶ms); 17008b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) { 17018b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ALOGD("Query input allocators returned %zu params => %s (%u)", 17028b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin params.size(), asString(err), err); 17038b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } else if (err == C2_OK && params.size() == 1) { 17048b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2PortAllocatorsTuning::input *inputAllocators = 17058b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2PortAllocatorsTuning::input::From(params[0].get()); 17068b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (inputAllocators && inputAllocators->flexCount() > 0) { 17078b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::shared_ptr<C2Allocator> allocator; 17088b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // verify allocator IDs and resolve default allocator 17098b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin allocatorStore->fetchAllocator(inputAllocators->m.values[0], &allocator); 17108b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (allocator) { 17118b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin pools->inputAllocatorId = allocator->getId(); 17128b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } else { 17138b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ALOGD("component requested invalid input allocator ID %u", 17148b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin inputAllocators->m.values[0]); 17158b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 17168b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 17178b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 17188b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 17198b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // TODO: use C2Component wrapper to associate this pool with ourselves 17200c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar if ((poolMask >> pools->inputAllocatorId) & 1) { 17210c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar err = CreateCodec2BlockPool(pools->inputAllocatorId, nullptr, &pool); 17220c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar ALOGD("Created input block pool with allocatorID %u => poolID %llu - %s (%d)", 17230c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar pools->inputAllocatorId, 17240c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar (unsigned long long)(pool ? pool->getLocalId() : 111000111), 17250c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar asString(err), err); 17260c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar } else { 17270c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar err = C2_NOT_FOUND; 17280c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar } 17298b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (err != C2_OK) { 17308b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2BlockPool::local_id_t inputPoolId = 17318b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR; 17328b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin err = GetCodec2BlockPool(inputPoolId, nullptr, &pool); 17338b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ALOGD("Using basic input block pool with poolID %llu => got %llu - %s (%d)", 17348b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin (unsigned long long)inputPoolId, 17358b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin (unsigned long long)(pool ? pool->getLocalId() : 111000111), 17368b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin asString(err), err); 17378b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (err != C2_OK) { 17388b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin return NO_MEMORY; 17398b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 17408b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 17418b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin pools->inputPool = pool; 17428b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 17438b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 17448b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1745033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (graphic) { 1746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mInputSurface) { 1747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new DummyInputBuffers); 1748f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } else if (mMetaMode == MODE_ANW) { 1749f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim buffers->reset(new GraphicMetadataInputBuffers); 1750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new GraphicInputBuffers); 1752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (hasCryptoOrDescrambler()) { 1755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mDealer == nullptr) { 1756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDealer = new MemoryDealer( 1757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim align(kLinearBufferSize, MemoryDealer::getAllocationAlignment()) 175860e4b7347394676287f7686ddced77544a106831Wonsik Kim * (kMinInputBufferArraySize + 1), 1759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "EncryptedLinearInputBuffers"); 1760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDecryptDestination = mDealer->allocate(kLinearBufferSize); 1761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mCrypto != nullptr && mHeapSeqNum < 0) { 1763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap()); 1764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mHeapSeqNum = -1; 1766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new EncryptedLinearInputBuffers( 1768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim secure, mDealer, mCrypto, mHeapSeqNum)); 1769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new LinearInputBuffers); 1771033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffers)->setFormat(inputFormat); 1774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err == C2_OK) { 1776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffers)->setPool(pool); 1777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: error 1779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (outputFormat != nullptr) { 17832cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa sp<IGraphicBufferProducer> outputSurface; 17842cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa uint32_t outputGeneration; 1785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<OutputSurface>::Locked output(mOutputSurface); 17872cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputSurface = output->surface ? 17882cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa output->surface->getIGraphicBufferProducer() : nullptr; 17892cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputGeneration = output->generation; 1790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 17928b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin bool graphic = (oStreamFormat.value == C2FormatVideo); 17938b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2BlockPool::local_id_t outputPoolId_; 17942cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa 17958b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin { 17968b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin Mutexed<BlockPools>::Locked pools(mBlockPools); 17978b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 17988b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // set default allocator ID. 1799a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar pools->outputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC 18008b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin : C2PlatformAllocatorStore::ION; 18018b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 18028b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // query C2PortAllocatorsTuning::output from component, or use default allocator if 18038b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // unsuccessful. 18048b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::vector<std::unique_ptr<C2Param>> params; 18058b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin err = mComponent->query({ }, 18068b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin { C2PortAllocatorsTuning::output::PARAM_TYPE }, 18078b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2_DONT_BLOCK, 18088b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ¶ms); 18098b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) { 18108b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ALOGD("Query input allocators returned %zu params => %s (%u)", 18118b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin params.size(), asString(err), err); 18128b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } else if (err == C2_OK && params.size() == 1) { 18138b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2PortAllocatorsTuning::output *outputAllocators = 18148b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2PortAllocatorsTuning::output::From(params[0].get()); 18158b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (outputAllocators && outputAllocators->flexCount() > 0) { 18168b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::shared_ptr<C2Allocator> allocator; 18178b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // verify allocator IDs and resolve default allocator 18188b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin allocatorStore->fetchAllocator(outputAllocators->m.values[0], &allocator); 18198b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (allocator) { 18208b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin pools->outputAllocatorId = allocator->getId(); 18218b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } else { 18228b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ALOGD("component requested invalid output allocator ID %u", 18238b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin outputAllocators->m.values[0]); 18248b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 18258b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 18268b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 18278b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 1828a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar // use bufferqueue if outputting to a surface 1829a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar if (pools->outputAllocatorId == C2PlatformAllocatorStore::GRALLOC 18302cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa && outputSurface 1831a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar && ((poolMask >> C2PlatformAllocatorStore::BUFFERQUEUE) & 1)) { 1832a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar pools->outputAllocatorId = C2PlatformAllocatorStore::BUFFERQUEUE; 1833a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar } 1834a0d2cfa4011de5e4d62219a2872c479f42904c2eLajos Molnar 18350c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar if ((poolMask >> pools->outputAllocatorId) & 1) { 18360c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar err = mComponent->createBlockPool( 18370c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar pools->outputAllocatorId, &pools->outputPoolId, &pools->outputPoolIntf); 18380c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar ALOGI("Created output block pool with allocatorID %u => poolID %llu - %s", 18390c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar pools->outputAllocatorId, 18400c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar (unsigned long long)pools->outputPoolId, 18410c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar asString(err)); 18420c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar } else { 18430c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar err = C2_NOT_FOUND; 18440c751518fa35dda5d0adc290a5dc3d09fd30dca1Lajos Molnar } 18458b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin if (err != C2_OK) { 18468b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // use basic pool instead 18478b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin pools->outputPoolId = 18488b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR; 18498b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 18508b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 18518b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // Configure output block pool ID as parameter C2PortBlockPoolsTuning::output to 18528b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // component. 18538b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::unique_ptr<C2PortBlockPoolsTuning::output> poolIdsTuning = 18548b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin C2PortBlockPoolsTuning::output::AllocUnique({ pools->outputPoolId }); 18558b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 18568b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin std::vector<std::unique_ptr<C2SettingResult>> failures; 18578b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin err = mComponent->config({ poolIdsTuning.get() }, C2_MAY_BLOCK, &failures); 18588b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin ALOGD("Configured output block pool ids %llu => %s", 18598b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin (unsigned long long)poolIdsTuning->m.values[0], asString(err)); 18608b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin outputPoolId_ = pools->outputPoolId; 18618b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 18628b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 1863033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 1864033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1865033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (graphic) { 18662cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa if (outputSurface) { 1867033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new GraphicOutputBuffers); 1868033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1869033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new RawGraphicOutputBuffers); 1870033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1871033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1872033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers->reset(new LinearOutputBuffers); 1873033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1874d450fc3eced9eb713b7e27d98d2b353782a6a4f4Wonsik Kim (*buffers)->setFormat(outputFormat->dup()); 18758b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 18768b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin 18778b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin // Try to set output surface to created block pool if given. 18782cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa if (outputSurface) { 18792cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa mComponent->setOutputSurface( 18802cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputPoolId_, 18812cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputSurface, 18822cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputGeneration); 18838b0b2c32666ea799c27b30e64ea89291fa069f4dPin-chih Lin } 1884dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 1885dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (oStreamFormat.value == C2FormatAudio) { 1886dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t channelCount; 1887dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t sampleRate; 1888dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount) 1889dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) { 1890dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t delay = 0; 1891dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t padding = 0;; 1892dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (!outputFormat->findInt32("encoder-delay", &delay)) { 1893dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim delay = 0; 1894dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1895dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (!outputFormat->findInt32("encoder-padding", &padding)) { 1896dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim padding = 0; 1897dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1898dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (delay || padding) { 1899dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim // We need write access to the buffers.. 1900dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim (*buffers) = (*buffers)->toArrayMode(); 1901dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim (*buffers)->initSkipCutBuffer(delay, padding, sampleRate, channelCount); 1902dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1903dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1904dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 1905033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1906033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1907ce4de71f149b6ed922d018ec442d65711fd98a19Wonsik Kim mPendingFeed = 0; 1908033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSync.start(); 1909033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mInputSurface == nullptr) { 1910033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: use proper buffer depth instead of this random value 191160e4b7347394676287f7686ddced77544a106831Wonsik Kim for (size_t i = 0; i < kMinInputBufferArraySize; ++i) { 1912033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t index; 1913033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> buffer; 1914033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1915033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1916033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!(*buffers)->requestNewBuffer(&index, &buffer)) { 1917033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (i == 0) { 1918033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("start: cannot allocate memory at all"); 1919033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return NO_MEMORY; 1920033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1921033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("start: cannot allocate memory, only %zu buffers allocated", i); 1922033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1923033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1924033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1925033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1926e0512ca21578cb3f36328c3c01b6f9ad9b15fb47Praveen Chavan if (buffer) { 1927e0512ca21578cb3f36328c3c01b6f9ad9b15fb47Praveen Chavan mCallback->onInputBufferAvailable(index, buffer); 1928e0512ca21578cb3f36328c3c01b6f9ad9b15fb47Praveen Chavan } 1929033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1930033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1931033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1932033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1933033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1934033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::stop() { 1935033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSync.stop(); 1936033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mFirstValidFrameIndex = mFrameIndex.load(); 1937033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mInputSurface != nullptr) { 1938033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mInputSurface->disconnect(); 1939033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mInputSurface.reset(); 1940033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1941033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1942033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1943033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) { 1944a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim ALOGV("flush"); 1945033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1946033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers); 1947033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffers)->flush(); 1948033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1949033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1950033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 1951033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*buffers)->flush(flushedWork); 1952033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1953033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1954033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 19553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarvoid CCodecBufferChannel::onWorkDone( 19563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat, 19573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar const C2StreamInitDataInfo::output *initData) { 1958c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim if (handleWork(std::move(work), outputFormat, initData)) { 1959c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ALOGV("%s: pending feed +1 from %u", __func__, mPendingFeed.load()); 1960c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim ++mPendingFeed; 1961384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim } 1962c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim feedInputBufferIfAvailable(); 1963384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim} 1964a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim 1965384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimbool CCodecBufferChannel::handleWork( 1966384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim std::unique_ptr<C2Work> work, 1967384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim const sp<AMessage> &outputFormat, 1968384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim const C2StreamInitDataInfo::output *initData) { 1969033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work->result != C2_OK) { 1970033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work->result == C2_NOT_FOUND) { 1971033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: Define what flushed work's result is. 1972033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("flushed work; ignored."); 1973384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return true; 1974033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1975033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("work failed to complete: %d", work->result); 1976384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCCodecCallback->onError(work->result, ACTION_CODE_FATAL); 1977384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return false; 1978033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1979033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1980033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // NOTE: MediaCodec usage supposedly have only one worklet 1981033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work->worklets.size() != 1u) { 1982033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("onWorkDone: incorrect number of worklets: %zu", 1983033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.size()); 1984384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1985384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return false; 1986033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1987033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1988033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Worklet> &worklet = work->worklets.front(); 1989033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if ((worklet->output.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) { 1990033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Discard frames from previous generation. 1991a215f50524c8e0688cceb0b8489a6703a3bdf619Wonsik Kim ALOGD("Discard frames from previous generation."); 1992384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return true; 1993033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1994033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Buffer> buffer; 1995033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // NOTE: MediaCodec usage supposedly have only one output stream. 1996033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (worklet->output.buffers.size() > 1u) { 1997033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("onWorkDone: incorrect number of output buffers: %zu", 1998033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim worklet->output.buffers.size()); 1999384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 2000384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return false; 2001033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else if (worklet->output.buffers.size() == 1u) { 2002033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffer = worklet->output.buffers[0]; 2003033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!buffer) { 2004033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("onWorkDone: nullptr found in buffers; ignored."); 2005033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2006033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2007033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 20083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (outputFormat != nullptr) { 20098c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 20103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGD("onWorkDone: output format changed to %s", 20113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat->debugString().c_str()); 20123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar (*buffers)->setFormat(outputFormat); 2013dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 2014dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim AString mediaType; 2015dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (outputFormat->findString(KEY_MIME, &mediaType) 2016dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim && mediaType == MIMETYPE_AUDIO_RAW) { 2017dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t channelCount; 2018dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int32_t sampleRate; 2019dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount) 2020dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) { 2021dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim (*buffers)->updateSkipCutBuffer(sampleRate, channelCount); 2022dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 2023dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 2024033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2025033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2026033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t flags = 0; 2027033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) { 2028033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flags |= MediaCodec::BUFFER_FLAG_EOS; 2029033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("onWorkDone: output EOS"); 2030033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2031033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2032384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim bool feedNeeded = true; 2033033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<MediaCodecBuffer> outBuffer; 2034033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t index; 20353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (initData != nullptr) { 2036033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 20373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if ((*buffers)->registerCsd(initData, &index, &outBuffer)) { 2038033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek()); 2039365fd1a7643c3b6f7aba081dd38965d78d7d58ffHarish Mahendrakar outBuffer->meta()->setInt32("flags", MediaCodec::BUFFER_FLAG_CODECCONFIG); 2040033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("onWorkDone: csd index = %zu", index); 2041033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2042033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers.unlock(); 2043033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onOutputBufferAvailable(index, outBuffer); 2044033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers.lock(); 2045384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim feedNeeded = false; 2046033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 2047033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("onWorkDone: unable to register csd"); 2048033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers.unlock(); 2049384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 2050033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim buffers.lock(); 2051384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return false; 2052033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2053033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2054033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2055033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!buffer && !flags) { 2056a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim ALOGV("onWorkDone: Not reporting output buffer (%lld)", 2057a28531affe22ce6db653e09e7978730dbd1f068aWonsik Kim work->input.ordinal.frameIndex.peekull()); 2058384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return feedNeeded; 2059033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2060033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2061033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (buffer) { 2062033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (const std::shared_ptr<const C2Info> &info : buffer->info()) { 2063033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: properly translate these to metadata 2064033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (info->coreIndex().coreIndex()) { 2065033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case C2StreamPictureTypeMaskInfo::CORE_INDEX: 2066033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (((C2StreamPictureTypeMaskInfo *)info.get())->value & C2PictureTypeKeyFrame) { 2067033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; 2068033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2069033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 2070033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: 2071033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 2072033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2073033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2074033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2075033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2076033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 2077033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers); 2078033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!(*buffers)->registerBuffer(buffer, &index, &outBuffer)) { 2079033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("onWorkDone: unable to register output buffer"); 20806b660d3c8bbc9cf48f00d15e062d1708bc315efcPraveen Chavan // TODO 20816b660d3c8bbc9cf48f00d15e062d1708bc315efcPraveen Chavan // buffers.unlock(); 2082384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim // mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 20836b660d3c8bbc9cf48f00d15e062d1708bc315efcPraveen Chavan // buffers.lock(); 2084384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return false; 2085033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2086033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2087033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2088033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek()); 2089033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outBuffer->meta()->setInt32("flags", flags); 2090585b02290e1dc5c0fb6a635ce19d9ec785dbf60aWonsik Kim ALOGV("onWorkDone: out buffer index = %zu size = %zu", index, outBuffer->size()); 2091033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onOutputBufferAvailable(index, outBuffer); 2092384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim return false; 2093033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 2094033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2095033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) { 2096033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (newSurface != nullptr) { 2097033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 209860e4b7347394676287f7686ddced77544a106831Wonsik Kim newSurface->setMaxDequeuedBufferCount(kMinOutputBufferArraySize); 2099033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 2100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// if (newSurface == nullptr) { 2102033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// if (*surface != nullptr) { 2103033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// ALOGW("cannot unset a surface"); 2104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// return INVALID_OPERATION; 2105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// } 2106033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// return OK; 2107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// } 2108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// 2109033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// if (*surface == nullptr) { 2110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// ALOGW("component was not configured with a surface"); 2111033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// return INVALID_OPERATION; 2112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// } 2113033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21142cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa uint32_t generation; 21152cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa 2116c61f8ada1d56cae29a86f72ece574d011931e46bWonsik Kim ANativeWindowBuffer *buf; 21172cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa ANativeWindow *window = newSurface.get(); 2118c61f8ada1d56cae29a86f72ece574d011931e46bWonsik Kim int fenceFd; 2119c61f8ada1d56cae29a86f72ece574d011931e46bWonsik Kim window->dequeueBuffer(window, &buf, &fenceFd); 2120c61f8ada1d56cae29a86f72ece574d011931e46bWonsik Kim sp<GraphicBuffer> gbuf = GraphicBuffer::from(buf); 21212cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa generation = gbuf->getGenerationNumber(); 2122c61f8ada1d56cae29a86f72ece574d011931e46bWonsik Kim window->cancelBuffer(window, buf, fenceFd); 2123033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21242cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa std::shared_ptr<Codec2Client::Configurable> outputPoolIntf; 21252cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa C2BlockPool::local_id_t outputPoolId; 21262cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa { 21272cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa Mutexed<BlockPools>::Locked pools(mBlockPools); 21282cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputPoolId = pools->outputPoolId; 21292cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputPoolIntf = pools->outputPoolIntf; 21302cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa } 21312cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa 21322cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa if (outputPoolIntf) { 21332cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa if (mComponent->setOutputSurface( 21342cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa outputPoolId, 21352cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa newSurface->getIGraphicBufferProducer(), 21362cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa generation) != C2_OK) { 21372cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa ALOGW("setSurface -- setOutputSurface() failed to configure " 21382cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa "new surface to the component's output block pool."); 21392cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa return INVALID_OPERATION; 21402cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa } 21412cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa } 21422cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa 21432cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa { 21442cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa Mutexed<OutputSurface>::Locked output(mOutputSurface); 21452cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa output->surface = newSurface; 21462cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa output->generation = generation = gbuf->getGenerationNumber(); 21472cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa } 21482cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa 2149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 2150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 2151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2152f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kimvoid CCodecBufferChannel::setMetaMode(MetaMode mode) { 2153f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim mMetaMode = mode; 2154f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim} 2155f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 2156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 2157