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