Home | History | Annotate | Download | only in mp3
      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 "C2SoftMp3Dec"
     19 #include <log/log.h>
     20 
     21 #include <numeric>
     22 
     23 #include <media/stagefright/foundation/MediaDefs.h>
     24 
     25 #include <C2PlatformSupport.h>
     26 #include <SimpleC2Interface.h>
     27 
     28 #include "C2SoftMp3Dec.h"
     29 #include "pvmp3decoder_api.h"
     30 
     31 namespace android {
     32 
     33 namespace {
     34 
     35 constexpr char COMPONENT_NAME[] = "c2.android.mp3.decoder";
     36 
     37 }  // namespace
     38 
     39 class C2SoftMP3::IntfImpl : public SimpleInterface<void>::BaseParams {
     40 public:
     41     explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
     42         : SimpleInterface<void>::BaseParams(
     43                 helper,
     44                 COMPONENT_NAME,
     45                 C2Component::KIND_DECODER,
     46                 C2Component::DOMAIN_AUDIO,
     47                 MEDIA_MIMETYPE_AUDIO_MPEG) {
     48         noPrivateBuffers();
     49         noInputReferences();
     50         noOutputReferences();
     51         noInputLatency();
     52         noTimeStretch();
     53         setDerivedInstance(this);
     54 
     55         addParameter(
     56                 DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
     57                 .withConstValue(new C2ComponentAttributesSetting(
     58                     C2Component::ATTRIB_IS_TEMPORAL))
     59                 .build());
     60 
     61         addParameter(
     62                 DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
     63                 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
     64                 .withFields({C2F(mSampleRate, value).oneOf({8000, 11025, 12000, 16000,
     65                     22050, 24000, 32000, 44100, 48000})})
     66                 .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
     67                 .build());
     68 
     69         addParameter(
     70                 DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
     71                 .withDefault(new C2StreamChannelCountInfo::output(0u, 2))
     72                 .withFields({C2F(mChannelCount, value).inRange(1, 2)})
     73                 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
     74                 .build());
     75 
     76         addParameter(
     77                 DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
     78                 .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
     79                 .withFields({C2F(mBitrate, value).inRange(8000, 320000)})
     80                 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
     81                 .build());
     82 
     83         addParameter(
     84                 DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
     85                 .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
     86                 .build());
     87     }
     88 
     89 private:
     90     std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
     91     std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
     92     std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
     93     std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
     94 };
     95 
     96 C2SoftMP3::C2SoftMP3(const char *name, c2_node_id_t id,
     97                      const std::shared_ptr<IntfImpl> &intfImpl)
     98     : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
     99       mIntf(intfImpl),
    100       mConfig(nullptr),
    101       mDecoderBuf(nullptr) {
    102 }
    103 
    104 C2SoftMP3::~C2SoftMP3() {
    105     onRelease();
    106 }
    107 
    108 c2_status_t C2SoftMP3::onInit() {
    109     status_t err = initDecoder();
    110     return err == OK ? C2_OK : C2_NO_MEMORY;
    111 }
    112 
    113 c2_status_t C2SoftMP3::onStop() {
    114     // Make sure that the next buffer output does not still
    115     // depend on fragments from the last one decoded.
    116     pvmp3_InitDecoder(mConfig, mDecoderBuf);
    117     mSignalledError = false;
    118     mIsFirst = true;
    119     mSignalledOutputEos = false;
    120     mAnchorTimeStamp = 0;
    121     mProcessedSamples = 0;
    122 
    123     return C2_OK;
    124 }
    125 
    126 void C2SoftMP3::onReset() {
    127     (void)onStop();
    128 }
    129 
    130 void C2SoftMP3::onRelease() {
    131     mGaplessBytes = false;
    132     if (mDecoderBuf) {
    133         free(mDecoderBuf);
    134         mDecoderBuf = nullptr;
    135     }
    136 
    137     if (mConfig) {
    138         delete mConfig;
    139         mConfig = nullptr;
    140     }
    141 }
    142 
    143 status_t C2SoftMP3::initDecoder() {
    144     mConfig = new tPVMP3DecoderExternal{};
    145     if (!mConfig) return NO_MEMORY;
    146     mConfig->equalizerType = flat;
    147     mConfig->crcEnabled = false;
    148 
    149     size_t memRequirements = pvmp3_decoderMemRequirements();
    150     mDecoderBuf = malloc(memRequirements);
    151     if (!mDecoderBuf) return NO_MEMORY;
    152 
    153     pvmp3_InitDecoder(mConfig, mDecoderBuf);
    154 
    155     mIsFirst = true;
    156     mGaplessBytes = false;
    157     mSignalledError = false;
    158     mSignalledOutputEos = false;
    159     mAnchorTimeStamp = 0;
    160     mProcessedSamples = 0;
    161 
    162     return OK;
    163 }
    164 
    165 /* The below code is borrowed from ./test/mp3reader.cpp */
    166 static bool parseMp3Header(uint32_t header, size_t *frame_size,
    167                            uint32_t *out_sampling_rate = nullptr,
    168                            uint32_t *out_channels = nullptr,
    169                            uint32_t *out_bitrate = nullptr,
    170                            uint32_t *out_num_samples = nullptr) {
    171     *frame_size = 0;
    172     if (out_sampling_rate) *out_sampling_rate = 0;
    173     if (out_channels) *out_channels = 0;
    174     if (out_bitrate) *out_bitrate = 0;
    175     if (out_num_samples) *out_num_samples = 1152;
    176 
    177     if ((header & 0xffe00000) != 0xffe00000) return false;
    178 
    179     unsigned version = (header >> 19) & 3;
    180     if (version == 0x01) return false;
    181 
    182     unsigned layer = (header >> 17) & 3;
    183     if (layer == 0x00) return false;
    184 
    185     unsigned bitrate_index = (header >> 12) & 0x0f;
    186     if (bitrate_index == 0 || bitrate_index == 0x0f) return false;
    187 
    188     unsigned sampling_rate_index = (header >> 10) & 3;
    189     if (sampling_rate_index == 3) return false;
    190 
    191     static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
    192     int sampling_rate = kSamplingRateV1[sampling_rate_index];
    193     if (version == 2 /* V2 */) {
    194         sampling_rate /= 2;
    195     } else if (version == 0 /* V2.5 */) {
    196         sampling_rate /= 4;
    197     }
    198 
    199     unsigned padding = (header >> 9) & 1;
    200 
    201     if (layer == 3) { // layer I
    202         static const int kBitrateV1[] =
    203         {
    204             32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
    205         };
    206         static const int kBitrateV2[] =
    207         {
    208             32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256
    209         };
    210 
    211         int bitrate = (version == 3 /* V1 */) ? kBitrateV1[bitrate_index - 1] :
    212                 kBitrateV2[bitrate_index - 1];
    213 
    214         if (out_bitrate) {
    215             *out_bitrate = bitrate;
    216         }
    217         *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
    218         if (out_num_samples) {
    219             *out_num_samples = 384;
    220         }
    221     } else { // layer II or III
    222         static const int kBitrateV1L2[] =
    223         {
    224             32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
    225         };
    226 
    227         static const int kBitrateV1L3[] =
    228         {
    229             32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
    230         };
    231 
    232         static const int kBitrateV2[] =
    233         {
    234             8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
    235         };
    236 
    237         int bitrate;
    238         if (version == 3 /* V1 */) {
    239             bitrate = (layer == 2 /* L2 */) ? kBitrateV1L2[bitrate_index - 1] :
    240                     kBitrateV1L3[bitrate_index - 1];
    241 
    242             if (out_num_samples) {
    243                 *out_num_samples = 1152;
    244             }
    245         } else { // V2 (or 2.5)
    246             bitrate = kBitrateV2[bitrate_index - 1];
    247             if (out_num_samples) {
    248                 *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
    249             }
    250         }
    251 
    252         if (out_bitrate) {
    253             *out_bitrate = bitrate;
    254         }
    255 
    256         if (version == 3 /* V1 */) {
    257             *frame_size = 144000 * bitrate / sampling_rate + padding;
    258         } else { // V2 or V2.5
    259             size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
    260             *frame_size = tmp * bitrate / sampling_rate + padding;
    261         }
    262     }
    263 
    264     if (out_sampling_rate) {
    265         *out_sampling_rate = sampling_rate;
    266     }
    267 
    268     if (out_channels) {
    269         int channel_mode = (header >> 6) & 3;
    270 
    271         *out_channels = (channel_mode == 3) ? 1 : 2;
    272     }
    273 
    274     return true;
    275 }
    276 
    277 static uint32_t U32_AT(const uint8_t *ptr) {
    278     return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
    279 }
    280 
    281 static status_t calculateOutSize(uint8 *header, size_t inSize,
    282                                  std::vector<size_t> *decodedSizes) {
    283     uint32_t channels;
    284     uint32_t numSamples;
    285     size_t frameSize;
    286     size_t totalInSize = 0;
    287 
    288     while (totalInSize + 4 < inSize) {
    289         if (!parseMp3Header(U32_AT(header + totalInSize), &frameSize,
    290                             nullptr, &channels, nullptr, &numSamples)) {
    291             ALOGE("Error in parse mp3 header during outSize estimation");
    292             return UNKNOWN_ERROR;
    293         }
    294         totalInSize += frameSize;
    295         decodedSizes->push_back(numSamples * channels * sizeof(int16_t));
    296     }
    297 
    298     if (decodedSizes->empty()) return UNKNOWN_ERROR;
    299 
    300     return OK;
    301 }
    302 
    303 c2_status_t C2SoftMP3::onFlush_sm() {
    304     return onStop();
    305 }
    306 
    307 c2_status_t C2SoftMP3::drain(
    308         uint32_t drainMode,
    309         const std::shared_ptr<C2BlockPool> &pool) {
    310     (void) pool;
    311     if (drainMode == NO_DRAIN) {
    312         ALOGW("drain with NO_DRAIN: no-op");
    313         return C2_OK;
    314     }
    315     if (drainMode == DRAIN_CHAIN) {
    316         ALOGW("DRAIN_CHAIN not supported");
    317         return C2_OMITTED;
    318     }
    319 
    320     return C2_OK;
    321 }
    322 
    323 // TODO: Can overall error checking be improved? As in the check for validity of
    324 //       work, pool ptr, work->input.buffers.size() == 1, ...
    325 // TODO: Blind removal of 529 samples from the output may not work. Because
    326 //       mpeg layer 1 frame size is 384 samples per frame. This should introduce
    327 //       negative values and can cause SEG faults. Soft omx mp3 plugin can have
    328 //       this problem (CHECK!)
    329 void C2SoftMP3::process(
    330         const std::unique_ptr<C2Work> &work,
    331         const std::shared_ptr<C2BlockPool> &pool) {
    332     // Initialize output work
    333     work->result = C2_OK;
    334     work->workletsProcessed = 1u;
    335     work->worklets.front()->output.configUpdate.clear();
    336     work->worklets.front()->output.flags = work->input.flags;
    337 
    338     if (mSignalledError || mSignalledOutputEos) {
    339         work->result = C2_BAD_VALUE;
    340         return;
    341     }
    342 
    343     bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
    344     size_t inSize = 0u;
    345     C2ReadView rView = mDummyReadView;
    346     if (!work->input.buffers.empty()) {
    347         rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
    348         inSize = rView.capacity();
    349         if (inSize && rView.error()) {
    350             ALOGE("read view map failed %d", rView.error());
    351             work->result = rView.error();
    352             return;
    353         }
    354     }
    355 
    356     if (inSize == 0 && (!mGaplessBytes || !eos)) {
    357         work->worklets.front()->output.flags = work->input.flags;
    358         work->worklets.front()->output.buffers.clear();
    359         work->worklets.front()->output.ordinal = work->input.ordinal;
    360         return;
    361     }
    362     ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
    363           (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
    364 
    365     int32_t numChannels = mConfig->num_channels;
    366     size_t calOutSize;
    367     std::vector<size_t> decodedSizes;
    368     if (inSize && OK != calculateOutSize(const_cast<uint8 *>(rView.data()),
    369                                          inSize, &decodedSizes)) {
    370         work->result = C2_CORRUPTED;
    371         return;
    372     }
    373     calOutSize = std::accumulate(decodedSizes.begin(), decodedSizes.end(), 0);
    374     if (eos) {
    375         calOutSize += kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
    376     }
    377 
    378     std::shared_ptr<C2LinearBlock> block;
    379     C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
    380     c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
    381     if (err != C2_OK) {
    382         ALOGE("fetchLinearBlock for Output failed with status %d", err);
    383         work->result = C2_NO_MEMORY;
    384         return;
    385     }
    386     C2WriteView wView = block->map().get();
    387     if (wView.error()) {
    388         ALOGE("write view map failed %d", wView.error());
    389         work->result = wView.error();
    390         return;
    391     }
    392 
    393     int outSize = 0;
    394     int outOffset = 0;
    395     auto it = decodedSizes.begin();
    396     size_t inPos = 0;
    397     int32_t samplingRate = mConfig->samplingRate;
    398     while (inPos < inSize) {
    399         if (it == decodedSizes.end()) {
    400             ALOGE("unexpected trailing bytes, ignoring them");
    401             break;
    402         }
    403 
    404         mConfig->pInputBuffer = const_cast<uint8 *>(rView.data() + inPos);
    405         mConfig->inputBufferCurrentLength = (inSize - inPos);
    406         mConfig->inputBufferMaxLength = 0;
    407         mConfig->inputBufferUsedLength = 0;
    408         mConfig->outputFrameSize = (calOutSize - outSize);
    409         mConfig->pOutputBuffer = reinterpret_cast<int16_t *> (wView.data() + outSize);
    410 
    411         ERROR_CODE decoderErr;
    412         if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
    413                 != NO_DECODING_ERROR) {
    414             ALOGE("mp3 decoder returned error %d", decoderErr);
    415             if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
    416                     && decoderErr != SIDE_INFO_ERROR) {
    417                 mSignalledError = true;
    418                 work->result = C2_CORRUPTED;
    419                 return;
    420             }
    421 
    422             // This is recoverable, just ignore the current frame and
    423             // play silence instead.
    424             ALOGV("ignoring error and sending silence");
    425             if (mConfig->outputFrameSize == 0) {
    426                 mConfig->outputFrameSize = *it / sizeof(int16_t);
    427             }
    428             memset(mConfig->pOutputBuffer, 0, mConfig->outputFrameSize * sizeof(int16_t));
    429         } else if (mConfig->samplingRate != samplingRate
    430                 || mConfig->num_channels != numChannels) {
    431             ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
    432                    samplingRate, mConfig->samplingRate,
    433                    numChannels, mConfig->num_channels);
    434             samplingRate = mConfig->samplingRate;
    435             numChannels = mConfig->num_channels;
    436 
    437             C2StreamSampleRateInfo::output sampleRateInfo(0u, samplingRate);
    438             C2StreamChannelCountInfo::output channelCountInfo(0u, numChannels);
    439             std::vector<std::unique_ptr<C2SettingResult>> failures;
    440             c2_status_t err = mIntf->config(
    441                     { &sampleRateInfo, &channelCountInfo },
    442                     C2_MAY_BLOCK,
    443                     &failures);
    444             if (err == OK) {
    445                 work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
    446                 work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
    447             } else {
    448                 ALOGE("Config Update failed");
    449                 mSignalledError = true;
    450                 work->result = C2_CORRUPTED;
    451                 return;
    452             }
    453         }
    454         if (*it != mConfig->outputFrameSize * sizeof(int16_t)) {
    455             ALOGE("panic, parsed size does not match decoded size");
    456             mSignalledError = true;
    457             work->result = C2_CORRUPTED;
    458             return;
    459         }
    460         outSize += mConfig->outputFrameSize * sizeof(int16_t);
    461         inPos += mConfig->inputBufferUsedLength;
    462         it++;
    463     }
    464     if (mIsFirst) {
    465         mIsFirst = false;
    466         mGaplessBytes = true;
    467         // The decoder delay is 529 samples, so trim that many samples off
    468         // the start of the first output buffer. This essentially makes this
    469         // decoder have zero delay, which the rest of the pipeline assumes.
    470         outOffset = kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
    471         mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
    472     }
    473     if (eos) {
    474         if (calOutSize >=
    475             outSize + kPVMP3DecoderDelay * numChannels * sizeof(int16_t)) {
    476             if (!memset(reinterpret_cast<int16_t*>(wView.data() + outSize), 0,
    477                         kPVMP3DecoderDelay * numChannels * sizeof(int16_t))) {
    478                 mSignalledError = true;
    479                 work->result = C2_CORRUPTED;
    480                 return;
    481              }
    482             ALOGV("Adding 529 samples at end");
    483             mGaplessBytes = false;
    484             outSize += kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
    485         }
    486     }
    487 
    488     uint64_t outTimeStamp = mProcessedSamples * 1000000ll / samplingRate;
    489     mProcessedSamples += ((outSize - outOffset) / (numChannels * sizeof(int16_t)));
    490     ALOGV("out buffer attr. offset %d size %d timestamp %u", outOffset, outSize - outOffset,
    491           (uint32_t)(mAnchorTimeStamp + outTimeStamp));
    492     decodedSizes.clear();
    493     work->worklets.front()->output.flags = work->input.flags;
    494     work->worklets.front()->output.buffers.clear();
    495     work->worklets.front()->output.buffers.push_back(
    496             createLinearBuffer(block, outOffset, outSize - outOffset));
    497     work->worklets.front()->output.ordinal = work->input.ordinal;
    498     work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
    499     if (eos) {
    500         mSignalledOutputEos = true;
    501         ALOGV("signalled EOS");
    502     }
    503 }
    504 
    505 class C2SoftMp3DecFactory : public C2ComponentFactory {
    506 public:
    507     C2SoftMp3DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
    508             GetCodec2PlatformComponentStore()->getParamReflector())) {
    509     }
    510 
    511     virtual c2_status_t createComponent(
    512             c2_node_id_t id,
    513             std::shared_ptr<C2Component>* const component,
    514             std::function<void(C2Component*)> deleter) override {
    515         *component = std::shared_ptr<C2Component>(
    516               new C2SoftMP3(COMPONENT_NAME,
    517                             id,
    518                             std::make_shared<C2SoftMP3::IntfImpl>(mHelper)),
    519               deleter);
    520         return C2_OK;
    521     }
    522 
    523     virtual c2_status_t createInterface(
    524             c2_node_id_t id,
    525             std::shared_ptr<C2ComponentInterface>* const interface,
    526             std::function<void(C2ComponentInterface*)> deleter) override {
    527         *interface = std::shared_ptr<C2ComponentInterface>(
    528               new SimpleInterface<C2SoftMP3::IntfImpl>(
    529                       COMPONENT_NAME, id, std::make_shared<C2SoftMP3::IntfImpl>(mHelper)),
    530               deleter);
    531         return C2_OK;
    532     }
    533 
    534     virtual ~C2SoftMp3DecFactory() override = default;
    535 
    536 private:
    537     std::shared_ptr<C2ReflectorHelper> mHelper;
    538 };
    539 
    540 }  // namespace android
    541 
    542 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
    543     ALOGV("in %s", __func__);
    544     return new ::android::C2SoftMp3DecFactory();
    545 }
    546 
    547 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
    548     ALOGV("in %s", __func__);
    549     delete factory;
    550 }
    551