1 /* 2 * Copyright (C) 2018 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 "C2SoftXaacDec" 19 #include <log/log.h> 20 21 #include <inttypes.h> 22 23 #include <cutils/properties.h> 24 #include <media/stagefright/foundation/ADebug.h> 25 #include <media/stagefright/foundation/MediaDefs.h> 26 #include <media/stagefright/foundation/hexdump.h> 27 28 #include <C2PlatformSupport.h> 29 #include <SimpleC2Interface.h> 30 31 #include "C2SoftXaacDec.h" 32 33 #define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */ 34 #define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */ 35 #define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */ 36 #define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */ 37 #define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */ 38 #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) */ 39 #define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */ 40 // names of properties that can be used to override the default DRC settings 41 #define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level" 42 #define PROP_DRC_OVERRIDE_CUT "aac_drc_cut" 43 #define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost" 44 #define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy" 45 #define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level" 46 #define PROP_DRC_OVERRIDE_EFFECT_TYPE "ro.aac_drc_effect_type" 47 48 #define RETURN_IF_FATAL(retval, str) \ 49 if (retval & IA_FATAL_ERROR) { \ 50 ALOGE("Error in %s: Returned: %d", str, retval); \ 51 return retval; \ 52 } else if (retval != IA_NO_ERROR) { \ 53 ALOGW("Warning in %s: Returned: %d", str, retval); \ 54 } 55 56 57 namespace android { 58 59 namespace { 60 61 constexpr char COMPONENT_NAME[] = "c2.android.xaac.decoder"; 62 63 } // namespace 64 65 class C2SoftXaacDec::IntfImpl : public SimpleInterface<void>::BaseParams { 66 public: 67 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper) 68 : SimpleInterface<void>::BaseParams( 69 helper, 70 COMPONENT_NAME, 71 C2Component::KIND_DECODER, 72 C2Component::DOMAIN_AUDIO, 73 MEDIA_MIMETYPE_AUDIO_AAC) { 74 noPrivateBuffers(); 75 noInputReferences(); 76 noOutputReferences(); 77 noInputLatency(); 78 noTimeStretch(); 79 80 addParameter( 81 DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES) 82 .withConstValue(new C2ComponentAttributesSetting( 83 C2Component::ATTRIB_IS_TEMPORAL)) 84 .build()); 85 86 addParameter( 87 DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE) 88 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100)) 89 .withFields({C2F(mSampleRate, value).oneOf({ 90 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 91 })}) 92 .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps)) 93 .build()); 94 95 addParameter( 96 DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT) 97 .withDefault(new C2StreamChannelCountInfo::output(0u, 1)) 98 .withFields({C2F(mChannelCount, value).inRange(1, 8)}) 99 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps) 100 .build()); 101 102 addParameter( 103 DefineParam(mBitrate, C2_PARAMKEY_BITRATE) 104 .withDefault(new C2StreamBitrateInfo::input(0u, 64000)) 105 .withFields({C2F(mBitrate, value).inRange(8000, 960000)}) 106 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps) 107 .build()); 108 109 addParameter( 110 DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE) 111 .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192)) 112 .build()); 113 114 addParameter( 115 DefineParam(mAacFormat, C2_PARAMKEY_AAC_PACKAGING) 116 .withDefault(new C2StreamAacFormatInfo::input(0u, C2Config::AAC_PACKAGING_RAW)) 117 .withFields({C2F(mAacFormat, value).oneOf({ 118 C2Config::AAC_PACKAGING_RAW, C2Config::AAC_PACKAGING_ADTS 119 })}) 120 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps) 121 .build()); 122 123 addParameter( 124 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL) 125 .withDefault(new C2StreamProfileLevelInfo::input(0u, 126 C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED)) 127 .withFields({ 128 C2F(mProfileLevel, profile).oneOf({ 129 C2Config::PROFILE_AAC_LC, 130 C2Config::PROFILE_AAC_HE, 131 C2Config::PROFILE_AAC_HE_PS, 132 C2Config::PROFILE_AAC_LD, 133 C2Config::PROFILE_AAC_ELD, 134 C2Config::PROFILE_AAC_XHE}), 135 C2F(mProfileLevel, level).oneOf({ 136 C2Config::LEVEL_UNUSED 137 }) 138 }) 139 .withSetter(ProfileLevelSetter) 140 .build()); 141 142 addParameter( 143 DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE) 144 .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY)) 145 .withFields({ 146 C2F(mDrcCompressMode, value).oneOf({ 147 C2Config::DRC_COMPRESSION_ODM_DEFAULT, 148 C2Config::DRC_COMPRESSION_NONE, 149 C2Config::DRC_COMPRESSION_LIGHT, 150 C2Config::DRC_COMPRESSION_HEAVY}) 151 }) 152 .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps) 153 .build()); 154 155 addParameter( 156 DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL) 157 .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL)) 158 .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)}) 159 .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps) 160 .build()); 161 162 addParameter( 163 DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL) 164 .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL)) 165 .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)}) 166 .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps) 167 .build()); 168 169 addParameter( 170 DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR) 171 .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST)) 172 .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)}) 173 .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps) 174 .build()); 175 176 addParameter( 177 DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR) 178 .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT)) 179 .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)}) 180 .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps) 181 .build()); 182 183 addParameter( 184 DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE) 185 .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE)) 186 .withFields({ 187 C2F(mDrcEffectType, value).oneOf({ 188 C2Config::DRC_EFFECT_ODM_DEFAULT, 189 C2Config::DRC_EFFECT_OFF, 190 C2Config::DRC_EFFECT_NONE, 191 C2Config::DRC_EFFECT_LATE_NIGHT, 192 C2Config::DRC_EFFECT_NOISY_ENVIRONMENT, 193 C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE, 194 C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL, 195 C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT, 196 C2Config::DRC_EFFECT_GENERAL_COMPRESSION}) 197 }) 198 .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps) 199 .build()); 200 } 201 202 bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; } 203 uint32_t getBitrate() const { return mBitrate->value; } 204 static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) { 205 (void)mayBlock; 206 (void)me; // TODO: validate 207 return C2R::Ok(); 208 } 209 int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; } 210 int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); } 211 int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); } 212 int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; } 213 int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; } 214 int32_t getDrcEffectType() const { return mDrcEffectType->value; } 215 216 private: 217 std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate; 218 std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount; 219 std::shared_ptr<C2StreamBitrateInfo::input> mBitrate; 220 std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize; 221 std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat; 222 std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel; 223 std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode; 224 std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel; 225 std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel; 226 std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor; 227 std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor; 228 std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType; 229 // TODO Add : C2StreamAacSbrModeTuning 230 }; 231 232 C2SoftXaacDec::C2SoftXaacDec( 233 const char* name, 234 c2_node_id_t id, 235 const std::shared_ptr<IntfImpl> &intfImpl) 236 : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)), 237 mIntf(intfImpl), 238 mXheaacCodecHandle(nullptr), 239 mMpegDDrcHandle(nullptr), 240 mOutputDrainBuffer(nullptr) { 241 } 242 243 C2SoftXaacDec::~C2SoftXaacDec() { 244 onRelease(); 245 } 246 247 c2_status_t C2SoftXaacDec::onInit() { 248 mOutputFrameLength = 1024; 249 mInputBuffer = nullptr; 250 mOutputBuffer = nullptr; 251 mSampFreq = 0; 252 mNumChannels = 0; 253 mPcmWdSz = 0; 254 mChannelMask = 0; 255 mNumOutBytes = 0; 256 mCurFrameIndex = 0; 257 mCurTimestamp = 0; 258 mIsCodecInitialized = false; 259 mIsCodecConfigFlushRequired = false; 260 mSignalledOutputEos = false; 261 mSignalledError = false; 262 mOutputDrainBufferWritePos = 0; 263 mDRCFlag = 0; 264 mMpegDDRCPresent = 0; 265 mMemoryVec.clear(); 266 mDrcMemoryVec.clear(); 267 268 IA_ERRORCODE err = initDecoder(); 269 return err == IA_NO_ERROR ? C2_OK : C2_CORRUPTED; 270 271 } 272 273 c2_status_t C2SoftXaacDec::onStop() { 274 mOutputFrameLength = 1024; 275 drainDecoder(); 276 // reset the "configured" state 277 mSampFreq = 0; 278 mNumChannels = 0; 279 mPcmWdSz = 0; 280 mChannelMask = 0; 281 mNumOutBytes = 0; 282 mCurFrameIndex = 0; 283 mCurTimestamp = 0; 284 mSignalledOutputEos = false; 285 mSignalledError = false; 286 mOutputDrainBufferWritePos = 0; 287 mDRCFlag = 0; 288 mMpegDDRCPresent = 0; 289 290 return C2_OK; 291 } 292 293 void C2SoftXaacDec::onReset() { 294 (void)onStop(); 295 } 296 297 void C2SoftXaacDec::onRelease() { 298 IA_ERRORCODE errCode = deInitXAACDecoder(); 299 if (IA_NO_ERROR != errCode) ALOGE("deInitXAACDecoder() failed %d", errCode); 300 301 errCode = deInitMPEGDDDrc(); 302 if (IA_NO_ERROR != errCode) ALOGE("deInitMPEGDDDrc() failed %d", errCode); 303 304 if (mOutputDrainBuffer) { 305 delete[] mOutputDrainBuffer; 306 mOutputDrainBuffer = nullptr; 307 } 308 } 309 310 IA_ERRORCODE C2SoftXaacDec::initDecoder() { 311 ALOGV("initDecoder()"); 312 IA_ERRORCODE err_code = IA_NO_ERROR; 313 314 err_code = initXAACDecoder(); 315 if (err_code != IA_NO_ERROR) { 316 ALOGE("initXAACDecoder Failed"); 317 /* Call deInit to free any allocated memory */ 318 deInitXAACDecoder(); 319 return IA_FATAL_ERROR; 320 } 321 322 if (!mOutputDrainBuffer) { 323 mOutputDrainBuffer = new (std::nothrow) char[kOutputDrainBufferSize]; 324 if (!mOutputDrainBuffer) return IA_FATAL_ERROR; 325 } 326 327 err_code = initXAACDrc(); 328 RETURN_IF_FATAL(err_code, "initXAACDrc"); 329 330 331 return IA_NO_ERROR; 332 } 333 334 static void fillEmptyWork(const std::unique_ptr<C2Work>& work) { 335 uint32_t flags = 0; 336 if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) { 337 flags |= C2FrameData::FLAG_END_OF_STREAM; 338 ALOGV("signalling eos"); 339 } 340 work->worklets.front()->output.flags = (C2FrameData::flags_t)flags; 341 work->worklets.front()->output.buffers.clear(); 342 work->worklets.front()->output.ordinal = work->input.ordinal; 343 work->workletsProcessed = 1u; 344 } 345 346 void C2SoftXaacDec::finishWork(const std::unique_ptr<C2Work>& work, 347 const std::shared_ptr<C2BlockPool>& pool) { 348 ALOGV("mCurFrameIndex = %" PRIu64, mCurFrameIndex); 349 350 std::shared_ptr<C2LinearBlock> block; 351 C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}; 352 // TODO: error handling, proper usage, etc. 353 c2_status_t err = 354 pool->fetchLinearBlock(mOutputDrainBufferWritePos, usage, &block); 355 if (err != C2_OK) { 356 ALOGE("fetchLinearBlock failed : err = %d", err); 357 work->result = C2_NO_MEMORY; 358 return; 359 } 360 C2WriteView wView = block->map().get(); 361 int16_t* outBuffer = reinterpret_cast<int16_t*>(wView.data()); 362 memcpy(outBuffer, mOutputDrainBuffer, mOutputDrainBufferWritePos); 363 mOutputDrainBufferWritePos = 0; 364 365 auto fillWork = [buffer = createLinearBuffer(block)]( 366 const std::unique_ptr<C2Work>& work) { 367 uint32_t flags = 0; 368 if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) { 369 flags |= C2FrameData::FLAG_END_OF_STREAM; 370 ALOGV("signalling eos"); 371 } 372 work->worklets.front()->output.flags = (C2FrameData::flags_t)flags; 373 work->worklets.front()->output.buffers.clear(); 374 work->worklets.front()->output.buffers.push_back(buffer); 375 work->worklets.front()->output.ordinal = work->input.ordinal; 376 work->workletsProcessed = 1u; 377 }; 378 if (work && work->input.ordinal.frameIndex == c2_cntr64_t(mCurFrameIndex)) { 379 fillWork(work); 380 } else { 381 finish(mCurFrameIndex, fillWork); 382 } 383 384 ALOGV("out timestamp %" PRIu64 " / %u", mCurTimestamp, block->capacity()); 385 } 386 387 void C2SoftXaacDec::process(const std::unique_ptr<C2Work>& work, 388 const std::shared_ptr<C2BlockPool>& pool) { 389 // Initialize output work 390 work->result = C2_OK; 391 work->workletsProcessed = 1u; 392 work->worklets.front()->output.configUpdate.clear(); 393 work->worklets.front()->output.flags = work->input.flags; 394 395 if (mSignalledError || mSignalledOutputEos) { 396 work->result = C2_BAD_VALUE; 397 return; 398 } 399 uint8_t* inBuffer = nullptr; 400 uint32_t inBufferLength = 0; 401 C2ReadView view = mDummyReadView; 402 size_t offset = 0u; 403 size_t size = 0u; 404 if (!work->input.buffers.empty()) { 405 view = work->input.buffers[0]->data().linearBlocks().front().map().get(); 406 size = view.capacity(); 407 } 408 if (size && view.error()) { 409 ALOGE("read view map failed %d", view.error()); 410 work->result = view.error(); 411 return; 412 } 413 414 bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0; 415 bool codecConfig = 416 (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0; 417 if (codecConfig) { 418 if (size == 0u) { 419 ALOGE("empty codec config"); 420 mSignalledError = true; 421 work->result = C2_CORRUPTED; 422 return; 423 } 424 // const_cast because of libAACdec method signature. 425 inBuffer = const_cast<uint8_t*>(view.data() + offset); 426 inBufferLength = size; 427 428 /* GA header configuration sent to Decoder! */ 429 IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength); 430 if (IA_NO_ERROR != err_code) { 431 ALOGE("configXAACDecoder err_code = %d", err_code); 432 mSignalledError = true; 433 work->result = C2_CORRUPTED; 434 return; 435 } 436 work->worklets.front()->output.flags = work->input.flags; 437 work->worklets.front()->output.ordinal = work->input.ordinal; 438 work->worklets.front()->output.buffers.clear(); 439 return; 440 } 441 442 mCurFrameIndex = work->input.ordinal.frameIndex.peeku(); 443 mCurTimestamp = work->input.ordinal.timestamp.peeku(); 444 mOutputDrainBufferWritePos = 0; 445 char* tempOutputDrainBuffer = mOutputDrainBuffer; 446 while (size > 0u) { 447 if ((kOutputDrainBufferSize * sizeof(int16_t) - 448 mOutputDrainBufferWritePos) < 449 (mOutputFrameLength * sizeof(int16_t) * mNumChannels)) { 450 ALOGV("skipping decode: not enough space left in DrainBuffer"); 451 break; 452 } 453 454 ALOGV("inAttribute size = %zu", size); 455 if (mIntf->isAdts()) { 456 ALOGV("ADTS"); 457 size_t adtsHeaderSize = 0; 458 // skip 30 bits, aac_frame_length follows. 459 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 460 461 const uint8_t* adtsHeader = view.data() + offset; 462 bool signalError = false; 463 if (size < 7) { 464 ALOGE("Audio data too short to contain even the ADTS header. " 465 "Got %zu bytes.", size); 466 hexdump(adtsHeader, size); 467 signalError = true; 468 } else { 469 bool protectionAbsent = (adtsHeader[1] & 1); 470 unsigned aac_frame_length = ((adtsHeader[3] & 3) << 11) | 471 (adtsHeader[4] << 3) | 472 (adtsHeader[5] >> 5); 473 474 if (size < aac_frame_length) { 475 ALOGE("Not enough audio data for the complete frame. " 476 "Got %zu bytes, frame size according to the ADTS " 477 "header is %u bytes.", size, aac_frame_length); 478 hexdump(adtsHeader, size); 479 signalError = true; 480 } else { 481 adtsHeaderSize = (protectionAbsent ? 7 : 9); 482 if (aac_frame_length < adtsHeaderSize) { 483 signalError = true; 484 } else { 485 // const_cast because of libAACdec method signature. 486 inBuffer = 487 const_cast<uint8_t*>(adtsHeader + adtsHeaderSize); 488 inBufferLength = aac_frame_length - adtsHeaderSize; 489 490 offset += adtsHeaderSize; 491 size -= adtsHeaderSize; 492 } 493 } 494 } 495 496 if (signalError) { 497 mSignalledError = true; 498 work->result = C2_CORRUPTED; 499 return; 500 } 501 } else { 502 ALOGV("Non ADTS"); 503 // const_cast because of libAACdec method signature. 504 inBuffer = const_cast<uint8_t*>(view.data() + offset); 505 inBufferLength = size; 506 } 507 508 signed int prevSampleRate = mSampFreq; 509 signed int prevNumChannels = mNumChannels; 510 511 /* XAAC decoder expects first frame to be fed via configXAACDecoder API 512 * which should initialize the codec. Once this state is reached, call the 513 * decodeXAACStream API with same frame to decode! */ 514 if (!mIsCodecInitialized) { 515 IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength); 516 if (IA_NO_ERROR != err_code) { 517 ALOGE("configXAACDecoder Failed 2 err_code = %d", err_code); 518 mSignalledError = true; 519 work->result = C2_CORRUPTED; 520 return; 521 } 522 523 if ((mSampFreq != prevSampleRate) || 524 (mNumChannels != prevNumChannels)) { 525 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels", 526 prevSampleRate, mSampFreq, prevNumChannels, mNumChannels); 527 528 C2StreamSampleRateInfo::output sampleRateInfo(0u, mSampFreq); 529 C2StreamChannelCountInfo::output channelCountInfo(0u, mNumChannels); 530 std::vector<std::unique_ptr<C2SettingResult>> failures; 531 c2_status_t err = mIntf->config( 532 { &sampleRateInfo, &channelCountInfo }, 533 C2_MAY_BLOCK, 534 &failures); 535 if (err == OK) { 536 work->worklets.front()->output.configUpdate.push_back( 537 C2Param::Copy(sampleRateInfo)); 538 work->worklets.front()->output.configUpdate.push_back( 539 C2Param::Copy(channelCountInfo)); 540 } else { 541 ALOGE("Config Update failed"); 542 mSignalledError = true; 543 work->result = C2_CORRUPTED; 544 return; 545 } 546 } 547 } 548 549 signed int bytesConsumed = 0; 550 IA_ERRORCODE errorCode = IA_NO_ERROR; 551 if (mIsCodecInitialized) { 552 mIsCodecConfigFlushRequired = true; 553 errorCode = decodeXAACStream(inBuffer, inBufferLength, 554 &bytesConsumed, &mNumOutBytes); 555 } else if (!mIsCodecConfigFlushRequired) { 556 ALOGW("Assumption that first frame after header initializes decoder Failed!"); 557 mSignalledError = true; 558 work->result = C2_CORRUPTED; 559 return; 560 } 561 size -= bytesConsumed; 562 offset += bytesConsumed; 563 564 if (inBufferLength != (uint32_t)bytesConsumed) 565 ALOGW("All data not consumed"); 566 567 /* In case of error, decoder would have given out empty buffer */ 568 if ((IA_NO_ERROR != errorCode) && (0 == mNumOutBytes) && mIsCodecInitialized) 569 mNumOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels; 570 571 if (!bytesConsumed) { 572 ALOGW("bytesConsumed = 0 should never happen"); 573 } 574 575 if ((uint32_t)mNumOutBytes > 576 mOutputFrameLength * sizeof(int16_t) * mNumChannels) { 577 ALOGE("mNumOutBytes > mOutputFrameLength * sizeof(int16_t) * mNumChannels, should never happen"); 578 mSignalledError = true; 579 work->result = C2_CORRUPTED; 580 return; 581 } 582 583 if (IA_NO_ERROR != errorCode) { 584 // TODO: check for overflow, ASAN 585 memset(mOutputBuffer, 0, mNumOutBytes); 586 587 // Discard input buffer. 588 size = 0; 589 590 // fall through 591 } 592 memcpy(tempOutputDrainBuffer, mOutputBuffer, mNumOutBytes); 593 tempOutputDrainBuffer += mNumOutBytes; 594 mOutputDrainBufferWritePos += mNumOutBytes; 595 } 596 597 if (mOutputDrainBufferWritePos) { 598 finishWork(work, pool); 599 } else { 600 fillEmptyWork(work); 601 } 602 if (eos) mSignalledOutputEos = true; 603 } 604 605 c2_status_t C2SoftXaacDec::drain(uint32_t drainMode, 606 const std::shared_ptr<C2BlockPool>& pool) { 607 (void)pool; 608 if (drainMode == NO_DRAIN) { 609 ALOGW("drain with NO_DRAIN: no-op"); 610 return C2_OK; 611 } 612 if (drainMode == DRAIN_CHAIN) { 613 ALOGW("DRAIN_CHAIN not supported"); 614 return C2_OMITTED; 615 } 616 617 return C2_OK; 618 } 619 620 IA_ERRORCODE C2SoftXaacDec::configflushDecode() { 621 IA_ERRORCODE err_code; 622 uint32_t ui_init_done; 623 uint32_t inBufferLength = 8203; 624 625 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 626 IA_API_CMD_INIT, 627 IA_CMD_TYPE_FLUSH_MEM, 628 nullptr); 629 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM"); 630 631 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 632 IA_API_CMD_SET_INPUT_BYTES, 633 0, 634 &inBufferLength); 635 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES"); 636 637 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 638 IA_API_CMD_INIT, 639 IA_CMD_TYPE_FLUSH_MEM, 640 nullptr); 641 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM"); 642 643 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 644 IA_API_CMD_INIT, 645 IA_CMD_TYPE_INIT_DONE_QUERY, 646 &ui_init_done); 647 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY"); 648 649 if (ui_init_done) { 650 err_code = getXAACStreamInfo(); 651 RETURN_IF_FATAL(err_code, "getXAACStreamInfo"); 652 ALOGV("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d", 653 mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength); 654 mIsCodecInitialized = true; 655 } 656 return IA_NO_ERROR; 657 } 658 659 c2_status_t C2SoftXaacDec::onFlush_sm() { 660 if (mIsCodecInitialized) { 661 IA_ERRORCODE err_code = configflushDecode(); 662 if (err_code != IA_NO_ERROR) { 663 ALOGE("Error in configflushDecode: Error %d", err_code); 664 } 665 } 666 drainDecoder(); 667 mSignalledOutputEos = false; 668 mSignalledError = false; 669 670 return C2_OK; 671 } 672 673 IA_ERRORCODE C2SoftXaacDec::drainDecoder() { 674 /* Output delay compensation logic should sit here. */ 675 /* Nothing to be done as XAAC decoder does not introduce output buffer delay */ 676 677 return 0; 678 } 679 680 IA_ERRORCODE C2SoftXaacDec::initXAACDecoder() { 681 /* First part */ 682 /* Error Handler Init */ 683 /* Get Library Name, Library Version and API Version */ 684 /* Initialize API structure + Default config set */ 685 /* Set config params from user */ 686 /* Initialize memory tables */ 687 /* Get memory information and allocate memory */ 688 689 mInputBufferSize = 0; 690 mInputBuffer = nullptr; 691 mOutputBuffer = nullptr; 692 /* Process struct initing end */ 693 694 /* ******************************************************************/ 695 /* Initialize API structure and set config params to default */ 696 /* ******************************************************************/ 697 /* API size */ 698 uint32_t pui_api_size; 699 /* Get the API size */ 700 IA_ERRORCODE err_code = ixheaacd_dec_api(nullptr, 701 IA_API_CMD_GET_API_SIZE, 702 0, 703 &pui_api_size); 704 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE"); 705 706 /* Allocate memory for API */ 707 mXheaacCodecHandle = memalign(4, pui_api_size); 708 if (!mXheaacCodecHandle) { 709 ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4); 710 return IA_FATAL_ERROR; 711 } 712 mMemoryVec.push(mXheaacCodecHandle); 713 714 /* Set the config params to default values */ 715 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 716 IA_API_CMD_INIT, 717 IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, 718 nullptr); 719 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS"); 720 721 /* Get the API size */ 722 err_code = ia_drc_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size); 723 724 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE"); 725 726 /* Allocate memory for API */ 727 mMpegDDrcHandle = memalign(4, pui_api_size); 728 if (!mMpegDDrcHandle) { 729 ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4); 730 return IA_FATAL_ERROR; 731 } 732 mMemoryVec.push(mMpegDDrcHandle); 733 734 /* Set the config params to default values */ 735 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 736 IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr); 737 738 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS"); 739 740 /* ******************************************************************/ 741 /* Set config parameters */ 742 /* ******************************************************************/ 743 uint32_t ui_mp4_flag = 1; 744 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 745 IA_API_CMD_SET_CONFIG_PARAM, 746 IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, 747 &ui_mp4_flag); 748 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4"); 749 750 /* ******************************************************************/ 751 /* Initialize Memory info tables */ 752 /* ******************************************************************/ 753 uint32_t ui_proc_mem_tabs_size; 754 pVOID pv_alloc_ptr; 755 /* Get memory info tables size */ 756 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 757 IA_API_CMD_GET_MEMTABS_SIZE, 758 0, 759 &ui_proc_mem_tabs_size); 760 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE"); 761 762 pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size); 763 if (!pv_alloc_ptr) { 764 ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!", ui_proc_mem_tabs_size + 4); 765 return IA_FATAL_ERROR; 766 } 767 mMemoryVec.push(pv_alloc_ptr); 768 769 /* Set pointer for process memory tables */ 770 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 771 IA_API_CMD_SET_MEMTABS_PTR, 772 0, 773 pv_alloc_ptr); 774 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR"); 775 776 /* initialize the API, post config, fill memory tables */ 777 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 778 IA_API_CMD_INIT, 779 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, 780 nullptr); 781 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS"); 782 783 /* ******************************************************************/ 784 /* Allocate Memory with info from library */ 785 /* ******************************************************************/ 786 /* There are four different types of memories, that needs to be allocated */ 787 /* persistent,scratch,input and output */ 788 for (int i = 0; i < 4; i++) { 789 int ui_size = 0, ui_alignment = 0, ui_type = 0; 790 791 /* Get memory size */ 792 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 793 IA_API_CMD_GET_MEM_INFO_SIZE, 794 i, 795 &ui_size); 796 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE"); 797 798 /* Get memory alignment */ 799 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 800 IA_API_CMD_GET_MEM_INFO_ALIGNMENT, 801 i, 802 &ui_alignment); 803 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT"); 804 805 /* Get memory type */ 806 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 807 IA_API_CMD_GET_MEM_INFO_TYPE, 808 i, 809 &ui_type); 810 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE"); 811 812 pv_alloc_ptr = memalign(ui_alignment, ui_size); 813 if (!pv_alloc_ptr) { 814 ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!", 815 ui_size + ui_alignment); 816 return IA_FATAL_ERROR; 817 } 818 mMemoryVec.push(pv_alloc_ptr); 819 820 /* Set the buffer pointer */ 821 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 822 IA_API_CMD_SET_MEM_PTR, 823 i, 824 pv_alloc_ptr); 825 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR"); 826 if (ui_type == IA_MEMTYPE_INPUT) { 827 mInputBuffer = (pWORD8)pv_alloc_ptr; 828 mInputBufferSize = ui_size; 829 } 830 if (ui_type == IA_MEMTYPE_OUTPUT) 831 mOutputBuffer = (pWORD8)pv_alloc_ptr; 832 } 833 /* End first part */ 834 835 return IA_NO_ERROR; 836 } 837 838 status_t C2SoftXaacDec::initXAACDrc() { 839 IA_ERRORCODE err_code = IA_NO_ERROR; 840 unsigned int ui_drc_val; 841 // DRC_PRES_MODE_WRAP_DESIRED_TARGET 842 int32_t targetRefLevel = mIntf->getDrcTargetRefLevel(); 843 ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel); 844 ui_drc_val = (unsigned int)targetRefLevel; 845 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 846 IA_API_CMD_SET_CONFIG_PARAM, 847 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, 848 &ui_drc_val); 849 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL"); 850 851 /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or DRC_DEFAULT_MOBILE_REF_LEVEL 852 * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */ 853 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 854 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val); 855 856 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS"); 857 858 int32_t attenuationFactor = mIntf->getDrcAttenuationFactor(); 859 ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor); 860 ui_drc_val = (unsigned int)attenuationFactor; 861 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 862 IA_API_CMD_SET_CONFIG_PARAM, 863 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, 864 &ui_drc_val); 865 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT"); 866 867 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR 868 int32_t boostFactor = mIntf->getDrcBoostFactor(); 869 ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor); 870 ui_drc_val = (unsigned int)boostFactor; 871 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 872 IA_API_CMD_SET_CONFIG_PARAM, 873 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, 874 &ui_drc_val); 875 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST"); 876 877 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY 878 int32_t compressMode = mIntf->getDrcCompressMode(); 879 ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode); 880 ui_drc_val = (unsigned int)compressMode; 881 882 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 883 IA_API_CMD_SET_CONFIG_PARAM, 884 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP, 885 &ui_drc_val); 886 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP"); 887 888 // AAC_UNIDRC_SET_EFFECT 889 int32_t effectType = mIntf->getDrcEffectType(); 890 ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType); 891 ui_drc_val = (unsigned int)effectType; 892 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 893 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val); 894 895 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE"); 896 897 return IA_NO_ERROR; 898 } 899 900 IA_ERRORCODE C2SoftXaacDec::deInitXAACDecoder() { 901 ALOGV("deInitXAACDecoder"); 902 903 /* Error code */ 904 IA_ERRORCODE err_code = IA_NO_ERROR; 905 906 if (mXheaacCodecHandle) { 907 /* Tell that the input is over in this buffer */ 908 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 909 IA_API_CMD_INPUT_OVER, 910 0, 911 nullptr); 912 } 913 914 /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */ 915 for (void* buf : mMemoryVec) { 916 if (buf) free(buf); 917 } 918 mMemoryVec.clear(); 919 mXheaacCodecHandle = nullptr; 920 921 return err_code; 922 } 923 924 IA_ERRORCODE C2SoftXaacDec::deInitMPEGDDDrc() { 925 ALOGV("deInitMPEGDDDrc"); 926 927 for (void* buf : mDrcMemoryVec) { 928 if (buf) free(buf); 929 } 930 mDrcMemoryVec.clear(); 931 return IA_NO_ERROR; 932 } 933 934 IA_ERRORCODE C2SoftXaacDec::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) { 935 if (mInputBufferSize < inBufferLength) { 936 ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength); 937 return false; 938 } 939 /* Copy the buffer passed by Android plugin to codec input buffer */ 940 memcpy(mInputBuffer, inBuffer, inBufferLength); 941 942 /* Set number of bytes to be processed */ 943 IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle, 944 IA_API_CMD_SET_INPUT_BYTES, 945 0, 946 &inBufferLength); 947 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES"); 948 949 if (mIsCodecConfigFlushRequired) { 950 /* If codec is already initialized, then GA header is passed again */ 951 /* Need to call the Flush API instead of INIT_PROCESS */ 952 mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */ 953 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 954 IA_API_CMD_INIT, 955 IA_CMD_TYPE_GA_HDR, 956 nullptr); 957 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_GA_HDR"); 958 } else { 959 /* Initialize the process */ 960 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 961 IA_API_CMD_INIT, 962 IA_CMD_TYPE_INIT_PROCESS, 963 nullptr); 964 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS"); 965 } 966 967 uint32_t ui_init_done; 968 /* Checking for end of initialization */ 969 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 970 IA_API_CMD_INIT, 971 IA_CMD_TYPE_INIT_DONE_QUERY, 972 &ui_init_done); 973 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY"); 974 975 /* How much buffer is used in input buffers */ 976 int32_t i_bytes_consumed; 977 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 978 IA_API_CMD_GET_CURIDX_INPUT_BUF, 979 0, 980 &i_bytes_consumed); 981 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF"); 982 983 if (ui_init_done) { 984 err_code = getXAACStreamInfo(); 985 RETURN_IF_FATAL(err_code, "getXAACStreamInfo"); 986 ALOGI("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d", 987 mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength); 988 mIsCodecInitialized = true; 989 990 err_code = configMPEGDDrc(); 991 RETURN_IF_FATAL(err_code, "configMPEGDDrc"); 992 } 993 994 return IA_NO_ERROR; 995 } 996 IA_ERRORCODE C2SoftXaacDec::initMPEGDDDrc() { 997 IA_ERRORCODE err_code = IA_NO_ERROR; 998 999 for (int i = 0; i < (WORD32)2; i++) { 1000 WORD32 ui_size, ui_alignment, ui_type; 1001 pVOID pv_alloc_ptr; 1002 1003 /* Get memory size */ 1004 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size); 1005 1006 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE"); 1007 1008 /* Get memory alignment */ 1009 err_code = 1010 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment); 1011 1012 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT"); 1013 1014 /* Get memory type */ 1015 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type); 1016 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE"); 1017 1018 pv_alloc_ptr = memalign(4, ui_size); 1019 if (pv_alloc_ptr == nullptr) { 1020 ALOGE(" Cannot create requested memory %d", ui_size); 1021 return IA_FATAL_ERROR; 1022 } 1023 mDrcMemoryVec.push(pv_alloc_ptr); 1024 1025 /* Set the buffer pointer */ 1026 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr); 1027 1028 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR"); 1029 } 1030 1031 WORD32 ui_size; 1032 ui_size = 8192 * 2; 1033 1034 mDrcInBuf = (int8_t*)memalign(4, ui_size); 1035 if (mDrcInBuf == nullptr) { 1036 ALOGE(" Cannot create requested memory %d", ui_size); 1037 return IA_FATAL_ERROR; 1038 } 1039 mDrcMemoryVec.push(mDrcInBuf); 1040 1041 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf); 1042 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR"); 1043 1044 mDrcOutBuf = (int8_t*)memalign(4, ui_size); 1045 if (mDrcOutBuf == nullptr) { 1046 ALOGE(" Cannot create requested memory %d", ui_size); 1047 return IA_FATAL_ERROR; 1048 } 1049 mDrcMemoryVec.push(mDrcOutBuf); 1050 1051 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf); 1052 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR"); 1053 1054 return IA_NO_ERROR; 1055 } 1056 int C2SoftXaacDec::configMPEGDDrc() { 1057 IA_ERRORCODE err_code = IA_NO_ERROR; 1058 int i_effect_type; 1059 int i_loud_norm; 1060 int i_target_loudness; 1061 unsigned int i_sbr_mode; 1062 uint32_t ui_proc_mem_tabs_size = 0; 1063 pVOID pv_alloc_ptr = NULL; 1064 1065 /* Sampling Frequency */ 1066 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1067 IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq); 1068 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ"); 1069 /* Total Number of Channels */ 1070 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1071 IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels); 1072 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS"); 1073 1074 /* PCM word size */ 1075 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1076 IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz); 1077 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ"); 1078 1079 /*Set Effect Type*/ 1080 1081 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1082 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type); 1083 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE"); 1084 1085 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1086 IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type); 1087 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE"); 1088 1089 /*Set target loudness */ 1090 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1091 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, 1092 &i_target_loudness); 1093 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS"); 1094 1095 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1096 IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness); 1097 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS"); 1098 1099 /*Set loud_norm_flag*/ 1100 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1101 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm); 1102 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM"); 1103 1104 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1105 IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm); 1106 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM"); 1107 1108 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1109 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode); 1110 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE"); 1111 1112 /* Get memory info tables size */ 1113 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0, 1114 &ui_proc_mem_tabs_size); 1115 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE"); 1116 1117 pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size); 1118 if (pv_alloc_ptr == NULL) { 1119 ALOGE(" Cannot create requested memory %d", ui_proc_mem_tabs_size); 1120 return IA_FATAL_ERROR; 1121 } 1122 memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size); 1123 mMemoryVec.push(pv_alloc_ptr); 1124 1125 /* Set pointer for process memory tables */ 1126 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0, 1127 pv_alloc_ptr); 1128 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR"); 1129 1130 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 1131 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr); 1132 1133 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS"); 1134 1135 /* Free any memory that is allocated for MPEG D Drc so far */ 1136 deInitMPEGDDDrc(); 1137 1138 err_code = initMPEGDDDrc(); 1139 if (err_code != IA_NO_ERROR) { 1140 ALOGE("initMPEGDDDrc failed with error %d", err_code); 1141 deInitMPEGDDDrc(); 1142 return err_code; 1143 } 1144 1145 /* DRC buffers 1146 buf[0] - contains extension element pay load loudness related 1147 buf[1] - contains extension element pay load*/ 1148 { 1149 VOID* p_array[2][16]; 1150 WORD32 ii; 1151 WORD32 buf_sizes[2][16]; 1152 WORD32 num_elements; 1153 WORD32 num_config_ext; 1154 WORD32 bit_str_fmt = 1; 1155 1156 WORD32 uo_num_chan; 1157 1158 memset(buf_sizes, 0, 32 * sizeof(WORD32)); 1159 1160 err_code = 1161 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1162 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]); 1163 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES"); 1164 1165 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1166 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array); 1167 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR"); 1168 1169 err_code = 1170 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr); 1171 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR"); 1172 1173 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1174 IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements); 1175 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE"); 1176 1177 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1178 IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext); 1179 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT"); 1180 1181 for (ii = 0; ii < num_config_ext; ii++) { 1182 /*copy loudness bitstream*/ 1183 if (buf_sizes[0][ii] > 0) { 1184 memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]); 1185 1186 /*Set bitstream_split_format */ 1187 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1188 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt); 1189 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT"); 1190 1191 /* Set number of bytes to be processed */ 1192 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0, 1193 &buf_sizes[0][ii]); 1194 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS"); 1195 1196 /* Execute process */ 1197 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 1198 IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr); 1199 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF"); 1200 1201 mDRCFlag = 1; 1202 } 1203 } 1204 1205 for (ii = 0; ii < num_elements; ii++) { 1206 /*copy config bitstream*/ 1207 if (buf_sizes[1][ii] > 0) { 1208 memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]); 1209 /* Set number of bytes to be processed */ 1210 1211 /*Set bitstream_split_format */ 1212 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1213 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt); 1214 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT"); 1215 1216 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0, 1217 &buf_sizes[1][ii]); 1218 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS"); 1219 1220 /* Execute process */ 1221 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 1222 IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr); 1223 1224 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF"); 1225 1226 mDRCFlag = 1; 1227 } 1228 } 1229 1230 if (mDRCFlag == 1) { 1231 mMpegDDRCPresent = 1; 1232 } else { 1233 mMpegDDRCPresent = 0; 1234 } 1235 1236 /*Read interface buffer config file bitstream*/ 1237 if (mMpegDDRCPresent == 1) { 1238 WORD32 interface_is_present = 1; 1239 1240 if (i_sbr_mode != 0) { 1241 if (i_sbr_mode == 1) { 1242 mOutputFrameLength = 2048; 1243 } else if (i_sbr_mode == 3) { 1244 mOutputFrameLength = 4096; 1245 } else { 1246 mOutputFrameLength = 1024; 1247 } 1248 } else { 1249 mOutputFrameLength = 4096; 1250 } 1251 1252 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1253 IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, (WORD32 *)&mOutputFrameLength); 1254 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE"); 1255 1256 err_code = 1257 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1258 IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present); 1259 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT"); 1260 1261 /* Execute process */ 1262 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 1263 IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr); 1264 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF"); 1265 1266 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 1267 IA_CMD_TYPE_INIT_PROCESS, nullptr); 1268 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS"); 1269 1270 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM, 1271 IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan); 1272 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS"); 1273 } 1274 } 1275 1276 return err_code; 1277 } 1278 1279 IA_ERRORCODE C2SoftXaacDec::decodeXAACStream(uint8_t* inBuffer, 1280 uint32_t inBufferLength, 1281 int32_t* bytesConsumed, 1282 int32_t* outBytes) { 1283 if (mInputBufferSize < inBufferLength) { 1284 ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength); 1285 return -1; 1286 } 1287 /* Copy the buffer passed by Android plugin to codec input buffer */ 1288 memcpy(mInputBuffer, inBuffer, inBufferLength); 1289 1290 /* Set number of bytes to be processed */ 1291 IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1292 IA_API_CMD_SET_INPUT_BYTES, 1293 0, 1294 &inBufferLength); 1295 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES"); 1296 1297 /* Execute process */ 1298 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1299 IA_API_CMD_EXECUTE, 1300 IA_CMD_TYPE_DO_EXECUTE, 1301 nullptr); 1302 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE"); 1303 1304 /* Checking for end of processing */ 1305 uint32_t ui_exec_done; 1306 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1307 IA_API_CMD_EXECUTE, 1308 IA_CMD_TYPE_DONE_QUERY, 1309 &ui_exec_done); 1310 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DONE_QUERY"); 1311 1312 if (ui_exec_done != 1) { 1313 VOID* p_array; // ITTIAM:buffer to handle gain payload 1314 WORD32 buf_size = 0; // ITTIAM:gain payload length 1315 WORD32 bit_str_fmt = 1; 1316 WORD32 gain_stream_flag = 1; 1317 1318 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1319 IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size); 1320 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN"); 1321 1322 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1323 IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array); 1324 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF"); 1325 1326 if (buf_size > 0) { 1327 /*Set bitstream_split_format */ 1328 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1329 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt); 1330 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT"); 1331 1332 memcpy(mDrcInBuf, p_array, buf_size); 1333 /* Set number of bytes to be processed */ 1334 err_code = 1335 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS, 0, &buf_size); 1336 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT"); 1337 1338 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1339 IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag); 1340 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT"); 1341 1342 /* Execute process */ 1343 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, 1344 IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr); 1345 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT"); 1346 1347 mMpegDDRCPresent = 1; 1348 } 1349 } 1350 1351 /* How much buffer is used in input buffers */ 1352 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1353 IA_API_CMD_GET_CURIDX_INPUT_BUF, 1354 0, 1355 bytesConsumed); 1356 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF"); 1357 1358 /* Get the output bytes */ 1359 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1360 IA_API_CMD_GET_OUTPUT_BYTES, 1361 0, 1362 outBytes); 1363 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_OUTPUT_BYTES"); 1364 1365 if (mMpegDDRCPresent == 1) { 1366 memcpy(mDrcInBuf, mOutputBuffer, *outBytes); 1367 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0, outBytes); 1368 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES"); 1369 1370 err_code = 1371 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, nullptr); 1372 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE"); 1373 1374 memcpy(mOutputBuffer, mDrcOutBuf, *outBytes); 1375 } 1376 return IA_NO_ERROR; 1377 } 1378 1379 IA_ERRORCODE C2SoftXaacDec::getXAACStreamInfo() { 1380 IA_ERRORCODE err_code = IA_NO_ERROR; 1381 1382 /* Sampling frequency */ 1383 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1384 IA_API_CMD_GET_CONFIG_PARAM, 1385 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ, 1386 &mSampFreq); 1387 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ"); 1388 1389 /* Total Number of Channels */ 1390 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1391 IA_API_CMD_GET_CONFIG_PARAM, 1392 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS, 1393 &mNumChannels); 1394 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS"); 1395 if (mNumChannels > MAX_CHANNEL_COUNT) { 1396 ALOGE(" No of channels are more than max channels\n"); 1397 return IA_FATAL_ERROR; 1398 } 1399 1400 /* PCM word size */ 1401 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1402 IA_API_CMD_GET_CONFIG_PARAM, 1403 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, 1404 &mPcmWdSz); 1405 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ"); 1406 if ((mPcmWdSz / 8) != 2) { 1407 ALOGE(" No of channels are more than max channels\n"); 1408 return IA_FATAL_ERROR; 1409 } 1410 1411 /* channel mask to tell the arrangement of channels in bit stream */ 1412 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1413 IA_API_CMD_GET_CONFIG_PARAM, 1414 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK, 1415 &mChannelMask); 1416 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK"); 1417 1418 /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */ 1419 uint32_t ui_channel_mode; 1420 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1421 IA_API_CMD_GET_CONFIG_PARAM, 1422 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE, 1423 &ui_channel_mode); 1424 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE"); 1425 if (ui_channel_mode == 0) 1426 ALOGV("Channel Mode: MONO_OR_PS\n"); 1427 else if (ui_channel_mode == 1) 1428 ALOGV("Channel Mode: STEREO\n"); 1429 else if (ui_channel_mode == 2) 1430 ALOGV("Channel Mode: DUAL-MONO\n"); 1431 else 1432 ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n"); 1433 1434 /* Channel mode to tell SBR PRESENT/NOT_PRESENT */ 1435 uint32_t ui_sbr_mode; 1436 err_code = ixheaacd_dec_api(mXheaacCodecHandle, 1437 IA_API_CMD_GET_CONFIG_PARAM, 1438 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, 1439 &ui_sbr_mode); 1440 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE"); 1441 if (ui_sbr_mode == 0) 1442 ALOGV("SBR Mode: NOT_PRESENT\n"); 1443 else if (ui_sbr_mode == 1) 1444 ALOGV("SBR Mode: PRESENT\n"); 1445 else 1446 ALOGV("SBR Mode: ILLEGAL\n"); 1447 1448 /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */ 1449 /* For USAC it could be 1024 * 3 , support to query */ 1450 /* not yet added in codec */ 1451 mOutputFrameLength = 1024 * (1 + ui_sbr_mode); 1452 ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode); 1453 1454 return IA_NO_ERROR; 1455 } 1456 1457 IA_ERRORCODE C2SoftXaacDec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost, 1458 int32_t drcRefLevel, 1459 int32_t drcHeavyCompression, 1460 int32_t drEffectType) { 1461 IA_ERRORCODE err_code = IA_NO_ERROR; 1462 1463 int32_t ui_drc_enable = 1; 1464 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1465 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE, 1466 &ui_drc_enable); 1467 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE"); 1468 if (drcCut != -1) { 1469 err_code = 1470 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1471 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut); 1472 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT"); 1473 } 1474 1475 if (drcBoost != -1) { 1476 err_code = ixheaacd_dec_api( 1477 mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1478 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost); 1479 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST"); 1480 } 1481 1482 if (drcRefLevel != -1) { 1483 err_code = ixheaacd_dec_api( 1484 mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1485 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel); 1486 RETURN_IF_FATAL(err_code, 1487 "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL"); 1488 } 1489 1490 if (drcRefLevel != -1) { 1491 err_code = ixheaacd_dec_api( 1492 mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1493 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel); 1494 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS"); 1495 } 1496 1497 if (drcHeavyCompression != -1) { 1498 err_code = 1499 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1500 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP, 1501 &drcHeavyCompression); 1502 RETURN_IF_FATAL(err_code, 1503 "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP"); 1504 } 1505 1506 err_code = 1507 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM, 1508 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType); 1509 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE"); 1510 1511 int32_t i_effect_type, i_target_loudness, i_loud_norm; 1512 /*Set Effect Type*/ 1513 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1514 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, 1515 &i_effect_type); 1516 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE"); 1517 1518 err_code = 1519 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1520 IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type); 1521 1522 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE"); 1523 1524 /*Set target loudness */ 1525 err_code = ixheaacd_dec_api( 1526 mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1527 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness); 1528 RETURN_IF_FATAL(err_code, 1529 "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS"); 1530 1531 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1532 IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, 1533 &i_target_loudness); 1534 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS"); 1535 1536 /*Set loud_norm_flag*/ 1537 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM, 1538 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, 1539 &i_loud_norm); 1540 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM"); 1541 1542 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM, 1543 IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm); 1544 1545 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM"); 1546 1547 return IA_NO_ERROR; 1548 } 1549 1550 class C2SoftXaacDecFactory : public C2ComponentFactory { 1551 public: 1552 C2SoftXaacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( 1553 GetCodec2PlatformComponentStore()->getParamReflector())) { 1554 } 1555 1556 virtual c2_status_t createComponent( 1557 c2_node_id_t id, 1558 std::shared_ptr<C2Component>* const component, 1559 std::function<void(C2Component*)> deleter) override { 1560 *component = std::shared_ptr<C2Component>( 1561 new C2SoftXaacDec(COMPONENT_NAME, 1562 id, 1563 std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)), 1564 deleter); 1565 return C2_OK; 1566 } 1567 1568 virtual c2_status_t createInterface( 1569 c2_node_id_t id, 1570 std::shared_ptr<C2ComponentInterface>* const interface, 1571 std::function<void(C2ComponentInterface*)> deleter) override { 1572 *interface = std::shared_ptr<C2ComponentInterface>( 1573 new SimpleInterface<C2SoftXaacDec::IntfImpl>( 1574 COMPONENT_NAME, id, std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)), 1575 deleter); 1576 return C2_OK; 1577 } 1578 1579 virtual ~C2SoftXaacDecFactory() override = default; 1580 1581 private: 1582 std::shared_ptr<C2ReflectorHelper> mHelper; 1583 }; 1584 1585 } // namespace android 1586 1587 extern "C" ::C2ComponentFactory* CreateCodec2Factory() { 1588 ALOGV("in %s", __func__); 1589 return new ::android::C2SoftXaacDecFactory(); 1590 } 1591 1592 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) { 1593 ALOGV("in %s", __func__); 1594 delete factory; 1595 } 1596