• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define HST_LOG_TAG "Minimp3DemuxerPlugin"
17 
18 #include "minimp3_demuxer_plugin.h"
19 #include <algorithm>
20 #include <cstdio>
21 #include <cstring>
22 #include <new>
23 #include "foundation/log.h"
24 #include "foundation/osal/utils/util.h"
25 #include "foundation/utils/constants.h"
26 #include "plugin/common/plugin_buffer.h"
27 #include "plugin/common/plugin_time.h"
28 
29 namespace OHOS {
30 namespace Media {
31 namespace Plugin {
32 namespace Minimp3 {
33 namespace {
34 constexpr uint32_t MAX_SAMPLES_PERFRAME    = 1152 * 2;
35 constexpr uint32_t MP3_SEEK_DISCARD_ITEMS  = 2;
36 constexpr uint32_t ID3_DETECT_SIZE         = 10;
37 constexpr uint32_t PROBE_READ_LENGTH       = 16 * 1024;
38 constexpr uint32_t MAX_RANK                = 100;
39 constexpr uint32_t MEDIA_IO_SIZE           = 4 * 1024;
40 constexpr uint32_t MAX_FRAME_SIZE          = MEDIA_IO_SIZE;
41 constexpr uint32_t AUDIO_DEMUXER_SOURCE_ONCE_LENGTH_MAX = 1024;
42 uint32_t durationMs = 0;
43 uint32_t fileSize = 0;
44 AudioDemuxerMp3Attr mp3ProbeAttr;
45 AudioDemuxerRst mp3ProbeRst;
46 std::vector<uint32_t> infoLayer         = {1, 2, 3};
47 std::vector<uint32_t> infoSampleRate    = {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000};
48 std::vector<uint32_t> infoBitrateKbps   = {8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176,
49                                            192, 224, 256, 288, 320, 352, 384, 416, 448};
50 size_t AudioDecmuxerMp3Id3v2SizeCalculate(const uint8_t *buf);
51 bool AudioDemuxerMp3HasId3v2(const uint8_t *buf);
52 size_t AudioDemuxerMp3GetId3v2Size(const uint8_t *buf, size_t bufSize);
53 int AudioDemuxerMp3ProbeDecodeCheck(Mp3DemuxerFrameInfo *info);
54 int AudioDemuxerMp3IterateCallbackForProbe(void *userData, const uint8_t *frame, int frameSize, int freeFormatBytes,
55                                            size_t bufSize, uint64_t offset, Mp3DemuxerFrameInfo *info);
56 Status AudioDemuxerMp3Probe(AudioDemuxerMp3Attr *mp3DemuxerAttr, uint8_t *inputBuffer, uint32_t inputLength,
57                             AudioDemuxerRst *mp3DemuxerRst);
58 int Sniff(const std::string& pluginName, std::shared_ptr<DataSource> dataSource);
59 Status RegisterPlugin(const std::shared_ptr<Register>& reg);
60 }
61 
Minimp3DemuxerPlugin(std::string name)62 Minimp3DemuxerPlugin::Minimp3DemuxerPlugin(std::string name)
63     : DemuxerPlugin(std::move(name)),
64       inIoBufferSize_(MEDIA_IO_SIZE),
65       fileSize_(0),
66       inIoBuffer_(nullptr),
67       ioDataRemainSize_(0),
68       currentDemuxerPos_(0),
69       durationMs_(0),
70       ioContext_()
71 {
72     FALSE_LOG(memset_s(&mp3DemuxerAttr_, sizeof(mp3DemuxerAttr_), 0x00, sizeof(AudioDemuxerMp3Attr)) == 0);
73     FALSE_LOG(memset_s(&mp3DemuxerRst_, sizeof(mp3DemuxerRst_), 0x00, sizeof(AudioDemuxerRst)) == 0);
74     FALSE_LOG(memset_s(&mp3ProbeAttr, sizeof(mp3ProbeAttr), 0x00, sizeof(AudioDemuxerMp3Attr)) == 0);
75     FALSE_LOG(memset_s(&mp3ProbeRst, sizeof(mp3ProbeRst), 0x00, sizeof(AudioDemuxerRst)) == 0);
76     FALSE_LOG(memset_s(&minimp3DemuxerImpl_, sizeof(minimp3DemuxerImpl_), 0x00, sizeof(Minimp3DemuxerOp)) == 0);
77     MEDIA_LOG_I("Minimp3DemuxerPlugin, plugin name: " PUBLIC_LOG_S, pluginName_.c_str());
78 }
79 
~Minimp3DemuxerPlugin()80 Minimp3DemuxerPlugin::~Minimp3DemuxerPlugin()
81 {
82     MEDIA_LOG_I("~Minimp3DemuxerPlugin");
83 }
84 
SetDataSource(const std::shared_ptr<DataSource> & source)85 Status Minimp3DemuxerPlugin::SetDataSource(const std::shared_ptr<DataSource>& source)
86 {
87     ioContext_.dataSource = source;
88     if (ioContext_.dataSource != nullptr) {
89         ioContext_.dataSource->GetSize(fileSize_);
90     }
91     mp3DemuxerAttr_.fileSize = fileSize_;
92     fileSize = fileSize_;
93     seekable_ = source->GetSeekable();
94     MEDIA_LOG_I("fileSize_ " PUBLIC_LOG_ZU, fileSize_);
95     return Status::OK;
96 }
97 
DoReadFromSource(uint32_t readSize)98 Status Minimp3DemuxerPlugin::DoReadFromSource(uint32_t readSize)
99 {
100     auto buffer = std::make_shared<Buffer>();
101     auto bufData = buffer->AllocMemory(nullptr, readSize);
102     int retryTimes = 0;
103     MEDIA_LOG_DD("ioNeedReadSize " PUBLIC_LOG_U32 " inIoBufferSize_ " PUBLIC_LOG_D32 " ioDataRemainSize_ "
104                 PUBLIC_LOG_U32, readSize, inIoBufferSize_, ioDataRemainSize_);
105     do {
106         auto res = ioContext_.dataSource->ReadAt(ioContext_.offset, buffer, static_cast<size_t>(readSize));
107         FALSE_RETURN_V_MSG_W(res == Status::OK, res, "read data from source error " PUBLIC_LOG_D32, (int)res);
108         if (bufData->GetSize() == 0 && retryTimes < 200 && ioDataRemainSize_ == 0) { // 200
109             MEDIA_LOG_DD("bufData->GetSize() == 0 retryTimes = " PUBLIC_LOG_D32, retryTimes);
110             OSAL::SleepFor(30); // 30
111             retryTimes++;
112             continue;
113         }
114         FALSE_RETURN_V_MSG_E(retryTimes < 200, Status::ERROR_NOT_ENOUGH_DATA, // 200 times
115                              "not eof, but doesn't have enough data");
116         MEDIA_LOG_DD("bufData->GetSize() " PUBLIC_LOG "d", bufData->GetSize());
117         if (bufData->GetSize() > 0) {
118             if (readSize < bufData->GetSize()) {
119                 MEDIA_LOG_E("Error: ioNeedReadSize < bufData->GetSize()");
120                 return Status::ERROR_UNKNOWN;
121             }
122             auto ret = memcpy_s(inIoBuffer_ + ioDataRemainSize_, readSize,
123                                 const_cast<uint8_t *>(bufData->GetReadOnlyData()), bufData->GetSize());
124             if (ret != EOK) {
125                 MEDIA_LOG_W("memcpy into buffer failed with code " PUBLIC_LOG_D32, ret);
126                 return Status::ERROR_UNKNOWN;
127             }
128             ioContext_.offset += bufData->GetSize();
129             ioDataRemainSize_ += bufData->GetSize();
130         }
131         break;
132     } while (true);
133     return Status::OK;
134 }
135 
GetDataFromSource()136 Status Minimp3DemuxerPlugin::GetDataFromSource()
137 {
138     uint32_t ioNeedReadSize = inIoBufferSize_ - ioDataRemainSize_;
139     MEDIA_LOG_DD("remain size_ " PUBLIC_LOG_D32 " need read size " PUBLIC_LOG_D32, ioDataRemainSize_, ioNeedReadSize);
140     if (ioDataRemainSize_) {
141         // 将剩余数据移动到buffer的起始位置
142         auto ret = memmove_s(inIoBuffer_, ioDataRemainSize_, inIoBuffer_ + mp3DemuxerRst_.usedInputLength,
143             ioDataRemainSize_);
144         FALSE_RETURN_V_MSG_W(ret == 0, Status::ERROR_UNKNOWN, "copy buffer error " PUBLIC_LOG_D32, ret);
145         ret = memset_s(inIoBuffer_ + ioDataRemainSize_, ioNeedReadSize, 0x00, ioNeedReadSize);
146         FALSE_RETURN_V_MSG_W(ret == 0, Status::ERROR_UNKNOWN, "memset_s buffer error " PUBLIC_LOG_D32, ret);
147     }
148     if (ioContext_.offset >= fileSize_ && ioDataRemainSize_ == 0) {
149         ioContext_.eos = true;
150         return Status::END_OF_STREAM;
151     }
152     if (ioContext_.offset + ioNeedReadSize > fileSize_) {
153         ioNeedReadSize = fileSize_ - ioContext_.offset; // 在读取文件即将结束时,剩余数据不足,更新读取长度
154     }
155     if (ioNeedReadSize == 0) {
156         return Status::OK;
157     }
158     return DoReadFromSource(ioNeedReadSize);
159 }
160 
FillInMediaInfo(MediaInfo & mediaInfo) const161 void Minimp3DemuxerPlugin::FillInMediaInfo(MediaInfo& mediaInfo) const
162 {
163     mediaInfo.tracks.resize(1);
164     if (mp3DemuxerRst_.frameChannels == 1) {
165         mediaInfo.tracks[0].Set<Tag::AUDIO_CHANNEL_LAYOUT>(AudioChannelLayout::MONO);
166     } else {
167         mediaInfo.tracks[0].Set<Tag::AUDIO_CHANNEL_LAYOUT>(AudioChannelLayout::STEREO);
168     }
169     int64_t durationHst;
170     Ms2HstTime(durationMs, durationHst);
171     mediaInfo.tracks[0].Set<Tag::MEDIA_TYPE>(MediaType::AUDIO);
172     mediaInfo.tracks[0].Set<Tag::AUDIO_SAMPLE_RATE>(mp3DemuxerRst_.frameSampleRate);
173     mediaInfo.tracks[0].Set<Tag::MEDIA_BITRATE>(mp3DemuxerRst_.frameBitrateKbps);
174     mediaInfo.tracks[0].Set<Tag::AUDIO_CHANNELS>(mp3DemuxerRst_.frameChannels);
175     mediaInfo.tracks[0].Set<Tag::TRACK_ID>(0);
176     mediaInfo.tracks[0].Set<Tag::MIME>(MEDIA_MIME_AUDIO_MPEG);
177     mediaInfo.tracks[0].Set<Tag::AUDIO_MPEG_VERSION>(1);
178     mediaInfo.tracks[0].Set<Tag::AUDIO_MPEG_LAYER>(mp3DemuxerRst_.audioLayer);
179     mediaInfo.tracks[0].Set<Tag::AUDIO_SAMPLE_PER_FRAME>(mp3DemuxerRst_.samplesPerFrame);
180     mediaInfo.tracks[0].Set<Tag::MEDIA_DURATION>(durationHst);
181 }
182 
GetMediaInfo(MediaInfo & mediaInfo)183 Status Minimp3DemuxerPlugin::GetMediaInfo(MediaInfo& mediaInfo)
184 {
185     int processLoop = 1;
186     Status status;
187     while (processLoop) {
188         status = GetDataFromSource();
189         if (status != Status::OK) {
190             return status;
191         }
192         status = AudioDemuxerMp3Prepare(&mp3DemuxerAttr_, inIoBuffer_, ioDataRemainSize_, &mp3DemuxerRst_);
193         switch (status) {
194             case Status::ERROR_NOT_ENOUGH_DATA:
195                 MEDIA_LOG_D("GetMediaInfo: need more data usedInputLength " PUBLIC_LOG_U64,
196                             mp3DemuxerRst_.usedInputLength);
197                 ioDataRemainSize_ -= mp3DemuxerRst_.usedInputLength;
198                 currentDemuxerPos_ += mp3DemuxerRst_.usedInputLength;
199                 processLoop = 1;
200                 break;
201             case Status::OK:
202                 MEDIA_LOG_D("GetMediaInfo: OK usedInputLength " PUBLIC_LOG_U64, mp3DemuxerRst_.usedInputLength);
203                 ioDataRemainSize_ -= mp3DemuxerRst_.usedInputLength;
204                 currentDemuxerPos_ += mp3DemuxerRst_.usedInputLength;
205                 FillInMediaInfo(mediaInfo);
206                 processLoop = 0;
207                 break;
208             case Status::ERROR_UNSUPPORTED_FORMAT:
209                 return Status::ERROR_UNSUPPORTED_FORMAT;
210             case Status::ERROR_UNKNOWN:
211             default:
212                 MEDIA_LOG_I("AUDIO_DEMUXER_PREPARE_UNMATCHED_FORMAT " PUBLIC_LOG_D32, status);
213                 return Status::ERROR_UNKNOWN;
214         }
215     }
216 
217     mp3DemuxerAttr_.bitRate = mp3DemuxerRst_.frameBitrateKbps;
218     MEDIA_LOG_D("mp3DemuxerAttr_.bitRate " PUBLIC_LOG_U32 "kbps durationMs " PUBLIC_LOG_U32 " ms",
219                 mp3DemuxerRst_.frameBitrateKbps, durationMs);
220     return Status::OK;
221 }
222 
GetCurrentPositionTimeS(void)223 uint64_t Minimp3DemuxerPlugin::GetCurrentPositionTimeS(void)
224 {
225     uint64_t currentTime = (static_cast<uint64_t>(currentDemuxerPos_ - mp3DemuxerAttr_.id3v2Size) * 8 * HST_MSECOND) /
226         mp3DemuxerAttr_.bitRate;
227     return currentTime;
228 }
229 
WriteMp3Data(Buffer & outBuffer)230 void Minimp3DemuxerPlugin::WriteMp3Data(Buffer& outBuffer)
231 {
232     std::shared_ptr<Memory> mp3FrameData;
233     if (outBuffer.IsEmpty()) {
234         mp3FrameData = outBuffer.AllocMemory(nullptr, mp3DemuxerRst_.frameLength);
235     } else {
236         mp3FrameData = outBuffer.GetMemory();
237     }
238     MEDIA_LOG_DD("ReadFrame: success usedInputLength " PUBLIC_LOG_D32 " ioDataRemainSize_ " PUBLIC_LOG_D32,
239                  (uint32_t)mp3DemuxerRst_.usedInputLength, ioDataRemainSize_);
240     if (mp3DemuxerRst_.frameLength) {
241         mp3FrameData->Write(mp3DemuxerRst_.frameBuffer, mp3DemuxerRst_.frameLength);
242         ioDataRemainSize_ -= mp3DemuxerRst_.usedInputLength;
243         currentDemuxerPos_ += mp3DemuxerRst_.usedInputLength;
244     } else if (mp3DemuxerRst_.usedInputLength == 0) {
245         if (ioDataRemainSize_ > AUDIO_DEMUXER_SOURCE_ONCE_LENGTH_MAX) {
246             ioDataRemainSize_ = ioDataRemainSize_ - AUDIO_DEMUXER_SOURCE_ONCE_LENGTH_MAX;
247             currentDemuxerPos_ += AUDIO_DEMUXER_SOURCE_ONCE_LENGTH_MAX;
248         } else {
249             currentDemuxerPos_ += ioDataRemainSize_;
250             ioDataRemainSize_ = 0;
251         }
252     } else {
253         ioDataRemainSize_ -= mp3DemuxerRst_.usedInputLength;
254         currentDemuxerPos_ += mp3DemuxerRst_.usedInputLength;
255     }
256     outBuffer.pts = GetCurrentPositionTimeS();
257     MEDIA_LOG_DD("ReadFrame: mp3DemuxerRst_.frameLength " PUBLIC_LOG_U32 ", pts " PUBLIC_LOG_U64,
258                  mp3DemuxerRst_.frameLength, outBuffer.pts);
259     if (mp3DemuxerRst_.frameBuffer) {
260         free(mp3DemuxerRst_.frameBuffer);
261         mp3DemuxerRst_.frameBuffer = nullptr;
262     }
263 }
264 
ReadFrame(Buffer & outBuffer,int32_t timeOutMs)265 Status Minimp3DemuxerPlugin::ReadFrame(Buffer& outBuffer, int32_t timeOutMs)
266 {
267     int  status  = -1;
268     Status retResult = Status::OK;
269     NOK_RETURN(GetDataFromSource());
270     MEDIA_LOG_DD("ioDataRemainSize_ = " PUBLIC_LOG_D32, ioDataRemainSize_);
271     status = AudioDemuxerMp3Process(inIoBuffer_, ioDataRemainSize_);
272     MEDIA_LOG_DD("status = " PUBLIC_LOG_D32, status);
273     switch (status) {
274         case AUDIO_DEMUXER_SUCCESS:
275             WriteMp3Data(outBuffer);
276             break;
277         case AUDIO_DEMUXER_PROCESS_NEED_MORE_DATA:
278             ioDataRemainSize_ -= mp3DemuxerRst_.usedInputLength;
279             currentDemuxerPos_ += mp3DemuxerRst_.usedInputLength;
280             MEDIA_LOG_D("ReadFrame: need more data usedInputLength " PUBLIC_LOG_U64 " ioDataRemainSize_ "
281                         PUBLIC_LOG_U32, mp3DemuxerRst_.usedInputLength, ioDataRemainSize_);
282             break;
283         case AUDIO_DEMUXER_ERROR:
284         default:
285             MEDIA_LOG_E("ReadFrame error");
286             if (mp3DemuxerRst_.frameBuffer) {
287                 free(mp3DemuxerRst_.frameBuffer);
288                 mp3DemuxerRst_.frameBuffer = nullptr;
289             }
290             retResult = Status::ERROR_UNKNOWN;
291             break;
292     }
293     return retResult;
294 }
295 
SeekTo(int32_t trackId,int64_t seekTime,SeekMode mode,int64_t & realSeekTime)296 Status Minimp3DemuxerPlugin::SeekTo(int32_t trackId, int64_t seekTime, SeekMode mode, int64_t& realSeekTime)
297 {
298     uint64_t pos = 0;
299     uint32_t targetTimeMs = static_cast<uint32_t>(HstTime2Ms(seekTime));
300     if (AudioDemuxerMp3GetSeekPosition(targetTimeMs, &pos) == 0) {
301         ioContext_.offset = pos;
302         ioDataRemainSize_ = 0;
303         currentDemuxerPos_ = pos;
304         MEDIA_LOG_D("ioContext_.offset " PUBLIC_LOG_D32, static_cast<uint32_t>(ioContext_.offset));
305         (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
306     } else {
307         return Status::ERROR_INVALID_PARAMETER;
308     }
309     return Status::OK;
310 }
311 
Init()312 Status Minimp3DemuxerPlugin::Init()
313 {
314     minimp3DemuxerImpl_ = MiniMp3GetOpt();
315     AudioDemuxerMp3Open();
316     inIoBuffer_ = (uint8_t *)(malloc(inIoBufferSize_));
317     if (inIoBuffer_ == nullptr) {
318         MEDIA_LOG_E("inIoBuffer_ malloc failed");
319         return Status::ERROR_NO_MEMORY;
320     }
321     (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
322     return Status::OK;
323 }
324 
Deinit()325 Status Minimp3DemuxerPlugin::Deinit()
326 {
327     if (inIoBuffer_) {
328         free(inIoBuffer_);
329         inIoBuffer_ = nullptr;
330     }
331     return Status::OK;
332 }
333 
Prepare()334 Status Minimp3DemuxerPlugin::Prepare()
335 {
336     return Status::OK;
337 }
338 
Reset()339 Status Minimp3DemuxerPlugin::Reset()
340 {
341     ioContext_.eos = false;
342     ioContext_.dataSource.reset();
343     ioContext_.offset = 0;
344     ioDataRemainSize_ = 0;
345     currentDemuxerPos_ = 0;
346     (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
347     return Status::OK;
348 }
349 
Start()350 Status Minimp3DemuxerPlugin::Start()
351 {
352     return Status::OK;
353 }
354 
Stop()355 Status Minimp3DemuxerPlugin::Stop()
356 {
357     return Status::OK;
358 }
359 
GetParameter(Tag tag,ValueType & value)360 Status Minimp3DemuxerPlugin::GetParameter(Tag tag, ValueType &value)
361 {
362     return Status::ERROR_UNIMPLEMENTED;
363 }
364 
SetParameter(Tag tag,const ValueType & value)365 Status Minimp3DemuxerPlugin::SetParameter(Tag tag, const ValueType &value)
366 {
367     return Status::ERROR_UNIMPLEMENTED;
368 }
369 
GetAllocator()370 std::shared_ptr<Allocator> Minimp3DemuxerPlugin::GetAllocator()
371 {
372     return nullptr;
373 }
374 
SetCallback(Callback * cb)375 Status Minimp3DemuxerPlugin::SetCallback(Callback* cb)
376 {
377     return Status::OK;
378 }
379 
GetTrackCount()380 size_t Minimp3DemuxerPlugin::GetTrackCount()
381 {
382     return 0;
383 }
SelectTrack(int32_t trackId)384 Status Minimp3DemuxerPlugin::SelectTrack(int32_t trackId)
385 {
386     return Status::OK;
387 }
UnselectTrack(int32_t trackId)388 Status Minimp3DemuxerPlugin::UnselectTrack(int32_t trackId)
389 {
390     return Status::OK;
391 }
GetSelectedTracks(std::vector<int32_t> & trackIds)392 Status Minimp3DemuxerPlugin::GetSelectedTracks(std::vector<int32_t>& trackIds)
393 {
394     return Status::OK;
395 }
396 
AudioDemuxerMp3IgnoreTailZero(uint8_t * data,uint32_t * dataLen)397 void Minimp3DemuxerPlugin::AudioDemuxerMp3IgnoreTailZero(uint8_t *data, uint32_t *dataLen)
398 {
399     if ((data == nullptr) || (dataLen == nullptr) || (*dataLen == 0)) {
400         return;
401     }
402 
403     uint32_t len = *dataLen;
404     uint8_t  *ptr = data + len - 1;
405 
406     do {
407         if (*ptr == 0) {
408             ptr--;
409             len--;
410         } else {
411             break;
412         }
413     } while (len);
414 
415     *dataLen = len;
416 }
417 
AudioDemuxerMp3IterateCallback(void * userData,const uint8_t * frame,int frameSize,int freeFormatBytes,size_t bufSize,uint64_t offset,Mp3DemuxerFrameInfo * info)418 int Minimp3DemuxerPlugin::AudioDemuxerMp3IterateCallback(void *userData, const uint8_t *frame, int frameSize,
419                                                          int freeFormatBytes, size_t bufSize, uint64_t offset,
420                                                          Mp3DemuxerFrameInfo *info)
421 {
422     AudioDemuxerMp3Attr *mp3Demuxer = static_cast<AudioDemuxerMp3Attr *>(userData);
423     AudioDemuxerRst *rst = mp3Demuxer->rst;
424     uint64_t usedInputLength = 0;
425 
426     if (mp3Demuxer->internalRemainLen >= offset + frameSize) {
427         usedInputLength = offset + frameSize;
428     } else if (mp3Demuxer->internalRemainLen >= offset) {
429         usedInputLength = offset;
430     } else {
431         usedInputLength = 0;
432     }
433     MEDIA_LOG_DD("offset = " PUBLIC_LOG_U64 " internalRemainLen " PUBLIC_LOG_U32 " frameSize "
434                 PUBLIC_LOG_D32, offset, mp3Demuxer->internalRemainLen, frameSize);
435 
436     if (frameSize == 0) {
437         rst->usedInputLength = 0;
438         rst->frameBuffer = nullptr;
439         rst->frameLength = 0;
440         return 0;
441     }
442 
443     if (frameSize >= MAX_FRAME_SIZE) {
444         return AUDIO_DEMUXER_ERROR;
445     }
446 
447     uint8_t *rstFrame = static_cast<uint8_t *>(calloc(frameSize, sizeof(uint8_t)));
448     if (!rstFrame) {
449         MEDIA_LOG_E("rstFrame null error");
450         return AUDIO_DEMUXER_ERROR;
451     }
452 
453     (void)memcpy_s(rstFrame, frameSize, frame, frameSize);
454     rst->frameBuffer = rstFrame;
455     rst->frameLength = frameSize;
456     rst->frameBitrateKbps = info->bitrate_kbps;
457     rst->frameChannels    = info->channels;
458     rst->frameSampleRate  = info->hz;
459     rst->usedInputLength  = usedInputLength;
460     return 1;
461 }
462 
AudioDemuxerMp3IterateCallbackForPrepare(void * userData,const uint8_t * frame,int frameSize,int freeFormatBytes,size_t bufSize,uint64_t offset,Mp3DemuxerFrameInfo * info)463 int Minimp3DemuxerPlugin::AudioDemuxerMp3IterateCallbackForPrepare(void *userData, const uint8_t *frame,
464                                                                    int frameSize, int freeFormatBytes,
465                                                                    size_t bufSize, uint64_t offset,
466                                                                    Mp3DemuxerFrameInfo *info)
467 {
468     return AudioDemuxerMp3IterateCallbackForProbe(userData, frame, frameSize, freeFormatBytes, bufSize, offset, info);
469 }
470 
AudioDemuxerMp3Open()471 void Minimp3DemuxerPlugin::AudioDemuxerMp3Open()
472 {
473     minimp3DemuxerImpl_.init(&mp3DemuxerAttr_.mp3DemuxerHandle);
474     return;
475 }
476 
AudioDemuxerMp3Close()477 int  Minimp3DemuxerPlugin::AudioDemuxerMp3Close()
478 {
479     return 0;
480 }
481 
AudioDemuxerMp3Prepare(AudioDemuxerMp3Attr * mp3DemuxerAttr,uint8_t * inputBuffer,uint32_t inputLength,AudioDemuxerRst * mp3DemuxerRst)482 Status Minimp3DemuxerPlugin::AudioDemuxerMp3Prepare(AudioDemuxerMp3Attr *mp3DemuxerAttr, uint8_t *inputBuffer,
483                                                     uint32_t inputLength, AudioDemuxerRst *mp3DemuxerRst)
484 {
485     return AudioDemuxerMp3Probe(mp3DemuxerAttr, inputBuffer, inputLength, mp3DemuxerRst);
486 }
487 
AudioDemuxerMp3Process(uint8_t * buf,uint32_t len)488 int Minimp3DemuxerPlugin::AudioDemuxerMp3Process(uint8_t *buf, uint32_t len)
489 {
490     if ((buf == nullptr) || (len < 0)) {
491         MEDIA_LOG_E(PUBLIC_LOG_S " arg error", __func__);
492         return AUDIO_DEMUXER_ERROR;
493     }
494     if (len == 0) {
495         MEDIA_LOG_W("len == 0");
496         return AUDIO_DEMUXER_PROCESS_NEED_MORE_DATA;
497     }
498     int ret = 0;
499     uint32_t processLen = len;
500     AudioDemuxerMp3IgnoreTailZero(buf, &processLen);
501     // this memset_s will always success
502     (void)memset_s(&mp3DemuxerRst_, sizeof(AudioDemuxerRst), 0x00, sizeof(AudioDemuxerRst));
503     mp3DemuxerAttr_.rst = &mp3DemuxerRst_;
504     mp3DemuxerAttr_.internalRemainLen = processLen;
505     ret = minimp3DemuxerImpl_.iterateBuf(buf, processLen, AudioDemuxerMp3IterateCallback, &mp3DemuxerAttr_);
506     if (mp3DemuxerAttr_.mp3SeekFlag == 1 && mp3DemuxerAttr_.discardItemCount < MP3_SEEK_DISCARD_ITEMS) {
507         (void)memset_s(mp3DemuxerRst_.frameBuffer, mp3DemuxerRst_.frameLength, 0x00, mp3DemuxerRst_.frameLength);
508         mp3DemuxerAttr_.discardItemCount++;
509     } else {
510         mp3DemuxerAttr_.discardItemCount = 0;
511         mp3DemuxerAttr_.mp3SeekFlag = 0;
512     }
513     if (ret == 0 || ret == 1) {
514         return AUDIO_DEMUXER_SUCCESS;
515     } else {
516         return AUDIO_DEMUXER_ERROR;
517     }
518 }
519 
AudioDemuxerMp3FreeFrame(uint8_t * frame)520 int Minimp3DemuxerPlugin::AudioDemuxerMp3FreeFrame(uint8_t *frame)
521 {
522     if (frame) {
523         free(frame);
524         return 0;
525     } else {
526         return -1;
527     }
528 }
529 
AudioDemuxerMp3Seek(uint32_t pos,uint8_t * buf,uint32_t len,AudioDemuxerRst * rst)530 int Minimp3DemuxerPlugin::AudioDemuxerMp3Seek(uint32_t pos, uint8_t *buf, uint32_t len, AudioDemuxerRst *rst)
531 {
532     return 0;
533 }
534 
AudioDemuxerMp3GetSeekPosition(uint32_t targetTimeMs,uint64_t * pos)535 int Minimp3DemuxerPlugin::AudioDemuxerMp3GetSeekPosition(uint32_t targetTimeMs, uint64_t *pos)
536 {
537     if (!pos) {
538         MEDIA_LOG_I("pos nullptr error");
539         return AUDIO_DEMUXER_ERROR;
540     }
541     uint32_t targetPos = targetTimeMs * mp3DemuxerAttr_.bitRate / 8 + mp3DemuxerAttr_.id3v2Size;
542     if (targetPos > mp3DemuxerAttr_.fileSize) {
543         *pos = 0;
544         return -1;
545     }
546     *pos = static_cast<uint64_t>(targetPos);
547     mp3DemuxerAttr_.mp3SeekFlag = 1;
548     return 0;
549 }
550 
551 namespace {
AudioDecmuxerMp3Id3v2SizeCalculate(const uint8_t * buf)552 size_t AudioDecmuxerMp3Id3v2SizeCalculate(const uint8_t *buf)
553 {
554     return (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10;
555 }
556 
AudioDemuxerMp3HasId3v2(const uint8_t * buf)557 bool AudioDemuxerMp3HasId3v2(const uint8_t *buf)
558 {
559     return !memcmp(buf, "ID3", 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) ||
560                   (buf[8] & 0x80) || (buf[9] & 0x80));
561 }
562 
AudioDemuxerMp3GetId3v2Size(const uint8_t * buf,size_t bufSize)563 size_t AudioDemuxerMp3GetId3v2Size(const uint8_t *buf, size_t bufSize)
564 {
565     if (bufSize >= ID3_DETECT_SIZE && AudioDemuxerMp3HasId3v2(buf)) {
566         size_t id3v2Size = AudioDecmuxerMp3Id3v2SizeCalculate(buf);
567         if ((buf[5] & 16)) { // 5, 16
568             id3v2Size += 10; // 10
569         }
570         return id3v2Size;
571     }
572     return 0;
573 }
574 
AudioDemuxerMp3ProbeDecodeCheck(Mp3DemuxerFrameInfo * info)575 int AudioDemuxerMp3ProbeDecodeCheck(Mp3DemuxerFrameInfo *info)
576 {
577     if (!info) {
578         return -1;
579     }
580 
581     std::vector<uint32_t>::iterator it = find (infoLayer.begin(), infoLayer.end(), info->layer);
582     if (it == infoLayer.end()) {
583         return -1;
584     }
585 
586     it = find (infoSampleRate.begin(), infoSampleRate.end(), info->hz);
587     if (it == infoSampleRate.end()) {
588         return -1;
589     }
590 
591     it = find (infoBitrateKbps.begin(), infoBitrateKbps.end(), info->bitrate_kbps);
592     if (it == infoBitrateKbps.end()) {
593         return -1;
594     }
595 
596     return 0;
597 }
598 
AudioDemuxerMp3IterateCallbackForProbe(void * userData,const uint8_t * frame,int frameSize,int freeFormatBytes,size_t bufSize,uint64_t offset,Mp3DemuxerFrameInfo * info)599 int AudioDemuxerMp3IterateCallbackForProbe(void *userData, const uint8_t *frame, int frameSize, int freeFormatBytes,
600                                            size_t bufSize, uint64_t offset, Mp3DemuxerFrameInfo *info)
601 {
602     int sampleCount;
603     Minimp3WrapperMp3decFrameInfo frameInfo;
604     AudioDemuxerMp3Attr *mp3Demuxer = static_cast<AudioDemuxerMp3Attr *>(userData);
605     AudioDemuxerRst *rst  = mp3Demuxer->rst;
606     rst->frameBitrateKbps = info->bitrate_kbps;
607     rst->frameChannels    = info->channels;
608     rst->frameSampleRate  = info->hz;
609     rst->audioLayer       = info->layer;
610     rst->samplesPerFrame  = info->samples_per_frame;
611     sampleCount = Minimp3WrapperMp3decDecodeFrame(&mp3Demuxer->mp3DemuxerHandle, frame, frameSize,
612                                                   mp3Demuxer->probePcmBuf, &frameInfo);
613     if (sampleCount <= 0 && AudioDemuxerMp3ProbeDecodeCheck(info) != 0) {
614         return -1;
615     }
616     return 1;
617 }
618 
AudioDemuxerMp3Probe(AudioDemuxerMp3Attr * mp3DemuxerAttr,uint8_t * inputBuffer,uint32_t inputLength,AudioDemuxerRst * mp3DemuxerRst)619 Status AudioDemuxerMp3Probe(AudioDemuxerMp3Attr* mp3DemuxerAttr, uint8_t* inputBuffer, uint32_t inputLength,
620                             AudioDemuxerRst* mp3DemuxerRst)
621 {
622     FALSE_RETURN_V_MSG_W(inputBuffer != nullptr && inputLength >= 0, Status::ERROR_INVALID_PARAMETER, "invalid parameter");
623     if (inputLength == 0) {
624         return Status::ERROR_NOT_ENOUGH_DATA;
625     }
626     int ret = -1;
627     if (mp3DemuxerAttr->id3v2SkipFlag == 0) {
628         if (mp3DemuxerAttr->id3v2Offset == 0) {
629             if (inputLength < ID3_DETECT_SIZE) {
630                 mp3DemuxerRst->usedInputLength = 0;
631                 return Status::ERROR_NOT_ENOUGH_DATA;
632             } else {
633                 mp3DemuxerAttr->id3v2Size = AudioDemuxerMp3GetId3v2Size(inputBuffer, inputLength);
634                 mp3DemuxerAttr->id3v2Offset = mp3DemuxerAttr->id3v2Size;
635             }
636         }
637 
638         if (mp3DemuxerAttr->id3v2Offset) {
639             MEDIA_LOG_D("mp3 id3v2Offset = " PUBLIC_LOG_U32 ", input data inputLength " PUBLIC_LOG_U32,
640                         mp3DemuxerAttr->id3v2Offset, inputLength);
641             if (inputLength >= mp3DemuxerAttr->id3v2Offset) {
642                 mp3DemuxerRst->usedInputLength = mp3DemuxerAttr->id3v2Offset;
643                 mp3DemuxerAttr->id3v2SkipFlag  = 1;
644                 inputLength -= mp3DemuxerAttr->id3v2Offset;
645                 inputBuffer += mp3DemuxerAttr->id3v2Offset;
646                 mp3DemuxerAttr->id3v2Offset = 0;
647             } else {
648                 mp3DemuxerRst->usedInputLength = inputLength;
649                 mp3DemuxerAttr->id3v2Offset = mp3DemuxerAttr->id3v2Offset - inputLength;
650                 return Status::ERROR_NOT_ENOUGH_DATA;
651             }
652         }
653     }
654     mp3DemuxerAttr->rst = mp3DemuxerRst;
655     mp3DemuxerAttr->internalRemainLen = inputLength;
656     ret = Minimp3WrapperMp3decIterateBuf(inputBuffer, inputLength, AudioDemuxerMp3IterateCallbackForProbe,
657                                          mp3DemuxerAttr);
658     if (ret != 1) {
659         if (mp3DemuxerAttr->id3v2SkipFlag) {
660             return Status::ERROR_NOT_ENOUGH_DATA;
661         }
662         return Status::ERROR_UNSUPPORTED_FORMAT;
663     }
664     if (mp3DemuxerRst->frameBitrateKbps != 0) {
665         durationMs = static_cast<uint64_t>(fileSize * 8 / mp3DemuxerRst->frameBitrateKbps); // 8
666     }
667     MEDIA_LOG_I("bitrate_kbps = " PUBLIC_LOG_U32 " info->channels = " PUBLIC_LOG_U8 " info->hz = "
668                 PUBLIC_LOG_U32, mp3DemuxerRst->frameBitrateKbps, mp3DemuxerRst->frameChannels,
669                 mp3DemuxerRst->frameSampleRate);
670     return Status::OK;
671 }
672 
Sniff(const std::string & name,std::shared_ptr<DataSource> dataSource)673 int Sniff(const std::string& name, std::shared_ptr<DataSource> dataSource)
674 {
675     MEDIA_LOG_I("Sniff in");
676     Status status;
677     auto buffer = std::make_shared<Buffer>();
678     auto bufData = buffer->AllocMemory(nullptr, PROBE_READ_LENGTH);
679     int processLoop = 1;
680     uint8_t *inputDataPtr = nullptr;
681     int offset = 0;
682     int readSize = PROBE_READ_LENGTH;
683     uint64_t sourceSize = 0;
684     dataSource->GetSize(sourceSize);
685     while (processLoop) {
686         if (sourceSize < PROBE_READ_LENGTH && sourceSize != 0) {
687             readSize = sourceSize;
688         }
689         status = dataSource->ReadAt(offset, buffer, static_cast<size_t>(readSize));
690         if (status != Status::OK) {
691             MEDIA_LOG_E("Sniff Read Data Error");
692             return 0;
693         }
694         inputDataPtr = const_cast<uint8_t *>(bufData->GetReadOnlyData());
695 
696         status = AudioDemuxerMp3Probe(&mp3ProbeAttr, inputDataPtr, bufData->GetSize(), &mp3ProbeRst);
697         switch (status) {
698             case Status::ERROR_NOT_ENOUGH_DATA:
699                 OSAL::SleepFor(100); // 100
700                 offset += mp3ProbeRst.usedInputLength;
701                 MEDIA_LOG_D("offset " PUBLIC_LOG_D32, offset);
702                 processLoop = 1;
703                 break;
704             case Status::OK:
705                 processLoop = 0;
706                 break;
707             case Status::ERROR_UNSUPPORTED_FORMAT:
708                 return 0;
709             case Status::ERROR_UNKNOWN:
710             default:
711                 MEDIA_LOG_I("AUDIO_DEMUXER_PREPARE_UNMATCHED_FORMAT " PUBLIC_LOG_D32, status);
712                 return 0;
713         }
714     }
715     return MAX_RANK;
716 }
717 
RegisterPlugin(const std::shared_ptr<Register> & reg)718 Status RegisterPlugin(const std::shared_ptr<Register>& reg)
719 {
720     MEDIA_LOG_I("RegisterPlugin called.");
721     if (!reg) {
722         MEDIA_LOG_I("RegisterPlugin failed due to nullptr pointer for reg.");
723         return Status::ERROR_INVALID_PARAMETER;
724     }
725 
726     std::string pluginName = "Minimp3DemuxerPlugin";
727     DemuxerPluginDef regInfo;
728     regInfo.name = pluginName;
729     regInfo.description = "adapter for minimp3 demuxer plugin";
730     regInfo.rank = MAX_RANK;
731     regInfo.creator = [](const std::string &name) -> std::shared_ptr<DemuxerPlugin> {
732         return std::make_shared<Minimp3DemuxerPlugin>(name);
733     };
734     regInfo.sniffer = Sniff;
735     auto rtv = reg->AddPlugin(regInfo);
736     if (rtv != Status::OK) {
737         MEDIA_LOG_I("RegisterPlugin AddPlugin failed with return " PUBLIC_LOG_D32, static_cast<int>(rtv));
738     }
739     return Status::OK;
740 }
741 }
742 
__anon9011af210402null743 PLUGIN_DEFINITION(Minimp3Demuxer, LicenseType::CC0, RegisterPlugin, [] {});
744 } // namespace Minimp3
745 } // namespace Plugin
746 } // namespace Media
747 } // namespace OHOS
748