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