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