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