Home | History | Annotate | Download | only in aac
      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