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