• 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 "Minimp4DemuxerPlugin"
17 
18 #include "minimp4_demuxer_plugin.h"
19 #include <algorithm>
20 #include <cstdio>
21 #include <cstring>
22 #include <new>
23 
24 #include <securec.h>
25 #include "foundation/log.h"
26 #include "plugin/common/plugin_buffer.h"
27 #include "plugin/common/plugin_time.h"
28 #include "utils/constants.h"
29 #include "osal/utils/util.h"
30 
31 namespace OHOS {
32 namespace Media {
33 namespace Plugin {
34 namespace Minimp4 {
35 namespace {
36 std::vector<int> sampleRateVec {
37     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
38 };
39 uint32_t durationMs = 0;
40 uint32_t fileSize = 0;
41 uint32_t readDataSize = 0;
42 constexpr int8_t ADTS_HEADER_SIZE = 7;
43 constexpr int8_t MP4_HEADER_OFFSET = 4;
44 constexpr int8_t RANK_MAX = 100;
45 constexpr unsigned int DEFAULT_AUDIO_SAMPLE_PER_FRAME = 1024;
46 constexpr unsigned int MEDIA_IO_SIZE = 16 * 1024;
47 int Sniff(const std::string &name, std::shared_ptr<DataSource> dataSource);
48 Status RegisterPlugins(const std::shared_ptr<Register> &reg);
49 }
50 
MiniMP4DemuxerPlugin(std::string name)51 MiniMP4DemuxerPlugin::MiniMP4DemuxerPlugin(std::string name)
52     : DemuxerPlugin(std::move(name)),
53       ioContext_(),
54       fileSize_(0),
55       inIoBuffer_(nullptr),
56       inIoBufferSize_(MEDIA_IO_SIZE),
57       ioDataRemainSize_(0),
58       sampleIndex_(0)
59 {
60     (void)memset_s(&miniMP4_, sizeof(MP4D_demux_t), 0, sizeof(MP4D_demux_t));
61     MEDIA_LOG_I("MiniMP4DemuxerPlugin, plugin name: " PUBLIC_LOG_S, pluginName_.c_str());
62 }
63 
~MiniMP4DemuxerPlugin()64 MiniMP4DemuxerPlugin::~MiniMP4DemuxerPlugin()
65 {
66     MEDIA_LOG_I("~MiniMP4DemuxerPlugin");
67 }
68 
SetDataSource(const std::shared_ptr<DataSource> & source)69 Status MiniMP4DemuxerPlugin::SetDataSource(const std::shared_ptr<DataSource> &source)
70 {
71     ioContext_.dataSource = source;
72     if (ioContext_.dataSource != nullptr) {
73         ioContext_.dataSource->GetSize(fileSize_);
74     }
75     fileSize = fileSize_;
76     MEDIA_LOG_I("fileSize_ " PUBLIC_LOG_ZU, fileSize_);
77     return Status::OK;
78 }
79 
Init()80 Status MiniMP4DemuxerPlugin::Init()
81 {
82     MEDIA_LOG_I("Init called");
83     inIoBuffer_ = static_cast<uint8_t *>(malloc(inIoBufferSize_));
84     if (inIoBuffer_ == nullptr) {
85         MEDIA_LOG_E("inIoBuffer_ malloc failed");
86         return Status::ERROR_NO_MEMORY;
87     }
88     (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
89     return Status::OK;
90 }
91 
Deinit()92 Status MiniMP4DemuxerPlugin::Deinit()
93 {
94     if (inIoBuffer_) {
95         free(inIoBuffer_);
96         inIoBuffer_ = nullptr;
97     }
98     return Status::OK;
99 }
100 
Prepare()101 Status MiniMP4DemuxerPlugin::Prepare()
102 {
103     return Status::OK;
104 }
105 
Reset()106 Status MiniMP4DemuxerPlugin::Reset()
107 {
108     MEDIA_LOG_D("Reset in");
109     ioContext_.eos = false;
110     ioContext_.offset = 0;
111     ioContext_.dataSource.reset();
112     ioDataRemainSize_ = 0;
113     (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
114     return Status::OK;
115 }
116 
Stop()117 Status MiniMP4DemuxerPlugin::Stop()
118 {
119     return Status::OK;
120 }
121 
GetParameter(Tag tag,ValueType & value)122 Status MiniMP4DemuxerPlugin::GetParameter(Tag tag, ValueType &value)
123 {
124     (void)tag;
125     (void)value;
126     return Status::ERROR_UNIMPLEMENTED;
127 }
128 
SetParameter(Tag tag,const ValueType & value)129 Status MiniMP4DemuxerPlugin::SetParameter(Tag tag, const ValueType &value)
130 {
131     (void)tag;
132     (void)value;
133     return Status::ERROR_UNIMPLEMENTED;
134 }
135 
GetAllocator()136 std::shared_ptr<Allocator> MiniMP4DemuxerPlugin::GetAllocator()
137 {
138     return nullptr;
139 }
140 
SetCallback(Callback * cb)141 Status MiniMP4DemuxerPlugin::SetCallback(Callback* cb)
142 {
143     return Status::OK;
144 }
145 
GetTrackCount()146 size_t MiniMP4DemuxerPlugin::GetTrackCount()
147 {
148     size_t trackCnt = 0;
149     return trackCnt;
150 }
151 
SelectTrack(int32_t trackId)152 Status MiniMP4DemuxerPlugin::SelectTrack(int32_t trackId)
153 {
154     return Status::ERROR_UNIMPLEMENTED;
155 }
156 
UnselectTrack(int32_t trackId)157 Status MiniMP4DemuxerPlugin::UnselectTrack(int32_t trackId)
158 {
159     return Status::OK;
160 }
161 
GetSelectedTracks(std::vector<int32_t> & trackIds)162 Status MiniMP4DemuxerPlugin::GetSelectedTracks(std::vector<int32_t> &trackIds)
163 {
164     trackIds.clear();
165     trackIds.push_back(1);
166     return Status::OK;
167 }
168 
DoReadFromSource(uint32_t readSize)169 Status MiniMP4DemuxerPlugin::DoReadFromSource(uint32_t readSize)
170 {
171     if (readSize == 0) {
172         return Status::OK;
173     }
174     auto buffer  = std::make_shared<Buffer>();
175     auto bufData = buffer->AllocMemory(nullptr, readSize);
176     int retryTimes = 0;
177     MEDIA_LOG_D("readSize " PUBLIC_LOG_U32 " inIoBufferSize_ " PUBLIC_LOG_D32 "ioDataRemainSize_ "
178                 PUBLIC_LOG_U32 "", readSize, inIoBufferSize_, ioDataRemainSize_);
179     do {
180         auto result = ioContext_.dataSource->ReadAt(ioContext_.offset, buffer, static_cast<size_t>(readSize));
181         MEDIA_LOG_D("ioContext_.offset " PUBLIC_LOG_D32, static_cast<uint32_t>(ioContext_.offset));
182         if (result != Status::OK) {
183             MEDIA_LOG_W("read data from source warning " PUBLIC_LOG_D32, static_cast<int>(result));
184             return result;
185         }
186 
187         MEDIA_LOG_D("bufData->GetSize() " PUBLIC_LOG_ZU, bufData->GetSize());
188         if (bufData->GetSize() > 0) {
189             if (readSize >= bufData->GetSize()) {
190                 (void)memcpy_s(inIoBuffer_ + ioDataRemainSize_, readSize,
191                     const_cast<uint8_t *>(bufData->GetReadOnlyData()), bufData->GetSize());
192             } else {
193                 MEDIA_LOG_E("Error: readSize < bufData->GetSize()");
194                 return Status::ERROR_UNKNOWN;
195             }
196             ioContext_.offset += bufData->GetSize();
197             ioDataRemainSize_  += bufData->GetSize();
198         }
199         if (bufData->GetSize() == 0 && ioDataRemainSize_ == 0 && retryTimes < 200) { // 200
200             OHOS::Media::OSAL::SleepFor(30); // 30
201             retryTimes++;
202             continue;
203         }
204         if (retryTimes >= 200) { // 200
205             MEDIA_LOG_E("Warning: not end of file, but do not have enough data");
206             return Status::ERROR_NOT_ENOUGH_DATA;
207         }
208         break;
209     } while (true);
210     return Status::OK;
211 }
212 
GetDataFromSource()213 Status MiniMP4DemuxerPlugin::GetDataFromSource()
214 {
215     uint32_t ioNeedReadSize = inIoBufferSize_ - ioDataRemainSize_;
216     MEDIA_LOG_D("ioDataRemainSize_ " PUBLIC_LOG_D32 " ioNeedReadSize " PUBLIC_LOG_D32, ioDataRemainSize_,
217         ioNeedReadSize);
218     if (ioDataRemainSize_) {
219         // 将剩余数据移动到buffer的起始位置
220         auto ret = memmove_s(inIoBuffer_,
221                              ioDataRemainSize_,
222                              inIoBuffer_ + readDataSize,
223                              ioDataRemainSize_);
224         if (ret != 0) {
225             MEDIA_LOG_E("copy buffer error(" PUBLIC_LOG_D32 ")", ret);
226             return Status::ERROR_UNKNOWN;
227         }
228         ret = memset_s(inIoBuffer_ + ioDataRemainSize_, ioNeedReadSize, 0x00, ioNeedReadSize);
229         if (ret != 0) {
230             MEDIA_LOG_E("memset_s buffer error(" PUBLIC_LOG_D32 ")", ret);
231             return Status::ERROR_UNKNOWN;
232         }
233     }
234     if (ioContext_.offset >= fileSize_ && ioDataRemainSize_ == 0) {
235         ioContext_.eos = true;
236         return Status::END_OF_STREAM;
237     }
238     if (ioContext_.offset + ioNeedReadSize > fileSize_) {
239         ioNeedReadSize = fileSize_ - ioContext_.offset; // 在读取文件即将结束时,剩余数据不足,更新读取长度
240     }
241 
242     return DoReadFromSource(ioNeedReadSize);
243 }
244 
GetMediaInfo(MediaInfo & mediaInfo)245 Status MiniMP4DemuxerPlugin::GetMediaInfo(MediaInfo &mediaInfo)
246 {
247     if (fileSize_ == 0 || ioContext_.dataSource == nullptr) {
248         return Status::ERROR_UNKNOWN;
249     }
250 
251     if (MP4D_open(&miniMP4_, ReadCallback, reinterpret_cast<void *>(this), fileSize_) == 0) {
252         MEDIA_LOG_E("MP4D_open IS ERROR");
253         return Status::ERROR_MISMATCHED_TYPE;
254     }
255     if (AudioAdapterForDecoder() != Status::OK) {
256         return Status::ERROR_UNKNOWN;
257     }
258     mediaInfo.tracks.resize(1);
259     mediaInfo.tracks[0].Insert<Tag::MEDIA_TYPE>(MediaType::AUDIO);
260     mediaInfo.tracks[0].Insert<Tag::AUDIO_SAMPLE_RATE>(miniMP4_.track->SampleDescription.audio.samplerate_hz);
261     mediaInfo.tracks[0].Insert<Tag::MEDIA_BITRATE>(miniMP4_.track->avg_bitrate_bps);
262     mediaInfo.tracks[0].Insert<Tag::AUDIO_CHANNELS>(miniMP4_.track->SampleDescription.audio.channelcount);
263     mediaInfo.tracks[0].Insert<Tag::TRACK_ID>(0);
264     mediaInfo.tracks[0].Insert<Tag::MIME>(MEDIA_MIME_AUDIO_AAC);
265     mediaInfo.tracks[0].Insert<Tag::AUDIO_MPEG_VERSION>(4); // 4
266     mediaInfo.tracks[0].Insert<Tag::AUDIO_AAC_PROFILE>(AudioAacProfile::LC);
267     mediaInfo.tracks[0].Insert<Tag::AUDIO_AAC_STREAM_FORMAT>(AudioAacStreamFormat::MP4ADTS);
268     mediaInfo.tracks[0].Insert<Tag::AUDIO_SAMPLE_FORMAT>(AudioSampleFormat::S16);
269     mediaInfo.tracks[0].Insert<Tag::AUDIO_SAMPLE_PER_FRAME>(DEFAULT_AUDIO_SAMPLE_PER_FRAME);
270     if (miniMP4_.track->SampleDescription.audio.channelcount == 1) {
271         mediaInfo.tracks[0].Insert<Tag::AUDIO_CHANNEL_LAYOUT>(AudioChannelLayout::MONO);
272     } else {
273         mediaInfo.tracks[0].Insert<Tag::AUDIO_CHANNEL_LAYOUT>(AudioChannelLayout::STEREO);
274     }
275 
276     unsigned int frameSize = 0;
277     unsigned int timeStamp = 0;
278     unsigned int duration = 0;
279     int64_t offset = MP4D_frame_offset(&miniMP4_, 0, 0, &frameSize, &timeStamp, &duration);
280     ioDataRemainSize_ = 0;
281     ioContext_.offset = offset;
282     MEDIA_LOG_D("samplerate_hz " PUBLIC_LOG_D32,
283         static_cast<uint32_t>(miniMP4_.track->SampleDescription.audio.samplerate_hz));
284     MEDIA_LOG_D("avg_bitrate_bps " PUBLIC_LOG_D32, static_cast<uint32_t>(miniMP4_.track->avg_bitrate_bps));
285     MEDIA_LOG_D("channel num " PUBLIC_LOG_D32,
286         static_cast<uint32_t>(miniMP4_.track->SampleDescription.audio.channelcount));
287     return Status::OK;
288 }
289 
290 
FillADTSHead(std::shared_ptr<Memory> & data,unsigned int frameSize)291 void MiniMP4DemuxerPlugin::FillADTSHead(std::shared_ptr<Memory> &data, unsigned int frameSize)
292 {
293     uint8_t adtsHeader[ADTS_HEADER_SIZE] = {0};
294     unsigned int channelConfig = miniMP4_.track->SampleDescription.audio.channelcount;
295     unsigned int packetLen = frameSize + 7;
296     unsigned int samplerateIndex = 0;
297     /* 按格式读取信息帧 */
298     uint8_t objectTypeIndication = miniMP4_.track->object_type_indication;
299     samplerateIndex = ((miniMP4_.track->dsi[0] & 0x7) << 1) + (miniMP4_.track->dsi[1] >> 7); // 1,7 按协议取信息帧
300     adtsHeader[0] = static_cast<uint8_t>(0xFF);
301     adtsHeader[1] = static_cast<uint8_t>(0xF1);
302     adtsHeader[2] = static_cast<uint8_t>(objectTypeIndication) + (samplerateIndex << 2) + (channelConfig >> 2); // 2
303     adtsHeader[3] = static_cast<uint8_t>(((channelConfig & 0x3) << 6) + (packetLen >> 11)); // 3,6,11 按协议取信息帧
304     adtsHeader[4] = static_cast<uint8_t>((packetLen & 0x7FF) >> 3); // 4, 3 按协议取信息帧
305     adtsHeader[5] = static_cast<uint8_t>(((packetLen & 0x7) << 5) + 0x1F); // 5 按协议取信息帧
306     adtsHeader[6] = static_cast<uint8_t>(0xFC); // 6 按协议取信息帧
307     data->Write(adtsHeader, ADTS_HEADER_SIZE, 0);
308 }
309 
ReadCallback(int64_t offset,void * buffer,size_t size,void * token)310 int MiniMP4DemuxerPlugin::ReadCallback(int64_t offset, void* buffer, size_t size, void* token)
311 {
312     MiniMP4DemuxerPlugin* mp4Demuxer = reinterpret_cast<MiniMP4DemuxerPlugin*>(token);
313     unsigned int file_size = mp4Demuxer->GetFileSize();
314     if (offset >= file_size) {
315         MEDIA_LOG_E("ReadCallback offset is bigger");
316         return -1;
317     }
318 
319     if ((offset + size) <= mp4Demuxer->ioContext_.offset) {
320         (void)memcpy_s(buffer, size, mp4Demuxer->inIoBuffer_ +
321             (mp4Demuxer->ioDataRemainSize_ - (mp4Demuxer->ioContext_.offset - offset)), size);
322         return 0;
323     }
324     while ((offset + size) > mp4Demuxer->ioContext_.offset) {
325         MEDIA_LOG_D("offset " PUBLIC_LOG_D32 " size " PUBLIC_LOG_ZU,
326             static_cast<uint32_t>(offset), static_cast<uint32_t>(size));
327         MEDIA_LOG_D("mp4Demuxer->ioContext_.offset " PUBLIC_LOG_D32,
328             static_cast<uint32_t>(mp4Demuxer->ioContext_.offset));
329         mp4Demuxer->ioDataRemainSize_ = 0;
330         mp4Demuxer->ioContext_.offset = offset;
331         Status status = Status::ERROR_UNKNOWN;
332         readDataSize = mp4Demuxer->inIoBufferSize_;
333         status = mp4Demuxer->GetDataFromSource();
334         if (status != Status::OK) {
335             return (int)status;
336         }
337     }
338 
339     (void)memcpy_s(buffer, size, mp4Demuxer->inIoBuffer_, size);
340 
341     return 0;
342 }
343 
ReadFrame(Buffer & outBuffer,int32_t timeOutMs)344 Status MiniMP4DemuxerPlugin::ReadFrame(Buffer &outBuffer, int32_t timeOutMs)
345 {
346     Status retResult = Status::OK;
347     std::shared_ptr<Memory> mp4FrameData;
348     if (sampleIndex_ >= miniMP4_.track->sample_count) {
349         (void)memset_s(inIoBuffer_, MEDIA_IO_SIZE, 0, MEDIA_IO_SIZE);
350         ioDataRemainSize_ = 0;
351         MEDIA_LOG_DD("sampleIndex_ " PUBLIC_LOG_D32, sampleIndex_);
352         MEDIA_LOG_DD("miniMP4_.track->sample_count " PUBLIC_LOG_D32, miniMP4_.track->sample_count);
353         return Status::END_OF_STREAM;
354     }
355     unsigned int frameSize = 0;
356     unsigned int timeStamp = 0;
357     unsigned int duration = 0;
358     uint64_t offset = MP4D_frame_offset(&miniMP4_, 0, sampleIndex_, &frameSize, &timeStamp, &duration);
359     if (offset > fileSize_) {
360         return Status::ERROR_UNKNOWN;
361     }
362     MEDIA_LOG_D("frameSize " PUBLIC_LOG_D32 " offset " PUBLIC_LOG_D32 " sampleIndex_ " PUBLIC_LOG_D32,
363         frameSize, static_cast<uint32_t>(offset), sampleIndex_);
364     if (outBuffer.IsEmpty()) {
365         mp4FrameData = outBuffer.AllocMemory(nullptr, frameSize + ADTS_HEADER_SIZE);
366     } else {
367         mp4FrameData = outBuffer.GetMemory();
368     }
369 
370     if (offset > ioContext_.offset) {
371         (void)memset_s(inIoBuffer_, MEDIA_IO_SIZE, 0, MEDIA_IO_SIZE);
372         ioDataRemainSize_ = 0;
373         ioContext_.offset = offset;
374     }
375     retResult = GetDataFromSource();
376     if (retResult != Status::OK) {
377         return retResult;
378     }
379     FillADTSHead(mp4FrameData, frameSize);
380     size_t writeSize = mp4FrameData->Write(inIoBuffer_, frameSize, ADTS_HEADER_SIZE);
381     sampleIndex_++;
382     MEDIA_LOG_D("writeSize " PUBLIC_LOG_ZU " mp4FrameData size " PUBLIC_LOG_ZU, writeSize, mp4FrameData->GetSize());
383     ioDataRemainSize_ -= frameSize;
384     readDataSize = frameSize;
385 
386     return Status::OK;
387 }
388 
SeekTo(int32_t trackId,int64_t hstTime,SeekMode mode)389 Status MiniMP4DemuxerPlugin::SeekTo(int32_t trackId, int64_t hstTime, SeekMode mode)
390 {
391     unsigned int frameSize = 0;
392     unsigned int timeStamp = 0;
393     unsigned int duration = 0;
394     uint64_t offsetStart = MP4D_frame_offset(&miniMP4_, 0, 0, &frameSize, &timeStamp, &duration);
395     uint64_t offsetEnd =
396         MP4D_frame_offset(&miniMP4_, 0, miniMP4_.track->sample_count - 1, &frameSize, &timeStamp, &duration);
397     uint64_t targetPos = (Plugin::HstTime2Ms(hstTime) * static_cast<int64_t>(miniMP4_.track->avg_bitrate_bps)) / 8 +
398         offsetStart;
399     if (targetPos >= offsetEnd) {
400         sampleIndex_ = miniMP4_.track->sample_count;
401         return Status::OK;
402     }
403     sampleIndex_ = 0;
404     uint64_t tempPos = 0;
405     while (sampleIndex_ < miniMP4_.track->sample_count) {
406         tempPos = MP4D_frame_offset(&miniMP4_, 0, sampleIndex_, &frameSize, &timeStamp, &duration);
407         if (tempPos < targetPos) {
408             sampleIndex_++;
409         } else {
410             break;
411         }
412     }
413     ioContext_.offset = tempPos;
414     ioDataRemainSize_ = 0;
415     MEDIA_LOG_D("ioContext_.offset " PUBLIC_LOG_D32, static_cast<uint32_t>(ioContext_.offset));
416     (void)memset_s(inIoBuffer_, inIoBufferSize_, 0x00, inIoBufferSize_);
417     return Status::OK;
418 }
419 
GetFileSize()420 size_t MiniMP4DemuxerPlugin::GetFileSize()
421 {
422     return fileSize_;
423 }
424 
AudioAdapterForDecoder()425 Status MiniMP4DemuxerPlugin::AudioAdapterForDecoder()
426 {
427     if (miniMP4_.track == nullptr) {
428         return Status::ERROR_UNKNOWN;
429     }
430     /* 适配解码协议 */
431     size_t sampleRateIndex = (static_cast<unsigned int>(miniMP4_.track->dsi[0] & 0x7) << 1) +
432         (static_cast<unsigned int>(miniMP4_.track->dsi[1]) >> 7);
433 
434     if ((sampleRateVec.size() <= sampleRateIndex) || (miniMP4_.track->dsi_bytes >= 20)) { // 20 按协议适配解码器
435         return Status::ERROR_MISMATCHED_TYPE;
436     }
437     miniMP4_.track->SampleDescription.audio.samplerate_hz = sampleRateVec[sampleRateIndex];
438     miniMP4_.track->SampleDescription.audio.channelcount = (miniMP4_.track->dsi[1] & 0x7F) >> 3; // 3 按协议适配解码器
439     return Status::OK;
440 }
441 
442 namespace {
Sniff(const std::string & name,std::shared_ptr<DataSource> dataSource)443 int Sniff(const std::string &name, std::shared_ptr<DataSource> dataSource)
444 {
445     unsigned char m4aCheck[] = {'f', 't', 'y', 'p'};
446     auto buffer = std::make_shared<Buffer>();
447     auto bufData = buffer->AllocMemory(nullptr, sizeof(m4aCheck));
448     int retryTimes = 0;
449     do {
450         if (dataSource->ReadAt(MP4_HEADER_OFFSET, buffer, static_cast<size_t>(sizeof(m4aCheck))) != Status::OK) {
451             return 0;
452         }
453         if (bufData->GetSize() < sizeof(m4aCheck) && retryTimes < 50) { // 50
454             OSAL::SleepFor(100); // 100
455             retryTimes++;
456             continue;
457         }
458         if (memcmp(const_cast<uint8_t *>(bufData->GetReadOnlyData()), &m4aCheck, sizeof(m4aCheck)) != 0) {
459             MEDIA_LOG_E("memcmp m4aCheck is error");
460             return 0;
461         }
462         break;
463     } while (true);
464     return RANK_MAX;
465 }
466 
RegisterPlugins(const std::shared_ptr<Register> & reg)467 Status RegisterPlugins(const std::shared_ptr<Register> &reg)
468 {
469     MEDIA_LOG_D("RegisterPlugins called");
470     if (!reg) {
471         MEDIA_LOG_E("RegisterPlugins fail due to null pointer for reg");
472         return Status::ERROR_INVALID_PARAMETER;
473     }
474     std::string pluginName = "MiniMP4DemuxerPlugin";
475     DemuxerPluginDef regInfo;
476     regInfo.name = pluginName;
477     regInfo.description = "adapter for minimp4 demuxer plugin";
478     regInfo.rank = RANK_MAX;
479     regInfo.creator = [](const std::string &name) -> std::shared_ptr<DemuxerPlugin> {
480         return std::make_shared<MiniMP4DemuxerPlugin>(name);
481     };
482     regInfo.sniffer = Sniff;
483     auto ret = reg->AddPlugin(regInfo);
484     if (ret != Status::OK) {
485         MEDIA_LOG_E("RegisterPlugin AddPlugin failed with return " PUBLIC_LOG_D32, static_cast<int>(ret));
486     }
487     return Status::OK;
488 }
489 }
490 
__anonda59e0050402null491 PLUGIN_DEFINITION(MiniMP4Demuxer, LicenseType::CC0, RegisterPlugins, [] {});
492 } // namespace Minimp4
493 } // namespace Plugin
494 } // namespace Media
495 } // namespace OHOS