• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define HST_LOG_TAG "MediaDemuxer"
16 #define MEDIA_ATOMIC_ABILITY
17 
18 #include "media_demuxer.h"
19 
20 #include <algorithm>
21 #include <map>
22 #include <memory>
23 
24 #include "avcodec_common.h"
25 #include "avcodec_trace.h"
26 #include "cpp_ext/type_traits_ext.h"
27 #include "buffer/avallocator.h"
28 #include "common/event.h"
29 #include "format.h"
30 #include "common/log.h"
31 #include "hisysevent.h"
32 #include "meta/media_types.h"
33 #include "meta/meta.h"
34 #include "osal/utils/dump_buffer.h"
35 #include "plugin/plugin_info.h"
36 #include "plugin/plugin_buffer.h"
37 #include "source/source.h"
38 #include "stream_demuxer.h"
39 #include "media_core.h"
40 #include "osal/utils/dump_buffer.h"
41 #include "demuxer_plugin_manager.h"
42 #include "media_demuxer_pts_functions.cpp"
43 #include "avcodec_log.h"
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 static constexpr int32_t INVALID_STREAM_OR_TRACK_ID = -1;
51 static constexpr int32_t SKIP_NEXT_OPEN_GOP_CNT = 2;
52 constexpr uint32_t THREAD_PRIORITY_41 = 7;
53 std::map<OHOS::Media::TrackType, OHOS::Media::StreamType> TRACK_TO_STREAM_MAP = {
54     {OHOS::Media::TrackType::TRACK_VIDEO, OHOS::Media::StreamType::VIDEO},
55     {OHOS::Media::TrackType::TRACK_AUDIO, OHOS::Media::StreamType::AUDIO},
56     {OHOS::Media::TrackType::TRACK_SUBTITLE, OHOS::Media::StreamType::SUBTITLE},
57     {OHOS::Media::TrackType::TRACK_INVALID, OHOS::Media::StreamType::MIXED}
58 };
59 } // namespace
60 
61 namespace OHOS {
62 namespace Media {
63 constexpr uint32_t REQUEST_BUFFER_TIMEOUT = 0; // Requesting buffer overtimes 0ms means no retry
64 constexpr int32_t START = 1;
65 constexpr int32_t PAUSE = 2;
66 constexpr int32_t SEEK_TO_EOS = 1;
67 constexpr uint32_t RETRY_DELAY_TIME_US = 100000; // 100ms, Delay time for RETRY if no buffer in avbufferqueue producer.
68 constexpr uint32_t NEXT_DELAY_TIME_US = 10; // 10us is ok
69 constexpr uint32_t SAMPLE_LOOP_RETRY_TIME_US = 20000;
70 constexpr uint32_t SAMPLE_LOOP_DELAY_TIME_US = 100000;
71 constexpr uint32_t SAMPLE_FLOW_CONTROL_MIN_SAMPLE_DURATION_US = 200000;
72 constexpr uint32_t SAMPLE_FLOW_CONTROL_RATE_POW = 6; // 2^6
73 constexpr int64_t UPDATE_SOURCE_CACHE_MS = 100;
74 
75 constexpr uint32_t BUFFERING_WAVELINE_FOR_SAMPLE_QUEUE = 1000000;
76 constexpr double DECODE_RATE_THRESHOLD = 0.05;   // allow actual rate exceeding 5%
77 constexpr uint32_t REQUEST_FAILED_RETRY_TIMES = 12000; // Max times for RETRY if no buffer in avbufferqueue producer.
78 constexpr int32_t US_TO_S = 1000000;
79 constexpr int32_t US_TO_MS = 1000;
80 constexpr int32_t SAMPLE_BUFFER_SIZE_EXTRA = 128;
81 const std::unordered_map<PluginDfxEventType, std::pair<std::string, DfxEventType>> DFX_EVENT_MAP = {
82     { PluginDfxEventType::PERF_SOURCE, { "SRC", DfxEventType::DFX_INFO_PERF_REPORT } }
83 };
84 
85 static const std::map<TrackType, DemuxerTrackType> TRACK_MAP = {
86     {TrackType::TRACK_AUDIO, DemuxerTrackType::AUDIO},
87     {TrackType::TRACK_VIDEO, DemuxerTrackType::VIDEO},
88     {TrackType::TRACK_SUBTITLE, DemuxerTrackType::SUBTITLE},
89 };
90 
91 static const std::map<DemuxerTrackType, std::string> TRACK_SUFFIX_MAP = {
92     {DemuxerTrackType::VIDEO, "V"},
93     {DemuxerTrackType::AUDIO, "A"},
94     {DemuxerTrackType::SUBTITLE, "S"},
95 };
96 enum SceneCode : int32_t {
97     /**
98      * This option is used to mark parser ref for dragging play scene.
99      */
100     AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY = 3 // scene code of parser ref for dragging play is 3
101 };
102 
103 class MediaDemuxer::AVBufferQueueProducerListener : public IRemoteStub<IProducerListener> {
104 public:
AVBufferQueueProducerListener(uint32_t trackId,std::shared_ptr<MediaDemuxer> demuxer,std::unique_ptr<Task> & notifyTask)105     explicit AVBufferQueueProducerListener(uint32_t trackId, std::shared_ptr<MediaDemuxer> demuxer,
106         std::unique_ptr<Task>& notifyTask) : trackId_(trackId), demuxer_(demuxer), notifyTask_(std::move(notifyTask)) {}
107 
108     virtual ~AVBufferQueueProducerListener() = default;
OnRemoteRequest(uint32_t code,MessageParcel & arguments,MessageParcel & reply,MessageOption & option)109     int OnRemoteRequest(uint32_t code, MessageParcel& arguments, MessageParcel& reply, MessageOption& option) override
110     {
111         return IPCObjectStub::OnRemoteRequest(code, arguments, reply, option);
112     }
OnBufferAvailable()113     void OnBufferAvailable() override
114     {
115         MEDIA_LOG_D("Buffer available for track " PUBLIC_LOG_U32, trackId_);
116         if (notifyTask_ == nullptr) {
117             return;
118         }
119         notifyTask_->SubmitJobOnce([this] {
120             auto demuxer = demuxer_.lock();
121             if (demuxer) {
122                 demuxer->OnBufferAvailable(trackId_);
123             }
124         });
125     }
126 private:
127     uint32_t trackId_{0};
128     std::weak_ptr<MediaDemuxer> demuxer_;
129     std::unique_ptr<Task> notifyTask_;
130 };
131 
132 class MediaDemuxer::TrackWrapper {
133 public:
TrackWrapper(uint32_t trackId,sptr<IProducerListener> listener,std::shared_ptr<MediaDemuxer> demuxer)134     explicit TrackWrapper(uint32_t trackId, sptr<IProducerListener> listener, std::shared_ptr<MediaDemuxer> demuxer)
135         : trackId_(trackId), listener_(listener), demuxer_(demuxer) {}
GetProducerListener()136     sptr<IProducerListener> GetProducerListener()
137     {
138         return listener_;
139     }
SetNotifyFlag(bool isNotifyNeeded)140     void SetNotifyFlag(bool isNotifyNeeded)
141     {
142         isNotifyNeeded_ = isNotifyNeeded;
143         MEDIA_LOG_D("TrackId:" PUBLIC_LOG_U32 ", isNotifyNeeded:" PUBLIC_LOG_D32,
144             trackId_, isNotifyNeeded);
145     }
GetNotifyFlag()146     bool GetNotifyFlag()
147     {
148         return isNotifyNeeded_.load();
149     }
150 
SetNotifySampleConsumerFlag(bool isNotifySampleConsumerNeeded)151     void SetNotifySampleConsumerFlag(bool isNotifySampleConsumerNeeded)
152     {
153         isNotifySampleConsumerNeeded_ = isNotifySampleConsumerNeeded;
154         MEDIA_LOG_D("TrackId:" PUBLIC_LOG_U32 ", isNotifySampleConsumerNeeded:" PUBLIC_LOG_D32,
155             trackId_, isNotifySampleConsumerNeeded);
156     }
157 
GetNotifySampleConsumerFlag() const158     bool GetNotifySampleConsumerFlag() const
159     {
160         return isNotifySampleConsumerNeeded_.load();
161     }
162 private:
163     std::atomic<bool> isNotifyNeeded_{false};
164     std::atomic<bool> isNotifySampleConsumerNeeded_{false};
165     uint32_t trackId_{0};
166     sptr<IProducerListener> listener_ = nullptr;
167     std::weak_ptr<MediaDemuxer> demuxer_;
168 };
169 
MediaDemuxer()170 MediaDemuxer::MediaDemuxer()
171     : seekable_(Plugins::Seekable::INVALID),
172       subSeekable_(Plugins::Seekable::INVALID),
173       uri_(),
174       mediaDataSize_(0),
175       subMediaDataSize_(0),
176       source_(std::make_shared<Source>()),
177       subtitleSource_(std::make_shared<Source>()),
178       mediaMetaData_(),
179       bufferQueueMap_(),
180       bufferMap_(),
181       sampleQueueMap_(),
182       eventReceiver_(),
183       streamDemuxer_(),
184       demuxerPluginManager_(std::make_shared<DemuxerPluginManager>())
185 {
186     MEDIA_LOG_D("In");
187 }
188 
~MediaDemuxer()189 MediaDemuxer::~MediaDemuxer()
190 {
191     MEDIA_LOG_D("In");
192     ResetInner();
193     if (parserRefInfoTask_ != nullptr) {
194         parserRefInfoTask_->Stop();
195         parserRefInfoTask_ = nullptr;
196     }
197     demuxerPluginManager_ = nullptr;
198     source_ = nullptr;
199     eventReceiver_ = nullptr;
200     eosMap_.clear();
201     requestBufferErrorCountMap_.clear();
202     streamDemuxer_ = nullptr;
203     localDrmInfos_.clear();
204 }
205 
GetCurFFmpegPlugin()206 std::shared_ptr<Plugins::DemuxerPlugin> MediaDemuxer::GetCurFFmpegPlugin()
207 {
208     int32_t tempTrackId = (videoTrackId_ != TRACK_ID_DUMMY ? static_cast<int32_t>(videoTrackId_) : -1);
209     tempTrackId = (tempTrackId == -1 ? static_cast<int32_t>(audioTrackId_) : tempTrackId);
210     int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(tempTrackId);
211     return demuxerPluginManager_->GetPluginByStreamID(streamID);
212 }
213 
ReportSceneCodeForDemuxer(SceneCode scene)214 static void ReportSceneCodeForDemuxer(SceneCode scene)
215 {
216     if (scene != SceneCode::AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY) {
217         return;
218     }
219     MEDIA_LOG_I("Scene %{public}d", scene);
220     auto now =
221         std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
222     int32_t ret = HiSysEventWrite(
223         PERFORMANCE_STATS, "CPU_SCENE_ENTRY", OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PACKAGE_NAME",
224         "media_service", "SCENE_ID", std::to_string(scene).c_str(), "HAPPEN_TIME", now.count());
225     if (ret != MSERR_OK) {
226         MEDIA_LOG_W("Report failed");
227     }
228 }
229 
IsRefParserSupported()230 bool MediaDemuxer::IsRefParserSupported()
231 {
232     FALSE_RETURN_V_MSG_E(videoTrackId_ != TRACK_ID_DUMMY, false, "Video track is nullptr");
233     std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
234     FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, false, "Demuxer plugin is nullptr");
235     return videoPlugin->IsRefParserSupported();
236 }
237 
StartReferenceParser(int64_t startTimeMs,bool isForward)238 Status MediaDemuxer::StartReferenceParser(int64_t startTimeMs, bool isForward)
239 {
240     FALSE_RETURN_V_MSG_E(startTimeMs >= 0, Status::ERROR_UNKNOWN,
241                          "Start failed, startTimeMs: " PUBLIC_LOG_D64, startTimeMs);
242     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
243     FALSE_RETURN_V_MSG_E(videoTrackId_ != TRACK_ID_DUMMY, Status::ERROR_UNKNOWN, "Video track is nullptr");
244     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
245     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
246     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
247     Status ret = plugin->ParserRefUpdatePos(startTimeMs, isForward);
248     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "ParserRefUpdatePos failed");
249     if (isFirstParser_) {
250         isFirstParser_ = false;
251         FALSE_RETURN_V_MSG(source_->GetSeekable() == Plugins::Seekable::SEEKABLE,
252             Status::ERROR_INVALID_OPERATION, "Unsupport online video");
253         parserRefInfoTask_ = std::make_unique<Task>("ParserRefInfo", playerId_);
254         parserRefInfoTask_->RegisterJob([this] { return ParserRefInfo(); });
255         ReportSceneCodeForDemuxer(SceneCode::AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY);
256         parserRefInfoTask_->Start();
257     }
258     TryReclaimParserTask();
259     return ret;
260 }
261 
TryReclaimParserTask()262 void MediaDemuxer::TryReclaimParserTask()
263 {
264     std::lock_guard<std::mutex> lock(parserTaskMutex_);
265     if (isParserTaskEnd_ && parserRefInfoTask_ != nullptr) {
266         parserRefInfoTask_->Stop();
267         parserRefInfoTask_ = nullptr;
268         MEDIA_LOG_I("Success to reclaim parser task");
269     }
270 }
271 
ParserRefInfo()272 int64_t MediaDemuxer::ParserRefInfo()
273 {
274     FALSE_RETURN_V_MSG_D(demuxerPluginManager_ != nullptr, 0, "Plugin manager is nullptr");
275     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
276     FALSE_RETURN_V_MSG_D(plugin != nullptr, 0, "Demuxer plugin is nullptr");
277     Status ret = plugin->ParserRefInfo();
278     std::lock_guard<std::mutex> lock(parserTaskMutex_);
279     if ((ret == Status::OK || ret == Status::ERROR_UNKNOWN) && parserRefInfoTask_ != nullptr) {
280         parserRefInfoTask_->Stop();
281         isParserTaskEnd_ = true;
282         MEDIA_LOG_I("Success to stop");
283     } else {
284         MEDIA_LOG_I("ret is " PUBLIC_LOG_D32, ret);
285     }
286     return 0;
287 }
288 
GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample,FrameLayerInfo & frameLayerInfo)289 Status MediaDemuxer::GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample, FrameLayerInfo &frameLayerInfo)
290 {
291     FALSE_RETURN_V_MSG_E(videoSample != nullptr, Status::ERROR_NULL_POINTER, "VideoSample is nullptr");
292     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
293     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
294     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
295     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
296     TryReclaimParserTask();
297     Status ret = plugin->GetFrameLayerInfo(videoSample, frameLayerInfo);
298     if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
299         return Status::ERROR_AGAIN;
300     }
301     return ret;
302 }
303 
GetFrameLayerInfo(uint32_t frameId,FrameLayerInfo & frameLayerInfo)304 Status MediaDemuxer::GetFrameLayerInfo(uint32_t frameId, FrameLayerInfo &frameLayerInfo)
305 {
306     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
307     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
308     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
309     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
310     TryReclaimParserTask();
311     Status ret = plugin->GetFrameLayerInfo(frameId, frameLayerInfo);
312     if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
313         return Status::ERROR_AGAIN;
314     }
315     return ret;
316 }
317 
GetGopLayerInfo(uint32_t gopId,GopLayerInfo & gopLayerInfo)318 Status MediaDemuxer::GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo)
319 {
320     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
321     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
322     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
323     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
324     TryReclaimParserTask();
325     Status ret = plugin->GetGopLayerInfo(gopId, gopLayerInfo);
326     if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
327         return Status::ERROR_AGAIN;
328     }
329     return ret;
330 }
331 
RegisterVideoStreamReadyCallback(const std::shared_ptr<VideoStreamReadyCallback> & callback)332 void MediaDemuxer::RegisterVideoStreamReadyCallback(const std::shared_ptr<VideoStreamReadyCallback> &callback)
333 {
334     std::unique_lock<std::mutex> draggingLock(draggingMutex_);
335     MEDIA_LOG_I("In");
336     VideoStreamReadyCallback_ = callback;
337 }
338 
DeregisterVideoStreamReadyCallback()339 void MediaDemuxer::DeregisterVideoStreamReadyCallback()
340 {
341     std::unique_lock<std::mutex> draggingLock(draggingMutex_);
342     MEDIA_LOG_I("In");
343     VideoStreamReadyCallback_ = nullptr;
344     EnterDraggingOpenGopCnt();
345 }
346 
GetIFramePos(std::vector<uint32_t> & IFramePos)347 Status MediaDemuxer::GetIFramePos(std::vector<uint32_t> &IFramePos)
348 {
349     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
350     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
351     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
352     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
353     TryReclaimParserTask();
354     return plugin->GetIFramePos(IFramePos);
355 }
356 
Dts2FrameId(int64_t dts,uint32_t & frameId)357 Status MediaDemuxer::Dts2FrameId(int64_t dts, uint32_t &frameId)
358 {
359     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
360     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
361     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
362     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
363     TryReclaimParserTask();
364     return plugin->Dts2FrameId(dts, frameId);
365 }
366 
SeekMs2FrameId(int64_t seekMs,uint32_t & frameId)367 Status MediaDemuxer::SeekMs2FrameId(int64_t seekMs, uint32_t &frameId)
368 {
369     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
370     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
371     std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
372     FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
373     TryReclaimParserTask();
374     return videoPlugin->SeekMs2FrameId(seekMs, frameId);
375 }
376 
FrameId2SeekMs(uint32_t frameId,int64_t & seekMs)377 Status MediaDemuxer::FrameId2SeekMs(uint32_t frameId, int64_t &seekMs)
378 {
379     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
380     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
381     std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
382     FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
383     TryReclaimParserTask();
384     return videoPlugin->FrameId2SeekMs(frameId, seekMs);
385 }
386 
OnBufferAvailable(uint32_t trackId)387 void MediaDemuxer::OnBufferAvailable(uint32_t trackId)
388 {
389     MEDIA_LOG_D("Buffer available track " PUBLIC_LOG_U32, trackId);
390     UpdateLastVideoBufferAbsPts(trackId);
391     // buffer is available trigger SampleConsumer working task to run immediately.
392     AccelerateSampleConsumerTask(trackId);
393 }
394 
AccelerateSampleConsumerTask(uint32_t trackId)395 void MediaDemuxer::AccelerateSampleConsumerTask(uint32_t trackId)
396 {
397     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::AccelerateSampleConsumerTask");
398     {
399         std::unique_lock<std::mutex> stopLock(stopMutex_);
400         if (isStopped_ || isThreadExit_) {
401             return;
402         }
403     }
404     AutoLock lock(mapMutex_);
405     auto track = trackMap_.find(trackId);
406     if (track == trackMap_.end() || track->second == nullptr || !track->second->GetNotifySampleConsumerFlag()) {
407         return;
408     }
409     track->second->SetNotifySampleConsumerFlag(false);
410 
411     auto sampleConsumerTask = sampleConsumerTaskMap_.find(trackId);
412     if (sampleConsumerTask == sampleConsumerTaskMap_.end()) {
413         return;
414     }
415     sampleConsumerTask->second->UpdateDelayTime();
416 }
417 
AccelerateTrackTask(uint32_t trackId)418 void MediaDemuxer::AccelerateTrackTask(uint32_t trackId)
419 {
420     {
421         std::unique_lock<std::mutex> stopLock(stopMutex_);
422         if (isStopped_ || isThreadExit_) {
423             return;
424         }
425     }
426     AutoLock lock(mapMutex_);
427 
428     auto track = trackMap_.find(trackId);
429     if (track == trackMap_.end() || track->second == nullptr || !track->second->GetNotifyFlag()) {
430         return;
431     }
432     track->second->SetNotifyFlag(false);
433 
434     auto task = taskMap_.find(trackId);
435     if (task == taskMap_.end()) {
436         return;
437     }
438     MEDIA_LOG_D("Accelerate track " PUBLIC_LOG_U32, trackId);
439     task->second->UpdateDelayTime();
440 }
441 
SetTrackNotifyFlag(uint32_t trackId,bool isNotifyNeeded)442 void MediaDemuxer::SetTrackNotifyFlag(uint32_t trackId, bool isNotifyNeeded)
443 {
444     // This function is called in demuxer track working thread, and if track info exists it is valid.
445     auto track = trackMap_.find(trackId);
446     if (track != trackMap_.end() && track->second != nullptr) {
447         track->second->SetNotifyFlag(isNotifyNeeded);
448     }
449 }
450 
SetTrackNotifySampleConsumerFlag(uint32_t trackId,bool isNotifySampleConsumerNeeded)451 void MediaDemuxer::SetTrackNotifySampleConsumerFlag(uint32_t trackId, bool isNotifySampleConsumerNeeded)
452 {
453     // This function is called in samplequeue consumer working thread, and if track info exists it is valid.
454     auto track = trackMap_.find(trackId);
455     if (track != trackMap_.end() && track->second != nullptr) {
456         track->second->SetNotifySampleConsumerFlag(isNotifySampleConsumerNeeded);
457     }
458 }
459 
GetBitRates(std::vector<uint32_t> & bitRates)460 Status MediaDemuxer::GetBitRates(std::vector<uint32_t> &bitRates)
461 {
462     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
463     return source_->GetBitRates(bitRates);
464 }
465 
GetMediaKeySystemInfo(std::multimap<std::string,std::vector<uint8_t>> & infos)466 Status MediaDemuxer::GetMediaKeySystemInfo(std::multimap<std::string, std::vector<uint8_t>> &infos)
467 {
468     MEDIA_LOG_I("In");
469     std::shared_lock<std::shared_mutex> lock(drmMutex);
470     infos = localDrmInfos_;
471     return Status::OK;
472 }
473 
GetDownloadInfo(DownloadInfo & downloadInfo)474 Status MediaDemuxer::GetDownloadInfo(DownloadInfo& downloadInfo)
475 {
476     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
477     return source_->GetDownloadInfo(downloadInfo);
478 }
479 
GetPlaybackInfo(PlaybackInfo & playbackInfo)480 Status MediaDemuxer::GetPlaybackInfo(PlaybackInfo& playbackInfo)
481 {
482     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
483     return source_->GetPlaybackInfo(playbackInfo);
484 }
485 
SetDrmCallback(const std::shared_ptr<OHOS::MediaAVCodec::AVDemuxerCallback> & callback)486 void MediaDemuxer::SetDrmCallback(const std::shared_ptr<OHOS::MediaAVCodec::AVDemuxerCallback> &callback)
487 {
488     MEDIA_LOG_I("In");
489     drmCallback_ = callback;
490     bool isExisted = IsLocalDrmInfosExisted();
491     if (isExisted) {
492         MEDIA_LOG_D("Already received drminfo and report");
493         ReportDrmInfos(localDrmInfos_);
494     }
495 }
496 
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)497 void MediaDemuxer::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> &receiver)
498 {
499     eventReceiver_ = receiver;
500 }
501 
SetPlayerId(std::string playerId)502 void MediaDemuxer::SetPlayerId(std::string playerId)
503 {
504     playerId_ = playerId;
505 }
506 
SetDumpInfo(bool isDump,uint64_t instanceId)507 void MediaDemuxer::SetDumpInfo(bool isDump, uint64_t instanceId)
508 {
509     FALSE_RETURN_MSG(!isDump || instanceId != 0, "Can not dump with instanceId 0");
510     dumpPrefix_ = std::to_string(instanceId);
511     isDump_ = isDump;
512 }
513 
GetDuration(int64_t & durationMs)514 bool MediaDemuxer::GetDuration(int64_t& durationMs)
515 {
516     AutoLock lock(mapMutex_);
517     if (source_ == nullptr) {
518         durationMs = -1;
519         return false;
520     }
521     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::GetDuration");
522     seekable_ = source_->GetSeekable();
523 
524     FALSE_LOG(seekable_ != Seekable::INVALID);
525     if (source_->IsSeekToTimeSupported()) {
526         duration_ = source_->GetDuration();
527         if (duration_ != Plugins::HST_TIME_NONE) {
528             MEDIA_LOG_I("Hls: " PUBLIC_LOG_D64, duration_);
529             mediaMetaData_.globalMeta->Set<Tag::MEDIA_DURATION>(Plugins::HstTime2Us(duration_));
530         }
531         MEDIA_LOG_I("SeekToTime");
532         return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
533     }
534 
535     // not hls and seekable
536     if (seekable_ == Plugins::Seekable::SEEKABLE) {
537         duration_ = source_->GetDuration();
538         if (duration_ != Plugins::HST_TIME_NONE) {
539             MEDIA_LOG_I("Not hls: " PUBLIC_LOG_D64, duration_);
540             mediaMetaData_.globalMeta->Set<Tag::MEDIA_DURATION>(Plugins::HstTime2Us(duration_));
541         }
542         MEDIA_LOG_I("Seekble");
543         return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
544     }
545     MEDIA_LOG_I("Other");
546     return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
547 }
548 
GetDrmInfosUpdated(const std::multimap<std::string,std::vector<uint8_t>> & newInfos,std::multimap<std::string,std::vector<uint8_t>> & result)549 bool MediaDemuxer::GetDrmInfosUpdated(const std::multimap<std::string, std::vector<uint8_t>> &newInfos,
550     std::multimap<std::string, std::vector<uint8_t>> &result)
551 {
552     MEDIA_LOG_D("In");
553     std::unique_lock<std::shared_mutex> lock(drmMutex);
554     for (auto &newItem : newInfos) {
555         if (localDrmInfos_.find(newItem.first) == localDrmInfos_.end()) {
556             MEDIA_LOG_D("Uuid doesn't exist, update");
557             result.insert(newItem);
558             localDrmInfos_.insert(newItem);
559             continue;
560         }
561         auto pos = localDrmInfos_.equal_range(newItem.first);
562         bool isSame = false;
563         for (; pos.first != pos.second; ++pos.first) {
564             if (newItem.second == pos.first->second) {
565                 MEDIA_LOG_D("Uuid exists and the pssh is same, not update");
566                 isSame = true;
567                 break;
568             }
569         }
570         if (!isSame) {
571             MEDIA_LOG_D("Uuid exists but pssh not same, update");
572             result.insert(newItem);
573             localDrmInfos_.insert(newItem);
574         }
575     }
576     return !result.empty();
577 }
578 
IsLocalDrmInfosExisted()579 bool MediaDemuxer::IsLocalDrmInfosExisted()
580 {
581     std::shared_lock<std::shared_mutex> lock(drmMutex);
582     return !localDrmInfos_.empty();
583 }
584 
ReportDrmInfos(const std::multimap<std::string,std::vector<uint8_t>> & info)585 Status MediaDemuxer::ReportDrmInfos(const std::multimap<std::string, std::vector<uint8_t>> &info)
586 {
587     MEDIA_LOG_I("In");
588     FALSE_RETURN_V_MSG_E(drmCallback_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Drm callback is nullptr");
589     MEDIA_LOG_D("Filter will update drminfo");
590     drmCallback_->OnDrmInfoChanged(info);
591     return Status::OK;
592 }
593 
ProcessDrmInfos()594 Status MediaDemuxer::ProcessDrmInfos()
595 {
596     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
597     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
598     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
599     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
600 
601     std::multimap<std::string, std::vector<uint8_t>> drmInfo;
602     Status ret = pluginTemp->GetDrmInfo(drmInfo);
603     if (ret == Status::OK && !drmInfo.empty()) {
604         MEDIA_LOG_D("Get drminfo success");
605         std::multimap<std::string, std::vector<uint8_t>> infosUpdated;
606         bool isUpdated = GetDrmInfosUpdated(drmInfo, infosUpdated);
607         if (isUpdated) {
608             return ReportDrmInfos(infosUpdated);
609         } else {
610             MEDIA_LOG_D("Received drminfo but not update");
611         }
612     } else {
613         if (ret != Status::OK) {
614             MEDIA_LOG_D("Get drminfo failed, ret:" PUBLIC_LOG_D32, (int32_t)(ret));
615         }
616     }
617     return Status::OK;
618 }
619 
AddDemuxerCopyTask(uint32_t trackId,TaskType type)620 Status MediaDemuxer::AddDemuxerCopyTask(uint32_t trackId, TaskType type)
621 {
622     std::string taskName = "Demux";
623     switch (type) {
624         case TaskType::VIDEO: {
625             taskName += "V";
626             break;
627         }
628         case TaskType::AUDIO: {
629             taskName += "A";
630             break;
631         }
632         case TaskType::SUBTITLE: {
633             taskName += "S";
634             break;
635         }
636         default: {
637             MEDIA_LOG_E("Add demuxer task failed, unknow task type:" PUBLIC_LOG_D32, type);
638             return Status::ERROR_UNKNOWN;
639         }
640     }
641 
642     std::unique_ptr<Task> task = std::make_unique<Task>(taskName, playerId_, type);
643     FALSE_RETURN_V_MSG_W(task != nullptr, Status::OK,
644         "Create task failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
645         trackId, type);
646 #ifdef SUPPORT_START_STOP_ON_DEMAND
647     task->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
648 #else
649     if (!HasVideo() && trackId == audioTrackId_) {
650         task->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
651         MEDIA_LOG_I("Update thread priority for audio-only source");
652     }
653 #endif
654     taskMap_[trackId] = std::move(task);
655     taskMap_[trackId]->RegisterJob([this, trackId] { return ReadLoop(trackId); });
656 
657     // To wake up DEMUXER TRACK WORKING TASK immediately on input buffer available.
658     std::unique_ptr<Task> notifyTask =
659         std::make_unique<Task>(taskName + "N", playerId_, type, TaskPriority::NORMAL, false);
660     FALSE_RETURN_V_MSG_W(notifyTask != nullptr, Status::OK,
661         "Create notify task failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
662         trackId, static_cast<uint32_t>(type));
663 
664     sptr<IProducerListener> listener =
665         OHOS::sptr<AVBufferQueueProducerListener>::MakeSptr(trackId, shared_from_this(), notifyTask);
666     FALSE_RETURN_V_MSG_W(listener != nullptr, Status::OK,
667         "Create listener failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
668         trackId, static_cast<uint32_t>(type));
669 
670     trackMap_.emplace(trackId, std::make_shared<TrackWrapper>(trackId, listener, shared_from_this()));
671     return Status::OK;
672 }
673 
AddDemuxerCopyTaskByTrack(uint32_t trackId,DemuxerTrackType type)674 Status MediaDemuxer::AddDemuxerCopyTaskByTrack(uint32_t trackId, DemuxerTrackType type)
675 {
676     uint32_t trackType = static_cast<uint32_t>(type);
677     std::string taskName = "Demux" + TRACK_SUFFIX_MAP.at(type);
678     auto task = std::make_unique<Task>(taskName, playerId_, TaskType::DEMUXER);
679     FALSE_RETURN_V_MSG_W(task != nullptr, Status::ERROR_NULL_POINTER,
680         "Create task failed, track:" PUBLIC_LOG_U32 ",DemuxerTrackType:" PUBLIC_LOG_D32, trackId, type);
681     taskMap_[trackId] = std::move(task);
682     taskMap_[trackId]->RegisterJob([this, trackId] { return ReadLoop(trackId); });
683 
684     std::string sampleConsumerTaskName = "SampleConsumer" + TRACK_SUFFIX_MAP.at(type);
685     auto sampleConsumerTask = std::make_unique<Task>(sampleConsumerTaskName, playerId_, TaskType::DECODER);
686     FALSE_RETURN_V_MSG_W(sampleConsumerTask != nullptr, Status::ERROR_NULL_POINTER,
687         "Create sampleConsumerTask failed, track:" PUBLIC_LOG_U32 ",DemuxerTrackType:" PUBLIC_LOG_D32, trackId, type);
688     sampleConsumerTaskMap_[trackId] = std::move(sampleConsumerTask);
689     sampleConsumerTaskMap_[trackId]->RegisterJob([this, trackId] { return SampleConsumerLoop(trackId); });
690 
691     // To wake up DEMUXER TRACK WORKING TASK immediately on input buffer available.
692     std::unique_ptr<Task> notifyTask =
693         std::make_unique<Task>(taskName + "N", playerId_, TaskType::GLOBAL, TaskPriority::HIGH, false);
694     FALSE_RETURN_V_MSG_W(notifyTask != nullptr, Status::ERROR_NULL_POINTER,
695         "Create notify task failed, track:" PUBLIC_LOG_U32 ", TrackType:" PUBLIC_LOG_D32, trackId, trackType);
696 
697     sptr<IProducerListener> listener =
698         OHOS::sptr<AVBufferQueueProducerListener>::MakeSptr(trackId, shared_from_this(), notifyTask);
699     FALSE_RETURN_V_MSG_W(listener != nullptr, Status::ERROR_NULL_POINTER,
700         "Create listener failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32, trackId, trackType);
701     trackMap_.emplace(trackId, std::make_shared<TrackWrapper>(trackId, listener, shared_from_this()));
702 
703     if (isFlvLiveStream_ && type == DemuxerTrackType::VIDEO) {
704         notifyBitrateTask_ =
705             std::make_unique<Task>(taskName + "BN", playerId_, TaskType::DEMUXER, TaskPriority::NORMAL, false);
706         if (!notifyBitrateTask_) {
707             MEDIA_LOG_W("Create notifyBitrateTask_ failed, track:" PUBLIC_LOG_U32 ", type:" PUBLIC_LOG_D32,
708                 trackId, trackType);
709         }
710     }
711     MEDIA_LOG_I("create tasks done: trackId=" PUBLIC_LOG_U32 ",type=" PUBLIC_LOG_U32, trackId, trackType);
712     return Status::OK;
713 }
714 
InnerPrepare()715 Status MediaDemuxer::InnerPrepare()
716 {
717     Plugins::MediaInfo mediaInfo;
718     Status ret = demuxerPluginManager_->LoadCurrentAllPlugin(streamDemuxer_, mediaInfo);
719     if (ret == Status::OK) {
720         InitMediaMetaData(mediaInfo);
721         InitDefaultTrack(mediaInfo, videoTrackId_, audioTrackId_, subtitleTrackId_, videoMime_);
722         InitMediaStartPts();
723         if (videoTrackId_ != TRACK_ID_DUMMY) {
724             AddDemuxerCopyTaskByTrack(videoTrackId_, DemuxerTrackType::VIDEO);
725             demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, videoTrackId_, -1);
726             int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(videoTrackId_);
727             streamDemuxer_->SetNewVideoStreamID(streamId);
728             streamDemuxer_->SetChangeFlag(true);
729             streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
730             int64_t bitRate = 0;
731             mediaMetaData_.trackMetas[videoTrackId_]->GetData(Tag::MEDIA_BITRATE, bitRate);
732             source_->SetCurrentBitRate(bitRate, streamId);
733             targetBitRate_ = demuxerPluginManager_->GetCurrentBitRate();
734         }
735         if (audioTrackId_ != TRACK_ID_DUMMY) {
736             AddDemuxerCopyTaskByTrack(audioTrackId_, DemuxerTrackType::AUDIO);
737             demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, audioTrackId_, -1);
738             int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(audioTrackId_);
739             streamDemuxer_->SetNewAudioStreamID(streamId);
740             streamDemuxer_->SetChangeFlag(true);
741             streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
742             int64_t bitRate = 0;
743             mediaMetaData_.trackMetas[audioTrackId_]->GetData(Tag::MEDIA_BITRATE, bitRate);
744             // ignore the bitrate of audio in flv livestream case
745             if (!isFlvLiveStream_) {
746                 source_->SetCurrentBitRate(bitRate, streamId);
747             }
748         }
749         if (subtitleTrackId_ != TRACK_ID_DUMMY) {
750             AddDemuxerCopyTaskByTrack(subtitleTrackId_, DemuxerTrackType::SUBTITLE);
751             demuxerPluginManager_->UpdateTempTrackMapInfo(subtitleTrackId_, subtitleTrackId_, -1);
752             int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_);
753             streamDemuxer_->SetNewSubtitleStreamID(streamId);
754             streamDemuxer_->SetChangeFlag(true);
755             streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
756         }
757     } else {
758         MEDIA_LOG_E("Parse meta failed, ret: " PUBLIC_LOG_D32, (int32_t)(ret));
759     }
760     return ret;
761 }
762 
GetTargetVideoTrackId(std::vector<std::shared_ptr<Meta>> trackInfos)763 uint32_t MediaDemuxer::GetTargetVideoTrackId(std::vector<std::shared_ptr<Meta>> trackInfos)
764 {
765     FALSE_RETURN_V(targetVideoTrackId_ == TRACK_ID_DUMMY, targetVideoTrackId_);
766     MEDIA_LOG_I_SHORT("GetTargetVideoTrackId enter");
767     for (size_t index = 0; index < trackInfos.size(); index++) {
768         std::shared_ptr<Meta> meta = trackInfos[index];
769         if (meta == nullptr) {
770             MEDIA_LOG_E_SHORT("meta is invalid, index: %zu", index);
771             continue;
772         }
773         Plugins::MediaType mediaType = Plugins::MediaType::AUDIO;
774         if (!meta->GetData(Tag::MEDIA_TYPE, mediaType)) {
775             continue;
776         }
777         if (mediaType != Plugins::MediaType::VIDEO) {
778             continue;
779         }
780         MEDIA_LOG_I_SHORT("SelectVideoTrack trackId: %{public}d", static_cast<int32_t>(index));
781         targetVideoTrackId_ = static_cast<uint32_t>(index);
782         break;
783     }
784     return targetVideoTrackId_;
785 }
786 
SetDataSource(const std::shared_ptr<MediaSource> & source)787 Status MediaDemuxer::SetDataSource(const std::shared_ptr<MediaSource> &source)
788 {
789     MediaAVCodec::AVCODEC_SYNC_TRACE;
790     MEDIA_LOG_I("In");
791     FALSE_RETURN_V_MSG_E(isThreadExit_, Status::ERROR_WRONG_STATE, "Process is running");
792     source_->SetCallback(this);
793     auto res = source_->SetSource(source);
794     FALSE_RETURN_V_MSG_E(res == Status::OK, res, "Plugin set source failed");
795     isFlvLiveStream_ = source_->IsFlvLiveStream();
796     Status ret = source_->GetSize(mediaDataSize_);
797     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Get file size failed");
798 
799     std::vector<StreamInfo> streams;
800     source_->GetStreamInfo(streams);
801     isHlsFmp4_ = source_->IsHlsFmp4();
802     MEDIA_LOG_I("ishlsfmp4: " PUBLIC_LOG_D32, static_cast<int32_t>(isHlsFmp4_));
803     demuxerPluginManager_->SetIsHlsFmp4(isHlsFmp4_);
804     demuxerPluginManager_->InitDefaultPlay(streams);
805 
806     streamDemuxer_ = std::make_shared<StreamDemuxer>();
807     streamDemuxer_->SetSourceType(source->GetSourceType());
808     streamDemuxer_->SetInterruptState(isInterruptNeeded_);
809     streamDemuxer_->SetSource(source_);
810     streamDemuxer_->Init(uri_);
811 
812     ret = InnerPrepare();
813     source_->NotifyInitSuccess();
814     ProcessDrmInfos();
815     MEDIA_LOG_I("Out");
816     return ret;
817 }
818 
IsSubtitleMime(const std::string & mime)819 bool MediaDemuxer::IsSubtitleMime(const std::string& mime)
820 {
821     if (mime == "application/x-subrip" || mime == "text/vtt") {
822         return true;
823     }
824     return false;
825 }
826 
SetSubtitleSource(const std::shared_ptr<MediaSource> & subSource)827 Status MediaDemuxer::SetSubtitleSource(const std::shared_ptr<MediaSource> &subSource)
828 {
829     MEDIA_LOG_I("In");
830     if (subtitleTrackId_ != TRACK_ID_DUMMY) {
831         MEDIA_LOG_W("Found subtitle track, not support ext");
832         return Status::OK;
833     }
834     subtitleSource_->SetCallback(this);
835     subtitleSource_->SetSource(subSource);
836     Status ret = subtitleSource_->GetSize(subMediaDataSize_);
837     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Get file size failed");
838     subSeekable_ = subtitleSource_->GetSeekable();
839 
840     int32_t subtitleStreamID = demuxerPluginManager_->AddExternalSubtitle();
841     subStreamDemuxer_ = std::make_shared<StreamDemuxer>();
842     subStreamDemuxer_->SetSourceType(subSource->GetSourceType());
843     subStreamDemuxer_->SetInterruptState(isInterruptNeeded_);
844     subStreamDemuxer_->SetSource(subtitleSource_);
845     subStreamDemuxer_->Init(subSource->GetSourceUri());
846 
847     MediaInfo mediaInfo;
848     ret = demuxerPluginManager_->LoadCurrentSubtitlePlugin(subStreamDemuxer_, mediaInfo);
849     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Parse meta failed, ret:" PUBLIC_LOG_D32, (int32_t)(ret));
850     InitMediaMetaData(mediaInfo);  // update mediaMetaData_
851     for (uint32_t index = 0; index < mediaInfo.tracks.size(); index++) {
852         auto trackMeta = mediaInfo.tracks[index];
853         std::string mimeType;
854         std::string trackType;
855         trackMeta.Get<Tag::MIME_TYPE>(mimeType);
856         int32_t curStreamID = demuxerPluginManager_->GetStreamIDByTrackID(index);
857         if (trackMeta.Get<Tag::MIME_TYPE>(mimeType) && IsSubtitleMime(mimeType) && curStreamID == subtitleStreamID) {
858             MEDIA_LOG_I("STrack " PUBLIC_LOG_U32, index);
859             subtitleTrackId_ = index;   // dash inner subtitle can be replace by out subtitle
860             break;
861         }
862     }
863 
864     if (subtitleTrackId_ != TRACK_ID_DUMMY) {
865         AddDemuxerCopyTaskByTrack(subtitleTrackId_, DemuxerTrackType::SUBTITLE);
866         demuxerPluginManager_->UpdateTempTrackMapInfo(subtitleTrackId_, subtitleTrackId_, -1);
867         subStreamDemuxer_->SetNewSubtitleStreamID(subtitleStreamID);
868         subStreamDemuxer_->SetDemuxerState(subtitleStreamID, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
869     }
870 
871     MEDIA_LOG_I("Out, ext sub %{public}d", subtitleTrackId_);
872     return ret;
873 }
874 
OnInterrupted(bool isInterruptNeeded)875 void MediaDemuxer::OnInterrupted(bool isInterruptNeeded)
876 {
877     MEDIA_LOG_D("MediaDemuxer OnInterrupted %{public}d", isInterruptNeeded);
878     isInterruptNeeded_ = isInterruptNeeded;
879     if (demuxerPluginManager_ != nullptr && demuxerPluginManager_->IsDash()) {
880         std::unique_lock<std::mutex> lock(rebootPluginMutex_);
881         rebootPluginCondition_.notify_all();
882     }
883     if (source_ != nullptr) {
884         source_->SetInterruptState(isInterruptNeeded);
885     }
886     if (streamDemuxer_ != nullptr) {
887         streamDemuxer_->SetInterruptState(isInterruptNeeded);
888     }
889     if (subStreamDemuxer_ != nullptr) {
890         subStreamDemuxer_->SetInterruptState(isInterruptNeeded);
891     }
892     if (demuxerPluginManager_ != nullptr) {
893         demuxerPluginManager_->NotifyInitialBufferingEnd(false);
894         demuxerPluginManager_->SetInterruptState(isInterruptNeeded);
895     }
896 }
897 
SetBundleName(const std::string & bundleName)898 void MediaDemuxer::SetBundleName(const std::string& bundleName)
899 {
900     if (source_ != nullptr) {
901         MEDIA_LOG_I("BundleName: " PUBLIC_LOG_S, bundleName.c_str());
902         bundleName_ = bundleName;
903         streamDemuxer_->SetBundleName(bundleName);
904         source_->SetBundleName(bundleName);
905     }
906 }
907 
SetOutputBufferQueue(int32_t trackId,const sptr<AVBufferQueueProducer> & producer)908 Status MediaDemuxer::SetOutputBufferQueue(int32_t trackId, const sptr<AVBufferQueueProducer>& producer)
909 {
910     AutoLock lock(mapMutex_);
911     FALSE_RETURN_V_MSG_E(trackId >= 0 && (uint32_t)trackId < mediaMetaData_.trackMetas.size(),
912         Status::ERROR_INVALID_PARAMETER, "Invalid track");
913     useBufferQueue_ = true;
914     MEDIA_LOG_I("Set bufferQueue for track " PUBLIC_LOG_D32, trackId);
915     FALSE_RETURN_V_MSG_E(isThreadExit_, Status::ERROR_WRONG_STATE, "Process is running");
916     FALSE_RETURN_V_MSG_E(producer != nullptr, Status::ERROR_INVALID_PARAMETER, "BufferQueue is nullptr");
917     if (bufferQueueMap_.find(trackId) != bufferQueueMap_.end()) {
918         MEDIA_LOG_W("Has been set already");
919     }
920     Status ret = InnerSelectTrack(trackId);
921     if (ret == Status::OK) {
922         auto track = trackMap_.find(trackId);
923         if (track != trackMap_.end()) {
924             auto listener = track->second->GetProducerListener();
925             if (listener) {
926                 MEDIA_LOG_W("Set listener");
927                 producer->SetBufferAvailableListener(listener);
928             }
929         }
930         bufferQueueMap_.insert(std::pair<uint32_t, sptr<AVBufferQueueProducer>>(trackId, producer));
931         bufferMap_.insert(std::pair<uint32_t, std::shared_ptr<AVBuffer>>(trackId, nullptr));
932         MEDIA_LOG_I("Set bufferQueue successfully");
933         ret = AddSampleBufferQueue(trackId);
934         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "AddSampleBufferQueue failed for track " PUBLIC_LOG_D32, trackId);
935     }
936     return ret;
937 }
938 
OnDumpInfo(int32_t fd)939 void MediaDemuxer::OnDumpInfo(int32_t fd)
940 {
941     MEDIA_LOG_D("In");
942     if (fd < 0) {
943         MEDIA_LOG_E("Invalid fd");
944         return;
945     }
946     std::string dumpString;
947     dumpString += "MediaDemuxer buffer queue map size: " + std::to_string(bufferQueueMap_.size()) + "\n";
948     dumpString += "MediaDemuxer buffer map size: " + std::to_string(bufferMap_.size()) + "\n";
949     int ret = write(fd, dumpString.c_str(), dumpString.size());
950     if (ret < 0) {
951         MEDIA_LOG_E("MediaDemuxer::OnDumpInfo write failed");
952         return;
953     }
954 }
955 
GetBufferQueueProducerMap()956 std::map<uint32_t, sptr<AVBufferQueueProducer>> MediaDemuxer::GetBufferQueueProducerMap()
957 {
958     return bufferQueueMap_;
959 }
960 
InnerSelectTrack(int32_t trackId)961 Status MediaDemuxer::InnerSelectTrack(int32_t trackId)
962 {
963     eosMap_[trackId] = false;
964     requestBufferErrorCountMap_[trackId] = 0;
965 
966     int32_t innerTrackID = trackId;
967     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
968     if (IsNeedMapToInnerTrackID()) {
969         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
970         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
971         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
972         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
973     } else {
974         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(demuxerPluginManager_->GetStreamIDByTrackID(trackId));
975         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
976     }
977 
978     return pluginTemp->SelectTrack(innerTrackID);
979 }
980 
StartTask(int32_t trackId)981 Status MediaDemuxer::StartTask(int32_t trackId)
982 {
983     MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
984     Status ret = Status::OK;
985     TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
986     auto iterTrack = TRACK_MAP.find(trackType);
987     FALSE_RETURN_V_MSG_E(iterTrack != TRACK_MAP.end(), Status::ERROR_INVALID_PARAMETER,
988         "invalid trackId: " PUBLIC_LOG_D32, trackId);
989     if (taskMap_.find(trackId) == taskMap_.end() ||
990         sampleConsumerTaskMap_.find(trackId) == sampleConsumerTaskMap_.end()) {
991         ret = AddDemuxerCopyTaskByTrack(trackId, iterTrack->second);
992         FALSE_RETURN_V(ret == Status::OK, ret);
993     }
994 
995     if (taskMap_[trackId] != nullptr && !taskMap_[trackId]->IsTaskRunning()) {
996         UpdateBufferQueueListener(trackId);
997         taskMap_[trackId]->Start();
998     }
999     if (sampleConsumerTaskMap_[trackId] != nullptr && !sampleConsumerTaskMap_[trackId]->IsTaskRunning()) {
1000         sampleConsumerTaskMap_[trackId]->Start();
1001     }
1002     return Status::OK;
1003 }
1004 
UpdateBufferQueueListener(int32_t trackId)1005 void MediaDemuxer::UpdateBufferQueueListener(int32_t trackId)
1006 {
1007     FALSE_RETURN(bufferQueueMap_.find(trackId) != bufferQueueMap_.end() && trackMap_.find(trackId) != trackMap_.end());
1008     auto producer = bufferQueueMap_[trackId];
1009     auto listener = trackMap_[trackId]->GetProducerListener();
1010     producer->SetBufferAvailableListener(listener);
1011 }
1012 
HandleDashSelectTrack(int32_t trackId)1013 Status MediaDemuxer::HandleDashSelectTrack(int32_t trackId)
1014 {
1015     MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
1016     eosMap_[trackId] = false;
1017     requestBufferErrorCountMap_[trackId] = 0;
1018 
1019     int32_t targetStreamID = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
1020     if (targetStreamID == -1) {
1021         MEDIA_LOG_E("Get stream failed");
1022         return Status::ERROR_UNKNOWN;
1023     }
1024 
1025     int32_t curTrackId = -1;
1026     TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1027     if (trackType == TrackType::TRACK_AUDIO) {
1028         curTrackId = static_cast<int32_t>(audioTrackId_);
1029     } else if (trackType == TrackType::TRACK_VIDEO) {
1030         curTrackId = static_cast<int32_t>(videoTrackId_);
1031     } else if (trackType == TrackType::TRACK_SUBTITLE) {
1032         curTrackId = static_cast<int32_t>(subtitleTrackId_);
1033     } else {   // invalid
1034         MEDIA_LOG_E("Track type invalid");
1035         return Status::ERROR_UNKNOWN;
1036     }
1037 
1038     if (trackId == curTrackId || targetStreamID != demuxerPluginManager_->GetTmpStreamIDByTrackID(curTrackId)) {
1039         MEDIA_LOG_I("Select stream");
1040         {
1041             std::lock_guard<std::mutex> lock(isSelectTrackMutex_);
1042             inSelectTrackType_[static_cast<int32_t>(trackType)] = trackId;
1043         }
1044         return source_->SelectStream(targetStreamID);
1045     }
1046 
1047     // same streamID
1048     Status ret = DoSelectTrack(trackId, curTrackId);
1049     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "DoSelectTrack track failed");
1050     if (eventReceiver_ != nullptr) {
1051         if (trackType == TrackType::TRACK_AUDIO) {
1052             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, trackId});
1053             audioTrackId_ = static_cast<uint32_t>(trackId);
1054         } else if (trackType == TrackType::TRACK_VIDEO) {
1055             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, trackId});
1056             videoTrackId_ = static_cast<uint32_t>(trackId);
1057         } else if (trackType == TrackType::TRACK_SUBTITLE) {
1058             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_SUBTITLE_TRACK_CHANGE, trackId});
1059             subtitleTrackId_ = static_cast<uint32_t>(trackId);
1060         } else {}
1061     }
1062     return Status::OK;
1063 }
1064 
DoSelectTrack(int32_t trackId,int32_t curTrackId)1065 Status MediaDemuxer::DoSelectTrack(int32_t trackId, int32_t curTrackId)
1066 {
1067     if (static_cast<uint32_t>(curTrackId) != TRACK_ID_DUMMY) {
1068         if (taskMap_.find(curTrackId) != taskMap_.end() && taskMap_[curTrackId] != nullptr) {
1069             taskMap_[curTrackId]->Stop();
1070         }
1071         if (sampleConsumerTaskMap_.find(curTrackId) != sampleConsumerTaskMap_.end() &&
1072             sampleConsumerTaskMap_[curTrackId] != nullptr) {
1073             sampleConsumerTaskMap_[curTrackId]->Stop();
1074         }
1075         Status ret = UnselectTrack(curTrackId);
1076         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Unselect track failed");
1077         bufferQueueMap_.insert(
1078             std::pair<uint32_t, sptr<AVBufferQueueProducer>>(trackId, bufferQueueMap_[curTrackId]));
1079         bufferMap_.insert(std::pair<uint32_t, std::shared_ptr<AVBuffer>>(trackId, bufferMap_[curTrackId]));
1080         bufferQueueMap_.erase(curTrackId);
1081         bufferMap_.erase(curTrackId);
1082         demuxerPluginManager_->UpdateTempTrackMapInfo(trackId, trackId, -1);
1083 
1084         sampleQueueMap_.insert(
1085             std::pair<uint32_t, std::shared_ptr<SampleQueue>>(trackId, sampleQueueMap_[curTrackId]));
1086         sampleQueueMap_.erase(curTrackId);
1087         if (sampleQueueMap_[trackId] != nullptr) {
1088             sampleQueueMap_[trackId]->UpdateQueueId(trackId);
1089         }
1090         return InnerSelectTrack(trackId);
1091     }
1092     return Status::ERROR_UNKNOWN;
1093 }
1094 
HandleSelectTrack(int32_t trackId)1095 Status MediaDemuxer::HandleSelectTrack(int32_t trackId)
1096 {
1097     int32_t curTrackId = -1;
1098     TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1099     if (trackType == TrackType::TRACK_AUDIO) {
1100         MEDIA_LOG_I("Select audio [" PUBLIC_LOG_D32 "->" PUBLIC_LOG_D32 "]", audioTrackId_, trackId);
1101         curTrackId = static_cast<int32_t>(audioTrackId_);
1102     } else {    // inner subtitle and video not support
1103         MEDIA_LOG_W("Unsupport track " PUBLIC_LOG_D32, trackId);
1104         return Status::ERROR_INVALID_PARAMETER;
1105     }
1106 
1107     if (curTrackId == trackId) {
1108         return Status::OK;
1109     }
1110 
1111     Status ret = DoSelectTrack(trackId, curTrackId);
1112     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "DoSelectTrack track failed");
1113     if (eventReceiver_ != nullptr) {
1114         if (trackType == TrackType::TRACK_AUDIO) {
1115             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, trackId});
1116             audioTrackId_ =  static_cast<uint32_t>(trackId);
1117         } else if (trackType == TrackType::TRACK_VIDEO) {
1118             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, trackId});
1119             videoTrackId_ =  static_cast<uint32_t>(trackId);
1120         } else {}
1121     }
1122 
1123     return ret;
1124 }
1125 
SelectTrack(int32_t trackId)1126 Status MediaDemuxer::SelectTrack(int32_t trackId)
1127 {
1128     MediaAVCodec::AVCODEC_SYNC_TRACE;
1129     MEDIA_LOG_D("Select " PUBLIC_LOG_D32, trackId);
1130     FALSE_RETURN_V_MSG_E(trackId >= 0 && (uint32_t)trackId < mediaMetaData_.trackMetas.size(),
1131         Status::ERROR_INVALID_PARAMETER, "Select track failed");
1132     if (!useBufferQueue_) {
1133         return InnerSelectTrack(trackId);
1134     }
1135     if (demuxerPluginManager_->IsDash()) {
1136         if (streamDemuxer_->CanDoChangeStream() == false) {
1137             MEDIA_LOG_W("Wrong state: selecting");
1138             return Status::ERROR_WRONG_STATE;
1139         }
1140         return HandleDashSelectTrack(trackId);
1141     }
1142     return HandleSelectTrack(trackId);
1143 }
1144 
UnselectTrack(int32_t trackId)1145 Status MediaDemuxer::UnselectTrack(int32_t trackId)
1146 {
1147     MediaAVCodec::AVCODEC_SYNC_TRACE;
1148     MEDIA_LOG_D("Unselect " PUBLIC_LOG_D32, trackId);
1149 
1150     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
1151     int32_t innerTrackID = trackId;
1152     if (IsNeedMapToInnerTrackID()) {
1153         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1154         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
1155         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1156         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
1157     } else {
1158         int32_t streamID = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
1159         if (streamID == -1) {
1160             MEDIA_LOG_W("Invalid track " PUBLIC_LOG_D32, trackId);
1161             return Status::OK;
1162         }
1163         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
1164         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1165     }
1166     demuxerPluginManager_->DeleteTempTrackMapInfo(trackId);
1167 
1168     return pluginTemp->UnselectTrack(innerTrackID);
1169 }
1170 
HandleHlsRebootPlugin()1171 Status MediaDemuxer::HandleHlsRebootPlugin()
1172 {
1173     MEDIA_LOG_D("In");
1174     StreamType streamType = StreamType::MIXED;
1175     TrackType trackType = videoTrackId_ != TRACK_ID_DUMMY ? TrackType::TRACK_VIDEO : TrackType::TRACK_AUDIO;
1176     int32_t trackId = videoTrackId_ != TRACK_ID_DUMMY ? static_cast<int32_t>(videoTrackId_)
1177                                         : static_cast<int32_t>(audioTrackId_);
1178     FALSE_RETURN_V(!subStreamDemuxer_ || trackId != static_cast<int32_t>(subtitleTrackId_), Status::OK);
1179     Status ret = Status::OK;
1180     if (static_cast<uint32_t>(trackId) != TRACK_ID_DUMMY) {
1181         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1182         FALSE_RETURN_V_MSG_E(streamID != INVALID_STREAM_OR_TRACK_ID, Status::ERROR_INVALID_PARAMETER,
1183             "Invalid streamId");
1184         std::pair<int32_t, bool> seekReadyInfo;
1185         {
1186             std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1187             if (!isInterruptNeeded_.load() &&
1188                 seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) == seekReadyStreamInfo_.end()) {
1189                 rebootPluginCondition_.wait(lock, [this, streamType] {
1190                     return isInterruptNeeded_.load() ||
1191                         seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) != seekReadyStreamInfo_.end();
1192                 });
1193             }
1194             FALSE_RETURN_V(!isInterruptNeeded_.load(), Status::OK);
1195             seekReadyInfo = seekReadyStreamInfo_[static_cast<int32_t>(streamType)];
1196             seekReadyStreamInfo_.erase(static_cast<int32_t>(streamType));
1197         }
1198         if (seekReadyInfo.second == SEEK_TO_EOS) {
1199             MEDIA_LOG_I("Seek to eos");
1200             return Status::OK;
1201         } else if (seekReadyInfo.first >= 0 && seekReadyInfo.first != streamID) {
1202             return HandleSeekChangeStream(streamID, seekReadyInfo.first, trackId);
1203         }
1204         bool isRebooted = true;
1205         ret = demuxerPluginManager_->RebootPlugin(streamID, trackType, streamDemuxer_, isRebooted);
1206         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot demuxer plugin failed");
1207     }
1208     Status audioRet = audioTrackId_ != TRACK_ID_DUMMY ?
1209         InnerSelectTrack(static_cast<int32_t>(audioTrackId_)) : Status::OK;
1210     Status videoRet = videoTrackId_ != TRACK_ID_DUMMY ?
1211         InnerSelectTrack(static_cast<int32_t>(videoTrackId_)) : Status::OK;
1212     ret = audioRet == Status::OK ? videoRet : audioRet;
1213     {
1214         std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1215         seekReadyStreamInfo_.clear();
1216     }
1217     return ret;
1218 }
1219 
HandleSeekChangeStream(int32_t currentStreamId,int32_t newStreamId,int32_t trackId)1220 Status MediaDemuxer::HandleSeekChangeStream(int32_t currentStreamId, int32_t newStreamId, int32_t trackId)
1221 {
1222     MEDIA_LOG_I("streamID changed, streamId: " PUBLIC_LOG_D32 ", newStreamId: " PUBLIC_LOG_D32,
1223         currentStreamId, newStreamId);
1224     // only fix completed seek currently
1225     if (streamDemuxer_ != nullptr && HasEosTrack()) {
1226         streamDemuxer_->SetNewVideoStreamID(newStreamId);
1227         HandleDashChangeStream(trackId);
1228     }
1229     return Status::OK;
1230 }
1231 
HandleRebootPlugin(int32_t trackId,bool & isRebooted)1232 Status MediaDemuxer::HandleRebootPlugin(int32_t trackId, bool& isRebooted)
1233 {
1234     FALSE_RETURN_V(!subStreamDemuxer_ || trackId != static_cast<int32_t>(subtitleTrackId_), Status::OK);
1235     Status ret = Status::OK;
1236     if (static_cast<uint32_t>(trackId) != TRACK_ID_DUMMY) {
1237         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1238         FALSE_RETURN_V_MSG_E(streamID != INVALID_STREAM_OR_TRACK_ID, Status::ERROR_INVALID_PARAMETER,
1239             "Invalid streamId");
1240         TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1241         MEDIA_LOG_D("TrackType " PUBLIC_LOG_D32 " TrackId " PUBLIC_LOG_D32, static_cast<int32_t>(trackType), trackId);
1242         FALSE_RETURN_V_MSG_E(trackType != TRACK_INVALID, Status::ERROR_INVALID_PARAMETER, "TrackType is invalid");
1243         StreamType streamType = TRACK_TO_STREAM_MAP[trackType];
1244         std::pair<int32_t, bool> seekReadyInfo;
1245         {
1246             std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1247             if (!isInterruptNeeded_.load() &&
1248                 seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) == seekReadyStreamInfo_.end()) {
1249                 rebootPluginCondition_.wait(lock, [this, streamType] {
1250                     return isInterruptNeeded_.load() ||
1251                         seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) != seekReadyStreamInfo_.end();
1252                 });
1253             }
1254             FALSE_RETURN_V(!isInterruptNeeded_.load(), Status::OK);
1255             seekReadyInfo = seekReadyStreamInfo_[static_cast<int32_t>(streamType)];
1256             seekReadyStreamInfo_.erase(static_cast<int32_t>(streamType));
1257         }
1258         if (seekReadyInfo.second == SEEK_TO_EOS || (seekReadyInfo.first >= 0 && seekReadyInfo.first != streamID)) {
1259             MEDIA_LOG_I("End of stream or streamID changed, isEOS: " PUBLIC_LOG_D32 ", streamId: " PUBLIC_LOG_D32,
1260                 seekReadyInfo.second, seekReadyInfo.first);
1261             return Status::OK;
1262         }
1263         ret = demuxerPluginManager_->RebootPlugin(streamID, trackType, streamDemuxer_, isRebooted);
1264         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot demuxer plugin failed");
1265         ret = InnerSelectTrack(trackId);
1266     }
1267     return ret;
1268 }
1269 
SeekToTimeAfter()1270 Status MediaDemuxer::SeekToTimeAfter()
1271 {
1272     FALSE_RETURN_V_NOLOG(demuxerPluginManager_ != nullptr && demuxerPluginManager_->IsDash(), Status::OK);
1273     MEDIA_LOG_D("Reboot plugin begin");
1274     if (isHlsFmp4_) {
1275         return HandleHlsRebootPlugin();
1276     }
1277     Status ret = Status::OK;
1278     bool isDemuxerPluginRebooted = true;
1279     ret = HandleRebootPlugin(subtitleTrackId_, isDemuxerPluginRebooted);
1280     if (shouldCheckSubtitleFramePts_) {
1281         shouldCheckSubtitleFramePts_ = false;
1282     }
1283     FALSE_LOG_MSG_W(ret == Status::OK, "Reboot subtitle demuxer plugin failed");
1284 
1285     isDemuxerPluginRebooted = true;
1286     ret = HandleRebootPlugin(audioTrackId_, isDemuxerPluginRebooted);
1287     if (shouldCheckAudioFramePts_) {
1288         shouldCheckAudioFramePts_ = false;
1289     }
1290     FALSE_LOG_MSG_W(ret == Status::OK, "Reboot audio demuxer plugin failed");
1291 
1292     isDemuxerPluginRebooted = true;
1293     ret = HandleRebootPlugin(videoTrackId_, isDemuxerPluginRebooted);
1294     {
1295         std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1296         seekReadyStreamInfo_.clear();
1297     }
1298     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot video demuxer plugin failed");
1299     MEDIA_LOG_D("Reboot plugin success");
1300     return Status::OK;
1301 }
1302 
SeekTo(int64_t seekTime,Plugins::SeekMode mode,int64_t & realSeekTime)1303 Status MediaDemuxer::SeekTo(int64_t seekTime, Plugins::SeekMode mode, int64_t& realSeekTime)
1304 {
1305     MediaAVCodec::AVCODEC_SYNC_TRACE;
1306     Status ret;
1307     isSeekError_.store(false);
1308     if (source_ != nullptr && source_->IsSeekToTimeSupported()) {
1309         MEDIA_LOG_D("Source seek");
1310         if (mode == SeekMode::SEEK_CLOSEST_INNER) {
1311             ret = source_->SeekToTime(seekTime, SeekMode::SEEK_PREVIOUS_SYNC);
1312         } else {
1313             ret = source_->SeekToTime(seekTime, SeekMode::SEEK_CLOSEST_SYNC);
1314         }
1315         if (subtitleSource_) {
1316             demuxerPluginManager_->localSubtitleSeekTo(seekTime);
1317         }
1318         SeekToTimeAfter();
1319         Plugins::Ms2HstTime(seekTime, realSeekTime);
1320     } else {
1321         MEDIA_LOG_D("Demuxer seek");
1322         if (mode == SeekMode::SEEK_CLOSEST_INNER) {
1323             ret = demuxerPluginManager_->SeekTo(seekTime, SeekMode::SEEK_PREVIOUS_SYNC, realSeekTime);
1324         } else {
1325             ret = demuxerPluginManager_->SeekTo(seekTime, mode, realSeekTime);
1326         }
1327     }
1328     isSeeked_ = true;
1329     for (auto item : eosMap_) {
1330         eosMap_[item.first] = false;
1331     }
1332     for (auto item : requestBufferErrorCountMap_) {
1333         requestBufferErrorCountMap_[item.first] = 0;
1334     }
1335     if (ret != Status::OK) {
1336         isSeekError_.store(true);
1337     }
1338     isFirstFrameAfterSeek_.store(true);
1339     MEDIA_LOG_D("Out");
1340     return ret;
1341 }
1342 
SelectBitRate(uint32_t bitRate)1343 Status MediaDemuxer::SelectBitRate(uint32_t bitRate)
1344 {
1345     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Source is nullptr");
1346     MEDIA_LOG_I("In");
1347 
1348     if (isFlvLiveStream_ && IsRightMediaTrack(videoTrackId_, DemuxerTrackType::VIDEO)) {
1349         auto sqIt = sampleQueueMap_.find(videoTrackId_);
1350         FALSE_RETURN_V_MSG_E(sqIt != sampleQueueMap_.end() && sqIt->second, Status::ERROR_WRONG_STATE,
1351             "sampleQueue is nullptr");
1352         return sqIt->second->ReadySwitchBitrate(bitRate);
1353     }
1354     if (demuxerPluginManager_->IsDash()) {
1355         if (streamDemuxer_->CanDoChangeStream() == false) {
1356             MEDIA_LOG_W("Wrong state: selecting");
1357             return Status::OK;
1358         }
1359         if (bitRate == demuxerPluginManager_->GetCurrentBitRate()) {
1360             MEDIA_LOG_W("Same bitrate");
1361             return Status::OK;
1362         }
1363         isSelectBitRate_.store(true);
1364     } else {
1365         streamDemuxer_->ResetAllCache();
1366     }
1367 
1368     Status ret = source_->SelectBitRate(bitRate);
1369     if (ret != Status::OK) {
1370         MEDIA_LOG_E("Source select bitrate failed");
1371         if (demuxerPluginManager_->IsDash()) {
1372             isSelectBitRate_.store(false);
1373         }
1374     }
1375     targetBitRate_ = bitRate;
1376     MEDIA_LOG_I("Out");
1377     return ret;
1378 }
1379 
StopBufferring(bool flag)1380 Status MediaDemuxer::StopBufferring(bool flag)
1381 {
1382     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Source is nullptr");
1383     MEDIA_LOG_I("In");
1384     Status ret = source_->StopBufferring(flag);
1385     if (ret != Status::OK) {
1386         MEDIA_LOG_E("Stop buffering failed");
1387         return ret;
1388     }
1389     MEDIA_LOG_I("Out");
1390     return ret;
1391 }
1392 
GetStreamMetaInfo() const1393 std::vector<std::shared_ptr<Meta>> MediaDemuxer::GetStreamMetaInfo() const
1394 {
1395     MediaAVCodec::AVCODEC_SYNC_TRACE;
1396     return mediaMetaData_.trackMetas;
1397 }
1398 
GetGlobalMetaInfo()1399 std::shared_ptr<Meta> MediaDemuxer::GetGlobalMetaInfo()
1400 {
1401     AutoLock lock(mapMutex_);
1402     MediaAVCodec::AVCODEC_SYNC_TRACE;
1403     return mediaMetaData_.globalMeta;
1404 }
1405 
GetUserMeta()1406 std::shared_ptr<Meta> MediaDemuxer::GetUserMeta()
1407 {
1408     MediaAVCodec::AVCODEC_SYNC_TRACE;
1409     return demuxerPluginManager_->GetUserMeta();
1410 }
1411 
Flush()1412 Status MediaDemuxer::Flush()
1413 {
1414     MEDIA_LOG_I("In");
1415     ResetDraggingOpenGopCnt();
1416     if (streamDemuxer_) {
1417         streamDemuxer_->Flush();
1418     }
1419 
1420     {
1421         AutoLock lock(mapMutex_);
1422         auto it = bufferQueueMap_.begin();
1423         while (it != bufferQueueMap_.end()) {
1424             uint32_t trackId = it->first;
1425             if (trackId != videoTrackId_) {
1426                 bufferQueueMap_[trackId]->Clear();
1427             }
1428             it++;
1429         }
1430 
1431         auto sqIt = sampleQueueMap_.begin();
1432         while (sqIt != sampleQueueMap_.end()) {
1433             uint32_t trackId = sqIt->first;
1434             if (trackId != videoTrackId_) {
1435                 sampleQueueMap_[trackId]->Clear();
1436             }
1437             sqIt++;
1438         }
1439     }
1440 
1441     if (demuxerPluginManager_) {
1442         if (source_ != nullptr && source_->IsSeekToTimeSupported()) {
1443             demuxerPluginManager_->SetResetEosStatus(true);
1444         }
1445         demuxerPluginManager_->Flush();
1446     }
1447 
1448     InitPtsInfo();
1449     return Status::OK;
1450 }
1451 
StopAllTask()1452 Status MediaDemuxer::StopAllTask()
1453 {
1454     MEDIA_LOG_I("In");
1455     AutoLock lock(mapMutex_);
1456     isDemuxerLoopExecuting_ = false;
1457     if (streamDemuxer_ != nullptr) {
1458         streamDemuxer_->SetIsIgnoreParse(true);
1459     }
1460     auto it = taskMap_.begin();
1461     while (it != taskMap_.end()) {
1462         if (it->second != nullptr) {
1463             it->second->Stop();
1464             it->second = nullptr;
1465         }
1466         it = taskMap_.erase(it);
1467     }
1468     for (auto stIt = sampleConsumerTaskMap_.begin(); stIt != sampleConsumerTaskMap_.end();) {
1469         if (stIt->second != nullptr) {
1470             stIt->second->Stop();
1471         }
1472         stIt = sampleConsumerTaskMap_.erase(stIt);
1473     }
1474     isThreadExit_ = true;
1475     MEDIA_LOG_I("Out");
1476     return Status::OK;
1477 }
1478 
PauseAllTask()1479 Status MediaDemuxer::PauseAllTask()
1480 {
1481     MEDIA_LOG_I("In");
1482     isDemuxerLoopExecuting_ = false;
1483     for (auto &iter : taskMap_) {
1484         if (iter.second != nullptr) {
1485             iter.second->Pause();
1486         }
1487     }
1488 
1489     for (auto &iter : sampleConsumerTaskMap_) {
1490         if (iter.second != nullptr) {
1491             iter.second->Pause();
1492         }
1493     }
1494     MEDIA_LOG_I("Out");
1495     return Status::OK;
1496 }
1497 
PauseAllTaskAsync()1498 Status MediaDemuxer::PauseAllTaskAsync()
1499 {
1500     MEDIA_LOG_I("In");
1501     // To accelerate DemuxerLoop thread to run into PAUSED state
1502     for (auto &iter : taskMap_) {
1503         if (iter.second != nullptr) {
1504             iter.second->PauseAsync();
1505         }
1506     }
1507     for (auto &iter : sampleConsumerTaskMap_) {
1508         if (iter.second != nullptr) {
1509             iter.second->PauseAsync();
1510         }
1511     }
1512     MEDIA_LOG_I("Out");
1513     return Status::OK;
1514 }
1515 
ResumeAllTask()1516 Status MediaDemuxer::ResumeAllTask()
1517 {
1518     MEDIA_LOG_I("In");
1519     isDemuxerLoopExecuting_ = true;
1520     streamDemuxer_->SetIsIgnoreParse(false);
1521 
1522     auto it = bufferQueueMap_.begin();
1523     while (it != bufferQueueMap_.end()) {
1524         uint32_t trackId = it->first;
1525         if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
1526             taskMap_[trackId]->Start();
1527         } else {
1528             MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " task is not exist", trackId);
1529         }
1530         auto sampleConsumerTaskIt = sampleConsumerTaskMap_.find(trackId);
1531         if (sampleConsumerTaskIt != sampleConsumerTaskMap_.end() && sampleConsumerTaskIt->second != nullptr) {
1532             sampleConsumerTaskIt->second->Start();
1533         } else {
1534             MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " sampleConsumerTask is not exist", trackId);
1535         }
1536         it++;
1537     }
1538     MEDIA_LOG_I("Out");
1539     return Status::OK;
1540 }
1541 
Pause()1542 Status MediaDemuxer::Pause()
1543 {
1544     MEDIA_LOG_I("In");
1545     isPaused_ = true;
1546     if (streamDemuxer_) {
1547         streamDemuxer_->SetIsIgnoreParse(true);
1548         streamDemuxer_->Pause();
1549     }
1550     if (source_) {
1551         source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1552         source_->Pause();
1553     }
1554     if (inPreroll_.load()) {
1555         if (CheckTrackEnabledById(videoTrackId_)) {
1556             taskMap_[videoTrackId_]->PauseAsync();
1557             taskMap_[videoTrackId_]->Pause();
1558             sampleConsumerTaskMap_[videoTrackId_]->PauseAsync();
1559             sampleConsumerTaskMap_[videoTrackId_]->Pause();
1560         }
1561     } else {
1562         PauseAllTaskAsync();
1563         PauseAllTask();
1564     }
1565     if (source_ != nullptr) {
1566         source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1567     }
1568     return Status::OK;
1569 }
1570 
PauseDragging()1571 Status MediaDemuxer::PauseDragging()
1572 {
1573     MEDIA_LOG_I("In");
1574     isPaused_ = true;
1575     if (streamDemuxer_) {
1576         streamDemuxer_->SetIsIgnoreParse(true);
1577         streamDemuxer_->Pause();
1578     }
1579     if (source_) {
1580         source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1581         source_->Pause();
1582     }
1583     if (CheckTrackEnabledById(videoTrackId_)) {
1584             taskMap_[videoTrackId_]->PauseAsync();
1585             taskMap_[videoTrackId_]->Pause();
1586             sampleConsumerTaskMap_[videoTrackId_]->PauseAsync();
1587             sampleConsumerTaskMap_[videoTrackId_]->Pause();
1588     }
1589 
1590     if (source_ != nullptr) {
1591         source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1592     }
1593     return Status::OK;
1594 }
1595 
PauseAudioAlign()1596 Status MediaDemuxer::PauseAudioAlign()
1597 {
1598     MEDIA_LOG_I("PauseDragging");
1599     isPaused_ = true;
1600     if (streamDemuxer_) {
1601         streamDemuxer_->SetIsIgnoreParse(true);
1602         streamDemuxer_->Pause();
1603     }
1604     if (source_) {
1605         source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1606         source_->Pause();
1607     }
1608     if (CheckTrackEnabledById(audioTrackId_)) {
1609             taskMap_[audioTrackId_]->PauseAsync();
1610             taskMap_[audioTrackId_]->Pause();
1611             sampleConsumerTaskMap_[audioTrackId_]->PauseAsync();
1612             sampleConsumerTaskMap_[audioTrackId_]->Pause();
1613     }
1614 
1615     if (source_ != nullptr) {
1616         source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1617     }
1618     return Status::OK;
1619 }
1620 
PauseTaskByTrackId(int32_t trackId)1621 Status MediaDemuxer::PauseTaskByTrackId(int32_t trackId)
1622 {
1623     MEDIA_LOG_I("In, track %{public}d", trackId);
1624     FALSE_RETURN_V_MSG_E(trackId >= 0, Status::ERROR_INVALID_PARAMETER, "Invalid track");
1625 
1626     // To accelerate DemuxerLoop thread to run into PAUSED state
1627     if (CheckTrackEnabledById(trackId)) {
1628             taskMap_[trackId]->PauseAsync();
1629             taskMap_[trackId]->Pause();
1630             sampleConsumerTaskMap_[trackId]->PauseAsync();
1631             sampleConsumerTaskMap_[trackId]->Pause();
1632     }
1633     return Status::OK;
1634 }
1635 
Resume()1636 Status MediaDemuxer::Resume()
1637 {
1638     MEDIA_LOG_I("In");
1639     if (streamDemuxer_) {
1640         streamDemuxer_->Resume();
1641     }
1642     if (source_) {
1643         source_->Resume();
1644     }
1645     if (inPreroll_.load()) {
1646         if (CheckTrackEnabledById(videoTrackId_)) {
1647             if (streamDemuxer_) {
1648                 streamDemuxer_->SetIsIgnoreParse(false);
1649             }
1650             taskMap_[videoTrackId_]->Start();
1651             sampleConsumerTaskMap_[videoTrackId_]->Start();
1652         }
1653     } else {
1654         ResumeAllTask();
1655     }
1656     isPaused_ = false;
1657     return Status::OK;
1658 }
1659 
ResumeDragging()1660 Status MediaDemuxer::ResumeDragging()
1661 {
1662     MEDIA_LOG_I("In");
1663     ResetDraggingOpenGopCnt();
1664     for (auto item : eosMap_) {
1665         eosMap_[item.first] = false;
1666     }
1667     if (streamDemuxer_) {
1668         streamDemuxer_->Resume();
1669     }
1670     if (source_) {
1671         source_->Resume();
1672     }
1673     if (CheckTrackEnabledById(videoTrackId_)) {
1674         if (streamDemuxer_) {
1675             streamDemuxer_->SetIsIgnoreParse(false);
1676         }
1677         taskMap_[videoTrackId_]->Start();
1678         sampleConsumerTaskMap_[videoTrackId_]->Start();
1679     }
1680     isPaused_ = false;
1681     return Status::OK;
1682 }
1683 
ResumeAudioAlign()1684 Status MediaDemuxer::ResumeAudioAlign()
1685 {
1686     MEDIA_LOG_I("ResumeAudioAlign");
1687     {
1688         AutoLock lock(mapMutex_);
1689         auto it = bufferQueueMap_.begin();
1690         while (it != bufferQueueMap_.end()) {
1691             uint32_t trackId = it->first;
1692             if (trackId == audioTrackId_) {
1693                 bufferQueueMap_[trackId]->Clear();
1694             }
1695             it++;
1696         }
1697     }
1698     if (streamDemuxer_) {
1699         streamDemuxer_->Resume();
1700     }
1701     if (source_) {
1702         source_->Resume();
1703     }
1704     if (CheckTrackEnabledById(audioTrackId_)) {
1705         if (streamDemuxer_) {
1706             streamDemuxer_->SetIsIgnoreParse(false);
1707         }
1708         taskMap_[audioTrackId_]->Start();
1709         sampleConsumerTaskMap_[audioTrackId_]->Start();
1710     }
1711     isPaused_ = false;
1712     return Status::OK;
1713 }
1714 
ResetInner()1715 void MediaDemuxer::ResetInner()
1716 {
1717     std::map<uint32_t, std::shared_ptr<TrackWrapper>> trackMap;
1718     {
1719         AutoLock lock(mapMutex_);
1720         mediaMetaData_.globalMeta.reset();
1721         mediaMetaData_.trackMetas.clear();
1722     }
1723     Stop();
1724     {
1725         AutoLock lock(mapMutex_);
1726         std::swap(trackMap, trackMap_);
1727         bufferQueueMap_.clear();
1728         bufferMap_.clear();
1729         sampleQueueMap_.clear();
1730         localDrmInfos_.clear();
1731     }
1732     // Should perform trackMap_ clear without holding mapMutex_ to avoid dead lock:
1733     // 1. TrackWrapper indirectly holds notifyTask which holds its jobMutex_ firstly when run, then requires mapMutex_.
1734     // 2. Release notifyTask also needs hold its jobMutex_ firstly.
1735     trackMap.clear();
1736 }
1737 
Reset()1738 Status MediaDemuxer::Reset()
1739 {
1740     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Reset");
1741     FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1742     isDemuxerLoopExecuting_ = false;
1743     ResetInner();
1744     for (auto item : eosMap_) {
1745         eosMap_[item.first] = false;
1746     }
1747     for (auto item : requestBufferErrorCountMap_) {
1748         requestBufferErrorCountMap_[item.first] = 0;
1749     }
1750     videoStartTime_ = 0;
1751     streamDemuxer_->ResetAllCache();
1752     isSeekError_.store(false);
1753     return demuxerPluginManager_->Reset();
1754 }
1755 
Start()1756 Status MediaDemuxer::Start()
1757 {
1758     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Start");
1759     MEDIA_LOG_I("In");
1760     FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1761     FALSE_RETURN_V_MSG_E(isThreadExit_, Status::OK, "Process has been started already");
1762     FALSE_RETURN_V_MSG_E(bufferQueueMap_.size() != 0, Status::OK, "No buffer queue");
1763     for (auto it = eosMap_.begin(); it != eosMap_.end(); it++) {
1764         it->second = false;
1765     }
1766     for (auto it = requestBufferErrorCountMap_.begin(); it != requestBufferErrorCountMap_.end(); it++) {
1767         it->second = 0;
1768     }
1769     InitPtsInfo();
1770     {
1771         std::unique_lock<std::mutex> stopLock(stopMutex_);
1772         isThreadExit_ = false;
1773         isStopped_ = false;
1774     }
1775     isDemuxerLoopExecuting_ = true;
1776     if (inPreroll_.load()) {
1777         if (CheckTrackEnabledById(videoTrackId_)) {
1778             taskMap_[videoTrackId_]->Start();
1779             sampleConsumerTaskMap_[videoTrackId_]->Start();
1780         }
1781     } else {
1782         auto it = bufferQueueMap_.begin();
1783         while (it != bufferQueueMap_.end()) {
1784             uint32_t trackId = it->first;
1785             if (CheckTrackEnabledById(trackId)) {
1786                 taskMap_[trackId]->Start();
1787                 sampleConsumerTaskMap_[trackId]->Start();
1788             } else {
1789                 MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " task is not exist", trackId);
1790             }
1791             it++;
1792         }
1793     }
1794     source_->Start();
1795     return demuxerPluginManager_->Start();
1796 }
1797 
Preroll()1798 Status MediaDemuxer::Preroll()
1799 {
1800     std::lock_guard<std::mutex> lock(prerollMutex_);
1801     if (inPreroll_.load()) {
1802         return Status::OK;
1803     }
1804     if (!CheckTrackEnabledById(videoTrackId_)) {
1805         return Status::OK;
1806     }
1807     inPreroll_.store(true);
1808     MEDIA_LOG_D("Preroll enter.");
1809     Status ret = Status::OK;
1810     if (isStopped_.load()) {
1811         ret = Start();
1812     } else if (isPaused_.load()) {
1813         ret = Resume();
1814     }
1815     if (ret != Status::OK) {
1816         inPreroll_.store(false);
1817         MEDIA_LOG_E("Preroll failed, ret: %{public}d", ret);
1818     }
1819     return ret;
1820 }
1821 
PausePreroll()1822 Status MediaDemuxer::PausePreroll()
1823 {
1824     std::lock_guard<std::mutex> lock(prerollMutex_);
1825     if (!inPreroll_.load()) {
1826         return Status::OK;
1827     }
1828     MEDIA_LOG_D("Preroll enter.");
1829     Status ret = Pause();
1830     inPreroll_.store(false);
1831     return ret;
1832 }
1833 
Stop()1834 Status MediaDemuxer::Stop()
1835 {
1836     MEDIA_LOG_I("In");
1837     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Stop");
1838     FALSE_RETURN_V_MSG_E(!isThreadExit_, Status::OK, "Thread exit");
1839     if (useBufferQueue_) {
1840         FALSE_RETURN_V_MSG_E(!isStopped_, Status::OK, "Process has been stopped already, ignore");
1841         {
1842             std::unique_lock<std::mutex> stopLock(stopMutex_);
1843             isStopped_ = true;
1844         }
1845         StopAllTask();
1846     }
1847     if (source_ != nullptr) {
1848         source_->Stop();
1849     }
1850     if (streamDemuxer_) {
1851         streamDemuxer_->Stop();
1852     }
1853     if (demuxerPluginManager_) {
1854         demuxerPluginManager_->Stop();
1855     }
1856     return Status::OK;
1857 }
1858 
HasVideo()1859 bool MediaDemuxer::HasVideo()
1860 {
1861     return videoTrackId_ != TRACK_ID_DUMMY;
1862 }
1863 
InitMediaMetaData(const Plugins::MediaInfo & mediaInfo)1864 void MediaDemuxer::InitMediaMetaData(const Plugins::MediaInfo& mediaInfo)
1865 {
1866     AutoLock lock(mapMutex_);
1867     mediaMetaData_.globalMeta = std::make_shared<Meta>(mediaInfo.general);
1868     if (mediaMetaData_.globalMeta != nullptr && mediaMetaData_.globalMeta->GetData(Tag::MEDIA_FILE_TYPE, fileType_)) {
1869         MEDIA_LOG_D("FileType " PUBLIC_LOG_D32, static_cast<int32_t>(fileType_));
1870     }
1871     mediaMetaData_.trackMetas.clear();
1872     mediaMetaData_.trackMetas.reserve(mediaInfo.tracks.size());
1873     for (uint32_t index = 0; index < mediaInfo.tracks.size(); index++) {
1874         auto trackMeta = mediaInfo.tracks[index];
1875         mediaMetaData_.trackMetas.emplace_back(std::make_shared<Meta>(trackMeta));
1876     }
1877 }
1878 
InitDefaultTrack(const Plugins::MediaInfo & mediaInfo,uint32_t & videoTrackId,uint32_t & audioTrackId,uint32_t & subtitleTrackId,std::string & videoMime)1879 void MediaDemuxer::InitDefaultTrack(const Plugins::MediaInfo& mediaInfo, uint32_t& videoTrackId,
1880     uint32_t& audioTrackId, uint32_t& subtitleTrackId, std::string& videoMime)
1881 {
1882     AutoLock lock(mapMutex_);
1883     std::string dafaultTrack = "[";
1884     for (uint32_t index = 0; index < mediaInfo.tracks.size(); index++) {
1885         if (demuxerPluginManager_->CheckTrackIsActive(index) == false) {
1886             continue;
1887         }
1888         auto trackMeta = mediaInfo.tracks[index];
1889         std::string mimeType;
1890         bool ret = trackMeta.Get<Tag::MIME_TYPE>(mimeType);
1891         if (ret) {
1892             MEDIA_LOG_D("mimeType: " PUBLIC_LOG_S ", index: " PUBLIC_LOG_U32, mimeType.c_str(), index);
1893         }
1894         if (ret && mimeType.find("video") == 0 &&
1895             !IsTrackDisabled(Plugins::MediaType::VIDEO)) {
1896             dafaultTrack += "/V:";
1897             dafaultTrack += std::to_string(index);
1898             videoMime = mimeType;
1899             if (videoTrackId == TRACK_ID_DUMMY) {
1900                 videoTrackId = index;
1901             }
1902             if (!trackMeta.GetData(Tag::MEDIA_START_TIME, videoStartTime_)) {
1903                 MEDIA_LOG_W("Get media start time failed");
1904             }
1905         } else if (ret && mimeType.find("audio") == 0 &&
1906             !IsTrackDisabled(Plugins::MediaType::AUDIO)) {
1907             dafaultTrack += "/A:";
1908             dafaultTrack += std::to_string(index);
1909             if (audioTrackId == TRACK_ID_DUMMY) {
1910                 audioTrackId = index;
1911             }
1912         } else if (ret && IsSubtitleMime(mimeType) &&
1913             !IsTrackDisabled(Plugins::MediaType::SUBTITLE)) {
1914             dafaultTrack += "/S:";
1915             dafaultTrack += std::to_string(index);
1916             if (subtitleTrackId == TRACK_ID_DUMMY) {
1917                 subtitleTrackId = index;
1918             }
1919         } else {}
1920     }
1921     dafaultTrack += "]";
1922     MEDIA_LOG_I(PUBLIC_LOG_S, dafaultTrack.c_str());
1923 }
1924 
IsOffsetValid(int64_t offset) const1925 bool MediaDemuxer::IsOffsetValid(int64_t offset) const
1926 {
1927     if (seekable_ == Plugins::Seekable::SEEKABLE) {
1928         return mediaDataSize_ == 0 || offset <= static_cast<int64_t>(mediaDataSize_);
1929     }
1930     return true;
1931 }
1932 
GetBufferFromUserQueue(uint32_t queueIndex,uint32_t size)1933 bool MediaDemuxer::GetBufferFromUserQueue(uint32_t queueIndex, uint32_t size)
1934 {
1935     MEDIA_LOG_D("In, queue: " PUBLIC_LOG_U32 ", size: " PUBLIC_LOG_U32, queueIndex, size);
1936     FALSE_RETURN_V_MSG_E(sampleQueueMap_.count(queueIndex) > 0 && sampleQueueMap_[queueIndex] != nullptr, false,
1937         "sampleQueue " PUBLIC_LOG_D32 " is nullptr", queueIndex);
1938 
1939     AVBufferConfig avBufferConfig;
1940     avBufferConfig.capacity = static_cast<int32_t>(size) + SAMPLE_BUFFER_SIZE_EXTRA;
1941     avBufferConfig.size = static_cast<int32_t>(size);
1942     Status ret = sampleQueueMap_[queueIndex]->RequestBuffer(bufferMap_[queueIndex], avBufferConfig,
1943         REQUEST_BUFFER_TIMEOUT);
1944     if (ret != Status::OK) {
1945         requestBufferErrorCountMap_[queueIndex]++;
1946         if (requestBufferErrorCountMap_[queueIndex] % 5 == 0) { // log per 5 times fail
1947             MEDIA_LOG_W("Request buffer failed, queue: " PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32
1948                 ", errorCnt:" PUBLIC_LOG_U32, queueIndex, (int32_t)(ret), requestBufferErrorCountMap_[queueIndex]);
1949         }
1950         if (requestBufferErrorCountMap_[queueIndex] >= REQUEST_FAILED_RETRY_TIMES) {
1951             MEDIA_LOG_E("Request failed too many times in 1min");
1952         }
1953     } else {
1954         requestBufferErrorCountMap_[queueIndex] = 0;
1955         MEDIA_LOG_I("RequestBuffer from samplequeue trackId=" PUBLIC_LOG_U32 ",size=" PUBLIC_LOG_U32, queueIndex, size);
1956     }
1957     return ret == Status::OK;
1958 }
1959 
HandleSelectTrackStreamSeek(int32_t streamID,int32_t & trackId)1960 void MediaDemuxer::HandleSelectTrackStreamSeek(int32_t streamID, int32_t& trackId)
1961 {
1962     int64_t startTime = 0;
1963     int64_t realSeekTime = 0;
1964     std::string mimeType;
1965     FALSE_RETURN(mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) &&
1966         mediaMetaData_.trackMetas[trackId]->Get<Tag::MEDIA_START_TIME>(startTime));
1967     if (mimeType.find("audio") == 0) {
1968         Status retSeek = demuxerPluginManager_->SingleStreamSeekTo((lastAudioPts_ - startTime) / US_TO_S,
1969             SeekMode::SEEK_CLOSEST_SYNC, streamID, realSeekTime);
1970         MEDIA_LOG_I("Audio lastAudioPts_ " PUBLIC_LOG_D64 " relativePts " PUBLIC_LOG_D64
1971             " realSeekTime " PUBLIC_LOG_D64" ret " PUBLIC_LOG_D32, lastAudioPts_,
1972             lastAudioPts_ - startTime, realSeekTime, static_cast<int32_t>(retSeek));
1973     }
1974     if (mimeType == "application/x-subrip" || mimeType == "text/vtt") {
1975         Status retSeek = demuxerPluginManager_->SingleStreamSeekTo((lastSubtitlePts_ - startTime) / US_TO_S,
1976             SeekMode::SEEK_CLOSEST_SYNC, streamID, realSeekTime);
1977         MEDIA_LOG_I("Subtitle lastSubtitlePts_ " PUBLIC_LOG_D64 " relativePts " PUBLIC_LOG_D64
1978             " realSeekTime " PUBLIC_LOG_D64 " ret " PUBLIC_LOG_D32, lastSubtitlePts_,
1979             lastSubtitlePts_ - startTime, realSeekTime, static_cast<int32_t>(retSeek));
1980     }
1981 }
1982 
HandleSelectTrackChangeStream(int32_t trackId,int32_t newStreamID,int32_t & newTrackId)1983 bool MediaDemuxer::HandleSelectTrackChangeStream(int32_t trackId, int32_t newStreamID, int32_t& newTrackId)
1984 {
1985     StreamType streamType = demuxerPluginManager_->GetStreamTypeByTrackID(trackId);
1986     TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1987     int32_t currentStreamID = demuxerPluginManager_->GetStreamIDByTrackType(type);
1988     int32_t currentTrackId = trackId;
1989     if (newStreamID == -1 || currentStreamID == -1 || currentStreamID == newStreamID) {
1990         return false;
1991     }
1992     MEDIA_LOG_I("In");
1993     // stop plugin
1994     demuxerPluginManager_->StopPlugin(currentStreamID, streamDemuxer_);
1995 
1996     // start plugin
1997     Status ret = demuxerPluginManager_->StartPlugin(newStreamID, streamDemuxer_);
1998     FALSE_RETURN_V_MSG_E(ret == Status::OK, false, "Start plugin failed");
1999 
2000     // get new mediainfo
2001     Plugins::MediaInfo mediaInfo;
2002     demuxerPluginManager_->UpdateDefaultStreamID(mediaInfo, streamType, newStreamID);
2003     InitMediaMetaData(mediaInfo); // update mediaMetaData_
2004 
2005     // get newStreamID
2006     int32_t newInnerTrackId;
2007     demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId);
2008 
2009     // update track map
2010     demuxerPluginManager_->DeleteTempTrackMapInfo(currentTrackId);
2011     int32_t innerTrackID = demuxerPluginManager_->GetInnerTrackIDByTrackID(newTrackId);
2012     demuxerPluginManager_->UpdateTempTrackMapInfo(newTrackId, newTrackId, innerTrackID);
2013     MEDIA_LOG_I("Updata info");
2014 
2015     InnerSelectTrack(newTrackId);
2016 
2017     HandleSelectTrackStreamSeek(newStreamID, newTrackId);
2018 
2019     // update buffer queue
2020     bufferQueueMap_.insert(std::pair<uint32_t, sptr<AVBufferQueueProducer>>(newTrackId,
2021         bufferQueueMap_[currentTrackId]));
2022     bufferMap_.insert(std::pair<uint32_t, std::shared_ptr<AVBuffer>>(newTrackId,
2023         bufferMap_[currentTrackId]));
2024     bufferQueueMap_.erase(currentTrackId);
2025     bufferMap_.erase(currentTrackId);
2026 
2027     sampleQueueMap_.insert(
2028         std::pair<uint32_t, std::shared_ptr<SampleQueue>>(newTrackId, sampleQueueMap_[currentTrackId]));
2029     sampleQueueMap_.erase(currentTrackId);
2030     sampleQueueMap_[newTrackId]->UpdateQueueId(newTrackId);
2031 
2032     MEDIA_LOG_I("Out");
2033     return true;
2034 }
2035 
SelectTrackChangeStream(uint32_t trackId)2036 bool MediaDemuxer::SelectTrackChangeStream(uint32_t trackId)
2037 {
2038     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::SelectTrackChangeStream");
2039     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Invalid param");
2040     TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(static_cast<int32_t>(trackId));
2041     int32_t newStreamID = -1;
2042     if (type == TRACK_AUDIO) {
2043         newStreamID = streamDemuxer_->GetNewAudioStreamID();
2044     } else if (type == TRACK_SUBTITLE) {
2045         newStreamID = streamDemuxer_->GetNewSubtitleStreamID();
2046     } else if (type == TRACK_VIDEO) {
2047         newStreamID = streamDemuxer_->GetNewVideoStreamID();
2048     } else {
2049         MEDIA_LOG_W("Invalid track " PUBLIC_LOG_U32, trackId);
2050         return false;
2051     }
2052 
2053     int32_t newTrackId;
2054     bool ret = HandleSelectTrackChangeStream(trackId, newStreamID, newTrackId);
2055     if (ret && eventReceiver_ != nullptr) {
2056         MEDIA_LOG_I("TrackType: " PUBLIC_LOG_U32 ", TrackId " PUBLIC_LOG_D32 " >> " PUBLIC_LOG_D32,
2057             static_cast<uint32_t>(type), trackId, newTrackId);
2058         if (type == TrackType::TRACK_AUDIO) {
2059             audioTrackId_ = static_cast<uint32_t>(newTrackId);
2060             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, newTrackId});
2061             shouldCheckAudioFramePts_ = true;
2062         } else if (type == TrackType::TRACK_VIDEO) {
2063             videoTrackId_ = static_cast<uint32_t>(newTrackId);
2064             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, newTrackId});
2065         } else if (type == TrackType::TRACK_SUBTITLE) {
2066             subtitleTrackId_ = static_cast<uint32_t>(newTrackId);
2067             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_SUBTITLE_TRACK_CHANGE, newTrackId});
2068             shouldCheckSubtitleFramePts_ = true;
2069         }
2070 
2071         {
2072             std::lock_guard<std::mutex> lock(isSelectTrackMutex_);
2073             if (inSelectTrackType_.find(static_cast<int32_t>(type)) != inSelectTrackType_.end() &&
2074                 inSelectTrackType_[static_cast<int32_t>(type)] == newTrackId) {
2075                 inSelectTrackType_.erase(static_cast<int32_t>(type));
2076             }
2077         }
2078         if (CheckTrackEnabledById(trackId)) {
2079             taskMap_[trackId]->StopAsync(); // stop self
2080             sampleConsumerTaskMap_[trackId]->StopAsync();
2081         }
2082     }
2083     return ret;
2084 }
2085 
SelectBitRateChangeStream(uint32_t trackId)2086 bool MediaDemuxer::SelectBitRateChangeStream(uint32_t trackId)
2087 {
2088     (void) trackId;
2089     FALSE_RETURN_V(videoTrackId_ != TRACK_ID_DUMMY, false);
2090     std::unique_lock<std::mutex> changeStreamLock(changeStreamMutex_);
2091     int32_t currentStreamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(videoTrackId_);
2092     int32_t newStreamID = streamDemuxer_->GetNewVideoStreamID();
2093     if (newStreamID >= 0 && currentStreamID != newStreamID) {
2094         MEDIA_LOG_I("In");
2095         demuxerPluginManager_->StopPlugin(currentStreamID, streamDemuxer_);
2096 
2097         Status ret = demuxerPluginManager_->StartPlugin(newStreamID, streamDemuxer_);
2098         FALSE_RETURN_V_MSG_E(ret == Status::OK, false, "Start plugin failed");
2099 
2100         Plugins::MediaInfo mediaInfo;
2101         demuxerPluginManager_->UpdateDefaultStreamID(mediaInfo, VIDEO, newStreamID);
2102         InitMediaMetaData(mediaInfo); // update mediaMetaData_
2103 
2104         int32_t newInnerTrackId = -1;
2105         int32_t newTrackId = -1;
2106         if (isHlsFmp4_) {
2107             demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId, TRACK_VIDEO);
2108             demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, newTrackId, newInnerTrackId);
2109             newInnerTrackId = -1;
2110             newTrackId = -1;
2111             if (audioTrackId_ != TRACK_ID_DUMMY) {
2112                 demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId, TRACK_AUDIO);
2113                 demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, newTrackId, newInnerTrackId);
2114             }
2115         } else {
2116             demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId);
2117             demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, newTrackId, newInnerTrackId);
2118         }
2119 
2120         MEDIA_LOG_I("Updata info");
2121         InnerSelectTrack(static_cast<int32_t>(videoTrackId_));
2122         if (isHlsFmp4_ && audioTrackId_ != TRACK_ID_DUMMY) {
2123             InnerSelectTrack(static_cast<int32_t>(audioTrackId_));
2124         }
2125         MEDIA_LOG_I("Out");
2126         return true;
2127     }
2128     return false;
2129 }
2130 
DumpBufferToFile(uint32_t trackId,std::shared_ptr<AVBuffer> buffer)2131 void MediaDemuxer::DumpBufferToFile(uint32_t trackId, std::shared_ptr<AVBuffer> buffer)
2132 {
2133     std::string mimeType;
2134     if (isDump_) {
2135         if (mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) && mimeType.find("audio") == 0) {
2136                 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_DEMUXER_AUDIO_FILE_NAME, buffer);
2137         }
2138         if (mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) && mimeType.find("video") == 0) {
2139                 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_DEMUXER_VIDEO_FILE_NAME, buffer);
2140         }
2141     }
2142 }
2143 
HandleRead(uint32_t trackId)2144 Status MediaDemuxer::HandleRead(uint32_t trackId)
2145 {
2146     Status ret = InnerReadSample(trackId, bufferMap_[trackId]);
2147     if (IsRightMediaTrack(trackId, DemuxerTrackType::VIDEO)) {
2148         std::unique_lock<std::mutex> draggingLock(draggingMutex_);
2149         if (VideoStreamReadyCallback_ != nullptr) {
2150             if (ret != Status::OK && ret != Status::END_OF_STREAM) {
2151                 sampleQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], false);
2152                 MEDIA_LOG_E("Read failed, track " PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32, trackId, (int32_t)(ret));
2153                 return ret;
2154             }
2155             std::shared_ptr<VideoStreamReadyCallback> videoStreamReadyCallback = VideoStreamReadyCallback_;
2156             draggingLock.unlock();
2157             bool isDiscardable = videoStreamReadyCallback->IsVideoStreamDiscardable(bufferMap_[trackId]);
2158             UpdateSyncFrameInfo(bufferMap_[trackId], trackId, isDiscardable);
2159             sampleQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], !isDiscardable);
2160             return Status::OK;
2161         }
2162     }
2163 
2164     if (source_ != nullptr && source_->IsSeekToTimeSupported() && isSeeked_ && HasVideo()) {
2165         if (trackId == videoTrackId_ && isFirstFrameAfterSeek_.load()) {
2166             bool isSyncFrame = (bufferMap_[trackId]->flag_ & (uint32_t)(AVBufferFlag::SYNC_FRAME)) != 0;
2167             if (!isSyncFrame) {
2168                 MEDIA_LOG_E("The first frame after seeking is not a sync frame");
2169             }
2170             isFirstFrameAfterSeek_.store(false);
2171         }
2172         MEDIA_LOG_I("Seeking, found idr frame track " PUBLIC_LOG_U32, trackId);
2173         isSeeked_ = false;
2174     }
2175     if (ret == Status::OK || ret == Status::END_OF_STREAM) {
2176         if (bufferMap_[trackId]->flag_ & (uint32_t)(AVBufferFlag::EOS)) {
2177             return HandleTrackEos(trackId);
2178         }
2179         HandleAutoMaintainPts(trackId, bufferMap_[trackId]);
2180         bool isDroppable = IsBufferDroppable(bufferMap_[trackId], trackId);
2181         if (fileType_ == FileType::AVI && trackId == videoTrackId_) {
2182             SetOutputBufferPts(bufferMap_[trackId]);
2183         }
2184         sampleQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], !isDroppable);
2185     } else {
2186         sampleQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], false);
2187         MEDIA_LOG_E("Read failed, track " PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32, trackId, (int32_t)(ret));
2188     }
2189     return ret;
2190 }
2191 
HandleTrackEos(uint32_t trackId)2192 Status MediaDemuxer::HandleTrackEos(uint32_t trackId)
2193 {
2194     eosMap_[trackId] = true;
2195     if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
2196         taskMap_[trackId]->StopAsync();
2197     }
2198     MEDIA_LOG_I("Track eos, track: " PUBLIC_LOG_U32 ", bufferId: " PUBLIC_LOG_U64
2199         ", pts: " PUBLIC_LOG_D64 ", flag: " PUBLIC_LOG_U32, trackId, bufferMap_[trackId]->GetUniqueId(),
2200         bufferMap_[trackId]->pts_, bufferMap_[trackId]->flag_);
2201     (void)sampleQueueMap_[trackId]->PushBuffer(bufferMap_[trackId], true);
2202     return Status::OK;
2203 }
2204 
SetOutputBufferPts(std::shared_ptr<AVBuffer> & outputBuffer)2205 void MediaDemuxer::SetOutputBufferPts(std::shared_ptr<AVBuffer> &outputBuffer)
2206 {
2207     FALSE_RETURN_MSG(outputBuffer != nullptr, "outputBuffer is nullptr.");
2208     MEDIA_LOG_D("OutputBuffer PTS: " PUBLIC_LOG_D64 " DTS: " PUBLIC_LOG_D64, outputBuffer->pts_, outputBuffer->dts_);
2209     outputBuffer->pts_ = outputBuffer->dts_;
2210 }
2211 
HandleDashChangeStream(uint32_t trackId)2212 bool MediaDemuxer::HandleDashChangeStream(uint32_t trackId)
2213 {
2214     FALSE_RETURN_V_NOLOG(demuxerPluginManager_->IsDash(), false);
2215     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Plugin manager is nullptr");
2216     FALSE_RETURN_V_MSG_E(streamDemuxer_ != nullptr, false, "Stream is nullptr");
2217 
2218     MEDIA_LOG_D("IN");
2219     TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(static_cast<int32_t>(trackId));
2220     int32_t currentStreamID = demuxerPluginManager_->GetStreamIDByTrackType(type);
2221     int32_t newStreamID = demuxerPluginManager_->GetStreamDemuxerNewStreamID(type, streamDemuxer_);
2222     bool ret = false;
2223     FALSE_RETURN_V_NOLOG(newStreamID != -1 && currentStreamID != newStreamID, ret);
2224 
2225     MEDIA_LOG_I("Change stream begin, currentStreamID: " PUBLIC_LOG_D32 " newStreamID: " PUBLIC_LOG_D32,
2226         currentStreamID, newStreamID);
2227     if ((trackId == videoTrackId_ || isHlsFmp4_) && demuxerPluginManager_->GetCurrentBitRate() != targetBitRate_) {
2228         ret = SelectBitRateChangeStream(trackId);
2229         if (ret) {
2230             streamDemuxer_->SetChangeFlag(true);
2231             MEDIA_LOG_I("targetBitrate: " PUBLIC_LOG_U32 " currentBitrate: " PUBLIC_LOG_U32, targetBitRate_,
2232                 demuxerPluginManager_->GetCurrentBitRate());
2233             isSelectBitRate_.store(targetBitRate_ != demuxerPluginManager_->GetCurrentBitRate());
2234         }
2235     } else {
2236         isSelectTrack_.store(true);
2237         ret = SelectTrackChangeStream(trackId);
2238         if (ret) {
2239             MEDIA_LOG_I("targetBitrate: " PUBLIC_LOG_U32 " currentBitrate: " PUBLIC_LOG_U32, targetBitRate_,
2240                 demuxerPluginManager_->GetCurrentBitRate());
2241             targetBitRate_ = demuxerPluginManager_->GetCurrentBitRate();
2242             streamDemuxer_->SetChangeFlag(true);
2243         }
2244         isSelectTrack_.store(false);
2245     }
2246     MEDIA_LOG_I("Change stream success");
2247     return ret;
2248 }
2249 
CopyFrameToUserQueue(uint32_t trackId)2250 Status MediaDemuxer::CopyFrameToUserQueue(uint32_t trackId)
2251 {
2252     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::CopyFrameToUserQueue");
2253     MEDIA_LOG_D("In, track:" PUBLIC_LOG_U32, trackId);
2254 
2255     int32_t innerTrackID = static_cast<int32_t>(trackId);
2256     int32_t id = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
2257     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = demuxerPluginManager_->GetPluginByStreamID(id);
2258     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
2259     if (IsNeedMapToInnerTrackID()) {
2260         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
2261     }
2262 
2263     int32_t size = 0;
2264     Status ret = pluginTemp->GetNextSampleSize(innerTrackID, size);
2265     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_UNKNOWN, ret, "Get size failed for track " PUBLIC_LOG_U32, trackId);
2266     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_AGAIN, ret,
2267         "Get size failed for track " PUBLIC_LOG_U32 ", retry", trackId);
2268     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_NO_MEMORY, ret, "Get size failed for track " PUBLIC_LOG_U32, trackId);
2269     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_WRONG_STATE, ret, " Get size interrupt");
2270     if (HandleDashChangeStream(trackId)) {
2271         MEDIA_LOG_I("HandleDashChangeStream success");
2272         return Status::OK;
2273     }
2274 
2275     SetTrackNotifyFlag(trackId, true);
2276     if (!GetBufferFromUserQueue(trackId, size)) {
2277         return Status::ERROR_INVALID_PARAMETER;
2278     }
2279     SetTrackNotifyFlag(trackId, false);
2280     ret = HandleRead(trackId);
2281     MEDIA_LOG_D("Out, track:" PUBLIC_LOG_U32, trackId);
2282     return ret;
2283 }
2284 
InnerReadSample(uint32_t trackId,std::shared_ptr<AVBuffer> sample)2285 Status MediaDemuxer::InnerReadSample(uint32_t trackId, std::shared_ptr<AVBuffer> sample)
2286 {
2287     MEDIA_LOG_D("In, track " PUBLIC_LOG_U32, trackId);
2288 
2289     int32_t innerTrackID = static_cast<int32_t>(trackId);
2290     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
2291     if (IsNeedMapToInnerTrackID()) {
2292         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
2293         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
2294         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
2295         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
2296     } else {
2297         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(demuxerPluginManager_->GetStreamIDByTrackID(trackId));
2298         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
2299     }
2300 
2301     Status ret = ReadSampleWithPerfRecord(pluginTemp, innerTrackID, sample);
2302     if (ret == Status::END_OF_STREAM) {
2303         MEDIA_LOG_I("Read eos for track " PUBLIC_LOG_U32, trackId);
2304     } else if (ret != Status::OK) {
2305         MEDIA_LOG_I("Read error for track " PUBLIC_LOG_U32 ", ret: " PUBLIC_LOG_D32, trackId, (int32_t)(ret));
2306     }
2307     MEDIA_LOG_D("Out, track " PUBLIC_LOG_U32, trackId);
2308 
2309     // to get DrmInfo
2310     ProcessDrmInfos();
2311     return ret;
2312 }
2313 
ReadSampleWithPerfRecord(const std::shared_ptr<Plugins::DemuxerPlugin> & pluginTemp,const int32_t & innerTrackID,const std::shared_ptr<AVBuffer> & sample)2314 Status MediaDemuxer::ReadSampleWithPerfRecord(const std::shared_ptr<Plugins::DemuxerPlugin> &pluginTemp,
2315     const int32_t &innerTrackID, const std::shared_ptr<AVBuffer> &sample)
2316 {
2317     FALSE_RETURN_V_NOLOG(perfRecEnabled_, pluginTemp->ReadSample(innerTrackID, sample));
2318     Status ret = Status::OK;
2319     int64_t demuxDuration = CALC_EXPR_TIME_MS(ret = pluginTemp->ReadSample(innerTrackID, sample));
2320     FALSE_RETURN_V_MSG(eventReceiver_ != nullptr, Status::OK, "Report perf failed, callback is nullptr");
2321     FALSE_RETURN_V_NOLOG(perfRecorder_.Record(demuxDuration) == PerfRecorder::FULL, ret);
2322     eventReceiver_->OnDfxEvent({ "DEMUX", DfxEventType::DFX_INFO_PERF_REPORT, perfRecorder_.GetMainPerfData() });
2323     perfRecorder_.Reset();
2324     return ret;
2325 }
2326 
SetPerfRecEnabled(bool isPerfRecEnabled)2327 Status MediaDemuxer::SetPerfRecEnabled(bool isPerfRecEnabled)
2328 {
2329     MEDIA_LOG_I("widdraw DoSetPerfRecEnabled %{public}d", isPerfRecEnabled);
2330     perfRecEnabled_ = isPerfRecEnabled;
2331     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_NO_MEMORY, "Source not exist, no memory");
2332     source_->SetPerfRecEnabled(isPerfRecEnabled);
2333     return Status::OK;
2334 }
2335 
GetReadLoopRetryUs(uint32_t trackId)2336 int64_t MediaDemuxer::GetReadLoopRetryUs(uint32_t trackId)
2337 {
2338     if (!isFlvLiveStream_) {
2339         return NEXT_DELAY_TIME_US;
2340     }
2341     FALSE_RETURN_V_MSG_E(sampleQueueMap_.count(trackId) > 0 && sampleQueueMap_[trackId] != nullptr, NEXT_DELAY_TIME_US,
2342         "sampleQueue " PUBLIC_LOG_D32 " is nullptr", trackId);
2343     uint64_t sampleDuration = sampleQueueMap_[trackId]->GetCacheDuration();
2344     if (sampleDuration <= SAMPLE_FLOW_CONTROL_MIN_SAMPLE_DURATION_US) {
2345         return NEXT_DELAY_TIME_US;
2346     }
2347     return static_cast<int64_t>(sampleDuration >> SAMPLE_FLOW_CONTROL_RATE_POW);
2348 }
2349 
ReadLoop(uint32_t trackId)2350 int64_t MediaDemuxer::ReadLoop(uint32_t trackId)
2351 {
2352     if (streamDemuxer_->GetIsIgnoreParse() || isStopped_ || isPaused_ || isSeekError_) {
2353         MEDIA_LOG_D("ReadLoop pausing or error, track " PUBLIC_LOG_U32, trackId);
2354         perfRecorder_.Reset();
2355         return 6 * 1000; // sleep 6ms in pausing to avoid useless reading
2356     } else {
2357         Status ret = CopyFrameToUserQueue(trackId);
2358         // when read failed, or request always failed in 1min, send error event
2359         bool ignoreError = isStopped_ || isPaused_ || isInterruptNeeded_.load();
2360         if ((ret == Status::ERROR_UNKNOWN && !ignoreError) ||
2361              requestBufferErrorCountMap_[trackId] >= REQUEST_FAILED_RETRY_TIMES) {
2362             MEDIA_LOG_E("Invalid data source, can not get frame");
2363             if (eventReceiver_ != nullptr) {
2364                 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DATA_SOURCE_ERROR_UNKNOWN});
2365             } else {
2366                 MEDIA_LOG_D("EventReceiver is nullptr");
2367             }
2368         }
2369         bool isNeedRetry = ret == Status::OK || ret == Status::ERROR_AGAIN;
2370         if (isNeedRetry) {
2371             return GetReadLoopRetryUs(trackId);
2372         } else if (ret == Status::ERROR_NO_MEMORY) {
2373             MEDIA_LOG_E("Cache data size is out of limit");
2374             if (eventReceiver_ != nullptr && !isOnEventNoMemory_.load()) {
2375                 isOnEventNoMemory_.store(true);
2376                 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DEMUXER_BUFFER_NO_MEMORY});
2377             }
2378             return NEXT_DELAY_TIME_US;
2379         } else {
2380             MEDIA_LOG_D("ReadLoop wait, track:" PUBLIC_LOG_U32 ", ret:" PUBLIC_LOG_D32,
2381                 trackId, static_cast<int32_t>(ret));
2382             return RETRY_DELAY_TIME_US; // delay to retry if no frame
2383         }
2384     }
2385 }
2386 
ReadSample(uint32_t trackId,std::shared_ptr<AVBuffer> sample)2387 Status MediaDemuxer::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer> sample)
2388 {
2389     MediaAVCodec::AVCODEC_SYNC_TRACE;
2390     FALSE_RETURN_V_MSG_E(!useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
2391     MEDIA_LOG_D("In");
2392     FALSE_RETURN_V_MSG_E(eosMap_.count(trackId) > 0, Status::ERROR_INVALID_OPERATION, "Track has not been selected");
2393     FALSE_RETURN_V_MSG_E(sample != nullptr && sample->memory_!=nullptr, Status::ERROR_INVALID_PARAMETER,
2394         "AVBuffer is nullptr");
2395     if (eosMap_[trackId]) {
2396         MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " has reached eos", trackId);
2397         sample->flag_ = (uint32_t)(AVBufferFlag::EOS);
2398         sample->memory_->SetSize(0);
2399         return Status::END_OF_STREAM;
2400     }
2401     Status ret = InnerReadSample(trackId, sample);
2402     if (ret == Status::OK || ret == Status::END_OF_STREAM) {
2403         if (sample->flag_ & (uint32_t)(AVBufferFlag::EOS)) {
2404             eosMap_[trackId] = true;
2405             sample->memory_->SetSize(0);
2406         }
2407         if (sample->flag_ & (uint32_t)(AVBufferFlag::PARTIAL_FRAME)) {
2408             ret = Status::ERROR_NO_MEMORY;
2409         }
2410     }
2411     return ret;
2412 }
2413 
HandleSourceDrmInfoEvent(const std::multimap<std::string,std::vector<uint8_t>> & info)2414 void MediaDemuxer::HandleSourceDrmInfoEvent(const std::multimap<std::string, std::vector<uint8_t>> &info)
2415 {
2416     MEDIA_LOG_I("In");
2417     std::multimap<std::string, std::vector<uint8_t>> infoUpdated;
2418     bool isUpdated = GetDrmInfosUpdated(info, infoUpdated);
2419     if (isUpdated) {
2420         ReportDrmInfos(infoUpdated);
2421         return;
2422     }
2423     MEDIA_LOG_D("Demuxer filter received source drminfos but not update");
2424 }
2425 
HandleEvent(const Plugins::PluginEvent & event)2426 void MediaDemuxer::HandleEvent(const Plugins::PluginEvent &event)
2427 {
2428     switch (event.type) {
2429         case PluginEventType::CLIENT_ERROR:
2430         case PluginEventType::SERVER_ERROR: {
2431             MEDIA_LOG_E("HandleEvent error code " PUBLIC_LOG_D32, AnyCast<int32_t>(event.param));
2432             FALSE_RETURN(demuxerPluginManager_ != nullptr);
2433             demuxerPluginManager_->NotifyInitialBufferingEnd(false);
2434             break;
2435         }
2436         case PluginEventType::INITIAL_BUFFER_SUCCESS: {
2437             MEDIA_LOG_I("HandleEvent initial buffer success");
2438             FALSE_RETURN(demuxerPluginManager_ != nullptr);
2439             demuxerPluginManager_->NotifyInitialBufferingEnd(true);
2440             break;
2441         }
2442         default:
2443             break;
2444     }
2445 }
2446 
OnEvent(const Plugins::PluginEvent & event)2447 void MediaDemuxer::OnEvent(const Plugins::PluginEvent &event)
2448 {
2449     MEDIA_LOG_D("In");
2450     HandleEvent(event);
2451     std::weak_ptr<Pipeline::EventReceiver> weakEventReceiver = eventReceiver_;
2452     auto eventReceiver = weakEventReceiver.lock();
2453     if (eventReceiver == nullptr && event.type != PluginEventType::SOURCE_DRM_INFO_UPDATE) {
2454         MEDIA_LOG_D("EventReceiver is nullptr");
2455         return;
2456     }
2457     switch (event.type) {
2458         case PluginEventType::SOURCE_DRM_INFO_UPDATE: {
2459             MEDIA_LOG_D("OnEvent source drmInfo update");
2460             HandleSourceDrmInfoEvent(AnyCast<std::multimap<std::string, std::vector<uint8_t>>>(event.param));
2461             break;
2462         }
2463         case PluginEventType::CLIENT_ERROR:
2464         case PluginEventType::SERVER_ERROR: {
2465             MEDIA_LOG_E("OnEvent error code " PUBLIC_LOG_D32, AnyCast<int32_t>(event.param));
2466             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, event.param});
2467             break;
2468         }
2469         case PluginEventType::CACHED_DURATION: {
2470             MEDIA_LOG_D("OnEvent cached duration");
2471             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_CACHED_DURATION, event.param});
2472             break;
2473         }
2474         case PluginEventType::SOURCE_BITRATE_START: {
2475             MEDIA_LOG_D("OnEvent source bitrate start");
2476             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_SOURCE_BITRATE_START, event.param});
2477             break;
2478         }
2479         default:
2480             break;
2481     }
2482     OnEventBuffer(event, eventReceiver);
2483 }
2484 
OnEventBuffer(const Plugins::PluginEvent & event,std::shared_ptr<Pipeline::EventReceiver> eventReceiver)2485 void MediaDemuxer::OnEventBuffer(const Plugins::PluginEvent &event,
2486     std::shared_ptr<Pipeline::EventReceiver> eventReceiver)
2487 {
2488     switch (event.type) {
2489         case PluginEventType::BUFFERING_END: {
2490             MEDIA_LOG_D("OnEvent pause");
2491             if (!IsIgonreBuffering()) {
2492                 MEDIA_LOG_D("OnEvent BUFFERING_END");
2493                 eventReceiver->OnEvent({"demuxer_filter", EventType::BUFFERING_END, PAUSE});
2494             }
2495             break;
2496         }
2497         case PluginEventType::BUFFERING_START: {
2498             MEDIA_LOG_D("OnEvent start");
2499             if (!IsIgonreBuffering()) {
2500                 MEDIA_LOG_D("OnEvent BUFFERING_START");
2501                 eventReceiver->OnEvent({"demuxer_filter", EventType::BUFFERING_START, START});
2502             }
2503             break;
2504         }
2505         case PluginEventType::EVENT_BUFFER_PROGRESS: {
2506             MEDIA_LOG_D("OnEvent percent update");
2507             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_BUFFER_PROGRESS, event.param});
2508             break;
2509         }
2510         default:
2511             break;
2512     }
2513     OnSeekReadyEvent(event);
2514 }
2515 
OnSeekReadyEvent(const Plugins::PluginEvent & event)2516 void MediaDemuxer::OnSeekReadyEvent(const Plugins::PluginEvent &event)
2517 {
2518     switch (event.type) {
2519         case PluginEventType::DASH_SEEK_READY: {
2520             MEDIA_LOG_D("OnEvent dash seek ready");
2521             OnDashSeekReadyEvent(event);
2522             break;
2523         }
2524         case PluginEventType::HLS_SEEK_READY: {
2525             MEDIA_LOG_D("OnEvent hls seek ready");
2526             OnHlsSeekReadyEvent(event);
2527             break;
2528         }
2529         default:
2530             break;
2531     }
2532 }
2533 
OnDashSeekReadyEvent(const Plugins::PluginEvent & event)2534 void MediaDemuxer::OnDashSeekReadyEvent(const Plugins::PluginEvent &event)
2535 {
2536     FALSE_RETURN_NOLOG(event.type == PluginEventType::DASH_SEEK_READY);
2537     MEDIA_LOG_D("Onevent dash seek ready");
2538     std::unique_lock<std::mutex> lock(rebootPluginMutex_);
2539     Format param = AnyCast<Format>(event.param);
2540     int32_t currentStreamType = -1;
2541     param.GetIntValue("currentStreamType", currentStreamType);
2542     int32_t isEOS = -1;
2543     param.GetIntValue("isEOS", isEOS);
2544     int32_t currentStreamId = -1;
2545     param.GetIntValue("currentStreamId", currentStreamId);
2546     MEDIA_LOG_D("HandleDashSeekReady, streamType: " PUBLIC_LOG_D32 " streamId: " PUBLIC_LOG_D32
2547         " isEos: " PUBLIC_LOG_D32, currentStreamType, currentStreamId, isEOS);
2548     switch (currentStreamType) {
2549         case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_VID):
2550             seekReadyStreamInfo_[static_cast<int32_t>(StreamType::VIDEO)] = std::make_pair(currentStreamId, isEOS);
2551             break;
2552         case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_AUD):
2553             seekReadyStreamInfo_[static_cast<int32_t>(StreamType::AUDIO)] = std::make_pair(currentStreamId, isEOS);
2554             break;
2555         case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_SUBTITLE):
2556             seekReadyStreamInfo_[static_cast<int32_t>(StreamType::SUBTITLE)] = std::make_pair(currentStreamId, isEOS);
2557             break;
2558         default:
2559             break;
2560     }
2561     rebootPluginCondition_.notify_all();
2562 }
2563 
OnHlsSeekReadyEvent(const Plugins::PluginEvent & event)2564 void MediaDemuxer::OnHlsSeekReadyEvent(const Plugins::PluginEvent &event)
2565 {
2566     MEDIA_LOG_D("Onevent hls seek ready");
2567     std::unique_lock<std::mutex> lock(rebootPluginMutex_);
2568     Format param = AnyCast<Format>(event.param);
2569     int32_t currentStreamType = -1;
2570     param.GetIntValue("currentStreamType", currentStreamType);
2571     int32_t isEOS = -1;
2572     param.GetIntValue("isEOS", isEOS);
2573     int32_t currentStreamId = -1;
2574     param.GetIntValue("currentStreamId", currentStreamId);
2575     MEDIA_LOG_D("HandleHlsSeekReady, streamType: " PUBLIC_LOG_D32 " streamId: " PUBLIC_LOG_D32
2576         " isEos: " PUBLIC_LOG_D32, currentStreamType, currentStreamId, isEOS);
2577     seekReadyStreamInfo_[static_cast<int32_t>(StreamType::MIXED)] = std::make_pair(currentStreamId, isEOS);
2578     rebootPluginCondition_.notify_all();
2579 }
2580 
OnDfxEvent(const Plugins::PluginDfxEvent & event)2581 void MediaDemuxer::OnDfxEvent(const Plugins::PluginDfxEvent &event)
2582 {
2583     FALSE_RETURN_MSG(eventReceiver_ != nullptr, "Dfx event report error, receiver is nullptr");
2584     auto it = DFX_EVENT_MAP.find(event.type);
2585     FALSE_RETURN_MSG(it != DFX_EVENT_MAP.end(), "No mapped dfx event type, src type %{public}d", event.type);
2586     eventReceiver_->OnDfxEvent({ it->second.first, it->second.second, event.param });
2587 }
2588 
OptimizeDecodeSlow(bool isDecodeOptimizationEnabled)2589 Status MediaDemuxer::OptimizeDecodeSlow(bool isDecodeOptimizationEnabled)
2590 {
2591     MEDIA_LOG_I("In");
2592     isDecodeOptimizationEnabled_ = isDecodeOptimizationEnabled;
2593     return Status::OK;
2594 }
2595 
SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit,uint32_t trackId)2596 Status MediaDemuxer::SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit,
2597     uint32_t trackId)
2598 {
2599     MEDIA_LOG_I("DecoderFramerateUpperLimit=" PUBLIC_LOG_D32 " trackId=" PUBLIC_LOG_D32,
2600         decoderFramerateUpperLimit, trackId);
2601     FALSE_RETURN_V(trackId == videoTrackId_, Status::OK);
2602     FALSE_RETURN_V_MSG_E(decoderFramerateUpperLimit > 0, Status::ERROR_INVALID_PARAMETER,
2603         "SetDecoderFramerateUpperLimit failed, decoderFramerateUpperLimit <= 0");
2604     decoderFramerateUpperLimit_.store(decoderFramerateUpperLimit);
2605     return Status::OK;
2606 }
2607 
SetSpeed(float speed)2608 Status MediaDemuxer::SetSpeed(float speed)
2609 {
2610     MEDIA_LOG_I("Speed=" PUBLIC_LOG_F, speed);
2611     FALSE_RETURN_V_MSG_E(speed > 0, Status::ERROR_INVALID_PARAMETER, "Speed <= 0");
2612     speed_.store(speed);
2613     return Status::OK;
2614 }
2615 
SetFrameRate(double framerate,uint32_t trackId)2616 Status MediaDemuxer::SetFrameRate(double framerate, uint32_t trackId)
2617 {
2618     MEDIA_LOG_I("Framerate=" PUBLIC_LOG_F " trackId=" PUBLIC_LOG_D32, framerate, trackId);
2619     FALSE_RETURN_V(trackId == videoTrackId_, Status::OK);
2620     FALSE_RETURN_V_MSG_E(framerate > 0, Status::ERROR_INVALID_PARAMETER, "Framerate <= 0");
2621     framerate_.store(framerate);
2622     return Status::OK;
2623 }
2624 
CheckDropAudioFrame(std::shared_ptr<AVBuffer> sample,uint32_t trackId)2625 bool MediaDemuxer::CheckDropAudioFrame(std::shared_ptr<AVBuffer> sample, uint32_t trackId)
2626 {
2627     if (trackId == audioTrackId_) {
2628         if (shouldCheckAudioFramePts_ == false) {
2629             lastAudioPts_ = sample->pts_;
2630             MEDIA_LOG_I("Set last audio pts " PUBLIC_LOG_D64, lastAudioPts_);
2631             return false;
2632         }
2633         if (sample->pts_ <= lastAudioPts_) {
2634             MEDIA_LOG_I("Drop audio buffer pts " PUBLIC_LOG_D64, sample->pts_);
2635             return true;
2636         }
2637         if (shouldCheckAudioFramePts_) {
2638             shouldCheckAudioFramePts_ = false;
2639             lastAudioPts_ = sample->pts_;
2640         }
2641     }
2642     if (trackId == subtitleTrackId_) {
2643         if (shouldCheckSubtitleFramePts_ == false) {
2644             lastSubtitlePts_ = sample->pts_;
2645             MEDIA_LOG_I("Set last subtitle pts " PUBLIC_LOG_D64, lastSubtitlePts_);
2646             return false;
2647         }
2648         if (sample->pts_ <= lastSubtitlePts_) {
2649             MEDIA_LOG_I("Drop subtitle buffer pts " PUBLIC_LOG_D64, sample->pts_);
2650             return true;
2651         }
2652         if (shouldCheckSubtitleFramePts_) {
2653             shouldCheckSubtitleFramePts_ = false;
2654             lastSubtitlePts_ = sample->pts_;
2655         }
2656     }
2657     return false;
2658 }
2659 
IsBufferDroppable(std::shared_ptr<AVBuffer> sample,uint32_t trackId)2660 bool MediaDemuxer::IsBufferDroppable(std::shared_ptr<AVBuffer> sample, uint32_t trackId)
2661 {
2662     DumpBufferToFile(trackId, sample);
2663 
2664     if (demuxerPluginManager_->IsDash() && (trackId == audioTrackId_ || trackId == subtitleTrackId_)) {
2665         return CheckDropAudioFrame(sample, trackId);
2666     }
2667 
2668     if (trackId != videoTrackId_) {
2669         return false;
2670     }
2671 
2672     FALSE_RETURN_V_NOLOG(!IsOpenGopBufferDroppable(sample, trackId), true);
2673 
2674     if (!isDecodeOptimizationEnabled_.load()) {
2675         return false;
2676     }
2677 
2678     double targetRate = framerate_.load() * speed_.load();
2679     double actualRate = decoderFramerateUpperLimit_.load() * (1 + DECODE_RATE_THRESHOLD);
2680     if (targetRate <= actualRate) {
2681         return false;
2682     }
2683 
2684     bool canDrop = false;
2685     bool ret = sample->meta_->GetData(Media::Tag::VIDEO_BUFFER_CAN_DROP, canDrop);
2686     if (!ret || !canDrop) {
2687         return false;
2688     }
2689 
2690     MEDIA_LOG_D("Drop buffer, framerate=" PUBLIC_LOG_F " speed=" PUBLIC_LOG_F " decodeUpLimit="
2691         PUBLIC_LOG_D32 " pts=" PUBLIC_LOG_D64, framerate_.load(), speed_.load(),
2692         decoderFramerateUpperLimit_.load(), sample->pts_);
2693     return true;
2694 }
2695 
DisableMediaTrack(Plugins::MediaType mediaType)2696 Status MediaDemuxer::DisableMediaTrack(Plugins::MediaType mediaType)
2697 {
2698     disabledMediaTracks_.emplace(mediaType);
2699     return Status::OK;
2700 }
2701 
IsTrackDisabled(Plugins::MediaType mediaType)2702 bool MediaDemuxer::IsTrackDisabled(Plugins::MediaType mediaType)
2703 {
2704     return !disabledMediaTracks_.empty() && disabledMediaTracks_.find(mediaType) != disabledMediaTracks_.end();
2705 }
2706 
CheckTrackEnabledById(uint32_t trackId)2707 bool MediaDemuxer::CheckTrackEnabledById(uint32_t trackId)
2708 {
2709     bool hasTrack = trackId != TRACK_ID_DUMMY;
2710     if (!hasTrack) {
2711         return false;
2712     }
2713     bool hasTask = taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr;
2714     bool hasSampleQueueTask = sampleConsumerTaskMap_.find(trackId) != sampleConsumerTaskMap_.end() &&
2715                             sampleConsumerTaskMap_[trackId] != nullptr;
2716     if (!hasTask || !hasSampleQueueTask) {
2717         return false;
2718     }
2719 
2720     bool hasBufferQueue = bufferQueueMap_.find(trackId) != bufferQueueMap_.end()
2721         && bufferQueueMap_[trackId] != nullptr;
2722     bool hasSampleQueue = sampleQueueMap_.find(trackId) != sampleQueueMap_.end()
2723         && sampleQueueMap_[trackId] != nullptr;
2724     if (!hasBufferQueue || !hasSampleQueue) {
2725         MEDIA_LOG_I(" not hasBufferQueue or hasSampleQueueTask: TrackId=" PUBLIC_LOG_U32, trackId);
2726         return false;
2727     }
2728     return true;
2729 }
2730 
SetSelectBitRateFlag(bool flag,uint32_t desBitRate)2731 void MediaDemuxer::SetSelectBitRateFlag(bool flag, uint32_t desBitRate)
2732 {
2733     MEDIA_LOG_I("Flag=" PUBLIC_LOG_D32 " desBitRate=" PUBLIC_LOG_U32,
2734         static_cast<int32_t>(flag), desBitRate);
2735     isSelectBitRate_.store(flag);
2736     if (flag) {
2737         targetBitRate_ = desBitRate;
2738     }
2739 }
2740 
CanAutoSelectBitRate()2741 bool MediaDemuxer::CanAutoSelectBitRate()
2742 {
2743     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Plugin manager is nullptr");
2744     // calculating auto selectbitrate time
2745     return !(isSelectBitRate_.load()) && !(isSelectTrack_.load())
2746         && (targetBitRate_ == demuxerPluginManager_->GetCurrentBitRate());
2747 }
2748 
IsRenderNextVideoFrameSupported()2749 bool MediaDemuxer::IsRenderNextVideoFrameSupported()
2750 {
2751     bool isDataSrcLiveStream = source_ != nullptr && source_->IsNeedPreDownload() &&
2752         source_->GetSeekable() == Plugins::Seekable::UNSEEKABLE;
2753     return videoTrackId_ != TRACK_ID_DUMMY && !IsTrackDisabled(Plugins::MediaType::VIDEO) &&
2754         !isDataSrcLiveStream && !isFlvLiveStream_;
2755 }
2756 
GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,const uint64_t relativePresentationTimeUs,uint32_t & index)2757 Status MediaDemuxer::GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,
2758     const uint64_t relativePresentationTimeUs, uint32_t &index)
2759 {
2760     MEDIA_LOG_D("In");
2761     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
2762     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
2763     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
2764 
2765     Status ret = pluginTemp->GetIndexByRelativePresentationTimeUs(trackIndex, relativePresentationTimeUs, index);
2766     if (ret != Status::OK) {
2767         MEDIA_LOG_E("Get index failed");
2768     }
2769     return ret;
2770 }
2771 
GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,const uint32_t index,uint64_t & relativePresentationTimeUs)2772 Status MediaDemuxer::GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,
2773     const uint32_t index, uint64_t &relativePresentationTimeUs)
2774 {
2775     MEDIA_LOG_D("In");
2776     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
2777     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
2778     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
2779 
2780     Status ret = pluginTemp->GetRelativePresentationTimeUsByIndex(trackIndex, index, relativePresentationTimeUs);
2781     if (ret != Status::OK) {
2782         MEDIA_LOG_E("Get pts failed");
2783     }
2784     return ret;
2785 }
2786 
ResumeDemuxerReadLoop()2787 Status MediaDemuxer::ResumeDemuxerReadLoop()
2788 {
2789     MEDIA_LOG_I("In");
2790     if (isDemuxerLoopExecuting_) {
2791         MEDIA_LOG_I("Has already resumed");
2792         return Status::OK;
2793     }
2794     isDemuxerLoopExecuting_ = true;
2795     return ResumeAllTask();
2796 }
2797 
PauseDemuxerReadLoop()2798 Status MediaDemuxer::PauseDemuxerReadLoop()
2799 {
2800     MEDIA_LOG_I("In");
2801     if (!isDemuxerLoopExecuting_) {
2802         MEDIA_LOG_I("Has already paused");
2803         return Status::OK;
2804     }
2805     isDemuxerLoopExecuting_ = false;
2806     return PauseAllTaskAsync();
2807 }
2808 
SetCacheLimit(uint32_t limitSize)2809 void MediaDemuxer::SetCacheLimit(uint32_t limitSize)
2810 {
2811     MEDIA_LOG_D("In");
2812     FALSE_RETURN_MSG(demuxerPluginManager_ != nullptr, "Plugin manager is nullptr");
2813     int32_t tempTrackId = (videoTrackId_ != TRACK_ID_DUMMY ? static_cast<int32_t>(videoTrackId_) : -1);
2814     tempTrackId = (tempTrackId == -1 ? static_cast<int32_t>(audioTrackId_) : tempTrackId);
2815     int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(tempTrackId);
2816     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
2817     FALSE_RETURN_MSG(pluginTemp != nullptr, "Demuxer plugin is nullptr");
2818 
2819     pluginTemp->SetCacheLimit(limitSize);
2820 }
2821 
IsVideoEos()2822 bool MediaDemuxer::IsVideoEos()
2823 {
2824     if (videoTrackId_ == TRACK_ID_DUMMY) {
2825         return true;
2826     }
2827     return eosMap_[videoTrackId_];
2828 }
2829 
HasEosTrack()2830 bool MediaDemuxer::HasEosTrack()
2831 {
2832     for (auto it = eosMap_.begin(); it != eosMap_.end(); it++) {
2833         if (it->second) {
2834             return true;
2835         }
2836     }
2837     return false;
2838 }
2839 
SetEnableOnlineFdCache(bool isEnableFdCache)2840 void MediaDemuxer::SetEnableOnlineFdCache(bool isEnableFdCache)
2841 {
2842     FALSE_RETURN(source_ != nullptr);
2843     source_->SetEnableOnlineFdCache(isEnableFdCache);
2844 }
2845 
WaitForBufferingEnd()2846 void MediaDemuxer::WaitForBufferingEnd()
2847 {
2848     FALSE_RETURN_MSG(source_ != nullptr, "Source is nullptr");
2849     source_->WaitForBufferingEnd();
2850 }
2851 
GetCurrentVideoTrackId()2852 int32_t MediaDemuxer::GetCurrentVideoTrackId()
2853 {
2854     return (videoTrackId_ != TRACK_ID_DUMMY ? static_cast<int32_t>(videoTrackId_) : -1);
2855 }
2856 
SetIsEnableReselectVideoTrack(bool isEnable)2857 void MediaDemuxer::SetIsEnableReselectVideoTrack(bool isEnable)
2858 {
2859     isEnableReselectVideoTrack_  = isEnable;
2860 }
2861 
IsOpenGopBufferDroppable(std::shared_ptr<AVBuffer> sample,uint32_t trackId)2862 bool MediaDemuxer::IsOpenGopBufferDroppable(std::shared_ptr<AVBuffer> sample, uint32_t trackId)
2863 {
2864     FALSE_RETURN_V_NOLOG(trackId == videoTrackId_ && sample != nullptr, false);
2865     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
2866     if ((sample->flag_ & static_cast<uint32_t>(AVBufferFlag::SYNC_FRAME)) > 0) {
2867         syncFrameInfo_.pts = sample->pts_;
2868         if (syncFrameInfo_.skipOpenGopUnrefFrameCnt > 0) {
2869             syncFrameInfo_.skipOpenGopUnrefFrameCnt--;
2870         }
2871         return false;
2872     }
2873     if (syncFrameInfo_.skipOpenGopUnrefFrameCnt <= 0 || sample->pts_ >= syncFrameInfo_.pts) {
2874         return false;
2875     }
2876     MEDIA_LOG_D("drop opengop-buffer after dragging, pts: " PUBLIC_LOG_D64 ", i frame pts: "
2877         PUBLIC_LOG_D64, sample->pts_, syncFrameInfo_.pts);
2878     return true;
2879 }
2880 
UpdateSyncFrameInfo(std::shared_ptr<AVBuffer> sample,uint32_t trackId,bool isDiscardable)2881 void MediaDemuxer::UpdateSyncFrameInfo(std::shared_ptr<AVBuffer> sample, uint32_t trackId, bool isDiscardable)
2882 {
2883     FALSE_RETURN_NOLOG(trackId == videoTrackId_ && sample != nullptr && !isDiscardable);
2884     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
2885     if ((sample->flag_ & static_cast<uint32_t>(AVBufferFlag::SYNC_FRAME)) > 0) {
2886         syncFrameInfo_.pts = sample->pts_;
2887     }
2888 }
2889 
EnterDraggingOpenGopCnt()2890 void MediaDemuxer::EnterDraggingOpenGopCnt()
2891 {
2892     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
2893     syncFrameInfo_.skipOpenGopUnrefFrameCnt = SKIP_NEXT_OPEN_GOP_CNT;
2894 }
2895 
ResetDraggingOpenGopCnt()2896 void MediaDemuxer::ResetDraggingOpenGopCnt()
2897 {
2898     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
2899     syncFrameInfo_.skipOpenGopUnrefFrameCnt = 0;
2900 }
2901 
SetApiVersion(int32_t apiVersion)2902 void MediaDemuxer::SetApiVersion(int32_t apiVersion)
2903 {
2904     apiVersion_ = apiVersion;
2905     demuxerPluginManager_->SetApiVersion(apiVersion);
2906 }
2907 
IsLocalFd()2908 bool MediaDemuxer::IsLocalFd()
2909 {
2910     FALSE_RETURN_V_MSG_E(source_ != nullptr, false, "source_ is nullptr");
2911     return source_->IsLocalFd();
2912 }
2913 
AddSampleBufferQueue(uint32_t trackId)2914 Status MediaDemuxer::AddSampleBufferQueue(uint32_t trackId)
2915 {
2916     std::shared_ptr<SampleQueue> sampleQueue = std::make_shared<SampleQueue>();
2917     FALSE_RETURN_V_MSG_E(sampleQueue != nullptr, Status::ERROR_NO_MEMORY, "SampleQueue create failed");
2918     bool isVideo = IsRightMediaTrack(trackId, DemuxerTrackType::VIDEO);
2919     SampleQueue::Config sampleQueueConfig{};
2920     sampleQueueConfig.isFlvLiveStream_ = isFlvLiveStream_;
2921     sampleQueueConfig.isSupportBitrateSwitch_ = sampleQueueConfig.isFlvLiveStream_ && isVideo;
2922     sampleQueueConfig.queueId_ = trackId;
2923     sampleQueueConfig.bufferCap_ =
2924         isVideo ? SampleQueue::DEFAULT_VIDEO_SAMPLE_BUFFER_CAP : SampleQueue::DEFAULT_SAMPLE_BUFFER_CAP;
2925     Status status = sampleQueue->Init(sampleQueueConfig);
2926     FALSE_RETURN_V_MSG_E(status == Status::OK, status, "SampleQueue Init failed");
2927 
2928     sampleQueue->SetSampleQueueCallback(shared_from_this());
2929 
2930     sampleQueueMap_.insert(std::pair<uint32_t, std::shared_ptr<SampleQueue>>(trackId, sampleQueue));
2931     MEDIA_LOG_I("AddSampleBufferQueue successfully trackId " PUBLIC_LOG_U32, trackId);
2932     return Status::OK;
2933 }
2934 
SampleConsumerLoop(uint32_t trackId)2935 int64_t MediaDemuxer::SampleConsumerLoop(uint32_t trackId)
2936 {
2937     MEDIA_LOG_D("In, SampleConsumerLoop trackId: " PUBLIC_LOG_U32, trackId);
2938     FALSE_RETURN_V_MSG_E(bufferQueueMap_.count(trackId) > 0 && bufferQueueMap_[trackId] != nullptr, RETRY_DELAY_TIME_US,
2939         "BufferQueue " PUBLIC_LOG_D32 " is nullptr", trackId);
2940 
2941     FALSE_RETURN_V_MSG_E(sampleQueueMap_.count(trackId) > 0 && sampleQueueMap_[trackId] != nullptr,
2942         RETRY_DELAY_TIME_US, "SampleQueueMap " PUBLIC_LOG_D32 " is nullptr", trackId);
2943 
2944     auto& sampleQueue = sampleQueueMap_[trackId];
2945     auto& bufferQueue = bufferQueueMap_[trackId];
2946     Status status = Status::OK;
2947 
2948     do {
2949         size_t size = 0;
2950         status = sampleQueue->QuerySizeForNextAcquireBuffer(size);
2951         CHECK_AND_BREAK_LOG(status == Status::OK, "QuerySizeForNextAcquireBuffer failed " PUBLIC_LOG_U32, trackId);
2952         UpdateSampleQueueCache();
2953 
2954         SetTrackNotifySampleConsumerFlag(trackId, true);
2955         AVBufferConfig avBufferConfig;
2956         std::shared_ptr<AVBuffer> dstBuffer;
2957         avBufferConfig.capacity = static_cast<int32_t>(size);
2958         status = bufferQueue->RequestBuffer(dstBuffer, avBufferConfig, REQUEST_BUFFER_TIMEOUT);
2959         CHECK_AND_BREAK_LOG(status == Status::OK, "RequestBuffer from bufferQueue failed " PUBLIC_LOG_U32, trackId);
2960         SetTrackNotifySampleConsumerFlag(trackId, false);
2961 
2962         status = sampleQueue->AcquireCopyToDstBuffer(dstBuffer);
2963 
2964         status = bufferQueue->PushBuffer(dstBuffer, status == Status::OK);
2965         CHECK_AND_BREAK_LOG(status == Status::OK, "PushBuffer to bufferQueue failed " PUBLIC_LOG_U32, trackId);
2966     } while (0);
2967 
2968     return status == Status::OK ? SAMPLE_LOOP_RETRY_TIME_US : SAMPLE_LOOP_DELAY_TIME_US;
2969 }
2970 
SetSyncCenter(std::shared_ptr<MediaSyncManager> syncCenter)2971 void MediaDemuxer::SetSyncCenter(std::shared_ptr<MediaSyncManager> syncCenter)
2972 {
2973     syncCenter_ = syncCenter;
2974 }
2975 
IsRightMediaTrack(uint32_t trackId,DemuxerTrackType type) const2976 bool MediaDemuxer::IsRightMediaTrack(uint32_t trackId, DemuxerTrackType type) const
2977 {
2978     if (trackId == TRACK_ID_DUMMY) {
2979         return false;
2980     }
2981     switch (type) {
2982         case DemuxerTrackType::VIDEO:
2983             return trackId == videoTrackId_;
2984         case DemuxerTrackType::AUDIO:
2985             return trackId == audioTrackId_;
2986         case DemuxerTrackType::SUBTITLE:
2987             return trackId == subtitleTrackId_;
2988         default:
2989             return false;
2990     }
2991 }
2992 
GetLastVideoBufferAbsPts(uint32_t trackId) const2993 int64_t MediaDemuxer::GetLastVideoBufferAbsPts(uint32_t trackId) const
2994 {
2995     if (syncCenter_ == nullptr) {
2996         return HST_TIME_NONE;
2997     }
2998     FALSE_RETURN_V_MSG_E(syncCenter_ != nullptr, HST_TIME_NONE, "syncCenter_ is nullptr");
2999     return syncCenter_->GetLastVideoBufferAbsPts();
3000 }
3001 
UpdateLastVideoBufferAbsPts(uint32_t trackId)3002 void MediaDemuxer::UpdateLastVideoBufferAbsPts(uint32_t trackId)
3003 {
3004     if (!isFlvLiveStream_ || !IsRightMediaTrack(trackId, DemuxerTrackType::VIDEO)) {
3005         return;
3006     }
3007     int64_t lastVideoBufferAbsPts = GetLastVideoBufferAbsPts(trackId);
3008     if (lastVideoBufferAbsPts == HST_TIME_NONE) {
3009         return;
3010     }
3011     AutoLock lock(mapMutex_);
3012     auto sqIt = sampleQueueMap_.find(trackId);
3013     if (sqIt != sampleQueueMap_.end() && sqIt->second != nullptr) {
3014         sqIt->second->UpdateLastEndSamplePts(lastVideoBufferAbsPts);
3015     }
3016 }
3017 
3018 // now only for the flv living streaming case, callback by SampleQueue
OnSelectBitrateOk(int64_t startPts,uint32_t bitRate)3019 Status MediaDemuxer::OnSelectBitrateOk(int64_t startPts, uint32_t bitRate)
3020 {
3021     MEDIA_LOG_I("OnSelectBitrateOk startPts=" PUBLIC_LOG_D64 " bitRate=" PUBLIC_LOG_U32, startPts, bitRate);
3022     FALSE_RETURN_V_MSG_E(notifyBitrateTask_ != nullptr, Status::ERROR_NULL_POINTER, "notifyBitrateTask_ is nullptr");
3023     notifyBitrateTask_->SubmitJobOnce([this, startPts, bitRate] {
3024         HandleSelectBitrateBySampleQueue(startPts, bitRate);
3025     });
3026     return Status::OK;
3027 }
3028 
OnSampleQueueBufferAvailable(uint32_t queueId)3029 Status MediaDemuxer::OnSampleQueueBufferAvailable(uint32_t queueId)
3030 {
3031     MEDIA_LOG_I("OnSampleQueueBufferAvailable queueId=" PUBLIC_LOG_U32, queueId);
3032     AccelerateTrackTask(queueId);
3033     return Status::OK;
3034 }
3035 
OnSampleQueueBufferConsume(uint32_t queueId)3036 Status MediaDemuxer::OnSampleQueueBufferConsume(uint32_t queueId)
3037 {
3038     MEDIA_LOG_I("OnSampleQueueBufferConsume queueId=" PUBLIC_LOG_U32, queueId);
3039     uint32_t trackId = queueId;
3040     {
3041         std::unique_lock<std::mutex> stopLock(stopMutex_);
3042         if (isStopped_ || isThreadExit_) {
3043             return Status::OK;
3044         }
3045     }
3046     AutoLock lock(mapMutex_);
3047 
3048     auto track = trackMap_.find(trackId);
3049     if (track == trackMap_.end() || track->second == nullptr) {
3050         return Status::ERROR_INVALID_PARAMETER;
3051     }
3052     track->second->SetNotifySampleConsumerFlag(false);
3053 
3054     // accelerate SampleQueue toConsumer
3055     auto sampleConsumerTask = sampleConsumerTaskMap_.find(trackId);
3056     if (sampleConsumerTask == sampleConsumerTaskMap_.end()) {
3057         return Status::OK;
3058     }
3059     sampleConsumerTask->second->UpdateDelayTime();
3060 
3061     return Status::OK;
3062 }
3063 
HandleSelectBitrateBySampleQueue(int64_t startPts,uint32_t bitrate)3064 Status MediaDemuxer::HandleSelectBitrateBySampleQueue(int64_t startPts, uint32_t bitrate)
3065 {
3066     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::HandleSelectBitrateBySampleQueue");
3067     MEDIA_LOG_I("In bitrate=" PUBLIC_LOG_U32 " startPts=" PUBLIC_LOG_D64, bitrate, startPts);
3068     FALSE_RETURN_V(source_ != nullptr && demuxerPluginManager_ != nullptr && streamDemuxer_ != nullptr,
3069         Status::ERROR_NULL_POINTER);
3070 
3071     Status ret = Status::OK;
3072     source_->SetStartPts(startPts / US_TO_MS);
3073     source_->SelectBitRate(bitrate);
3074     MEDIA_LOG_I("source SelectBitrate bitrate=" PUBLIC_LOG_U32 " startPts=" PUBLIC_LOG_D64, bitrate, startPts);
3075 
3076     {
3077         AutoLock lock(mapMutex_);
3078         for (auto &sqIt : sampleQueueMap_) {
3079             FALSE_RETURN_V_MSG_E(
3080                 sqIt.second != nullptr, Status::ERROR_INVALID_STATE, "invalid trackId" PUBLIC_LOG_U32, sqIt.first);
3081             ret = sqIt.second->ResponseForSwitchDone(startPts);
3082             FALSE_RETURN_V_MSG_E(
3083                 ret == Status::OK, ret, "ResponseForSwitchDone failed trackId" PUBLIC_LOG_D64, startPts);
3084         }
3085     }
3086 
3087     int32_t videoStreamID = streamDemuxer_->GetNewVideoStreamID();
3088     demuxerPluginManager_->StopPlugin(videoStreamID, streamDemuxer_);
3089     ret = demuxerPluginManager_->StartPlugin(videoStreamID, streamDemuxer_);
3090     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Start plugin failed" PUBLIC_LOG_D32, videoStreamID);
3091 
3092     // update track map in track id change case
3093     if (demuxerPluginManager_->GetTrackTypeByTrackID(audioTrackId_) == TRACK_VIDEO) {
3094         demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, videoTrackId_, audioTrackId_);
3095     }
3096     if (demuxerPluginManager_->GetTrackTypeByTrackID(videoTrackId_) == TRACK_AUDIO) {
3097         demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, audioTrackId_, videoTrackId_);
3098     }
3099 
3100     InnerSelectTrack(static_cast<int32_t>(videoTrackId_));
3101     InnerSelectTrack(static_cast<int32_t>(audioTrackId_));
3102     MEDIA_LOG_I("Out bitrate=" PUBLIC_LOG_U32 " startPts=" PUBLIC_LOG_D64, bitrate, startPts);
3103     return Status::OK;
3104 }
3105 
IsIgonreBuffering()3106 bool MediaDemuxer::IsIgonreBuffering()
3107 {
3108     MEDIA_LOG_I("IsIgonreBuffering in");
3109     if (!IsRightMediaTrack(videoTrackId_, DemuxerTrackType::VIDEO)) {
3110         return false;
3111     }
3112     AutoLock lock(mapMutex_);
3113     auto sqIt = sampleQueueMap_.find(videoTrackId_);
3114     FALSE_RETURN_V_MSG_E(sqIt != sampleQueueMap_.end() && sqIt->second, false,
3115         "sampleQueue is nullptr");
3116     uint64_t cacheDuration = sqIt->second->GetCacheDuration();
3117     MEDIA_LOG_I("samplequeue cacheDuration=" PUBLIC_LOG_U64, cacheDuration);
3118     return cacheDuration > BUFFERING_WAVELINE_FOR_SAMPLE_QUEUE;
3119 }
3120 
RebootPlugin()3121 Status MediaDemuxer::RebootPlugin()
3122 {
3123     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::RebootPlugin");
3124     FALSE_RETURN_V(source_ != nullptr && demuxerPluginManager_ != nullptr && streamDemuxer_ != nullptr,
3125         Status::ERROR_NULL_POINTER);
3126     RestartAndClearBuffer();
3127     Status ret = Status::OK;
3128     int32_t videoStreamID = streamDemuxer_->GetNewVideoStreamID();
3129     demuxerPluginManager_->StopPlugin(videoStreamID, streamDemuxer_);
3130     ret = demuxerPluginManager_->StartPlugin(videoStreamID, streamDemuxer_);
3131     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Start plugin failed" PUBLIC_LOG_D32, videoStreamID);
3132     ret = InnerSelectTrack(static_cast<int32_t>(videoTrackId_));
3133     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "inner select video track failed");
3134     ret = InnerSelectTrack(static_cast<int32_t>(audioTrackId_));
3135     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "inner select audio track failed");
3136     return Status::OK;
3137 }
3138 
IsFlvLiveStream()3139 bool MediaDemuxer::IsFlvLiveStream()
3140 {
3141     return isFlvLiveStream_;
3142 }
3143 
GetCachedDuration()3144 uint64_t MediaDemuxer::GetCachedDuration()
3145 {
3146     FALSE_RETURN_V_MSG_E(source_ != nullptr, 0, "source_ is nullptr");
3147     demuxerCacheDuration_ = GetSampleQueueDuration();
3148     sourceCacheDuration_ = source_->GetCachedDuration();
3149     MEDIA_LOG_I("samplequeue cacheDuration=" PUBLIC_LOG_U64 ", sourceCache=" PUBLIC_LOG_U64, demuxerCacheDuration_,
3150         sourceCacheDuration_);
3151     return sourceCacheDuration_ + demuxerCacheDuration_;
3152 }
3153 
GetSampleQueueDuration()3154 uint64_t MediaDemuxer::GetSampleQueueDuration()
3155 {
3156     uint64_t sampleQueueDration = std::numeric_limits<uint64_t>::max();
3157     {
3158         AutoLock lock(mapMutex_);
3159         FALSE_RETURN_V_MSG_E(sampleQueueMap_.size() > 0, 0, "sampleQueueMap_ empty");
3160         for (auto sqIt = sampleQueueMap_.begin(); sqIt != sampleQueueMap_.end(); sqIt++) {
3161             FALSE_RETURN_V_MSG_E(sqIt->second != nullptr, 0, "sampleQueue empty");
3162             sampleQueueDration = std::min(sqIt->second->GetCacheDuration() / US_TO_MS, sampleQueueDration);
3163         }
3164     }
3165     return sampleQueueDration;
3166 }
3167 
UpdateSampleQueueCache()3168 void MediaDemuxer::UpdateSampleQueueCache()
3169 {
3170     FALSE_RETURN_NOLOG(isFlvLiveStream_);
3171     int64_t currentClockTimeMs = SteadyClock::GetCurrentTimeMs();
3172     if (lastClockTimeMs_ != 0 && currentClockTimeMs - lastClockTimeMs_ < UPDATE_SOURCE_CACHE_MS) {
3173         return;
3174     }
3175     lastClockTimeMs_ = currentClockTimeMs;
3176     demuxerCacheDuration_ = GetSampleQueueDuration();
3177     if (source_) {
3178         source_->SetExtraCache(demuxerCacheDuration_);
3179         MEDIA_LOG_I("samplequeue cacheDuration=" PUBLIC_LOG_U64 ", sourceCache=" PUBLIC_LOG_U64, demuxerCacheDuration_,
3180             source_->GetCachedDuration());
3181     }
3182 }
3183 
RestartAndClearBuffer()3184 void MediaDemuxer::RestartAndClearBuffer()
3185 {
3186     FALSE_RETURN_MSG(source_ != nullptr, "source_ is nullptr");
3187     return source_->RestartAndClearBuffer();
3188 }
3189 
IsFlvLive()3190 bool MediaDemuxer::IsFlvLive()
3191 {
3192     FALSE_RETURN_V_MSG_E(source_ != nullptr, false, "source_ is nullptr");
3193     return source_->IsFlvLive();
3194 }
3195 
IsNeedMapToInnerTrackID()3196 bool MediaDemuxer::IsNeedMapToInnerTrackID()
3197 {
3198     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "demuxerPluginManager_ is nullptr");
3199     return (isFlvLiveStream_ || demuxerPluginManager_->IsDash() ||
3200         demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_) != -1);
3201 }
3202 
3203 } // namespace Media
3204 } // namespace OHOS