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