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