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 17d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar//#define LOG_NDEBUG 0 1872dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#define LOG_TAG "C2SoftAacDec" 19d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <log/log.h> 20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <inttypes.h> 22d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <math.h> 23d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <numeric> 24033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <cutils/properties.h> 26033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/MediaDefs.h> 27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/hexdump.h> 28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/MediaErrors.h> 29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/misc.h> 30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 31d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <C2PlatformSupport.h> 32d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <SimpleC2Interface.h> 33d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar 34d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include "C2SoftAacDec.h" 35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define FILEREAD_MAX_LAYERS 2 37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 38033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */ 39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */ 40033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */ 41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */ 42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */ 43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */ 44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// names of properties that can be used to override the default DRC settings 45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level" 46033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut" 47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost" 48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy" 49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level" 50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 51033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android { 52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 5372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarclass C2SoftAacDec::IntfImpl : public C2InterfaceHelper { 54277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimpublic: 55277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper) 56277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim : C2InterfaceHelper(helper) { 57277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 58277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim setDerivedInstance(this); 59277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 60277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 61277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING) 62277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed)) 63277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 64277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 65277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 66277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING) 67277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio)) 68277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 69277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 70277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 71277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING) 72277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(AllocSharedString<C2PortMimeConfig::input>( 73277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim MEDIA_MIMETYPE_AUDIO_AAC)) 74277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 75277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 76277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 77277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING) 78277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(AllocSharedString<C2PortMimeConfig::output>( 79277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim MEDIA_MIMETYPE_AUDIO_RAW)) 80277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 81277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 82277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 83277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING) 84277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2StreamSampleRateInfo::output(0u, 44100)) 85277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mSampleRate, value).oneOf({ 86277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 87277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim })}) 88fcb80244c30a69f0728c53027d08b94dcda12643Wonsik Kim .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps) 89277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 90277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 91277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 92277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING) 93277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2StreamChannelCountInfo::output(0u, 1)) 94277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mChannelCount, value).inRange(1, 8)}) 95277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps) 96277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 97277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 98277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 99277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING) 100277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2BitrateTuning::input(0u, 64000)) 101277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mBitrate, value).inRange(8000, 960000)}) 102277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps) 103277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 104277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 105277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 10660f1d71e3ae1f64f147b9c2fe3153eb5f477a24aHarish Mahendrakar DefineParam(mAacFormat, C2_NAME_STREAM_AAC_FORMAT_SETTING) 107277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw)) 108277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mAacFormat, value).oneOf({ 109277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2AacStreamFormatRaw, C2AacStreamFormatAdts 110277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim })}) 111277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps) 112277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 113277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } 114277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 115277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; } 116277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 117277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate: 118277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamFormatConfig::input> mInputFormat; 119277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat; 120277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2PortMimeConfig::input> mInputMediaType; 121277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType; 122277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate; 123277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount; 124277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2BitrateTuning::input> mBitrate; 125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 126277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat; 127277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim}; 128277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 1295c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnarconstexpr char COMPONENT_NAME[] = "c2.android.aac.decoder"; 130277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 13172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftAacDec::C2SoftAacDec( 132277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const char *name, 133277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim c2_node_id_t id, 134277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::shared_ptr<IntfImpl> &intfImpl) 135277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)), 136e15da79378e753bbd20f1c0f5c6858cc89bd4141Wonsik Kim mIntf(intfImpl), 137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mAACDecoder(NULL), 138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo(NULL), 139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError(false), 140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBuffer(NULL) { 141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 14372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftAacDec::~C2SoftAacDec() { 144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim onRelease(); 145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 14772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::onInit() { 148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = initDecoder(); 149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err == OK ? C2_OK : C2_CORRUPTED; 150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 15272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::onStop() { 153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim drainDecoder(); 154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // reset the "configured" state 155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayCompensated = 0; 156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferWritePos = 0; 157033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos = 0; 158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferFilled = 0; 159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.clear(); 160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // To make the codec behave the same before and after a reset, we need to invalidate the 162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // streaminfo struct. This does that: 163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only 164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = false; 166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 17072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::onReset() { 171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)onStop(); 172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 17472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::onRelease() { 175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mAACDecoder) { 176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_Close(mAACDecoder); 177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mAACDecoder = NULL; 178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBuffer) { 180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim delete[] mOutputDelayRingBuffer; 181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBuffer = NULL; 182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 18572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarstatus_t C2SoftAacDec::initDecoder() { 186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("initDecoder()"); 187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t status = UNKNOWN_ERROR; 188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1); 189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mAACDecoder != NULL) { 190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder); 191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mStreamInfo != NULL) { 192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status = OK; 193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayCompensated = 0; 197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax; 198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize]; 199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferWritePos = 0; 200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos = 0; 201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferFilled = 0; 202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mAACDecoder == NULL) { 204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code"); 205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0); 208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim //init DRC wrapper 210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setDecoderHandle(mAACDecoder); 211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.submitStreamData(mStreamInfo); 212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties 214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone) 215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim char value[PROPERTY_VALUE_MAX]; 216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // DRC_PRES_MODE_WRAP_DESIRED_TARGET 217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) { 218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned refLevel = atoi(value); 219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel, 220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DRC_DEFAULT_MOBILE_REF_LEVEL); 221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel); 222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL); 224033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 225033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR 226033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) { 227033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned cut = atoi(value); 228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut, 229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DRC_DEFAULT_MOBILE_DRC_CUT); 230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut); 231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT); 233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR 235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) { 236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned boost = atoi(value); 237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost, 238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DRC_DEFAULT_MOBILE_DRC_BOOST); 239033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost); 240033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 241033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST); 242033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 243033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // DRC_PRES_MODE_WRAP_DESIRED_HEAVY 244033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) { 245033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned heavy = atoi(value); 246033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy, 247033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim DRC_DEFAULT_MOBILE_DRC_HEAVY); 248033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy); 249033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 250033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY); 251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // DRC_PRES_MODE_WRAP_ENCODER_TARGET 253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) { 254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned encoderRefLevel = atoi(value); 255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d", 256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL); 257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel); 258033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 259033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL); 260033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 262033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // By default, the decoder creates a 5.1 channel downmix signal. 263033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // For seven and eight channel input streams, enable 6.1 and 7.1 channel output 264033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1); 265033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 266033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return status; 267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 26972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarbool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) { 270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (numSamples == 0) { 271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (outputDelayRingBufferSpaceLeft() < numSamples) { 274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("RING BUFFER WOULD OVERFLOW"); 275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize 278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos 279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) { 280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // faster memcopy loop without checks, if the preconditions allow this 281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (int32_t i = 0; i < numSamples; i++) { 282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i]; 283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) { 286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize; 287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 28972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()"); 290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (int32_t i = 0; i < numSamples; i++) { 292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i]; 293033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferWritePos++; 294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) { 295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize; 296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferFilled += numSamples; 300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 30372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarint32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) { 304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (numSamples > mOutputDelayRingBufferFilled) { 306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("RING BUFFER WOULD UNDERRUN"); 307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return -1; 308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize 311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos 312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) { 313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // faster memcopy loop without checks, if the preconditions allow this 314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (samples != 0) { 315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (int32_t i = 0; i < numSamples; i++) { 316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++]; 317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos += numSamples; 320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) { 322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize; 323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 32572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()"); 326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (int32_t i = 0; i < numSamples; i++) { 328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (samples != 0) { 329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos]; 330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos++; 332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) { 333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize; 334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferFilled -= numSamples; 338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return numSamples; 339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 34172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarint32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() { 342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mOutputDelayRingBufferFilled; 343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 34572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarint32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() { 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable(); 347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 34972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::drainRingBuffer( 350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work, 351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos) { 353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable() 354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim >= mStreamInfo->frameSize * mStreamInfo->numChannels) { 355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Info &outInfo = mBuffersInfo.front(); 356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex); 357d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t); 358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int available = outputDelayRingBufferSamplesAvailable(); 360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int numFrames = outInfo.decodedSizes.size(); 361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels); 362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (available < numSamples) { 363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numSamples = available; 365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("%d samples available (%d), or %d frames", 370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numSamples, available, numFrames); 371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("getting %d from ringbuffer", numSamples); 372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2LinearBlock> block; 374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(const std::unique_ptr<C2Work>&)> fillWork = 3758c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim [&block, numSamples, pool, this]() 376033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim -> std::function<void(const std::unique_ptr<C2Work>&)> { 3778c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim auto fillEmptyWork = []( 378277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::unique_ptr<C2Work> &work, c2_status_t err) { 379033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = err; 380277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2FrameData &output = work->worklets.front()->output; 381277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.flags = work->input.flags; 382277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.buffers.clear(); 383277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.ordinal = work->input.ordinal; 384277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 386033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim using namespace std::placeholders; 389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (numSamples == 0) { 390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::bind(fillEmptyWork, _1, C2_OK); 391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: error handling, proper usage, etc. 394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = pool->fetchLinearBlock( 396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numSamples * sizeof(int16_t), usage, &block); 397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("failed to fetch a linear block (%d)", err); 399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::bind(fillEmptyWork, _1, C2_NO_MEMORY); 401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2WriteView wView = block->map().get(); 403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data()); 405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples); 406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (ns != numSamples) { 407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("not a complete frame of samples available"); 408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::bind(fillEmptyWork, _1, C2_CORRUPTED); 410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 4118c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim return [buffer = createLinearBuffer(block)]( 412277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::unique_ptr<C2Work> &work) { 413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_OK; 414277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2FrameData &output = work->worklets.front()->output; 415277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.flags = work->input.flags; 416277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.buffers.clear(); 417277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.buffers.push_back(buffer); 418277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.ordinal = work->input.ordinal; 419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) { 424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillWork(work); 425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim finish(outInfo.frameIndex, fillWork); 427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0); 430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.pop_front(); 431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 43472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::process( 435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work, 436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool) { 437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 0u; 438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_OK; 439277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim work->worklets.front()->output.configUpdate.clear(); 440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mSignalledError) { 441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UCHAR* inBuffer[FILEREAD_MAX_LAYERS]; 445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0}; 446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UINT bytesValid[FILEREAD_MAX_LAYERS] = {0}; 447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 44945c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim C2ReadView view = mDummyReadView; 450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t offset = 0u; 45145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim size_t size = 0u; 45245c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim if (!work->input.buffers.empty()) { 45345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim view = work->input.buffers[0]->data().linearBlocks().front().map().get(); 45445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim size = view.capacity(); 45545c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim } 456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0; 458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0; 459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim //TODO 461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#if 0 462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mInputBufferCount == 0 && !codecConfig) { 463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("first buffer should have FLAG_CODEC_CONFIG set"); 464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codecConfig = true; 465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif 46745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim if (codecConfig && size > 0u) { 468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // const_cast because of libAACdec method signature. 469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer[0] = const_cast<UCHAR *>(view.data() + offset); 470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength[0] = size; 471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AAC_DECODER_ERROR decoderErr = 473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_ConfigRaw(mAACDecoder, 474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer, 475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength); 476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr != AAC_DEC_OK) { 478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr); 479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: error 481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.ordinal = work->input.ordinal; 485033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.clear(); 486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 490033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Info inInfo; 491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.frameIndex = work->input.ordinal.frameIndex.peeku(); 492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.timestamp = work->input.ordinal.timestamp.peeku(); 493033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.bufferSize = size; 494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.clear(); 495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (size > 0u) { 496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("size = %zu", size); 497277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim if (mIntf->isAdts()) { 498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t adtsHeaderSize = 0; 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // skip 30 bits, aac_frame_length follows. 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 501033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *adtsHeader = view.data() + offset; 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool signalError = false; 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (size < 7) { 506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Audio data too short to contain even the ADTS header. " 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "Got %zu bytes.", size); 508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hexdump(adtsHeader, size); 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim signalError = true; 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool protectionAbsent = (adtsHeader[1] & 1); 512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned aac_frame_length = 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ((adtsHeader[3] & 3) << 11) 515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim | (adtsHeader[4] << 3) 516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim | (adtsHeader[5] >> 5); 517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (size < aac_frame_length) { 519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Not enough audio data for the complete frame. " 520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "Got %zu bytes, frame size according to the ADTS " 521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "header is %u bytes.", 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size, aac_frame_length); 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hexdump(adtsHeader, size); 524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim signalError = true; 525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim adtsHeaderSize = (protectionAbsent ? 7 : 9); 527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (aac_frame_length < adtsHeaderSize) { 528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim signalError = true; 529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // const_cast because of libAACdec method signature. 531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize); 532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength[0] = aac_frame_length - adtsHeaderSize; 533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim offset += adtsHeaderSize; 535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size -= adtsHeaderSize; 536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (signalError) { 541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL); 543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // const_cast because of libAACdec method signature. 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer[0] = const_cast<UCHAR *>(view.data() + offset); 548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength[0] = size; 549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Fill and decode 552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bytesValid[0] = inBufferLength[0]; 553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT prevSampleRate = mStreamInfo->sampleRate; 555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT prevNumChannels = mStreamInfo->numChannels; 556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_Fill(mAACDecoder, 558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer, 559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength, 560033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bytesValid); 561033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // run DRC check 563033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.submitStreamData(mStreamInfo); 564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.update(); 565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 566033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0]; 567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size -= inBufferUsedLength; 568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim offset += inBufferUsedLength; 569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AAC_DECODER_ERROR decoderErr; 571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim do { 572033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (outputDelayRingBufferSpaceLeft() < 573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (mStreamInfo->frameSize * mStreamInfo->numChannels)) { 574033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("skipping decode: not enough space left in ringbuffer"); 575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int numConsumed = mStreamInfo->numTotalBytes; 579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim decoderErr = aacDecoder_DecodeFrame(mAACDecoder, 580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim tmpOutBuffer, 581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2048 * MAX_CHANNEL_COUNT, 582033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 0 /* flags */); 583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numConsumed = mStreamInfo->numTotalBytes - numConsumed; 585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) { 587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 588033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 589033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.push_back(numConsumed); 590033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 591033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr != AAC_DEC_OK) { 592033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 593033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 594033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 595033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (bytesValid[0] != 0) { 596033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("bytesValid[0] != 0 should never happen"); 597033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 598033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t numOutBytes = 603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels; 604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr == AAC_DEC_OK) { 606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->frameSize * mStreamInfo->numChannels)) { 608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr); 614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow 616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 617033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->frameSize * mStreamInfo->numChannels)) { 619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Discard input buffer. 625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size = 0; 626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); 628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // After an error, replace bufferSize with the sum of the 630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // decodedSizes to resynchronize the in/out lists. 631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.pop_back(); 632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.bufferSize = std::accumulate( 633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0); 634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // fall through 636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /* 639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * AAC+/eAAC+ streams can be signalled in two ways: either explicitly 640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual 641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * rate system and the sampling rate in the final output is actually 642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * doubled compared with the core AAC decoder sampling rate. 643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Explicit signalling is done by explicitly defining SBR audio object 645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * type in the bitstream. Implicit signalling is done by embedding 646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * SBR content in AAC extension payload specific to SBR, and hence 647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * requires an AAC decoder to perform pre-checks on actual audio frames. 648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Thus, we could not say for sure whether a stream is 650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * AAC+/eAAC+ until the first data frame is decoded. 651033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) { 653277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) { 654277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim ALOGD("Invalid AAC stream"); 655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 656277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // mSignalledError = true; 657277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // } 658277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } else if ((mStreamInfo->sampleRate != prevSampleRate) || 659277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim (mStreamInfo->numChannels != prevNumChannels)) { 660277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels", 661277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim prevSampleRate, mStreamInfo->sampleRate, 662277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim prevNumChannels, mStreamInfo->numChannels); 663277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 664277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); 665277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); 666277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::vector<std::unique_ptr<C2SettingResult>> failures; 667277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim c2_status_t err = mIntf->config( 668277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim { &sampleRateInfo, &channelCountInfo }, 669277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2_MAY_BLOCK, 670277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim &failures); 671277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim if (err == OK) { 672277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // TODO: this does not handle the case where the values are 673277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // altered during config. 6748c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim C2FrameData &output = work->worklets.front()->output; 6758c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim output.configUpdate.push_back(C2Param::Copy(sampleRateInfo)); 6768c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim output.configUpdate.push_back(C2Param::Copy(channelCountInfo)); 677033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 678277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // TODO: error handling 679033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("size = %zu", size); 681033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } while (decoderErr == AAC_DEC_OK); 682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 683033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels; 685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 686033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.push_back(std::move(inInfo)); 687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!eos && mOutputDelayCompensated < outputDelay) { 689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // discard outputDelay at the beginning 690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t toCompensate = outputDelay - mOutputDelayCompensated; 691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t discard = outputDelayRingBufferSamplesAvailable(); 692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (discard > toCompensate) { 693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim discard = toCompensate; 694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t discarded = outputDelayRingBufferGetSamples(0, discard); 696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayCompensated += discarded; 697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 7018c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work); 702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 7038c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim drainRingBuffer(work, pool, false /* not EOS */); 704033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 706033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 70772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::drainInternal( 708033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t drainMode, 709033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 7108c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim const std::unique_ptr<C2Work> &work) { 711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == NO_DRAIN) { 712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("drain with NO_DRAIN: no-op"); 713033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 714033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == DRAIN_CHAIN) { 716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("DRAIN_CHAIN not supported"); 717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OMITTED; 718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 719033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS); 721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim drainDecoder(); 7238c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim drainRingBuffer(work, pool, eos); 724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) { 727033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.flags = work->input.flags; 728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.clear(); 729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.ordinal = work->input.ordinal; 730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (mBuffersInfo.size() > 1u) { 733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim finish(mBuffersInfo.front().frameIndex, fillEmptyWork); 734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.pop_front(); 735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 736fd7de566b96cd02944556c4ccec08df88bdbc0b2Harish Mahendrakar if (work && work->workletsProcessed == 0u) { 737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillEmptyWork(work); 738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.clear(); 740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 74572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::drain( 746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t drainMode, 747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool) { 748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return drainInternal(drainMode, pool, nullptr); 749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 75172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::onFlush_sm() { 752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim drainDecoder(); 753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.clear(); 754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int avail; 756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) { 757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) { 758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim avail = mStreamInfo->frameSize * mStreamInfo->numChannels; 759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t ns = outputDelayRingBufferGetSamples(0, avail); 761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (ns != avail) { 762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("not a complete frame of samples available"); 763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos; 767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 77172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::drainDecoder() { 772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // flush decoder until outputDelay is compensated 773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (mOutputDelayCompensated > 0) { 774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC 775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // run DRC check 778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.submitStreamData(mStreamInfo); 779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.update(); 780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AAC_DECODER_ERROR decoderErr = 782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_DecodeFrame(mAACDecoder, 783033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim tmpOutBuffer, 784033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2048 * MAX_CHANNEL_COUNT, 785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AACDEC_FLUSH); 786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr != AAC_DEC_OK) { 787033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 788033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 789033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels; 791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tmpOutBufferSamples > mOutputDelayCompensated) { 792033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim tmpOutBufferSamples = mOutputDelayCompensated; 793033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 794033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples); 795033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 796033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayCompensated -= tmpOutBufferSamples; 797033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 798033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 799033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 800033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftAacDecFactory : public C2ComponentFactory { 801033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 802277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( 803277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim GetCodec2PlatformComponentStore()->getParamReflector())) { 804277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } 805277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 806033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual c2_status_t createComponent( 807033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_node_id_t id, 808033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component>* const component, 809033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(C2Component*)> deleter) override { 810277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim *component = std::shared_ptr<C2Component>( 81172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar new C2SoftAacDec(COMPONENT_NAME, 812277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim id, 81372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)), 814277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim deleter); 815033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 816033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 817033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 818033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual c2_status_t createInterface( 819277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, 820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(C2ComponentInterface*)> deleter) override { 821277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim *interface = std::shared_ptr<C2ComponentInterface>( 82272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar new SimpleInterface<C2SoftAacDec::IntfImpl>( 82372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)), 824277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim deleter); 825033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 826033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 827033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 828033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual ~C2SoftAacDecFactory() override = default; 829277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 830277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate: 831277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2ReflectorHelper> mHelper; 832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 833033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 834033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 835033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() { 837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in %s", __func__); 838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new ::android::C2SoftAacDecFactory(); 839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) { 842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in %s", __func__); 843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim delete factory; 844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 845