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