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