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