blob: 677f31643a486a666f6988bad4fccd9b664f3c9e [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "C2SoftAacDec"
19#include <log/log.h>
20
21#include <inttypes.h>
22#include <math.h>
23#include <numeric>
24
25#include <cutils/properties.h>
26#include <media/stagefright/foundation/MediaDefs.h>
27#include <media/stagefright/foundation/hexdump.h>
28#include <media/stagefright/MediaErrors.h>
29#include <utils/misc.h>
30
31#include <C2PlatformSupport.h>
32#include <SimpleC2Interface.h>
33
34#include "C2SoftAacDec.h"
35
36#define FILEREAD_MAX_LAYERS 2
37
38#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
39#define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */
40#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
41#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */
42#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -080043#define DRC_DEFAULT_MOBILE_DRC_ALBUM 0 /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -080044#define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS (0.25) /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
Pawin Vongmasa36653902018-11-15 00:10:25 -080045#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
46#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
47// names of properties that can be used to override the default DRC settings
48#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
49#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
50#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
51#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
52#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
53#define PROP_DRC_OVERRIDE_EFFECT "ro.aac_drc_effect_type"
54
55namespace android {
56
Wonsik Kimab34ed62019-01-31 15:28:46 -080057constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
58
59class C2SoftAacDec::IntfImpl : public SimpleInterface<void>::BaseParams {
Pawin Vongmasa36653902018-11-15 00:10:25 -080060public:
61 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
Wonsik Kimab34ed62019-01-31 15:28:46 -080062 : SimpleInterface<void>::BaseParams(
63 helper,
64 COMPONENT_NAME,
65 C2Component::KIND_DECODER,
66 C2Component::DOMAIN_AUDIO,
67 MEDIA_MIMETYPE_AUDIO_AAC) {
68 noPrivateBuffers();
69 noInputReferences();
70 noOutputReferences();
71 noInputLatency();
72 noTimeStretch();
Pawin Vongmasa36653902018-11-15 00:10:25 -080073
74 addParameter(
Wonsik Kimab34ed62019-01-31 15:28:46 -080075 DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
76 .withConstValue(new C2PortActualDelayTuning::output(2u))
Pawin Vongmasa36653902018-11-15 00:10:25 -080077 .build());
78
79 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -080080 DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
Pawin Vongmasa36653902018-11-15 00:10:25 -080081 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
82 .withFields({C2F(mSampleRate, value).oneOf({
Sungtak Leed7f88ee2019-11-14 16:04:25 -080083 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000,
84 44100, 48000, 64000, 88200, 96000
Pawin Vongmasa36653902018-11-15 00:10:25 -080085 })})
86 .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
87 .build());
88
89 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -080090 DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
Pawin Vongmasa36653902018-11-15 00:10:25 -080091 .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -070092 .withFields({C2F(mChannelCount, value).inRange(1, MAX_CHANNEL_COUNT)})
Pawin Vongmasa36653902018-11-15 00:10:25 -080093 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
94 .build());
95
96 addParameter(
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -070097 DefineParam(mMaxChannelCount, C2_PARAMKEY_MAX_CHANNEL_COUNT)
98 .withDefault(new C2StreamMaxChannelCountInfo::input(0u, MAX_CHANNEL_COUNT))
99 .withFields({C2F(mMaxChannelCount, value).inRange(1, MAX_CHANNEL_COUNT)})
100 .withSetter(Setter<decltype(*mMaxChannelCount)>::StrictValueWithNoDeps)
101 .build());
102
103 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800104 DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
105 .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
Pawin Vongmasa36653902018-11-15 00:10:25 -0800106 .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
107 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
108 .build());
109
110 addParameter(
111 DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
112 .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
113 .build());
114
115 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800116 DefineParam(mAacFormat, C2_PARAMKEY_AAC_PACKAGING)
117 .withDefault(new C2StreamAacFormatInfo::input(0u, C2Config::AAC_PACKAGING_RAW))
Pawin Vongmasa36653902018-11-15 00:10:25 -0800118 .withFields({C2F(mAacFormat, value).oneOf({
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800119 C2Config::AAC_PACKAGING_RAW, C2Config::AAC_PACKAGING_ADTS
Pawin Vongmasa36653902018-11-15 00:10:25 -0800120 })})
121 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
122 .build());
123
124 addParameter(
125 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
126 .withDefault(new C2StreamProfileLevelInfo::input(0u,
127 C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
128 .withFields({
129 C2F(mProfileLevel, profile).oneOf({
130 C2Config::PROFILE_AAC_LC,
131 C2Config::PROFILE_AAC_HE,
132 C2Config::PROFILE_AAC_HE_PS,
133 C2Config::PROFILE_AAC_LD,
134 C2Config::PROFILE_AAC_ELD,
135 C2Config::PROFILE_AAC_ER_SCALABLE,
136 C2Config::PROFILE_AAC_XHE}),
137 C2F(mProfileLevel, level).oneOf({
138 C2Config::LEVEL_UNUSED
139 })
140 })
141 .withSetter(ProfileLevelSetter)
142 .build());
143
144 addParameter(
145 DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
146 .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
147 .withFields({
148 C2F(mDrcCompressMode, value).oneOf({
149 C2Config::DRC_COMPRESSION_ODM_DEFAULT,
150 C2Config::DRC_COMPRESSION_NONE,
151 C2Config::DRC_COMPRESSION_LIGHT,
152 C2Config::DRC_COMPRESSION_HEAVY})
153 })
154 .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
155 .build());
156
157 addParameter(
158 DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
159 .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
160 .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
161 .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
162 .build());
163
164 addParameter(
165 DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
166 .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
167 .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
168 .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
169 .build());
170
171 addParameter(
172 DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
173 .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
174 .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
175 .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
176 .build());
177
178 addParameter(
179 DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
180 .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
181 .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
182 .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
183 .build());
184
185 addParameter(
186 DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
187 .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
188 .withFields({
189 C2F(mDrcEffectType, value).oneOf({
190 C2Config::DRC_EFFECT_ODM_DEFAULT,
191 C2Config::DRC_EFFECT_OFF,
192 C2Config::DRC_EFFECT_NONE,
193 C2Config::DRC_EFFECT_LATE_NIGHT,
194 C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
195 C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
196 C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
197 C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
198 C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
199 })
200 .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
201 .build());
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800202
203 addParameter(
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800204 DefineParam(mDrcAlbumMode, C2_PARAMKEY_DRC_ALBUM_MODE)
205 .withDefault(new C2StreamDrcAlbumModeTuning::input(0u, C2Config::DRC_ALBUM_MODE_OFF))
206 .withFields({
207 C2F(mDrcAlbumMode, value).oneOf({
208 C2Config::DRC_ALBUM_MODE_OFF,
209 C2Config::DRC_ALBUM_MODE_ON})
210 })
211 .withSetter(Setter<decltype(*mDrcAlbumMode)>::StrictValueWithNoDeps)
212 .build());
213
214 addParameter(
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800215 DefineParam(mDrcOutputLoudness, C2_PARAMKEY_DRC_OUTPUT_LOUDNESS)
216 .withDefault(new C2StreamDrcOutputLoudnessTuning::output(0u, DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS))
217 .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)})
218 .withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps)
219 .build());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800220 }
221
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800222 bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800223 static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
224 (void)mayBlock;
225 (void)me; // TODO: validate
226 return C2R::Ok();
227 }
228 int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
229 int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
230 int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
231 int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
232 int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
233 int32_t getDrcEffectType() const { return mDrcEffectType->value; }
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800234 int32_t getDrcAlbumMode() const { return mDrcAlbumMode->value; }
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700235 u_int32_t getMaxChannelCount() const { return mMaxChannelCount->value; }
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800236 int32_t getDrcOutputLoudness() const { return (mDrcOutputLoudness->value <= 0 ? -mDrcOutputLoudness->value * 4. + 0.5 : -1); }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800237
238private:
Pawin Vongmasa36653902018-11-15 00:10:25 -0800239 std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
240 std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800241 std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800242 std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
243 std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
244 std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
245 std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
246 std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
247 std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
248 std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
249 std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
250 std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800251 std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode;
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700252 std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount;
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800253 std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800254 // TODO Add : C2StreamAacSbrModeTuning
255};
256
Pawin Vongmasa36653902018-11-15 00:10:25 -0800257C2SoftAacDec::C2SoftAacDec(
258 const char *name,
259 c2_node_id_t id,
260 const std::shared_ptr<IntfImpl> &intfImpl)
261 : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
262 mIntf(intfImpl),
263 mAACDecoder(nullptr),
264 mStreamInfo(nullptr),
265 mSignalledError(false),
266 mOutputDelayRingBuffer(nullptr) {
267}
268
269C2SoftAacDec::~C2SoftAacDec() {
270 onRelease();
271}
272
273c2_status_t C2SoftAacDec::onInit() {
274 status_t err = initDecoder();
275 return err == OK ? C2_OK : C2_CORRUPTED;
276}
277
278c2_status_t C2SoftAacDec::onStop() {
279 drainDecoder();
280 // reset the "configured" state
281 mOutputDelayCompensated = 0;
282 mOutputDelayRingBufferWritePos = 0;
283 mOutputDelayRingBufferReadPos = 0;
284 mOutputDelayRingBufferFilled = 0;
285 mBuffersInfo.clear();
286
287 // To make the codec behave the same before and after a reset, we need to invalidate the
288 // streaminfo struct. This does that:
289 mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
290
291 mSignalledError = false;
292
293 return C2_OK;
294}
295
296void C2SoftAacDec::onReset() {
297 (void)onStop();
298}
299
300void C2SoftAacDec::onRelease() {
301 if (mAACDecoder) {
302 aacDecoder_Close(mAACDecoder);
303 mAACDecoder = nullptr;
304 }
305 if (mOutputDelayRingBuffer) {
306 delete[] mOutputDelayRingBuffer;
307 mOutputDelayRingBuffer = nullptr;
308 }
309}
310
311status_t C2SoftAacDec::initDecoder() {
312 ALOGV("initDecoder()");
313 status_t status = UNKNOWN_ERROR;
314 mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
315 if (mAACDecoder != nullptr) {
316 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
317 if (mStreamInfo != nullptr) {
318 status = OK;
319 }
320 }
321
322 mOutputDelayCompensated = 0;
323 mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
324 mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
325 mOutputDelayRingBufferWritePos = 0;
326 mOutputDelayRingBufferReadPos = 0;
327 mOutputDelayRingBufferFilled = 0;
328
329 if (mAACDecoder == nullptr) {
330 ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
331 }
332
333 //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
334
335 //init DRC wrapper
336 mDrcWrap.setDecoderHandle(mAACDecoder);
337 mDrcWrap.submitStreamData(mStreamInfo);
338
339 // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
340 // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
341
342 // DRC_PRES_MODE_WRAP_DESIRED_TARGET
343 int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
344 ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
345 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
346
347 // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
348
349 int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
350 ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
351 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
352
353 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
354 int32_t boostFactor = mIntf->getDrcBoostFactor();
355 ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
356 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
357
358 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
359 int32_t compressMode = mIntf->getDrcCompressMode();
Jean-Michel Triviedf942b2020-01-29 09:59:44 -0800360 ALOGV("AAC decoder using desired DRC heavy compression switch of %d", compressMode);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800361 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
362
363 // DRC_PRES_MODE_WRAP_ENCODER_TARGET
364 int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
365 ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
366 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
367
368 // AAC_UNIDRC_SET_EFFECT
369 int32_t effectType = mIntf->getDrcEffectType();
370 ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
371 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
372
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800373 // AAC_UNIDRC_ALBUM_MODE
374 int32_t albumMode = mIntf->getDrcAlbumMode();
375 ALOGV("AAC decoder using MPEG-D DRC album mode %d", albumMode);
376 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
377
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700378 // AAC_PCM_MAX_OUTPUT_CHANNELS
379 u_int32_t maxChannelCount = mIntf->getMaxChannelCount();
380 ALOGV("AAC decoder using maximum output channel count %d", maxChannelCount);
381 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, maxChannelCount);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800382
383 return status;
384}
385
386bool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
387 if (numSamples == 0) {
388 return true;
389 }
390 if (outputDelayRingBufferSpaceLeft() < numSamples) {
391 ALOGE("RING BUFFER WOULD OVERFLOW");
392 return false;
393 }
394 if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
395 && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
396 || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
397 // faster memcopy loop without checks, if the preconditions allow this
398 for (int32_t i = 0; i < numSamples; i++) {
399 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
400 }
401
402 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
403 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
404 }
405 } else {
406 ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
407
408 for (int32_t i = 0; i < numSamples; i++) {
409 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
410 mOutputDelayRingBufferWritePos++;
411 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
412 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
413 }
414 }
415 }
416 mOutputDelayRingBufferFilled += numSamples;
417 return true;
418}
419
420int32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
421
422 if (numSamples > mOutputDelayRingBufferFilled) {
423 ALOGE("RING BUFFER WOULD UNDERRUN");
424 return -1;
425 }
426
427 if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
428 && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
429 || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
430 // faster memcopy loop without checks, if the preconditions allow this
431 if (samples != nullptr) {
432 for (int32_t i = 0; i < numSamples; i++) {
433 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
434 }
435 } else {
436 mOutputDelayRingBufferReadPos += numSamples;
437 }
438 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
439 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
440 }
441 } else {
442 ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
443
444 for (int32_t i = 0; i < numSamples; i++) {
445 if (samples != nullptr) {
446 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
447 }
448 mOutputDelayRingBufferReadPos++;
449 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
450 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
451 }
452 }
453 }
454 mOutputDelayRingBufferFilled -= numSamples;
455 return numSamples;
456}
457
458int32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
459 return mOutputDelayRingBufferFilled;
460}
461
462int32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
463 return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
464}
465
466void C2SoftAacDec::drainRingBuffer(
467 const std::unique_ptr<C2Work> &work,
468 const std::shared_ptr<C2BlockPool> &pool,
469 bool eos) {
470 while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
471 >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
472 Info &outInfo = mBuffersInfo.front();
473 ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
474 int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
475
476 int available = outputDelayRingBufferSamplesAvailable();
477 int numFrames = outInfo.decodedSizes.size();
478 int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
479 if (available < numSamples) {
480 if (eos) {
481 numSamples = available;
482 } else {
483 break;
484 }
485 }
486 ALOGV("%d samples available (%d), or %d frames",
487 numSamples, available, numFrames);
488 ALOGV("getting %d from ringbuffer", numSamples);
489
490 std::shared_ptr<C2LinearBlock> block;
491 std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
492 [&block, numSamples, pool, this]()
493 -> std::function<void(const std::unique_ptr<C2Work>&)> {
494 auto fillEmptyWork = [](
495 const std::unique_ptr<C2Work> &work, c2_status_t err) {
496 work->result = err;
497 C2FrameData &output = work->worklets.front()->output;
498 output.flags = work->input.flags;
499 output.buffers.clear();
500 output.ordinal = work->input.ordinal;
501
502 work->workletsProcessed = 1u;
503 };
504
505 using namespace std::placeholders;
506 if (numSamples == 0) {
507 return std::bind(fillEmptyWork, _1, C2_OK);
508 }
509
510 // TODO: error handling, proper usage, etc.
511 C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
512 c2_status_t err = pool->fetchLinearBlock(
513 numSamples * sizeof(int16_t), usage, &block);
514 if (err != C2_OK) {
515 ALOGD("failed to fetch a linear block (%d)", err);
516 return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
517 }
518 C2WriteView wView = block->map().get();
519 // TODO
520 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
521 int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
522 if (ns != numSamples) {
523 ALOGE("not a complete frame of samples available");
524 mSignalledError = true;
525 return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
526 }
527 return [buffer = createLinearBuffer(block)](
528 const std::unique_ptr<C2Work> &work) {
529 work->result = C2_OK;
530 C2FrameData &output = work->worklets.front()->output;
531 output.flags = work->input.flags;
532 output.buffers.clear();
533 output.buffers.push_back(buffer);
534 output.ordinal = work->input.ordinal;
535 work->workletsProcessed = 1u;
536 };
537 }();
538
539 if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
540 fillWork(work);
541 } else {
542 finish(outInfo.frameIndex, fillWork);
543 }
544
545 ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
546 mBuffersInfo.pop_front();
547 }
548}
549
550void C2SoftAacDec::process(
551 const std::unique_ptr<C2Work> &work,
552 const std::shared_ptr<C2BlockPool> &pool) {
553 // Initialize output work
554 work->result = C2_OK;
555 work->workletsProcessed = 1u;
556 work->worklets.front()->output.configUpdate.clear();
557 work->worklets.front()->output.flags = work->input.flags;
558
559 if (mSignalledError) {
560 return;
561 }
562
563 UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
564 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
565 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
566
567 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
568 C2ReadView view = mDummyReadView;
569 size_t offset = 0u;
570 size_t size = 0u;
571 if (!work->input.buffers.empty()) {
572 view = work->input.buffers[0]->data().linearBlocks().front().map().get();
573 size = view.capacity();
574 }
575
576 bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
577 bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
578
579 //TODO
580#if 0
581 if (mInputBufferCount == 0 && !codecConfig) {
582 ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
583 codecConfig = true;
584 }
585#endif
586 if (codecConfig && size > 0u) {
587 // const_cast because of libAACdec method signature.
588 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
589 inBufferLength[0] = size;
590
591 AAC_DECODER_ERROR decoderErr =
592 aacDecoder_ConfigRaw(mAACDecoder,
593 inBuffer,
594 inBufferLength);
595
596 if (decoderErr != AAC_DEC_OK) {
597 ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
598 mSignalledError = true;
599 work->result = C2_CORRUPTED;
600 return;
601 }
602 work->worklets.front()->output.flags = work->input.flags;
603 work->worklets.front()->output.ordinal = work->input.ordinal;
604 work->worklets.front()->output.buffers.clear();
605 return;
606 }
607
608 Info inInfo;
609 inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
610 inInfo.timestamp = work->input.ordinal.timestamp.peeku();
611 inInfo.bufferSize = size;
612 inInfo.decodedSizes.clear();
613 while (size > 0u) {
614 ALOGV("size = %zu", size);
615 if (mIntf->isAdts()) {
616 size_t adtsHeaderSize = 0;
617 // skip 30 bits, aac_frame_length follows.
618 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
619
620 const uint8_t *adtsHeader = view.data() + offset;
621
622 bool signalError = false;
623 if (size < 7) {
624 ALOGE("Audio data too short to contain even the ADTS header. "
625 "Got %zu bytes.", size);
626 hexdump(adtsHeader, size);
627 signalError = true;
628 } else {
629 bool protectionAbsent = (adtsHeader[1] & 1);
630
631 unsigned aac_frame_length =
632 ((adtsHeader[3] & 3) << 11)
633 | (adtsHeader[4] << 3)
634 | (adtsHeader[5] >> 5);
635
636 if (size < aac_frame_length) {
637 ALOGE("Not enough audio data for the complete frame. "
638 "Got %zu bytes, frame size according to the ADTS "
639 "header is %u bytes.",
640 size, aac_frame_length);
641 hexdump(adtsHeader, size);
642 signalError = true;
643 } else {
644 adtsHeaderSize = (protectionAbsent ? 7 : 9);
645 if (aac_frame_length < adtsHeaderSize) {
646 signalError = true;
647 } else {
648 // const_cast because of libAACdec method signature.
649 inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
650 inBufferLength[0] = aac_frame_length - adtsHeaderSize;
651
652 offset += adtsHeaderSize;
653 size -= adtsHeaderSize;
654 }
655 }
656 }
657
658 if (signalError) {
659 mSignalledError = true;
660 work->result = C2_CORRUPTED;
661 return;
662 }
663 } else {
664 // const_cast because of libAACdec method signature.
665 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
666 inBufferLength[0] = size;
667 }
668
669 // Fill and decode
670 bytesValid[0] = inBufferLength[0];
671
672 INT prevSampleRate = mStreamInfo->sampleRate;
673 INT prevNumChannels = mStreamInfo->numChannels;
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800674 INT prevOutLoudness = mStreamInfo->outputLoudness;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800675
676 aacDecoder_Fill(mAACDecoder,
677 inBuffer,
678 inBufferLength,
679 bytesValid);
680
681 // run DRC check
682 mDrcWrap.submitStreamData(mStreamInfo);
Jean-Michel Triviedf942b2020-01-29 09:59:44 -0800683
684 // apply runtime updates
685 // DRC_PRES_MODE_WRAP_DESIRED_TARGET
686 int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
687 ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
688 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
689
690 // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
691 int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
692 ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
693 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
694
695 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
696 int32_t boostFactor = mIntf->getDrcBoostFactor();
697 ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
698 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
699
700 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
701 int32_t compressMode = mIntf->getDrcCompressMode();
702 ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
703 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
704
705 // DRC_PRES_MODE_WRAP_ENCODER_TARGET
706 int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
707 ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
708 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
709
710 // AAC_UNIDRC_SET_EFFECT
711 int32_t effectType = mIntf->getDrcEffectType();
712 ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
713 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
714
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800715 // AAC_UNIDRC_ALBUM_MODE
716 int32_t albumMode = mIntf->getDrcAlbumMode();
717 ALOGV("AAC decoder using MPEG-D DRC album mode %d", albumMode);
718 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
719
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700720 // AAC_PCM_MAX_OUTPUT_CHANNELS
721 int32_t maxChannelCount = mIntf->getMaxChannelCount();
722 ALOGV("AAC decoder using maximum output channel count %d", maxChannelCount);
723 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, maxChannelCount);
724
Pawin Vongmasa36653902018-11-15 00:10:25 -0800725 mDrcWrap.update();
726
727 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
728 size -= inBufferUsedLength;
729 offset += inBufferUsedLength;
730
731 AAC_DECODER_ERROR decoderErr;
732 do {
733 if (outputDelayRingBufferSpaceLeft() <
734 (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
735 ALOGV("skipping decode: not enough space left in ringbuffer");
736 // discard buffer
737 size = 0;
738 break;
739 }
740
741 int numConsumed = mStreamInfo->numTotalBytes;
742 decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
743 tmpOutBuffer,
744 2048 * MAX_CHANNEL_COUNT,
745 0 /* flags */);
746
747 numConsumed = mStreamInfo->numTotalBytes - numConsumed;
748
749 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
750 break;
751 }
752 inInfo.decodedSizes.push_back(numConsumed);
753
754 if (decoderErr != AAC_DEC_OK) {
755 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
756 }
757
758 if (bytesValid[0] != 0) {
759 ALOGE("bytesValid[0] != 0 should never happen");
760 mSignalledError = true;
761 work->result = C2_CORRUPTED;
762 return;
763 }
764
765 size_t numOutBytes =
766 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
767
768 if (decoderErr == AAC_DEC_OK) {
769 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
770 mStreamInfo->frameSize * mStreamInfo->numChannels)) {
771 mSignalledError = true;
772 work->result = C2_CORRUPTED;
773 return;
774 }
775 } else {
776 ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
777
778 memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
779
780 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
781 mStreamInfo->frameSize * mStreamInfo->numChannels)) {
782 mSignalledError = true;
783 work->result = C2_CORRUPTED;
784 return;
785 }
786
787 // Discard input buffer.
788 size = 0;
789
790 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
791
792 // After an error, replace bufferSize with the sum of the
793 // decodedSizes to resynchronize the in/out lists.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800794 inInfo.bufferSize = std::accumulate(
795 inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
796
797 // fall through
798 }
799
800 /*
801 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
802 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
803 * rate system and the sampling rate in the final output is actually
804 * doubled compared with the core AAC decoder sampling rate.
805 *
806 * Explicit signalling is done by explicitly defining SBR audio object
807 * type in the bitstream. Implicit signalling is done by embedding
808 * SBR content in AAC extension payload specific to SBR, and hence
809 * requires an AAC decoder to perform pre-checks on actual audio frames.
810 *
811 * Thus, we could not say for sure whether a stream is
812 * AAC+/eAAC+ until the first data frame is decoded.
813 */
814 if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
815 // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
816 ALOGD("Invalid AAC stream");
817 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
818 // mSignalledError = true;
819 // }
820 } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
821 (mStreamInfo->numChannels != prevNumChannels)) {
822 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
823 prevSampleRate, mStreamInfo->sampleRate,
824 prevNumChannels, mStreamInfo->numChannels);
825
826 C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
827 C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
828 std::vector<std::unique_ptr<C2SettingResult>> failures;
829 c2_status_t err = mIntf->config(
830 { &sampleRateInfo, &channelCountInfo },
831 C2_MAY_BLOCK,
832 &failures);
833 if (err == OK) {
834 // TODO: this does not handle the case where the values are
835 // altered during config.
836 C2FrameData &output = work->worklets.front()->output;
837 output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
838 output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
839 } else {
840 ALOGE("Config Update failed");
841 mSignalledError = true;
842 work->result = C2_CORRUPTED;
843 return;
844 }
845 }
846 ALOGV("size = %zu", size);
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800847
848 if (mStreamInfo->outputLoudness != prevOutLoudness) {
849 C2StreamDrcOutputLoudnessTuning::output
850 drcOutLoudness(0u, (float) (mStreamInfo->outputLoudness*-0.25));
851
852 std::vector<std::unique_ptr<C2SettingResult>> failures;
853 c2_status_t err = mIntf->config(
854 { &drcOutLoudness },
855 C2_MAY_BLOCK,
856 &failures);
857 if (err == OK) {
858 work->worklets.front()->output.configUpdate.push_back(
859 C2Param::Copy(drcOutLoudness));
860 } else {
861 ALOGE("Getting output loudness failed");
862 }
863 }
Jean-Michel Trivi52ea7282020-06-05 09:54:38 -0700864
865 // update config with values used for decoding:
866 // Album mode, target reference level, DRC effect type, DRC attenuation and boost
867 // factor, DRC compression mode, encoder target level and max channel count
868 // with input values as they were not modified by decoder
869
870 C2StreamDrcAttenuationFactorTuning::input currentAttenuationFactor(0u,
871 (C2FloatValue) (attenuationFactor/127.));
872 work->worklets.front()->output.configUpdate.push_back(
873 C2Param::Copy(currentAttenuationFactor));
874
875 C2StreamDrcBoostFactorTuning::input currentBoostFactor(0u,
876 (C2FloatValue) (boostFactor/127.));
877 work->worklets.front()->output.configUpdate.push_back(
878 C2Param::Copy(currentBoostFactor));
879
880 C2StreamDrcCompressionModeTuning::input currentCompressMode(0u,
881 (C2Config::drc_compression_mode_t) compressMode);
882 work->worklets.front()->output.configUpdate.push_back(
883 C2Param::Copy(currentCompressMode));
884
885 C2StreamDrcEncodedTargetLevelTuning::input currentEncodedTargetLevel(0u,
886 (C2FloatValue) (encTargetLevel*-0.25));
887 work->worklets.front()->output.configUpdate.push_back(
888 C2Param::Copy(currentEncodedTargetLevel));
889
890 C2StreamDrcAlbumModeTuning::input currentAlbumMode(0u,
891 (C2Config::drc_album_mode_t) albumMode);
892 work->worklets.front()->output.configUpdate.push_back(
893 C2Param::Copy(currentAlbumMode));
894
895 C2StreamDrcTargetReferenceLevelTuning::input currentTargetRefLevel(0u,
896 (float) (targetRefLevel*-0.25));
897 work->worklets.front()->output.configUpdate.push_back(
898 C2Param::Copy(currentTargetRefLevel));
899
900 C2StreamDrcEffectTypeTuning::input currentEffectype(0u,
901 (C2Config::drc_effect_type_t) effectType);
902 work->worklets.front()->output.configUpdate.push_back(
903 C2Param::Copy(currentEffectype));
904
905 C2StreamMaxChannelCountInfo::input currentMaxChannelCnt(0u, maxChannelCount);
906 work->worklets.front()->output.configUpdate.push_back(
907 C2Param::Copy(currentMaxChannelCnt));
908
Pawin Vongmasa36653902018-11-15 00:10:25 -0800909 } while (decoderErr == AAC_DEC_OK);
910 }
911
912 int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
913
914 mBuffersInfo.push_back(std::move(inInfo));
915 work->workletsProcessed = 0u;
916 if (!eos && mOutputDelayCompensated < outputDelay) {
917 // discard outputDelay at the beginning
918 int32_t toCompensate = outputDelay - mOutputDelayCompensated;
919 int32_t discard = outputDelayRingBufferSamplesAvailable();
920 if (discard > toCompensate) {
921 discard = toCompensate;
922 }
923 int32_t discarded = outputDelayRingBufferGetSamples(nullptr, discard);
924 mOutputDelayCompensated += discarded;
925 return;
926 }
927
928 if (eos) {
929 drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
930 } else {
931 drainRingBuffer(work, pool, false /* not EOS */);
932 }
933}
934
935c2_status_t C2SoftAacDec::drainInternal(
936 uint32_t drainMode,
937 const std::shared_ptr<C2BlockPool> &pool,
938 const std::unique_ptr<C2Work> &work) {
939 if (drainMode == NO_DRAIN) {
940 ALOGW("drain with NO_DRAIN: no-op");
941 return C2_OK;
942 }
943 if (drainMode == DRAIN_CHAIN) {
944 ALOGW("DRAIN_CHAIN not supported");
945 return C2_OMITTED;
946 }
947
948 bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
949
950 drainDecoder();
951 drainRingBuffer(work, pool, eos);
952
953 if (eos) {
954 auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
955 work->worklets.front()->output.flags = work->input.flags;
956 work->worklets.front()->output.buffers.clear();
957 work->worklets.front()->output.ordinal = work->input.ordinal;
958 work->workletsProcessed = 1u;
959 };
960 while (mBuffersInfo.size() > 1u) {
961 finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
962 mBuffersInfo.pop_front();
963 }
964 if (work && work->workletsProcessed == 0u) {
965 fillEmptyWork(work);
966 }
967 mBuffersInfo.clear();
968 }
969
970 return C2_OK;
971}
972
973c2_status_t C2SoftAacDec::drain(
974 uint32_t drainMode,
975 const std::shared_ptr<C2BlockPool> &pool) {
976 return drainInternal(drainMode, pool, nullptr);
977}
978
979c2_status_t C2SoftAacDec::onFlush_sm() {
980 drainDecoder();
981 mBuffersInfo.clear();
982
983 int avail;
984 while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
985 if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
986 avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
987 }
988 int32_t ns = outputDelayRingBufferGetSamples(nullptr, avail);
989 if (ns != avail) {
990 ALOGW("not a complete frame of samples available");
991 break;
992 }
993 }
994 mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
995
996 return C2_OK;
997}
998
999void C2SoftAacDec::drainDecoder() {
1000 // flush decoder until outputDelay is compensated
1001 while (mOutputDelayCompensated > 0) {
1002 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
1003 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
1004
1005 // run DRC check
1006 mDrcWrap.submitStreamData(mStreamInfo);
1007 mDrcWrap.update();
1008
1009 AAC_DECODER_ERROR decoderErr =
1010 aacDecoder_DecodeFrame(mAACDecoder,
1011 tmpOutBuffer,
1012 2048 * MAX_CHANNEL_COUNT,
1013 AACDEC_FLUSH);
1014 if (decoderErr != AAC_DEC_OK) {
1015 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
1016 }
1017
1018 int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
1019 if (tmpOutBufferSamples > mOutputDelayCompensated) {
1020 tmpOutBufferSamples = mOutputDelayCompensated;
1021 }
1022 outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
1023
1024 mOutputDelayCompensated -= tmpOutBufferSamples;
1025 }
1026}
1027
1028class C2SoftAacDecFactory : public C2ComponentFactory {
1029public:
1030 C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
1031 GetCodec2PlatformComponentStore()->getParamReflector())) {
1032 }
1033
1034 virtual c2_status_t createComponent(
1035 c2_node_id_t id,
1036 std::shared_ptr<C2Component>* const component,
1037 std::function<void(C2Component*)> deleter) override {
1038 *component = std::shared_ptr<C2Component>(
1039 new C2SoftAacDec(COMPONENT_NAME,
1040 id,
1041 std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
1042 deleter);
1043 return C2_OK;
1044 }
1045
1046 virtual c2_status_t createInterface(
1047 c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
1048 std::function<void(C2ComponentInterface*)> deleter) override {
1049 *interface = std::shared_ptr<C2ComponentInterface>(
1050 new SimpleInterface<C2SoftAacDec::IntfImpl>(
1051 COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
1052 deleter);
1053 return C2_OK;
1054 }
1055
1056 virtual ~C2SoftAacDecFactory() override = default;
1057
1058private:
1059 std::shared_ptr<C2ReflectorHelper> mHelper;
1060};
1061
1062} // namespace android
1063
1064extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
1065 ALOGV("in %s", __func__);
1066 return new ::android::C2SoftAacDecFactory();
1067}
1068
1069extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
1070 ALOGV("in %s", __func__);
1071 delete factory;
1072}