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