1 /*
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 */
43 #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) */
44 #define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
45 // names of properties that can be used to override the default DRC settings
46 #define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
47 #define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
48 #define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
49 #define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
50 #define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
51 #define PROP_DRC_OVERRIDE_EFFECT "ro.aac_drc_effect_type"
52
53 namespace android {
54
55 class C2SoftAacDec::IntfImpl : public C2InterfaceHelper {
56 public:
IntfImpl(const std::shared_ptr<C2ReflectorHelper> & helper)57 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
58 : C2InterfaceHelper(helper) {
59
60 setDerivedInstance(this);
61
62 addParameter(
63 DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
64 .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
65 .build());
66
67 addParameter(
68 DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
69 .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
70 .build());
71
72 addParameter(
73 DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
74 .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
75 MEDIA_MIMETYPE_AUDIO_AAC))
76 .build());
77
78 addParameter(
79 DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
80 .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
81 MEDIA_MIMETYPE_AUDIO_RAW))
82 .build());
83
84 addParameter(
85 DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
86 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
87 .withFields({C2F(mSampleRate, value).oneOf({
88 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
89 })})
90 .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
91 .build());
92
93 addParameter(
94 DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
95 .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
96 .withFields({C2F(mChannelCount, value).inRange(1, 8)})
97 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
98 .build());
99
100 addParameter(
101 DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
102 .withDefault(new C2BitrateTuning::input(0u, 64000))
103 .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
104 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
105 .build());
106
107 addParameter(
108 DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
109 .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
110 .build());
111
112 addParameter(
113 DefineParam(mAacFormat, C2_NAME_STREAM_AAC_FORMAT_SETTING)
114 .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
115 .withFields({C2F(mAacFormat, value).oneOf({
116 C2AacStreamFormatRaw, C2AacStreamFormatAdts
117 })})
118 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
119 .build());
120
121 addParameter(
122 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
123 .withDefault(new C2StreamProfileLevelInfo::input(0u,
124 C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
125 .withFields({
126 C2F(mProfileLevel, profile).oneOf({
127 C2Config::PROFILE_AAC_LC,
128 C2Config::PROFILE_AAC_HE,
129 C2Config::PROFILE_AAC_HE_PS,
130 C2Config::PROFILE_AAC_LD,
131 C2Config::PROFILE_AAC_ELD,
132 C2Config::PROFILE_AAC_ER_SCALABLE,
133 C2Config::PROFILE_AAC_XHE}),
134 C2F(mProfileLevel, level).oneOf({
135 C2Config::LEVEL_UNUSED
136 })
137 })
138 .withSetter(ProfileLevelSetter)
139 .build());
140
141 addParameter(
142 DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
143 .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
144 .withFields({
145 C2F(mDrcCompressMode, value).oneOf({
146 C2Config::DRC_COMPRESSION_ODM_DEFAULT,
147 C2Config::DRC_COMPRESSION_NONE,
148 C2Config::DRC_COMPRESSION_LIGHT,
149 C2Config::DRC_COMPRESSION_HEAVY})
150 })
151 .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
152 .build());
153
154 addParameter(
155 DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
156 .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
157 .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
158 .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
159 .build());
160
161 addParameter(
162 DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
163 .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
164 .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
165 .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
166 .build());
167
168 addParameter(
169 DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
170 .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
171 .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
172 .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
173 .build());
174
175 addParameter(
176 DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
177 .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
178 .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
179 .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
180 .build());
181
182 addParameter(
183 DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
184 .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
185 .withFields({
186 C2F(mDrcEffectType, value).oneOf({
187 C2Config::DRC_EFFECT_ODM_DEFAULT,
188 C2Config::DRC_EFFECT_OFF,
189 C2Config::DRC_EFFECT_NONE,
190 C2Config::DRC_EFFECT_LATE_NIGHT,
191 C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
192 C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
193 C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
194 C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
195 C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
196 })
197 .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
198 .build());
199 }
200
isAdts() const201 bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
ProfileLevelSetter(bool mayBlock,C2P<C2StreamProfileLevelInfo::input> & me)202 static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
203 (void)mayBlock;
204 (void)me; // TODO: validate
205 return C2R::Ok();
206 }
getDrcCompressMode() const207 int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
getDrcTargetRefLevel() const208 int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
getDrcEncTargetLevel() const209 int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
getDrcBoostFactor() const210 int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
getDrcAttenuationFactor() const211 int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
getDrcEffectType() const212 int32_t getDrcEffectType() const { return mDrcEffectType->value; }
213
214 private:
215 std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
216 std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
217 std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
218 std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
219 std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
220 std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
221 std::shared_ptr<C2BitrateTuning::input> mBitrate;
222 std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
223 std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
224 std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
225 std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
226 std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
227 std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
228 std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
229 std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
230 std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
231 // TODO Add : C2StreamAacSbrModeTuning
232 };
233
234 constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
235
C2SoftAacDec(const char * name,c2_node_id_t id,const std::shared_ptr<IntfImpl> & intfImpl)236 C2SoftAacDec::C2SoftAacDec(
237 const char *name,
238 c2_node_id_t id,
239 const std::shared_ptr<IntfImpl> &intfImpl)
240 : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
241 mIntf(intfImpl),
242 mAACDecoder(nullptr),
243 mStreamInfo(nullptr),
244 mSignalledError(false),
245 mOutputDelayRingBuffer(nullptr) {
246 }
247
~C2SoftAacDec()248 C2SoftAacDec::~C2SoftAacDec() {
249 onRelease();
250 }
251
onInit()252 c2_status_t C2SoftAacDec::onInit() {
253 status_t err = initDecoder();
254 return err == OK ? C2_OK : C2_CORRUPTED;
255 }
256
onStop()257 c2_status_t C2SoftAacDec::onStop() {
258 drainDecoder();
259 // reset the "configured" state
260 mOutputDelayCompensated = 0;
261 mOutputDelayRingBufferWritePos = 0;
262 mOutputDelayRingBufferReadPos = 0;
263 mOutputDelayRingBufferFilled = 0;
264 mBuffersInfo.clear();
265
266 // To make the codec behave the same before and after a reset, we need to invalidate the
267 // streaminfo struct. This does that:
268 mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
269
270 mSignalledError = false;
271
272 return C2_OK;
273 }
274
onReset()275 void C2SoftAacDec::onReset() {
276 (void)onStop();
277 }
278
onRelease()279 void C2SoftAacDec::onRelease() {
280 if (mAACDecoder) {
281 aacDecoder_Close(mAACDecoder);
282 mAACDecoder = nullptr;
283 }
284 if (mOutputDelayRingBuffer) {
285 delete[] mOutputDelayRingBuffer;
286 mOutputDelayRingBuffer = nullptr;
287 }
288 }
289
initDecoder()290 status_t C2SoftAacDec::initDecoder() {
291 ALOGV("initDecoder()");
292 status_t status = UNKNOWN_ERROR;
293 mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
294 if (mAACDecoder != nullptr) {
295 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
296 if (mStreamInfo != nullptr) {
297 status = OK;
298 }
299 }
300
301 mOutputDelayCompensated = 0;
302 mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
303 mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
304 mOutputDelayRingBufferWritePos = 0;
305 mOutputDelayRingBufferReadPos = 0;
306 mOutputDelayRingBufferFilled = 0;
307
308 if (mAACDecoder == nullptr) {
309 ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
310 }
311
312 //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
313
314 //init DRC wrapper
315 mDrcWrap.setDecoderHandle(mAACDecoder);
316 mDrcWrap.submitStreamData(mStreamInfo);
317
318 // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
319 // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
320
321 // DRC_PRES_MODE_WRAP_DESIRED_TARGET
322 int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
323 ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
324 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
325
326 // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
327
328 int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
329 ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
330 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
331
332 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
333 int32_t boostFactor = mIntf->getDrcBoostFactor();
334 ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
335 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
336
337 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
338 int32_t compressMode = mIntf->getDrcCompressMode();
339 ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
340 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
341
342 // DRC_PRES_MODE_WRAP_ENCODER_TARGET
343 int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
344 ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
345 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
346
347 // AAC_UNIDRC_SET_EFFECT
348 int32_t effectType = mIntf->getDrcEffectType();
349 ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
350 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
351
352 // By default, the decoder creates a 5.1 channel downmix signal.
353 // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
354 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
355
356 return status;
357 }
358
outputDelayRingBufferPutSamples(INT_PCM * samples,int32_t numSamples)359 bool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
360 if (numSamples == 0) {
361 return true;
362 }
363 if (outputDelayRingBufferSpaceLeft() < numSamples) {
364 ALOGE("RING BUFFER WOULD OVERFLOW");
365 return false;
366 }
367 if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
368 && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
369 || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
370 // faster memcopy loop without checks, if the preconditions allow this
371 for (int32_t i = 0; i < numSamples; i++) {
372 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
373 }
374
375 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
376 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
377 }
378 } else {
379 ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
380
381 for (int32_t i = 0; i < numSamples; i++) {
382 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
383 mOutputDelayRingBufferWritePos++;
384 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
385 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
386 }
387 }
388 }
389 mOutputDelayRingBufferFilled += numSamples;
390 return true;
391 }
392
outputDelayRingBufferGetSamples(INT_PCM * samples,int32_t numSamples)393 int32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
394
395 if (numSamples > mOutputDelayRingBufferFilled) {
396 ALOGE("RING BUFFER WOULD UNDERRUN");
397 return -1;
398 }
399
400 if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
401 && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
402 || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
403 // faster memcopy loop without checks, if the preconditions allow this
404 if (samples != nullptr) {
405 for (int32_t i = 0; i < numSamples; i++) {
406 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
407 }
408 } else {
409 mOutputDelayRingBufferReadPos += numSamples;
410 }
411 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
412 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
413 }
414 } else {
415 ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
416
417 for (int32_t i = 0; i < numSamples; i++) {
418 if (samples != nullptr) {
419 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
420 }
421 mOutputDelayRingBufferReadPos++;
422 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
423 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
424 }
425 }
426 }
427 mOutputDelayRingBufferFilled -= numSamples;
428 return numSamples;
429 }
430
outputDelayRingBufferSamplesAvailable()431 int32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
432 return mOutputDelayRingBufferFilled;
433 }
434
outputDelayRingBufferSpaceLeft()435 int32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
436 return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
437 }
438
drainRingBuffer(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool,bool eos)439 void C2SoftAacDec::drainRingBuffer(
440 const std::unique_ptr<C2Work> &work,
441 const std::shared_ptr<C2BlockPool> &pool,
442 bool eos) {
443 while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
444 >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
445 Info &outInfo = mBuffersInfo.front();
446 ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
447 int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
448
449 int available = outputDelayRingBufferSamplesAvailable();
450 int numFrames = outInfo.decodedSizes.size();
451 int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
452 if (available < numSamples) {
453 if (eos) {
454 numSamples = available;
455 } else {
456 break;
457 }
458 }
459 ALOGV("%d samples available (%d), or %d frames",
460 numSamples, available, numFrames);
461 ALOGV("getting %d from ringbuffer", numSamples);
462
463 std::shared_ptr<C2LinearBlock> block;
464 std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
465 [&block, numSamples, pool, this]()
466 -> std::function<void(const std::unique_ptr<C2Work>&)> {
467 auto fillEmptyWork = [](
468 const std::unique_ptr<C2Work> &work, c2_status_t err) {
469 work->result = err;
470 C2FrameData &output = work->worklets.front()->output;
471 output.flags = work->input.flags;
472 output.buffers.clear();
473 output.ordinal = work->input.ordinal;
474
475 work->workletsProcessed = 1u;
476 };
477
478 using namespace std::placeholders;
479 if (numSamples == 0) {
480 return std::bind(fillEmptyWork, _1, C2_OK);
481 }
482
483 // TODO: error handling, proper usage, etc.
484 C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
485 c2_status_t err = pool->fetchLinearBlock(
486 numSamples * sizeof(int16_t), usage, &block);
487 if (err != C2_OK) {
488 ALOGD("failed to fetch a linear block (%d)", err);
489 return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
490 }
491 C2WriteView wView = block->map().get();
492 // TODO
493 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
494 int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
495 if (ns != numSamples) {
496 ALOGE("not a complete frame of samples available");
497 mSignalledError = true;
498 return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
499 }
500 return [buffer = createLinearBuffer(block)](
501 const std::unique_ptr<C2Work> &work) {
502 work->result = C2_OK;
503 C2FrameData &output = work->worklets.front()->output;
504 output.flags = work->input.flags;
505 output.buffers.clear();
506 output.buffers.push_back(buffer);
507 output.ordinal = work->input.ordinal;
508 work->workletsProcessed = 1u;
509 };
510 }();
511
512 if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
513 fillWork(work);
514 } else {
515 finish(outInfo.frameIndex, fillWork);
516 }
517
518 ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
519 mBuffersInfo.pop_front();
520 }
521 }
522
process(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool)523 void C2SoftAacDec::process(
524 const std::unique_ptr<C2Work> &work,
525 const std::shared_ptr<C2BlockPool> &pool) {
526 // Initialize output work
527 work->result = C2_OK;
528 work->workletsProcessed = 1u;
529 work->worklets.front()->output.configUpdate.clear();
530 work->worklets.front()->output.flags = work->input.flags;
531
532 if (mSignalledError) {
533 return;
534 }
535
536 UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
537 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
538 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
539
540 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
541 C2ReadView view = mDummyReadView;
542 size_t offset = 0u;
543 size_t size = 0u;
544 if (!work->input.buffers.empty()) {
545 view = work->input.buffers[0]->data().linearBlocks().front().map().get();
546 size = view.capacity();
547 }
548
549 bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
550 bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
551
552 //TODO
553 #if 0
554 if (mInputBufferCount == 0 && !codecConfig) {
555 ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
556 codecConfig = true;
557 }
558 #endif
559 if (codecConfig && size > 0u) {
560 // const_cast because of libAACdec method signature.
561 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
562 inBufferLength[0] = size;
563
564 AAC_DECODER_ERROR decoderErr =
565 aacDecoder_ConfigRaw(mAACDecoder,
566 inBuffer,
567 inBufferLength);
568
569 if (decoderErr != AAC_DEC_OK) {
570 ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
571 mSignalledError = true;
572 work->result = C2_CORRUPTED;
573 return;
574 }
575 work->worklets.front()->output.flags = work->input.flags;
576 work->worklets.front()->output.ordinal = work->input.ordinal;
577 work->worklets.front()->output.buffers.clear();
578 return;
579 }
580
581 Info inInfo;
582 inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
583 inInfo.timestamp = work->input.ordinal.timestamp.peeku();
584 inInfo.bufferSize = size;
585 inInfo.decodedSizes.clear();
586 while (size > 0u) {
587 ALOGV("size = %zu", size);
588 if (mIntf->isAdts()) {
589 size_t adtsHeaderSize = 0;
590 // skip 30 bits, aac_frame_length follows.
591 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
592
593 const uint8_t *adtsHeader = view.data() + offset;
594
595 bool signalError = false;
596 if (size < 7) {
597 ALOGE("Audio data too short to contain even the ADTS header. "
598 "Got %zu bytes.", size);
599 hexdump(adtsHeader, size);
600 signalError = true;
601 } else {
602 bool protectionAbsent = (adtsHeader[1] & 1);
603
604 unsigned aac_frame_length =
605 ((adtsHeader[3] & 3) << 11)
606 | (adtsHeader[4] << 3)
607 | (adtsHeader[5] >> 5);
608
609 if (size < aac_frame_length) {
610 ALOGE("Not enough audio data for the complete frame. "
611 "Got %zu bytes, frame size according to the ADTS "
612 "header is %u bytes.",
613 size, aac_frame_length);
614 hexdump(adtsHeader, size);
615 signalError = true;
616 } else {
617 adtsHeaderSize = (protectionAbsent ? 7 : 9);
618 if (aac_frame_length < adtsHeaderSize) {
619 signalError = true;
620 } else {
621 // const_cast because of libAACdec method signature.
622 inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
623 inBufferLength[0] = aac_frame_length - adtsHeaderSize;
624
625 offset += adtsHeaderSize;
626 size -= adtsHeaderSize;
627 }
628 }
629 }
630
631 if (signalError) {
632 mSignalledError = true;
633 work->result = C2_CORRUPTED;
634 return;
635 }
636 } else {
637 // const_cast because of libAACdec method signature.
638 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
639 inBufferLength[0] = size;
640 }
641
642 // Fill and decode
643 bytesValid[0] = inBufferLength[0];
644
645 INT prevSampleRate = mStreamInfo->sampleRate;
646 INT prevNumChannels = mStreamInfo->numChannels;
647
648 aacDecoder_Fill(mAACDecoder,
649 inBuffer,
650 inBufferLength,
651 bytesValid);
652
653 // run DRC check
654 mDrcWrap.submitStreamData(mStreamInfo);
655 mDrcWrap.update();
656
657 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
658 size -= inBufferUsedLength;
659 offset += inBufferUsedLength;
660
661 AAC_DECODER_ERROR decoderErr;
662 do {
663 if (outputDelayRingBufferSpaceLeft() <
664 (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
665 ALOGV("skipping decode: not enough space left in ringbuffer");
666 // discard buffer
667 size = 0;
668 break;
669 }
670
671 int numConsumed = mStreamInfo->numTotalBytes;
672 decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
673 tmpOutBuffer,
674 2048 * MAX_CHANNEL_COUNT,
675 0 /* flags */);
676
677 numConsumed = mStreamInfo->numTotalBytes - numConsumed;
678
679 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
680 break;
681 }
682 inInfo.decodedSizes.push_back(numConsumed);
683
684 if (decoderErr != AAC_DEC_OK) {
685 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
686 }
687
688 if (bytesValid[0] != 0) {
689 ALOGE("bytesValid[0] != 0 should never happen");
690 mSignalledError = true;
691 work->result = C2_CORRUPTED;
692 return;
693 }
694
695 size_t numOutBytes =
696 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
697
698 if (decoderErr == AAC_DEC_OK) {
699 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
700 mStreamInfo->frameSize * mStreamInfo->numChannels)) {
701 mSignalledError = true;
702 work->result = C2_CORRUPTED;
703 return;
704 }
705 } else {
706 ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
707
708 memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
709
710 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
711 mStreamInfo->frameSize * mStreamInfo->numChannels)) {
712 mSignalledError = true;
713 work->result = C2_CORRUPTED;
714 return;
715 }
716
717 // Discard input buffer.
718 size = 0;
719
720 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
721
722 // After an error, replace bufferSize with the sum of the
723 // decodedSizes to resynchronize the in/out lists.
724 inInfo.decodedSizes.pop_back();
725 inInfo.bufferSize = std::accumulate(
726 inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
727
728 // fall through
729 }
730
731 /*
732 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
733 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
734 * rate system and the sampling rate in the final output is actually
735 * doubled compared with the core AAC decoder sampling rate.
736 *
737 * Explicit signalling is done by explicitly defining SBR audio object
738 * type in the bitstream. Implicit signalling is done by embedding
739 * SBR content in AAC extension payload specific to SBR, and hence
740 * requires an AAC decoder to perform pre-checks on actual audio frames.
741 *
742 * Thus, we could not say for sure whether a stream is
743 * AAC+/eAAC+ until the first data frame is decoded.
744 */
745 if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
746 // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
747 ALOGD("Invalid AAC stream");
748 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
749 // mSignalledError = true;
750 // }
751 } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
752 (mStreamInfo->numChannels != prevNumChannels)) {
753 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
754 prevSampleRate, mStreamInfo->sampleRate,
755 prevNumChannels, mStreamInfo->numChannels);
756
757 C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
758 C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
759 std::vector<std::unique_ptr<C2SettingResult>> failures;
760 c2_status_t err = mIntf->config(
761 { &sampleRateInfo, &channelCountInfo },
762 C2_MAY_BLOCK,
763 &failures);
764 if (err == OK) {
765 // TODO: this does not handle the case where the values are
766 // altered during config.
767 C2FrameData &output = work->worklets.front()->output;
768 output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
769 output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
770 } else {
771 ALOGE("Config Update failed");
772 mSignalledError = true;
773 work->result = C2_CORRUPTED;
774 return;
775 }
776 }
777 ALOGV("size = %zu", size);
778 } while (decoderErr == AAC_DEC_OK);
779 }
780
781 int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
782
783 mBuffersInfo.push_back(std::move(inInfo));
784 work->workletsProcessed = 0u;
785 if (!eos && mOutputDelayCompensated < outputDelay) {
786 // discard outputDelay at the beginning
787 int32_t toCompensate = outputDelay - mOutputDelayCompensated;
788 int32_t discard = outputDelayRingBufferSamplesAvailable();
789 if (discard > toCompensate) {
790 discard = toCompensate;
791 }
792 int32_t discarded = outputDelayRingBufferGetSamples(nullptr, discard);
793 mOutputDelayCompensated += discarded;
794 return;
795 }
796
797 if (eos) {
798 drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
799 } else {
800 drainRingBuffer(work, pool, false /* not EOS */);
801 }
802 }
803
drainInternal(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool,const std::unique_ptr<C2Work> & work)804 c2_status_t C2SoftAacDec::drainInternal(
805 uint32_t drainMode,
806 const std::shared_ptr<C2BlockPool> &pool,
807 const std::unique_ptr<C2Work> &work) {
808 if (drainMode == NO_DRAIN) {
809 ALOGW("drain with NO_DRAIN: no-op");
810 return C2_OK;
811 }
812 if (drainMode == DRAIN_CHAIN) {
813 ALOGW("DRAIN_CHAIN not supported");
814 return C2_OMITTED;
815 }
816
817 bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
818
819 drainDecoder();
820 drainRingBuffer(work, pool, eos);
821
822 if (eos) {
823 auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
824 work->worklets.front()->output.flags = work->input.flags;
825 work->worklets.front()->output.buffers.clear();
826 work->worklets.front()->output.ordinal = work->input.ordinal;
827 work->workletsProcessed = 1u;
828 };
829 while (mBuffersInfo.size() > 1u) {
830 finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
831 mBuffersInfo.pop_front();
832 }
833 if (work && work->workletsProcessed == 0u) {
834 fillEmptyWork(work);
835 }
836 mBuffersInfo.clear();
837 }
838
839 return C2_OK;
840 }
841
drain(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool)842 c2_status_t C2SoftAacDec::drain(
843 uint32_t drainMode,
844 const std::shared_ptr<C2BlockPool> &pool) {
845 return drainInternal(drainMode, pool, nullptr);
846 }
847
onFlush_sm()848 c2_status_t C2SoftAacDec::onFlush_sm() {
849 drainDecoder();
850 mBuffersInfo.clear();
851
852 int avail;
853 while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
854 if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
855 avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
856 }
857 int32_t ns = outputDelayRingBufferGetSamples(nullptr, avail);
858 if (ns != avail) {
859 ALOGW("not a complete frame of samples available");
860 break;
861 }
862 }
863 mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
864
865 return C2_OK;
866 }
867
drainDecoder()868 void C2SoftAacDec::drainDecoder() {
869 // flush decoder until outputDelay is compensated
870 while (mOutputDelayCompensated > 0) {
871 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
872 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
873
874 // run DRC check
875 mDrcWrap.submitStreamData(mStreamInfo);
876 mDrcWrap.update();
877
878 AAC_DECODER_ERROR decoderErr =
879 aacDecoder_DecodeFrame(mAACDecoder,
880 tmpOutBuffer,
881 2048 * MAX_CHANNEL_COUNT,
882 AACDEC_FLUSH);
883 if (decoderErr != AAC_DEC_OK) {
884 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
885 }
886
887 int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
888 if (tmpOutBufferSamples > mOutputDelayCompensated) {
889 tmpOutBufferSamples = mOutputDelayCompensated;
890 }
891 outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
892
893 mOutputDelayCompensated -= tmpOutBufferSamples;
894 }
895 }
896
897 class C2SoftAacDecFactory : public C2ComponentFactory {
898 public:
C2SoftAacDecFactory()899 C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
900 GetCodec2PlatformComponentStore()->getParamReflector())) {
901 }
902
createComponent(c2_node_id_t id,std::shared_ptr<C2Component> * const component,std::function<void (C2Component *)> deleter)903 virtual c2_status_t createComponent(
904 c2_node_id_t id,
905 std::shared_ptr<C2Component>* const component,
906 std::function<void(C2Component*)> deleter) override {
907 *component = std::shared_ptr<C2Component>(
908 new C2SoftAacDec(COMPONENT_NAME,
909 id,
910 std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
911 deleter);
912 return C2_OK;
913 }
914
createInterface(c2_node_id_t id,std::shared_ptr<C2ComponentInterface> * const interface,std::function<void (C2ComponentInterface *)> deleter)915 virtual c2_status_t createInterface(
916 c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
917 std::function<void(C2ComponentInterface*)> deleter) override {
918 *interface = std::shared_ptr<C2ComponentInterface>(
919 new SimpleInterface<C2SoftAacDec::IntfImpl>(
920 COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
921 deleter);
922 return C2_OK;
923 }
924
925 virtual ~C2SoftAacDecFactory() override = default;
926
927 private:
928 std::shared_ptr<C2ReflectorHelper> mHelper;
929 };
930
931 } // namespace android
932
CreateCodec2Factory()933 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
934 ALOGV("in %s", __func__);
935 return new ::android::C2SoftAacDecFactory();
936 }
937
DestroyCodec2Factory(::C2ComponentFactory * factory)938 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
939 ALOGV("in %s", __func__);
940 delete factory;
941 }
942