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