1033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/* 2033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Copyright (C) 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 170f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa#define LOG_NDEBUG 0 18033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define LOG_TAG "CCodec" 19033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/Log.h> 20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar#include <sstream> 22033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <thread> 23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 24277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim#include <C2Config.h> 253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <C2Debug.h> 26069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim#include <C2ParamInternal.h> 27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h> 28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2V4l2Support.h> 29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <android/IOMXBufferSource.h> 311c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim#include <android/IGraphicBufferSource.h> 322bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa#include <cutils/properties.h> 33033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> 341c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim#include <gui/IGraphicBufferProducer.h> 35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <gui/Surface.h> 361c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim#include <media/omx/1.0/WOmx.h> 37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/codec2/1.0/InputSurface.h> 38033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/BufferProducerWrapper.h> 393bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar#include <media/stagefright/MediaCodecConstants.h> 40033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/PersistentSurface.h> 41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "C2OMXNode.h" 43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "CCodec.h" 44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "CCodecBufferChannel.h" 45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "InputSurfaceWrapper.h" 46033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android { 48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing namespace std::chrono_literals; 50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer; 511c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kimusing BGraphicBufferSource = ::android::IGraphicBufferSource; 52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 53033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace { 54033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 55033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass CCodecWatchdog : public AHandler { 56033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 57033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim enum { 58033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim kWhatRegister, 59033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim kWhatWatch, 60033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 61033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim constexpr static int64_t kWatchIntervalUs = 3000000; // 3 secs 62033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 63033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 64033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim static sp<CCodecWatchdog> getInstance() { 65033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<sp<CCodecWatchdog>>::Locked instance(sInstance); 66033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (*instance == nullptr) { 67033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *instance = new CCodecWatchdog; 68033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*instance)->init(); 69033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 70033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return *instance; 71033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 72033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 73033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~CCodecWatchdog() = default; 74033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 75033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void registerCodec(CCodec *codec) { 76033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg = new AMessage(kWhatRegister, this); 77033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setPointer("codec", codec); 78033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 79033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 80033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 81033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprotected: 82033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void onMessageReceived(const sp<AMessage> &msg) { 83033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (msg->what()) { 84033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatRegister: { 85033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void *ptr = nullptr; 86033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findPointer("codec", &ptr)); 87033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs); 88033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codecs->emplace_back((CCodec *)ptr); 89033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 90033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 91033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 92033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatWatch: { 93033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs); 94033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (auto it = codecs->begin(); it != codecs->end(); ) { 95033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<CCodec> codec = it->promote(); 96033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codec == nullptr) { 97033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim it = codecs->erase(it); 98033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim continue; 99033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codec->initiateReleaseIfStuck(); 101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ++it; 102033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 103033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(kWatchIntervalUs); 104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 106033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: { 108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim TRESPASS("CCodecWatchdog: unrecognized message"); 109033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 111033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 113033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 114033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CCodecWatchdog() : mLooper(new ALooper) {} 115033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 116033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void init() { 117033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mLooper->setName("CCodecWatchdog"); 118033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mLooper->registerHandler(this); 119033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mLooper->start(); 120033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs); 121033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 122033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 123033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim static Mutexed<sp<CCodecWatchdog>> sInstance; 124033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<ALooper> mLooper; 126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<wp<CCodec>>> mCodecs; 127033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 128033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 129033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimMutexed<sp<CCodecWatchdog>> CCodecWatchdog::sInstance; 130033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2InputSurfaceWrapper : public InputSurfaceWrapper { 132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 1330f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa explicit C2InputSurfaceWrapper( 1340f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa const std::shared_ptr<Codec2Client::InputSurface> &surface) : 1350f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mSurface(surface) { 1360f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa } 1370f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa 138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~C2InputSurfaceWrapper() override = default; 139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1400f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override { 141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mConnection != nullptr) { 142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return ALREADY_EXISTS; 143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1440f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa return static_cast<status_t>( 1450f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mSurface->connectToComponent(comp, &mConnection)); 146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void disconnect() override { 149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mConnection != nullptr) { 150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mConnection->disconnect(); 1510f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mConnection = nullptr; 152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1557a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim status_t signalEndOfInputStream() override { 1567a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim C2InputSurfaceEosTuning eos(true); 1577a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim std::vector<std::unique_ptr<C2SettingResult>> failures; 1587a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim c2_status_t err = mSurface->getConfigurable()->config({&eos}, C2_MAY_BLOCK, &failures); 1597a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim if (err != C2_OK) { 1607a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return UNKNOWN_ERROR; 1617a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 1627a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return OK; 1637a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 1647a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim 165cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t configure(Config &config __unused) { 166cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // TODO 167cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar return OK; 168cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 169cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 1710f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::InputSurface> mSurface; 1720f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::InputSurfaceConnection> mConnection; 173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass GraphicBufferSourceWrapper : public InputSurfaceWrapper { 176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 177ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim// explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {} 178ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim GraphicBufferSourceWrapper( 179ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim const sp<BGraphicBufferSource> &source, 180ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t width, 181ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t height) 182ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim : mSource(source), mWidth(width), mHeight(height) {} 183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~GraphicBufferSourceWrapper() override = default; 184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1850f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override { 186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: proper color aspect & dataspace 187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim android_dataspace dataSpace = HAL_DATASPACE_BT709; 188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mNode = new C2OMXNode(comp); 190ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim mNode->setFrameSize(mWidth, mHeight); 191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSource->configure(mNode, dataSpace); 192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: configure according to intf(). 194cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // TODO: initial color aspects (dataspace) 195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IOMXBufferSource> source = mNode->getSource(); 197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (source == nullptr) { 198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return NO_INIT; 199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim constexpr size_t kNumSlots = 16; 201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < kNumSlots; ++i) { 202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onInputBufferAdded(i); 203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxExecuting(); 205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void disconnect() override { 209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mNode == nullptr) { 210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IOMXBufferSource> source = mNode->getSource(); 213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (source == nullptr) { 214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource."); 215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxIdle(); 218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxLoaded(); 219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mNode.clear(); 220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 222cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t GetStatus(const binder::Status &status) { 223cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t err = OK; 224cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (!status.isOk()) { 225cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = status.serviceSpecificErrorCode(); 226cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (err == OK) { 227cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = status.transactionError(); 228cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (err == OK) { 229cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // binder status failed, but there is no servie or transaction error 230cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = UNKNOWN_ERROR; 231cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 232cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 233cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 234cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar return err; 235cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 236cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 2377a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim status_t signalEndOfInputStream() override { 238cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar return GetStatus(mSource->signalEndOfInputStream()); 239cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 240cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 241cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t configure(Config &config) { 242cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar std::stringstream status; 2437a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim status_t err = OK; 244cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 245cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // handle each configuration granually, in case we need to handle part of the configuration 246cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // elsewhere 247cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 248cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // TRICKY: we do not unset frame delay repeating 249cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config.mMinFps > 0 && config.mMinFps != mConfig.mMinFps) { 250cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar int64_t us = 1e6 / config.mMinFps + 0.5; 251cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t res = GetStatus(mSource->setRepeatPreviousFrameDelayUs(us)); 252cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " minFps=" << config.mMinFps << " => repeatDelayUs=" << us; 253cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 254cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 255cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = res; 256cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 257cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mMinFps = config.mMinFps; 258cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 259cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 260cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // TODO: pts gap 261cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 262cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // max fps 263cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // TRICKY: we do not unset max fps to 0 unless using fixed fps 264cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if ((config.mMaxFps > 0 || (config.mFixedAdjustedFps > 0 && config.mMaxFps == 0)) 265cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar && config.mMaxFps != mConfig.mMaxFps) { 266cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t res = GetStatus(mSource->setMaxFps(config.mMaxFps)); 267cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " maxFps=" << config.mMaxFps; 268cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 269cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 270cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = res; 271cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 272cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mMaxFps = config.mMaxFps; 273cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 274cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 275cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config.mTimeOffsetUs != mConfig.mTimeOffsetUs) { 276cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t res = GetStatus(mSource->setTimeOffsetUs(config.mTimeOffsetUs)); 277cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " timeOffset " << config.mTimeOffsetUs << "us"; 278cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 279cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 280cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = res; 281cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 282cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mTimeOffsetUs = config.mTimeOffsetUs; 2837a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 284cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 285cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // TODO: time lapse config 286cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 287cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config.mStartAtUs != mConfig.mStartAtUs 288cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar || (config.mStopped != mConfig.mStopped && !config.mStopped)) { 289cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t res = GetStatus(mSource->setStartTimeUs(config.mStartAtUs)); 290cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " start at " << config.mStartAtUs << "us"; 291cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 292cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 293cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = res; 294cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 295cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mStartAtUs = config.mStartAtUs; 296cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mStopped = config.mStopped; 297cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 298cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 299cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // suspend-resume 300cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config.mSuspended != mConfig.mSuspended) { 301cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t res = GetStatus(mSource->setSuspend(config.mSuspended, config.mSuspendAtUs)); 302cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " " << (config.mSuspended ? "suspend" : "resume") 303cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar << " at " << config.mSuspendAtUs << "us"; 304cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 305cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 306cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = res; 307cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 308cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mSuspended = config.mSuspended; 309cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mSuspendAtUs = config.mSuspendAtUs; 310cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 311cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 312cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config.mStopped != mConfig.mStopped && config.mStopped) { 313cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status_t res = GetStatus(mSource->setStopTimeUs(config.mStopAtUs)); 314cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " stop at " << config.mStopAtUs << "us"; 315cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 316cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 317cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar err = res; 318cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } else { 319cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " delayUs"; 320cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs)); 321cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (res != OK) { 322cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << " (=> " << asString(res) << ")"; 323cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } else { 324cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar status << "=" << config.mInputDelayUs << "us"; 325cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 326cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mInputDelayUs = config.mInputDelayUs; 327cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 328cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mStopAtUs = config.mStopAtUs; 329cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar mConfig.mStopped = config.mStopped; 330cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 331cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 332cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // color aspects (android._color-aspects) 333cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 334cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar // consumer usage 335cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar ALOGD("ISConfig%s", status.str().c_str()); 336cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar return err; 3377a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 3387a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim 339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 3401c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim sp<BGraphicBufferSource> mSource; 341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<C2OMXNode> mNode; 342ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t mWidth; 343ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t mHeight; 344cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar Config mConfig; 345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 34778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnarclass Codec2ClientInterfaceWrapper : public C2ComponentStore { 34878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::shared_ptr<Codec2Client> mClient; 34978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 35078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnarpublic: 35178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar Codec2ClientInterfaceWrapper(std::shared_ptr<Codec2Client> client) 35278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar : mClient(client) { } 35378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 35478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual ~Codec2ClientInterfaceWrapper() = default; 35578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 35678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t config_sm( 35778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar const std::vector<C2Param *> ¶ms, 35878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::vector<std::unique_ptr<C2SettingResult>> *const failures) { 35978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return mClient->config(params, C2_MAY_BLOCK, failures); 36078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar }; 36178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 36278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t copyBuffer( 36378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::shared_ptr<C2GraphicBuffer>, 36478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::shared_ptr<C2GraphicBuffer>) { 36578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return C2_OMITTED; 36678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 36778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 36878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t createComponent( 36978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar C2String, std::shared_ptr<C2Component> *const component) { 37078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar component->reset(); 37178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return C2_OMITTED; 37278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 37378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 37478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t createInterface( 37578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar C2String, std::shared_ptr<C2ComponentInterface> *const interface) { 37678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar interface->reset(); 37778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return C2_OMITTED; 37878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 37978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 38078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t query_sm( 38178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar const std::vector<C2Param *> &stackParams, 38278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar const std::vector<C2Param::Index> &heapParamIndices, 38378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::vector<std::unique_ptr<C2Param>> *const heapParams) const { 38478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams); 38578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 38678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 38778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t querySupportedParams_nb( 38878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const { 38978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return mClient->querySupportedParams(params); 39078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 39178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 39278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual c2_status_t querySupportedValues_sm( 39378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::vector<C2FieldSupportedValuesQuery> &fields) const { 39478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return mClient->querySupportedValues(fields, C2_MAY_BLOCK); 39578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 39678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 39778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual C2String getName() const { 39878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return mClient->getName(); 39978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 40078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 40178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual std::shared_ptr<C2ParamReflector> getParamReflector() const { 40278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return mClient->getParamReflector(); 40378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 40478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 40578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() { 40678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar return std::vector<std::shared_ptr<const C2Component::Traits>>(); 40778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 40878746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar}; 40978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace 411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 4120f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa// CCodec::ClientListener 4130f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4140f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasastruct CCodec::ClientListener : public Codec2Client::Listener { 4150f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4160f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa explicit ClientListener(const wp<CCodec> &codec) : mCodec(codec) {} 4170f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4180f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onWorkDone( 4190f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component, 4200f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa std::list<std::unique_ptr<C2Work>>& workItems) override { 4210f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)component; 4220f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa sp<CCodec> codec(mCodec.promote()); 4230f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa if (!codec) { 4240f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa return; 4250f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4260f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa codec->onWorkDone(workItems); 4270f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4280f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4290f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onTripped( 4300f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component, 4310f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::vector<std::shared_ptr<C2SettingResult>>& settingResult 4320f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa ) override { 4330f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa // TODO 4340f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)component; 4350f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)settingResult; 4360f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4370f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4380f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onError( 4390f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component, 4400f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa uint32_t errorCode) override { 4410f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa // TODO 4420f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)component; 4430f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)errorCode; 4440f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4450f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4460f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onDeath( 4470f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component) override { 4480f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa { // Log the death of the component. 4490f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa std::shared_ptr<Codec2Client::Component> comp = component.lock(); 4500f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa if (!comp) { 4510f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa ALOGE("Codec2 component died."); 4520f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } else { 4530f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa ALOGE("Codec2 component \"%s\" died.", comp->getName().c_str()); 4540f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4550f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4560f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 4570f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa // Report to MediaCodec. 4580f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa sp<CCodec> codec(mCodec.promote()); 4590f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa if (!codec || !codec->mCallback) { 4600f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa return; 4610f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4620f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa codec->mCallback->onError(DEAD_OBJECT, ACTION_CODE_FATAL); 4630f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 4640f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 465c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa virtual void onFramesRendered( 466c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa const std::vector<RenderedFrame>& renderedFrames) override { 467c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa // TODO 468c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa (void)renderedFrames; 469c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa } 470c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa 4710f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasaprivate: 4720f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa wp<CCodec> mCodec; 4730f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa}; 4740f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 475384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim// CCodecCallbackImpl 476384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 477384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimclass CCodecCallbackImpl : public CCodecCallback { 478384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimpublic: 479384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim explicit CCodecCallbackImpl(CCodec *codec) : mCodec(codec) {} 480384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim ~CCodecCallbackImpl() override = default; 481384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 482384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim void onError(status_t err, enum ActionCode actionCode) override { 483384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCodec->mCallback->onError(err, actionCode); 484384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim } 485384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 486384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) override { 487384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCodec->mCallback->onOutputFramesRendered( 488384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim {RenderedFrameInfo(mediaTimeUs, renderTimeNs)}); 489384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim } 490384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 491384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimprivate: 492384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim CCodec *mCodec; 493384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim}; 494384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 4950f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa// CCodec 4960f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 497033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodec::CCodec() 498384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim : mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))) { 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CCodecWatchdog::getInstance()->registerCodec(this); 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 501033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodec::~CCodec() { 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstd::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() { 506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mChannel; 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::tryAndReportOnError(std::function<status_t()> job) { 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = job(); 511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err; 515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateAllocateComponent(const sp<AMessage> &msg) { 518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setAllocating = [this] { 519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RELEASED) { 521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return INVALID_OPERATION; 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATING); 524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setAllocating) != OK) { 527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> codecInfo; 531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("codecInfo", &codecInfo)); 532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // For Codec 2.0 components, componentName == codecInfo->getCodecName(). 533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this)); 535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocMsg->setObject("codecInfo", codecInfo); 536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocMsg->post(); 537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) { 540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codecInfo == nullptr) { 541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("allocate(%s)", codecInfo->getCodecName()); 5450f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa mClientListener.reset(new ClientListener(this)); 546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString componentName = codecInfo->getCodecName(); 5480f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client> client; 54978746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 55078746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar // set up preferred component store to access vendor store parameters 55178746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar client = Codec2Client::CreateFromService("default", false); 55278746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar if (client) { 55378746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar ALOGI("setting up '%s' as default (vendor) store", client->getInstanceName().c_str()); 55478746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar SetPreferredCodec2ComponentStore( 55578746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar std::make_shared<Codec2ClientInterfaceWrapper>(client)); 55678746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar } 55778746a1fc9643659f5a50658a5c6db75955d440cLajos Molnar 5580f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp = 5590f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa Codec2Client::CreateComponentByName( 5600f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa componentName.c_str(), 5610f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa mClientListener, 5620f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa &client); 5630f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa if (!comp) { 564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed Create component: %s", componentName.c_str()); 565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 566033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 5680f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 5723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGI("Created component [%s]", componentName.c_str()); 573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->setComponent(comp); 5740f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa auto setAllocated = [this, comp, client] { 575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATING) { 577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATED); 581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->comp = comp; 5820f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mClient = client; 583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setAllocated) != OK) { 586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 5883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 5893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // initialize config here in case setParameters is called prior to configure 5903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 5913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar status_t err = config->initialize(mClient, comp); 5923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (err != OK) { 5933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGW("Failed to initialize configuration support"); 5943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TODO: report error once we complete implementation. 5953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 5963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->queryConfiguration(comp); 5973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 5980f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mCallback->onComponentAllocated(comp->getName().c_str()); 599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateConfigureComponent(const sp<AMessage> &format) { 602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkAllocated = [this] { 603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK; 605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkAllocated) != OK) { 607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg(new AMessage(kWhatConfigure, this)); 611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setMessage("format", format); 612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::configure(const sp<AMessage> &msg) { 6160f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 6170f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa auto checkAllocated = [this, &comp] { 618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 6230f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa comp = state->comp; 624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkAllocated) != OK) { 627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 6303078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim auto doConfig = [msg, comp, this]() -> status_t { 631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString mime; 632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!msg->findString("mime", &mime)) { 633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return BAD_VALUE; 634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t encoder; 637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!msg->findInt32("encoder", &encoder)) { 638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encoder = false; 639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 6413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TODO: read from intf() 6423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if ((!encoder) != (comp->getName().find("encoder") == std::string::npos)) { 6433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar return UNKNOWN_ERROR; 6443bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 6453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 646f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim int32_t storeMeta; 647f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (encoder 648f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim && msg->findInt32("android._input-metadata-buffer-type", &storeMeta) 649f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim && storeMeta != kMetadataBufferTypeInvalid) { 650f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (storeMeta != kMetadataBufferTypeANWBuffer) { 651f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim ALOGD("Only ANW buffers are supported for legacy metadata mode"); 652f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return BAD_VALUE; 653f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 654f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim mChannel->setMetaMode(CCodecBufferChannel::MODE_ANW); 655f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 656f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 657033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 658c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar sp<Surface> surface; 659033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (msg->findObject("native-window", &obj)) { 660c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar surface = static_cast<Surface *>(obj.get()); 661033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setSurface(surface); 662033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 663033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 6643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 665cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 666c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar /* 667cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar * Handle input surface configuration 668cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar */ 669cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE)) 670cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar && (config->mDomain & Config::IS_ENCODER)) { 671cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig.reset(new InputSurfaceWrapper::Config{}); 672cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar { 673cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mMinFps = 0; 674cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar int64_t value; 675cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (msg->findInt64("repeat-previous-frame-after", &value) && value > 0) { 676cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mMinFps = 1e6 / value; 677cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 678cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar (void)msg->findFloat("max-fps-to-encoder", &config->mISConfig->mMaxFps); 679cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mMinAdjustedFps = 0; 680cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mFixedAdjustedFps = 0; 681cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (msg->findInt64("max-pts-gap-to-encoder", &value)) { 682cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (value < 0 && value >= INT32_MIN) { 683cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mFixedAdjustedFps = -1e6 / value; 684cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } else if (value > 0 && value <= INT32_MAX) { 685cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mMinAdjustedFps = 1e6 / value; 686cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 687cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 688cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 689cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 690cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar { 691cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar double value; 692cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (!msg->findDouble("time-lapse-fps", &value)) { 693cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mCaptureFps = value; 694cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 695cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 696cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 697cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar { 698cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mSuspended = false; 699cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mSuspendAtUs = -1; 700cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar int32_t value; 701cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (msg->findInt32("create-input-buffers-suspended", &value) && value) { 702cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mSuspended = true; 703cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 704cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 705cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 706cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 707c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar /* 708c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar * Handle desired color format. 709c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar */ 710c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) { 711c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar int32_t format = -1; 712c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if (!msg->findInt32(KEY_COLOR_FORMAT, &format)) { 713c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar /* 714c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar * Also handle default color format (encoders require color format, so this is only 715c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar * needed for decoders. 716c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar */ 717c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if (!(config->mDomain & Config::IS_ENCODER)) { 718c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar format = (surface == nullptr) ? COLOR_FormatYUV420Planar : COLOR_FormatSurface; 719c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 720c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 721c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar 722c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if (format >= 0) { 723c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar msg->setInt32("android._color-format", format); 724c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 725c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 726c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar 7273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::vector<std::unique_ptr<C2Param>> configUpdate; 7283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar status_t err = config->getConfigUpdateFromSdkParams( 7293bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar comp, msg, Config::CONFIG, C2_DONT_BLOCK, &configUpdate); 7303bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (err != OK) { 7313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGW("failed to convert configuration to c2 params"); 7323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 7333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar err = config->setParameters(comp, configUpdate, C2_DONT_BLOCK); 7343bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (err != OK) { 7353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGW("failed to configure c2 params"); 7363078c7c3136bc9546da39943f0d6abb1f7e344c8Wonsik Kim return err; 7373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 7383bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<std::unique_ptr<C2Param>> params; 7403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar C2StreamUsageTuning::input usage(0u, 0u); 7413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar C2StreamMaxBufferSizeInfo::input maxInputSize(0u, 0u); 7423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::initializer_list<C2Param::Index> indices { 744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 7453bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar c2_status_t c2err = comp->query( 7463bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar { &usage, &maxInputSize }, 747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim indices, 748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2_DONT_BLOCK, 749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ¶ms); 750f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (c2err != C2_OK && c2err != C2_BAD_INDEX) { 751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to query component interface: %d", c2err); 752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (params.size() != indices.size()) { 755f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim ALOGE("Component returns wrong number of params: expected %zu actual %zu", 756f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim indices.size(), params.size()); 757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 759f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (usage && (usage.value & C2MemoryUsage::CPU_READ)) { 7603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mInputFormat->setInt32("using-sw-read-often", true); 761f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 763e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar // use client specified input size if specified 764e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar bool clientInputSize = msg->findInt32(KEY_MAX_INPUT_SIZE, (int32_t*)&maxInputSize.value); 765e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar 7663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TEMP: enforce minimum buffer size of 1MB for video decoders 767e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar if (!clientInputSize && maxInputSize.value == 0 768e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar && !encoder && !(config->mDomain & Config::IS_AUDIO)) { 769e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar maxInputSize.value = 1048576u; 770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 771033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 772a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar // TODO: do this based on component requiring linear allocator for input 7733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if ((config->mDomain & Config::IS_DECODER) || (config->mDomain & Config::IS_AUDIO)) { 7740fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar // Pass max input size on input format to the buffer channel (if supplied by the 7750fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar // component or by a default) 7760fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar if (maxInputSize.value) { 7770fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar config->mInputFormat->setInt32( 778e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar KEY_MAX_INPUT_SIZE, 779e0a6b0044d208783922b0ca9553dbcd98f4aa442Lajos Molnar (int32_t)(c2_min(maxInputSize.value, uint32_t(INT32_MAX)))); 7800fde62fab8b7a8802e4c8fbe8007f41af9dfcf9bLajos Molnar } 781a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar } 782a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar 783c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) { 784c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar // Set desired color format from configuration parameter 785c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar int32_t format; 786c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if (msg->findInt32("android._color-format", &format)) { 787c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar if (config->mDomain & Config::IS_ENCODER) { 788c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar config->mInputFormat->setInt32(KEY_COLOR_FORMAT, format); 789c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } else { 790c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar config->mOutputFormat->setInt32(KEY_COLOR_FORMAT, format); 791c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 792c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 793c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar } 794c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar 795c3979a09c521d8aa8bf2a8e6c18a622b7701a2ceLajos Molnar // propagate encoder delay and padding to output format 796dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if ((config->mDomain & Config::IS_DECODER) && (config->mDomain & Config::IS_AUDIO)) { 797dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int delay = 0; 798dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (msg->findInt32("encoder-delay", &delay)) { 799dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim config->mOutputFormat->setInt32("encoder-delay", delay); 800dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 801dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim int padding = 0; 802dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim if (msg->findInt32("encoder-padding", &padding)) { 803dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim config->mOutputFormat->setInt32("encoder-padding", padding); 804dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 805dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim } 806dd4e2987beb3fe8a5cd3520a54675e73d71f40b6Wonsik Kim 8073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGD("setup formats input: %s and output: %s", 8083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mInputFormat->debugString().c_str(), 8093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mOutputFormat->debugString().c_str()); 810033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 811033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 812033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(doConfig) != OK) { 813033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 814033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 815033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 8163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 8173bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 8183bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat); 819033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 821033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateCreateInputSurface() { 822033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = [this] { 823033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 824033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 825033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 826033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 827033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: read it from intf() properly. 8280f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa if (state->comp->getName().find("encoder") == std::string::npos) { 829033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return INVALID_OPERATION; 830033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 831033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 833033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 834033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 835033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatCreateInputSurface, this))->post(); 839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::createInputSurface() { 8422bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa status_t err; 8431c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim sp<IGraphicBufferProducer> bufferProducer; 844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 845033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 846033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 847033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 8483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 8493bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar inputFormat = config->mInputFormat; 8503bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat = config->mOutputFormat; 851033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 8522bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 8532bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa // TODO: Remove this property check and assume it's always true. 8542bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (property_get_bool("debug.stagefright.c2inputsurface", false)) { 8552bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa std::shared_ptr<Codec2Client::InputSurface> surface; 8562bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 8572bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = static_cast<status_t>(mClient->createInputSurface(&surface)); 8582bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (err != OK) { 8592bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface: %d", static_cast<int>(err)); 8602bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(err); 8612bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 8622bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 8632bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (!surface) { 8642bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface: null input surface"); 8652bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); 8662bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 8672bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 8682bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa bufferProducer = surface->getGraphicBufferProducer(); 8692bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(surface)); 8702bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } else { // TODO: Remove this block. 8712bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa using namespace ::android::hardware::media::omx::V1_0; 8722bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa sp<IOmx> tOmx = IOmx::getService("default"); 8732bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (tOmx == nullptr) { 8742bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface"); 8752bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); 8762bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 8772bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 8782bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa sp<IOMX> omx = new utils::LWOmx(tOmx); 8792bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 8802bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa sp<BGraphicBufferSource> bufferSource; 8812bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = omx->createInputSurface(&bufferProducer, &bufferSource); 8822bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 8832bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (err != OK) { 8842bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface: %d", err); 8852bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(err); 8862bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 8872bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 8882bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa int32_t width = 0; 8892bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa (void)outputFormat->findInt32("width", &width); 8902bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa int32_t height = 0; 8912bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa (void)outputFormat->findInt32("height", &height); 8922bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( 8932bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa bufferSource, width, height)); 8942bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 8952bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 896ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim if (err != OK) { 897ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim ALOGE("Failed to set up input surface: %d", err); 898ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 899ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim return; 900ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim } 901033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreated( 902033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat, 903033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat, 9041c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim new BufferProducerWrapper(bufferProducer)); 905033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 906033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 907033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) { 908033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = mChannel->setInputSurface(surface); 909033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 910033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err; 911033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 912033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 913cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar Mutexed<Config>::Locked config(mConfig); 914cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mInputSurface = surface; 915cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config->mISConfig) { 916cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar surface->configure(*config->mISConfig); 917cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } else { 918cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar ALOGD("ISConfig: no configuration"); 919cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 920cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 921033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: configure |surface| with other settings. 922033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 923033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 924033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 925033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) { 926033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 927033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setObject("surface", surface); 928033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 929033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 930033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 931033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::setInputSurface(const sp<PersistentSurface> &surface) { 932033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 933033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 934033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 9353bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 9363bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar inputFormat = config->mInputFormat; 9373bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat = config->mOutputFormat; 938033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 939ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim int32_t width = 0; 940ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim (void)outputFormat->findInt32("width", &width); 941ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim int32_t height = 0; 942ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim (void)outputFormat->findInt32("height", &height); 943ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( 944ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim surface->getBufferSource(), width, height)); 945ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim if (err != OK) { 946ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim ALOGE("Failed to set up input surface: %d", err); 947ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim mCallback->onInputSurfaceDeclined(err); 948ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim return; 949ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim } 950033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceAccepted(inputFormat, outputFormat); 951033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 952033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 953033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateStart() { 954033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setStarting = [this] { 955033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 956033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 957033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 958033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 959033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(STARTING); 960033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 961033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 962033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setStarting) != OK) { 963033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 964033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 965033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 966033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatStart, this))->post(); 967033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 968033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 969033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::start() { 9700f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 971033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkStarting = [this, &comp] { 972033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 973033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != STARTING) { 974033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 975033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 976033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 977033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 978033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 979033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkStarting) != OK) { 980033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 981033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 982033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 983033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = comp->start(); 984033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 985033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 986033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 987033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 988033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 989033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 990033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 991033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 9923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 9933bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar inputFormat = config->mInputFormat; 9943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat = config->mOutputFormat; 995033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 996033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err2 = mChannel->start(inputFormat, outputFormat); 997033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err2 != OK) { 998033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err2, ACTION_CODE_FATAL); 999033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1000033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1001033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1002033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setRunning = [this] { 1003033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1004033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != STARTING) { 1005033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1006033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1007033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RUNNING); 1008033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1009033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 1010033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setRunning) != OK) { 1011033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1012033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1013033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStartCompleted(); 1014033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1015033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1016033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateShutdown(bool keepComponentAllocated) { 1017033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (keepComponentAllocated) { 1018033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateStop(); 1019033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 1020033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateRelease(); 1021033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1022033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1023033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1024033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateStop() { 1025033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1026033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1027033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == ALLOCATED 1028033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == RELEASED 1029033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == STOPPING 1030033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == RELEASING) { 1031033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already stopped, released, or doing it right now. 1032033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1033033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 1034033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1035033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1036033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1037033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(STOPPING); 1038033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1039033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1040c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim mChannel->stop(); 1041033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatStop, this))->post(); 1042033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1043033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1044033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::stop() { 10450f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 1046033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1047033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1048033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASING) { 1049033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1050033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already stopped or release is in progress. 1051033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 1052033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1053033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1054033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else if (state->get() != STOPPING) { 1055033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1056033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1057033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1058033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1059033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1060033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 1061033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1062033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = comp->stop(); 1063033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 1064033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 1065033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1066033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1067033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1068033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1069033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1070033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == STOPPING) { 1071033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATED); 1072033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1073033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1074033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 1075033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1076033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1077033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateRelease(bool sendCallback /* = true */) { 1078033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1079033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1080033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASED || state->get() == RELEASING) { 1081033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already released or doing it right now. 1082033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 1083033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1084033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 1085033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1086033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1087033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1088033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1089033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == ALLOCATING) { 1090033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASING); 1091033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // With the altered state allocate() would fail and clean up. 1092033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 1093033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1094033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 1095033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1096033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1097033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1098033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1099033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASING); 1100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1102c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim mChannel->stop(); 1103033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::thread([this, sendCallback] { release(sendCallback); }).detach(); 1104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1106033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::release(bool sendCallback) { 11070f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 1108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1109033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASED) { 1111033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 1112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1113033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 1114033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1115033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1116033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1117033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1118033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 1119033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1120033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp->release(); 1121033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1122033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1123033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1124033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 1125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->comp.reset(); 1126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1127033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 1128033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 1129033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1130033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::setSurface(const sp<Surface> &surface) { 1133033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mChannel->setSurface(surface); 1134033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1135033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1136033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalFlush() { 1137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = [this] { 1138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == FLUSHED) { 1140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return ALREADY_EXISTS; 1141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RUNNING) { 1143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(FLUSHING); 1146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 1148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (err) { 1149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case ALREADY_EXISTS: 1150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onFlushCompleted(); 1151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case OK: 1153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: 1155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 1156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1157033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1159c2088887496fa8627e0a2a4e713f413301065516Wonsik Kim mChannel->stop(); 1160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatFlush, this))->post(); 1161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::flush() { 11640f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 1165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkFlushing = [this, &comp] { 1166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != FLUSHING) { 1168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 1171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 1173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkFlushing) != OK) { 1174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::list<std::unique_ptr<C2Work>> flushedWork; 11780f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa c2_status_t err = comp->flush(C2Component::FLUSH_COMPONENT, &flushedWork); 1179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 1180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 1181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->flush(flushedWork); 1185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(FLUSHED); 1189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onFlushCompleted(); 1191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalResume() { 1194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setResuming = [this] { 1195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != FLUSHED) { 1197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 1198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RESUMING); 1200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 1201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 1202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setResuming) != OK) { 1203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)mChannel->start(nullptr, nullptr); 1207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 1210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RESUMING) { 1211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 1212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 1214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RUNNING); 1217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1220069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kimvoid CCodec::signalSetParameters(const sp<AMessage> ¶ms) { 1221069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 1222069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim msg->setMessage("params", params); 1223069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim msg->post(); 1224069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim} 1225069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim 12263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarvoid CCodec::setParameters(const sp<AMessage> ¶ms) { 1227069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim std::shared_ptr<Codec2Client::Component> comp; 1228069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim auto checkState = [this, &comp] { 1229069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim Mutexed<State>::Locked state(mState); 1230069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim if (state->get() == RELEASED) { 1231069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim return INVALID_OPERATION; 1232069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 1233069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim comp = state->comp; 1234069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim return OK; 1235069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim }; 1236069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim if (tryAndReportOnError(checkState) != OK) { 1237069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim return; 1238069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 1239069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim 12403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 1241cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 1242cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar /** 1243cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar * Handle input surface parameters 1244cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar */ 1245cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE)) 1246cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar && (config->mDomain & Config::IS_ENCODER) && config->mInputSurface && config->mISConfig) { 1247cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar (void)params->findInt64("time-offset-us", &config->mISConfig->mTimeOffsetUs); 1248cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 1249cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (params->findInt64("skip-frames-before", &config->mISConfig->mStartAtUs)) { 1250cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mStopped = false; 1251cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } else if (params->findInt64("stop-time-us", &config->mISConfig->mStopAtUs)) { 1252cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mStopped = true; 1253cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 1254cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 1255cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar int32_t value; 1256cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (params->findInt32("drop-input-frames", &value)) { 1257cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mSuspended = value; 1258cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mISConfig->mSuspendAtUs = -1; 1259cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar (void)params->findInt64("drop-start-time-us", &config->mISConfig->mSuspendAtUs); 1260cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 1261cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 1262cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar (void)config->mInputSurface->configure(*config->mISConfig); 1263cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar if (config->mISConfig->mStopped) { 1264cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar config->mInputFormat->setInt64( 1265cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar "android._stop-time-offset-us", config->mISConfig->mInputDelayUs); 1266cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 1267cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar } 1268cb27b4537d5bbf2f327b30f76b1178b73955fc06Lajos Molnar 12693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::vector<std::unique_ptr<C2Param>> configUpdate; 12703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar (void)config->getConfigUpdateFromSdkParams(comp, params, Config::PARAM, C2_MAY_BLOCK, &configUpdate); 12713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (property_get_bool("debug.stagefright.ccodec_delayed_params", false)) { 12723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // mChannel->queueConfigUpdate(configUpdate); 12733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } else { 12743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar (void)config->setParameters(comp, configUpdate, C2_MAY_BLOCK); 1275069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 1276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalEndOfInputStream() { 12797a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim mCallback->onSignaledInputEOS(mChannel->signalEndOfInputStream()); 1280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalRequestIDRFrame() { 1283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 1284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) { 1287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue); 1288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim queue->splice(queue->end(), workItems); 1289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWorkDone, this))->post(); 1290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::onMessageReceived(const sp<AMessage> &msg) { 1293033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim TimePoint now = std::chrono::steady_clock::now(); 1294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (msg->what()) { 1295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatAllocate: { 1296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2ComponentStore::createComponent() should return within 100ms. 1297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 150ms, "allocate"); 1298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 1299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("codecInfo", &obj)); 1300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocate((MediaCodecInfo *)obj.get()); 1301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatConfigure: { 1304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::commit_sm() should return within 5ms. 1305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 50ms, "configure"); 1306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> format; 1307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findMessage("format", &format)); 1308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim configure(format); 1309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatStart: { 1312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::start() should return within 500ms. 1313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 550ms, "start"); 1314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim start(); 1315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatStop: { 1318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::stop() should return within 500ms. 1319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 550ms, "stop"); 1320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim stop(); 1321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatFlush: { 1324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::flush_sm() should return within 5ms. 1325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 50ms, "flush"); 1326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flush(); 1327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatCreateInputSurface: { 1330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Surface operations may be briefly blocking. 1331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 100ms, "createInputSurface"); 1332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim createInputSurface(); 1333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatSetInputSurface: { 1336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Surface operations may be briefly blocking. 1337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 100ms, "setInputSurface"); 1338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 1339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("surface", &obj)); 1340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get())); 1341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setInputSurface(surface); 1342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1344069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim case kWhatSetParameters: { 1345069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim setDeadline(now + 50ms, "setParameters"); 1346069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim sp<AMessage> params; 1347069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim CHECK(msg->findMessage("params", ¶ms)); 1348069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim setParameters(params); 1349069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim break; 1350069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 1351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatWorkDone: { 1352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<C2Work> work; 1353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue); 1355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (queue->empty()) { 1356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work.swap(queue->front()); 1359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim queue->pop_front(); 1360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!queue->empty()) { 1361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWorkDone, this))->post(); 1362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 13643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 13653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // handle configuration changes in work done 13663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 13673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar bool changed = false; 13683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Config::Watcher<C2StreamInitDataInfo::output> initData = 13693bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->watch<C2StreamInitDataInfo::output>(); 13703bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (!work->worklets.empty() 13713bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar && (work->worklets.front()->output.flags 13723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar & C2FrameData::FLAG_DISCARD_FRAME) == 0) { 1373b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1374b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // copy buffer info to config 1375b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::vector<std::unique_ptr<C2Param>> updates = 1376b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::move(work->worklets.front()->output.configUpdate); 1377b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar unsigned stream = 0; 1378b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) { 1379b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (const std::shared_ptr<const C2Info> &info : buf->info()) { 1380b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // move all info into output-stream #0 domain 1381b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar updates.emplace_back(C2Param::CopyAsStream(*info, true /* output */, stream)); 1382b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1383b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (const C2ConstGraphicBlock &block : buf->data().graphicBlocks()) { 1384b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // ALOGV("got output buffer with crop %u,%u+%u,%u and size %u,%u", 1385b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // block.crop().left, block.crop().top, 1386b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // block.crop().width, block.crop().height, 1387b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // block.width(), block.height()); 1388b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar updates.emplace_back(new C2StreamCropRectInfo::output(stream, block.crop())); 1389b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar updates.emplace_back(new C2StreamPictureSizeInfo::output( 1390b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar stream, block.width(), block.height())); 1391b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar break; // for now only do the first block 1392b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1393b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ++stream; 1394b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1395b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 13966ee7f3e4abf2e0cad1461033bb3132d337179beeLajos Molnar changed = config->updateConfiguration(updates, config->mOutputDomain); 1397b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar 1398b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // copy standard infos to graphic buffers if not already present (otherwise, we 1399b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar // may overwrite the actual intermediate value with a final value) 1400b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar stream = 0; 1401b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar const static std::vector<C2Param::Index> stdGfxInfos = { 1402b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2StreamRotationInfo::output::PARAM_TYPE, 1403b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2StreamColorAspectsInfo::output::PARAM_TYPE, 1404b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2StreamHdrStaticInfo::output::PARAM_TYPE, 1405b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2StreamPixelAspectRatioInfo::output::PARAM_TYPE, 1406b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar C2StreamSurfaceScalingInfo::output::PARAM_TYPE 1407b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar }; 1408b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) { 1409b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (buf->data().graphicBlocks().size()) { 1410b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar for (C2Param::Index ix : stdGfxInfos) { 1411b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (!buf->hasInfo(ix)) { 1412b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar const C2Param *param = 1413b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar config->getConfigParameterValue(ix.withStream(stream)); 1414b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar if (param) { 1415b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar std::shared_ptr<C2Param> info(C2Param::Copy(*param)); 1416b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar buf->setInfo(std::static_pointer_cast<C2Info>(info)); 1417b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1418b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1419b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1420b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 1421b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar ++stream; 1422b53199ea9a1ba3c1c5e98fb1e6452ae45340e101Lajos Molnar } 14233bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 14243bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar mChannel->onWorkDone( 14253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::move(work), changed ? config->mOutputFormat : nullptr, 14263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar initData.hasChanged() ? initData.update().get() : nullptr); 1427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: { 1430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("unrecognized message"); 1431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1434033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(TimePoint::max(), "none"); 1435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::setDeadline(const TimePoint &newDeadline, const char *name) { 1438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<NamedTimePoint>::Locked deadline(mDeadline); 1439033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim deadline->set(newDeadline, name); 1440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateReleaseIfStuck() { 1443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::string name; 1444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<NamedTimePoint>::Locked deadline(mDeadline); 1446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (deadline->get() >= std::chrono::steady_clock::now()) { 1447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're not stuck. 1448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1449033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim name = deadline->getName(); 1451033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1453033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("previous call to %s exceeded timeout", name.c_str()); 1454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateRelease(false); 1455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 1459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" android::CodecBase *CreateCodec() { 1461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new android::CCodec; 1462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 14630f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa 1464