CCodec.cpp revision 384b6a0bcf56a6cdc81fad923fc4695027fa42dd
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 <cutils/properties.h> 20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/Log.h> 21033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 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 165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 1660f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::InputSurface> mSurface; 1670f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::InputSurfaceConnection> mConnection; 168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass GraphicBufferSourceWrapper : public InputSurfaceWrapper { 171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 172ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim// explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {} 173ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim GraphicBufferSourceWrapper( 174ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim const sp<BGraphicBufferSource> &source, 175ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t width, 176ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t height) 177ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim : mSource(source), mWidth(width), mHeight(height) {} 178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~GraphicBufferSourceWrapper() override = default; 179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1800f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override { 181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: proper color aspect & dataspace 182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim android_dataspace dataSpace = HAL_DATASPACE_BT709; 183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mNode = new C2OMXNode(comp); 185ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim mNode->setFrameSize(mWidth, mHeight); 186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSource->configure(mNode, dataSpace); 187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: configure according to intf(). 189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IOMXBufferSource> source = mNode->getSource(); 191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (source == nullptr) { 192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return NO_INIT; 193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim constexpr size_t kNumSlots = 16; 195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < kNumSlots; ++i) { 196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onInputBufferAdded(i); 197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxExecuting(); 199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void disconnect() override { 203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mNode == nullptr) { 204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IOMXBufferSource> source = mNode->getSource(); 207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (source == nullptr) { 208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource."); 209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxIdle(); 212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxLoaded(); 213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mNode.clear(); 214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2167a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim status_t signalEndOfInputStream() override { 2177a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim binder::Status status = mSource->signalEndOfInputStream(); 2187a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim status_t err = OK; 2197a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim if (status.isOk()) { 2207a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return OK; 2217a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } else if ((err = status.serviceSpecificErrorCode()) != OK) { 2227a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return err; 2237a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } else if ((err = status.transactionError()) != OK) { 2247a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return err; 2257a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } else { 2267a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim return UNKNOWN_ERROR; 2277a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 2287a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim } 2297a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim 230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 2311c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim sp<BGraphicBufferSource> mSource; 232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<C2OMXNode> mNode; 233ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t mWidth; 234ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim uint32_t mHeight; 235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace 238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2390f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa// CCodec::ClientListener 2400f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2410f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasastruct CCodec::ClientListener : public Codec2Client::Listener { 2420f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2430f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa explicit ClientListener(const wp<CCodec> &codec) : mCodec(codec) {} 2440f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2450f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onWorkDone( 2460f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component, 2470f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa std::list<std::unique_ptr<C2Work>>& workItems) override { 2480f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)component; 2490f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa sp<CCodec> codec(mCodec.promote()); 2500f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa if (!codec) { 2510f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa return; 2520f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2530f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa codec->onWorkDone(workItems); 2540f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2550f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2560f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onTripped( 2570f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component, 2580f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::vector<std::shared_ptr<C2SettingResult>>& settingResult 2590f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa ) override { 2600f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa // TODO 2610f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)component; 2620f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)settingResult; 2630f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2640f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2650f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onError( 2660f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component, 2670f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa uint32_t errorCode) override { 2680f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa // TODO 2690f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)component; 2700f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa (void)errorCode; 2710f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2720f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2730f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa virtual void onDeath( 2740f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa const std::weak_ptr<Codec2Client::Component>& component) override { 2750f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa { // Log the death of the component. 2760f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa std::shared_ptr<Codec2Client::Component> comp = component.lock(); 2770f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa if (!comp) { 2780f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa ALOGE("Codec2 component died."); 2790f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } else { 2800f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa ALOGE("Codec2 component \"%s\" died.", comp->getName().c_str()); 2810f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2820f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2830f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 2840f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa // Report to MediaCodec. 2850f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa sp<CCodec> codec(mCodec.promote()); 2860f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa if (!codec || !codec->mCallback) { 2870f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa return; 2880f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2890f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa codec->mCallback->onError(DEAD_OBJECT, ACTION_CODE_FATAL); 2900f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa } 2910f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 292c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa virtual void onFramesRendered( 293c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa const std::vector<RenderedFrame>& renderedFrames) override { 294c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa // TODO 295c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa (void)renderedFrames; 296c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa } 297c3d20aa9415c8f02e568f203560685eaf12c3e2dPawin Vongmasa 2980f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasaprivate: 2990f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa wp<CCodec> mCodec; 3000f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa}; 3010f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 302384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim// CCodecCallbackImpl 303384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 304384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimclass CCodecCallbackImpl : public CCodecCallback { 305384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimpublic: 306384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim explicit CCodecCallbackImpl(CCodec *codec) : mCodec(codec) {} 307384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim ~CCodecCallbackImpl() override = default; 308384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 309384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim void onError(status_t err, enum ActionCode actionCode) override { 310384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCodec->mCallback->onError(err, actionCode); 311384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim } 312384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 313384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) override { 314384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim mCodec->mCallback->onOutputFramesRendered( 315384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim {RenderedFrameInfo(mediaTimeUs, renderTimeNs)}); 316384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim } 317384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 318384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kimprivate: 319384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim CCodec *mCodec; 320384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim}; 321384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim 3220f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa// CCodec 3230f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa 324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodec::CCodec() 325384b6a0bcf56a6cdc81fad923fc4695027fa42ddWonsik Kim : mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))) { 326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CCodecWatchdog::getInstance()->registerCodec(this); 327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodec::~CCodec() { 330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstd::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() { 333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mChannel; 334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::tryAndReportOnError(std::function<status_t()> job) { 337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = job(); 338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err; 342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateAllocateComponent(const sp<AMessage> &msg) { 345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setAllocating = [this] { 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RELEASED) { 348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return INVALID_OPERATION; 349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATING); 351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setAllocating) != OK) { 354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> codecInfo; 358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("codecInfo", &codecInfo)); 359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // For Codec 2.0 components, componentName == codecInfo->getCodecName(). 360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this)); 362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocMsg->setObject("codecInfo", codecInfo); 363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocMsg->post(); 364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) { 367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codecInfo == nullptr) { 368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("allocate(%s)", codecInfo->getCodecName()); 3720f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa mClientListener.reset(new ClientListener(this)); 373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString componentName = codecInfo->getCodecName(); 3750f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client> client; 3760f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp = 3770f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa Codec2Client::CreateComponentByName( 3780f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa componentName.c_str(), 3790f9da7a2c27625c1ebbd7910d3749494bc78d58aPawin Vongmasa mClientListener, 3800f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa &client); 3810f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa if (!comp) { 382033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed Create component: %s", componentName.c_str()); 383033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 384033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 3860f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 3903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGI("Created component [%s]", componentName.c_str()); 391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->setComponent(comp); 3920f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa auto setAllocated = [this, comp, client] { 393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATING) { 395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATED); 399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->comp = comp; 4000f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mClient = client; 401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setAllocated) != OK) { 404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 4063bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 4073bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // initialize config here in case setParameters is called prior to configure 4083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 4093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar status_t err = config->initialize(mClient, comp); 4103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (err != OK) { 4113bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGW("Failed to initialize configuration support"); 4123bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TODO: report error once we complete implementation. 4133bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 4143bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->queryConfiguration(comp); 4153bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 4160f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa mCallback->onComponentAllocated(comp->getName().c_str()); 417033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 418033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateConfigureComponent(const sp<AMessage> &format) { 420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkAllocated = [this] { 421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK; 423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkAllocated) != OK) { 425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg(new AMessage(kWhatConfigure, this)); 429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setMessage("format", format); 430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::configure(const sp<AMessage> &msg) { 4340f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 4350f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa auto checkAllocated = [this, &comp] { 436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 439033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 4410f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa comp = state->comp; 442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkAllocated) != OK) { 445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 4483bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar auto doConfig = [msg, comp, this] { 449033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString mime; 450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!msg->findString("mime", &mime)) { 451033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return BAD_VALUE; 452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 453033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t encoder; 455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!msg->findInt32("encoder", &encoder)) { 456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encoder = false; 457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 4593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TODO: read from intf() 4603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if ((!encoder) != (comp->getName().find("encoder") == std::string::npos)) { 4613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar return UNKNOWN_ERROR; 4623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 4633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 464f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim int32_t storeMeta; 465f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (encoder 466f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim && msg->findInt32("android._input-metadata-buffer-type", &storeMeta) 467f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim && storeMeta != kMetadataBufferTypeInvalid) { 468f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (storeMeta != kMetadataBufferTypeANWBuffer) { 469f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim ALOGD("Only ANW buffers are supported for legacy metadata mode"); 470f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim return BAD_VALUE; 471f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 472f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim mChannel->setMetaMode(CCodecBufferChannel::MODE_ANW); 473f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 474f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim 475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (msg->findObject("native-window", &obj)) { 477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Surface> surface = static_cast<Surface *>(obj.get()); 478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setSurface(surface); 479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 4813bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 4823bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::vector<std::unique_ptr<C2Param>> configUpdate; 4833bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar status_t err = config->getConfigUpdateFromSdkParams( 4843bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar comp, msg, Config::CONFIG, C2_DONT_BLOCK, &configUpdate); 4853bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (err != OK) { 4863bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGW("failed to convert configuration to c2 params"); 4873bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 4883bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar err = config->setParameters(comp, configUpdate, C2_DONT_BLOCK); 4893bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (err != OK) { 4903bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGW("failed to configure c2 params"); 4913bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 4923bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 493033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<std::unique_ptr<C2Param>> params; 4943bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar C2StreamUsageTuning::input usage(0u, 0u); 4953bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar C2StreamMaxBufferSizeInfo::input maxInputSize(0u, 0u); 4963bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TEMP: get max input size from format (in case component is not exposing this) 4973bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar (void)msg->findInt32(KEY_MAX_INPUT_SIZE, (int32_t*)&maxInputSize.value); 4983bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::initializer_list<C2Param::Index> indices { 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 5013bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar c2_status_t c2err = comp->query( 5023bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar { &usage, &maxInputSize }, 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim indices, 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2_DONT_BLOCK, 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ¶ms); 506f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (c2err != C2_OK && c2err != C2_BAD_INDEX) { 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to query component interface: %d", c2err); 508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (params.size() != indices.size()) { 511f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim ALOGE("Component returns wrong number of params: expected %zu actual %zu", 512f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim indices.size(), params.size()); 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 515f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim if (usage && (usage.value & C2MemoryUsage::CPU_READ)) { 5163bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mInputFormat->setInt32("using-sw-read-often", true); 517f15a341c8d0e931321c4ba4fa8ab1da53b9504e2Wonsik Kim } 518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 5193bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // TEMP: enforce minimum buffer size of 1MB for video decoders 5203bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (!encoder && !(config->mDomain & Config::IS_AUDIO)) { 5213bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar maxInputSize.value = c2_max(1048576u, maxInputSize.value); 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 524a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar // TODO: do this based on component requiring linear allocator for input 5253bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if ((config->mDomain & Config::IS_DECODER) || (config->mDomain & Config::IS_AUDIO)) { 5263bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // Pass max input size on input format to the buffer channel 5273bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mInputFormat->setInt32( 5283bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar KEY_MAX_INPUT_SIZE, (int32_t)(c2_min(maxInputSize.value, uint32_t(INT32_MAX)))); 529a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar } 530a00de0de4f172b294f286460292dc4a99f9dda67Lajos Molnar 5313bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar ALOGD("setup formats input: %s and output: %s", 5323bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mInputFormat->debugString().c_str(), 5333bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mOutputFormat->debugString().c_str()); 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(doConfig) != OK) { 537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 5403bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 5413bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 5423bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat); 543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateCreateInputSurface() { 546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = [this] { 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: read it from intf() properly. 5520f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa if (state->comp->getName().find("encoder") == std::string::npos) { 553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return INVALID_OPERATION; 554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 560033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 561033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatCreateInputSurface, this))->post(); 563033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::createInputSurface() { 5662bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa status_t err; 5671c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim sp<IGraphicBufferProducer> bufferProducer; 568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 5723bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 5733bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar inputFormat = config->mInputFormat; 5743bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat = config->mOutputFormat; 575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 5762bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 5772bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa // TODO: Remove this property check and assume it's always true. 5782bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (property_get_bool("debug.stagefright.c2inputsurface", false)) { 5792bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa std::shared_ptr<Codec2Client::InputSurface> surface; 5802bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 5812bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = static_cast<status_t>(mClient->createInputSurface(&surface)); 5822bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (err != OK) { 5832bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface: %d", static_cast<int>(err)); 5842bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(err); 5852bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 5862bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 5872bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (!surface) { 5882bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface: null input surface"); 5892bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); 5902bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 5912bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 5922bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa bufferProducer = surface->getGraphicBufferProducer(); 5932bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(surface)); 5942bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } else { // TODO: Remove this block. 5952bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa using namespace ::android::hardware::media::omx::V1_0; 5962bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa sp<IOmx> tOmx = IOmx::getService("default"); 5972bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (tOmx == nullptr) { 5982bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface"); 5992bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); 6002bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 6012bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 6022bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa sp<IOMX> omx = new utils::LWOmx(tOmx); 6032bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 6042bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa sp<BGraphicBufferSource> bufferSource; 6052bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = omx->createInputSurface(&bufferProducer, &bufferSource); 6062bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 6072bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa if (err != OK) { 6082bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa ALOGE("Failed to create input surface: %d", err); 6092bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa mCallback->onInputSurfaceCreationFailed(err); 6102bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa return; 6112bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 6122bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa int32_t width = 0; 6132bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa (void)outputFormat->findInt32("width", &width); 6142bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa int32_t height = 0; 6152bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa (void)outputFormat->findInt32("height", &height); 6162bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( 6172bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa bufferSource, width, height)); 6182bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa } 6192bc4356b1c43e24210c9bb2d2b7afeef419fa2e7Pawin Vongmasa 620ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim if (err != OK) { 621ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim ALOGE("Failed to set up input surface: %d", err); 622ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 623ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim return; 624ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim } 625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreated( 626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat, 627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat, 6281c421ef3ded7c7dd25a44ea0d90db1ec46f5c1fbWonsik Kim new BufferProducerWrapper(bufferProducer)); 629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) { 632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = mChannel->setInputSurface(surface); 633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err; 635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: configure |surface| with other settings. 638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) { 642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setObject("surface", surface); 644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::setInputSurface(const sp<PersistentSurface> &surface) { 648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 6513bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 6523bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar inputFormat = config->mInputFormat; 6533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat = config->mOutputFormat; 654033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 655ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim int32_t width = 0; 656ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim (void)outputFormat->findInt32("width", &width); 657ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim int32_t height = 0; 658ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim (void)outputFormat->findInt32("height", &height); 659ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( 660ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim surface->getBufferSource(), width, height)); 661ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim if (err != OK) { 662ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim ALOGE("Failed to set up input surface: %d", err); 663ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim mCallback->onInputSurfaceDeclined(err); 664ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim return; 665ea8fb50202473df2711f12a8b31418118cd3bdaaWonsik Kim } 666033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceAccepted(inputFormat, outputFormat); 667033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 668033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 669033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateStart() { 670033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setStarting = [this] { 671033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 672033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 673033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 674033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 675033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(STARTING); 676033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 677033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 678033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setStarting) != OK) { 679033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 681033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatStart, this))->post(); 683033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::start() { 6860f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkStarting = [this, &comp] { 688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != STARTING) { 690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkStarting) != OK) { 696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = comp->start(); 700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 701033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 703033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 704033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 706033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 707033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 7083bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 7093bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar inputFormat = config->mInputFormat; 7103bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar outputFormat = config->mOutputFormat; 711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err2 = mChannel->start(inputFormat, outputFormat); 713033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err2 != OK) { 714033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err2, ACTION_CODE_FATAL); 715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setRunning = [this] { 719033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != STARTING) { 721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 723033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RUNNING); 724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setRunning) != OK) { 727033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStartCompleted(); 730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateShutdown(bool keepComponentAllocated) { 733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (keepComponentAllocated) { 734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateStop(); 735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 736033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateRelease(); 737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateStop() { 741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == ALLOCATED 744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == RELEASED 745033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == STOPPING 746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == RELEASING) { 747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already stopped, released, or doing it right now. 748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(STOPPING); 754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatStop, this))->post(); 757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::stop() { 7600f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASING) { 764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already stopped or release is in progress. 766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else if (state->get() != STOPPING) { 770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 771033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->stop(); 778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = comp->stop(); 779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 783033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 784033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == STOPPING) { 787033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATED); 788033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 789033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 792033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 793033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateRelease(bool sendCallback /* = true */) { 794033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 795033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 796033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASED || state->get() == RELEASING) { 797033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already released or doing it right now. 798033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 799033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 800033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 801033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 802033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 803033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 804033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 805033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == ALLOCATING) { 806033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASING); 807033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // With the altered state allocate() would fail and clean up. 808033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 809033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 810033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 811033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 812033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 813033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 814033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 815033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASING); 816033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 817033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 818033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::thread([this, sendCallback] { release(sendCallback); }).detach(); 819033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 821033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::release(bool sendCallback) { 8220f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 823033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 824033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 825033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASED) { 826033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 827033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 828033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 829033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 830033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 831033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 833033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 834033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 835033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->stop(); 836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp->release(); 837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->comp.reset(); 842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 845033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 846033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 847033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 848033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::setSurface(const sp<Surface> &surface) { 849033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mChannel->setSurface(surface); 850033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 851033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 852033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalFlush() { 853033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = [this] { 854033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 855033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == FLUSHED) { 856033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return ALREADY_EXISTS; 857033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 858033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RUNNING) { 859033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 860033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 861033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(FLUSHING); 862033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 863033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 864033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (err) { 865033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case ALREADY_EXISTS: 866033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onFlushCompleted(); 867033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 868033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case OK: 869033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 870033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: 871033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 872033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 873033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 874033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 875033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatFlush, this))->post(); 876033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 877033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 878033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::flush() { 8790f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa std::shared_ptr<Codec2Client::Component> comp; 880033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkFlushing = [this, &comp] { 881033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 882033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != FLUSHING) { 883033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 884033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 885033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 886033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 887033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 888033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkFlushing) != OK) { 889033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 890033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 891033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 892033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->stop(); 893033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 894033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::list<std::unique_ptr<C2Work>> flushedWork; 8950f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa c2_status_t err = comp->flush(C2Component::FLUSH_COMPONENT, &flushedWork); 896033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 897033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 898033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 899033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 900033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 901033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->flush(flushedWork); 902033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 903033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 904033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 905033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(FLUSHED); 906033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 907033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onFlushCompleted(); 908033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 909033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 910033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalResume() { 911033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setResuming = [this] { 912033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 913033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != FLUSHED) { 914033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 915033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 916033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RESUMING); 917033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 918033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 919033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setResuming) != OK) { 920033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 921033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 922033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 923033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)mChannel->start(nullptr, nullptr); 924033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 925033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 926033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 927033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RESUMING) { 928033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 929033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 930033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 931033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 932033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 933033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RUNNING); 934033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 935033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 936033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 937069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kimvoid CCodec::signalSetParameters(const sp<AMessage> ¶ms) { 938069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 939069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim msg->setMessage("params", params); 940069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim msg->post(); 941069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim} 942069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim 9433bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnarvoid CCodec::setParameters(const sp<AMessage> ¶ms) { 944069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim std::shared_ptr<Codec2Client::Component> comp; 945069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim auto checkState = [this, &comp] { 946069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim Mutexed<State>::Locked state(mState); 947069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim if (state->get() == RELEASED) { 948069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim return INVALID_OPERATION; 949069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 950069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim comp = state->comp; 951069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim return OK; 952069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim }; 953069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim if (tryAndReportOnError(checkState) != OK) { 954069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim return; 955069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 956069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim 9573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 9583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::vector<std::unique_ptr<C2Param>> configUpdate; 9593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar (void)config->getConfigUpdateFromSdkParams(comp, params, Config::PARAM, C2_MAY_BLOCK, &configUpdate); 9603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (property_get_bool("debug.stagefright.ccodec_delayed_params", false)) { 9613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // mChannel->queueConfigUpdate(configUpdate); 9623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } else { 9633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar (void)config->setParameters(comp, configUpdate, C2_MAY_BLOCK); 964069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 965033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 966033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 967033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalEndOfInputStream() { 9687a702c9f08c57f64121149e3e233cbe8fcf4dc36Wonsik Kim mCallback->onSignaledInputEOS(mChannel->signalEndOfInputStream()); 969033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 970033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 971033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalRequestIDRFrame() { 972033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 973033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 974033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 975033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) { 976033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue); 977033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim queue->splice(queue->end(), workItems); 978033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWorkDone, this))->post(); 979033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 980033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 981033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::onMessageReceived(const sp<AMessage> &msg) { 982033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim TimePoint now = std::chrono::steady_clock::now(); 983033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (msg->what()) { 984033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatAllocate: { 985033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2ComponentStore::createComponent() should return within 100ms. 986033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 150ms, "allocate"); 987033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 988033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("codecInfo", &obj)); 989033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocate((MediaCodecInfo *)obj.get()); 990033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 991033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 992033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatConfigure: { 993033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::commit_sm() should return within 5ms. 994033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 50ms, "configure"); 995033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> format; 996033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findMessage("format", &format)); 997033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim configure(format); 998033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 999033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1000033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatStart: { 1001033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::start() should return within 500ms. 1002033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 550ms, "start"); 1003033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim start(); 1004033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1005033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1006033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatStop: { 1007033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::stop() should return within 500ms. 1008033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 550ms, "stop"); 1009033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim stop(); 1010033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1011033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1012033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatFlush: { 1013033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::flush_sm() should return within 5ms. 1014033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 50ms, "flush"); 1015033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flush(); 1016033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1017033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1018033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatCreateInputSurface: { 1019033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Surface operations may be briefly blocking. 1020033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 100ms, "createInputSurface"); 1021033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim createInputSurface(); 1022033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1023033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1024033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatSetInputSurface: { 1025033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Surface operations may be briefly blocking. 1026033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 100ms, "setInputSurface"); 1027033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 1028033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("surface", &obj)); 1029033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get())); 1030033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setInputSurface(surface); 1031033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1032033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1033069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim case kWhatSetParameters: { 1034069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim setDeadline(now + 50ms, "setParameters"); 1035069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim sp<AMessage> params; 1036069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim CHECK(msg->findMessage("params", ¶ms)); 1037069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim setParameters(params); 1038069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim break; 1039069f7358a56620fca51d26dfb7b1c02a5501c703Wonsik Kim } 1040033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatWorkDone: { 1041033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<C2Work> work; 1042033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1043033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue); 1044033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (queue->empty()) { 1045033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1046033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1047033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work.swap(queue->front()); 1048033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim queue->pop_front(); 1049033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!queue->empty()) { 1050033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWorkDone, this))->post(); 1051033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1052033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 10533bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar 10543bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar // handle configuration changes in work done 10553bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Mutexed<Config>::Locked config(mConfig); 10563bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar bool changed = false; 10573bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar Config::Watcher<C2StreamInitDataInfo::output> initData = 10583bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->watch<C2StreamInitDataInfo::output>(); 10593bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar if (!work->worklets.empty() 10603bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar && (work->worklets.front()->output.flags 10613bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar & C2FrameData::FLAG_DISCARD_FRAME) == 0) { 10623bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar changed = config->updateConfiguration( 10633bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar work->worklets.front()->output.configUpdate, 10643bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar config->mOutputDomain); 10653bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar } 10663bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar mChannel->onWorkDone( 10673bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar std::move(work), changed ? config->mOutputFormat : nullptr, 10683bce60a27e0b0a996e42bd2c9e5bf60373db2780Lajos Molnar initData.hasChanged() ? initData.update().get() : nullptr); 1069033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1070033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1071033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: { 1072033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("unrecognized message"); 1073033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 1074033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1075033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1076033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(TimePoint::max(), "none"); 1077033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1078033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1079033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::setDeadline(const TimePoint &newDeadline, const char *name) { 1080033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<NamedTimePoint>::Locked deadline(mDeadline); 1081033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim deadline->set(newDeadline, name); 1082033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1083033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1084033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateReleaseIfStuck() { 1085033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::string name; 1086033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 1087033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<NamedTimePoint>::Locked deadline(mDeadline); 1088033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (deadline->get() >= std::chrono::steady_clock::now()) { 1089033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're not stuck. 1090033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 1091033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1092033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim name = deadline->getName(); 1093033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 1094033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1095033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("previous call to %s exceeded timeout", name.c_str()); 1096033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateRelease(false); 1097033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 1098033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 1099033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 1101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 1102033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" android::CodecBase *CreateCodec() { 1103033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new android::CCodec; 1104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 11050f04c4d93761015d0a138aff8a468b1583d684e4Pawin Vongmasa 1106