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,
55 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,uint64_t offset,Mp3DemuxerFrameInfo * info)418 int Minimp3DemuxerPlugin::AudioDemuxerMp3IterateCallback(void *userData, const uint8_t *frame, int frameSize,
419 uint64_t offset, Mp3DemuxerFrameInfo *info)
420 {
421 AudioDemuxerMp3Attr *mp3Demuxer = static_cast<AudioDemuxerMp3Attr *>(userData);
422 AudioDemuxerRst *rst = mp3Demuxer->rst;
423 uint64_t usedInputLength = 0;
424
425 if (mp3Demuxer->internalRemainLen >= offset + frameSize) {
426 usedInputLength = offset + frameSize;
427 } else if (mp3Demuxer->internalRemainLen >= offset) {
428 usedInputLength = offset;
429 } else {
430 usedInputLength = 0;
431 }
432 MEDIA_LOG_DD("offset = " PUBLIC_LOG_U64 " internalRemainLen " PUBLIC_LOG_U32 " frameSize "
433 PUBLIC_LOG_D32, offset, mp3Demuxer->internalRemainLen, frameSize);
434
435 if (frameSize == 0) {
436 rst->usedInputLength = 0;
437 rst->frameBuffer = nullptr;
438 rst->frameLength = 0;
439 return 0;
440 }
441
442 if (frameSize >= MAX_FRAME_SIZE) {
443 return AUDIO_DEMUXER_ERROR;
444 }
445
446 uint8_t *rstFrame = static_cast<uint8_t *>(calloc(frameSize, sizeof(uint8_t)));
447 if (!rstFrame) {
448 MEDIA_LOG_E("rstFrame null error");
449 return AUDIO_DEMUXER_ERROR;
450 }
451
452 (void)memcpy_s(rstFrame, frameSize, frame, frameSize);
453 rst->frameBuffer = rstFrame;
454 rst->frameLength = frameSize;
455 rst->frameBitrateKbps = info->bitrate_kbps;
456 rst->frameChannels = info->channels;
457 rst->frameSampleRate = info->hz;
458 rst->usedInputLength = usedInputLength;
459 return 1;
460 }
461
AudioDemuxerMp3IterateCallbackForPrepare(void * userData,const uint8_t * frame,int frameSize,Mp3DemuxerFrameInfo * info)462 int Minimp3DemuxerPlugin::AudioDemuxerMp3IterateCallbackForPrepare(void *userData, const uint8_t *frame,
463 int frameSize, Mp3DemuxerFrameInfo *info)
464 {
465 return AudioDemuxerMp3IterateCallbackForProbe(userData, frame, frameSize, info);
466 }
467
AudioDemuxerMp3Open()468 void Minimp3DemuxerPlugin::AudioDemuxerMp3Open()
469 {
470 minimp3DemuxerImpl_.init(&mp3DemuxerAttr_.mp3DemuxerHandle);
471 return;
472 }
473
AudioDemuxerMp3Close()474 int Minimp3DemuxerPlugin::AudioDemuxerMp3Close()
475 {
476 return 0;
477 }
478
AudioDemuxerMp3Prepare(AudioDemuxerMp3Attr * mp3DemuxerAttr,uint8_t * inputBuffer,uint32_t inputLength,AudioDemuxerRst * mp3DemuxerRst)479 Status Minimp3DemuxerPlugin::AudioDemuxerMp3Prepare(AudioDemuxerMp3Attr *mp3DemuxerAttr, uint8_t *inputBuffer,
480 uint32_t inputLength, AudioDemuxerRst *mp3DemuxerRst)
481 {
482 return AudioDemuxerMp3Probe(mp3DemuxerAttr, inputBuffer, inputLength, mp3DemuxerRst);
483 }
484
AudioDemuxerMp3Process(uint8_t * buf,uint32_t len)485 int Minimp3DemuxerPlugin::AudioDemuxerMp3Process(uint8_t *buf, uint32_t len)
486 {
487 if ((buf == nullptr) || (len < 0)) {
488 MEDIA_LOG_E(PUBLIC_LOG_S " arg error", __func__);
489 return AUDIO_DEMUXER_ERROR;
490 }
491 if (len == 0) {
492 MEDIA_LOG_W("len == 0");
493 return AUDIO_DEMUXER_PROCESS_NEED_MORE_DATA;
494 }
495 int ret = 0;
496 uint32_t processLen = len;
497 AudioDemuxerMp3IgnoreTailZero(buf, &processLen);
498 // this memset_s will always success
499 (void)memset_s(&mp3DemuxerRst_, sizeof(AudioDemuxerRst), 0x00, sizeof(AudioDemuxerRst));
500 mp3DemuxerAttr_.rst = &mp3DemuxerRst_;
501 mp3DemuxerAttr_.internalRemainLen = processLen;
502 ret = minimp3DemuxerImpl_.iterateBuf(buf, processLen, AudioDemuxerMp3IterateCallback, &mp3DemuxerAttr_);
503 if (mp3DemuxerAttr_.mp3SeekFlag == 1 && mp3DemuxerAttr_.discardItemCount < MP3_SEEK_DISCARD_ITEMS) {
504 (void)memset_s(mp3DemuxerRst_.frameBuffer, mp3DemuxerRst_.frameLength, 0x00, mp3DemuxerRst_.frameLength);
505 mp3DemuxerAttr_.discardItemCount++;
506 } else {
507 mp3DemuxerAttr_.discardItemCount = 0;
508 mp3DemuxerAttr_.mp3SeekFlag = 0;
509 }
510 if (ret == 0 || ret == 1) {
511 return AUDIO_DEMUXER_SUCCESS;
512 } else {
513 return AUDIO_DEMUXER_ERROR;
514 }
515 }
516
AudioDemuxerMp3FreeFrame(uint8_t * frame)517 int Minimp3DemuxerPlugin::AudioDemuxerMp3FreeFrame(uint8_t *frame)
518 {
519 if (frame) {
520 free(frame);
521 return 0;
522 } else {
523 return -1;
524 }
525 }
526
AudioDemuxerMp3Seek(uint32_t pos,uint8_t * buf,uint32_t len,AudioDemuxerRst * rst)527 int Minimp3DemuxerPlugin::AudioDemuxerMp3Seek(uint32_t pos, uint8_t *buf, uint32_t len, AudioDemuxerRst *rst)
528 {
529 return 0;
530 }
531
AudioDemuxerMp3GetSeekPosition(uint32_t targetTimeMs,uint64_t * pos)532 int Minimp3DemuxerPlugin::AudioDemuxerMp3GetSeekPosition(uint32_t targetTimeMs, uint64_t *pos)
533 {
534 if (!pos) {
535 MEDIA_LOG_I("pos nullptr error");
536 return AUDIO_DEMUXER_ERROR;
537 }
538 uint32_t targetPos = targetTimeMs * mp3DemuxerAttr_.bitRate / 8 + mp3DemuxerAttr_.id3v2Size;
539 if (targetPos > mp3DemuxerAttr_.fileSize) {
540 *pos = 0;
541 return -1;
542 }
543 *pos = static_cast<uint64_t>(targetPos);
544 mp3DemuxerAttr_.mp3SeekFlag = 1;
545 return 0;
546 }
547
548 namespace {
AudioDecmuxerMp3Id3v2SizeCalculate(const uint8_t * buf)549 size_t AudioDecmuxerMp3Id3v2SizeCalculate(const uint8_t *buf)
550 {
551 return (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10;
552 }
553
AudioDemuxerMp3HasId3v2(const uint8_t * buf)554 bool AudioDemuxerMp3HasId3v2(const uint8_t *buf)
555 {
556 return !memcmp(buf, "ID3", 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) ||
557 (buf[8] & 0x80) || (buf[9] & 0x80));
558 }
559
AudioDemuxerMp3GetId3v2Size(const uint8_t * buf,size_t bufSize)560 size_t AudioDemuxerMp3GetId3v2Size(const uint8_t *buf, size_t bufSize)
561 {
562 if (bufSize >= ID3_DETECT_SIZE && AudioDemuxerMp3HasId3v2(buf)) {
563 size_t id3v2Size = AudioDecmuxerMp3Id3v2SizeCalculate(buf);
564 if ((buf[5] & 16)) { // 5, 16
565 id3v2Size += 10; // 10
566 }
567 return id3v2Size;
568 }
569 return 0;
570 }
571
AudioDemuxerMp3ProbeDecodeCheck(Mp3DemuxerFrameInfo * info)572 int AudioDemuxerMp3ProbeDecodeCheck(Mp3DemuxerFrameInfo *info)
573 {
574 if (!info) {
575 return -1;
576 }
577
578 std::vector<uint32_t>::iterator it = find (infoLayer.begin(), infoLayer.end(), info->layer);
579 if (it == infoLayer.end()) {
580 return -1;
581 }
582
583 it = find (infoSampleRate.begin(), infoSampleRate.end(), info->hz);
584 if (it == infoSampleRate.end()) {
585 return -1;
586 }
587
588 it = find (infoBitrateKbps.begin(), infoBitrateKbps.end(), info->bitrate_kbps);
589 if (it == infoBitrateKbps.end()) {
590 return -1;
591 }
592
593 return 0;
594 }
595
AudioDemuxerMp3IterateCallbackForProbe(void * userData,const uint8_t * frame,int frameSize,Mp3DemuxerFrameInfo * info)596 int AudioDemuxerMp3IterateCallbackForProbe(void *userData, const uint8_t *frame, int frameSize,
597 Mp3DemuxerFrameInfo *info)
598 {
599 int sampleCount;
600 Minimp3WrapperMp3decFrameInfo frameInfo;
601 AudioDemuxerMp3Attr *mp3Demuxer = static_cast<AudioDemuxerMp3Attr *>(userData);
602 AudioDemuxerRst *rst = mp3Demuxer->rst;
603 rst->frameBitrateKbps = info->bitrate_kbps;
604 rst->frameChannels = info->channels;
605 rst->frameSampleRate = info->hz;
606 rst->audioLayer = info->layer;
607 rst->samplesPerFrame = info->samples_per_frame;
608 sampleCount = Minimp3WrapperMp3decDecodeFrame(&mp3Demuxer->mp3DemuxerHandle, frame, frameSize,
609 mp3Demuxer->probePcmBuf, &frameInfo);
610 if (sampleCount <= 0 && AudioDemuxerMp3ProbeDecodeCheck(info) != 0) {
611 return -1;
612 }
613 return 1;
614 }
615
AudioDemuxerMp3Probe(AudioDemuxerMp3Attr * mp3DemuxerAttr,uint8_t * inputBuffer,uint32_t inputLength,AudioDemuxerRst * mp3DemuxerRst)616 Status AudioDemuxerMp3Probe(AudioDemuxerMp3Attr* mp3DemuxerAttr, uint8_t* inputBuffer, uint32_t inputLength,
617 AudioDemuxerRst* mp3DemuxerRst)
618 {
619 FALSE_RETURN_V_MSG_W(inputBuffer != nullptr && inputLength >= 0, Status::ERROR_INVALID_PARAMETER, "invalid parameter");
620 if (inputLength == 0) {
621 return Status::ERROR_NOT_ENOUGH_DATA;
622 }
623 int ret = -1;
624 if (mp3DemuxerAttr->id3v2SkipFlag == 0) {
625 if (mp3DemuxerAttr->id3v2Offset == 0) {
626 if (inputLength < ID3_DETECT_SIZE) {
627 mp3DemuxerRst->usedInputLength = 0;
628 return Status::ERROR_NOT_ENOUGH_DATA;
629 } else {
630 mp3DemuxerAttr->id3v2Size = AudioDemuxerMp3GetId3v2Size(inputBuffer, inputLength);
631 mp3DemuxerAttr->id3v2Offset = mp3DemuxerAttr->id3v2Size;
632 }
633 }
634
635 if (mp3DemuxerAttr->id3v2Offset) {
636 MEDIA_LOG_D("mp3 id3v2Offset = " PUBLIC_LOG_U32 ", input data inputLength " PUBLIC_LOG_U32,
637 mp3DemuxerAttr->id3v2Offset, inputLength);
638 if (inputLength >= mp3DemuxerAttr->id3v2Offset) {
639 mp3DemuxerRst->usedInputLength = mp3DemuxerAttr->id3v2Offset;
640 mp3DemuxerAttr->id3v2SkipFlag = 1;
641 inputLength -= mp3DemuxerAttr->id3v2Offset;
642 inputBuffer += mp3DemuxerAttr->id3v2Offset;
643 mp3DemuxerAttr->id3v2Offset = 0;
644 } else {
645 mp3DemuxerRst->usedInputLength = inputLength;
646 mp3DemuxerAttr->id3v2Offset = mp3DemuxerAttr->id3v2Offset - inputLength;
647 return Status::ERROR_NOT_ENOUGH_DATA;
648 }
649 }
650 }
651 mp3DemuxerAttr->rst = mp3DemuxerRst;
652 mp3DemuxerAttr->internalRemainLen = inputLength;
653 ret = Minimp3WrapperMp3decIterateBuf(inputBuffer, inputLength, AudioDemuxerMp3IterateCallbackForProbe,
654 mp3DemuxerAttr);
655 if (ret != 1) {
656 if (mp3DemuxerAttr->id3v2SkipFlag) {
657 return Status::ERROR_NOT_ENOUGH_DATA;
658 }
659 return Status::ERROR_UNSUPPORTED_FORMAT;
660 }
661 if (mp3DemuxerRst->frameBitrateKbps != 0) {
662 durationMs = static_cast<uint64_t>(fileSize * 8 / mp3DemuxerRst->frameBitrateKbps); // 8
663 }
664 MEDIA_LOG_I("bitrate_kbps = " PUBLIC_LOG_U32 " info->channels = " PUBLIC_LOG_U8 " info->hz = "
665 PUBLIC_LOG_U32, mp3DemuxerRst->frameBitrateKbps, mp3DemuxerRst->frameChannels,
666 mp3DemuxerRst->frameSampleRate);
667 return Status::OK;
668 }
669
Sniff(const std::string & name,std::shared_ptr<DataSource> dataSource)670 int Sniff(const std::string& name, std::shared_ptr<DataSource> dataSource)
671 {
672 MEDIA_LOG_I("Sniff in");
673 Status status;
674 auto buffer = std::make_shared<Buffer>();
675 auto bufData = buffer->AllocMemory(nullptr, PROBE_READ_LENGTH);
676 int processLoop = 1;
677 uint8_t *inputDataPtr = nullptr;
678 int offset = 0;
679 int readSize = PROBE_READ_LENGTH;
680 uint64_t sourceSize = 0;
681 dataSource->GetSize(sourceSize);
682 while (processLoop) {
683 if (sourceSize < PROBE_READ_LENGTH && sourceSize != 0) {
684 readSize = sourceSize;
685 }
686 status = dataSource->ReadAt(offset, buffer, static_cast<size_t>(readSize));
687 if (status != Status::OK) {
688 MEDIA_LOG_E("Sniff Read Data Error");
689 return 0;
690 }
691 inputDataPtr = const_cast<uint8_t *>(bufData->GetReadOnlyData());
692
693 status = AudioDemuxerMp3Probe(&mp3ProbeAttr, inputDataPtr, bufData->GetSize(), &mp3ProbeRst);
694 switch (status) {
695 case Status::ERROR_NOT_ENOUGH_DATA:
696 OSAL::SleepFor(100); // 100
697 offset += mp3ProbeRst.usedInputLength;
698 MEDIA_LOG_D("offset " PUBLIC_LOG_D32, offset);
699 processLoop = 1;
700 break;
701 case Status::OK:
702 processLoop = 0;
703 break;
704 case Status::ERROR_UNSUPPORTED_FORMAT:
705 return 0;
706 case Status::ERROR_UNKNOWN:
707 default:
708 MEDIA_LOG_I("AUDIO_DEMUXER_PREPARE_UNMATCHED_FORMAT " PUBLIC_LOG_D32, status);
709 return 0;
710 }
711 }
712 return MAX_RANK;
713 }
714
RegisterPlugin(const std::shared_ptr<Register> & reg)715 Status RegisterPlugin(const std::shared_ptr<Register>& reg)
716 {
717 MEDIA_LOG_I("RegisterPlugin called.");
718 if (!reg) {
719 MEDIA_LOG_I("RegisterPlugin failed due to nullptr pointer for reg.");
720 return Status::ERROR_INVALID_PARAMETER;
721 }
722
723 std::string pluginName = "Minimp3DemuxerPlugin";
724 DemuxerPluginDef regInfo;
725 regInfo.name = pluginName;
726 regInfo.description = "adapter for minimp3 demuxer plugin";
727 regInfo.rank = MAX_RANK;
728 regInfo.creator = [](const std::string &name) -> std::shared_ptr<DemuxerPlugin> {
729 return std::make_shared<Minimp3DemuxerPlugin>(name);
730 };
731 regInfo.sniffer = Sniff;
732 auto rtv = reg->AddPlugin(regInfo);
733 if (rtv != Status::OK) {
734 MEDIA_LOG_I("RegisterPlugin AddPlugin failed with return " PUBLIC_LOG_D32, static_cast<int>(rtv));
735 }
736 return Status::OK;
737 }
738 }
739
__anon7c563a3b0402null740 PLUGIN_DEFINITION(Minimp3Demuxer, LicenseType::CC0, RegisterPlugin, [] {});
741 } // namespace Minimp3
742 } // namespace Plugin
743 } // namespace Media
744 } // namespace OHOS
745