• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define HST_LOG_TAG "DemuxerPluginManager"
17 
18 #include "demuxer_plugin_manager.h"
19 
20 #include <algorithm>
21 #include <map>
22 #include <memory>
23 
24 #include "avcodec_common.h"
25 #include "avcodec_trace.h"
26 #include "cpp_ext/type_traits_ext.h"
27 #include "buffer/avallocator.h"
28 #include "common/event.h"
29 #include "common/log.h"
30 #include "meta/media_types.h"
31 #include "meta/meta.h"
32 #include "osal/utils/dump_buffer.h"
33 #include "plugin/plugin_buffer.h"
34 #include "plugin/plugin_info.h"
35 #include "plugin/plugin_manager_v2.h"
36 #include "plugin/plugin_time.h"
37 #include "base_stream_demuxer.h"
38 #include "media_demuxer.h"
39 
40 namespace {
41 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "DemuxerPluginManager" };
42 constexpr int32_t INVALID_STREAM_OR_TRACK_ID = -1;
43 constexpr 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