1 /*
2  * Copyright (c) 2023-2024 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 "DemuxerPluginManager"
17 
18 #include "demuxer_plugin_manager.h"
19 
20 #include <algorithm>
21 #include <map>
22 #include <memory>
23 
24 #include "avcodec_common.h"
25 #include "avcodec_trace.h"
26 #include "cpp_ext/type_traits_ext.h"
27 #include "buffer/avallocator.h"
28 #include "common/event.h"
29 #include "common/log.h"
30 #include "meta/media_types.h"
31 #include "meta/meta.h"
32 #include "osal/utils/dump_buffer.h"
33 #include "plugin/plugin_buffer.h"
34 #include "plugin/plugin_info.h"
35 #include "plugin/plugin_manager_v2.h"
36 #include "plugin/plugin_time.h"
37 #include "base_stream_demuxer.h"
38 #include "media_demuxer.h"
39 
40 namespace {
41 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "DemuxerPluginManager" };
42 constexpr int32_t INVALID_STREAM_OR_TRACK_ID = -1;
43 }
44 
45 namespace OHOS {
46 namespace Media {
47 
DataSourceImpl(const std::shared_ptr<BaseStreamDemuxer> & stream,int32_t streamID)48 DataSourceImpl::DataSourceImpl(const std::shared_ptr<BaseStreamDemuxer>& stream, int32_t streamID)
49     : stream_(stream),
50       streamID_(streamID)
51 {
52 }
53 
IsOffsetValid(int64_t offset) const54 bool DataSourceImpl::IsOffsetValid(int64_t offset) const
55 {
56     if (stream_->seekable_ == Plugins::Seekable::SEEKABLE) {
57         return stream_->mediaDataSize_ == 0 || offset <= static_cast<int64_t>(stream_->mediaDataSize_);
58     }
59     return true;
60 }
61 
SetStreamID(int32_t streamID)62 Status DataSourceImpl::SetStreamID(int32_t streamID)
63 {
64     streamID_ = streamID;
65     return Status::OK;
66 }
67 
68 /**
69 * ReadAt Plugins::DataSource::ReadAt implementation.
70 * @param offset offset in media stream.
71 * @param buffer caller allocate real buffer.
72 * @param expectedLen buffer size wanted to read.
73 * @return read result.
74 */
ReadAt(int64_t offset,std::shared_ptr<Buffer> & buffer,size_t expectedLen)75 Status DataSourceImpl::ReadAt(int64_t offset, std::shared_ptr<Buffer>& buffer, size_t expectedLen)
76 {
77     MediaAVCodec::AVCodecTrace trace("DataSourceImpl::ReadAt");
78     if (!buffer || !IsOffsetValid(offset)) {
79         MEDIA_LOG_E("ReadAt failed, buffer empty: " PUBLIC_LOG_D32 ", expectedLen: " PUBLIC_LOG_D32
80                             ", offset: " PUBLIC_LOG_D64, !buffer, static_cast<int>(expectedLen), offset);
81         return Status::ERROR_UNKNOWN;
82     }
83     return stream_->CallbackReadAt(streamID_, offset, buffer, expectedLen);
84 }
85 
GetSize(uint64_t & size)86 Status DataSourceImpl::GetSize(uint64_t& size)
87 {
88     size = stream_->mediaDataSize_;
89     return (size > 0) ? Status::OK : Status::ERROR_WRONG_STATE;
90 }
91 
GetSeekable()92 Plugins::Seekable DataSourceImpl::GetSeekable()
93 {
94     return stream_->seekable_;
95 }
96 
GetStreamID()97 int32_t DataSourceImpl::GetStreamID()
98 {
99     return streamID_;
100 }
101 
SetIsDash(bool flag)102 void DataSourceImpl::SetIsDash(bool flag)
103 {
104     isDash_ = flag;
105 }
106 
IsDash()107 bool DataSourceImpl::IsDash()
108 {
109     return isDash_;
110 }
111 
DemuxerPluginManager()112 DemuxerPluginManager::DemuxerPluginManager()
113 {
114     MEDIA_LOG_I("DemuxerPluginManager called");
115 }
116 
~DemuxerPluginManager()117 DemuxerPluginManager::~DemuxerPluginManager()
118 {
119     MEDIA_LOG_D("~DemuxerPluginManager called");
120     for (auto& iter : streamInfoMap_) {
121         if (iter.second.plugin) {
122             iter.second.plugin->Deinit();
123         }
124         iter.second.plugin = nullptr;
125         iter.second.dataSource = nullptr;
126     }
127 }
128 
GetStreamCount() const129 size_t DemuxerPluginManager::GetStreamCount() const
130 {
131     return streamInfoMap_.size();
132 }
133 
InitAudioTrack(const StreamInfo & info)134 void DemuxerPluginManager::InitAudioTrack(const StreamInfo& info)
135 {
136     if (curAudioStreamID_ == -1) {    // 获取第一个音频流
137         curAudioStreamID_ = info.streamId;
138         streamInfoMap_[info.streamId].activated = true;
139         MEDIA_LOG_I("InitAudioTrack AUDIO");
140         isDash_ = true;
141     } else {
142         Meta format;
143         format.Set<Tag::MEDIA_BITRATE>(static_cast<uint32_t>(info.bitRate));
144         format.Set<Tag::MIME_TYPE>("audio/xxx");
145         streamInfoMap_[info.streamId].mediaInfo.tracks.push_back(format);
146         streamInfoMap_[info.streamId].mediaInfo.general.Set<Tag::MEDIA_HAS_AUDIO>(true);
147         streamInfoMap_[info.streamId].mediaInfo.general.Set<Tag::MEDIA_TRACK_COUNT>(1);
148     }
149     streamInfoMap_[info.streamId].type = AUDIO;
150 }
151 
InitVideoTrack(const StreamInfo & info)152 void DemuxerPluginManager::InitVideoTrack(const StreamInfo& info)
153 {
154     if (curVideoStreamID_ == -1) {
155         curVideoStreamID_ = info.streamId; // 获取第一个视频流
156         streamInfoMap_[info.streamId].activated = true;
157         MEDIA_LOG_I("InitVideoTrack VIDEO");
158         isDash_ = true;
159     } else {
160         Meta format;
161         format.Set<Tag::MEDIA_BITRATE>(static_cast<uint32_t>(info.bitRate));
162         format.Set<Tag::VIDEO_WIDTH>(static_cast<uint32_t>(info.videoWidth));
163         format.Set<Tag::VIDEO_HEIGHT>(static_cast<uint32_t>(info.videoHeight));
164         format.Set<Tag::MIME_TYPE>("video/xxx");
165         streamInfoMap_[info.streamId].mediaInfo.tracks.push_back(format);
166         streamInfoMap_[info.streamId].mediaInfo.general.Set<Tag::MEDIA_HAS_VIDEO>(true);
167         streamInfoMap_[info.streamId].mediaInfo.general.Set<Tag::MEDIA_TRACK_COUNT>(1);
168     }
169     streamInfoMap_[info.streamId].type = VIDEO;
170 }
171 
InitSubtitleTrack(const StreamInfo & info)172 void DemuxerPluginManager::InitSubtitleTrack(const StreamInfo& info)
173 {
174     if (curSubTitleStreamID_ == -1) {   // 获取第一个字幕流
175         curSubTitleStreamID_ = info.streamId;
176         streamInfoMap_[info.streamId].activated = true;
177         MEDIA_LOG_I("InitSubtitleTrack SUBTITLE");
178     } else {
179         Meta format;
180         format.Set<Tag::MIME_TYPE>("text/vtt");
181         streamInfoMap_[info.streamId].mediaInfo.tracks.push_back(format);
182         streamInfoMap_[info.streamId].mediaInfo.general.Set<Tag::MEDIA_HAS_SUBTITLE>(true);
183         streamInfoMap_[info.streamId].mediaInfo.general.Set<Tag::MEDIA_TRACK_COUNT>(1);
184     }
185     streamInfoMap_[info.streamId].type = SUBTITLE;
186 }
187 
InitDefaultPlay(const std::vector<StreamInfo> & streams)188 Status DemuxerPluginManager::InitDefaultPlay(const std::vector<StreamInfo>& streams)
189 {
190     MEDIA_LOG_I("InitDefaultPlay begin");
191     for (const auto& iter : streams) {
192         int32_t streamIndex = iter.streamId;
193         streamInfoMap_[streamIndex].streamID = streamIndex;
194         streamInfoMap_[streamIndex].bitRate = iter.bitRate;
195         if (iter.type == MIXED) {  // 存在混合流则只请求该流
196             curVideoStreamID_ = streamIndex;
197             streamInfoMap_[streamIndex].activated = true;
198             streamInfoMap_[streamIndex].type = MIXED;
199             curAudioStreamID_ = -1;
200             MEDIA_LOG_I("InitDefaultPlay MIX");
201             break;
202         } else if (iter.type == AUDIO) {
203             InitAudioTrack(iter);
204         } else if (iter.type == VIDEO) {
205             InitVideoTrack(iter);
206         } else if (iter.type == SUBTITLE) {
207             InitSubtitleTrack(iter);
208         } else {
209             MEDIA_LOG_W("streaminfo invalid type");
210         }
211     }
212     MEDIA_LOG_I("InitDefaultPlay end");
213     return Status::OK;
214 }
215 
GetPluginByStreamID(int32_t streamID)216 std::shared_ptr<Plugins::DemuxerPlugin> DemuxerPluginManager::GetPluginByStreamID(int32_t streamID)
217 {
218     if (streamID != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_.find(streamID) != streamInfoMap_.end()) {
219         return streamInfoMap_[streamID].plugin;
220     }
221     return nullptr;
222 }
223 
GetTrackInfoByStreamID(int32_t streamID,int32_t & trackId,int32_t & innerTrackId)224 void DemuxerPluginManager::GetTrackInfoByStreamID(int32_t streamID, int32_t& trackId, int32_t& innerTrackId)
225 {
226     auto iter = std::find_if(trackInfoMap_.begin(), trackInfoMap_.end(),
227         [&](const std::pair<int32_t, MediaTrackMap> &item) {
228         return item.second.streamID == streamID;
229     });
230     if (iter != trackInfoMap_.end()) {
231         trackId = iter->first;
232         innerTrackId = iter->second.innerTrackIndex;
233     }
234     return;
235 }
236 
LoadDemuxerPlugin(int32_t streamID,std::shared_ptr<BaseStreamDemuxer> streamDemuxer)237 Status DemuxerPluginManager::LoadDemuxerPlugin(int32_t streamID, std::shared_ptr<BaseStreamDemuxer> streamDemuxer)
238 {
239     if (streamID == INVALID_STREAM_OR_TRACK_ID) {
240         MEDIA_LOG_I("LoadDemuxerPlugin streamid invalid");
241         return Status::ERROR_UNKNOWN;
242     }
243 
244     std::string type = streamDemuxer->SnifferMediaType(streamID);
245     MediaTypeFound(streamDemuxer, type, streamID);
246 
247     FALSE_RETURN_V_MSG_E(streamInfoMap_[streamID].plugin != nullptr, Status::ERROR_INVALID_PARAMETER,
248         "Set data source failed due to create video demuxer plugin failed.");
249     Plugins::MediaInfo mediaInfoTemp;
250     Status ret = streamInfoMap_[streamID].plugin->GetMediaInfo(mediaInfoTemp);
251     if (ret == Status::OK) {
252         streamInfoMap_[streamID].mediaInfo = mediaInfoTemp;
253     }
254     return ret;
255 }
256 
LoadCurrentAllPlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,Plugins::MediaInfo & mediaInfo)257 Status DemuxerPluginManager::LoadCurrentAllPlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
258     Plugins::MediaInfo& mediaInfo)
259 {
260     if (curAudioStreamID_ != INVALID_STREAM_OR_TRACK_ID) {
261         MEDIA_LOG_I("LoadCurrentAllPlugin audio plugin");
262         Status ret = LoadDemuxerPlugin(curAudioStreamID_, streamDemuxer);
263         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin audio plugin failed.");
264     }
265     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID) {
266         MEDIA_LOG_I("LoadCurrentAllPlugin video plugin");
267         Status ret = LoadDemuxerPlugin(curVideoStreamID_, streamDemuxer);
268         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin video plugin failed.");
269     }
270 
271     if (curSubTitleStreamID_ != INVALID_STREAM_OR_TRACK_ID) {
272         MEDIA_LOG_I("LoadCurrentAllPlugin subtitle plugin");
273         Status ret = LoadDemuxerPlugin(curSubTitleStreamID_, streamDemuxer);
274         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin subtitle plugin failed.");
275     }
276 
277     for (auto& iter : streamInfoMap_) {
278         AddMediaInfo(iter.first, mediaInfo);
279     }
280 
281     curMediaInfo_ = mediaInfo;
282     return Status::OK;
283 }
284 
LoadCurrentSubtitlePlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,Plugins::MediaInfo & mediaInfo)285 Status DemuxerPluginManager::LoadCurrentSubtitlePlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
286     Plugins::MediaInfo& mediaInfo)
287 {
288     if (curSubTitleStreamID_ == INVALID_STREAM_OR_TRACK_ID) {
289         MEDIA_LOG_I("LoadCurrentSubtitleDemuxerPlugin failed, curSubTitleStreamID_ invalid");
290         return Status::ERROR_UNKNOWN;
291     }
292 
293     mediaInfo = curMediaInfo_;
294     MEDIA_LOG_I("LoadCurrentSubtitleDemuxerPlugin begin");
295     Status ret = LoadDemuxerPlugin(curSubTitleStreamID_, streamDemuxer);
296     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin subtitle plugin failed.");
297     AddMediaInfo(curSubTitleStreamID_, mediaInfo);
298     curMediaInfo_ = mediaInfo;
299     MEDIA_LOG_I("LoadCurrentSubtitleDemuxerPlugin success");
300     return Status::OK;
301 }
302 
AddMediaInfo(int32_t streamID,Plugins::MediaInfo & mediaInfo)303 void DemuxerPluginManager::AddMediaInfo(int32_t streamID, Plugins::MediaInfo& mediaInfo)
304 {
305     MEDIA_LOG_I("AddMediaInfo enter");
306     AddGeneral(streamInfoMap_[streamID], mediaInfo.general);
307     for (uint32_t index = 0; index < streamInfoMap_[streamID].mediaInfo.tracks.size(); index++) {
308         auto trackMeta = streamInfoMap_[streamID].mediaInfo.tracks[index];
309         mediaInfo.tracks.push_back(trackMeta);
310         MEDIA_LOG_I("AddMediaInfo streamID = " PUBLIC_LOG_D32 " index = " PUBLIC_LOG_D32, streamID, index);
311         AddTrackMapInfo(streamID, index);
312     }
313     return;
314 }
315 
AddTrackMapInfo(int32_t streamID,int32_t trackIndex)316 Status DemuxerPluginManager::AddTrackMapInfo(int32_t streamID, int32_t trackIndex)
317 {
318     MEDIA_LOG_D("DemuxerPluginManager::AddTrackMapInfo in");
319     for (const auto& iter : trackInfoMap_) {
320         if (iter.second.streamID == streamID && iter.second.innerTrackIndex == trackIndex) {
321             return Status::OK;
322         }
323     }
324     size_t index = trackInfoMap_.size();
325     trackInfoMap_[index].streamID = streamID;
326     trackInfoMap_[index].innerTrackIndex = trackIndex;
327     return Status::OK;
328 }
329 
DeleteTempTrackMapInfo(int32_t oldTrackId)330 void DemuxerPluginManager::DeleteTempTrackMapInfo(int32_t oldTrackId)
331 {
332     MEDIA_LOG_I("DeleteTempTrackMapInfo oldTrackId =  "  PUBLIC_LOG_D32, oldTrackId);
333     temp2TrackInfoMap_.erase(oldTrackId);
334 }
335 
UpdateTempTrackMapInfo(int32_t oldTrackId,int32_t newTrackId,int32_t newInnerTrackIndex)336 void DemuxerPluginManager::UpdateTempTrackMapInfo(int32_t oldTrackId, int32_t newTrackId, int32_t newInnerTrackIndex)
337 {
338     temp2TrackInfoMap_[oldTrackId].streamID = trackInfoMap_[newTrackId].streamID;
339     if (newInnerTrackIndex == -1) {
340         MEDIA_LOG_I("UpdateTempTrackMapInfo oldTrackId =  "  PUBLIC_LOG_D32 " newTrackId = " PUBLIC_LOG_D32
341             "innerTrackIndex = " PUBLIC_LOG_D32, oldTrackId, newTrackId, trackInfoMap_[newTrackId].innerTrackIndex);
342         temp2TrackInfoMap_[oldTrackId].innerTrackIndex = trackInfoMap_[newTrackId].innerTrackIndex;
343     } else {
344         MEDIA_LOG_I("UpdateTempTrackMapInfo oldTrackId =  "  PUBLIC_LOG_D32 " newTrackId = " PUBLIC_LOG_D32
345             "innerTrackIndex = " PUBLIC_LOG_D32, oldTrackId, newTrackId, newInnerTrackIndex);
346         temp2TrackInfoMap_[oldTrackId].innerTrackIndex = newInnerTrackIndex;
347     }
348 }
349 
GetTmpInnerTrackIDByTrackID(int32_t trackId)350 int32_t DemuxerPluginManager::GetTmpInnerTrackIDByTrackID(int32_t trackId)
351 {
352     auto iter = temp2TrackInfoMap_.find(trackId);
353     if (iter != temp2TrackInfoMap_.end()) {
354         return temp2TrackInfoMap_[trackId].innerTrackIndex;
355     }
356     return INVALID_STREAM_OR_TRACK_ID;  // default
357 }
358 
GetTmpStreamIDByTrackID(int32_t trackId)359 int32_t DemuxerPluginManager::GetTmpStreamIDByTrackID(int32_t trackId)
360 {
361     auto iter = temp2TrackInfoMap_.find(trackId);
362     if (iter != temp2TrackInfoMap_.end()) {
363         return temp2TrackInfoMap_[trackId].streamID;
364     }
365     return INVALID_STREAM_OR_TRACK_ID;  // default
366 }
367 
UpdateGeneralValue(int32_t trackCount,const Meta & format,Meta & formatNew)368 Status DemuxerPluginManager::UpdateGeneralValue(int32_t trackCount, const Meta& format, Meta& formatNew)
369 {
370     formatNew.Set<Tag::MEDIA_TRACK_COUNT>(trackCount);
371 
372     bool hasVideo = false;
373     format.Get<Tag::MEDIA_HAS_VIDEO>(hasVideo);
374     if (hasVideo) {
375         formatNew.Set<Tag::MEDIA_HAS_VIDEO>(hasVideo);
376     }
377 
378     bool hasAudio = false;
379     format.Get<Tag::MEDIA_HAS_AUDIO>(hasAudio);
380     if (hasAudio) {
381         formatNew.Set<Tag::MEDIA_HAS_AUDIO>(hasAudio);
382     }
383 
384     bool hasSubtitle = false;
385     format.Get<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
386     if (hasSubtitle) {
387         formatNew.Set<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
388     }
389     return Status::OK;
390 }
391 
AddGeneral(const MediaStreamInfo & info,Meta & formatNew)392 Status DemuxerPluginManager::AddGeneral(const MediaStreamInfo& info, Meta& formatNew)
393 {
394     FileType fileType = FileType::UNKNOW;
395     int32_t curTrackCount = 0;
396     formatNew.Get<Tag::MEDIA_TRACK_COUNT>(curTrackCount);
397 
398     bool hasVideo = false;
399     formatNew.Get<Tag::MEDIA_HAS_VIDEO>(hasVideo);
400 
401     bool hasAudio = false;
402     formatNew.Get<Tag::MEDIA_HAS_AUDIO>(hasAudio);
403 
404     bool hasSubtitle = false;
405     formatNew.Get<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
406 
407     if (formatNew.Get<Tag::MEDIA_FILE_TYPE>(fileType) == false && info.activated == true) {
408         formatNew = info.mediaInfo.general;
409     }
410 
411     formatNew.Set<Tag::MEDIA_HAS_VIDEO>(hasVideo);
412     formatNew.Set<Tag::MEDIA_HAS_AUDIO>(hasAudio);
413     formatNew.Set<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
414 
415     int32_t newTrackCount = 0;
416     if (info.mediaInfo.general.Get<Tag::MEDIA_TRACK_COUNT>(newTrackCount) == false) {
417         newTrackCount = 1;
418     }
419     int32_t totalTrackCount = newTrackCount + curTrackCount;
420     UpdateGeneralValue(totalTrackCount, info.mediaInfo.general, formatNew);
421 
422     return Status::OK;
423 }
424 
CheckTrackIsActive(int32_t trackId)425 bool DemuxerPluginManager::CheckTrackIsActive(int32_t trackId)
426 {
427     MEDIA_LOG_I("CheckTrackIsActive enter");
428     auto iter = trackInfoMap_.find(trackId);
429     if (iter != trackInfoMap_.end()) {
430         int32_t streamId = iter->second.streamID;
431         return streamInfoMap_[streamId].activated;
432     }
433     return false;
434 }
435 
GetInnerTrackIDByTrackID(int32_t trackId)436 int32_t DemuxerPluginManager::GetInnerTrackIDByTrackID(int32_t trackId)
437 {
438     auto iter = trackInfoMap_.find(trackId);
439     if (iter != trackInfoMap_.end()) {
440         return trackInfoMap_[trackId].innerTrackIndex;
441     }
442     return INVALID_STREAM_OR_TRACK_ID;  // default
443 }
444 
GetStreamIDByTrackID(int32_t trackId)445 int32_t DemuxerPluginManager::GetStreamIDByTrackID(int32_t trackId)
446 {
447     auto iter = trackInfoMap_.find(trackId);
448     if (iter != trackInfoMap_.end()) {
449         return trackInfoMap_[trackId].streamID;
450     }
451     return INVALID_STREAM_OR_TRACK_ID;  // default
452 }
453 
GetStreamIDByTrackType(TrackType type)454 int32_t DemuxerPluginManager::GetStreamIDByTrackType(TrackType type)
455 {
456     if (type == TRACK_VIDEO) {
457         return curVideoStreamID_;
458     } else if (type == TRACK_AUDIO) {
459         return curAudioStreamID_;
460     } else if (type == TRACK_SUBTITLE) {
461         return curSubTitleStreamID_;
462     } else {
463         return INVALID_STREAM_OR_TRACK_ID;
464     }
465 }
466 
CreatePlugin(std::string pluginName,int32_t id)467 bool DemuxerPluginManager::CreatePlugin(std::string pluginName, int32_t id)
468 {
469     if (streamInfoMap_[id].plugin != nullptr) {
470         streamInfoMap_[id].plugin->Deinit();
471     }
472     auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(pluginName);
473     if (plugin == nullptr) {
474         return false;
475     }
476     streamInfoMap_[id].plugin = std::static_pointer_cast<Plugins::DemuxerPlugin>(plugin);
477     if (!streamInfoMap_[id].plugin || streamInfoMap_[id].plugin->Init() != Status::OK) {
478         MEDIA_LOG_E("CreatePlugin " PUBLIC_LOG_S " failed.", pluginName.c_str());
479         return false;
480     }
481     MEDIA_LOG_I("CreatePlugin " PUBLIC_LOG_S " success, id " PUBLIC_LOG_D32, pluginName.c_str(), id);
482     streamInfoMap_[id].pluginName = pluginName;
483     return true;
484 }
485 
InitPlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,const std::string & pluginName,int32_t id)486 bool DemuxerPluginManager::InitPlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
487     const std::string& pluginName, int32_t id)
488 {
489     if (pluginName.empty()) {
490         return false;
491     }
492     if (streamInfoMap_[id].pluginName != pluginName) {
493         FALSE_RETURN_V(CreatePlugin(pluginName, id), false);
494     } else {
495         if (streamInfoMap_[id].plugin->Reset() != Status::OK) {
496             FALSE_RETURN_V(CreatePlugin(pluginName, id), false);
497         }
498     }
499     MEDIA_LOG_I("InitPlugin, " PUBLIC_LOG_S " used, id " PUBLIC_LOG_D32, pluginName.c_str(), id);
500     streamDemuxer->SetDemuxerState(id, DemuxerState::DEMUXER_STATE_PARSE_HEADER);
501     if (streamDemuxer->GetIsExtSubtitle() == true) {
502         streamDemuxer->SetIsDash(false);
503     } else {
504         streamDemuxer->SetIsDash(isDash_);
505     }
506 
507     streamInfoMap_[id].dataSource = std::make_shared<DataSourceImpl>(streamDemuxer, id);
508     if (streamDemuxer->GetIsExtSubtitle() == true) {
509         streamInfoMap_[id].dataSource->SetIsDash(false);
510     } else {
511         streamInfoMap_[id].dataSource->SetIsDash(isDash_);
512     }
513 
514     Status st = streamInfoMap_[id].plugin->SetDataSource(streamInfoMap_[id].dataSource);
515     return st == Status::OK;
516 }
517 
IsDash() const518 bool DemuxerPluginManager::IsDash() const
519 {
520     return isDash_;
521 }
522 
SetResetEosStatus(bool flag)523 void DemuxerPluginManager::SetResetEosStatus(bool flag)
524 {
525     needResetEosStatus_ = flag;
526 }
527 
StartPlugin(int32_t streamId,std::shared_ptr<BaseStreamDemuxer> streamDemuxer)528 Status DemuxerPluginManager::StartPlugin(int32_t streamId, std::shared_ptr<BaseStreamDemuxer> streamDemuxer)
529 {
530     MEDIA_LOG_I("StartPlugin begin. id = " PUBLIC_LOG_D32, streamId);
531     auto iter = streamInfoMap_.find(streamId);
532     if (iter != streamInfoMap_.end()) {
533         streamInfoMap_[streamId].activated = true;
534         if (streamInfoMap_[streamId].plugin != nullptr) {
535             streamInfoMap_[streamId].plugin.reset();
536             streamInfoMap_[streamId].pluginName = "";
537         }
538         streamDemuxer->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_HEADER);
539         Status ret = LoadDemuxerPlugin(streamId, streamDemuxer);
540         streamDemuxer->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
541         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin failed.");
542         UpdateMediaInfo(streamId);
543     }
544     MEDIA_LOG_I("StartPlugin success. id = " PUBLIC_LOG_D32, streamId);
545     return Status::OK;
546 }
547 
StopPlugin(int32_t streamId,std::shared_ptr<BaseStreamDemuxer> streamDemuxer)548 Status DemuxerPluginManager::StopPlugin(int32_t streamId, std::shared_ptr<BaseStreamDemuxer> streamDemuxer)
549 {
550     MEDIA_LOG_I("StopPlugin begin. id = " PUBLIC_LOG_D32, streamId);
551     auto iter = streamInfoMap_.find(streamId);
552     if (iter != streamInfoMap_.end()) {
553         streamInfoMap_[streamId].activated = false;
554         if (streamInfoMap_[streamId].plugin != nullptr) {
555             streamInfoMap_[streamId].plugin.reset();
556             streamInfoMap_[streamId].pluginName = "";
557         }
558     }
559     streamDemuxer->ResetCache(streamId);
560     MEDIA_LOG_I("StopPlugin success. id = " PUBLIC_LOG_D32, streamId);
561     return Status::OK;
562 }
563 
RebootPlugin(int32_t streamId,TrackType trackType,std::shared_ptr<BaseStreamDemuxer> streamDemuxer,bool & isRebooted)564 Status DemuxerPluginManager::RebootPlugin(int32_t streamId, TrackType trackType,
565     std::shared_ptr<BaseStreamDemuxer> streamDemuxer, bool& isRebooted)
566 {
567     FALSE_RETURN_V_MSG_E(streamInfoMap_.find(streamId) != streamInfoMap_.end(),
568         Status::ERROR_INVALID_PARAMETER, "streamId is invalid");
569     FALSE_RETURN_V_MSG_E(streamDemuxer != nullptr, Status::ERROR_NULL_POINTER, "streamDemuxer is nullptr");
570     MEDIA_LOG_D("RebootPlugin begin. id = " PUBLIC_LOG_D32, streamId);
571     streamDemuxer->ResetCache(streamId);
572     streamDemuxer->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_HEADER);
573     std::string type = streamDemuxer->SnifferMediaType(streamId);
574     int32_t newStreamId = GetStreamDemuxerNewStreamID(trackType, streamDemuxer);
575     MEDIA_LOG_D("TrackType: " PUBLIC_LOG_D32 " oldstreamID: " PUBLIC_LOG_D32 " newStreamID: " PUBLIC_LOG_D32,
576         static_cast<int32_t>(trackType), streamId, newStreamId);
577     if (newStreamId != INVALID_STREAM_OR_TRACK_ID && streamId != newStreamId) {
578         MEDIA_LOG_I("StreamID changed, oldstreamID: " PUBLIC_LOG_D32 " newStreamID: " PUBLIC_LOG_D32,
579             streamId, newStreamId);
580         isRebooted = false;
581         return Status::OK;
582     }
583     if (type.empty()) {
584         MEDIA_LOG_W("RebootPlugin failed, sniff failed");
585     }
586 
587     // Start to reboot demuxer plugin while streamId is not changed
588     streamInfoMap_[streamId].activated = true;
589     if (streamInfoMap_[streamId].plugin != nullptr) {
590         streamInfoMap_[streamId].plugin.reset();
591         type = type.empty()? streamInfoMap_[streamId].pluginName : type;
592         streamInfoMap_[streamId].pluginName = "";
593     }
594     MediaTypeFound(streamDemuxer, type, streamId);
595     FALSE_RETURN_V_MSG_E(streamInfoMap_[streamId].plugin != nullptr, Status::ERROR_INVALID_PARAMETER,
596         "Set data source failed due to create video demuxer plugin failed");
597     Plugins::MediaInfo mediaInfoTemp;
598     Status ret = streamInfoMap_[streamId].plugin->GetMediaInfo(mediaInfoTemp);
599     isRebooted = true;
600     streamDemuxer->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
601     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "GetMediaInfo failed");
602     streamInfoMap_[streamId].mediaInfo = mediaInfoTemp;
603     UpdateMediaInfo(streamId);
604     MEDIA_LOG_D("RebootPlugin success. id = " PUBLIC_LOG_D32, streamId);
605     return Status::OK;
606 }
607 
MediaTypeFound(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,const std::string & pluginName,int32_t id)608 void DemuxerPluginManager::MediaTypeFound(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
609     const std::string& pluginName, int32_t id)
610 {
611     MediaAVCodec::AVCodecTrace trace("DemuxerPluginManager::MediaTypeFound");
612     if (!InitPlugin(streamDemuxer, pluginName, id)) {
613         MEDIA_LOG_E("MediaTypeFound init plugin error.");
614     }
615 }
616 
GetStreamDemuxerNewStreamID(TrackType trackType,std::shared_ptr<BaseStreamDemuxer> streamDemuxer)617 int32_t DemuxerPluginManager::GetStreamDemuxerNewStreamID(TrackType trackType,
618     std::shared_ptr<BaseStreamDemuxer> streamDemuxer)
619 {
620     FALSE_RETURN_V_MSG_E(streamDemuxer != nullptr, INVALID_STREAM_OR_TRACK_ID, "streamDemuxer is nullptr");
621     int32_t newStreamID = INVALID_STREAM_OR_TRACK_ID;
622     if (trackType == TRACK_AUDIO) {
623         newStreamID = streamDemuxer->GetNewAudioStreamID();
624     } else if (trackType == TRACK_SUBTITLE) {
625         newStreamID = streamDemuxer->GetNewSubtitleStreamID();
626     } else if (trackType == TRACK_VIDEO) {
627         newStreamID = streamDemuxer->GetNewVideoStreamID();
628     } else {
629         MEDIA_LOG_W("Invalid trackType " PUBLIC_LOG_U32, trackType);
630         return INVALID_STREAM_OR_TRACK_ID;
631     }
632     return newStreamID;
633 }
634 
localSubtitleSeekTo(int64_t seekTime)635 Status DemuxerPluginManager::localSubtitleSeekTo(int64_t seekTime)
636 {
637     FALSE_RETURN_V_MSG_E(curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr,
638                          Status::ERROR_NO_MEMORY, "subtitle seek failed, no subtitle");
639     int64_t realSeekTime = 0;
640     auto plugin = streamInfoMap_[curSubTitleStreamID_].plugin;
641     auto preSeekRes = plugin->SeekTo(-1, seekTime, Plugins::SeekMode::SEEK_PREVIOUS_SYNC, realSeekTime);
642     FALSE_RETURN_V(preSeekRes != Status::OK, Status::OK);
643     return plugin->SeekTo(-1, seekTime, Plugins::SeekMode::SEEK_NEXT_SYNC, realSeekTime);
644 }
645 
SeekTo(int64_t seekTime,Plugins::SeekMode mode,int64_t & realSeekTime)646 Status DemuxerPluginManager::SeekTo(int64_t seekTime, Plugins::SeekMode mode, int64_t& realSeekTime)
647 {
648     if (curAudioStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
649         Status ret = streamInfoMap_[curAudioStreamID_].plugin->SeekTo(-1, seekTime, mode, realSeekTime);
650         if (ret != Status::OK) {
651             return ret;
652         }
653     }
654     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
655         Status ret = streamInfoMap_[curVideoStreamID_].plugin->SeekTo(-1, seekTime, mode, realSeekTime);
656         if (ret != Status::OK) {
657             return ret;
658         }
659     }
660     if (curSubTitleStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
661         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->SeekTo(-1, seekTime, mode, realSeekTime);
662         if (ret != Status::OK && mode != Plugins::SeekMode::SEEK_NEXT_SYNC) {
663             ret = streamInfoMap_[curSubTitleStreamID_].plugin->SeekTo(
664                 -1, seekTime, Plugins::SeekMode::SEEK_NEXT_SYNC, realSeekTime);
665         }
666     }
667     return Status::OK;
668 }
669 
Flush()670 Status DemuxerPluginManager::Flush()
671 {
672     if (curAudioStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
673         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Flush();
674         if (needResetEosStatus_) {
675             streamInfoMap_[curAudioStreamID_].plugin->ResetEosStatus();
676         }
677         if (ret != Status::OK) {
678             return ret;
679         }
680     }
681     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
682         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Flush();
683         if (needResetEosStatus_) {
684             streamInfoMap_[curVideoStreamID_].plugin->ResetEosStatus();
685         }
686         if (ret != Status::OK) {
687             return ret;
688         }
689     }
690     if (curSubTitleStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
691         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Flush();
692         if (needResetEosStatus_) {
693             streamInfoMap_[curSubTitleStreamID_].plugin->ResetEosStatus();
694         }
695         if (ret != Status::OK) {
696             return ret;
697         }
698     }
699     return Status::OK;
700 }
701 
Reset()702 Status DemuxerPluginManager::Reset()
703 {
704     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
705         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Reset();
706         if (ret != Status::OK) {
707             return ret;
708         }
709     }
710     if (curAudioStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
711         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Reset();
712         if (ret != Status::OK) {
713             return ret;
714         }
715     }
716     if (curSubTitleStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
717         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Reset();
718         if (ret != Status::OK) {
719             return ret;
720         }
721     }
722     return Status::OK;   // todo: 待适配返回值
723 }
724 
Stop()725 Status DemuxerPluginManager::Stop()
726 {
727     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
728         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Stop();
729         if (ret != Status::OK) {
730             return ret;
731         }
732     }
733     if (curAudioStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
734         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Stop();
735         if (ret != Status::OK) {
736             return ret;
737         }
738     }
739     if (curSubTitleStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
740         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Stop();
741         if (ret != Status::OK) {
742             return ret;
743         }
744     }
745     return Status::OK;   // todo: 待适配返回值
746 }
747 
Start()748 Status DemuxerPluginManager::Start()
749 {
750     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
751         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Start();
752         if (ret != Status::OK) {
753             return ret;
754         }
755     }
756     if (curAudioStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
757         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Start();
758         if (ret != Status::OK) {
759             return ret;
760         }
761     }
762     if (curSubTitleStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
763         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Start();
764         if (ret != Status::OK) {
765             return ret;
766         }
767     }
768     return Status::OK;   // todo: 待适配返回值
769 }
770 
UpdateMediaInfo(int32_t streamID)771 Status DemuxerPluginManager::UpdateMediaInfo(int32_t streamID)
772 {
773     Plugins::MediaInfo mediaInfo = curMediaInfo_;
774     std::map<int32_t, MediaTrackMap> tempTrackInfoMap = trackInfoMap_;
775     for (size_t i = 0; i < streamInfoMap_[streamID].mediaInfo.tracks.size(); i++) {
776         auto trackMeta = streamInfoMap_[streamID].mediaInfo.tracks[i];
777         size_t j = 0;
778         for (j = 0; j < tempTrackInfoMap.size(); j++) {
779             if (tempTrackInfoMap[j].streamID == streamID
780                 && tempTrackInfoMap[j].innerTrackIndex == static_cast<int32_t>(i)) {
781                 mediaInfo.tracks[j] = trackMeta;     // cover
782                 break;
783             }
784         }
785         if (j >= tempTrackInfoMap.size()) {   // can not find, add
786             AddTrackMapInfo(streamID, static_cast<int32_t>(i));
787             mediaInfo.tracks.push_back(trackMeta);
788         }
789     }
790 
791     UpdateGeneralValue(trackInfoMap_.size() - tempTrackInfoMap.size(),
792         streamInfoMap_[streamID].mediaInfo.general, mediaInfo.general);
793 
794     curMediaInfo_ = mediaInfo;
795     return Status::OK;
796 }
797 
UpdateDefaultStreamID(Plugins::MediaInfo & mediaInfo,StreamType type,int32_t newStreamID)798 Status DemuxerPluginManager::UpdateDefaultStreamID(Plugins::MediaInfo& mediaInfo, StreamType type, int32_t newStreamID)
799 {
800     MEDIA_LOG_I("UpdateDefaultStreamID plugin");
801     if (type == AUDIO) {
802         curAudioStreamID_ = newStreamID;
803     } else if (type == SUBTITLE) {
804         curSubTitleStreamID_ = newStreamID;
805     } else if (type == VIDEO) {
806         curVideoStreamID_ = newStreamID;
807     } else {}
808 
809     mediaInfo = curMediaInfo_;
810     return Status::OK;
811 }
812 
GetUserMeta()813 std::shared_ptr<Meta> DemuxerPluginManager::GetUserMeta()
814 {
815     if (IsDash()) {
816         MEDIA_LOG_W("GetUserMeta dash not support.");
817         return nullptr;
818     }
819     std::shared_ptr<Meta> meta = std::make_shared<Meta>();
820     FALSE_RETURN_V_MSG_E(meta != nullptr, nullptr, "Create meta failed.");
821     if (curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID && streamInfoMap_[curVideoStreamID_].plugin) {
822         Status ret = streamInfoMap_[curVideoStreamID_].plugin->GetUserMeta(meta);
823         if (ret != Status::OK) {
824             MEDIA_LOG_W("No valid user data");
825         }
826     } else {
827         MEDIA_LOG_W("Demuxer plugin is not exist.");
828     }
829     return meta;
830 }
831 
GetCurrentBitRate()832 uint32_t DemuxerPluginManager::GetCurrentBitRate()
833 {
834     if (IsDash() && curVideoStreamID_ != INVALID_STREAM_OR_TRACK_ID) {
835         return streamInfoMap_[curVideoStreamID_].bitRate;
836     }
837     return 0;
838 }
839 
GetStreamTypeByTrackID(int32_t trackId)840 StreamType DemuxerPluginManager::GetStreamTypeByTrackID(int32_t trackId)
841 {
842     int32_t streamID = GetStreamIDByTrackID(trackId);
843     return streamInfoMap_[streamID].type;
844 }
845 
IsSubtitleMime(const std::string & mime)846 bool DemuxerPluginManager::IsSubtitleMime(const std::string& mime)
847 {
848     if (mime == "application/x-subrip" || mime == "text/vtt") {
849         return true;
850     }
851     return false;
852 }
853 
GetTrackTypeByTrackID(int32_t trackId)854 TrackType DemuxerPluginManager::GetTrackTypeByTrackID(int32_t trackId)
855 {
856     if (static_cast<size_t>(trackId) >= curMediaInfo_.tracks.size()) {
857         return TRACK_INVALID;
858     }
859     std::string mimeType = "";
860     bool ret = curMediaInfo_.tracks[trackId].Get<Tag::MIME_TYPE>(mimeType);
861     if (ret && mimeType.find("audio") == 0) {
862         return TRACK_AUDIO;
863     } else if (ret && mimeType.find("video") == 0) {
864         return TRACK_VIDEO;
865     } else if (ret && IsSubtitleMime(mimeType)) {
866         return TRACK_SUBTITLE;
867     } else {
868         return TRACK_INVALID;
869     }
870 }
871 
AddExternalSubtitle()872 int32_t DemuxerPluginManager::AddExternalSubtitle()
873 {
874     if (curSubTitleStreamID_ == INVALID_STREAM_OR_TRACK_ID) {
875         int32_t streamIndex = static_cast<int32_t>(streamInfoMap_.size());
876         curSubTitleStreamID_ = streamIndex;
877         streamInfoMap_[streamIndex].activated = true;
878         streamInfoMap_[streamIndex].type = SUBTITLE;
879         MEDIA_LOG_I("InitDefaultPlay SUBTITLE");
880         return streamIndex;
881     }
882     return INVALID_STREAM_OR_TRACK_ID;
883 }
884 
SetCacheLimit(uint32_t limitSize)885 Status DemuxerPluginManager::SetCacheLimit(uint32_t limitSize)
886 {
887     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
888         streamInfoMap_[curVideoStreamID_].plugin->SetCacheLimit(limitSize);
889     }
890     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
891         streamInfoMap_[curAudioStreamID_].plugin->SetCacheLimit(limitSize);
892     }
893     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
894         streamInfoMap_[curSubTitleStreamID_].plugin->SetCacheLimit(limitSize);
895     }
896     return Status::OK;
897 }
898 
899 } // namespace Media
900 } // namespace OHOS
901