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