1 /*
2 * Copyright (c) 2023-2023 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 "MediaDemuxer"
17 #define MEDIA_ATOMIC_ABILITY
18
19 #include "media_demuxer.h"
20
21 #include <algorithm>
22 #include <map>
23 #include <memory>
24
25 #include "avcodec_common.h"
26 #include "avcodec_trace.h"
27 #include "cpp_ext/type_traits_ext.h"
28 #include "buffer/avallocator.h"
29 #include "common/event.h"
30 #include "format.h"
31 #include "common/log.h"
32 #include "hisysevent.h"
33 #include "meta/media_types.h"
34 #include "meta/meta.h"
35 #include "osal/utils/dump_buffer.h"
36 #include "plugin/plugin_buffer.h"
37 #include "plugin/plugin_info.h"
38 #include "plugin/plugin_time.h"
39 #include "source/source.h"
40 #include "stream_demuxer.h"
41 #include "media_core.h"
42 #include "osal/utils/dump_buffer.h"
43 #include "demuxer_plugin_manager.h"
44 #include "media_demuxer_pts_founctions.cpp"
45
46 namespace {
47 const std::string DUMP_PARAM = "a";
48 const std::string DUMP_DEMUXER_AUDIO_FILE_NAME = "player_demuxer_audio_output.es";
49 const std::string DUMP_DEMUXER_VIDEO_FILE_NAME = "player_demuxer_video_output.es";
50 static constexpr char PERFORMANCE_STATS[] = "PERFORMANCE";
51 static constexpr int32_t INVALID_TRACK_ID = -1;
52 std::map<OHOS::Media::TrackType, OHOS::Media::StreamType> TRACK_TO_STREAM_MAP = {
53 {OHOS::Media::TrackType::TRACK_VIDEO, OHOS::Media::StreamType::VIDEO},
54 {OHOS::Media::TrackType::TRACK_AUDIO, OHOS::Media::StreamType::AUDIO},
55 {OHOS::Media::TrackType::TRACK_SUBTITLE, OHOS::Media::StreamType::SUBTITLE},
56 {OHOS::Media::TrackType::TRACK_INVALID, OHOS::Media::StreamType::MIXED}
57 };
58 } // namespace
59
60 namespace OHOS {
61 namespace Media {
62 namespace {
63 constexpr uint32_t REQUEST_BUFFER_TIMEOUT = 0; // Requesting buffer overtimes 0ms means no retry
64 constexpr int32_t START = 1;
65 constexpr int32_t PAUSE = 2;
66 constexpr int32_t SEEK_TO_EOS = 1;
67 constexpr uint32_t RETRY_DELAY_TIME_US = 100000; // 100ms, Delay time for RETRY if no buffer in avbufferqueue producer.
68 constexpr double DECODE_RATE_THRESHOLD = 0.05; // allow actual rate exceeding 5%
69 constexpr uint32_t REQUEST_FAILED_RETRY_TIMES = 12000; // Max times for RETRY if no buffer in avbufferqueue producer.
70 constexpr int32_t DEFAULT_MULTI_VIDEO_TRACK_NUM = 5;
71 }
72
73 enum SceneCode : int32_t {
74 /**
75 * This option is used to mark parser ref for dragging play scene.
76 */
77 AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY = 3 // scene code of parser ref for dragging play is 3
78 };
79
80 class MediaDemuxer::AVBufferQueueProducerListener : public IRemoteStub<IProducerListener> {
81 public:
AVBufferQueueProducerListener(uint32_t trackId,std::shared_ptr<MediaDemuxer> demuxer,std::unique_ptr<Task> & notifyTask)82 explicit AVBufferQueueProducerListener(uint32_t trackId, std::shared_ptr<MediaDemuxer> demuxer,
83 std::unique_ptr<Task>& notifyTask) : trackId_(trackId), demuxer_(demuxer), notifyTask_(std::move(notifyTask)) {}
84
85 virtual ~AVBufferQueueProducerListener() = default;
OnRemoteRequest(uint32_t code,MessageParcel & arguments,MessageParcel & reply,MessageOption & option)86 int OnRemoteRequest(uint32_t code, MessageParcel& arguments, MessageParcel& reply, MessageOption& option) override
87 {
88 return IPCObjectStub::OnRemoteRequest(code, arguments, reply, option);
89 }
OnBufferAvailable()90 void OnBufferAvailable() override
91 {
92 MEDIA_LOG_D("Buffer available for track " PUBLIC_LOG_U32, trackId_);
93 if (notifyTask_ == nullptr) {
94 return;
95 }
96 notifyTask_->SubmitJobOnce([this] {
97 auto demuxer = demuxer_.lock();
98 if (demuxer) {
99 demuxer->OnBufferAvailable(trackId_);
100 }
101 });
102 }
103 private:
104 uint32_t trackId_{0};
105 std::weak_ptr<MediaDemuxer> demuxer_;
106 std::unique_ptr<Task> notifyTask_;
107 };
108
109 class MediaDemuxer::TrackWrapper {
110 public:
TrackWrapper(uint32_t trackId,sptr<IProducerListener> listener,std::shared_ptr<MediaDemuxer> demuxer)111 explicit TrackWrapper(uint32_t trackId, sptr<IProducerListener> listener, std::shared_ptr<MediaDemuxer> demuxer)
112 : trackId_(trackId), listener_(listener), demuxer_(demuxer) {}
GetProducerListener()113 sptr<IProducerListener> GetProducerListener()
114 {
115 return listener_;
116 }
SetNotifyFlag(bool isNotifyNeeded)117 void SetNotifyFlag(bool isNotifyNeeded)
118 {
119 isNotifyNeeded_ = isNotifyNeeded;
120 MEDIA_LOG_D("TrackId:" PUBLIC_LOG_U32 ", isNotifyNeeded:" PUBLIC_LOG_D32,
121 trackId_, isNotifyNeeded);
122 }
GetNotifyFlag()123 bool GetNotifyFlag()
124 {
125 return isNotifyNeeded_.load();
126 }
127 private:
128 std::atomic<bool> isNotifyNeeded_{false};
129 uint32_t trackId_{0};
130 sptr<IProducerListener> listener_ = nullptr;
131 std::weak_ptr<MediaDemuxer> demuxer_;
132 };
133
MediaDemuxer()134 MediaDemuxer::MediaDemuxer()
135 : seekable_(Plugins::Seekable::INVALID),
136 subSeekable_(Plugins::Seekable::INVALID),
137 uri_(),
138 mediaDataSize_(0),
139 subMediaDataSize_(0),
140 source_(std::make_shared<Source>()),
141 subtitleSource_(std::make_shared<Source>()),
142 mediaMetaData_(),
143 bufferQueueMap_(),
144 bufferMap_(),
145 eventReceiver_(),
146 streamDemuxer_(),
147 demuxerPluginManager_(std::make_shared<DemuxerPluginManager>())
148 {
149 MEDIA_LOG_D("In");
150 }
151
~MediaDemuxer()152 MediaDemuxer::~MediaDemuxer()
153 {
154 MEDIA_LOG_D("In");
155 ResetInner();
156 demuxerPluginManager_ = nullptr;
157 mediaSource_ = nullptr;
158 source_ = nullptr;
159 eventReceiver_ = nullptr;
160 eosMap_.clear();
161 requestBufferErrorCountMap_.clear();
162 streamDemuxer_ = nullptr;
163 localDrmInfos_.clear();
164
165 if (parserRefInfoTask_ != nullptr) {
166 parserRefInfoTask_->Stop();
167 parserRefInfoTask_ = nullptr;
168 }
169 }
170
GetCurFFmpegPlugin()171 std::shared_ptr<Plugins::DemuxerPlugin> MediaDemuxer::GetCurFFmpegPlugin()
172 {
173 int32_t tempTrackId = (videoTrackId_ != TRACK_ID_DUMMY ? static_cast<int32_t>(videoTrackId_) : -1);
174 tempTrackId = (tempTrackId == -1 ? static_cast<int32_t>(audioTrackId_) : tempTrackId);
175 int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(tempTrackId);
176 return demuxerPluginManager_->GetPluginByStreamID(streamID);
177 }
178
ReportSceneCodeForDemuxer(SceneCode scene)179 static void ReportSceneCodeForDemuxer(SceneCode scene)
180 {
181 if (scene != SceneCode::AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY) {
182 return;
183 }
184 MEDIA_LOG_I("Scene %{public}d", scene);
185 auto now =
186 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
187 int32_t ret = HiSysEventWrite(
188 PERFORMANCE_STATS, "CPU_SCENE_ENTRY", OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PACKAGE_NAME",
189 "media_service", "SCENE_ID", std::to_string(scene).c_str(), "HAPPEN_TIME", now.count());
190 if (ret != MSERR_OK) {
191 MEDIA_LOG_W("Report failed");
192 }
193 }
194
IsRefParserSupported()195 bool MediaDemuxer::IsRefParserSupported()
196 {
197 FALSE_RETURN_V_MSG_E(videoTrackId_ != TRACK_ID_DUMMY, false, "Video track is nullptr");
198 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
199 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, false, "Demuxer plugin is nullptr");
200 return videoPlugin->IsRefParserSupported();
201 }
202
StartReferenceParser(int64_t startTimeMs,bool isForward)203 Status MediaDemuxer::StartReferenceParser(int64_t startTimeMs, bool isForward)
204 {
205 FALSE_RETURN_V_MSG_E(startTimeMs >= 0, Status::ERROR_UNKNOWN,
206 "Start failed, startTimeMs: " PUBLIC_LOG_D64, startTimeMs);
207 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
208 FALSE_RETURN_V_MSG_E(videoTrackId_ != TRACK_ID_DUMMY, Status::ERROR_UNKNOWN, "Video track is nullptr");
209 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
210 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
211 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
212 Status ret = videoPlugin->ParserRefUpdatePos(startTimeMs, isForward);
213 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "ParserRefUpdatePos failed");
214 if (isFirstParser_) {
215 isFirstParser_ = false;
216 if (source_->GetSeekable() != Plugins::Seekable::SEEKABLE) {
217 MEDIA_LOG_E("Unsupport online video");
218 return Status::ERROR_INVALID_OPERATION;
219 }
220 parserRefInfoTask_ = std::make_unique<Task>("ParserRefInfo", playerId_);
221 parserRefInfoTask_->RegisterJob([this] { return ParserRefInfo(); });
222 ReportSceneCodeForDemuxer(SceneCode::AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY);
223 parserRefInfoTask_->Start();
224 }
225 TryRecvParserTask();
226 return ret;
227 }
228
TryRecvParserTask()229 void MediaDemuxer::TryRecvParserTask()
230 {
231 if (isParserTaskEnd_ && parserRefInfoTask_ != nullptr) {
232 parserRefInfoTask_->Stop();
233 parserRefInfoTask_ = nullptr;
234 MEDIA_LOG_I("Success to recovery");
235 }
236 }
237
ParserRefInfo()238 int64_t MediaDemuxer::ParserRefInfo()
239 {
240 if (demuxerPluginManager_ == nullptr) {
241 MEDIA_LOG_D("Plugin manager is nullptr");
242 return 0;
243 }
244 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
245 if (videoPlugin == nullptr) {
246 MEDIA_LOG_D("Demuxer plugin is nullptr");
247 return 0;
248 }
249 Status ret = videoPlugin->ParserRefInfo();
250 if ((ret == Status::OK || ret == Status::ERROR_UNKNOWN) && parserRefInfoTask_ != nullptr) {
251 parserRefInfoTask_->Stop();
252 isParserTaskEnd_ = true;
253 MEDIA_LOG_I("Success to stop");
254 } else {
255 MEDIA_LOG_I("ret is " PUBLIC_LOG_D32, ret);
256 }
257 return 0;
258 }
259
GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample,FrameLayerInfo & frameLayerInfo)260 Status MediaDemuxer::GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample, FrameLayerInfo &frameLayerInfo)
261 {
262 FALSE_RETURN_V_MSG_E(videoSample != nullptr, Status::ERROR_NULL_POINTER, "videoSample is nullptr");
263 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
264 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
265 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
266 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
267 TryRecvParserTask();
268 Status ret = videoPlugin->GetFrameLayerInfo(videoSample, frameLayerInfo);
269 if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
270 return Status::ERROR_AGAIN;
271 }
272 return ret;
273 }
274
GetFrameLayerInfo(uint32_t frameId,FrameLayerInfo & frameLayerInfo)275 Status MediaDemuxer::GetFrameLayerInfo(uint32_t frameId, FrameLayerInfo &frameLayerInfo)
276 {
277 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
278 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
279 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
280 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
281 TryRecvParserTask();
282 Status ret = videoPlugin->GetFrameLayerInfo(frameId, frameLayerInfo);
283 if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
284 return Status::ERROR_AGAIN;
285 }
286 return ret;
287 }
288
GetGopLayerInfo(uint32_t gopId,GopLayerInfo & gopLayerInfo)289 Status MediaDemuxer::GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo)
290 {
291 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
292 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
293 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
294 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
295 TryRecvParserTask();
296 Status ret = videoPlugin->GetGopLayerInfo(gopId, gopLayerInfo);
297 if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
298 return Status::ERROR_AGAIN;
299 }
300 return ret;
301 }
302
RegisterVideoStreamReadyCallback(const std::shared_ptr<VideoStreamReadyCallback> & callback)303 void MediaDemuxer::RegisterVideoStreamReadyCallback(const std::shared_ptr<VideoStreamReadyCallback> &callback)
304 {
305 std::unique_lock<std::mutex> draggingLock(draggingMutex_);
306 MEDIA_LOG_I("In");
307 VideoStreamReadyCallback_ = callback;
308 }
309
DeregisterVideoStreamReadyCallback()310 void MediaDemuxer::DeregisterVideoStreamReadyCallback()
311 {
312 std::unique_lock<std::mutex> draggingLock(draggingMutex_);
313 MEDIA_LOG_I("In");
314 VideoStreamReadyCallback_ = nullptr;
315 }
316
GetIFramePos(std::vector<uint32_t> & IFramePos)317 Status MediaDemuxer::GetIFramePos(std::vector<uint32_t> &IFramePos)
318 {
319 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
320 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
321 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
322 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
323 TryRecvParserTask();
324 return videoPlugin->GetIFramePos(IFramePos);
325 }
326
Dts2FrameId(int64_t dts,uint32_t & frameId,bool offset)327 Status MediaDemuxer::Dts2FrameId(int64_t dts, uint32_t &frameId, bool offset)
328 {
329 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
330 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
331 std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
332 FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
333 TryRecvParserTask();
334 return videoPlugin->Dts2FrameId(dts, frameId, offset);
335 }
336
OnBufferAvailable(uint32_t trackId)337 void MediaDemuxer::OnBufferAvailable(uint32_t trackId)
338 {
339 MEDIA_LOG_D("Buffer available track " PUBLIC_LOG_U32, trackId);
340 AccelerateTrackTask(trackId); // buffer is available trigger demuxer track working task to run immediately.
341 }
342
AccelerateTrackTask(uint32_t trackId)343 void MediaDemuxer::AccelerateTrackTask(uint32_t trackId)
344 {
345 AutoLock lock(mapMutex_);
346 if (isStopped_ || isThreadExit_) {
347 return;
348 }
349 auto track = trackMap_.find(trackId);
350 if (track == trackMap_.end() || !track->second->GetNotifyFlag()) {
351 return;
352 }
353 track->second->SetNotifyFlag(false);
354
355 auto task = taskMap_.find(trackId);
356 if (task == taskMap_.end()) {
357 return;
358 }
359 MEDIA_LOG_D("Accelerate track " PUBLIC_LOG_U32, trackId);
360 task->second->UpdateDelayTime();
361 }
362
SetTrackNotifyFlag(uint32_t trackId,bool isNotifyNeeded)363 void MediaDemuxer::SetTrackNotifyFlag(uint32_t trackId, bool isNotifyNeeded)
364 {
365 // This function is called in demuxer track working thread, and if track info exists it is valid.
366 auto track = trackMap_.find(trackId);
367 if (track != trackMap_.end()) {
368 track->second->SetNotifyFlag(isNotifyNeeded);
369 }
370 }
371
GetBitRates(std::vector<uint32_t> & bitRates)372 Status MediaDemuxer::GetBitRates(std::vector<uint32_t> &bitRates)
373 {
374 if (source_ == nullptr) {
375 MEDIA_LOG_E("Source is nullptr");
376 return Status::ERROR_INVALID_OPERATION;
377 }
378 return source_->GetBitRates(bitRates);
379 }
380
GetMediaKeySystemInfo(std::multimap<std::string,std::vector<uint8_t>> & infos)381 Status MediaDemuxer::GetMediaKeySystemInfo(std::multimap<std::string, std::vector<uint8_t>> &infos)
382 {
383 MEDIA_LOG_I("In");
384 std::shared_lock<std::shared_mutex> lock(drmMutex);
385 infos = localDrmInfos_;
386 return Status::OK;
387 }
388
GetDownloadInfo(DownloadInfo & downloadInfo)389 Status MediaDemuxer::GetDownloadInfo(DownloadInfo& downloadInfo)
390 {
391 if (source_ == nullptr) {
392 MEDIA_LOG_E("Source is nullptr");
393 return Status::ERROR_INVALID_OPERATION;
394 }
395 return source_->GetDownloadInfo(downloadInfo);
396 }
397
GetPlaybackInfo(PlaybackInfo & playbackInfo)398 Status MediaDemuxer::GetPlaybackInfo(PlaybackInfo& playbackInfo)
399 {
400 FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
401 return source_->GetPlaybackInfo(playbackInfo);
402 }
403
SetDrmCallback(const std::shared_ptr<OHOS::MediaAVCodec::AVDemuxerCallback> & callback)404 void MediaDemuxer::SetDrmCallback(const std::shared_ptr<OHOS::MediaAVCodec::AVDemuxerCallback> &callback)
405 {
406 MEDIA_LOG_I("In");
407 drmCallback_ = callback;
408 bool isExisted = IsLocalDrmInfosExisted();
409 if (isExisted) {
410 MEDIA_LOG_D("Already received drminfo and report");
411 ReportDrmInfos(localDrmInfos_);
412 }
413 }
414
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)415 void MediaDemuxer::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> &receiver)
416 {
417 eventReceiver_ = receiver;
418 }
419
SetPlayerId(const std::string & playerId)420 void MediaDemuxer::SetPlayerId(const std::string &playerId)
421 {
422 playerId_ = playerId;
423 }
424
SetDumpInfo(bool isDump,uint64_t instanceId)425 void MediaDemuxer::SetDumpInfo(bool isDump, uint64_t instanceId)
426 {
427 if (isDump && instanceId == 0) {
428 MEDIA_LOG_W("Can not dump with instanceId 0");
429 return;
430 }
431 dumpPrefix_ = std::to_string(instanceId);
432 isDump_ = isDump;
433 }
434
GetDuration(int64_t & durationMs)435 bool MediaDemuxer::GetDuration(int64_t& durationMs)
436 {
437 AutoLock lock(mapMutex_);
438 if (source_ == nullptr) {
439 durationMs = -1;
440 return false;
441 }
442 MediaAVCodec::AVCodecTrace trace("MediaDemuxer::GetDuration");
443 seekable_ = source_->GetSeekable();
444
445 FALSE_LOG(seekable_ != Seekable::INVALID);
446 if (source_->IsSeekToTimeSupported()) {
447 duration_ = source_->GetDuration();
448 if (duration_ != Plugins::HST_TIME_NONE) {
449 MEDIA_LOG_I("Hls: " PUBLIC_LOG_D64, duration_);
450 mediaMetaData_.globalMeta->Set<Tag::MEDIA_DURATION>(Plugins::HstTime2Us(duration_));
451 }
452 MEDIA_LOG_I("SeekToTime");
453 return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
454 }
455
456 // not hls and seekable
457 if (seekable_ == Plugins::Seekable::SEEKABLE) {
458 duration_ = source_->GetDuration();
459 if (duration_ != Plugins::HST_TIME_NONE) {
460 MEDIA_LOG_I("Not hls: " PUBLIC_LOG_D64, duration_);
461 mediaMetaData_.globalMeta->Set<Tag::MEDIA_DURATION>(Plugins::HstTime2Us(duration_));
462 }
463 MEDIA_LOG_I("Seekble");
464 return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
465 }
466 MEDIA_LOG_I("Other");
467 return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
468 }
469
GetDrmInfosUpdated(const std::multimap<std::string,std::vector<uint8_t>> & newInfos,std::multimap<std::string,std::vector<uint8_t>> & result)470 bool MediaDemuxer::GetDrmInfosUpdated(const std::multimap<std::string, std::vector<uint8_t>> &newInfos,
471 std::multimap<std::string, std::vector<uint8_t>> &result)
472 {
473 MEDIA_LOG_D("In");
474 std::unique_lock<std::shared_mutex> lock(drmMutex);
475 for (auto &newItem : newInfos) {
476 if (localDrmInfos_.find(newItem.first) == localDrmInfos_.end()) {
477 MEDIA_LOG_D("Uuid doesn't exist, update");
478 result.insert(newItem);
479 localDrmInfos_.insert(newItem);
480 continue;
481 }
482 auto pos = localDrmInfos_.equal_range(newItem.first);
483 bool isSame = false;
484 for (; pos.first != pos.second; ++pos.first) {
485 if (newItem.second == pos.first->second) {
486 MEDIA_LOG_D("Uuid exists and the pssh is same, not update");
487 isSame = true;
488 break;
489 }
490 }
491 if (!isSame) {
492 MEDIA_LOG_D("Uuid exists but pssh not same, update");
493 result.insert(newItem);
494 localDrmInfos_.insert(newItem);
495 }
496 }
497 return !result.empty();
498 }
499
IsLocalDrmInfosExisted()500 bool MediaDemuxer::IsLocalDrmInfosExisted()
501 {
502 std::shared_lock<std::shared_mutex> lock(drmMutex);
503 return !localDrmInfos_.empty();
504 }
505
ReportDrmInfos(const std::multimap<std::string,std::vector<uint8_t>> & info)506 Status MediaDemuxer::ReportDrmInfos(const std::multimap<std::string, std::vector<uint8_t>> &info)
507 {
508 MEDIA_LOG_I("In");
509 FALSE_RETURN_V_MSG_E(drmCallback_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Drm callback is nullptr");
510 MEDIA_LOG_D("Filter will update drminfo");
511 drmCallback_->OnDrmInfoChanged(info);
512 return Status::OK;
513 }
514
ProcessDrmInfos()515 Status MediaDemuxer::ProcessDrmInfos()
516 {
517 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
518 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
519 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
520 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
521
522 std::multimap<std::string, std::vector<uint8_t>> drmInfo;
523 Status ret = pluginTemp->GetDrmInfo(drmInfo);
524 if (ret == Status::OK && !drmInfo.empty()) {
525 MEDIA_LOG_D("Get drminfo success");
526 std::multimap<std::string, std::vector<uint8_t>> infosUpdated;
527 bool isUpdated = GetDrmInfosUpdated(drmInfo, infosUpdated);
528 if (isUpdated) {
529 return ReportDrmInfos(infosUpdated);
530 } else {
531 MEDIA_LOG_D("Received drminfo but not update");
532 }
533 } else {
534 if (ret != Status::OK) {
535 MEDIA_LOG_D("Get drminfo failed, ret:" PUBLIC_LOG_D32, (int32_t)(ret));
536 }
537 }
538 return Status::OK;
539 }
540
AddDemuxerCopyTask(uint32_t trackId,TaskType type)541 Status MediaDemuxer::AddDemuxerCopyTask(uint32_t trackId, TaskType type)
542 {
543 std::string taskName = "Demux";
544 switch (type) {
545 case TaskType::VIDEO: {
546 taskName += "V";
547 break;
548 }
549 case TaskType::AUDIO: {
550 taskName += "A";
551 break;
552 }
553 case TaskType::SUBTITLE: {
554 taskName += "S";
555 break;
556 }
557 default: {
558 MEDIA_LOG_E("Add demuxer task failed, unknow task type:" PUBLIC_LOG_D32, type);
559 return Status::ERROR_UNKNOWN;
560 }
561 }
562
563 std::unique_ptr<Task> task = std::make_unique<Task>(taskName, playerId_, type);
564 if (task == nullptr) {
565 MEDIA_LOG_W("Create task failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
566 trackId, type);
567 return Status::OK;
568 }
569 taskMap_[trackId] = std::move(task);
570 taskMap_[trackId]->RegisterJob([this, trackId] { return ReadLoop(trackId); });
571
572 // To wake up DEMUXER TRACK WORKING TASK immediately on input buffer available.
573 std::unique_ptr<Task> notifyTask =
574 std::make_unique<Task>(taskName + "N", playerId_, type, TaskPriority::NORMAL, false);
575 if (!notifyTask) {
576 MEDIA_LOG_W("Create notify task failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
577 trackId, static_cast<uint32_t>(type));
578 return Status::OK;
579 }
580
581 sptr<IProducerListener> listener =
582 OHOS::sptr<AVBufferQueueProducerListener>::MakeSptr(trackId, shared_from_this(), notifyTask);
583 if (listener == nullptr) {
584 MEDIA_LOG_W("Create listener failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
585 trackId, static_cast<uint32_t>(type));
586 return Status::OK;
587 }
588
589 trackMap_.emplace(trackId, std::make_shared<TrackWrapper>(trackId, listener, shared_from_this()));
590 return Status::OK;
591 }
592
InnerPrepare()593 Status MediaDemuxer::InnerPrepare()
594 {
595 Plugins::MediaInfo mediaInfo;
596 Status ret = demuxerPluginManager_->LoadCurrentAllPlugin(streamDemuxer_, mediaInfo);
597 if (ret == Status::OK) {
598 InitMediaMetaData(mediaInfo);
599 InitDefaultTrack(mediaInfo, videoTrackId_, audioTrackId_, subtitleTrackId_, videoMime_);
600 if (videoTrackId_ != TRACK_ID_DUMMY) {
601 if (isEnableReselectVideoTrack_ && IsHasMultiVideoTrack()) {
602 videoTrackId_ = GetTargetVideoTrackId(mediaMetaData_.trackMetas);
603 }
604 AddDemuxerCopyTask(videoTrackId_, TaskType::VIDEO);
605 demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, videoTrackId_, -1);
606 int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(videoTrackId_);
607 streamDemuxer_->SetNewVideoStreamID(streamId);
608 streamDemuxer_->SetChangeFlag(true);
609 streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
610 int64_t bitRate = 0;
611 mediaMetaData_.trackMetas[videoTrackId_]->GetData(Tag::MEDIA_BITRATE, bitRate);
612 source_->SetCurrentBitRate(bitRate, streamId);
613 targetBitRate_ = demuxerPluginManager_->GetCurrentBitRate();
614 }
615 if (audioTrackId_ != TRACK_ID_DUMMY) {
616 AddDemuxerCopyTask(audioTrackId_, TaskType::AUDIO);
617 demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, audioTrackId_, -1);
618 int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(audioTrackId_);
619 streamDemuxer_->SetNewAudioStreamID(streamId);
620 streamDemuxer_->SetChangeFlag(true);
621 streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
622 int64_t bitRate = 0;
623 mediaMetaData_.trackMetas[audioTrackId_]->GetData(Tag::MEDIA_BITRATE, bitRate);
624 source_->SetCurrentBitRate(bitRate, streamId);
625 }
626 if (subtitleTrackId_ != TRACK_ID_DUMMY) {
627 AddDemuxerCopyTask(subtitleTrackId_, TaskType::SUBTITLE);
628 demuxerPluginManager_->UpdateTempTrackMapInfo(subtitleTrackId_, subtitleTrackId_, -1);
629 int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_);
630 streamDemuxer_->SetNewSubtitleStreamID(streamId);
631 streamDemuxer_->SetChangeFlag(true);
632 streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
633 }
634 } else {
635 MEDIA_LOG_E("Parse meta failed, ret: " PUBLIC_LOG_D32, (int32_t)(ret));
636 }
637 return ret;
638 }
639
GetTargetVideoTrackId(std::vector<std::shared_ptr<Meta>> trackInfos)640 uint32_t MediaDemuxer::GetTargetVideoTrackId(std::vector<std::shared_ptr<Meta>> trackInfos)
641 {
642 FALSE_RETURN_V(targetVideoTrackId_ == TRACK_ID_DUMMY, targetVideoTrackId_);
643 MEDIA_LOG_I_SHORT("GetTargetVideoTrackId enter");
644 int64_t videoRes = 0;
645 int32_t videoWidth = 0;
646 int32_t videoHeight = 0;
647 for (size_t index = 0; index < trackInfos.size(); index++) {
648 std::shared_ptr<Meta> meta = trackInfos[index];
649 if (meta == nullptr) {
650 MEDIA_LOG_E_SHORT("meta is invalid, index: %zu", index);
651 continue;
652 }
653 Plugins::MediaType mediaType = Plugins::MediaType::AUDIO;
654 if (!meta->GetData(Tag::MEDIA_TYPE, mediaType)) {
655 continue;
656 }
657 if (mediaType != Plugins::MediaType::VIDEO) {
658 continue;
659 }
660 if (!meta->GetData(Tag::VIDEO_WIDTH, videoWidth)) {
661 continue;
662 }
663 if (!meta->GetData(Tag::VIDEO_HEIGHT, videoHeight)) {
664 continue;
665 }
666 MEDIA_LOG_I_SHORT("SelectVideoTrack trackId: %{public}d width: %{public}d height: %{public}d",
667 static_cast<int32_t>(index), videoWidth, videoHeight);
668 int64_t resolution = static_cast<int64_t>(videoWidth) * static_cast<int64_t>(videoHeight);
669 if (resolution > videoRes) {
670 videoRes = resolution;
671 targetVideoTrackId_ = static_cast<uint32_t>(index);
672 }
673 }
674 return targetVideoTrackId_;
675 }
676
SetDataSource(const std::shared_ptr<MediaSource> & source)677 Status MediaDemuxer::SetDataSource(const std::shared_ptr<MediaSource> &source)
678 {
679 MediaAVCodec::AVCODEC_SYNC_TRACE;
680 MEDIA_LOG_I("In");
681 FALSE_RETURN_V_MSG_E(isThreadExit_, Status::ERROR_WRONG_STATE, "Process is running");
682 source_->SetCallback(this);
683 auto res = source_->SetSource(source);
684 FALSE_RETURN_V_MSG_E(res == Status::OK, res, "Plugin set source failed");
685
686 std::vector<StreamInfo> streams;
687 source_->GetStreamInfo(streams);
688 demuxerPluginManager_->InitDefaultPlay(streams);
689
690 streamDemuxer_ = std::make_shared<StreamDemuxer>();
691 streamDemuxer_->SetSourceType(source->GetSourceType());
692 streamDemuxer_->SetInterruptState(isInterruptNeeded_);
693 streamDemuxer_->SetSource(source_);
694 streamDemuxer_->Init(uri_);
695 streamDemuxer_->SetIsExtSubtitle(false);
696
697 res = InnerPrepare();
698
699 ProcessDrmInfos();
700 MEDIA_LOG_I("Out");
701 return res;
702 }
703
IsSubtitleMime(const std::string & mime)704 bool MediaDemuxer::IsSubtitleMime(const std::string& mime)
705 {
706 if (mime == "application/x-subrip" || mime == "text/vtt") {
707 return true;
708 }
709 return false;
710 }
711
SetSubtitleSource(const std::shared_ptr<MediaSource> & subSource)712 Status MediaDemuxer::SetSubtitleSource(const std::shared_ptr<MediaSource> &subSource)
713 {
714 MEDIA_LOG_I("In");
715 if (subtitleTrackId_ != TRACK_ID_DUMMY) {
716 MEDIA_LOG_W("Found subtitle track, not support ext");
717 return Status::OK;
718 }
719 subtitleSource_->SetCallback(this);
720 subtitleSource_->SetSource(subSource);
721 Status ret = subtitleSource_->GetSize(subMediaDataSize_);
722 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Get file size failed");
723 subSeekable_ = subtitleSource_->GetSeekable();
724
725 int32_t subtitleStreamID = demuxerPluginManager_->AddExternalSubtitle();
726 subStreamDemuxer_ = std::make_shared<StreamDemuxer>();
727 subStreamDemuxer_->SetSourceType(subSource->GetSourceType());
728 subStreamDemuxer_->SetInterruptState(isInterruptNeeded_);
729 subStreamDemuxer_->SetSource(subtitleSource_);
730 subStreamDemuxer_->Init(subSource->GetSourceUri());
731 subStreamDemuxer_->SetIsExtSubtitle(true);
732
733 MediaInfo mediaInfo;
734 ret = demuxerPluginManager_->LoadCurrentSubtitlePlugin(subStreamDemuxer_, mediaInfo);
735 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Parse meta failed, ret:" PUBLIC_LOG_D32, (int32_t)(ret));
736 InitMediaMetaData(mediaInfo); // update mediaMetaData_
737 for (uint32_t index = 0; index < mediaInfo.tracks.size(); index++) {
738 auto trackMeta = mediaInfo.tracks[index];
739 std::string mimeType;
740 std::string trackType;
741 trackMeta.Get<Tag::MIME_TYPE>(mimeType);
742 int32_t curStreamID = demuxerPluginManager_->GetStreamIDByTrackID(index);
743 if (trackMeta.Get<Tag::MIME_TYPE>(mimeType) && IsSubtitleMime(mimeType) && curStreamID == subtitleStreamID) {
744 MEDIA_LOG_I("STrack " PUBLIC_LOG_U32, index);
745 subtitleTrackId_ = index; // dash inner subtitle can be replace by out subtitle
746 break;
747 }
748 }
749
750 if (subtitleTrackId_ != TRACK_ID_DUMMY) {
751 AddDemuxerCopyTask(subtitleTrackId_, TaskType::SUBTITLE);
752 demuxerPluginManager_->UpdateTempTrackMapInfo(subtitleTrackId_, subtitleTrackId_, -1);
753 subStreamDemuxer_->SetNewSubtitleStreamID(subtitleStreamID);
754 subStreamDemuxer_->SetDemuxerState(subtitleStreamID, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
755 }
756
757 MEDIA_LOG_I("Out, ext sub %{public}d", subtitleTrackId_);
758 return ret;
759 }
760
SetInterruptState(bool isInterruptNeeded)761 void MediaDemuxer::SetInterruptState(bool isInterruptNeeded)
762 {
763 isInterruptNeeded_ = isInterruptNeeded;
764 if (demuxerPluginManager_ != nullptr && demuxerPluginManager_->IsDash()) {
765 std::unique_lock<std::mutex> lock(rebootPluginMutex_);
766 rebootPluginCondition_.notify_all();
767 }
768 if (source_ != nullptr) {
769 source_->SetInterruptState(isInterruptNeeded);
770 }
771 if (streamDemuxer_ != nullptr) {
772 streamDemuxer_->SetInterruptState(isInterruptNeeded);
773 }
774 }
775
SetBundleName(const std::string & bundleName)776 void MediaDemuxer::SetBundleName(const std::string& bundleName)
777 {
778 if (source_ != nullptr) {
779 MEDIA_LOG_I("BundleName: " PUBLIC_LOG_S, bundleName.c_str());
780 bundleName_ = bundleName;
781 streamDemuxer_->SetBundleName(bundleName);
782 source_->SetBundleName(bundleName);
783 }
784 }
785
SetOutputBufferQueue(int32_t trackId,const sptr<AVBufferQueueProducer> & producer)786 Status MediaDemuxer::SetOutputBufferQueue(int32_t trackId, const sptr<AVBufferQueueProducer>& producer)
787 {
788 AutoLock lock(mapMutex_);
789 FALSE_RETURN_V_MSG_E(trackId >= 0 && (uint32_t)trackId < mediaMetaData_.trackMetas.size(),
790 Status::ERROR_INVALID_PARAMETER, "Invalid track");
791 useBufferQueue_ = true;
792 MEDIA_LOG_I("Set bufferQueue for track " PUBLIC_LOG_D32, trackId);
793 FALSE_RETURN_V_MSG_E(isThreadExit_, Status::ERROR_WRONG_STATE, "Process is running");
794 FALSE_RETURN_V_MSG_E(producer != nullptr, Status::ERROR_INVALID_PARAMETER, "BufferQueue is nullptr");
795 if (bufferQueueMap_.find(trackId) != bufferQueueMap_.end()) {
796 MEDIA_LOG_W("Has been set already");
797 }
798 Status ret = InnerSelectTrack(trackId);
799 if (ret == Status::OK) {
800 auto track = trackMap_.find(trackId);
801 if (track != trackMap_.end()) {
802 auto listener = track->second->GetProducerListener();
803 if (listener) {
804 MEDIA_LOG_W("Set listener");
805 producer->SetBufferAvailableListener(listener);
806 }
807 }
808 bufferQueueMap_.insert(std::pair<uint32_t, sptr<AVBufferQueueProducer>>(trackId, producer));
809 bufferMap_.insert(std::pair<uint32_t, std::shared_ptr<AVBuffer>>(trackId, nullptr));
810 MEDIA_LOG_I("Set bufferQueue successfully");
811 }
812 return ret;
813 }
814
OnDumpInfo(int32_t fd)815 void MediaDemuxer::OnDumpInfo(int32_t fd)
816 {
817 MEDIA_LOG_D("In");
818 if (fd < 0) {
819 MEDIA_LOG_E("Invalid fd");
820 return;
821 }
822 std::string dumpString;
823 dumpString += "MediaDemuxer buffer queue map size: " + std::to_string(bufferQueueMap_.size()) + "\n";
824 dumpString += "MediaDemuxer buffer map size: " + std::to_string(bufferMap_.size()) + "\n";
825 int ret = write(fd, dumpString.c_str(), dumpString.size());
826 if (ret < 0) {
827 MEDIA_LOG_E("MediaDemuxer::OnDumpInfo write failed");
828 return;
829 }
830 }
831
GetBufferQueueProducerMap()832 std::map<uint32_t, sptr<AVBufferQueueProducer>> MediaDemuxer::GetBufferQueueProducerMap()
833 {
834 return bufferQueueMap_;
835 }
836
InnerSelectTrack(int32_t trackId)837 Status MediaDemuxer::InnerSelectTrack(int32_t trackId)
838 {
839 eosMap_[trackId] = false;
840 requestBufferErrorCountMap_[trackId] = 0;
841 int32_t innerTrackID = trackId;
842 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
843 if (demuxerPluginManager_->IsDash() || demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_) != -1) {
844 int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
845 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
846 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
847 innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
848 } else {
849 int32_t streamId = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
850 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
851 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
852 }
853 return pluginTemp->SelectTrack(innerTrackID);
854 }
855
StartTask(int32_t trackId)856 Status MediaDemuxer::StartTask(int32_t trackId)
857 {
858 MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
859 std::string mimeType;
860 auto iter = taskMap_.find(trackId);
861 if (iter == taskMap_.end()) {
862 TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
863 if (trackType == TrackType::TRACK_AUDIO) {
864 AddDemuxerCopyTask(trackId, TaskType::AUDIO);
865 } else if (trackType == TrackType::TRACK_VIDEO) {
866 AddDemuxerCopyTask(trackId, TaskType::VIDEO);
867 } else if (trackType == TrackType::TRACK_SUBTITLE) {
868 AddDemuxerCopyTask(trackId, TaskType::SUBTITLE);
869 }
870 if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
871 taskMap_[trackId]->Start();
872 }
873 } else {
874 if (taskMap_[trackId] != nullptr && !taskMap_[trackId]->IsTaskRunning()) {
875 taskMap_[trackId]->Start();
876 }
877 }
878 return Status::OK;
879 }
880
HandleDashSelectTrack(int32_t trackId)881 Status MediaDemuxer::HandleDashSelectTrack(int32_t trackId)
882 {
883 MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
884 eosMap_[trackId] = false;
885 requestBufferErrorCountMap_[trackId] = 0;
886
887 int32_t targetStreamID = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
888 if (targetStreamID == -1) {
889 MEDIA_LOG_E("Get stream failed");
890 return Status::ERROR_UNKNOWN;
891 }
892
893 int32_t curTrackId = -1;
894 TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
895 if (trackType == TrackType::TRACK_AUDIO) {
896 curTrackId = static_cast<int32_t>(audioTrackId_);
897 } else if (trackType == TrackType::TRACK_VIDEO) {
898 curTrackId = static_cast<int32_t>(videoTrackId_);
899 } else if (trackType == TrackType::TRACK_SUBTITLE) {
900 curTrackId = static_cast<int32_t>(subtitleTrackId_);
901 } else { // invalid
902 MEDIA_LOG_E("Track type invalid");
903 return Status::ERROR_UNKNOWN;
904 }
905
906 if (curTrackId == trackId || targetStreamID != demuxerPluginManager_->GetTmpStreamIDByTrackID(curTrackId)) {
907 MEDIA_LOG_I("Select stream");
908 {
909 std::lock_guard<std::mutex> lock(isSelectTrackMutex_);
910 inSelectTrackType_[static_cast<int32_t>(trackType)] = trackId;
911 }
912 return source_->SelectStream(targetStreamID);
913 }
914
915 // same streamID
916 Status ret = DoSelectTrack(trackId, curTrackId);
917 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "DoSelectTrack track failed");
918 if (eventReceiver_ != nullptr) {
919 MEDIA_LOG_I("HandleDashSelectTrack report track change event");
920 if (trackType == TrackType::TRACK_AUDIO) {
921 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, trackId});
922 audioTrackId_ = static_cast<uint32_t>(trackId);
923 } else if (trackType == TrackType::TRACK_VIDEO) {
924 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, trackId});
925 videoTrackId_ = static_cast<uint32_t>(trackId);
926 } else if (trackType == TrackType::TRACK_SUBTITLE) {
927 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_SUBTITLE_TRACK_CHANGE, trackId});
928 subtitleTrackId_ = static_cast<uint32_t>(trackId);
929 } else {}
930 }
931
932 return Status::OK;
933 }
934
DoSelectTrack(int32_t trackId,int32_t curTrackId)935 Status MediaDemuxer::DoSelectTrack(int32_t trackId, int32_t curTrackId)
936 {
937 if (static_cast<uint32_t>(curTrackId) != TRACK_ID_DUMMY) {
938 if (taskMap_.find(curTrackId) != taskMap_.end() && taskMap_[curTrackId] != nullptr) {
939 taskMap_[curTrackId]->Stop();
940 }
941 Status ret = UnselectTrack(curTrackId);
942 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Unselect track failed");
943 bufferQueueMap_.insert(
944 std::pair<uint32_t, sptr<AVBufferQueueProducer>>(trackId, bufferQueueMap_[curTrackId]));
945 bufferMap_.insert(std::pair<uint32_t, std::shared_ptr<AVBuffer>>(trackId, bufferMap_[curTrackId]));
946 bufferQueueMap_.erase(curTrackId);
947 bufferMap_.erase(curTrackId);
948 demuxerPluginManager_->UpdateTempTrackMapInfo(trackId, trackId, -1);
949 return InnerSelectTrack(trackId);
950 }
951 return Status::ERROR_UNKNOWN;
952 }
953
HandleSelectTrack(int32_t trackId)954 Status MediaDemuxer::HandleSelectTrack(int32_t trackId)
955 {
956 int32_t curTrackId = -1;
957 TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
958 if (trackType == TrackType::TRACK_AUDIO) {
959 MEDIA_LOG_I("Select audio [" PUBLIC_LOG_D32 "->" PUBLIC_LOG_D32 "]", audioTrackId_, trackId);
960 curTrackId = static_cast<int32_t>(audioTrackId_);
961 } else { // inner subtitle and video not support
962 MEDIA_LOG_W("Unsupport track " PUBLIC_LOG_D32, trackId);
963 return Status::ERROR_INVALID_PARAMETER;
964 }
965
966 if (curTrackId == trackId) {
967 return Status::OK;
968 }
969
970 Status ret = DoSelectTrack(trackId, curTrackId);
971 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "DoSelectTrack track failed");
972 if (eventReceiver_ != nullptr) {
973 MEDIA_LOG_I("HandleSelectTrack report track change event");
974 if (trackType == TrackType::TRACK_AUDIO) {
975 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, trackId});
976 audioTrackId_ = static_cast<uint32_t>(trackId);
977 } else if (trackType == TrackType::TRACK_VIDEO) {
978 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, trackId});
979 videoTrackId_ = static_cast<uint32_t>(trackId);
980 } else {}
981 }
982
983 return ret;
984 }
985
SelectTrack(int32_t trackId)986 Status MediaDemuxer::SelectTrack(int32_t trackId)
987 {
988 MediaAVCodec::AVCODEC_SYNC_TRACE;
989 MEDIA_LOG_D("Select " PUBLIC_LOG_D32, trackId);
990 FALSE_RETURN_V_MSG_E(trackId >= 0 && (uint32_t)trackId < mediaMetaData_.trackMetas.size(),
991 Status::ERROR_INVALID_PARAMETER, "Select track failed");
992 if (!useBufferQueue_) {
993 return InnerSelectTrack(trackId);
994 }
995 if (demuxerPluginManager_->IsDash()) {
996 if (streamDemuxer_->CanDoChangeStream() == false) {
997 MEDIA_LOG_W("Wrong state: selecting");
998 return Status::ERROR_WRONG_STATE;
999 }
1000 return HandleDashSelectTrack(trackId);
1001 }
1002 return HandleSelectTrack(trackId);
1003 }
1004
UnselectTrack(int32_t trackId)1005 Status MediaDemuxer::UnselectTrack(int32_t trackId)
1006 {
1007 MediaAVCodec::AVCODEC_SYNC_TRACE;
1008 MEDIA_LOG_D("Unselect " PUBLIC_LOG_D32, trackId);
1009
1010 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
1011 int32_t innerTrackID = trackId;
1012 if (demuxerPluginManager_->IsDash() || demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_) != -1) {
1013 int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1014 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
1015 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1016 innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
1017 } else {
1018 int32_t streamID = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
1019 if (streamID == -1) {
1020 MEDIA_LOG_W("Invalid track " PUBLIC_LOG_D32, trackId);
1021 return Status::OK;
1022 }
1023 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
1024 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1025 }
1026 demuxerPluginManager_->DeleteTempTrackMapInfo(trackId);
1027
1028 return pluginTemp->UnselectTrack(innerTrackID);
1029 }
1030
HandleRebootPlugin(int32_t trackId,bool & isRebooted)1031 Status MediaDemuxer::HandleRebootPlugin(int32_t trackId, bool& isRebooted)
1032 {
1033 FALSE_RETURN_V(!subStreamDemuxer_ || trackId != static_cast<int32_t>(subtitleTrackId_), Status::OK);
1034 Status ret = Status::OK;
1035 if (static_cast<uint32_t>(trackId) != TRACK_ID_DUMMY) {
1036 int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1037 TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1038 MEDIA_LOG_D("TrackType " PUBLIC_LOG_D32, static_cast<int32_t>(trackType));
1039 FALSE_RETURN_V_MSG_E(trackType != TRACK_INVALID, Status::ERROR_INVALID_PARAMETER, "TrackType is invalid");
1040 StreamType streamType = TRACK_TO_STREAM_MAP[trackType];
1041 std::pair<int32_t, bool> seekReadyInfo;
1042 {
1043 std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1044 if (!isInterruptNeeded_.load() &&
1045 seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) == seekReadyStreamInfo_.end()) {
1046 rebootPluginCondition_.wait(lock, [this, streamType] {
1047 return isInterruptNeeded_.load() ||
1048 seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) != seekReadyStreamInfo_.end();
1049 });
1050 }
1051 FALSE_RETURN_V(!isInterruptNeeded_.load(), Status::OK);
1052 seekReadyInfo = seekReadyStreamInfo_[static_cast<int32_t>(streamType)];
1053 seekReadyStreamInfo_.erase(static_cast<int32_t>(streamType));
1054 }
1055 if (seekReadyInfo.second == SEEK_TO_EOS || (seekReadyInfo.first >= 0 && seekReadyInfo.first != streamID)) {
1056 MEDIA_LOG_I("End of stream or streamID changed, isEOS: " PUBLIC_LOG_D32 ", streamId: " PUBLIC_LOG_D32,
1057 seekReadyInfo.second, seekReadyInfo.first);
1058 return Status::OK;
1059 }
1060 ret = demuxerPluginManager_->RebootPlugin(streamID, trackType, streamDemuxer_, isRebooted);
1061 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot demuxer plugin failed");
1062 ret = InnerSelectTrack(trackId);
1063 }
1064 return ret;
1065 }
1066
SeekToTimeAfter()1067 Status MediaDemuxer::SeekToTimeAfter()
1068 {
1069 FALSE_RETURN_V_NOLOG(demuxerPluginManager_ != nullptr && demuxerPluginManager_->IsDash(), Status::OK);
1070 MEDIA_LOG_D("Reboot plugin begin");
1071 Status ret = Status::OK;
1072 bool isDemuxerPluginRebooted = true;
1073 ret = HandleRebootPlugin(subtitleTrackId_, isDemuxerPluginRebooted);
1074 if (shouldCheckSubtitleFramePts_) {
1075 shouldCheckSubtitleFramePts_ = false;
1076 }
1077 FALSE_LOG_MSG_W(ret == Status::OK, "Reboot subtitle demuxer plugin failed");
1078
1079 isDemuxerPluginRebooted = true;
1080 ret = HandleRebootPlugin(audioTrackId_, isDemuxerPluginRebooted);
1081 if (shouldCheckAudioFramePts_) {
1082 shouldCheckAudioFramePts_ = false;
1083 }
1084 FALSE_LOG_MSG_W(ret == Status::OK, "Reboot audio demuxer plugin failed");
1085
1086 isDemuxerPluginRebooted = true;
1087 ret = HandleRebootPlugin(videoTrackId_, isDemuxerPluginRebooted);
1088 {
1089 std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1090 seekReadyStreamInfo_.clear();
1091 }
1092 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot video demuxer plugin failed");
1093 MEDIA_LOG_D("Reboot plugin success");
1094 return Status::OK;
1095 }
1096
SeekTo(int64_t seekTime,Plugins::SeekMode mode,int64_t & realSeekTime)1097 Status MediaDemuxer::SeekTo(int64_t seekTime, Plugins::SeekMode mode, int64_t& realSeekTime)
1098 {
1099 MediaAVCodec::AVCODEC_SYNC_TRACE;
1100 Status ret;
1101 isSeekError_.store(false);
1102 if (source_ != nullptr && source_->IsSeekToTimeSupported()) {
1103 MEDIA_LOG_D("Source seek");
1104 if (mode == SeekMode::SEEK_CLOSEST_INNER) {
1105 ret = source_->SeekToTime(seekTime, SeekMode::SEEK_PREVIOUS_SYNC);
1106 } else {
1107 ret = source_->SeekToTime(seekTime, SeekMode::SEEK_CLOSEST_SYNC);
1108 }
1109 if (subStreamDemuxer_) {
1110 demuxerPluginManager_->localSubtitleSeekTo(seekTime);
1111 }
1112 SeekToTimeAfter();
1113 Plugins::Ms2HstTime(seekTime, realSeekTime);
1114 } else {
1115 MEDIA_LOG_D("Demuxer seek");
1116 if (mode == SeekMode::SEEK_CLOSEST_INNER) {
1117 ret = demuxerPluginManager_->SeekTo(seekTime, SeekMode::SEEK_PREVIOUS_SYNC, realSeekTime);
1118 } else {
1119 ret = demuxerPluginManager_->SeekTo(seekTime, mode, realSeekTime);
1120 }
1121 }
1122 isSeeked_ = true;
1123 for (auto item : eosMap_) {
1124 eosMap_[item.first] = false;
1125 }
1126 for (auto item : requestBufferErrorCountMap_) {
1127 requestBufferErrorCountMap_[item.first] = 0;
1128 }
1129 if (ret != Status::OK) {
1130 isSeekError_.store(true);
1131 }
1132 isFirstFrameAfterSeek_.store(true);
1133 MEDIA_LOG_D("Out");
1134 return ret;
1135 }
1136
SelectBitRate(uint32_t bitRate)1137 Status MediaDemuxer::SelectBitRate(uint32_t bitRate)
1138 {
1139 FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Source is nullptr");
1140 MEDIA_LOG_I("In");
1141 if (demuxerPluginManager_->IsDash()) {
1142 if (streamDemuxer_->CanDoChangeStream() == false) {
1143 MEDIA_LOG_W("Wrong state: selecting");
1144 return Status::OK;
1145 }
1146 if (bitRate == demuxerPluginManager_->GetCurrentBitRate()) {
1147 MEDIA_LOG_W("Same bitrate");
1148 return Status::OK;
1149 }
1150 isSelectBitRate_.store(true);
1151 } else {
1152 streamDemuxer_->ResetAllCache();
1153 }
1154
1155 Status ret = source_->SelectBitRate(bitRate);
1156 if (ret != Status::OK) {
1157 MEDIA_LOG_E("Source select bitrate failed");
1158 if (demuxerPluginManager_->IsDash()) {
1159 isSelectBitRate_.store(false);
1160 }
1161 }
1162 targetBitRate_ = bitRate;
1163 MEDIA_LOG_I("Out");
1164 return ret;
1165 }
1166
GetStreamMetaInfo() const1167 std::vector<std::shared_ptr<Meta>> MediaDemuxer::GetStreamMetaInfo() const
1168 {
1169 MediaAVCodec::AVCODEC_SYNC_TRACE;
1170 return mediaMetaData_.trackMetas;
1171 }
1172
GetGlobalMetaInfo() const1173 std::shared_ptr<Meta> MediaDemuxer::GetGlobalMetaInfo() const
1174 {
1175 MediaAVCodec::AVCODEC_SYNC_TRACE;
1176 return mediaMetaData_.globalMeta;
1177 }
1178
GetUserMeta()1179 std::shared_ptr<Meta> MediaDemuxer::GetUserMeta()
1180 {
1181 MediaAVCodec::AVCODEC_SYNC_TRACE;
1182 return demuxerPluginManager_->GetUserMeta();
1183 }
1184
Flush()1185 Status MediaDemuxer::Flush()
1186 {
1187 MEDIA_LOG_I("In");
1188 if (streamDemuxer_) {
1189 streamDemuxer_->Flush();
1190 }
1191
1192 {
1193 AutoLock lock(mapMutex_);
1194 auto it = bufferQueueMap_.begin();
1195 while (it != bufferQueueMap_.end()) {
1196 uint32_t trackId = it->first;
1197 if (trackId != videoTrackId_) {
1198 bufferQueueMap_[trackId]->Clear();
1199 }
1200 it++;
1201 }
1202 }
1203
1204 if (demuxerPluginManager_) {
1205 // hls reset ffmpeg eos status
1206 if (source_ != nullptr && source_->IsSeekToTimeSupported()) {
1207 demuxerPluginManager_->SetResetEosStatus(true);
1208 }
1209 demuxerPluginManager_->Flush();
1210 }
1211
1212 InitPtsInfo();
1213 return Status::OK;
1214 }
1215
StopAllTask()1216 Status MediaDemuxer::StopAllTask()
1217 {
1218 MEDIA_LOG_I("In");
1219 isDemuxerLoopExecuting_ = false;
1220 if (streamDemuxer_ != nullptr) {
1221 streamDemuxer_->SetIsIgnoreParse(true);
1222 }
1223 if (source_ != nullptr) {
1224 source_->Stop();
1225 }
1226
1227 auto it = taskMap_.begin();
1228 while (it != taskMap_.end()) {
1229 if (it->second != nullptr) {
1230 it->second->Stop();
1231 it->second = nullptr;
1232 }
1233 it = taskMap_.erase(it);
1234 }
1235 isThreadExit_ = true;
1236 MEDIA_LOG_I("Out");
1237 return Status::OK;
1238 }
1239
PauseAllTask()1240 Status MediaDemuxer::PauseAllTask()
1241 {
1242 MEDIA_LOG_I("In");
1243 isDemuxerLoopExecuting_ = false;
1244 // To accelerate DemuxerLoop thread to run into PAUSED state
1245 for (auto &iter : taskMap_) {
1246 if (iter.second != nullptr) {
1247 iter.second->PauseAsync();
1248 }
1249 }
1250
1251 for (auto &iter : taskMap_) {
1252 if (iter.second != nullptr) {
1253 iter.second->Pause();
1254 }
1255 }
1256 MEDIA_LOG_I("Out");
1257 return Status::OK;
1258 }
1259
ResumeAllTask()1260 Status MediaDemuxer::ResumeAllTask()
1261 {
1262 MEDIA_LOG_I("In");
1263 isDemuxerLoopExecuting_ = true;
1264 streamDemuxer_->SetIsIgnoreParse(false);
1265
1266 auto it = bufferQueueMap_.begin();
1267 while (it != bufferQueueMap_.end()) {
1268 uint32_t trackId = it->first;
1269 if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
1270 taskMap_[trackId]->Start();
1271 } else {
1272 MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " task is not exist", trackId);
1273 }
1274 it++;
1275 }
1276 MEDIA_LOG_I("Out");
1277 return Status::OK;
1278 }
1279
Pause()1280 Status MediaDemuxer::Pause()
1281 {
1282 MEDIA_LOG_I("In");
1283 isPaused_ = true;
1284 if (streamDemuxer_) {
1285 streamDemuxer_->SetIsIgnoreParse(true);
1286 streamDemuxer_->Pause();
1287 }
1288 if (source_) {
1289 source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1290 source_->Pause();
1291 }
1292 if (inPreroll_.load()) {
1293 if (CheckTrackEnabledById(videoTrackId_)) {
1294 taskMap_[videoTrackId_]->PauseAsync();
1295 taskMap_[videoTrackId_]->Pause();
1296 }
1297 } else {
1298 PauseAllTask();
1299 }
1300 if (source_ != nullptr) {
1301 source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1302 }
1303 return Status::OK;
1304 }
1305
PauseDragging()1306 Status MediaDemuxer::PauseDragging()
1307 {
1308 MEDIA_LOG_I("PauseDragging");
1309 isPaused_ = true;
1310 if (streamDemuxer_) {
1311 streamDemuxer_->SetIsIgnoreParse(true);
1312 streamDemuxer_->Pause();
1313 }
1314 if (source_) {
1315 source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1316 source_->Pause();
1317 }
1318 if (taskMap_.find(videoTrackId_) != taskMap_.end() && taskMap_[videoTrackId_] != nullptr) {
1319 taskMap_[videoTrackId_]->PauseAsync();
1320 taskMap_[videoTrackId_]->Pause();
1321 }
1322
1323 if (source_ != nullptr) {
1324 source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1325 }
1326 return Status::OK;
1327 }
1328
PauseAudioAlign()1329 Status MediaDemuxer::PauseAudioAlign()
1330 {
1331 MEDIA_LOG_I("PauseDragging");
1332 isPaused_ = true;
1333 if (streamDemuxer_) {
1334 streamDemuxer_->SetIsIgnoreParse(true);
1335 streamDemuxer_->Pause();
1336 }
1337 if (source_) {
1338 source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1339 source_->Pause();
1340 }
1341 if (taskMap_.find(audioTrackId_) != taskMap_.end() && taskMap_[audioTrackId_] != nullptr) {
1342 taskMap_[audioTrackId_]->PauseAsync();
1343 taskMap_[audioTrackId_]->Pause();
1344 }
1345
1346 if (source_ != nullptr) {
1347 source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1348 }
1349 return Status::OK;
1350 }
1351
PauseTaskByTrackId(int32_t trackId)1352 Status MediaDemuxer::PauseTaskByTrackId(int32_t trackId)
1353 {
1354 MEDIA_LOG_I("In, track %{public}d", trackId);
1355 FALSE_RETURN_V_MSG_E(trackId >= 0, Status::ERROR_INVALID_PARAMETER, "Invalid track");
1356
1357 // To accelerate DemuxerLoop thread to run into PAUSED state
1358 for (auto &iter : taskMap_) {
1359 if (iter.first == static_cast<uint32_t>(trackId) && iter.second != nullptr) {
1360 iter.second->PauseAsync();
1361 }
1362 }
1363
1364 for (auto &iter : taskMap_) {
1365 if (iter.first == static_cast<uint32_t>(trackId) && iter.second != nullptr) {
1366 iter.second->Pause();
1367 }
1368 }
1369 return Status::OK;
1370 }
1371
Resume()1372 Status MediaDemuxer::Resume()
1373 {
1374 MEDIA_LOG_I("In");
1375 if (streamDemuxer_) {
1376 streamDemuxer_->Resume();
1377 }
1378 if (source_) {
1379 source_->Resume();
1380 }
1381 if (inPreroll_.load()) {
1382 if (CheckTrackEnabledById(videoTrackId_)) {
1383 if (streamDemuxer_) {
1384 streamDemuxer_->SetIsIgnoreParse(false);
1385 }
1386 taskMap_[videoTrackId_]->Start();
1387 }
1388 } else {
1389 ResumeAllTask();
1390 }
1391 isPaused_ = false;
1392 return Status::OK;
1393 }
1394
ResumeDragging()1395 Status MediaDemuxer::ResumeDragging()
1396 {
1397 MEDIA_LOG_I("In");
1398 for (auto item : eosMap_) {
1399 eosMap_[item.first] = false;
1400 }
1401 if (streamDemuxer_) {
1402 streamDemuxer_->Resume();
1403 }
1404 if (source_) {
1405 source_->Resume();
1406 }
1407 if (taskMap_.find(videoTrackId_) != taskMap_.end() && taskMap_[videoTrackId_] != nullptr) {
1408 if (streamDemuxer_) {
1409 streamDemuxer_->SetIsIgnoreParse(false);
1410 }
1411 taskMap_[videoTrackId_]->Start();
1412 }
1413 isPaused_ = false;
1414 return Status::OK;
1415 }
1416
ResumeAudioAlign()1417 Status MediaDemuxer::ResumeAudioAlign()
1418 {
1419 MEDIA_LOG_I("Resume");
1420 if (streamDemuxer_) {
1421 streamDemuxer_->Resume();
1422 }
1423 if (source_) {
1424 source_->Resume();
1425 }
1426 if (taskMap_.find(audioTrackId_) != taskMap_.end() && taskMap_[audioTrackId_] != nullptr) {
1427 streamDemuxer_->SetIsIgnoreParse(false);
1428 taskMap_[audioTrackId_]->Start();
1429 }
1430 isPaused_ = false;
1431 return Status::OK;
1432 }
1433
ResetInner()1434 void MediaDemuxer::ResetInner()
1435 {
1436 std::map<uint32_t, std::shared_ptr<TrackWrapper>> trackMap;
1437 {
1438 AutoLock lock(mapMutex_);
1439 mediaMetaData_.globalMeta.reset();
1440 mediaMetaData_.trackMetas.clear();
1441 }
1442 Stop();
1443 {
1444 AutoLock lock(mapMutex_);
1445 std::swap(trackMap, trackMap_);
1446 bufferQueueMap_.clear();
1447 bufferMap_.clear();
1448 localDrmInfos_.clear();
1449 }
1450 // Should perform trackMap_ clear without holding mapMutex_ to avoid dead lock:
1451 // 1. TrackWrapper indirectly holds notifyTask which holds its jobMutex_ firstly when run, then requires mapMutex_.
1452 // 2. Release notifyTask also needs hold its jobMutex_ firstly.
1453 trackMap.clear();
1454 }
1455
Reset()1456 Status MediaDemuxer::Reset()
1457 {
1458 MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Reset");
1459 FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1460 isDemuxerLoopExecuting_ = false;
1461 ResetInner();
1462 for (auto item : eosMap_) {
1463 eosMap_[item.first] = false;
1464 }
1465 for (auto item : requestBufferErrorCountMap_) {
1466 requestBufferErrorCountMap_[item.first] = 0;
1467 }
1468 videoStartTime_ = 0;
1469 streamDemuxer_->ResetAllCache();
1470 isSeekError_.store(false);
1471 return demuxerPluginManager_->Reset();
1472 }
1473
Start()1474 Status MediaDemuxer::Start()
1475 {
1476 MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Start");
1477 MEDIA_LOG_I("In");
1478 FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1479 FALSE_RETURN_V_MSG_E(isThreadExit_, Status::OK, "Process has been started already");
1480 FALSE_RETURN_V_MSG_E(bufferQueueMap_.size() != 0, Status::OK, "No buffer queue");
1481 for (auto it = eosMap_.begin(); it != eosMap_.end(); it++) {
1482 it->second = false;
1483 }
1484 for (auto it = requestBufferErrorCountMap_.begin(); it != requestBufferErrorCountMap_.end(); it++) {
1485 it->second = 0;
1486 }
1487 InitPtsInfo();
1488 isThreadExit_ = false;
1489 isStopped_ = false;
1490 isDemuxerLoopExecuting_ = true;
1491 if (inPreroll_.load()) {
1492 if (CheckTrackEnabledById(videoTrackId_)) {
1493 taskMap_[videoTrackId_]->Start();
1494 }
1495 } else {
1496 auto it = bufferQueueMap_.begin();
1497 while (it != bufferQueueMap_.end()) {
1498 uint32_t trackId = it->first;
1499 if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
1500 taskMap_[trackId]->Start();
1501 } else {
1502 MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " task is not exist", trackId);
1503 }
1504 it++;
1505 }
1506 }
1507 source_->Start();
1508 return demuxerPluginManager_->Start();
1509 }
1510
Preroll()1511 Status MediaDemuxer::Preroll()
1512 {
1513 std::lock_guard<std::mutex> lock(prerollMutex_);
1514 if (inPreroll_.load()) {
1515 return Status::OK;
1516 }
1517 if (!CheckTrackEnabledById(videoTrackId_)) {
1518 return Status::OK;
1519 }
1520 inPreroll_.store(true);
1521 MEDIA_LOG_D("Preroll enter.");
1522 Status ret = Status::OK;
1523 if (isStopped_.load()) {
1524 ret = Start();
1525 } else if (isPaused_.load()) {
1526 ret = Resume();
1527 }
1528 if (ret != Status::OK) {
1529 inPreroll_.store(false);
1530 MEDIA_LOG_E("Preroll failed, ret: %{public}d", ret);
1531 }
1532 return ret;
1533 }
1534
PausePreroll()1535 Status MediaDemuxer::PausePreroll()
1536 {
1537 std::lock_guard<std::mutex> lock(prerollMutex_);
1538 if (!inPreroll_.load()) {
1539 return Status::OK;
1540 }
1541 MEDIA_LOG_D("Preroll enter.");
1542 Status ret = Pause();
1543 inPreroll_.store(false);
1544 return ret;
1545 }
1546
Stop()1547 Status MediaDemuxer::Stop()
1548 {
1549 FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Cannot reset track when not use buffer queue.");
1550 FALSE_RETURN_V_MSG_E(!isThreadExit_, Status::OK, "Thread exit");
1551 MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Stop");
1552 MEDIA_LOG_I("In");
1553 {
1554 AutoLock lock(mapMutex_);
1555 FALSE_RETURN_V_MSG_E(!isStopped_, Status::OK, "Process has been stopped already, ignore");
1556 isStopped_ = true;
1557 StopAllTask();
1558 }
1559 streamDemuxer_->Stop();
1560 return demuxerPluginManager_->Stop();
1561 }
1562
HasVideo()1563 bool MediaDemuxer::HasVideo()
1564 {
1565 return videoTrackId_ != TRACK_ID_DUMMY;
1566 }
1567
InitMediaMetaData(const Plugins::MediaInfo & mediaInfo)1568 void MediaDemuxer::InitMediaMetaData(const Plugins::MediaInfo& mediaInfo)
1569 {
1570 AutoLock lock(mapMutex_);
1571 mediaMetaData_.globalMeta = std::make_shared<Meta>(mediaInfo.general);
1572 mediaMetaData_.trackMetas.clear();
1573 mediaMetaData_.trackMetas.reserve(mediaInfo.tracks.size());
1574 for (uint32_t index = 0; index < mediaInfo.tracks.size(); index++) {
1575 auto trackMeta = mediaInfo.tracks[index];
1576 mediaMetaData_.trackMetas.emplace_back(std::make_shared<Meta>(trackMeta));
1577 }
1578 }
1579
InitDefaultTrack(const Plugins::MediaInfo & mediaInfo,uint32_t & videoTrackId,uint32_t & audioTrackId,uint32_t & subtitleTrackId,std::string & videoMime)1580 void MediaDemuxer::InitDefaultTrack(const Plugins::MediaInfo& mediaInfo, uint32_t& videoTrackId,
1581 uint32_t& audioTrackId, uint32_t& subtitleTrackId, std::string& videoMime)
1582 {
1583 AutoLock lock(mapMutex_);
1584 std::string dafaultTrack = "[";
1585 for (uint32_t index = 0; index < mediaInfo.tracks.size(); index++) {
1586 if (demuxerPluginManager_->CheckTrackIsActive(index) == false) {
1587 continue;
1588 }
1589 auto trackMeta = mediaInfo.tracks[index];
1590 std::string mimeType;
1591 bool ret = trackMeta.Get<Tag::MIME_TYPE>(mimeType);
1592 if (ret && mimeType.find("video") == 0 &&
1593 !IsTrackDisabled(Plugins::MediaType::VIDEO)) {
1594 videoTrackCount_++;
1595 dafaultTrack += "/V:";
1596 dafaultTrack += std::to_string(index);
1597 videoMime = mimeType;
1598 if (videoTrackId == TRACK_ID_DUMMY) {
1599 videoTrackId = index;
1600 }
1601 if (!trackMeta.GetData(Tag::MEDIA_START_TIME, videoStartTime_)) {
1602 MEDIA_LOG_W("Get media start time failed");
1603 }
1604 } else if (ret && mimeType.find("audio") == 0 &&
1605 !IsTrackDisabled(Plugins::MediaType::AUDIO)) {
1606 dafaultTrack += "/A:";
1607 dafaultTrack += std::to_string(index);
1608 if (audioTrackId == TRACK_ID_DUMMY) {
1609 audioTrackId = index;
1610 }
1611 } else if (ret && IsSubtitleMime(mimeType) &&
1612 !IsTrackDisabled(Plugins::MediaType::SUBTITLE)) {
1613 dafaultTrack += "/S:";
1614 dafaultTrack += std::to_string(index);
1615 if (subtitleTrackId == TRACK_ID_DUMMY) {
1616 subtitleTrackId = index;
1617 }
1618 } else {}
1619 }
1620 dafaultTrack += "]";
1621 MEDIA_LOG_I(PUBLIC_LOG_S, dafaultTrack.c_str());
1622 }
1623
GetBufferFromUserQueue(uint32_t queueIndex,uint32_t size)1624 bool MediaDemuxer::GetBufferFromUserQueue(uint32_t queueIndex, uint32_t size)
1625 {
1626 MEDIA_LOG_D("In, queue: " PUBLIC_LOG_U32 ", size: " PUBLIC_LOG_U32, queueIndex, size);
1627 FALSE_RETURN_V_MSG_E(bufferQueueMap_.count(queueIndex) > 0 && bufferQueueMap_[queueIndex] != nullptr, false,
1628 "BufferQueue " PUBLIC_LOG_D32 " is nullptr", queueIndex);
1629
1630 AVBufferConfig avBufferConfig;
1631 avBufferConfig.capacity = static_cast<int32_t>(size);
1632 Status ret = bufferQueueMap_[queueIndex]->RequestBuffer(bufferMap_[queueIndex], avBufferConfig,
1633 REQUEST_BUFFER_TIMEOUT);
1634 if (ret != Status::OK) {
1635 requestBufferErrorCountMap_[queueIndex]++;
1636 if (requestBufferErrorCountMap_[queueIndex] % 5 == 0) { // log per 5 times fail
1637 MEDIA_LOG_W("Request buffer failed, queue: " PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32
1638 ", errorCnt:" PUBLIC_LOG_U32, queueIndex, (int32_t)(ret), requestBufferErrorCountMap_[queueIndex]);
1639 }
1640 if (requestBufferErrorCountMap_[queueIndex] >= REQUEST_FAILED_RETRY_TIMES) {
1641 MEDIA_LOG_E("Request failed too many times in 1min");
1642 }
1643 } else {
1644 requestBufferErrorCountMap_[queueIndex] = 0;
1645 }
1646 return ret == Status::OK;
1647 }
1648
HandleSelectTrackChangeStream(int32_t trackId,int32_t newStreamID,int32_t & newTrackId)1649 bool MediaDemuxer::HandleSelectTrackChangeStream(int32_t trackId, int32_t newStreamID, int32_t& newTrackId)
1650 {
1651 StreamType streamType = demuxerPluginManager_->GetStreamTypeByTrackID(trackId);
1652 TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1653 int32_t currentStreamID = demuxerPluginManager_->GetStreamIDByTrackType(type);
1654 int32_t currentTrackId = trackId;
1655 if (newStreamID == -1 || currentStreamID == -1 || currentStreamID == newStreamID) {
1656 return false;
1657 }
1658 MEDIA_LOG_I("In");
1659 // stop plugin
1660 demuxerPluginManager_->StopPlugin(currentStreamID, streamDemuxer_);
1661
1662 // start plugin
1663 Status ret = demuxerPluginManager_->StartPlugin(newStreamID, streamDemuxer_);
1664 FALSE_RETURN_V_MSG_E(ret == Status::OK, false, "Start plugin failed");
1665
1666 // get new mediainfo
1667 Plugins::MediaInfo mediaInfo;
1668 demuxerPluginManager_->UpdateDefaultStreamID(mediaInfo, streamType, newStreamID);
1669 InitMediaMetaData(mediaInfo); // update mediaMetaData_
1670
1671 // get newStreamID
1672 int32_t newInnerTrackId;
1673 demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId);
1674
1675 // update track map
1676 demuxerPluginManager_->DeleteTempTrackMapInfo(currentTrackId);
1677 int32_t innerTrackID = demuxerPluginManager_->GetInnerTrackIDByTrackID(newTrackId);
1678 demuxerPluginManager_->UpdateTempTrackMapInfo(newTrackId, newTrackId, innerTrackID);
1679 MEDIA_LOG_I("Updata info");
1680
1681 InnerSelectTrack(newTrackId);
1682
1683 // update buffer queue
1684 bufferQueueMap_.insert(std::pair<uint32_t, sptr<AVBufferQueueProducer>>(newTrackId,
1685 bufferQueueMap_[currentTrackId]));
1686 bufferMap_.insert(std::pair<uint32_t, std::shared_ptr<AVBuffer>>(newTrackId,
1687 bufferMap_[currentTrackId]));
1688 bufferQueueMap_.erase(currentTrackId);
1689 bufferMap_.erase(currentTrackId);
1690
1691 MEDIA_LOG_I("Out");
1692 return true;
1693 }
1694
SelectTrackChangeStream(uint32_t trackId)1695 bool MediaDemuxer::SelectTrackChangeStream(uint32_t trackId)
1696 {
1697 MediaAVCodec::AVCodecTrace trace("MediaDemuxer::SelectTrackChangeStream");
1698 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Invalid param");
1699 TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(static_cast<int32_t>(trackId));
1700 int32_t newStreamID = -1;
1701 if (type == TRACK_AUDIO) {
1702 newStreamID = streamDemuxer_->GetNewAudioStreamID();
1703 } else if (type == TRACK_SUBTITLE) {
1704 newStreamID = streamDemuxer_->GetNewSubtitleStreamID();
1705 } else if (type == TRACK_VIDEO) {
1706 newStreamID = streamDemuxer_->GetNewVideoStreamID();
1707 } else {
1708 MEDIA_LOG_W("Invalid track " PUBLIC_LOG_U32, trackId);
1709 return false;
1710 }
1711
1712 int32_t newTrackId;
1713 bool ret = HandleSelectTrackChangeStream(trackId, newStreamID, newTrackId);
1714 if (ret && eventReceiver_ != nullptr) {
1715 MEDIA_LOG_I("TrackType: " PUBLIC_LOG_U32 ", TrackId " PUBLIC_LOG_D32 " >> " PUBLIC_LOG_D32,
1716 static_cast<uint32_t>(type), trackId, newTrackId);
1717 if (type == TrackType::TRACK_AUDIO) {
1718 audioTrackId_ = static_cast<uint32_t>(newTrackId);
1719 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, newTrackId});
1720 shouldCheckAudioFramePts_ = true;
1721 } else if (type == TrackType::TRACK_VIDEO) {
1722 videoTrackId_ = static_cast<uint32_t>(newTrackId);
1723 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, newTrackId});
1724 } else if (type == TrackType::TRACK_SUBTITLE) {
1725 subtitleTrackId_ = static_cast<uint32_t>(newTrackId);
1726 eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_SUBTITLE_TRACK_CHANGE, newTrackId});
1727 shouldCheckSubtitleFramePts_ = true;
1728 }
1729
1730 {
1731 std::lock_guard<std::mutex> lock(isSelectTrackMutex_);
1732 if (inSelectTrackType_.find(static_cast<int32_t>(type)) != inSelectTrackType_.end() &&
1733 inSelectTrackType_[static_cast<int32_t>(type)] == newTrackId) {
1734 inSelectTrackType_.erase(static_cast<int32_t>(type));
1735 }
1736 }
1737
1738 if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
1739 taskMap_[trackId]->StopAsync(); // stop self
1740 }
1741 return true;
1742 }
1743 return ret;
1744 }
1745
SelectBitRateChangeStream(uint32_t trackId)1746 bool MediaDemuxer::SelectBitRateChangeStream(uint32_t trackId)
1747 {
1748 int32_t currentStreamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1749 int32_t newStreamID = streamDemuxer_->GetNewVideoStreamID();
1750 if (newStreamID >= 0 && currentStreamID != newStreamID) {
1751 MEDIA_LOG_I("In");
1752 demuxerPluginManager_->StopPlugin(currentStreamID, streamDemuxer_);
1753
1754 Status ret = demuxerPluginManager_->StartPlugin(newStreamID, streamDemuxer_);
1755 FALSE_RETURN_V_MSG_E(ret == Status::OK, false, "Start plugin failed");
1756
1757 Plugins::MediaInfo mediaInfo;
1758 demuxerPluginManager_->UpdateDefaultStreamID(mediaInfo, VIDEO, newStreamID);
1759 InitMediaMetaData(mediaInfo); // update mediaMetaData_
1760
1761 int32_t newInnerTrackId = -1;
1762 int32_t newTrackId = -1;
1763 demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId);
1764 demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, newTrackId, newInnerTrackId);
1765
1766 MEDIA_LOG_I("Updata info");
1767 InnerSelectTrack(static_cast<int32_t>(trackId));
1768 MEDIA_LOG_I("Out");
1769 return true;
1770 }
1771 return false;
1772 }
DumpBufferToFile(uint32_t trackId,std::shared_ptr<AVBuffer> buffer)1773 void MediaDemuxer::DumpBufferToFile(uint32_t trackId, std::shared_ptr<AVBuffer> buffer)
1774 {
1775 std::string mimeType;
1776 if (isDump_) {
1777 if (mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) && mimeType.find("audio") == 0) {
1778 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_DEMUXER_AUDIO_FILE_NAME, buffer);
1779 }
1780 if (mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) && mimeType.find("video") == 0) {
1781 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_DEMUXER_VIDEO_FILE_NAME, buffer);
1782 }
1783 }
1784 }
1785
HandleReadSample(uint32_t trackId)1786 Status MediaDemuxer::HandleReadSample(uint32_t trackId)
1787 {
1788 Status ret = InnerReadSample(trackId, bufferMap_[trackId]);
1789 if (trackId == videoTrackId_) {
1790 std::unique_lock<std::mutex> draggingLock(draggingMutex_);
1791 if (VideoStreamReadyCallback_ != nullptr) {
1792 if (ret != Status::OK && ret != Status::END_OF_STREAM) {
1793 bufferQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], false);
1794 MEDIA_LOG_E("Read failed, track " PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32, trackId, (int32_t)(ret));
1795 return ret;
1796 }
1797 MEDIA_LOG_D("In");
1798 std::shared_ptr<VideoStreamReadyCallback> videoStreamReadyCallback = VideoStreamReadyCallback_;
1799 draggingLock.unlock();
1800 bool isDiscardable = videoStreamReadyCallback->IsVideoStreamDiscardable(bufferMap_[trackId]);
1801 bufferQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], !isDiscardable);
1802 return Status::OK;
1803 }
1804 }
1805
1806 if (source_ != nullptr && source_->IsSeekToTimeSupported() && isSeeked_ && HasVideo()) {
1807 if (trackId == videoTrackId_ && isFirstFrameAfterSeek_.load()) {
1808 bool isSyncFrame = (bufferMap_[trackId]->flag_ & (uint32_t)(AVBufferFlag::SYNC_FRAME)) != 0;
1809 if (!isSyncFrame) {
1810 MEDIA_LOG_E("The first frame after seeking is not a sync frame");
1811 }
1812 isFirstFrameAfterSeek_.store(false);
1813 }
1814 MEDIA_LOG_I("Seeking, found idr frame track " PUBLIC_LOG_U32, trackId);
1815 isSeeked_ = false;
1816 }
1817 if (ret == Status::OK || ret == Status::END_OF_STREAM) {
1818 if (bufferMap_[trackId]->flag_ & (uint32_t)(AVBufferFlag::EOS)) {
1819 eosMap_[trackId] = true;
1820 if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
1821 taskMap_[trackId]->StopAsync();
1822 }
1823 MEDIA_LOG_I("Track eos, track: " PUBLIC_LOG_U32 ", bufferId: " PUBLIC_LOG_U64
1824 ", pts: " PUBLIC_LOG_D64 ", flag: " PUBLIC_LOG_U32, trackId, bufferMap_[trackId]->GetUniqueId(),
1825 bufferMap_[trackId]->pts_, bufferMap_[trackId]->flag_);
1826 ret = bufferQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], true);
1827 return Status::OK;
1828 }
1829 HandleAutoMaintainPts(trackId, bufferMap_[trackId]);
1830 bool isDroppable = IsBufferDroppable(bufferMap_[trackId], trackId);
1831 ret = bufferQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], !isDroppable);
1832 } else {
1833 bufferQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], false);
1834 MEDIA_LOG_E("Read failed, track " PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32, trackId, (int32_t)(ret));
1835 }
1836 return ret;
1837 }
1838
HandleDashChangeStream(uint32_t trackId)1839 bool MediaDemuxer::HandleDashChangeStream(uint32_t trackId)
1840 {
1841 FALSE_RETURN_V_NOLOG(demuxerPluginManager_->IsDash(), false);
1842 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Plugin manager is nullptr");
1843 FALSE_RETURN_V_MSG_E(streamDemuxer_ != nullptr, false, "Stream is nullptr");
1844
1845 MEDIA_LOG_D("IN");
1846 TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(static_cast<int32_t>(trackId));
1847 int32_t currentStreamID = demuxerPluginManager_->GetStreamIDByTrackType(type);
1848 int32_t newStreamID = demuxerPluginManager_->GetStreamDemuxerNewStreamID(type, streamDemuxer_);
1849 bool ret = false;
1850 FALSE_RETURN_V_NOLOG(newStreamID != -1 && currentStreamID != newStreamID, ret);
1851
1852 MEDIA_LOG_I("Change stream begin, currentStreamID: " PUBLIC_LOG_D32 " newStreamID: " PUBLIC_LOG_D32,
1853 currentStreamID, newStreamID);
1854 if (trackId == videoTrackId_ && demuxerPluginManager_->GetCurrentBitRate() != targetBitRate_) {
1855 ret = SelectBitRateChangeStream(trackId);
1856 if (ret) {
1857 streamDemuxer_->SetChangeFlag(true);
1858 MEDIA_LOG_I("targetBitrate: " PUBLIC_LOG_U32 " currentBitrate: " PUBLIC_LOG_U32, targetBitRate_,
1859 demuxerPluginManager_->GetCurrentBitRate());
1860 isSelectBitRate_.store(targetBitRate_ != demuxerPluginManager_->GetCurrentBitRate());
1861 }
1862 } else {
1863 isSelectTrack_.store(true);
1864 ret = SelectTrackChangeStream(trackId);
1865 if (ret) {
1866 MEDIA_LOG_I("targetBitrate: " PUBLIC_LOG_U32 " currentBitrate: " PUBLIC_LOG_U32, targetBitRate_,
1867 demuxerPluginManager_->GetCurrentBitRate());
1868 targetBitRate_ = demuxerPluginManager_->GetCurrentBitRate();
1869 streamDemuxer_->SetChangeFlag(true);
1870 }
1871 isSelectTrack_.store(false);
1872 }
1873 MEDIA_LOG_I("Change stream success");
1874 return ret;
1875 }
1876
CopyFrameToUserQueue(uint32_t trackId)1877 Status MediaDemuxer::CopyFrameToUserQueue(uint32_t trackId)
1878 {
1879 MediaAVCodec::AVCodecTrace trace("MediaDemuxer::CopyFrameToUserQueue");
1880 MEDIA_LOG_D("In, track:" PUBLIC_LOG_U32, trackId);
1881
1882 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
1883 int32_t innerTrackID = static_cast<int32_t>(trackId);
1884 int32_t id = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1885 if (demuxerPluginManager_->IsDash() || demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_) != -1) {
1886 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(id);
1887 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1888 innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
1889 } else {
1890 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(id);
1891 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1892 }
1893
1894 int32_t size = 0;
1895 Status ret = pluginTemp->GetNextSampleSize(innerTrackID, size);
1896 FALSE_RETURN_V_MSG_E(ret != Status::ERROR_UNKNOWN, ret, "Get size failed for track " PUBLIC_LOG_U32, trackId);
1897 FALSE_RETURN_V_MSG_E(ret != Status::ERROR_AGAIN, ret,
1898 "Get size failed for track " PUBLIC_LOG_U32 ", retry", trackId);
1899 FALSE_RETURN_V_MSG_E(ret != Status::ERROR_NO_MEMORY, ret, "Get size failed for track " PUBLIC_LOG_U32, trackId);
1900 if (HandleDashChangeStream(trackId)) {
1901 MEDIA_LOG_I("HandleDashChangeStream success");
1902 return Status::OK;
1903 }
1904 SetTrackNotifyFlag(trackId, true);
1905 if (!GetBufferFromUserQueue(trackId, size)) {
1906 return Status::ERROR_INVALID_PARAMETER;
1907 }
1908 SetTrackNotifyFlag(trackId, false);
1909 ret = HandleReadSample(trackId);
1910 MEDIA_LOG_D("Out, track:" PUBLIC_LOG_U32, trackId);
1911 return ret;
1912 }
1913
InnerReadSample(uint32_t trackId,std::shared_ptr<AVBuffer> sample)1914 Status MediaDemuxer::InnerReadSample(uint32_t trackId, std::shared_ptr<AVBuffer> sample)
1915 {
1916 MEDIA_LOG_D("In, track " PUBLIC_LOG_U32, trackId);
1917 int32_t innerTrackID = static_cast<int32_t>(trackId);
1918 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
1919 if (demuxerPluginManager_->IsDash() || demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_) != -1) {
1920 int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1921 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
1922 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1923 innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
1924 } else {
1925 int32_t streamId = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
1926 pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
1927 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1928 }
1929
1930 Status ret = pluginTemp->ReadSample(innerTrackID, sample);
1931 if (ret == Status::END_OF_STREAM) {
1932 MEDIA_LOG_I("Read eos for track " PUBLIC_LOG_U32, trackId);
1933 } else if (ret != Status::OK) {
1934 MEDIA_LOG_I("Read error for track " PUBLIC_LOG_U32 ", ret: " PUBLIC_LOG_D32, trackId, (int32_t)(ret));
1935 }
1936 MEDIA_LOG_D("Out, track " PUBLIC_LOG_U32, trackId);
1937 ProcessDrmInfos();
1938 return ret;
1939 }
1940
ReadLoop(uint32_t trackId)1941 int64_t MediaDemuxer::ReadLoop(uint32_t trackId)
1942 {
1943 if (streamDemuxer_->GetIsIgnoreParse() || isStopped_ || isPaused_ || isSeekError_) {
1944 MEDIA_LOG_D("ReadLoop pausing or error, track " PUBLIC_LOG_U32, trackId);
1945 return 6 * 1000; // sleep 6ms in pausing to avoid useless reading
1946 } else {
1947 Status ret = CopyFrameToUserQueue(trackId);
1948 // when read failed, or request always failed in 1min, send error event
1949 bool ignoreError = isStopped_ || isPaused_ || isInterruptNeeded_.load();
1950 if ((ret == Status::ERROR_UNKNOWN && !ignoreError) ||
1951 requestBufferErrorCountMap_[trackId] >= REQUEST_FAILED_RETRY_TIMES) {
1952 MEDIA_LOG_E("Invalid data source, can not get frame");
1953 if (eventReceiver_ != nullptr) {
1954 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DATA_SOURCE_ERROR_UNKNOWN});
1955 } else {
1956 MEDIA_LOG_D("EventReceiver is nullptr");
1957 }
1958 }
1959 bool isNeedRetry = ret == Status::OK || ret == Status::ERROR_AGAIN;
1960 if (isNeedRetry) {
1961 return 0; // retry next frame
1962 } else if (ret == Status::ERROR_NO_MEMORY) {
1963 MEDIA_LOG_E("Cache data size is out of limit");
1964 if (eventReceiver_ != nullptr && !isOnEventNoMemory_.load()) {
1965 isOnEventNoMemory_.store(true);
1966 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DEMUXER_BUFFER_NO_MEMORY});
1967 }
1968 return 0;
1969 } else {
1970 MEDIA_LOG_D("ReadLoop wait, track:" PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32,
1971 trackId, static_cast<int32_t>(ret));
1972 return RETRY_DELAY_TIME_US; // delay to retry if no frame
1973 }
1974 }
1975 }
1976
ReadSample(uint32_t trackId,std::shared_ptr<AVBuffer> sample)1977 Status MediaDemuxer::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer> sample)
1978 {
1979 MediaAVCodec::AVCODEC_SYNC_TRACE;
1980 FALSE_RETURN_V_MSG_E(!useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1981 MEDIA_LOG_D("In");
1982 FALSE_RETURN_V_MSG_E(eosMap_.count(trackId) > 0, Status::ERROR_INVALID_OPERATION, "Track has not been selected");
1983 FALSE_RETURN_V_MSG_E(sample != nullptr && sample->memory_!=nullptr, Status::ERROR_INVALID_PARAMETER,
1984 "AVBuffer is nullptr");
1985 if (eosMap_[trackId]) {
1986 MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " has reached eos", trackId);
1987 sample->flag_ = (uint32_t)(AVBufferFlag::EOS);
1988 sample->memory_->SetSize(0);
1989 return Status::END_OF_STREAM;
1990 }
1991 Status ret = InnerReadSample(trackId, sample);
1992 if (ret == Status::OK || ret == Status::END_OF_STREAM) {
1993 if (sample->flag_ & (uint32_t)(AVBufferFlag::EOS)) {
1994 eosMap_[trackId] = true;
1995 sample->memory_->SetSize(0);
1996 }
1997 if (sample->flag_ & (uint32_t)(AVBufferFlag::PARTIAL_FRAME)) {
1998 ret = Status::ERROR_NO_MEMORY;
1999 }
2000 }
2001 return ret;
2002 }
2003
HandleSourceDrmInfoEvent(const std::multimap<std::string,std::vector<uint8_t>> & info)2004 void MediaDemuxer::HandleSourceDrmInfoEvent(const std::multimap<std::string, std::vector<uint8_t>> &info)
2005 {
2006 MEDIA_LOG_I("In");
2007 std::multimap<std::string, std::vector<uint8_t>> infoUpdated;
2008 bool isUpdated = GetDrmInfosUpdated(info, infoUpdated);
2009 if (isUpdated) {
2010 ReportDrmInfos(infoUpdated);
2011 return;
2012 }
2013 MEDIA_LOG_D("Demuxer filter received source drminfos but not update");
2014 }
2015
OnEvent(const Plugins::PluginEvent & event)2016 void MediaDemuxer::OnEvent(const Plugins::PluginEvent &event)
2017 {
2018 MEDIA_LOG_D("In");
2019 if (eventReceiver_ == nullptr && event.type != PluginEventType::SOURCE_DRM_INFO_UPDATE) {
2020 MEDIA_LOG_D("EventReceiver is nullptr");
2021 return;
2022 }
2023 switch (event.type) {
2024 case PluginEventType::SOURCE_DRM_INFO_UPDATE: {
2025 MEDIA_LOG_D("OnEvent source drmInfo update");
2026 HandleSourceDrmInfoEvent(AnyCast<std::multimap<std::string, std::vector<uint8_t>>>(event.param));
2027 break;
2028 }
2029 case PluginEventType::CLIENT_ERROR:
2030 case PluginEventType::SERVER_ERROR: {
2031 MEDIA_LOG_E("OnEvent error code " PUBLIC_LOG_D32, AnyCast<int32_t>(event.param));
2032 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, event.param});
2033 break;
2034 }
2035 case PluginEventType::BUFFERING_END: {
2036 MEDIA_LOG_D("OnEvent pause");
2037 eventReceiver_->OnEvent({"demuxer_filter", EventType::BUFFERING_END, PAUSE});
2038 break;
2039 }
2040 case PluginEventType::BUFFERING_START: {
2041 MEDIA_LOG_D("OnEvent start");
2042 eventReceiver_->OnEvent({"demuxer_filter", EventType::BUFFERING_START, START});
2043 break;
2044 }
2045 case PluginEventType::CACHED_DURATION: {
2046 MEDIA_LOG_D("OnEvent cached duration");
2047 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_CACHED_DURATION, event.param});
2048 break;
2049 }
2050 case PluginEventType::SOURCE_BITRATE_START: {
2051 MEDIA_LOG_D("OnEvent source bitrate start");
2052 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_SOURCE_BITRATE_START, event.param});
2053 break;
2054 }
2055 case PluginEventType::EVENT_BUFFER_PROGRESS: {
2056 MEDIA_LOG_D("OnEvent percent update");
2057 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_BUFFER_PROGRESS, event.param});
2058 break;
2059 }
2060 default:
2061 break;
2062 }
2063 OnSeekReadyEvent(event);
2064 }
2065
OnSeekReadyEvent(const Plugins::PluginEvent & event)2066 void MediaDemuxer::OnSeekReadyEvent(const Plugins::PluginEvent &event)
2067 {
2068 FALSE_RETURN_NOLOG(event.type == PluginEventType::DASH_SEEK_READY);
2069 MEDIA_LOG_D("Onevent dash seek ready");
2070 std::unique_lock<std::mutex> lock(rebootPluginMutex_);
2071 Format param = AnyCast<Format>(event.param);
2072 int32_t currentStreamType = -1;
2073 param.GetIntValue("currentStreamType", currentStreamType);
2074 int32_t isEOS = -1;
2075 param.GetIntValue("isEOS", isEOS);
2076 int32_t currentStreamId = -1;
2077 param.GetIntValue("currentStreamId", currentStreamId);
2078 MEDIA_LOG_D("HandleDashSeekReady, streamType: " PUBLIC_LOG_D32 " streamId: " PUBLIC_LOG_D32
2079 " isEos: " PUBLIC_LOG_D32, currentStreamType, currentStreamId, isEOS);
2080 switch (currentStreamType) {
2081 case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_VID):
2082 seekReadyStreamInfo_[static_cast<int32_t>(StreamType::VIDEO)] = std::make_pair(currentStreamId, isEOS);
2083 break;
2084 case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_AUD):
2085 seekReadyStreamInfo_[static_cast<int32_t>(StreamType::AUDIO)] = std::make_pair(currentStreamId, isEOS);
2086 break;
2087 case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_SUBTITLE):
2088 seekReadyStreamInfo_[static_cast<int32_t>(StreamType::SUBTITLE)] = std::make_pair(currentStreamId, isEOS);
2089 break;
2090 default:
2091 break;
2092 }
2093 rebootPluginCondition_.notify_all();
2094 }
2095
OptimizeDecodeSlow(bool isDecodeOptimizationEnabled)2096 Status MediaDemuxer::OptimizeDecodeSlow(bool isDecodeOptimizationEnabled)
2097 {
2098 MEDIA_LOG_I("In");
2099 isDecodeOptimizationEnabled_ = isDecodeOptimizationEnabled;
2100 return Status::OK;
2101 }
2102
SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit,uint32_t trackId)2103 Status MediaDemuxer::SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit,
2104 uint32_t trackId)
2105 {
2106 MEDIA_LOG_I("DecoderFramerateUpperLimit=" PUBLIC_LOG_D32 " trackId=" PUBLIC_LOG_D32,
2107 decoderFramerateUpperLimit, trackId);
2108 FALSE_RETURN_V(trackId == videoTrackId_, Status::OK);
2109 FALSE_RETURN_V_MSG_E(decoderFramerateUpperLimit > 0, Status::ERROR_INVALID_PARAMETER,
2110 "SetDecoderFramerateUpperLimit failed, decoderFramerateUpperLimit <= 0");
2111 decoderFramerateUpperLimit_.store(decoderFramerateUpperLimit);
2112 return Status::OK;
2113 }
2114
SetSpeed(float speed)2115 Status MediaDemuxer::SetSpeed(float speed)
2116 {
2117 MEDIA_LOG_I("Speed=" PUBLIC_LOG_F, speed);
2118 FALSE_RETURN_V_MSG_E(speed > 0, Status::ERROR_INVALID_PARAMETER, "Speed <= 0");
2119 speed_.store(speed);
2120 return Status::OK;
2121 }
2122
SetFrameRate(double framerate,uint32_t trackId)2123 Status MediaDemuxer::SetFrameRate(double framerate, uint32_t trackId)
2124 {
2125 MEDIA_LOG_I("Framerate=" PUBLIC_LOG_F " trackId=" PUBLIC_LOG_D32, framerate, trackId);
2126 FALSE_RETURN_V(trackId == videoTrackId_, Status::OK);
2127 FALSE_RETURN_V_MSG_E(framerate > 0, Status::ERROR_INVALID_PARAMETER, "Framerate <= 0");
2128 framerate_.store(framerate);
2129 return Status::OK;
2130 }
2131
CheckDropAudioFrame(std::shared_ptr<AVBuffer> sample,uint32_t trackId)2132 void MediaDemuxer::CheckDropAudioFrame(std::shared_ptr<AVBuffer> sample, uint32_t trackId)
2133 {
2134 if (trackId == audioTrackId_) {
2135 if (shouldCheckAudioFramePts_ == false) {
2136 lastAudioPts_ = sample->pts_;
2137 MEDIA_LOG_I("Set last audio pts " PUBLIC_LOG_D64, lastAudioPts_);
2138 return;
2139 }
2140 if (sample->pts_ < lastAudioPts_) {
2141 MEDIA_LOG_I("Drop audio buffer pts " PUBLIC_LOG_D64, sample->pts_);
2142 return;
2143 }
2144 if (shouldCheckAudioFramePts_) {
2145 shouldCheckAudioFramePts_ = false;
2146 }
2147 }
2148 if (trackId == subtitleTrackId_) {
2149 if (shouldCheckSubtitleFramePts_ == false) {
2150 lastSubtitlePts_ = sample->pts_;
2151 MEDIA_LOG_I("Set last subtitle pts " PUBLIC_LOG_D64, lastSubtitlePts_);
2152 return;
2153 }
2154 if (sample->pts_ < lastSubtitlePts_) {
2155 MEDIA_LOG_I("Drop subtitle buffer pts " PUBLIC_LOG_D64, sample->pts_);
2156 return;
2157 }
2158 if (shouldCheckSubtitleFramePts_) {
2159 shouldCheckSubtitleFramePts_ = false;
2160 }
2161 }
2162 }
2163
IsBufferDroppable(std::shared_ptr<AVBuffer> sample,uint32_t trackId)2164 bool MediaDemuxer::IsBufferDroppable(std::shared_ptr<AVBuffer> sample, uint32_t trackId)
2165 {
2166 DumpBufferToFile(trackId, sample);
2167
2168 if (demuxerPluginManager_->IsDash()) {
2169 CheckDropAudioFrame(sample, trackId);
2170 }
2171
2172 if (trackId != videoTrackId_) {
2173 return false;
2174 }
2175
2176 if (!isDecodeOptimizationEnabled_.load()) {
2177 return false;
2178 }
2179
2180 double targetRate = framerate_.load() * speed_.load();
2181 double actualRate = decoderFramerateUpperLimit_.load() * (1 + DECODE_RATE_THRESHOLD);
2182 if (targetRate <= actualRate) {
2183 return false;
2184 }
2185
2186 bool canDrop = false;
2187 bool ret = sample->meta_->GetData(Media::Tag::VIDEO_BUFFER_CAN_DROP, canDrop);
2188 if (!ret || !canDrop) {
2189 return false;
2190 }
2191
2192 MEDIA_LOG_D("Drop buffer, framerate=" PUBLIC_LOG_F " speed=" PUBLIC_LOG_F " decodeUpLimit="
2193 PUBLIC_LOG_D32 " pts=" PUBLIC_LOG_D64, framerate_.load(), speed_.load(),
2194 decoderFramerateUpperLimit_.load(), sample->pts_);
2195 return true;
2196 }
2197
DisableMediaTrack(Plugins::MediaType mediaType)2198 Status MediaDemuxer::DisableMediaTrack(Plugins::MediaType mediaType)
2199 {
2200 disabledMediaTracks_.emplace(mediaType);
2201 return Status::OK;
2202 }
2203
IsTrackDisabled(Plugins::MediaType mediaType)2204 bool MediaDemuxer::IsTrackDisabled(Plugins::MediaType mediaType)
2205 {
2206 return !disabledMediaTracks_.empty() && disabledMediaTracks_.find(mediaType) != disabledMediaTracks_.end();
2207 }
2208
CheckTrackEnabledById(uint32_t trackId)2209 bool MediaDemuxer::CheckTrackEnabledById(uint32_t trackId)
2210 {
2211 bool hasTrack = trackId != TRACK_ID_DUMMY;
2212 if (!hasTrack) {
2213 return false;
2214 }
2215 bool hasTask = taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr;
2216 if (!hasTask) {
2217 return false;
2218 }
2219 bool linkNode = bufferQueueMap_.find(trackId) != bufferQueueMap_.end()
2220 && bufferQueueMap_[trackId] != nullptr;
2221 return linkNode;
2222 }
2223
SetSelectBitRateFlag(bool flag,uint32_t desBitRate)2224 void MediaDemuxer::SetSelectBitRateFlag(bool flag, uint32_t desBitRate)
2225 {
2226 MEDIA_LOG_I("Flag=" PUBLIC_LOG_D32 " desBitRate=" PUBLIC_LOG_U32,
2227 static_cast<int32_t>(flag), desBitRate);
2228 isSelectBitRate_.store(flag);
2229 if (flag) {
2230 targetBitRate_ = desBitRate;
2231 }
2232 }
2233
CanAutoSelectBitRate()2234 bool MediaDemuxer::CanAutoSelectBitRate()
2235 {
2236 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Plugin manager is nullptr");
2237 // calculating auto selectbitrate time
2238 return !(isSelectBitRate_.load()) && !(isSelectTrack_.load())
2239 && (targetBitRate_ == demuxerPluginManager_->GetCurrentBitRate());
2240 }
2241
IsRenderNextVideoFrameSupported()2242 bool MediaDemuxer::IsRenderNextVideoFrameSupported()
2243 {
2244 bool isDataSrcLiveStream = source_ != nullptr && source_->IsNeedPreDownload() &&
2245 source_->GetSeekable() == Plugins::Seekable::UNSEEKABLE;
2246 return videoTrackId_ != TRACK_ID_DUMMY && !IsTrackDisabled(Plugins::MediaType::VIDEO) &&
2247 !isDataSrcLiveStream;
2248 }
2249
GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,const uint64_t relativePresentationTimeUs,uint32_t & index)2250 Status MediaDemuxer::GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,
2251 const uint64_t relativePresentationTimeUs, uint32_t &index)
2252 {
2253 MEDIA_LOG_D("In");
2254 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
2255 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
2256 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
2257
2258 Status ret = pluginTemp->GetIndexByRelativePresentationTimeUs(trackIndex, relativePresentationTimeUs, index);
2259 if (ret != Status::OK) {
2260 MEDIA_LOG_E("Get index failed");
2261 }
2262 return ret;
2263 }
2264
GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,const uint32_t index,uint64_t & relativePresentationTimeUs)2265 Status MediaDemuxer::GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,
2266 const uint32_t index, uint64_t &relativePresentationTimeUs)
2267 {
2268 MEDIA_LOG_D("In");
2269 FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
2270 std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
2271 FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
2272
2273 Status ret = pluginTemp->GetRelativePresentationTimeUsByIndex(trackIndex, index, relativePresentationTimeUs);
2274 if (ret != Status::OK) {
2275 MEDIA_LOG_E("Get pts failed");
2276 }
2277 return ret;
2278 }
2279
ResumeDemuxerReadLoop()2280 Status MediaDemuxer::ResumeDemuxerReadLoop()
2281 {
2282 MEDIA_LOG_I("In");
2283 if (isDemuxerLoopExecuting_) {
2284 MEDIA_LOG_I("Has already resumed");
2285 return Status::OK;
2286 }
2287 isDemuxerLoopExecuting_ = true;
2288 return ResumeAllTask();
2289 }
2290
PauseDemuxerReadLoop()2291 Status MediaDemuxer::PauseDemuxerReadLoop()
2292 {
2293 MEDIA_LOG_I("In");
2294 if (!isDemuxerLoopExecuting_) {
2295 MEDIA_LOG_I("Has already paused");
2296 return Status::OK;
2297 }
2298 isDemuxerLoopExecuting_ = false;
2299 return PauseAllTask();
2300 }
2301
SetCacheLimit(uint32_t limitSize)2302 void MediaDemuxer::SetCacheLimit(uint32_t limitSize)
2303 {
2304 FALSE_RETURN_MSG(demuxerPluginManager_ != nullptr, "Plugin manager is nullptr");
2305 (void)demuxerPluginManager_->SetCacheLimit(limitSize);
2306 }
2307
IsVideoEos()2308 bool MediaDemuxer::IsVideoEos()
2309 {
2310 if (videoTrackId_ == TRACK_ID_DUMMY) {
2311 return true;
2312 }
2313 return eosMap_[videoTrackId_];
2314 }
2315
HasEosTrack()2316 bool MediaDemuxer::HasEosTrack()
2317 {
2318 for (auto it = eosMap_.begin(); it != eosMap_.end(); it++) {
2319 if (it->second) {
2320 return true;
2321 }
2322 }
2323 return false;
2324 }
2325
SetEnableOnlineFdCache(bool isEnableFdCache)2326 void MediaDemuxer::SetEnableOnlineFdCache(bool isEnableFdCache)
2327 {
2328 FALSE_RETURN(source_ != nullptr);
2329 source_->SetEnableOnlineFdCache(isEnableFdCache);
2330 }
2331
WaitForBufferingEnd()2332 void MediaDemuxer::WaitForBufferingEnd()
2333 {
2334 FALSE_RETURN_MSG(source_ != nullptr, "Source is nullptr");
2335 source_->WaitForBufferingEnd();
2336 }
2337
GetCurrentVideoTrackId()2338 int32_t MediaDemuxer::GetCurrentVideoTrackId()
2339 {
2340 return (videoTrackId_ != TRACK_ID_DUMMY ? static_cast<int32_t>(videoTrackId_) : INVALID_TRACK_ID);
2341 }
2342
SetIsEnableReselectVideoTrack(bool isEnable)2343 void MediaDemuxer::SetIsEnableReselectVideoTrack(bool isEnable)
2344 {
2345 isEnableReselectVideoTrack_ = isEnable;
2346 }
2347
IsHasMultiVideoTrack()2348 bool MediaDemuxer::IsHasMultiVideoTrack()
2349 {
2350 return videoTrackCount_ >= DEFAULT_MULTI_VIDEO_TRACK_NUM;
2351 }
2352 } // namespace Media
2353 } // namespace OHOS
2354