C2SoftAacDec.cpp revision 277b7295f317c6597fadb116b6aee5ca3be106c1
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 "C2SoftAac" 19033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/Log.h> 20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "C2SoftAac.h" 22033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h> 24277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim#include <SimpleInterfaceCommon.h> 25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 26033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <cutils/properties.h> 27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/ADebug.h> 28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/MediaDefs.h> 29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/hexdump.h> 30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/MediaErrors.h> 31033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/misc.h> 32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 33033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <inttypes.h> 34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <math.h> 35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <numeric> 36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define FILEREAD_MAX_LAYERS 2 38033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */ 40033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */ 41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */ 42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */ 43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik 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) */ 44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */ 45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// names of properties that can be used to override the default DRC settings 46033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level" 47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut" 48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost" 49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy" 50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level" 51033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android { 53033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 54277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimclass C2SoftAac::IntfImpl : public C2InterfaceHelper { 55277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimpublic: 56277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper) 57277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim : C2InterfaceHelper(helper) { 58277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 59277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim setDerivedInstance(this); 60277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 61277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 62277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING) 63277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed)) 64277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 65277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 66277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 67277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING) 68277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio)) 69277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 70277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 71277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 72277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING) 73277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(AllocSharedString<C2PortMimeConfig::input>( 74277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim MEDIA_MIMETYPE_AUDIO_AAC)) 75277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 76277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 77277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 78277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING) 79277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withConstValue(AllocSharedString<C2PortMimeConfig::output>( 80277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim MEDIA_MIMETYPE_AUDIO_RAW)) 81277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 82277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 83277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 84277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING) 85277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2StreamSampleRateInfo::output(0u, 44100)) 86277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mSampleRate, value).oneOf({ 87277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 88277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim })}) 89277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps)) 90277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 91277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 92277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 93277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING) 94277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2StreamChannelCountInfo::output(0u, 1)) 95277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mChannelCount, value).inRange(1, 8)}) 96277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps) 97277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 98277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 99277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 100277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING) 101277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2BitrateTuning::input(0u, 64000)) 102277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mBitrate, value).inRange(8000, 960000)}) 103277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps) 104277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 105277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 106277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim addParameter( 107277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim DefineParam(mAacFormat, C2_NAME_STREAM_BITRATE_SETTING) 108277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw)) 109277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withFields({C2F(mAacFormat, value).oneOf({ 110277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2AacStreamFormatRaw, C2AacStreamFormatAdts 111277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim })}) 112277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps) 113277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim .build()); 114277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } 115277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 116277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; } 117277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 118277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate: 119277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamFormatConfig::input> mInputFormat; 120277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat; 121277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2PortMimeConfig::input> mInputMediaType; 122277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType; 123277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate; 124277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount; 125277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2BitrateTuning::input> mBitrate; 126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 127277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat; 128277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim}; 129277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 130277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimconstexpr char COMPONENT_NAME[] = "c2.google.aac.decoder"; 131277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 132277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik KimC2SoftAac::C2SoftAac( 133277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const char *name, 134277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim c2_node_id_t id, 135277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::shared_ptr<IntfImpl> &intfImpl) 136277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)), 137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mAACDecoder(NULL), 138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo(NULL), 139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError(false), 140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBuffer(NULL) { 141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimC2SoftAac::~C2SoftAac() { 144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim onRelease(); 145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::onInit() { 148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = initDecoder(); 149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err == OK ? C2_OK : C2_CORRUPTED; 150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::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 170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::onReset() { 171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)onStop(); 172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::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 185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t C2SoftAac::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 269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimbool C2SoftAac::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 { 289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("slow C2SoftAac::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 303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimint32_t C2SoftAac::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 { 325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("slow C2SoftAac::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 341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimint32_t C2SoftAac::outputDelayRingBufferSamplesAvailable() { 342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mOutputDelayRingBufferFilled; 343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimint32_t C2SoftAac::outputDelayRingBufferSpaceLeft() { 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable(); 347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::drainRingBuffer( 350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work, 351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 352277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::vector<std::unique_ptr<C2Param>> *configUpdate, 353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos) { 354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable() 355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim >= mStreamInfo->frameSize * mStreamInfo->numChannels) { 356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Info &outInfo = mBuffersInfo.front(); 357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex); 358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int samplesize = mStreamInfo->numChannels * sizeof(int16_t); 359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int available = outputDelayRingBufferSamplesAvailable(); 361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int numFrames = outInfo.decodedSizes.size(); 362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels); 363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (available < numSamples) { 364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numSamples = available; 366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("%d samples available (%d), or %d frames", 371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numSamples, available, numFrames); 372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("getting %d from ringbuffer", numSamples); 373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2LinearBlock> block; 375033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(const std::unique_ptr<C2Work>&)> fillWork = 376277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim [&block, numSamples, pool, configUpdate, this]() 377033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim -> std::function<void(const std::unique_ptr<C2Work>&)> { 378277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim auto fillEmptyWork = [configUpdate]( 379277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::unique_ptr<C2Work> &work, c2_status_t err) { 380033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = err; 381277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2FrameData &output = work->worklets.front()->output; 382277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.flags = work->input.flags; 383277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.buffers.clear(); 384277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.ordinal = work->input.ordinal; 385277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim while (configUpdate && !configUpdate->empty()) { 386277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.configUpdate.push_back(std::move(configUpdate->front())); 387277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } 388277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim using namespace std::placeholders; 393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (numSamples == 0) { 394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::bind(fillEmptyWork, _1, C2_OK); 395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: error handling, proper usage, etc. 398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = pool->fetchLinearBlock( 400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numSamples * sizeof(int16_t), usage, &block); 401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGD("failed to fetch a linear block (%d)", err); 403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::bind(fillEmptyWork, _1, C2_NO_MEMORY); 405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2WriteView wView = block->map().get(); 407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO 408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data()); 409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples); 410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (ns != numSamples) { 411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("not a complete frame of samples available"); 412033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return std::bind(fillEmptyWork, _1, C2_CORRUPTED); 414033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 415277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim return [buffer = createLinearBuffer(block), configUpdate]( 416277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::unique_ptr<C2Work> &work) { 417033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_OK; 418277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2FrameData &output = work->worklets.front()->output; 419277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.flags = work->input.flags; 420277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.buffers.clear(); 421277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.buffers.push_back(buffer); 422277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.ordinal = work->input.ordinal; 423277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim while (configUpdate && !configUpdate->empty()) { 424277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim output.configUpdate.push_back(std::move(configUpdate->front())); 425277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } 426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }(); 429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) { 431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillWork(work); 432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim finish(outInfo.frameIndex, fillWork); 434033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0); 437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.pop_front(); 438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 439033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::process( 442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work, 443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool) { 444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 0u; 445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_OK; 446277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim work->worklets.front()->output.configUpdate.clear(); 447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mSignalledError) { 448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 449033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 451033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UCHAR* inBuffer[FILEREAD_MAX_LAYERS]; 452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0}; 453033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UINT bytesValid[FILEREAD_MAX_LAYERS] = {0}; 454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2ReadView view = work->input.buffers[0]->data().linearBlocks().front().map().get(); 457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t offset = 0u; 458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t size = view.capacity(); 459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0; 461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0; 462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim //TODO 464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#if 0 465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mInputBufferCount == 0 && !codecConfig) { 466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("first buffer should have FLAG_CODEC_CONFIG set"); 467033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim codecConfig = true; 468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif 470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codecConfig) { 471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // const_cast because of libAACdec method signature. 472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer[0] = const_cast<UCHAR *>(view.data() + offset); 473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength[0] = size; 474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AAC_DECODER_ERROR decoderErr = 476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_ConfigRaw(mAACDecoder, 477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer, 478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength); 479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr != AAC_DEC_OK) { 481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr); 482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: error 484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 485033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.ordinal = work->input.ordinal; 488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.clear(); 489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 490033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 493277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::vector<std::unique_ptr<C2Param>> configUpdate{}; 494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim Info inInfo; 495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.frameIndex = work->input.ordinal.frameIndex.peeku(); 496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.timestamp = work->input.ordinal.timestamp.peeku(); 497033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.bufferSize = size; 498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.clear(); 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (size > 0u) { 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("size = %zu", size); 501277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim if (mIntf->isAdts()) { 502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t adtsHeaderSize = 0; 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // skip 30 bits, aac_frame_length follows. 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *adtsHeader = view.data() + offset; 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool signalError = false; 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (size < 7) { 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Audio data too short to contain even the ADTS header. " 511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "Got %zu bytes.", size); 512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hexdump(adtsHeader, size); 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim signalError = true; 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool protectionAbsent = (adtsHeader[1] & 1); 516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim unsigned aac_frame_length = 518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ((adtsHeader[3] & 3) << 11) 519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim | (adtsHeader[4] << 3) 520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim | (adtsHeader[5] >> 5); 521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (size < aac_frame_length) { 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Not enough audio data for the complete frame. " 524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "Got %zu bytes, frame size according to the ADTS " 525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim "header is %u bytes.", 526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size, aac_frame_length); 527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim hexdump(adtsHeader, size); 528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim signalError = true; 529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim adtsHeaderSize = (protectionAbsent ? 7 : 9); 531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (aac_frame_length < adtsHeaderSize) { 532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim signalError = true; 533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // const_cast because of libAACdec method signature. 535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize); 536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength[0] = aac_frame_length - adtsHeaderSize; 537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim offset += adtsHeaderSize; 539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size -= adtsHeaderSize; 540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (signalError) { 545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL); 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // const_cast because of libAACdec method signature. 551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer[0] = const_cast<UCHAR *>(view.data() + offset); 552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength[0] = size; 553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Fill and decode 556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bytesValid[0] = inBufferLength[0]; 557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT prevSampleRate = mStreamInfo->sampleRate; 559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT prevNumChannels = mStreamInfo->numChannels; 560033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 561033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_Fill(mAACDecoder, 562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBuffer, 563033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inBufferLength, 564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bytesValid); 565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 566033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // run DRC check 567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.submitStreamData(mStreamInfo); 568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.update(); 569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0]; 571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size -= inBufferUsedLength; 572033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim offset += inBufferUsedLength; 573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 574033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AAC_DECODER_ERROR decoderErr; 575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim do { 576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (outputDelayRingBufferSpaceLeft() < 577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (mStreamInfo->frameSize * mStreamInfo->numChannels)) { 578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("skipping decode: not enough space left in ringbuffer"); 579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 582033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int numConsumed = mStreamInfo->numTotalBytes; 583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim decoderErr = aacDecoder_DecodeFrame(mAACDecoder, 584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim tmpOutBuffer, 585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2048 * MAX_CHANNEL_COUNT, 586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 0 /* flags */); 587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 588033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim numConsumed = mStreamInfo->numTotalBytes - numConsumed; 589033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 590033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) { 591033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 592033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 593033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.push_back(numConsumed); 594033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 595033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr != AAC_DEC_OK) { 596033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 597033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 598033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (bytesValid[0] != 0) { 600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("bytesValid[0] != 0 should never happen"); 601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t numOutBytes = 607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels; 608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr == AAC_DEC_OK) { 610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->frameSize * mStreamInfo->numChannels)) { 612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 617033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr); 618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow 620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mStreamInfo->frameSize * mStreamInfo->numChannels)) { 623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Discard input buffer. 629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size = 0; 630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); 632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // After an error, replace bufferSize with the sum of the 634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // decodedSizes to resynchronize the in/out lists. 635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.pop_back(); 636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.bufferSize = std::accumulate( 637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0); 638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // fall through 640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim /* 643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * AAC+/eAAC+ streams can be signalled in two ways: either explicitly 644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual 645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * rate system and the sampling rate in the final output is actually 646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * doubled compared with the core AAC decoder sampling rate. 647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Explicit signalling is done by explicitly defining SBR audio object 649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * type in the bitstream. Implicit signalling is done by embedding 650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * SBR content in AAC extension payload specific to SBR, and hence 651033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * requires an AAC decoder to perform pre-checks on actual audio frames. 652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 653033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Thus, we could not say for sure whether a stream is 654033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * AAC+/eAAC+ until the first data frame is decoded. 655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 656033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) { 657277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) { 658277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim ALOGD("Invalid AAC stream"); 659033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 660277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // mSignalledError = true; 661277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // } 662277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } else if ((mStreamInfo->sampleRate != prevSampleRate) || 663277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim (mStreamInfo->numChannels != prevNumChannels)) { 664277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels", 665277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim prevSampleRate, mStreamInfo->sampleRate, 666277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim prevNumChannels, mStreamInfo->numChannels); 667277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 668277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); 669277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); 670277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::vector<std::unique_ptr<C2SettingResult>> failures; 671277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim c2_status_t err = mIntf->config( 672277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim { &sampleRateInfo, &channelCountInfo }, 673277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2_MAY_BLOCK, 674277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim &failures); 675277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim if (err == OK) { 676277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // TODO: this does not handle the case where the values are 677277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // altered during config. 678277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim configUpdate.push_back(C2Param::Copy(sampleRateInfo)); 679277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim configUpdate.push_back(C2Param::Copy(channelCountInfo)); 680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 681277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim // TODO: error handling 682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 683033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("size = %zu", size); 684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } while (decoderErr == AAC_DEC_OK); 685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 686033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels; 688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.push_back(std::move(inInfo)); 690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!eos && mOutputDelayCompensated < outputDelay) { 692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // discard outputDelay at the beginning 693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t toCompensate = outputDelay - mOutputDelayCompensated; 694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t discard = outputDelayRingBufferSamplesAvailable(); 695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (discard > toCompensate) { 696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim discard = toCompensate; 697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t discarded = outputDelayRingBufferGetSamples(0, discard); 699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayCompensated += discarded; 700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 701033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 703033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 704277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work, &configUpdate); 705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 706277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim drainRingBuffer(work, pool, &configUpdate, false /* not EOS */); 707033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 708033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 709033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 710033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::drainInternal( 711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t drainMode, 712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 713277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim const std::unique_ptr<C2Work> &work, 714277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::vector<std::unique_ptr<C2Param>> *configUpdate) { 715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == NO_DRAIN) { 716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("drain with NO_DRAIN: no-op"); 717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 719033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == DRAIN_CHAIN) { 720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("DRAIN_CHAIN not supported"); 721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OMITTED; 722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 723033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS); 725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim drainDecoder(); 727277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim drainRingBuffer(work, pool, configUpdate, eos); 728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) { 731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.flags = work->input.flags; 732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.clear(); 733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.ordinal = work->input.ordinal; 734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 736033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (mBuffersInfo.size() > 1u) { 737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim finish(mBuffersInfo.front().frameIndex, fillEmptyWork); 738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.pop_front(); 739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work->workletsProcessed == 0u) { 741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillEmptyWork(work); 742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.clear(); 744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 745033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::drain( 750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t drainMode, 751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool) { 752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return drainInternal(drainMode, pool, nullptr); 753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::onFlush_sm() { 756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim drainDecoder(); 757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mBuffersInfo.clear(); 758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int avail; 760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) { 761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) { 762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim avail = mStreamInfo->frameSize * mStreamInfo->numChannels; 763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t ns = outputDelayRingBufferGetSamples(0, avail); 765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (ns != avail) { 766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("not a complete frame of samples available"); 767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim break; 768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos; 771033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::drainDecoder() { 776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // flush decoder until outputDelay is compensated 777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (mOutputDelayCompensated > 0) { 778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC 779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // run DRC check 782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.submitStreamData(mStreamInfo); 783033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mDrcWrap.update(); 784033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AAC_DECODER_ERROR decoderErr = 786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim aacDecoder_DecodeFrame(mAACDecoder, 787033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim tmpOutBuffer, 788033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2048 * MAX_CHANNEL_COUNT, 789033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim AACDEC_FLUSH); 790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (decoderErr != AAC_DEC_OK) { 791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 792033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 793033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 794033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels; 795033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (tmpOutBufferSamples > mOutputDelayCompensated) { 796033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim tmpOutBufferSamples = mOutputDelayCompensated; 797033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 798033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples); 799033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 800033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mOutputDelayCompensated -= tmpOutBufferSamples; 801033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 802033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 803033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 804033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftAacDecFactory : public C2ComponentFactory { 805033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 806277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( 807277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim GetCodec2PlatformComponentStore()->getParamReflector())) { 808277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim } 809277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 810033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual c2_status_t createComponent( 811033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_node_id_t id, 812033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component>* const component, 813033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(C2Component*)> deleter) override { 814277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim *component = std::shared_ptr<C2Component>( 815277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim new C2SoftAac(COMPONENT_NAME, 816277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim id, 817277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::make_shared<C2SoftAac::IntfImpl>(mHelper)), 818277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim deleter); 819033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 821033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 822033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual c2_status_t createInterface( 823277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, 824033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(C2ComponentInterface*)> deleter) override { 825277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim *interface = std::shared_ptr<C2ComponentInterface>( 826277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim new SimpleInterface<C2SoftAac::IntfImpl>( 827277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim COMPONENT_NAME, id, std::make_shared<C2SoftAac::IntfImpl>(mHelper)), 828277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim deleter); 829033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 830033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 831033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual ~C2SoftAacDecFactory() override = default; 833277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim 834277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate: 835277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim std::shared_ptr<C2ReflectorHelper> mHelper; 836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() { 841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in %s", __func__); 842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new ::android::C2SoftAacDecFactory(); 843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 845033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) { 846033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in %s", __func__); 847033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim delete factory; 848033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 849