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