CCodec.cpp revision 033ea548eec7ec220082ea6b199bf6e77f67a40d
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 17033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim//#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 24033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h> 25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2V4l2Support.h> 26033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <android/IOMXBufferSource.h> 28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> 29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <gui/Surface.h> 30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/codec2/1.0/InputSurface.h> 31033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/BufferProducerWrapper.h> 32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/PersistentSurface.h> 33033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "C2OMXNode.h" 35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "CCodec.h" 36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "CCodecBufferChannel.h" 37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "InputSurfaceWrapper.h" 38033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android { 40033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing namespace std::chrono_literals; 42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimusing ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer; 43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace { 45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 46033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass CCodecWatchdog : public AHandler { 47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim enum { 49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim kWhatRegister, 50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim kWhatWatch, 51033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim constexpr static int64_t kWatchIntervalUs = 3000000; // 3 secs 53033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 54033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 55033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim static sp<CCodecWatchdog> getInstance() { 56033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<sp<CCodecWatchdog>>::Locked instance(sInstance); 57033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (*instance == nullptr) { 58033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *instance = new CCodecWatchdog; 59033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (*instance)->init(); 60033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 61033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return *instance; 62033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 63033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 64033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~CCodecWatchdog() = default; 65033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 66033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void registerCodec(CCodec *codec) { 67033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg = new AMessage(kWhatRegister, this); 68033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setPointer("codec", codec); 69033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 70033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 71033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 72033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprotected: 73033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void onMessageReceived(const sp<AMessage> &msg) { 74033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (msg->what()) { 75033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatRegister: { 76033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void *ptr = nullptr; 77033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findPointer("codec", &ptr)); 78033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs); 79033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codecs->emplace_back((CCodec *)ptr); 80033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 81033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 82033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 83033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatWatch: { 84033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs); 85033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (auto it = codecs->begin(); it != codecs->end(); ) { 86033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<CCodec> codec = it->promote(); 87033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codec == nullptr) { 88033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim it = codecs->erase(it); 89033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim continue; 90033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 91033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codec->initiateReleaseIfStuck(); 92033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ++it; 93033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 94033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(kWatchIntervalUs); 95033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 96033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 97033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 98033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: { 99033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim TRESPASS("CCodecWatchdog: unrecognized message"); 100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 101033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 102033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 103033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 104033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CCodecWatchdog() : mLooper(new ALooper) {} 106033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void init() { 108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mLooper->setName("CCodecWatchdog"); 109033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mLooper->registerHandler(this); 110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mLooper->start(); 111033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs); 112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 113033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 114033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim static Mutexed<sp<CCodecWatchdog>> sInstance; 115033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 116033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<ALooper> mLooper; 117033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<wp<CCodec>>> mCodecs; 118033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 119033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 120033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimMutexed<sp<CCodecWatchdog>> CCodecWatchdog::sInstance; 121033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 122033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass CCodecListener : public C2Component::Listener { 123033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 124033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim explicit CCodecListener(const wp<CCodec> &codec) : mCodec(codec) {} 125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual void onWorkDone_nb( 127033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::weak_ptr<C2Component> component, 128033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::list<std::unique_ptr<C2Work>> workItems) override { 129033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)component; 130033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<CCodec> codec(mCodec.promote()); 131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!codec) { 132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 133033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 134033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codec->onWorkDone(workItems); 135033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 136033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual void onTripped_nb( 138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::weak_ptr<C2Component> component, 139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<std::shared_ptr<C2SettingResult>> settingResult) override { 140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)component; 142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)settingResult; 143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override { 146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)component; 148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)errorCode; 149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim wp<CCodec> mCodec; 153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2InputSurfaceWrapper : public InputSurfaceWrapper { 156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 157033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim explicit C2InputSurfaceWrapper(const sp<InputSurface> &surface) : mSurface(surface) {} 158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~C2InputSurfaceWrapper() override = default; 159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t connect(const std::shared_ptr<C2Component> &comp) override { 161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mConnection != nullptr) { 162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return ALREADY_EXISTS; 163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mConnection = mSurface->connectToComponent(comp); 165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void disconnect() override { 169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mConnection != nullptr) { 170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mConnection->disconnect(); 171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mConnection.clear(); 172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<InputSurface> mSurface; 177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<InputSurfaceConnection> mConnection; 178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass GraphicBufferSourceWrapper : public InputSurfaceWrapper { 181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim explicit GraphicBufferSourceWrapper(const sp<IGraphicBufferSource> &source) : mSource(source) {} 183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ~GraphicBufferSourceWrapper() override = default; 184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t connect(const std::shared_ptr<C2Component> &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); 190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSource->configure(mNode, dataSpace); 191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: configure according to intf(). 193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IOMXBufferSource> source = mNode->getSource(); 195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (source == nullptr) { 196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return NO_INIT; 197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim constexpr size_t kNumSlots = 16; 199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < kNumSlots; ++i) { 200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onInputBufferAdded(i); 201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxExecuting(); 203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim void disconnect() override { 207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mNode == nullptr) { 208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IOMXBufferSource> source = mNode->getSource(); 211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (source == nullptr) { 212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource."); 213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxIdle(); 216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim source->onOmxLoaded(); 217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mNode.clear(); 218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimprivate: 221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<IGraphicBufferSource> mSource; 222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<C2OMXNode> mNode; 223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 224033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 225033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace 226033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 227033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodec::CCodec() 228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim : mChannel(new CCodecBufferChannel([this] (status_t err, enum ActionCode actionCode) { 229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, actionCode); 230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim })) { 231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CCodecWatchdog::getInstance()->registerCodec(this); 232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimCCodec::~CCodec() { 235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstd::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() { 238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mChannel; 239033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 240033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 241033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::tryAndReportOnError(std::function<status_t()> job) { 242033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = job(); 243033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 244033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 245033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 246033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err; 247033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 248033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 249033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateAllocateComponent(const sp<AMessage> &msg) { 250033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setAllocating = [this] { 251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RELEASED) { 253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return INVALID_OPERATION; 254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATING); 256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 258033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setAllocating) != OK) { 259033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 260033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 262033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> codecInfo; 263033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("codecInfo", &codecInfo)); 264033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // For Codec 2.0 components, componentName == codecInfo->getCodecName(). 265033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 266033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this)); 267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocMsg->setObject("codecInfo", codecInfo); 268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocMsg->post(); 269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) { 272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codecInfo == nullptr) { 273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("allocate(%s)", codecInfo->getCodecName()); 277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mListener.reset(new CCodecListener(this)); 278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString componentName = codecInfo->getCodecName(); 280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: use codecInfo->getOwnerName() for connecting to remote process. 281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component> comp; 283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = GetCodec2PlatformComponentStore()->createComponent( 284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim componentName.c_str(), &comp); 285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim static bool v4l2Enabled = 286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim property_get_bool("debug.stagefright.ccodec_v4l2", false); 287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK && v4l2Enabled) { 288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim err = GetCodec2VDAComponentStore()->createComponent( 289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim componentName.c_str(), &comp); 290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed Create component: %s", componentName.c_str()); 293033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("Success Create component: %s", componentName.c_str()); 301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp->setListener_vb(mListener, C2_MAY_BLOCK); 302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->setComponent(comp); 303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setAllocated = [this, comp] { 304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATING) { 306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATED); 310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->comp = comp; 311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setAllocated) != OK) { 314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onComponentAllocated(comp->intf()->getName().c_str()); 317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateConfigureComponent(const sp<AMessage> &format) { 320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkAllocated = [this] { 321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK; 323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkAllocated) != OK) { 325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg(new AMessage(kWhatConfigure, this)); 329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setMessage("format", format); 330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::configure(const sp<AMessage> &msg) { 334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2ComponentInterface> intf; 335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkAllocated = [this, &intf] { 336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim intf = state->comp->intf(); 342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkAllocated) != OK) { 345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat(new AMessage); 349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat(new AMessage); 350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto doConfig = [=] { 351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AString mime; 352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!msg->findString("mime", &mime)) { 353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return BAD_VALUE; 354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t encoder; 357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!msg->findInt32("encoder", &encoder)) { 358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encoder = false; 359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: read from intf() 362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if ((!encoder) != (intf->getName().find("encoder") == std::string::npos)) { 363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (msg->findObject("native-window", &obj)) { 368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<Surface> surface = static_cast<Surface *>(obj.get()); 369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setSurface(surface); 370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::vector<std::unique_ptr<C2Param>> params; 373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::initializer_list<C2Param::Index> indices { 374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2PortMimeConfig::input::PARAM_TYPE, 375033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2PortMimeConfig::output::PARAM_TYPE, 376033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 377033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t c2err = intf->query_vb( 378033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim {}, 379033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim indices, 380033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2_DONT_BLOCK, 381033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ¶ms); 382033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (c2err != C2_OK) { 383033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to query component interface: %d", c2err); 384033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 386033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (params.size() != indices.size()) { 387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Component returns wrong number of params"); 388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!params[0] || !params[1]) { 391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Component returns null params"); 392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat->setString("mime", ((C2PortMimeConfig *)params[0].get())->m.value); 395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setString("mime", ((C2PortMimeConfig *)params[1].get())->m.value); 396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // XXX: hack 398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool audio = mime.startsWithIgnoreCase("audio/"); 399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (encoder) { 400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (audio) { 401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat->setInt32("channel-count", 1); 402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat->setInt32("sample-rate", 44100); 403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("channel-count", 1); 404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("sample-rate", 44100); 405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("width", 1080); 407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("height", 1920); 408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (audio) { 411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("channel-count", 2); 412033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("sample-rate", 44100); 413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 414033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t tmp; 415033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (msg->findInt32("width", &tmp)) { 416033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("width", tmp); 417033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 418033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (msg->findInt32("height", &tmp)) { 419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat->setInt32("height", tmp); 420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(doConfig) != OK) { 429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<Formats>::Locked formats(mFormats); 434033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim formats->inputFormat = inputFormat; 435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim formats->outputFormat = outputFormat; 436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onComponentConfigured(inputFormat, outputFormat); 438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 439033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateCreateInputSurface() { 441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = [this] { 442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: read it from intf() properly. 447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->comp->intf()->getName().find("encoder") == std::string::npos) { 448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return INVALID_OPERATION; 449033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 451033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 453033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatCreateInputSurface, this))->post(); 458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::createInputSurface() { 461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: get this from codec process 462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<InputSurface> surface(InputSurface::Create()); 463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: get proper error code. 465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = (surface == nullptr) ? UNKNOWN_ERROR : OK; 466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 467033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to initialize input surface: %d", err); 468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(surface)); 473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to set up input surface: %d", err); 475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreationFailed(err); 476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<Formats>::Locked formats(mFormats); 483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat = formats->inputFormat; 484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat = formats->outputFormat; 485033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceCreated( 487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat, 488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat, 489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim new BufferProducerWrapper(new H2BGraphicBufferProducer(surface))); 490033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) { 493033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = mChannel->setInputSurface(surface); 494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err; 496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 497033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: configure |surface| with other settings. 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 501033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) { 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->setObject("surface", surface); 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim msg->post(); 506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::setInputSurface(const sp<PersistentSurface> &surface) { 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim surface->getBufferSource())); 511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != OK) { 512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to set up input surface: %d", err); 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceDeclined(err); 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<Formats>::Locked formats(mFormats); 521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat = formats->inputFormat; 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat = formats->outputFormat; 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onInputSurfaceAccepted(inputFormat, outputFormat); 525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateStart() { 528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setStarting = [this] { 529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != ALLOCATED) { 531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(STARTING); 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setStarting) != OK) { 537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatStart, this))->post(); 541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::start() { 544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component> comp; 545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkStarting = [this, &comp] { 546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != STARTING) { 548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkStarting) != OK) { 554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = comp->start(); 558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 560033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 561033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 563033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> inputFormat; 564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> outputFormat; 565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 566033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<Formats>::Locked formats(mFormats); 567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inputFormat = formats->inputFormat; 568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputFormat = formats->outputFormat; 569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err2 = mChannel->start(inputFormat, outputFormat); 571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err2 != OK) { 572033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err2, ACTION_CODE_FATAL); 573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 574033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setRunning = [this] { 577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != STARTING) { 579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RUNNING); 582033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setRunning) != OK) { 585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStartCompleted(); 588033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 589033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 590033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateShutdown(bool keepComponentAllocated) { 591033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (keepComponentAllocated) { 592033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateStop(); 593033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 594033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateRelease(); 595033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 596033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 597033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 598033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateStop() { 599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == ALLOCATED 602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == RELEASED 603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == STOPPING 604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || state->get() == RELEASING) { 605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already stopped, released, or doing it right now. 606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(STOPPING); 612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatStop, this))->post(); 615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 617033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::stop() { 618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component> comp; 619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASING) { 622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already stopped or release is in progress. 624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else if (state->get() != STOPPING) { 628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->stop(); 636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = comp->stop(); 637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == STOPPING) { 645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(ALLOCATED); 646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onStopCompleted(); 649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 651033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateRelease(bool sendCallback /* = true */) { 652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 653033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 654033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASED || state->get() == RELEASING) { 655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're already released or doing it right now. 656033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 657033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 658033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 659033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 660033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 661033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 662033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 663033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == ALLOCATING) { 664033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASING); 665033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // With the altered state allocate() would fail and clean up. 666033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 667033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 668033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 669033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 670033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 671033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 672033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 673033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASING); 674033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 675033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 676033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::thread([this, sendCallback] { release(sendCallback); }).detach(); 677033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 678033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 679033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::release(bool sendCallback) { 680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component> comp; 681033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 683033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == RELEASED) { 684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 686033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->stop(); 694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp->release(); 695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RELEASED); 699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->comp.reset(); 700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 701033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (sendCallback) { 702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onReleaseCompleted(); 703033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 704033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 706033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t CCodec::setSurface(const sp<Surface> &surface) { 707033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mChannel->setSurface(surface); 708033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 709033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 710033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalFlush() { 711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = [this] { 712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 713033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() == FLUSHED) { 714033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return ALREADY_EXISTS; 715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RUNNING) { 717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 719033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(FLUSHING); 720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (err) { 723033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case ALREADY_EXISTS: 724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onFlushCompleted(); 725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case OK: 727033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: 729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(err, ACTION_CODE_FATAL); 730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatFlush, this))->post(); 734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 736033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::flush() { 737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component> comp; 738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto checkFlushing = [this, &comp] { 739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != FLUSHING) { 741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim comp = state->comp; 744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 745033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(checkFlushing) != OK) { 747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->stop(); 751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::list<std::unique_ptr<C2Work>> flushedWork; 753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = comp->flush_sm(C2Component::FLUSH_COMPONENT, &flushedWork); 754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: convert err into status_t 756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->flush(flushedWork); 760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(FLUSHED); 764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onFlushCompleted(); 766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalResume() { 769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto setResuming = [this] { 770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 771033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != FLUSHED) { 772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RESUMING); 775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tryAndReportOnError(setResuming) != OK) { 778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)mChannel->start(nullptr, nullptr); 782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 783033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 784033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<State>::Locked state(mState); 785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (state->get() != RESUMING) { 786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.unlock(); 787033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 788033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state.lock(); 789033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim state->set(RUNNING); 792033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 793033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 794033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 795033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalSetParameters(const sp<AMessage> &msg) { 796033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 797033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void) msg; 798033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 799033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 800033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalEndOfInputStream() { 801033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 802033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onSignaledInputEOS(INVALID_OPERATION); 803033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 804033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 805033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::signalRequestIDRFrame() { 806033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 807033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 808033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 809033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) { 810033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue); 811033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim queue->splice(queue->end(), workItems); 812033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWorkDone, this))->post(); 813033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 814033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 815033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::onMessageReceived(const sp<AMessage> &msg) { 816033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim TimePoint now = std::chrono::steady_clock::now(); 817033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim switch (msg->what()) { 818033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatAllocate: { 819033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2ComponentStore::createComponent() should return within 100ms. 820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 150ms, "allocate"); 821033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 822033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("codecInfo", &obj)); 823033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim allocate((MediaCodecInfo *)obj.get()); 824033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 825033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 826033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatConfigure: { 827033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::commit_sm() should return within 5ms. 828033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 50ms, "configure"); 829033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<AMessage> format; 830033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findMessage("format", &format)); 831033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim configure(format); 832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 833033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 834033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatStart: { 835033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::start() should return within 500ms. 836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 550ms, "start"); 837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim start(); 838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatStop: { 841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::stop() should return within 500ms. 842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 550ms, "stop"); 843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim stop(); 844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 845033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 846033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatFlush: { 847033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // C2Component::flush_sm() should return within 5ms. 848033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 50ms, "flush"); 849033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flush(); 850033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 851033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 852033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatCreateInputSurface: { 853033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Surface operations may be briefly blocking. 854033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 100ms, "createInputSurface"); 855033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim createInputSurface(); 856033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 857033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 858033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatSetInputSurface: { 859033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Surface operations may be briefly blocking. 860033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(now + 100ms, "setInputSurface"); 861033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<RefBase> obj; 862033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(msg->findObject("surface", &obj)); 863033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get())); 864033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setInputSurface(surface); 865033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 866033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 867033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim case kWhatWorkDone: { 868033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::unique_ptr<C2Work> work; 869033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 870033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue); 871033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (queue->empty()) { 872033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 873033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 874033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work.swap(queue->front()); 875033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim queue->pop_front(); 876033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!queue->empty()) { 877033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (new AMessage(kWhatWorkDone, this))->post(); 878033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 879033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 880033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mChannel->onWorkDone(work); 881033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 882033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 883033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim default: { 884033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("unrecognized message"); 885033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 886033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 887033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 888033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim setDeadline(TimePoint::max(), "none"); 889033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 890033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 891033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::setDeadline(const TimePoint &newDeadline, const char *name) { 892033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<NamedTimePoint>::Locked deadline(mDeadline); 893033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim deadline->set(newDeadline, name); 894033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 895033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 896033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid CCodec::initiateReleaseIfStuck() { 897033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::string name; 898033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim { 899033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Mutexed<NamedTimePoint>::Locked deadline(mDeadline); 900033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (deadline->get() >= std::chrono::steady_clock::now()) { 901033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // We're not stuck. 902033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 903033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 904033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim name = deadline->getName(); 905033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 906033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 907033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("previous call to %s exceeded timeout", name.c_str()); 908033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim initiateRelease(false); 909033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); 910033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 911033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 912033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 913033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 914033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" android::CodecBase *CreateCodec() { 915033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new android::CCodec; 916033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 917