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