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> ®);
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> ®)
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