• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_I("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_I("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 
270     if (curSubTitleStreamID_ != -1) {
271         MEDIA_LOG_I("LoadCurrentAllPlugin subtitle plugin");
272         Status ret = LoadDemuxerPlugin(curSubTitleStreamID_, streamDemuxer);
273         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin subtitle plugin failed.");
274     }
275 
276     for (auto& iter : streamInfoMap_) {
277         AddMediaInfo(iter.first, mediaInfo);
278     }
279 
280     curMediaInfo_ = mediaInfo;
281     return Status::OK;
282 }
283 
LoadCurrentSubtitlePlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,Plugins::MediaInfo & mediaInfo)284 Status DemuxerPluginManager::LoadCurrentSubtitlePlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
285     Plugins::MediaInfo& mediaInfo)
286 {
287     if (curSubTitleStreamID_ == -1) {
288         MEDIA_LOG_I("LoadCurrentSubtitleDemuxerPlugin failed, curSubTitleStreamID_ invalid");
289         return Status::ERROR_UNKNOWN;
290     }
291 
292     mediaInfo = curMediaInfo_;
293     MEDIA_LOG_I("LoadCurrentSubtitleDemuxerPlugin begin");
294     Status ret = LoadDemuxerPlugin(curSubTitleStreamID_, streamDemuxer);
295     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin subtitle plugin failed.");
296     AddMediaInfo(curSubTitleStreamID_, mediaInfo);
297     curMediaInfo_ = mediaInfo;
298     MEDIA_LOG_I("LoadCurrentSubtitleDemuxerPlugin success");
299     return Status::OK;
300 }
301 
AddMediaInfo(int32_t streamID,Plugins::MediaInfo & mediaInfo)302 void DemuxerPluginManager::AddMediaInfo(int32_t streamID, Plugins::MediaInfo& mediaInfo)
303 {
304     MEDIA_LOG_I("AddMediaInfo enter");
305     AddGeneral(streamInfoMap_[streamID], mediaInfo.general);
306     for (uint32_t index = 0; index < streamInfoMap_[streamID].mediaInfo.tracks.size(); index++) {
307         auto trackMeta = streamInfoMap_[streamID].mediaInfo.tracks[index];
308         mediaInfo.tracks.push_back(trackMeta);
309         MEDIA_LOG_I("AddMediaInfo streamID = " PUBLIC_LOG_D32 " index = " PUBLIC_LOG_D32, streamID, index);
310         AddTrackMapInfo(streamID, index);
311     }
312     return;
313 }
314 
AddTrackMapInfo(int32_t streamID,int32_t trackIndex)315 Status DemuxerPluginManager::AddTrackMapInfo(int32_t streamID, int32_t trackIndex)
316 {
317     MEDIA_LOG_D("DemuxerPluginManager::AddTrackMapInfo in");
318     for (const auto& iter : trackInfoMap_) {
319         if (iter.second.streamID == streamID && iter.second.innerTrackIndex == trackIndex) {
320             return Status::OK;
321         }
322     }
323     size_t index = trackInfoMap_.size();
324     trackInfoMap_[index].streamID = streamID;
325     trackInfoMap_[index].innerTrackIndex = trackIndex;
326     return Status::OK;
327 }
328 
DeleteTempTrackMapInfo(int32_t oldTrackId)329 void DemuxerPluginManager::DeleteTempTrackMapInfo(int32_t oldTrackId)
330 {
331     MEDIA_LOG_I("DeleteTempTrackMapInfo oldTrackId =  "  PUBLIC_LOG_D32, oldTrackId);
332     temp2TrackInfoMap_.erase(oldTrackId);
333 }
334 
UpdateTempTrackMapInfo(int32_t oldTrackId,int32_t newTrackId,int32_t newInnerTrackIndex)335 void DemuxerPluginManager::UpdateTempTrackMapInfo(int32_t oldTrackId, int32_t newTrackId, int32_t newInnerTrackIndex)
336 {
337     temp2TrackInfoMap_[oldTrackId].streamID = trackInfoMap_[newTrackId].streamID;
338     if (newInnerTrackIndex == -1) {
339         MEDIA_LOG_I("UpdateTempTrackMapInfo oldTrackId =  "  PUBLIC_LOG_D32 " newTrackId = " PUBLIC_LOG_D32
340             "innerTrackIndex = " PUBLIC_LOG_D32, oldTrackId, newTrackId, trackInfoMap_[newTrackId].innerTrackIndex);
341         temp2TrackInfoMap_[oldTrackId].innerTrackIndex = trackInfoMap_[newTrackId].innerTrackIndex;
342     } else {
343         MEDIA_LOG_I("UpdateTempTrackMapInfo oldTrackId =  "  PUBLIC_LOG_D32 " newTrackId = " PUBLIC_LOG_D32
344             "innerTrackIndex = " PUBLIC_LOG_D32, oldTrackId, newTrackId, newInnerTrackIndex);
345         temp2TrackInfoMap_[oldTrackId].innerTrackIndex = newInnerTrackIndex;
346     }
347 }
348 
GetTmpInnerTrackIDByTrackID(int32_t trackId)349 int32_t DemuxerPluginManager::GetTmpInnerTrackIDByTrackID(int32_t trackId)
350 {
351     auto iter = temp2TrackInfoMap_.find(trackId);
352     if (iter != temp2TrackInfoMap_.end()) {
353         return temp2TrackInfoMap_[trackId].innerTrackIndex;
354     }
355     return -1;  // default
356 }
357 
GetTmpStreamIDByTrackID(int32_t trackId)358 int32_t DemuxerPluginManager::GetTmpStreamIDByTrackID(int32_t trackId)
359 {
360     auto iter = temp2TrackInfoMap_.find(trackId);
361     if (iter != temp2TrackInfoMap_.end()) {
362         return temp2TrackInfoMap_[trackId].streamID;
363     }
364     return -1;  // default
365 }
366 
UpdateGeneralValue(int32_t trackCount,const Meta & format,Meta & formatNew)367 Status DemuxerPluginManager::UpdateGeneralValue(int32_t trackCount, const Meta& format, Meta& formatNew)
368 {
369     formatNew.Set<Tag::MEDIA_TRACK_COUNT>(trackCount);
370 
371     bool hasVideo = false;
372     format.Get<Tag::MEDIA_HAS_VIDEO>(hasVideo);
373     if (hasVideo) {
374         formatNew.Set<Tag::MEDIA_HAS_VIDEO>(hasVideo);
375     }
376 
377     bool hasAudio = false;
378     format.Get<Tag::MEDIA_HAS_AUDIO>(hasAudio);
379     if (hasAudio) {
380         formatNew.Set<Tag::MEDIA_HAS_AUDIO>(hasAudio);
381     }
382 
383     bool hasSubtitle = false;
384     format.Get<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
385     if (hasSubtitle) {
386         formatNew.Set<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
387     }
388     return Status::OK;
389 }
390 
AddGeneral(const MediaStreamInfo & info,Meta & formatNew)391 Status DemuxerPluginManager::AddGeneral(const MediaStreamInfo& info, Meta& formatNew)
392 {
393     FileType fileType = FileType::UNKNOW;
394     int32_t curTrackCount = 0;
395     formatNew.Get<Tag::MEDIA_TRACK_COUNT>(curTrackCount);
396 
397     bool hasVideo = false;
398     formatNew.Get<Tag::MEDIA_HAS_VIDEO>(hasVideo);
399 
400     bool hasAudio = false;
401     formatNew.Get<Tag::MEDIA_HAS_AUDIO>(hasAudio);
402 
403     bool hasSubtitle = false;
404     formatNew.Get<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
405 
406     if (formatNew.Get<Tag::MEDIA_FILE_TYPE>(fileType) == false && info.activated == true) {
407         formatNew = info.mediaInfo.general;
408     }
409 
410     formatNew.Set<Tag::MEDIA_HAS_VIDEO>(hasVideo);
411     formatNew.Set<Tag::MEDIA_HAS_AUDIO>(hasAudio);
412     formatNew.Set<Tag::MEDIA_HAS_SUBTITLE>(hasSubtitle);
413 
414     int32_t newTrackCount = 0;
415     if (info.mediaInfo.general.Get<Tag::MEDIA_TRACK_COUNT>(newTrackCount) == false) {
416         newTrackCount = 1;
417     }
418     int32_t totalTrackCount = newTrackCount + curTrackCount;
419     UpdateGeneralValue(totalTrackCount, info.mediaInfo.general, formatNew);
420 
421     return Status::OK;
422 }
423 
CheckTrackIsActive(int32_t trackId)424 bool DemuxerPluginManager::CheckTrackIsActive(int32_t trackId)
425 {
426     MEDIA_LOG_I("CheckTrackIsActive enter");
427     auto iter = trackInfoMap_.find(trackId);
428     if (iter != trackInfoMap_.end()) {
429         int32_t streamId = iter->second.streamID;
430         return streamInfoMap_[streamId].activated;
431     }
432     return false;
433 }
434 
GetInnerTrackIDByTrackID(int32_t trackId)435 int32_t DemuxerPluginManager::GetInnerTrackIDByTrackID(int32_t trackId)
436 {
437     auto iter = trackInfoMap_.find(trackId);
438     if (iter != trackInfoMap_.end()) {
439         return trackInfoMap_[trackId].innerTrackIndex;
440     }
441     return -1;  // default
442 }
443 
GetStreamIDByTrackID(int32_t trackId)444 int32_t DemuxerPluginManager::GetStreamIDByTrackID(int32_t trackId)
445 {
446     auto iter = trackInfoMap_.find(trackId);
447     if (iter != trackInfoMap_.end()) {
448         return trackInfoMap_[trackId].streamID;
449     }
450     return -1;  // default
451 }
452 
CreatePlugin(std::string pluginName,int32_t id)453 bool DemuxerPluginManager::CreatePlugin(std::string pluginName, int32_t id)
454 {
455     if (streamInfoMap_[id].plugin != nullptr) {
456         streamInfoMap_[id].plugin->Deinit();
457     }
458     auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(pluginName);
459     if (plugin == nullptr) {
460         return false;
461     }
462     streamInfoMap_[id].plugin = std::static_pointer_cast<Plugins::DemuxerPlugin>(plugin);
463     if (!streamInfoMap_[id].plugin || streamInfoMap_[id].plugin->Init() != Status::OK) {
464         MEDIA_LOG_E("CreatePlugin " PUBLIC_LOG_S " failed.", pluginName.c_str());
465         return false;
466     }
467     MEDIA_LOG_I("CreatePlugin " PUBLIC_LOG_S " success, id " PUBLIC_LOG_D32, pluginName.c_str(), id);
468     streamInfoMap_[id].pluginName = pluginName;
469     return true;
470 }
471 
InitPlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,const std::string & pluginName,int32_t id)472 bool DemuxerPluginManager::InitPlugin(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
473     const std::string& pluginName, int32_t id)
474 {
475     if (pluginName.empty()) {
476         return false;
477     }
478     if (streamInfoMap_[id].pluginName != pluginName) {
479         FALSE_RETURN_V(CreatePlugin(pluginName, id), false);
480     } else {
481         if (streamInfoMap_[id].plugin->Reset() != Status::OK) {
482             FALSE_RETURN_V(CreatePlugin(pluginName, id), false);
483         }
484     }
485     MEDIA_LOG_I("InitPlugin, " PUBLIC_LOG_S " used, id " PUBLIC_LOG_D32, pluginName.c_str(), id);
486     streamDemuxer->SetDemuxerState(id, DemuxerState::DEMUXER_STATE_PARSE_HEADER);
487     if (streamDemuxer->GetIsExtSubtitle() == true) {
488         streamDemuxer->SetIsDash(false);
489     } else {
490         streamDemuxer->SetIsDash(isDash_);
491     }
492 
493     streamInfoMap_[id].dataSource = std::make_shared<DataSourceImpl>(streamDemuxer, id);
494     if (streamDemuxer->GetIsExtSubtitle() == true) {
495         streamInfoMap_[id].dataSource->SetIsDash(false);
496     } else {
497         streamInfoMap_[id].dataSource->SetIsDash(isDash_);
498     }
499 
500     Status st = streamInfoMap_[id].plugin->SetDataSource(streamInfoMap_[id].dataSource);
501     return st == Status::OK;
502 }
503 
IsDash() const504 bool DemuxerPluginManager::IsDash() const
505 {
506     return isDash_;
507 }
508 
SetResetEosStatus(bool flag)509 void DemuxerPluginManager::SetResetEosStatus(bool flag)
510 {
511     needResetEosStatus_ = flag;
512 }
513 
StartPlugin(int32_t streamId,std::shared_ptr<BaseStreamDemuxer> streamDemuxer)514 Status DemuxerPluginManager::StartPlugin(int32_t streamId, std::shared_ptr<BaseStreamDemuxer> streamDemuxer)
515 {
516     MEDIA_LOG_I("StartPlugin begin. id = " PUBLIC_LOG_D32, streamId);
517     auto iter = streamInfoMap_.find(streamId);
518     if (iter != streamInfoMap_.end()) {
519         streamInfoMap_[streamId].activated = true;
520         if (streamInfoMap_[streamId].plugin != nullptr) {
521             streamInfoMap_[streamId].plugin.reset();
522             streamInfoMap_[streamId].pluginName = "";
523         }
524         streamDemuxer->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_HEADER);
525         Status ret = LoadDemuxerPlugin(streamId, streamDemuxer);
526         streamDemuxer->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
527         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "LoadDemuxerPlugin failed.");
528         UpdateMediaInfo(streamId);
529     }
530     MEDIA_LOG_I("StartPlugin success. id = " PUBLIC_LOG_D32, streamId);
531     return Status::OK;
532 }
533 
StopPlugin(int32_t streamId,std::shared_ptr<BaseStreamDemuxer> streamDemuxer)534 Status DemuxerPluginManager::StopPlugin(int32_t streamId, std::shared_ptr<BaseStreamDemuxer> streamDemuxer)
535 {
536     MEDIA_LOG_I("StopPlugin begin. id = " PUBLIC_LOG_D32, streamId);
537     auto iter = streamInfoMap_.find(streamId);
538     if (iter != streamInfoMap_.end()) {
539         streamInfoMap_[streamId].activated = false;
540         if (streamInfoMap_[streamId].plugin != nullptr) {
541             streamInfoMap_[streamId].plugin.reset();
542             streamInfoMap_[streamId].pluginName = "";
543         }
544     }
545     streamDemuxer->ResetCache(streamId);
546     MEDIA_LOG_I("StopPlugin success. id = " PUBLIC_LOG_D32, streamId);
547     return Status::OK;
548 }
549 
MediaTypeFound(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,const std::string & pluginName,int32_t id)550 void DemuxerPluginManager::MediaTypeFound(std::shared_ptr<BaseStreamDemuxer> streamDemuxer,
551     const std::string& pluginName, int32_t id)
552 {
553     MediaAVCodec::AVCodecTrace trace("DemuxerPluginManager::MediaTypeFound");
554     if (!InitPlugin(streamDemuxer, pluginName, id)) {
555         MEDIA_LOG_E("MediaTypeFound init plugin error.");
556     }
557 }
558 
localSubtitleSeekTo(int64_t seekTime)559 Status DemuxerPluginManager::localSubtitleSeekTo(int64_t seekTime)
560 {
561     FALSE_RETURN_V_MSG_E(curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr,
562                          Status::ERROR_NO_MEMORY, "subtitle seek failed, no subtitle");
563     int64_t realSeekTime = 0;
564     auto plugin = streamInfoMap_[curSubTitleStreamID_].plugin;
565     auto preSeekRes = plugin->SeekTo(-1, seekTime, Plugins::SeekMode::SEEK_PREVIOUS_SYNC, realSeekTime);
566     FALSE_RETURN_V(preSeekRes != Status::OK, Status::OK);
567     return plugin->SeekTo(-1, seekTime, Plugins::SeekMode::SEEK_NEXT_SYNC, realSeekTime);
568 }
569 
SeekTo(int64_t seekTime,Plugins::SeekMode mode,int64_t & realSeekTime)570 Status DemuxerPluginManager::SeekTo(int64_t seekTime, Plugins::SeekMode mode, int64_t& realSeekTime)
571 {
572     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
573         Status ret = streamInfoMap_[curAudioStreamID_].plugin->SeekTo(-1, seekTime, mode, realSeekTime);
574         if (ret != Status::OK) {
575             return ret;
576         }
577     }
578     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
579         Status ret = streamInfoMap_[curVideoStreamID_].plugin->SeekTo(-1, seekTime, mode, realSeekTime);
580         if (ret != Status::OK) {
581             return ret;
582         }
583     }
584     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
585         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->SeekTo(-1, seekTime, mode, realSeekTime);
586         if (ret != Status::OK && mode != Plugins::SeekMode::SEEK_NEXT_SYNC) {
587             ret = streamInfoMap_[curSubTitleStreamID_].plugin->SeekTo(
588                 -1, seekTime, Plugins::SeekMode::SEEK_NEXT_SYNC, realSeekTime);
589         }
590     }
591     return Status::OK;
592 }
593 
Flush()594 Status DemuxerPluginManager::Flush()
595 {
596     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
597         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Flush();
598         if (needResetEosStatus_) {
599             streamInfoMap_[curAudioStreamID_].plugin->ResetEosStatus();
600         }
601         if (ret != Status::OK) {
602             return ret;
603         }
604     }
605     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
606         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Flush();
607         if (needResetEosStatus_) {
608             streamInfoMap_[curVideoStreamID_].plugin->ResetEosStatus();
609         }
610         if (ret != Status::OK) {
611             return ret;
612         }
613     }
614     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
615         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Flush();
616         if (needResetEosStatus_) {
617             streamInfoMap_[curSubTitleStreamID_].plugin->ResetEosStatus();
618         }
619         if (ret != Status::OK) {
620             return ret;
621         }
622     }
623     return Status::OK;
624 }
625 
Reset()626 Status DemuxerPluginManager::Reset()
627 {
628     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
629         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Reset();
630         if (ret != Status::OK) {
631             return ret;
632         }
633     }
634     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
635         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Reset();
636         if (ret != Status::OK) {
637             return ret;
638         }
639     }
640     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
641         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Reset();
642         if (ret != Status::OK) {
643             return ret;
644         }
645     }
646     return Status::OK;   // todo: 待适配返回值
647 }
648 
Stop()649 Status DemuxerPluginManager::Stop()
650 {
651     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
652         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Stop();
653         if (ret != Status::OK) {
654             return ret;
655         }
656     }
657     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
658         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Stop();
659         if (ret != Status::OK) {
660             return ret;
661         }
662     }
663     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
664         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Stop();
665         if (ret != Status::OK) {
666             return ret;
667         }
668     }
669     return Status::OK;   // todo: 待适配返回值
670 }
671 
Start()672 Status DemuxerPluginManager::Start()
673 {
674     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
675         Status ret = streamInfoMap_[curVideoStreamID_].plugin->Start();
676         if (ret != Status::OK) {
677             return ret;
678         }
679     }
680     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
681         Status ret = streamInfoMap_[curAudioStreamID_].plugin->Start();
682         if (ret != Status::OK) {
683             return ret;
684         }
685     }
686     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
687         Status ret = streamInfoMap_[curSubTitleStreamID_].plugin->Start();
688         if (ret != Status::OK) {
689             return ret;
690         }
691     }
692     return Status::OK;   // todo: 待适配返回值
693 }
694 
UpdateMediaInfo(int32_t streamID)695 Status DemuxerPluginManager::UpdateMediaInfo(int32_t streamID)
696 {
697     Plugins::MediaInfo mediaInfo = curMediaInfo_;
698     std::map<int32_t, MediaTrackMap> tempTrackInfoMap = trackInfoMap_;
699     for (size_t i = 0; i < streamInfoMap_[streamID].mediaInfo.tracks.size(); i++) {
700         auto trackMeta = streamInfoMap_[streamID].mediaInfo.tracks[i];
701         size_t j = 0;
702         for (j = 0; j < tempTrackInfoMap.size(); j++) {
703             if (tempTrackInfoMap[j].streamID == streamID
704                 && tempTrackInfoMap[j].innerTrackIndex == static_cast<int32_t>(i)) {
705                 mediaInfo.tracks[j] = trackMeta;     // cover
706                 break;
707             }
708         }
709         if (j >= tempTrackInfoMap.size()) {   // can not find, add
710             AddTrackMapInfo(streamID, static_cast<int32_t>(i));
711             mediaInfo.tracks.push_back(trackMeta);
712         }
713     }
714 
715     UpdateGeneralValue(trackInfoMap_.size() - tempTrackInfoMap.size(),
716         streamInfoMap_[streamID].mediaInfo.general, mediaInfo.general);
717 
718     curMediaInfo_ = mediaInfo;
719     return Status::OK;
720 }
721 
UpdateDefaultStreamID(Plugins::MediaInfo & mediaInfo,StreamType type,int32_t newStreamID)722 Status DemuxerPluginManager::UpdateDefaultStreamID(Plugins::MediaInfo& mediaInfo, StreamType type, int32_t newStreamID)
723 {
724     MEDIA_LOG_I("UpdateDefaultStreamID plugin");
725     if (type == AUDIO) {
726         curAudioStreamID_ = newStreamID;
727     } else if (type == SUBTITLE) {
728         curSubTitleStreamID_ = newStreamID;
729     } else if (type == VIDEO) {
730         curVideoStreamID_ = newStreamID;
731     } else {}
732 
733     mediaInfo = curMediaInfo_;
734     return Status::OK;
735 }
736 
GetUserMeta()737 std::shared_ptr<Meta> DemuxerPluginManager::GetUserMeta()
738 {
739     if (IsDash()) {
740         MEDIA_LOG_W("GetUserMeta dash not support.");
741         return nullptr;
742     }
743     std::shared_ptr<Meta> meta = std::make_shared<Meta>();
744     FALSE_RETURN_V_MSG_E(meta != nullptr, nullptr, "Create meta failed.");
745     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin) {
746         Status ret = streamInfoMap_[curVideoStreamID_].plugin->GetUserMeta(meta);
747         if (ret != Status::OK) {
748             MEDIA_LOG_W("No valid user data");
749         }
750     } else {
751         MEDIA_LOG_W("Demuxer plugin is not exist.");
752     }
753     return meta;
754 }
755 
GetCurrentBitRate()756 uint32_t DemuxerPluginManager::GetCurrentBitRate()
757 {
758     if (IsDash() && curVideoStreamID_ != -1) {
759         return streamInfoMap_[curVideoStreamID_].bitRate;
760     }
761     return 0;
762 }
763 
GetStreamTypeByTrackID(int32_t trackId)764 StreamType DemuxerPluginManager::GetStreamTypeByTrackID(int32_t trackId)
765 {
766     int32_t streamID = GetStreamIDByTrackID(trackId);
767     return streamInfoMap_[streamID].type;
768 }
769 
IsSubtitleMime(const std::string & mime)770 bool DemuxerPluginManager::IsSubtitleMime(const std::string& mime)
771 {
772     if (mime == "application/x-subrip" || mime == "text/vtt") {
773         return true;
774     }
775     return false;
776 }
777 
GetTrackTypeByTrackID(int32_t trackId)778 TrackType DemuxerPluginManager::GetTrackTypeByTrackID(int32_t trackId)
779 {
780     if (static_cast<size_t>(trackId) >= curMediaInfo_.tracks.size()) {
781         return TRACK_INVALID;
782     }
783     std::string mimeType = "";
784     bool ret = curMediaInfo_.tracks[trackId].Get<Tag::MIME_TYPE>(mimeType);
785     if (ret && mimeType.find("audio") == 0) {
786         return TRACK_AUDIO;
787     } else if (ret && mimeType.find("video") == 0) {
788         return TRACK_VIDEO;
789     } else if (ret && IsSubtitleMime(mimeType)) {
790         return TRACK_SUBTITLE;
791     } else {
792         return TRACK_INVALID;
793     }
794 }
795 
AddExternalSubtitle()796 int32_t DemuxerPluginManager::AddExternalSubtitle()
797 {
798     if (curSubTitleStreamID_ == -1) {
799         int32_t streamIndex = static_cast<int32_t>(streamInfoMap_.size());
800         curSubTitleStreamID_ = streamIndex;
801         streamInfoMap_[streamIndex].activated = true;
802         streamInfoMap_[streamIndex].type = SUBTITLE;
803         MEDIA_LOG_I("InitDefaultPlay SUBTITLE");
804         return streamIndex;
805     }
806     return -1;
807 }
808 
SetCacheLimit(uint32_t limitSize)809 Status DemuxerPluginManager::SetCacheLimit(uint32_t limitSize)
810 {
811     if (curVideoStreamID_ != -1 && streamInfoMap_[curVideoStreamID_].plugin != nullptr) {
812         streamInfoMap_[curVideoStreamID_].plugin->SetCacheLimit(limitSize);
813     }
814     if (curAudioStreamID_ != -1 && streamInfoMap_[curAudioStreamID_].plugin != nullptr) {
815         streamInfoMap_[curAudioStreamID_].plugin->SetCacheLimit(limitSize);
816     }
817     if (curSubTitleStreamID_ != -1 && streamInfoMap_[curSubTitleStreamID_].plugin != nullptr) {
818         streamInfoMap_[curSubTitleStreamID_].plugin->SetCacheLimit(limitSize);
819     }
820     return Status::OK;
821 }
822 
823 } // namespace Media
824 } // namespace OHOS
825