C2SoftAacDec.cpp revision 277b7295f317c6597fadb116b6aee5ca3be106c1
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 "C2SoftAac" 19#include <utils/Log.h> 20 21#include "C2SoftAac.h" 22 23#include <C2PlatformSupport.h> 24#include <SimpleInterfaceCommon.h> 25 26#include <cutils/properties.h> 27#include <media/stagefright/foundation/ADebug.h> 28#include <media/stagefright/foundation/MediaDefs.h> 29#include <media/stagefright/foundation/hexdump.h> 30#include <media/stagefright/MediaErrors.h> 31#include <utils/misc.h> 32 33#include <inttypes.h> 34#include <math.h> 35#include <numeric> 36 37#define FILEREAD_MAX_LAYERS 2 38 39#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */ 40#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */ 41#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */ 42#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */ 43#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) */ 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 52namespace android { 53 54class C2SoftAac::IntfImpl : public C2InterfaceHelper { 55public: 56 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper) 57 : C2InterfaceHelper(helper) { 58 59 setDerivedInstance(this); 60 61 addParameter( 62 DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING) 63 .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed)) 64 .build()); 65 66 addParameter( 67 DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING) 68 .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio)) 69 .build()); 70 71 addParameter( 72 DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING) 73 .withConstValue(AllocSharedString<C2PortMimeConfig::input>( 74 MEDIA_MIMETYPE_AUDIO_AAC)) 75 .build()); 76 77 addParameter( 78 DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING) 79 .withConstValue(AllocSharedString<C2PortMimeConfig::output>( 80 MEDIA_MIMETYPE_AUDIO_RAW)) 81 .build()); 82 83 addParameter( 84 DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING) 85 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100)) 86 .withFields({C2F(mSampleRate, value).oneOf({ 87 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 88 })}) 89 .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps)) 90 .build()); 91 92 addParameter( 93 DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING) 94 .withDefault(new C2StreamChannelCountInfo::output(0u, 1)) 95 .withFields({C2F(mChannelCount, value).inRange(1, 8)}) 96 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps) 97 .build()); 98 99 addParameter( 100 DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING) 101 .withDefault(new C2BitrateTuning::input(0u, 64000)) 102 .withFields({C2F(mBitrate, value).inRange(8000, 960000)}) 103 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps) 104 .build()); 105 106 addParameter( 107 DefineParam(mAacFormat, C2_NAME_STREAM_BITRATE_SETTING) 108 .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw)) 109 .withFields({C2F(mAacFormat, value).oneOf({ 110 C2AacStreamFormatRaw, C2AacStreamFormatAdts 111 })}) 112 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps) 113 .build()); 114 } 115 116 bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; } 117 118private: 119 std::shared_ptr<C2StreamFormatConfig::input> mInputFormat; 120 std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat; 121 std::shared_ptr<C2PortMimeConfig::input> mInputMediaType; 122 std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType; 123 std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate; 124 std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount; 125 std::shared_ptr<C2BitrateTuning::input> mBitrate; 126 127 std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat; 128}; 129 130constexpr char COMPONENT_NAME[] = "c2.google.aac.decoder"; 131 132C2SoftAac::C2SoftAac( 133 const char *name, 134 c2_node_id_t id, 135 const std::shared_ptr<IntfImpl> &intfImpl) 136 : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)), 137 mAACDecoder(NULL), 138 mStreamInfo(NULL), 139 mSignalledError(false), 140 mOutputDelayRingBuffer(NULL) { 141} 142 143C2SoftAac::~C2SoftAac() { 144 onRelease(); 145} 146 147c2_status_t C2SoftAac::onInit() { 148 status_t err = initDecoder(); 149 return err == OK ? C2_OK : C2_CORRUPTED; 150} 151 152c2_status_t C2SoftAac::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 170void C2SoftAac::onReset() { 171 (void)onStop(); 172} 173 174void C2SoftAac::onRelease() { 175 if (mAACDecoder) { 176 aacDecoder_Close(mAACDecoder); 177 mAACDecoder = NULL; 178 } 179 if (mOutputDelayRingBuffer) { 180 delete[] mOutputDelayRingBuffer; 181 mOutputDelayRingBuffer = NULL; 182 } 183} 184 185status_t C2SoftAac::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 269bool C2SoftAac::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 C2SoftAac::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 303int32_t C2SoftAac::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 C2SoftAac::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 341int32_t C2SoftAac::outputDelayRingBufferSamplesAvailable() { 342 return mOutputDelayRingBufferFilled; 343} 344 345int32_t C2SoftAac::outputDelayRingBufferSpaceLeft() { 346 return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable(); 347} 348 349void C2SoftAac::drainRingBuffer( 350 const std::unique_ptr<C2Work> &work, 351 const std::shared_ptr<C2BlockPool> &pool, 352 std::vector<std::unique_ptr<C2Param>> *configUpdate, 353 bool eos) { 354 while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable() 355 >= mStreamInfo->frameSize * mStreamInfo->numChannels) { 356 Info &outInfo = mBuffersInfo.front(); 357 ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex); 358 int samplesize = mStreamInfo->numChannels * sizeof(int16_t); 359 360 int available = outputDelayRingBufferSamplesAvailable(); 361 int numFrames = outInfo.decodedSizes.size(); 362 int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels); 363 if (available < numSamples) { 364 if (eos) { 365 numSamples = available; 366 } else { 367 break; 368 } 369 } 370 ALOGV("%d samples available (%d), or %d frames", 371 numSamples, available, numFrames); 372 ALOGV("getting %d from ringbuffer", numSamples); 373 374 std::shared_ptr<C2LinearBlock> block; 375 std::function<void(const std::unique_ptr<C2Work>&)> fillWork = 376 [&block, numSamples, pool, configUpdate, this]() 377 -> std::function<void(const std::unique_ptr<C2Work>&)> { 378 auto fillEmptyWork = [configUpdate]( 379 const std::unique_ptr<C2Work> &work, c2_status_t err) { 380 work->result = err; 381 C2FrameData &output = work->worklets.front()->output; 382 output.flags = work->input.flags; 383 output.buffers.clear(); 384 output.ordinal = work->input.ordinal; 385 while (configUpdate && !configUpdate->empty()) { 386 output.configUpdate.push_back(std::move(configUpdate->front())); 387 } 388 389 work->workletsProcessed = 1u; 390 }; 391 392 using namespace std::placeholders; 393 if (numSamples == 0) { 394 return std::bind(fillEmptyWork, _1, C2_OK); 395 } 396 397 // TODO: error handling, proper usage, etc. 398 C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 399 c2_status_t err = pool->fetchLinearBlock( 400 numSamples * sizeof(int16_t), usage, &block); 401 if (err != C2_OK) { 402 ALOGD("failed to fetch a linear block (%d)", err); 403 mSignalledError = true; 404 return std::bind(fillEmptyWork, _1, C2_NO_MEMORY); 405 } 406 C2WriteView wView = block->map().get(); 407 // TODO 408 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data()); 409 int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples); 410 if (ns != numSamples) { 411 ALOGE("not a complete frame of samples available"); 412 mSignalledError = true; 413 return std::bind(fillEmptyWork, _1, C2_CORRUPTED); 414 } 415 return [buffer = createLinearBuffer(block), configUpdate]( 416 const std::unique_ptr<C2Work> &work) { 417 work->result = C2_OK; 418 C2FrameData &output = work->worklets.front()->output; 419 output.flags = work->input.flags; 420 output.buffers.clear(); 421 output.buffers.push_back(buffer); 422 output.ordinal = work->input.ordinal; 423 while (configUpdate && !configUpdate->empty()) { 424 output.configUpdate.push_back(std::move(configUpdate->front())); 425 } 426 work->workletsProcessed = 1u; 427 }; 428 }(); 429 430 if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) { 431 fillWork(work); 432 } else { 433 finish(outInfo.frameIndex, fillWork); 434 } 435 436 ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0); 437 mBuffersInfo.pop_front(); 438 } 439} 440 441void C2SoftAac::process( 442 const std::unique_ptr<C2Work> &work, 443 const std::shared_ptr<C2BlockPool> &pool) { 444 work->workletsProcessed = 0u; 445 work->result = C2_OK; 446 work->worklets.front()->output.configUpdate.clear(); 447 if (mSignalledError) { 448 return; 449 } 450 451 UCHAR* inBuffer[FILEREAD_MAX_LAYERS]; 452 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0}; 453 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0}; 454 455 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 456 C2ReadView view = work->input.buffers[0]->data().linearBlocks().front().map().get(); 457 size_t offset = 0u; 458 size_t size = view.capacity(); 459 460 bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0; 461 bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0; 462 463 //TODO 464#if 0 465 if (mInputBufferCount == 0 && !codecConfig) { 466 ALOGW("first buffer should have FLAG_CODEC_CONFIG set"); 467 codecConfig = true; 468 } 469#endif 470 if (codecConfig) { 471 // const_cast because of libAACdec method signature. 472 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset); 473 inBufferLength[0] = size; 474 475 AAC_DECODER_ERROR decoderErr = 476 aacDecoder_ConfigRaw(mAACDecoder, 477 inBuffer, 478 inBufferLength); 479 480 if (decoderErr != AAC_DEC_OK) { 481 ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr); 482 mSignalledError = true; 483 // TODO: error 484 return; 485 } 486 487 work->worklets.front()->output.ordinal = work->input.ordinal; 488 work->worklets.front()->output.buffers.clear(); 489 490 return; 491 } 492 493 std::vector<std::unique_ptr<C2Param>> configUpdate{}; 494 Info inInfo; 495 inInfo.frameIndex = work->input.ordinal.frameIndex.peeku(); 496 inInfo.timestamp = work->input.ordinal.timestamp.peeku(); 497 inInfo.bufferSize = size; 498 inInfo.decodedSizes.clear(); 499 while (size > 0u) { 500 ALOGV("size = %zu", size); 501 if (mIntf->isAdts()) { 502 size_t adtsHeaderSize = 0; 503 // skip 30 bits, aac_frame_length follows. 504 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 505 506 const uint8_t *adtsHeader = view.data() + offset; 507 508 bool signalError = false; 509 if (size < 7) { 510 ALOGE("Audio data too short to contain even the ADTS header. " 511 "Got %zu bytes.", size); 512 hexdump(adtsHeader, size); 513 signalError = true; 514 } else { 515 bool protectionAbsent = (adtsHeader[1] & 1); 516 517 unsigned aac_frame_length = 518 ((adtsHeader[3] & 3) << 11) 519 | (adtsHeader[4] << 3) 520 | (adtsHeader[5] >> 5); 521 522 if (size < aac_frame_length) { 523 ALOGE("Not enough audio data for the complete frame. " 524 "Got %zu bytes, frame size according to the ADTS " 525 "header is %u bytes.", 526 size, aac_frame_length); 527 hexdump(adtsHeader, size); 528 signalError = true; 529 } else { 530 adtsHeaderSize = (protectionAbsent ? 7 : 9); 531 if (aac_frame_length < adtsHeaderSize) { 532 signalError = true; 533 } else { 534 // const_cast because of libAACdec method signature. 535 inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize); 536 inBufferLength[0] = aac_frame_length - adtsHeaderSize; 537 538 offset += adtsHeaderSize; 539 size -= adtsHeaderSize; 540 } 541 } 542 } 543 544 if (signalError) { 545 mSignalledError = true; 546 // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL); 547 return; 548 } 549 } else { 550 // const_cast because of libAACdec method signature. 551 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset); 552 inBufferLength[0] = size; 553 } 554 555 // Fill and decode 556 bytesValid[0] = inBufferLength[0]; 557 558 INT prevSampleRate = mStreamInfo->sampleRate; 559 INT prevNumChannels = mStreamInfo->numChannels; 560 561 aacDecoder_Fill(mAACDecoder, 562 inBuffer, 563 inBufferLength, 564 bytesValid); 565 566 // run DRC check 567 mDrcWrap.submitStreamData(mStreamInfo); 568 mDrcWrap.update(); 569 570 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0]; 571 size -= inBufferUsedLength; 572 offset += inBufferUsedLength; 573 574 AAC_DECODER_ERROR decoderErr; 575 do { 576 if (outputDelayRingBufferSpaceLeft() < 577 (mStreamInfo->frameSize * mStreamInfo->numChannels)) { 578 ALOGV("skipping decode: not enough space left in ringbuffer"); 579 break; 580 } 581 582 int numConsumed = mStreamInfo->numTotalBytes; 583 decoderErr = aacDecoder_DecodeFrame(mAACDecoder, 584 tmpOutBuffer, 585 2048 * MAX_CHANNEL_COUNT, 586 0 /* flags */); 587 588 numConsumed = mStreamInfo->numTotalBytes - numConsumed; 589 590 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) { 591 break; 592 } 593 inInfo.decodedSizes.push_back(numConsumed); 594 595 if (decoderErr != AAC_DEC_OK) { 596 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 597 } 598 599 if (bytesValid[0] != 0) { 600 ALOGE("bytesValid[0] != 0 should never happen"); 601 mSignalledError = true; 602 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 603 return; 604 } 605 606 size_t numOutBytes = 607 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels; 608 609 if (decoderErr == AAC_DEC_OK) { 610 if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 611 mStreamInfo->frameSize * mStreamInfo->numChannels)) { 612 mSignalledError = true; 613 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 614 return; 615 } 616 } else { 617 ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr); 618 619 memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow 620 621 if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 622 mStreamInfo->frameSize * mStreamInfo->numChannels)) { 623 mSignalledError = true; 624 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 625 return; 626 } 627 628 // Discard input buffer. 629 size = 0; 630 631 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); 632 633 // After an error, replace bufferSize with the sum of the 634 // decodedSizes to resynchronize the in/out lists. 635 inInfo.decodedSizes.pop_back(); 636 inInfo.bufferSize = std::accumulate( 637 inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0); 638 639 // fall through 640 } 641 642 /* 643 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly 644 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual 645 * rate system and the sampling rate in the final output is actually 646 * doubled compared with the core AAC decoder sampling rate. 647 * 648 * Explicit signalling is done by explicitly defining SBR audio object 649 * type in the bitstream. Implicit signalling is done by embedding 650 * SBR content in AAC extension payload specific to SBR, and hence 651 * requires an AAC decoder to perform pre-checks on actual audio frames. 652 * 653 * Thus, we could not say for sure whether a stream is 654 * AAC+/eAAC+ until the first data frame is decoded. 655 */ 656 if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) { 657 // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) { 658 ALOGD("Invalid AAC stream"); 659 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 660 // mSignalledError = true; 661 // } 662 } else if ((mStreamInfo->sampleRate != prevSampleRate) || 663 (mStreamInfo->numChannels != prevNumChannels)) { 664 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels", 665 prevSampleRate, mStreamInfo->sampleRate, 666 prevNumChannels, mStreamInfo->numChannels); 667 668 C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); 669 C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); 670 std::vector<std::unique_ptr<C2SettingResult>> failures; 671 c2_status_t err = mIntf->config( 672 { &sampleRateInfo, &channelCountInfo }, 673 C2_MAY_BLOCK, 674 &failures); 675 if (err == OK) { 676 // TODO: this does not handle the case where the values are 677 // altered during config. 678 configUpdate.push_back(C2Param::Copy(sampleRateInfo)); 679 configUpdate.push_back(C2Param::Copy(channelCountInfo)); 680 } 681 // TODO: error handling 682 } 683 ALOGV("size = %zu", size); 684 } while (decoderErr == AAC_DEC_OK); 685 } 686 687 int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels; 688 689 mBuffersInfo.push_back(std::move(inInfo)); 690 691 if (!eos && mOutputDelayCompensated < outputDelay) { 692 // discard outputDelay at the beginning 693 int32_t toCompensate = outputDelay - mOutputDelayCompensated; 694 int32_t discard = outputDelayRingBufferSamplesAvailable(); 695 if (discard > toCompensate) { 696 discard = toCompensate; 697 } 698 int32_t discarded = outputDelayRingBufferGetSamples(0, discard); 699 mOutputDelayCompensated += discarded; 700 return; 701 } 702 703 if (eos) { 704 drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work, &configUpdate); 705 } else { 706 drainRingBuffer(work, pool, &configUpdate, false /* not EOS */); 707 } 708} 709 710c2_status_t C2SoftAac::drainInternal( 711 uint32_t drainMode, 712 const std::shared_ptr<C2BlockPool> &pool, 713 const std::unique_ptr<C2Work> &work, 714 std::vector<std::unique_ptr<C2Param>> *configUpdate) { 715 if (drainMode == NO_DRAIN) { 716 ALOGW("drain with NO_DRAIN: no-op"); 717 return C2_OK; 718 } 719 if (drainMode == DRAIN_CHAIN) { 720 ALOGW("DRAIN_CHAIN not supported"); 721 return C2_OMITTED; 722 } 723 724 bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS); 725 726 drainDecoder(); 727 drainRingBuffer(work, pool, configUpdate, eos); 728 729 if (eos) { 730 auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) { 731 work->worklets.front()->output.flags = work->input.flags; 732 work->worklets.front()->output.buffers.clear(); 733 work->worklets.front()->output.ordinal = work->input.ordinal; 734 work->workletsProcessed = 1u; 735 }; 736 while (mBuffersInfo.size() > 1u) { 737 finish(mBuffersInfo.front().frameIndex, fillEmptyWork); 738 mBuffersInfo.pop_front(); 739 } 740 if (work->workletsProcessed == 0u) { 741 fillEmptyWork(work); 742 } 743 mBuffersInfo.clear(); 744 } 745 746 return C2_OK; 747} 748 749c2_status_t C2SoftAac::drain( 750 uint32_t drainMode, 751 const std::shared_ptr<C2BlockPool> &pool) { 752 return drainInternal(drainMode, pool, nullptr); 753} 754 755c2_status_t C2SoftAac::onFlush_sm() { 756 drainDecoder(); 757 mBuffersInfo.clear(); 758 759 int avail; 760 while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) { 761 if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) { 762 avail = mStreamInfo->frameSize * mStreamInfo->numChannels; 763 } 764 int32_t ns = outputDelayRingBufferGetSamples(0, avail); 765 if (ns != avail) { 766 ALOGW("not a complete frame of samples available"); 767 break; 768 } 769 } 770 mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos; 771 772 return C2_OK; 773} 774 775void C2SoftAac::drainDecoder() { 776 // flush decoder until outputDelay is compensated 777 while (mOutputDelayCompensated > 0) { 778 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC 779 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 780 781 // run DRC check 782 mDrcWrap.submitStreamData(mStreamInfo); 783 mDrcWrap.update(); 784 785 AAC_DECODER_ERROR decoderErr = 786 aacDecoder_DecodeFrame(mAACDecoder, 787 tmpOutBuffer, 788 2048 * MAX_CHANNEL_COUNT, 789 AACDEC_FLUSH); 790 if (decoderErr != AAC_DEC_OK) { 791 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 792 } 793 794 int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels; 795 if (tmpOutBufferSamples > mOutputDelayCompensated) { 796 tmpOutBufferSamples = mOutputDelayCompensated; 797 } 798 outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples); 799 800 mOutputDelayCompensated -= tmpOutBufferSamples; 801 } 802} 803 804class C2SoftAacDecFactory : public C2ComponentFactory { 805public: 806 C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( 807 GetCodec2PlatformComponentStore()->getParamReflector())) { 808 } 809 810 virtual c2_status_t createComponent( 811 c2_node_id_t id, 812 std::shared_ptr<C2Component>* const component, 813 std::function<void(C2Component*)> deleter) override { 814 *component = std::shared_ptr<C2Component>( 815 new C2SoftAac(COMPONENT_NAME, 816 id, 817 std::make_shared<C2SoftAac::IntfImpl>(mHelper)), 818 deleter); 819 return C2_OK; 820 } 821 822 virtual c2_status_t createInterface( 823 c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, 824 std::function<void(C2ComponentInterface*)> deleter) override { 825 *interface = std::shared_ptr<C2ComponentInterface>( 826 new SimpleInterface<C2SoftAac::IntfImpl>( 827 COMPONENT_NAME, id, std::make_shared<C2SoftAac::IntfImpl>(mHelper)), 828 deleter); 829 return C2_OK; 830 } 831 832 virtual ~C2SoftAacDecFactory() override = default; 833 834private: 835 std::shared_ptr<C2ReflectorHelper> mHelper; 836}; 837 838} // namespace android 839 840extern "C" ::C2ComponentFactory* CreateCodec2Factory() { 841 ALOGV("in %s", __func__); 842 return new ::android::C2SoftAacDecFactory(); 843} 844 845extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) { 846 ALOGV("in %s", __func__); 847 delete factory; 848} 849