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