• 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 #include <iomanip>
24 #include <openssl/sha.h>
25 #include <sstream>
26 
27 #include "avcodec_common.h"
28 #include "avcodec_trace.h"
29 #include "cpp_ext/type_traits_ext.h"
30 #include "buffer/avallocator.h"
31 #include "common/event.h"
32 #include "format.h"
33 #include "common/log.h"
34 #include "hisysevent.h"
35 #include "meta/media_types.h"
36 #include "meta/meta.h"
37 #include "osal/utils/dump_buffer.h"
38 #include "plugin/plugin_info.h"
39 #include "plugin/plugin_buffer.h"
40 #include "plugin/plugin_list.h"
41 #include "source/source.h"
42 #include "stream_demuxer.h"
43 #include "media_core.h"
44 #include "osal/utils/dump_buffer.h"
45 #include "demuxer_plugin_manager.h"
46 #include "media_demuxer_pts_functions.cpp"
47 #include "avcodec_log.h"
48 #include "scoped_timer.h"
49 #include "param_wrapper.h"
50 #include "parameters.h"
51 #include "scope_guard.h"
52 #include "syspara/parameters.h"
53 
54 namespace {
55 const std::string DUMP_PARAM = "a";
56 const std::string DUMP_DEMUXER_AUDIO_FILE_NAME = "player_demuxer_audio_output.es";
57 const std::string DUMP_DEMUXER_VIDEO_FILE_NAME = "player_demuxer_video_output.es";
58 const std::string DEMUXER_PLUGIN_NAME_HEADER = "avdemux_";
59 const char DEMUXER_PLUGIN_NAME_DELIMITER = ',';
60 static constexpr char PERFORMANCE_STATS[] = "PERFORMANCE";
61 static constexpr int32_t INVALID_STREAM_OR_TRACK_ID = -1;
62 static constexpr int32_t SKIP_NEXT_OPEN_GOP_CNT = 2;
63 constexpr uint32_t THREAD_PRIORITY_41 = 7;
64 constexpr uint32_t MAX_VIDEO_LEAD_TIME_ON_MUTE_US = 34000; // Maximum video frame advance time during video mute
65 constexpr uint32_t SAMPLE_QUEUE_SIZE_ON_MUTE = 50; // After video mute, sampleSize increases to 50
66 constexpr uint32_t SAMPLE_QUEUE_ADD_SIZE_ON_MUTE = 20; // When samplequeue is full on mute, samplequeue size add 20
67 std::map<OHOS::Media::TrackType, OHOS::Media::StreamType> TRACK_TO_STREAM_MAP = {
68     {OHOS::Media::TrackType::TRACK_VIDEO, OHOS::Media::StreamType::VIDEO},
69     {OHOS::Media::TrackType::TRACK_AUDIO, OHOS::Media::StreamType::AUDIO},
70     {OHOS::Media::TrackType::TRACK_SUBTITLE, OHOS::Media::StreamType::SUBTITLE},
71     {OHOS::Media::TrackType::TRACK_INVALID, OHOS::Media::StreamType::MIXED}
72 };
73 } // namespace
74 
75 namespace OHOS {
76 namespace Media {
77 constexpr uint32_t REQUEST_BUFFER_TIMEOUT = 0; // Requesting buffer overtimes 0ms means no retry
78 constexpr int32_t START = 1;
79 constexpr int32_t PAUSE = 2;
80 constexpr bool SEEK_TO_EOS = true;
81 constexpr uint32_t RETRY_DELAY_TIME_US = 100000; // 100ms, Delay time for RETRY if no buffer in avbufferqueue producer.
82 constexpr uint32_t NEXT_DELAY_TIME_US = 10; // 10us is ok
83 constexpr uint32_t SAMPLE_LOOP_RETRY_TIME_US = 20000;
84 constexpr uint32_t SAMPLE_LOOP_DELAY_TIME_US = 100000;
85 constexpr uint32_t SAMPLE_FLOW_CONTROL_MIN_SAMPLE_DURATION_US = 200000;
86 constexpr uint32_t SAMPLE_FLOW_CONTROL_RATE_POW = 6; // 2^6
87 constexpr int64_t UPDATE_SOURCE_CACHE_MS = 100;
88 
89 constexpr uint32_t BUFFERING_WAVELINE_FOR_SAMPLE_QUEUE = 1000000;
90 constexpr double DECODE_RATE_THRESHOLD = 0.05;   // allow actual rate exceeding 5%
91 constexpr uint32_t REQUEST_FAILED_RETRY_TIMES = 12000; // Max times for RETRY if no buffer in avbufferqueue producer.
92 constexpr uint32_t SAMPLE_LOOP_ACQUIRE_FAILED_LOG_POW2 = 3;
93 constexpr uint32_t SAMPLE_LOOP_REQUEST_FAILED_LOG_POW2 = 8;
94 constexpr int32_t US_TO_S = 1000000;
95 constexpr int32_t US_TO_MS = 1000;
96 constexpr int32_t SAMPLE_BUFFER_SIZE_EXTRA = 128;
97 constexpr int64_t SEEK_ONLINE_WARNING_MS = 600;
98 constexpr int64_t SEEKCLOSEST_ONLINE_WARNING_MS = 800;
99 constexpr int64_t SEEK_LOCAL_WARNING_MS = 78;
100 constexpr int64_t SEEKCLOSEST_LOCAL_WARNING_MS = 309;
101 constexpr int64_t READSAMPLE_AUIDO_WARNING_MS = 50;
102 constexpr int64_t READSAMPLE_WARNING_MS = 100;
103 constexpr int32_t CONVERT_PACKET_ERROR_MAX_COUNT = 30;
104 const std::unordered_map<PluginDfxEventType, std::pair<std::string, DfxEventType>> DFX_EVENT_MAP = {
105     { PluginDfxEventType::PERF_SOURCE, { "SRC", DfxEventType::DFX_INFO_PERF_REPORT } }
106 };
107 constexpr uint32_t LIMIT_MEMORY_REPORT_COUNT = 1000;
108 constexpr int32_t DFX_BUFFER_QUEUE_SIZE_MAX = 50;
109 
110 static const std::map<TrackType, DemuxerTrackType> TRACK_MAP = {
111     {TrackType::TRACK_AUDIO, DemuxerTrackType::AUDIO},
112     {TrackType::TRACK_VIDEO, DemuxerTrackType::VIDEO},
113     {TrackType::TRACK_SUBTITLE, DemuxerTrackType::SUBTITLE},
114 };
115 
116 static const std::map<DemuxerTrackType, std::string> TRACK_SUFFIX_MAP = {
117     {DemuxerTrackType::VIDEO, "V"},
118     {DemuxerTrackType::AUDIO, "A"},
119     {DemuxerTrackType::SUBTITLE, "S"},
120 };
121 enum SceneCode : int32_t {
122     /**
123      * This option is used to mark parser ref for dragging play scene.
124      */
125     AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY = 3 // scene code of parser ref for dragging play is 3
126 };
127 
128 class MediaDemuxer::AVBufferQueueProducerListener : public IRemoteStub<IProducerListener> {
129 public:
AVBufferQueueProducerListener(int32_t trackId,std::shared_ptr<MediaDemuxer> demuxer,std::unique_ptr<Task> & notifyTask)130     explicit AVBufferQueueProducerListener(int32_t trackId, std::shared_ptr<MediaDemuxer> demuxer,
131         std::unique_ptr<Task>& notifyTask) : trackId_(trackId), demuxer_(demuxer), notifyTask_(std::move(notifyTask)) {}
132 
133     virtual ~AVBufferQueueProducerListener() = default;
OnRemoteRequest(uint32_t code,MessageParcel & arguments,MessageParcel & reply,MessageOption & option)134     int OnRemoteRequest(uint32_t code, MessageParcel& arguments, MessageParcel& reply, MessageOption& option) override
135     {
136         return IPCObjectStub::OnRemoteRequest(code, arguments, reply, option);
137     }
OnBufferAvailable()138     void OnBufferAvailable() override
139     {
140         MEDIA_LOG_DD("Buffer available for track " PUBLIC_LOG_D32, trackId_);
141         if (notifyTask_ == nullptr) {
142             return;
143         }
144         notifyTask_->SubmitJobOnce([this] {
145             auto demuxer = demuxer_.lock();
146             if (demuxer) {
147                 demuxer->OnBufferAvailable(trackId_);
148             }
149         });
150     }
151 private:
152     int32_t trackId_{0};
153     std::weak_ptr<MediaDemuxer> demuxer_;
154     std::unique_ptr<Task> notifyTask_;
155 };
156 
157 class MediaDemuxer::TrackWrapper {
158 public:
TrackWrapper(int32_t trackId,sptr<IProducerListener> listener,std::shared_ptr<MediaDemuxer> demuxer)159     explicit TrackWrapper(int32_t trackId, sptr<IProducerListener> listener, std::shared_ptr<MediaDemuxer> demuxer)
160         : trackId_(trackId), listener_(listener), demuxer_(demuxer)
161     {
162         MEDIA_LOG_D("TrackWrapper TrackId:" PUBLIC_LOG_U32, trackId_);
163     }
164 
GetProducerListener()165     sptr<IProducerListener> GetProducerListener()
166     {
167         return listener_;
168     }
SetNotifyFlag(bool isNotifyNeeded)169     void SetNotifyFlag(bool isNotifyNeeded)
170     {
171         isNotifyNeeded_ = isNotifyNeeded;
172         MEDIA_LOG_DD("TrackId:" PUBLIC_LOG_D32 ", isNotifyNeeded:" PUBLIC_LOG_D32,
173             trackId_, isNotifyNeeded);
174     }
GetNotifyFlag()175     bool GetNotifyFlag()
176     {
177         return isNotifyNeeded_.load();
178     }
179 
SetNotifySampleConsumerFlag(bool isNotifySampleConsumerNeeded)180     void SetNotifySampleConsumerFlag(bool isNotifySampleConsumerNeeded)
181     {
182         isNotifySampleConsumerNeeded_ = isNotifySampleConsumerNeeded;
183         MEDIA_LOG_DD("TrackId:" PUBLIC_LOG_D32 ", isNotifySampleConsumerNeeded:" PUBLIC_LOG_D32,
184             trackId_, isNotifySampleConsumerNeeded);
185     }
186 
GetNotifySampleConsumerFlag() const187     bool GetNotifySampleConsumerFlag() const
188     {
189         return isNotifySampleConsumerNeeded_.load();
190     }
191 private:
192     std::atomic<bool> isNotifyNeeded_{false};
193     std::atomic<bool> isNotifySampleConsumerNeeded_{false};
194     int32_t trackId_{0};
195     sptr<IProducerListener> listener_ = nullptr;
196     std::weak_ptr<MediaDemuxer> demuxer_;
197 };
198 
MediaDemuxer()199 MediaDemuxer::MediaDemuxer()
200     : seekable_(Plugins::Seekable::INVALID),
201       subSeekable_(Plugins::Seekable::INVALID),
202       uri_(),
203       mediaDataSize_(0),
204       subMediaDataSize_(0),
205       source_(std::make_shared<Source>()),
206       subtitleSource_(std::make_shared<Source>()),
207       mediaMetaData_(),
208       bufferQueueMap_(),
209       bufferMap_(),
210       sampleQueueMap_(),
211       eventReceiver_(),
212       streamDemuxer_(),
213       demuxerPluginManager_(std::make_shared<DemuxerPluginManager>())
214 {
215     MEDIA_LOG_D("In");
216     InitEnableSampleQueueFlag();
217     InitEnableDfxBufferQueue();
218 
219     funcBeforeReadSampleMap_.emplace(TrackType::TRACK_SUBTITLE,
220         [this](int32_t trackId) { return DoBeforeSubtitleTrackReadLoop(trackId); });
221     std::string enableAsyncDemuxer;
222     int32_t result = OHOS::system::GetStringParameter("sys.media.enable.async.demuxer", enableAsyncDemuxer, "");
223     if (result == 0 && !enableAsyncDemuxer.empty() && enableAsyncDemuxer == "false") {
224         enableAsyncDemuxer_ = false;
225     }
226 }
227 
~MediaDemuxer()228 MediaDemuxer::~MediaDemuxer()
229 {
230     MEDIA_LOG_D("In");
231     ResetInner();
232     if (parserRefInfoTask_ != nullptr) {
233         parserRefInfoTask_->Stop();
234         parserRefInfoTask_ = nullptr;
235     }
236     demuxerPluginManager_ = nullptr;
237     source_ = nullptr;
238     eventReceiver_ = nullptr;
239     eosMap_.clear();
240     requestBufferErrorCountMap_.clear();
241     streamDemuxer_ = nullptr;
242     localDrmInfos_.clear();
243 }
244 
GetCurFFmpegPlugin()245 std::shared_ptr<Plugins::DemuxerPlugin> MediaDemuxer::GetCurFFmpegPlugin()
246 {
247     int32_t tempTrackId = (IsValidTrackId(videoTrackId_) ? videoTrackId_ : audioTrackId_);
248     int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(tempTrackId);
249     return demuxerPluginManager_->GetPluginByStreamID(streamID);
250 }
251 
ReportSceneCodeForDemuxer(SceneCode scene)252 static void ReportSceneCodeForDemuxer(SceneCode scene)
253 {
254     if (scene != SceneCode::AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY) {
255         return;
256     }
257     MEDIA_LOG_I("Scene %{public}d", scene);
258     auto now =
259         std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
260     int32_t ret = HiSysEventWrite(
261         PERFORMANCE_STATS, "CPU_SCENE_ENTRY", OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PACKAGE_NAME",
262         "media_service", "SCENE_ID", std::to_string(scene).c_str(), "HAPPEN_TIME", now.count());
263     if (ret != MSERR_OK) {
264         MEDIA_LOG_W("Report failed");
265     }
266 }
267 
IsRefParserSupported()268 bool MediaDemuxer::IsRefParserSupported()
269 {
270     FALSE_RETURN_V_MSG_E(IsValidTrackId(videoTrackId_), false, "Video track is nullptr");
271     std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
272     FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, false, "Demuxer plugin is nullptr");
273     return videoPlugin->IsRefParserSupported();
274 }
275 
StartReferenceParser(int64_t startTimeMs,bool isForward)276 Status MediaDemuxer::StartReferenceParser(int64_t startTimeMs, bool isForward)
277 {
278     FALSE_RETURN_V_MSG_E(startTimeMs >= 0, Status::ERROR_UNKNOWN,
279                          "Start failed, startTimeMs: " PUBLIC_LOG_D64, startTimeMs);
280     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
281     FALSE_RETURN_V_MSG_E(IsValidTrackId(videoTrackId_), Status::ERROR_UNKNOWN, "Video track is nullptr");
282     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
283     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
284     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
285     Status ret = plugin->ParserRefUpdatePos(startTimeMs, isForward);
286     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "ParserRefUpdatePos failed");
287     if (isFirstParser_) {
288         isFirstParser_ = false;
289         FALSE_RETURN_V_MSG(source_->GetSeekable() == Plugins::Seekable::SEEKABLE,
290             Status::ERROR_INVALID_OPERATION, "Unsupport online video");
291         parserRefInfoTask_ = std::make_unique<Task>("ParserRefInfo", playerId_);
292         parserRefInfoTask_->RegisterJob([this] { return ParserRefInfo(); });
293         ReportSceneCodeForDemuxer(SceneCode::AV_META_SCENE_PARSE_REF_FOR_DRAGGING_PLAY);
294         parserRefInfoTask_->Start();
295     }
296     TryReclaimParserTask();
297     return ret;
298 }
299 
TryReclaimParserTask()300 void MediaDemuxer::TryReclaimParserTask()
301 {
302     std::lock_guard<std::mutex> lock(parserTaskMutex_);
303     if (isParserTaskEnd_ && parserRefInfoTask_ != nullptr) {
304         parserRefInfoTask_->Stop();
305         parserRefInfoTask_ = nullptr;
306         MEDIA_LOG_I("Success to reclaim parser task");
307     }
308 }
309 
ParserRefInfo()310 int64_t MediaDemuxer::ParserRefInfo()
311 {
312     FALSE_RETURN_V_MSG_D(demuxerPluginManager_ != nullptr, 0, "Plugin manager is nullptr");
313     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
314     FALSE_RETURN_V_MSG_D(plugin != nullptr, 0, "Demuxer plugin is nullptr");
315     Status ret = plugin->ParserRefInfo();
316     std::lock_guard<std::mutex> lock(parserTaskMutex_);
317     if ((ret == Status::OK || ret == Status::ERROR_UNKNOWN) && parserRefInfoTask_ != nullptr) {
318         parserRefInfoTask_->Stop();
319         isParserTaskEnd_ = true;
320         MEDIA_LOG_I("Success to stop");
321     } else {
322         MEDIA_LOG_I("ret is " PUBLIC_LOG_D32, ret);
323     }
324     return 0;
325 }
326 
GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample,FrameLayerInfo & frameLayerInfo)327 Status MediaDemuxer::GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample, FrameLayerInfo &frameLayerInfo)
328 {
329     FALSE_RETURN_V_MSG_E(videoSample != nullptr, Status::ERROR_NULL_POINTER, "VideoSample is nullptr");
330     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
331     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
332     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
333     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
334     TryReclaimParserTask();
335     Status ret = plugin->GetFrameLayerInfo(videoSample, frameLayerInfo);
336     if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
337         return Status::ERROR_AGAIN;
338     }
339     return ret;
340 }
341 
GetFrameLayerInfo(uint32_t frameId,FrameLayerInfo & frameLayerInfo)342 Status MediaDemuxer::GetFrameLayerInfo(uint32_t frameId, FrameLayerInfo &frameLayerInfo)
343 {
344     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
345     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
346     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
347     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
348     TryReclaimParserTask();
349     Status ret = plugin->GetFrameLayerInfo(frameId, frameLayerInfo);
350     if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
351         return Status::ERROR_AGAIN;
352     }
353     return ret;
354 }
355 
GetGopLayerInfo(uint32_t gopId,GopLayerInfo & gopLayerInfo)356 Status MediaDemuxer::GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo)
357 {
358     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
359     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
360     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
361     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
362     TryReclaimParserTask();
363     Status ret = plugin->GetGopLayerInfo(gopId, gopLayerInfo);
364     if (ret == Status::ERROR_NULL_POINTER && parserRefInfoTask_ != nullptr) {
365         return Status::ERROR_AGAIN;
366     }
367     return ret;
368 }
369 
RegisterVideoStreamReadyCallback(const std::shared_ptr<VideoStreamReadyCallback> & callback)370 void MediaDemuxer::RegisterVideoStreamReadyCallback(const std::shared_ptr<VideoStreamReadyCallback> &callback)
371 {
372     std::unique_lock<std::mutex> draggingLock(draggingMutex_);
373     MEDIA_LOG_I("In");
374     VideoStreamReadyCallback_ = callback;
375 }
376 
DeregisterVideoStreamReadyCallback()377 void MediaDemuxer::DeregisterVideoStreamReadyCallback()
378 {
379     std::unique_lock<std::mutex> draggingLock(draggingMutex_);
380     MEDIA_LOG_I("In");
381     VideoStreamReadyCallback_ = nullptr;
382     EnterDraggingOpenGopCnt();
383 }
384 
GetIFramePos(std::vector<uint32_t> & IFramePos)385 Status MediaDemuxer::GetIFramePos(std::vector<uint32_t> &IFramePos)
386 {
387     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
388     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
389     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
390     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
391     TryReclaimParserTask();
392     return plugin->GetIFramePos(IFramePos);
393 }
394 
Dts2FrameId(int64_t dts,uint32_t & frameId)395 Status MediaDemuxer::Dts2FrameId(int64_t dts, uint32_t &frameId)
396 {
397     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
398     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
399     std::shared_ptr<Plugins::DemuxerPlugin> plugin = GetCurFFmpegPlugin();
400     FALSE_RETURN_V_MSG_E(plugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
401     TryReclaimParserTask();
402     return plugin->Dts2FrameId(dts, frameId);
403 }
404 
SeekMs2FrameId(int64_t seekMs,uint32_t & frameId)405 Status MediaDemuxer::SeekMs2FrameId(int64_t seekMs, uint32_t &frameId)
406 {
407     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
408     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
409     std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
410     FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
411     TryReclaimParserTask();
412     return videoPlugin->SeekMs2FrameId(seekMs, frameId);
413 }
414 
FrameId2SeekMs(uint32_t frameId,int64_t & seekMs)415 Status MediaDemuxer::FrameId2SeekMs(uint32_t frameId, int64_t &seekMs)
416 {
417     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
418     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
419     std::shared_ptr<Plugins::DemuxerPlugin> videoPlugin = GetCurFFmpegPlugin();
420     FALSE_RETURN_V_MSG_E(videoPlugin != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
421     TryReclaimParserTask();
422     return videoPlugin->FrameId2SeekMs(frameId, seekMs);
423 }
424 
OnBufferAvailable(int32_t trackId)425 void MediaDemuxer::OnBufferAvailable(int32_t trackId)
426 {
427     MEDIA_LOG_DD("Buffer available track " PUBLIC_LOG_D32, trackId);
428     if (GetEnableSampleQueueFlag()) {
429         UpdateLastVideoBufferAbsPts(trackId);
430         // buffer is available trigger SampleConsumer working task to run immediately.
431         AccelerateSampleConsumerTask(trackId);
432     } else {
433         // buffer is available trigger demuxer track working task to run immediately.
434         AccelerateTrackTask(trackId);
435     }
436 }
437 
AccelerateSampleConsumerTask(int32_t trackId)438 void MediaDemuxer::AccelerateSampleConsumerTask(int32_t trackId)
439 {
440     MEDIA_TRACE_DEBUG("MediaDemuxer::AccelerateSampleConsumerTask");
441     {
442         std::unique_lock<std::mutex> stopLock(stopMutex_);
443         if (isStopped_ || isThreadExit_) {
444             return;
445         }
446     }
447     AutoLock lock(mapMutex_);
448     auto track = trackMap_.find(trackId);
449     if (track == trackMap_.end() || track->second == nullptr || !track->second->GetNotifySampleConsumerFlag()) {
450         return;
451     }
452     track->second->SetNotifySampleConsumerFlag(false);
453 
454     auto sampleConsumerTask = sampleConsumerTaskMap_.find(trackId);
455     if (sampleConsumerTask == sampleConsumerTaskMap_.end()) {
456         return;
457     }
458     sampleConsumerTask->second->UpdateDelayTime();
459 }
460 
AccelerateTrackTask(int32_t trackId)461 void MediaDemuxer::AccelerateTrackTask(int32_t trackId)
462 {
463     {
464         std::unique_lock<std::mutex> stopLock(stopMutex_);
465         if (isStopped_ || isThreadExit_) {
466             return;
467         }
468     }
469     AutoLock lock(mapMutex_);
470 
471     auto track = trackMap_.find(trackId);
472     if (track == trackMap_.end() || track->second == nullptr || !track->second->GetNotifyFlag()) {
473         return;
474     }
475     track->second->SetNotifyFlag(false);
476 
477     auto task = taskMap_.find(trackId);
478     if (task == taskMap_.end()) {
479         return;
480     }
481     MEDIA_LOG_DD("Accelerate track " PUBLIC_LOG_D32, trackId);
482     task->second->UpdateDelayTime();
483 }
484 
SetTrackNotifyFlag(int32_t trackId,bool isNotifyNeeded)485 void MediaDemuxer::SetTrackNotifyFlag(int32_t trackId, bool isNotifyNeeded)
486 {
487     // This function is called in demuxer track working thread, and if track info exists it is valid.
488     auto track = trackMap_.find(trackId);
489     if (track != trackMap_.end() && track->second != nullptr) {
490         track->second->SetNotifyFlag(isNotifyNeeded);
491     }
492 }
493 
SetTrackNotifySampleConsumerFlag(int32_t trackId,bool isNotifySampleConsumerNeeded)494 void MediaDemuxer::SetTrackNotifySampleConsumerFlag(int32_t trackId, bool isNotifySampleConsumerNeeded)
495 {
496     // This function is called in samplequeue consumer working thread, and if track info exists it is valid.
497     auto track = trackMap_.find(trackId);
498     if (track != trackMap_.end() && track->second != nullptr) {
499         track->second->SetNotifySampleConsumerFlag(isNotifySampleConsumerNeeded);
500     }
501 }
502 
GetBitRates(std::vector<uint32_t> & bitRates)503 Status MediaDemuxer::GetBitRates(std::vector<uint32_t> &bitRates)
504 {
505     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
506     return source_->GetBitRates(bitRates);
507 }
508 
GetMediaKeySystemInfo(std::multimap<std::string,std::vector<uint8_t>> & infos)509 Status MediaDemuxer::GetMediaKeySystemInfo(std::multimap<std::string, std::vector<uint8_t>> &infos)
510 {
511     MEDIA_LOG_I("In");
512     std::shared_lock<std::shared_mutex> lock(drmMutex);
513     infos = localDrmInfos_;
514     return Status::OK;
515 }
516 
GetDownloadInfo(DownloadInfo & downloadInfo)517 Status MediaDemuxer::GetDownloadInfo(DownloadInfo& downloadInfo)
518 {
519     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
520     return source_->GetDownloadInfo(downloadInfo);
521 }
522 
GetPlaybackInfo(PlaybackInfo & playbackInfo)523 Status MediaDemuxer::GetPlaybackInfo(PlaybackInfo& playbackInfo)
524 {
525     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_INVALID_OPERATION, "Source is nullptr");
526     return source_->GetPlaybackInfo(playbackInfo);
527 }
528 
SetDrmCallback(const std::shared_ptr<OHOS::MediaAVCodec::AVDemuxerCallback> & callback)529 void MediaDemuxer::SetDrmCallback(const std::shared_ptr<OHOS::MediaAVCodec::AVDemuxerCallback> &callback)
530 {
531     MEDIA_LOG_I("In");
532     drmCallback_ = callback;
533     bool isExisted = IsLocalDrmInfosExisted();
534     if (isExisted) {
535         MEDIA_LOG_D("Already received drminfo and report");
536         ReportDrmInfos(localDrmInfos_);
537     }
538 }
539 
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)540 void MediaDemuxer::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> &receiver)
541 {
542     eventReceiver_ = receiver;
543 }
544 
SetPlayerId(std::string playerId)545 void MediaDemuxer::SetPlayerId(std::string playerId)
546 {
547     playerId_ = playerId;
548 }
549 
SetDumpInfo(bool isDump,uint64_t instanceId)550 void MediaDemuxer::SetDumpInfo(bool isDump, uint64_t instanceId)
551 {
552     (void)instanceId;
553     auto tid = gettid();
554     if (isDump && tid <= 0) {
555         MEDIA_LOG_W("Cannot dump with tid <= 0.");
556         return;
557     }
558     dumpPrefix_ = std::to_string(tid);
559     isDump_ = isDump;
560 }
561 
GetDuration(int64_t & durationMs)562 bool MediaDemuxer::GetDuration(int64_t& durationMs)
563 {
564     AutoLock lock(mapMutex_);
565     if (source_ == nullptr) {
566         durationMs = -1;
567         return false;
568     }
569     MEDIA_TRACE_DEBUG("MediaDemuxer::GetDuration");
570     seekable_ = source_->GetSeekable();
571 
572     FALSE_LOG(seekable_ != Seekable::INVALID);
573     if (source_->IsSeekToTimeSupported()) {
574         duration_ = source_->GetDuration();
575         if (duration_ != Plugins::HST_TIME_NONE) {
576             MEDIA_LOG_I("Hls: " PUBLIC_LOG_D64, duration_);
577             mediaMetaData_.globalMeta->Set<Tag::MEDIA_DURATION>(Plugins::HstTime2Us(duration_));
578         }
579         MEDIA_LOG_I("SeekToTime");
580         return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
581     }
582 
583     // not hls and seekable
584     if (seekable_ == Plugins::Seekable::SEEKABLE) {
585         duration_ = source_->GetDuration();
586         if (duration_ != Plugins::HST_TIME_NONE) {
587             MEDIA_LOG_I("Not hls: " PUBLIC_LOG_D64, duration_);
588             mediaMetaData_.globalMeta->Set<Tag::MEDIA_DURATION>(Plugins::HstTime2Us(duration_));
589         }
590         MEDIA_LOG_I("Seekble");
591         return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
592     }
593     MEDIA_LOG_I("Other");
594     return mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(durationMs);
595 }
596 
GetDrmInfosUpdated(const std::multimap<std::string,std::vector<uint8_t>> & newInfos,std::multimap<std::string,std::vector<uint8_t>> & result)597 bool MediaDemuxer::GetDrmInfosUpdated(const std::multimap<std::string, std::vector<uint8_t>> &newInfos,
598     std::multimap<std::string, std::vector<uint8_t>> &result)
599 {
600     MEDIA_LOG_D("In");
601     std::unique_lock<std::shared_mutex> lock(drmMutex);
602     for (auto &newItem : newInfos) {
603         if (localDrmInfos_.find(newItem.first) == localDrmInfos_.end()) {
604             MEDIA_LOG_D("Uuid doesn't exist, update");
605             result.insert(newItem);
606             localDrmInfos_.insert(newItem);
607             continue;
608         }
609         auto pos = localDrmInfos_.equal_range(newItem.first);
610         bool isSame = false;
611         for (; pos.first != pos.second; ++pos.first) {
612             if (newItem.second == pos.first->second) {
613                 MEDIA_LOG_D("Uuid exists and the pssh is same, not update");
614                 isSame = true;
615                 break;
616             }
617         }
618         if (!isSame) {
619             MEDIA_LOG_D("Uuid exists but pssh not same, update");
620             result.insert(newItem);
621             localDrmInfos_.insert(newItem);
622         }
623     }
624     return !result.empty();
625 }
626 
IsLocalDrmInfosExisted()627 bool MediaDemuxer::IsLocalDrmInfosExisted()
628 {
629     std::shared_lock<std::shared_mutex> lock(drmMutex);
630     return !localDrmInfos_.empty();
631 }
632 
ReportDrmInfos(const std::multimap<std::string,std::vector<uint8_t>> & info)633 Status MediaDemuxer::ReportDrmInfos(const std::multimap<std::string, std::vector<uint8_t>> &info)
634 {
635     MEDIA_LOG_I("In");
636     FALSE_RETURN_V_MSG_E(drmCallback_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Drm callback is nullptr");
637     MEDIA_LOG_D("Filter will update drminfo");
638     drmCallback_->OnDrmInfoChanged(info);
639     return Status::OK;
640 }
641 
ProcessDrmInfos()642 Status MediaDemuxer::ProcessDrmInfos()
643 {
644     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "Source is nullptr");
645     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
646     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
647     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
648 
649     std::multimap<std::string, std::vector<uint8_t>> drmInfo;
650     Status ret = pluginTemp->GetDrmInfo(drmInfo);
651     if (ret == Status::OK && !drmInfo.empty()) {
652         MEDIA_LOG_D("Get drminfo success");
653         std::multimap<std::string, std::vector<uint8_t>> infosUpdated;
654         bool isUpdated = GetDrmInfosUpdated(drmInfo, infosUpdated);
655         if (isUpdated) {
656             return ReportDrmInfos(infosUpdated);
657         } else {
658             MEDIA_LOG_D("Received drminfo but not update");
659         }
660     } else {
661         if (ret != Status::OK) {
662             MEDIA_LOG_D("Get drminfo failed, ret:" PUBLIC_LOG_D32, static_cast<int32_t>(ret));
663         }
664     }
665     return Status::OK;
666 }
667 
AddDemuxerCopyTask(int32_t trackId,TaskType type)668 Status MediaDemuxer::AddDemuxerCopyTask(int32_t trackId, TaskType type)
669 {
670     std::string taskName = "Demux";
671     switch (type) {
672         case TaskType::VIDEO: {
673             taskName += "V";
674             break;
675         }
676         case TaskType::AUDIO: {
677             taskName += "A";
678             break;
679         }
680         case TaskType::SUBTITLE: {
681             taskName += "S";
682             break;
683         }
684         default: {
685             MEDIA_LOG_E("Add demuxer task failed, unknow task type:" PUBLIC_LOG_D32, static_cast<int32_t>(type));
686             return Status::ERROR_UNKNOWN;
687         }
688     }
689 
690     std::unique_ptr<Task> task = std::make_unique<Task>(taskName, playerId_, type);
691     FALSE_RETURN_V_MSG_W(task != nullptr, Status::OK,
692         "Create task failed, track:" PUBLIC_LOG_D32 ", type:" PUBLIC_LOG_D32,
693         trackId, static_cast<int32_t>(type));
694 
695     taskMap_[trackId] = std::move(task);
696     UpdateThreadPriority(trackId);
697     taskMap_[trackId]->RegisterJob([this, trackId] { return ReadLoop(trackId); });
698 
699     // To wake up DEMUXER TRACK WORKING TASK immediately on input buffer available.
700     std::unique_ptr<Task> notifyTask =
701         std::make_unique<Task>(taskName + "N", playerId_, type, TaskPriority::NORMAL, false);
702     FALSE_RETURN_V_MSG_W(notifyTask != nullptr, Status::OK,
703         "Create notify task failed, track:" PUBLIC_LOG_D32 ", type:" PUBLIC_LOG_D32,
704         trackId, static_cast<int32_t>(type));
705 
706     sptr<IProducerListener> listener =
707         OHOS::sptr<AVBufferQueueProducerListener>::MakeSptr(trackId, shared_from_this(), notifyTask);
708     FALSE_RETURN_V_MSG_W(listener != nullptr, Status::OK,
709         "Create listener failed, track:" PUBLIC_LOG_D32 ", type:" PUBLIC_LOG_D32,
710         trackId, static_cast<int32_t>(type));
711 
712     trackMap_.emplace(trackId, std::make_shared<TrackWrapper>(trackId, listener, shared_from_this()));
713     return Status::OK;
714 }
715 
UpdateThreadPriority(int32_t trackId)716 void MediaDemuxer::UpdateThreadPriority(int32_t trackId)
717 {
718 #ifdef SUPPORT_START_STOP_ON_DEMAND
719     taskMap_[trackId]->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
720     if (GetEnableSampleQueueFlag()) {
721         sampleConsumerTaskMap_[trackId]->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
722     }
723 #else
724     if (!HasVideo() && trackId == audioTrackId_) {
725         taskMap_[trackId]->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
726         if (GetEnableSampleQueueFlag()) {
727             sampleConsumerTaskMap_[trackId]->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
728         }
729         MEDIA_LOG_I("Update thread priority for audio-only source");
730     }
731 #endif
732 }
733 
AddDemuxerCopyTaskByTrack(int32_t trackId,DemuxerTrackType type)734 Status MediaDemuxer::AddDemuxerCopyTaskByTrack(int32_t trackId, DemuxerTrackType type)
735 {
736     int32_t trackType = static_cast<int32_t>(type);
737     std::string taskName = "Demux" + TRACK_SUFFIX_MAP.at(type);
738     auto task = std::make_unique<Task>(taskName, playerId_, TaskType::DEMUXER);
739     FALSE_RETURN_V_MSG_W(task != nullptr, Status::ERROR_NULL_POINTER,
740         "Create task failed, track:" PUBLIC_LOG_D32 ",DemuxerTrackType:" PUBLIC_LOG_D32, trackId, trackType);
741     taskMap_[trackId] = std::move(task);
742     taskMap_[trackId]->RegisterJob([this, trackId] { return ReadLoop(trackId); });
743 
744     std::string sampleConsumerTaskName = "SampleConsumer" + TRACK_SUFFIX_MAP.at(type);
745     auto sampleConsumerTask = std::make_unique<Task>(sampleConsumerTaskName, playerId_, TaskType::DECODER);
746     FALSE_RETURN_V_MSG_W(sampleConsumerTask != nullptr, Status::ERROR_NULL_POINTER,
747         "Create sampleConsumerTask failed, track:" PUBLIC_LOG_D32 ",DemuxerTrackType:" PUBLIC_LOG_D32,
748         trackId, trackType);
749     sampleConsumerTaskMap_[trackId] = std::move(sampleConsumerTask);
750     sampleConsumerTaskMap_[trackId]->RegisterJob([this, trackId] { return SampleConsumerLoop(trackId); });
751     UpdateThreadPriority(trackId);
752     if (notifySampleConsumeTask_ == nullptr) {
753         notifySampleConsumeTask_
754             = std::make_unique<Task>("SAM_CON", playerId_, TaskType::DECODER, TaskPriority::HIGH, false);
755         FALSE_RETURN_V_MSG_W(notifySampleConsumeTask_ != nullptr, Status::ERROR_NULL_POINTER,
756             "Create notifyConsume task failed, track:" PUBLIC_LOG_D32 ", TrackType:" PUBLIC_LOG_D32,
757             trackId, trackType);
758     }
759 
760     if (notifySampleProduceTask_ == nullptr) {
761         notifySampleProduceTask_
762             = std::make_unique<Task>("SAM_PRO", playerId_, TaskType::DEMUXER, TaskPriority::HIGH, false);
763         FALSE_RETURN_V_MSG_W(notifySampleProduceTask_ != nullptr, Status::ERROR_NULL_POINTER,
764             "Create notifyProduce task failed, track:" PUBLIC_LOG_D32 ", TrackType:" PUBLIC_LOG_D32,
765             trackId, trackType);
766     }
767 
768     // To wake up DEMUXER TRACK WORKING TASK immediately on input buffer available.
769     std::unique_ptr<Task> notifyTask =
770         std::make_unique<Task>(taskName + "N", playerId_, TaskType::DECODER, TaskPriority::HIGH, false);
771     FALSE_RETURN_V_MSG_W(notifyTask != nullptr, Status::ERROR_NULL_POINTER,
772         "Create notify task failed, track:" PUBLIC_LOG_D32 ", TrackType:" PUBLIC_LOG_D32, trackId, trackType);
773 
774     sptr<IProducerListener> listener =
775         OHOS::sptr<AVBufferQueueProducerListener>::MakeSptr(trackId, shared_from_this(), notifyTask);
776     FALSE_RETURN_V_MSG_W(listener != nullptr, Status::ERROR_NULL_POINTER,
777         "Create listener failed, track:" PUBLIC_LOG_D32 ", type:" PUBLIC_LOG_D32, trackId, trackType);
778     trackMap_.emplace(trackId, std::make_shared<TrackWrapper>(trackId, listener, shared_from_this()));
779     MEDIA_LOG_I("create tasks done: trackId=" PUBLIC_LOG_D32 ",type=" PUBLIC_LOG_D32, trackId, trackType);
780     return Status::OK;
781 }
782 
AddDemuxerCopyTaskByTrackIfFilter(int32_t trackId,DemuxerTrackType type)783 void MediaDemuxer::AddDemuxerCopyTaskByTrackIfFilter(int32_t trackId, DemuxerTrackType type)
784 {
785     FALSE_RETURN_NOLOG(isCreatedByFilter_);
786     AddDemuxerCopyTaskByTrack(trackId, type);
787 }
788 
AddDemuxerCopyTaskIfFilter(int32_t trackId,TaskType type)789 void MediaDemuxer::AddDemuxerCopyTaskIfFilter(int32_t trackId, TaskType type)
790 {
791     FALSE_RETURN_NOLOG(isCreatedByFilter_);
792     AddDemuxerCopyTask(trackId, type);
793 }
794 
AddHandleFlvSelectBitrateTask()795 void MediaDemuxer::AddHandleFlvSelectBitrateTask()
796 {
797     TaskType type = GetEnableSampleQueueFlag() ? TaskType::DEMUXER : TaskType::VIDEO;
798     std::string taskName = GetEnableSampleQueueFlag() ? "DemFlv" : "DemVFlv";
799     handleFlvSelectBitrateTask_ = std::make_unique<Task>(taskName, playerId_, type, TaskPriority::NORMAL, false);
800     FALSE_RETURN_MSG_W(handleFlvSelectBitrateTask_ != nullptr,
801         "Create handleFlvSelectBitrateTask_ failed, type:" PUBLIC_LOG_D32, type);
802 }
803 
InnerPrepare()804 Status MediaDemuxer::InnerPrepare()
805 {
806     Plugins::MediaInfo mediaInfo;
807     Status ret = demuxerPluginManager_->LoadCurrentAllPlugin(streamDemuxer_, mediaInfo);
808     if (ret == Status::OK) {
809         InitMediaMetaData(mediaInfo);
810         InitDefaultTrack(mediaInfo, videoTrackId_, audioTrackId_, subtitleTrackId_, videoMime_);
811         InitIsAudioDemuxDecodeAsync();
812         if (isTranscoderMode_) {
813             TranscoderInitMediaStartPts();
814             MEDIA_LOG_I("Media startTime: " PUBLIC_LOG_D64, transcoderStartPts_);
815         }
816         InitMediaStartPts();
817         InitVideoTrack();
818         InitAudioTrack();
819         InitSubtitleTrack();
820     } else {
821         MEDIA_LOG_E("Parse meta failed, ret: " PUBLIC_LOG_D32, (int32_t)(ret));
822     }
823     return ret;
824 }
825 
InitVideoTrack()826 void MediaDemuxer::InitVideoTrack()
827 {
828     FALSE_RETURN_MSG(IsValidTrackId(videoTrackId_), "videoTrackId_ invalid");
829     GetEnableSampleQueueFlag() ? AddDemuxerCopyTaskByTrackIfFilter(videoTrackId_, DemuxerTrackType::VIDEO)
830                             : AddDemuxerCopyTaskIfFilter(videoTrackId_, TaskType::VIDEO);
831     if (isFlvLiveStream_) {
832         AddHandleFlvSelectBitrateTask();
833     }
834     demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, videoTrackId_, -1);
835     int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(videoTrackId_);
836     streamDemuxer_->SetNewVideoStreamID(streamId);
837     streamDemuxer_->SetChangeFlag(true);
838     streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
839     int64_t bitRate = 0;
840     mediaMetaData_.trackMetas[videoTrackId_]->GetData(Tag::MEDIA_BITRATE, bitRate);
841     source_->SetCurrentBitRate(bitRate, streamId);
842     targetBitRate_ = demuxerPluginManager_->GetCurrentBitRate();
843 }
844 
InitAudioTrack()845 void MediaDemuxer::InitAudioTrack()
846 {
847     FALSE_RETURN_MSG(IsValidTrackId(audioTrackId_), "audioTrackId_ invalid");
848     GetEnableSampleQueueFlag() ? AddDemuxerCopyTaskByTrackIfFilter(audioTrackId_, DemuxerTrackType::AUDIO)
849                             : AddDemuxerCopyTaskIfFilter(audioTrackId_, TaskType::AUDIO);
850     demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, audioTrackId_, -1);
851     int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(audioTrackId_);
852     streamDemuxer_->SetNewAudioStreamID(streamId);
853     streamDemuxer_->SetChangeFlag(true);
854     streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
855     int64_t bitRate = 0;
856     mediaMetaData_.trackMetas[audioTrackId_]->GetData(Tag::MEDIA_BITRATE, bitRate);
857     // ignore the bitrate of audio in flv livestream case
858     if (!isFlvLiveStream_) {
859         source_->SetCurrentBitRate(bitRate, streamId);
860     }
861 }
862 
InitSubtitleTrack()863 void MediaDemuxer::InitSubtitleTrack()
864 {
865     FALSE_RETURN_MSG(IsValidTrackId(subtitleTrackId_), "subtitleTrackId_ invalid");
866     GetEnableSampleQueueFlag() ? AddDemuxerCopyTaskByTrackIfFilter(subtitleTrackId_, DemuxerTrackType::SUBTITLE)
867                             : AddDemuxerCopyTaskIfFilter(subtitleTrackId_, TaskType::SUBTITLE);
868     demuxerPluginManager_->UpdateTempTrackMapInfo(subtitleTrackId_, subtitleTrackId_, -1);
869     int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_);
870     streamDemuxer_->SetNewSubtitleStreamID(streamId);
871     streamDemuxer_->SetChangeFlag(true);
872     streamDemuxer_->SetDemuxerState(streamId, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
873 }
874 
GetTargetVideoTrackId(std::vector<std::shared_ptr<Meta>> trackInfos)875 int32_t MediaDemuxer::GetTargetVideoTrackId(std::vector<std::shared_ptr<Meta>> trackInfos)
876 {
877     FALSE_RETURN_V(!IsValidTrackId(targetVideoTrackId_), targetVideoTrackId_);
878     MEDIA_LOG_I_SHORT("GetTargetVideoTrackId enter");
879     int32_t trackInfoSize = static_cast<int32_t>(trackInfos.size());
880     for (int32_t index = 0; index < trackInfoSize; index++) {
881         std::shared_ptr<Meta> meta = trackInfos[index];
882         if (meta == nullptr) {
883             MEDIA_LOG_E_SHORT("meta is invalid, index: " PUBLIC_LOG_D32, index);
884             continue;
885         }
886         Plugins::MediaType mediaType = Plugins::MediaType::AUDIO;
887         if (!meta->GetData(Tag::MEDIA_TYPE, mediaType)) {
888             continue;
889         }
890         if (mediaType != Plugins::MediaType::VIDEO) {
891             continue;
892         }
893         MEDIA_LOG_I_SHORT("SelectVideoTrack trackId: %{public}d", index);
894         targetVideoTrackId_ = index;
895         break;
896     }
897     return targetVideoTrackId_;
898 }
899 
SetDataSource(const std::shared_ptr<MediaSource> & source)900 Status MediaDemuxer::SetDataSource(const std::shared_ptr<MediaSource> &source)
901 {
902     MediaAVCodec::AVCODEC_SYNC_TRACE;
903     MEDIA_LOG_I("In");
904     FALSE_RETURN_V_MSG_E(isThreadExit_, Status::ERROR_WRONG_STATE, "Process is running");
905     if (isCreatedByFilter_) {
906         source_->SetCallback(this);
907     }
908     auto res = source_->SetSource(source);
909     FALSE_RETURN_V_MSG_E(res == Status::OK, res, "Plugin set source failed");
910     isFlvLiveStream_ = source_->IsFlvLiveStream();
911     Status ret = source_->GetSize(mediaDataSize_);
912     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Get file size failed");
913 
914     std::vector<StreamInfo> streams;
915     source_->GetStreamInfo(streams);
916     isHlsFmp4_ = source_->IsHlsFmp4();
917     MEDIA_LOG_I("ishlsfmp4: " PUBLIC_LOG_D32, static_cast<int32_t>(isHlsFmp4_));
918     demuxerPluginManager_->SetIsHlsFmp4(isHlsFmp4_);
919     demuxerPluginManager_->InitDefaultPlay(streams);
920 
921     streamDemuxer_ = std::make_shared<StreamDemuxer>();
922     streamDemuxer_->SetSourceType(source->GetSourceType());
923     streamDemuxer_->SetInterruptState(isInterruptNeeded_);
924     streamDemuxer_->SetSource(source_);
925     streamDemuxer_->Init(uri_);
926 
927     std::string inferPluginName = InferDemuxerPluginNameByContentType();
928     res = InnerPrepare();
929     std::string snifferPluginName;
930     bool isGotPlugin = demuxerPluginManager_->GetPluginName(snifferPluginName);
931     source_->NotifyInitSuccess();
932     ProcessDrmInfos();
933     FALSE_RETURN_V_NOLOG(eventReceiver_ != nullptr, res);
934     eventReceiver_->OnMemoryUsageEvent({"SOURCE",
935         DfxEventType::DFX_INFO_MEMORY_USAGE, source_->GetMemorySize()});
936     if (!inferPluginName.empty() && isGotPlugin) {
937         eventReceiver_->OnDfxEvent({"DEMUX", DfxEventType::DFX_INFO_PLAYER_EOS_SEEK,
938             static_cast<int32_t>(snifferPluginName == inferPluginName)});
939     }
940     MEDIA_LOG_I("Out");
941     return res;
942 }
943 
InferDemuxerPluginNameByContentType()944 std::string MediaDemuxer::InferDemuxerPluginNameByContentType()
945 {
946     FALSE_RETURN_V(source_ != nullptr, "");
947     std::string contentType = source_->GetContentType();
948     FALSE_RETURN_V_NOLOG(!contentType.empty(), "");
949     FALSE_RETURN_V(demuxerPluginManager_ != nullptr, "");
950     std::vector<Plugins::PluginDescription> matchedPluginsDescriptions =
951         Plugins::PluginList::GetInstance().GetPluginsByType(Plugins::PluginType::DEMUXER);
952     for (auto& iter : matchedPluginsDescriptions) {
953         if (IsHitPlugin(iter.pluginName, contentType)) {
954             MEDIA_LOG_I("ContentType: " PUBLIC_LOG_S ", pluginName: " PUBLIC_LOG_S,
955                 contentType.c_str(), iter.pluginName.c_str());
956             return iter.pluginName;
957         }
958     }
959     return "";
960 }
961 
IsHitPlugin(std::string & pluginName,std::string & contentType)962 bool MediaDemuxer::IsHitPlugin(std::string& pluginName, std::string& contentType)
963 {
964     std::stringstream ss(pluginName);
965     std::string token;
966     while (std::getline(ss, token, DEMUXER_PLUGIN_NAME_DELIMITER)) {
967         size_t pos = 0;
968         if ((pos = token.find(DEMUXER_PLUGIN_NAME_HEADER, pos)) != std::string::npos) {
969             token.erase(pos, DEMUXER_PLUGIN_NAME_HEADER.size());
970         }
971         if (!token.empty() && contentType.find(token) != std::string::npos) {
972             return true;
973         }
974     }
975     return false;
976 }
977 
IsSubtitleMime(const std::string & mime)978 bool MediaDemuxer::IsSubtitleMime(const std::string& mime)
979 {
980     if (mime == "application/x-subrip" || mime == "text/vtt") {
981         return true;
982     }
983 #ifdef SUPPORT_DEMUXER_LRC
984     if (mime == "text/plain") {
985         return true;
986     }
987 #endif
988 #ifdef SUPPORT_DEMUXER_SAMI
989     if (mime == "application/x-sami") {
990         return true;
991     }
992 #endif
993 #ifdef SUPPORT_DEMUXER_ASS
994     if (mime == "text/x-ass") {
995         return true;
996     }
997 #endif
998     return false;
999 }
1000 
SetSubtitleSource(const std::shared_ptr<MediaSource> & subSource)1001 Status MediaDemuxer::SetSubtitleSource(const std::shared_ptr<MediaSource> &subSource)
1002 {
1003     MEDIA_LOG_I("In");
1004     if (IsValidTrackId(subtitleTrackId_)) {
1005         MEDIA_LOG_W("Found subtitle track, not support ext");
1006         return Status::OK;
1007     }
1008     subtitleSource_->SetCallback(this);
1009     subtitleSource_->SetSource(subSource);
1010     Status ret = subtitleSource_->GetSize(subMediaDataSize_);
1011     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Get file size failed");
1012     subSeekable_ = subtitleSource_->GetSeekable();
1013 
1014     int32_t subtitleStreamID = demuxerPluginManager_->AddExternalSubtitle();
1015     subStreamDemuxer_ = std::make_shared<StreamDemuxer>();
1016     subStreamDemuxer_->SetSourceType(subSource->GetSourceType());
1017     subStreamDemuxer_->SetInterruptState(isInterruptNeeded_);
1018     subStreamDemuxer_->SetSource(subtitleSource_);
1019     subStreamDemuxer_->Init(subSource->GetSourceUri());
1020 
1021     MediaInfo mediaInfo;
1022     ret = demuxerPluginManager_->LoadCurrentSubtitlePlugin(subStreamDemuxer_, mediaInfo);
1023     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Parse meta failed, ret:" PUBLIC_LOG_D32, static_cast<int32_t>(ret));
1024     InitMediaMetaData(mediaInfo);  // update mediaMetaData_
1025     int32_t trackSize = static_cast<int32_t>(mediaInfo.tracks.size());
1026     for (int32_t index = 0; index < trackSize; index++) {
1027         auto trackMeta = mediaInfo.tracks[index];
1028         std::string mimeType;
1029         std::string trackType;
1030         trackMeta.Get<Tag::MIME_TYPE>(mimeType);
1031         int32_t curStreamID = demuxerPluginManager_->GetStreamIDByTrackID(index);
1032         if (trackMeta.Get<Tag::MIME_TYPE>(mimeType) && IsSubtitleMime(mimeType) && curStreamID == subtitleStreamID) {
1033             MEDIA_LOG_I("STrack " PUBLIC_LOG_D32, index);
1034             subtitleTrackId_ = index;   // dash inner subtitle can be replace by out subtitle
1035             break;
1036         }
1037     }
1038 
1039     if (IsValidTrackId(subtitleTrackId_)) {
1040         GetEnableSampleQueueFlag() ? AddDemuxerCopyTaskByTrack(subtitleTrackId_, DemuxerTrackType::SUBTITLE)
1041                                    : AddDemuxerCopyTask(subtitleTrackId_, TaskType::SUBTITLE);
1042         demuxerPluginManager_->UpdateTempTrackMapInfo(subtitleTrackId_, subtitleTrackId_, -1);
1043         subStreamDemuxer_->SetNewSubtitleStreamID(subtitleStreamID);
1044         subStreamDemuxer_->SetDemuxerState(subtitleStreamID, DemuxerState::DEMUXER_STATE_PARSE_FIRST_FRAME);
1045     }
1046 
1047     MEDIA_LOG_I("Out, ext sub %{public}d", subtitleTrackId_);
1048     return ret;
1049 }
1050 
OnInterrupted(bool isInterruptNeeded)1051 void MediaDemuxer::OnInterrupted(bool isInterruptNeeded)
1052 {
1053     MEDIA_LOG_D("MediaDemuxer OnInterrupted %{public}d", isInterruptNeeded);
1054     isInterruptNeeded_ = isInterruptNeeded;
1055     if (demuxerPluginManager_ != nullptr && demuxerPluginManager_->IsDash()) {
1056         std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1057         rebootPluginCondition_.notify_all();
1058     }
1059     if (source_ != nullptr) {
1060         source_->SetInterruptState(isInterruptNeeded);
1061     }
1062     if (streamDemuxer_ != nullptr) {
1063         streamDemuxer_->SetInterruptState(isInterruptNeeded);
1064     }
1065     if (subStreamDemuxer_ != nullptr) {
1066         subStreamDemuxer_->SetInterruptState(isInterruptNeeded);
1067     }
1068     if (demuxerPluginManager_ != nullptr) {
1069         demuxerPluginManager_->NotifyInitialBufferingEnd(false);
1070         demuxerPluginManager_->SetInterruptState(isInterruptNeeded);
1071     }
1072 }
1073 
SetBundleName(const std::string & bundleName)1074 void MediaDemuxer::SetBundleName(const std::string& bundleName)
1075 {
1076     FALSE_RETURN(source_ != nullptr && streamDemuxer_ != nullptr);
1077     MEDIA_LOG_I("BundleName: " PUBLIC_LOG_S, bundleName.c_str());
1078     bundleName_ = bundleName;
1079     streamDemuxer_->SetBundleName(bundleName);
1080     source_->SetBundleName(bundleName);
1081 }
1082 
SetOutputBufferQueue(int32_t trackId,const sptr<AVBufferQueueProducer> & producer)1083 Status MediaDemuxer::SetOutputBufferQueue(int32_t trackId, const sptr<AVBufferQueueProducer>& producer)
1084 {
1085     AutoLock lock(mapMutex_);
1086     FALSE_RETURN_V_MSG_E(IsValidTrackId(trackId) &&
1087         static_cast<size_t>(trackId) < mediaMetaData_.trackMetas.size(),
1088         Status::ERROR_INVALID_PARAMETER, "Invalid track");
1089     useBufferQueue_ = true;
1090     MEDIA_LOG_I("Set bufferQueue for track " PUBLIC_LOG_D32, trackId);
1091     FALSE_RETURN_V_MSG_E(isThreadExit_, Status::ERROR_WRONG_STATE, "Process is running");
1092     FALSE_RETURN_V_MSG_E(producer != nullptr, Status::ERROR_INVALID_PARAMETER, "BufferQueue is nullptr");
1093     if (bufferQueueMap_.find(trackId) != bufferQueueMap_.end()) {
1094         MEDIA_LOG_W("Has been set already");
1095     }
1096     Status ret = InnerSelectTrack(trackId);
1097     if (ret == Status::OK) {
1098         auto track = trackMap_.find(trackId);
1099         if (track != trackMap_.end()) {
1100             auto listener = track->second->GetProducerListener();
1101             if (listener) {
1102                 MEDIA_LOG_W("Set listener");
1103                 producer->SetBufferAvailableListener(listener);
1104             }
1105         }
1106         bufferQueueMap_.insert(std::pair<int32_t, sptr<AVBufferQueueProducer>>(trackId, producer));
1107         bufferMap_.insert(std::pair<int32_t, std::shared_ptr<AVBuffer>>(trackId, nullptr));
1108         MEDIA_LOG_I("Set bufferQueue successfully");
1109         GenerateDfxBufferQueue(trackId);
1110         if (GetEnableSampleQueueFlag()) {
1111             ret = AddSampleBufferQueue(trackId);
1112             FALSE_RETURN_V_MSG_E(
1113                 ret == Status::OK, ret, "AddSampleBufferQueue failed for track " PUBLIC_LOG_D32, trackId);
1114         }
1115     }
1116     return ret;
1117 }
1118 
OnDumpInfo(int32_t fd)1119 void MediaDemuxer::OnDumpInfo(int32_t fd)
1120 {
1121     MEDIA_LOG_D("In");
1122     if (fd < 0) {
1123         MEDIA_LOG_E("Invalid fd");
1124         return;
1125     }
1126     std::string dumpString;
1127     dumpString += "MediaDemuxer buffer queue map size: " + std::to_string(bufferQueueMap_.size()) + "\n";
1128     dumpString += "MediaDemuxer buffer map size: " + std::to_string(bufferMap_.size()) + "\n";
1129     int ret = write(fd, dumpString.c_str(), dumpString.size());
1130     if (ret < 0) {
1131         MEDIA_LOG_E("MediaDemuxer::OnDumpInfo write failed");
1132         return;
1133     }
1134 }
1135 
GetBufferQueueProducerMap()1136 std::map<int32_t, sptr<AVBufferQueueProducer>> MediaDemuxer::GetBufferQueueProducerMap()
1137 {
1138     return bufferQueueMap_;
1139 }
1140 
InnerSelectTrack(int32_t trackId)1141 Status MediaDemuxer::InnerSelectTrack(int32_t trackId)
1142 {
1143     eosMap_[trackId] = false;
1144     requestBufferErrorCountMap_[trackId] = 0;
1145 
1146     int32_t innerTrackID = trackId;
1147     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
1148     if (IsNeedMapToInnerTrackID()) {
1149         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1150         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
1151         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1152         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
1153     } else {
1154         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(demuxerPluginManager_->GetStreamIDByTrackID(trackId));
1155         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1156     }
1157 
1158     return pluginTemp->SelectTrack(static_cast<uint32_t>(innerTrackID));
1159 }
1160 
StartTask(int32_t trackId)1161 Status MediaDemuxer::StartTask(int32_t trackId)
1162 {
1163     if (GetEnableSampleQueueFlag()) {
1164         return StartTaskWithSampleQueue(trackId);
1165     }
1166     MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
1167     std::string mimeType;
1168     auto iter = taskMap_.find(trackId);
1169     if (iter == taskMap_.end()) {
1170         TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1171         if (trackType == TrackType::TRACK_AUDIO) {
1172             AddDemuxerCopyTask(trackId, TaskType::AUDIO);
1173         } else if (trackType == TrackType::TRACK_VIDEO) {
1174             AddDemuxerCopyTask(trackId, TaskType::VIDEO);
1175         } else if (trackType == TrackType::TRACK_SUBTITLE) {
1176             AddDemuxerCopyTask(trackId, TaskType::SUBTITLE);
1177         }
1178         if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
1179             UpdateBufferQueueListener(trackId);
1180             taskMap_[trackId]->Start();
1181         }
1182     } else {
1183         if (taskMap_[trackId] != nullptr && !taskMap_[trackId]->IsTaskRunning()) {
1184             UpdateBufferQueueListener(trackId);
1185             taskMap_[trackId]->Start();
1186         }
1187     }
1188     return Status::OK;
1189 }
1190 
StartTaskWithSampleQueue(int32_t trackId)1191 Status MediaDemuxer::StartTaskWithSampleQueue(int32_t trackId)
1192 {
1193     MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
1194     Status ret = Status::OK;
1195     TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1196     auto iterTrack = TRACK_MAP.find(trackType);
1197     FALSE_RETURN_V_MSG_E(iterTrack != TRACK_MAP.end(), Status::ERROR_INVALID_PARAMETER,
1198         "invalid trackId: " PUBLIC_LOG_D32, trackId);
1199     if (taskMap_.find(trackId) == taskMap_.end() ||
1200         sampleConsumerTaskMap_.find(trackId) == sampleConsumerTaskMap_.end()) {
1201         ret = AddDemuxerCopyTaskByTrack(trackId, iterTrack->second);
1202         FALSE_RETURN_V(ret == Status::OK, ret);
1203     }
1204     if (taskMap_[trackId] != nullptr && !taskMap_[trackId]->IsTaskRunning()) {
1205         UpdateBufferQueueListener(trackId);
1206         taskMap_[trackId]->Start();
1207     }
1208     if (sampleConsumerTaskMap_[trackId] != nullptr && !sampleConsumerTaskMap_[trackId]->IsTaskRunning()) {
1209         FALSE_RETURN_V(trackId != videoTrackId_ || !isVideoMuted_ || needReleaseVideoDecoder_, Status::OK);
1210         sampleConsumerTaskMap_[trackId]->Start();
1211     }
1212     return Status::OK;
1213 }
1214 
UpdateBufferQueueListener(int32_t trackId)1215 void MediaDemuxer::UpdateBufferQueueListener(int32_t trackId)
1216 {
1217     FALSE_RETURN(bufferQueueMap_.find(trackId) != bufferQueueMap_.end() && trackMap_.find(trackId) != trackMap_.end());
1218     auto producer = bufferQueueMap_[trackId];
1219     auto listener = trackMap_[trackId]->GetProducerListener();
1220     producer->SetBufferAvailableListener(listener);
1221 }
1222 
HandleDashSelectTrack(int32_t trackId)1223 Status MediaDemuxer::HandleDashSelectTrack(int32_t trackId)
1224 {
1225     MEDIA_LOG_I("In, track " PUBLIC_LOG_D32, trackId);
1226     eosMap_[trackId] = false;
1227     requestBufferErrorCountMap_[trackId] = 0;
1228 
1229     int32_t targetStreamID = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
1230     if (targetStreamID == -1) {
1231         MEDIA_LOG_E("Get stream failed");
1232         return Status::ERROR_UNKNOWN;
1233     }
1234 
1235     int32_t curTrackId = TRACK_ID_INVALID;
1236     TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1237     if (trackType == TrackType::TRACK_AUDIO) {
1238         curTrackId = audioTrackId_;
1239     } else if (trackType == TrackType::TRACK_VIDEO) {
1240         curTrackId = videoTrackId_;
1241     } else if (trackType == TrackType::TRACK_SUBTITLE) {
1242         curTrackId = subtitleTrackId_;
1243     } else {   // invalid
1244         MEDIA_LOG_E("Track type invalid");
1245         return Status::ERROR_UNKNOWN;
1246     }
1247 
1248     if (trackId == curTrackId || targetStreamID != demuxerPluginManager_->GetTmpStreamIDByTrackID(curTrackId)) {
1249         MEDIA_LOG_I("Select stream");
1250         {
1251             std::lock_guard<std::mutex> lock(isSelectTrackMutex_);
1252             inSelectTrackType_[static_cast<int32_t>(trackType)] = trackId;
1253         }
1254         return source_->SelectStream(targetStreamID);
1255     }
1256 
1257     // same streamID
1258     Status ret = DoSelectTrack(trackId, curTrackId);
1259     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "DoSelectTrack track failed");
1260     if (eventReceiver_ != nullptr) {
1261         if (trackType == TrackType::TRACK_AUDIO) {
1262             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, trackId});
1263             audioTrackId_ = trackId;
1264         } else if (trackType == TrackType::TRACK_VIDEO) {
1265             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, trackId});
1266             videoTrackId_ = trackId;
1267         } else if (trackType == TrackType::TRACK_SUBTITLE) {
1268             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_SUBTITLE_TRACK_CHANGE, trackId});
1269             subtitleTrackId_ = trackId;
1270         } else {}
1271     }
1272     return Status::OK;
1273 }
1274 
DoSelectTrack(int32_t trackId,int32_t curTrackId)1275 Status MediaDemuxer::DoSelectTrack(int32_t trackId, int32_t curTrackId)
1276 {
1277     if (IsValidTrackId(curTrackId)) {
1278         if (taskMap_.find(curTrackId) != taskMap_.end() && taskMap_[curTrackId] != nullptr) {
1279             taskMap_[curTrackId]->Stop();
1280         }
1281         if (sampleConsumerTaskMap_.find(curTrackId) != sampleConsumerTaskMap_.end() &&
1282             sampleConsumerTaskMap_[curTrackId] != nullptr) {
1283             sampleConsumerTaskMap_[curTrackId]->Stop();
1284         }
1285         if (curTrackId == audioTrackId_ && sampleQueueMap_[curTrackId] != nullptr) {
1286             sampleQueueMap_[curTrackId]->Clear();
1287         }
1288         Status ret = UnselectTrack(curTrackId);
1289         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Unselect track failed");
1290         bufferQueueMap_.insert(
1291             std::pair<int32_t, sptr<AVBufferQueueProducer>>(trackId, bufferQueueMap_[curTrackId]));
1292         bufferMap_.insert(std::pair<int32_t, std::shared_ptr<AVBuffer>>(trackId, bufferMap_[curTrackId]));
1293         bufferQueueMap_.erase(curTrackId);
1294         bufferMap_.erase(curTrackId);
1295         demuxerPluginManager_->UpdateTempTrackMapInfo(trackId, trackId, -1);
1296 
1297         if (GetEnableSampleQueueFlag()) {
1298             AutoLock lock(mapMutex_);
1299             sampleQueueMap_.insert(
1300                 std::pair<int32_t, std::shared_ptr<SampleQueue>>(trackId, sampleQueueMap_[curTrackId]));
1301             sampleQueueMap_.erase(curTrackId);
1302             if (sampleQueueMap_[trackId] != nullptr) {
1303                 sampleQueueMap_[trackId]->UpdateQueueId(trackId);
1304             }
1305         }
1306         return InnerSelectTrack(trackId);
1307     }
1308     return Status::ERROR_UNKNOWN;
1309 }
1310 
HandleSelectTrack(int32_t trackId)1311 Status MediaDemuxer::HandleSelectTrack(int32_t trackId)
1312 {
1313     int32_t curTrackId = TRACK_ID_INVALID;
1314     TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1315     if (trackType == TrackType::TRACK_AUDIO) {
1316         MEDIA_LOG_I("Select audio [" PUBLIC_LOG_D32 "->" PUBLIC_LOG_D32 "]", audioTrackId_, trackId);
1317         curTrackId = audioTrackId_;
1318     } else {    // inner subtitle and video not support
1319         MEDIA_LOG_W("Unsupport track " PUBLIC_LOG_D32, trackId);
1320         return Status::ERROR_INVALID_PARAMETER;
1321     }
1322 
1323     if (curTrackId == trackId) {
1324         return Status::OK;
1325     }
1326 
1327     Status ret = DoSelectTrack(trackId, curTrackId);
1328     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "DoSelectTrack track failed");
1329     if (eventReceiver_ != nullptr) {
1330         if (trackType == TrackType::TRACK_AUDIO) {
1331             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, trackId});
1332             audioTrackId_ =  trackId;
1333         } else if (trackType == TrackType::TRACK_VIDEO) {
1334             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, trackId});
1335             videoTrackId_ =  trackId;
1336         } else {}
1337     }
1338 
1339     return ret;
1340 }
1341 
SelectTrack(uint32_t trackIndex)1342 Status MediaDemuxer::SelectTrack(uint32_t trackIndex)
1343 {
1344     int32_t trackId = static_cast<int32_t>(trackIndex);
1345     MediaAVCodec::AVCODEC_SYNC_TRACE;
1346     MEDIA_LOG_D("Select " PUBLIC_LOG_D32, trackId);
1347     FALSE_RETURN_V_MSG_E(IsValidTrackId(trackId) &&
1348         static_cast<size_t>(trackIndex) < mediaMetaData_.trackMetas.size(),
1349         Status::ERROR_INVALID_PARAMETER, "Select track failed");
1350     if (!useBufferQueue_) {
1351         return InnerSelectTrack(trackId);
1352     }
1353     if (demuxerPluginManager_->IsDash()) {
1354         if (streamDemuxer_->CanDoChangeStream() == false) {
1355             MEDIA_LOG_W("Wrong state: selecting");
1356             return Status::ERROR_WRONG_STATE;
1357         }
1358         return HandleDashSelectTrack(trackId);
1359     }
1360     return HandleSelectTrack(trackId);
1361 }
1362 
UnselectTrack(uint32_t trackIndex)1363 Status MediaDemuxer::UnselectTrack(uint32_t trackIndex)
1364 {
1365     int32_t trackId = static_cast<int32_t>(trackIndex);
1366     MediaAVCodec::AVCODEC_SYNC_TRACE;
1367     MEDIA_LOG_D("Unselect " PUBLIC_LOG_D32, trackId);
1368 
1369     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
1370     int32_t innerTrackID = trackId;
1371     if (IsNeedMapToInnerTrackID()) {
1372         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1373         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
1374         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1375         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
1376     } else {
1377         int32_t streamID = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
1378         if (streamID == -1) {
1379             MEDIA_LOG_W("Invalid track " PUBLIC_LOG_D32, trackId);
1380             return Status::OK;
1381         }
1382         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
1383         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
1384     }
1385     demuxerPluginManager_->DeleteTempTrackMapInfo(trackId);
1386 
1387     return pluginTemp->UnselectTrack(static_cast<uint32_t>(innerTrackID));
1388 }
1389 
HandleHlsRebootPlugin()1390 Status MediaDemuxer::HandleHlsRebootPlugin()
1391 {
1392     MEDIA_LOG_I("HandleHlsRebootPlugin In");
1393     StreamType streamType = StreamType::MIXED;
1394     TrackType trackType = IsValidTrackId(videoTrackId_) ? TrackType::TRACK_VIDEO : TrackType::TRACK_AUDIO;
1395     int32_t trackId = IsValidTrackId(videoTrackId_) ? videoTrackId_ : audioTrackId_;
1396     FALSE_RETURN_V(!subStreamDemuxer_ || trackId != subtitleTrackId_, Status::OK);
1397     Status ret = Status::OK;
1398     if (IsValidTrackId(trackId)) {
1399         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1400         FALSE_RETURN_V_MSG_E(streamID != INVALID_STREAM_OR_TRACK_ID, Status::ERROR_INVALID_PARAMETER,
1401             "Invalid streamId");
1402         std::pair<int32_t, bool> seekReadyInfo;
1403         {
1404             std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1405             if (!isInterruptNeeded_.load() &&
1406                 seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) == seekReadyStreamInfo_.end()) {
1407                 rebootPluginCondition_.wait(lock, [this, streamType] {
1408                     return isInterruptNeeded_.load() ||
1409                         seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) != seekReadyStreamInfo_.end();
1410                 });
1411             }
1412             FALSE_RETURN_V(!isInterruptNeeded_.load(), Status::OK);
1413             seekReadyInfo = seekReadyStreamInfo_[static_cast<int32_t>(streamType)];
1414             seekReadyStreamInfo_.erase(static_cast<int32_t>(streamType));
1415         }
1416         if (seekReadyInfo.second == SEEK_TO_EOS) {
1417             MEDIA_LOG_I("Seek to eos");
1418             return Status::OK;
1419         } else if (seekReadyInfo.first >= 0 && seekReadyInfo.first != streamID) {
1420             return HandleSeekChangeStream(streamID, seekReadyInfo.first, trackId);
1421         }
1422         bool isRebooted = true;
1423         ret = demuxerPluginManager_->RebootPlugin(streamID, trackType, streamDemuxer_, isRebooted);
1424         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot demuxer plugin failed");
1425     }
1426     Status audioRet = IsValidTrackId(audioTrackId_) ? InnerSelectTrack(audioTrackId_) : Status::OK;
1427     Status videoRet = IsValidTrackId(videoTrackId_) ? InnerSelectTrack(videoTrackId_) : Status::OK;
1428     ret = audioRet == Status::OK ? videoRet : audioRet;
1429     {
1430         std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1431         seekReadyStreamInfo_.clear();
1432     }
1433     return ret;
1434 }
1435 
HandleSeekChangeStream(int32_t currentStreamId,int32_t newStreamId,int32_t trackId)1436 Status MediaDemuxer::HandleSeekChangeStream(int32_t currentStreamId, int32_t newStreamId, int32_t trackId)
1437 {
1438     MEDIA_LOG_I("streamID changed, streamId: " PUBLIC_LOG_D32 ", newStreamId: " PUBLIC_LOG_D32,
1439         currentStreamId, newStreamId);
1440     // only fix completed seek currently
1441     if (streamDemuxer_ != nullptr && HasEosTrack()) {
1442         streamDemuxer_->SetNewVideoStreamID(newStreamId);
1443         FALSE_GOON_NOEXEC(demuxerPluginManager_ && demuxerPluginManager_->IsDash(), HandleDashChangeStream(trackId));
1444     }
1445     return Status::OK;
1446 }
1447 
HandleRebootPlugin(int32_t trackId,bool & isRebooted)1448 Status MediaDemuxer::HandleRebootPlugin(int32_t trackId, bool& isRebooted)
1449 {
1450     FALSE_RETURN_V(!subStreamDemuxer_ || trackId != static_cast<int32_t>(subtitleTrackId_), Status::OK);
1451     Status ret = Status::OK;
1452     if (IsValidTrackId(trackId)) {
1453         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
1454         FALSE_RETURN_V_MSG_E(streamID != INVALID_STREAM_OR_TRACK_ID, Status::ERROR_INVALID_PARAMETER,
1455             "Invalid streamId");
1456         TrackType trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
1457         MEDIA_LOG_D("TrackType " PUBLIC_LOG_D32 " TrackId " PUBLIC_LOG_D32, static_cast<int32_t>(trackType), trackId);
1458         FALSE_RETURN_V_MSG_E(trackType != TRACK_INVALID, Status::ERROR_INVALID_PARAMETER, "TrackType is invalid");
1459         StreamType streamType = TRACK_TO_STREAM_MAP[trackType];
1460         std::pair<int32_t, bool> seekReadyInfo;
1461         {
1462             std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1463             if (!isInterruptNeeded_.load() &&
1464                 seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) == seekReadyStreamInfo_.end()) {
1465                 rebootPluginCondition_.wait(lock, [this, streamType] {
1466                     return isInterruptNeeded_.load() ||
1467                         seekReadyStreamInfo_.find(static_cast<int32_t>(streamType)) != seekReadyStreamInfo_.end();
1468                 });
1469             }
1470             FALSE_RETURN_V(!isInterruptNeeded_.load(), Status::OK);
1471             seekReadyInfo = seekReadyStreamInfo_[static_cast<int32_t>(streamType)];
1472             seekReadyStreamInfo_.erase(static_cast<int32_t>(streamType));
1473         }
1474         if (seekReadyInfo.second == SEEK_TO_EOS || (seekReadyInfo.first >= 0 && seekReadyInfo.first != streamID)) {
1475             MEDIA_LOG_I("End of stream or streamID changed, isEOS: " PUBLIC_LOG_D32 ", streamId: " PUBLIC_LOG_D32,
1476                 seekReadyInfo.second, seekReadyInfo.first);
1477             return Status::OK;
1478         }
1479         ret = demuxerPluginManager_->RebootPlugin(streamID, trackType, streamDemuxer_, isRebooted);
1480         FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot demuxer plugin failed");
1481         ret = InnerSelectTrack(trackId);
1482     }
1483     return ret;
1484 }
1485 
SeekToTimeAfter()1486 Status MediaDemuxer::SeekToTimeAfter()
1487 {
1488     FALSE_RETURN_V_NOLOG(demuxerPluginManager_ != nullptr && demuxerPluginManager_->IsDash(), Status::OK);
1489     MEDIA_LOG_I("Reboot plugin begin");
1490     if (isHlsFmp4_) {
1491         return HandleHlsRebootPlugin();
1492     }
1493     Status ret = Status::OK;
1494     bool isDemuxerPluginRebooted = true;
1495     ret = HandleRebootPlugin(subtitleTrackId_, isDemuxerPluginRebooted);
1496     if (shouldCheckSubtitleFramePts_) {
1497         shouldCheckSubtitleFramePts_ = false;
1498     }
1499     FALSE_LOG_MSG_W(ret == Status::OK, "Reboot subtitle demuxer plugin failed");
1500 
1501     isDemuxerPluginRebooted = true;
1502     ret = HandleRebootPlugin(audioTrackId_, isDemuxerPluginRebooted);
1503     if (shouldCheckAudioFramePts_) {
1504         shouldCheckAudioFramePts_ = false;
1505     }
1506     FALSE_LOG_MSG_W(ret == Status::OK, "Reboot audio demuxer plugin failed");
1507 
1508     isDemuxerPluginRebooted = true;
1509     ret = HandleRebootPlugin(videoTrackId_, isDemuxerPluginRebooted);
1510     {
1511         std::unique_lock<std::mutex> lock(rebootPluginMutex_);
1512         seekReadyStreamInfo_.clear();
1513     }
1514     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Reboot video demuxer plugin failed");
1515     MEDIA_LOG_I("Reboot plugin success");
1516     return Status::OK;
1517 }
1518 
SeekTo(int64_t seekTime,Plugins::SeekMode mode,int64_t & realSeekTime)1519 Status MediaDemuxer::SeekTo(int64_t seekTime, Plugins::SeekMode mode, int64_t& realSeekTime)
1520 {
1521     MediaAVCodec::AVCODEC_SYNC_TRACE;
1522     Status ret;
1523     isSeekError_.store(false);
1524     if (source_ != nullptr && source_->IsSeekToTimeSupported()) {
1525         MEDIA_LOG_I("Source seek");
1526         if (mode == SeekMode::SEEK_CLOSEST_INNER) {
1527             ScopedTimer timer("seek closest online", SEEKCLOSEST_ONLINE_WARNING_MS);
1528             ret = source_->SeekToTime(seekTime, SeekMode::SEEK_PREVIOUS_SYNC);
1529         } else {
1530             ScopedTimer timer("seek online", SEEK_ONLINE_WARNING_MS);
1531             ret = source_->SeekToTime(seekTime, SeekMode::SEEK_CLOSEST_SYNC);
1532         }
1533         if (subtitleSource_) {
1534             demuxerPluginManager_->localSubtitleSeekTo(seekTime);
1535         }
1536         SeekToTimeAfter();
1537         Plugins::Ms2HstTime(seekTime, realSeekTime);
1538     } else {
1539         MEDIA_LOG_I("Demuxer seek");
1540         if (mode == SeekMode::SEEK_CLOSEST_INNER) {
1541             ScopedTimer timer("seek closest local", SEEKCLOSEST_LOCAL_WARNING_MS);
1542             ret = demuxerPluginManager_->SeekTo(seekTime, SeekMode::SEEK_PREVIOUS_SYNC, realSeekTime);
1543         } else {
1544             ScopedTimer timer("seek closest", SEEK_LOCAL_WARNING_MS);
1545             ret = demuxerPluginManager_->SeekTo(seekTime, mode, realSeekTime);
1546         }
1547     }
1548     isSeeked_ = true;
1549     if (isVideoMuted_ || needRestore_) {
1550         if (sampleQueueMap_[videoTrackId_] != nullptr) {
1551             sampleQueueMap_[videoTrackId_]->Clear();
1552         }
1553         lastVideoPts_ = -1;
1554     }
1555     for (auto item : eosMap_) {
1556         eosMap_[item.first] = false;
1557     }
1558     for (auto item : requestBufferErrorCountMap_) {
1559         requestBufferErrorCountMap_[item.first] = 0;
1560     }
1561     if (ret != Status::OK) {
1562         isSeekError_.store(true);
1563     }
1564     isFirstFrameAfterSeek_.store(true);
1565     convertErrorTime_.store(0);
1566     MEDIA_LOG_D("Out");
1567     return ret;
1568 }
1569 
SelectBitRate(uint32_t bitRate,bool isAutoSelect)1570 Status MediaDemuxer::SelectBitRate(uint32_t bitRate, bool isAutoSelect)
1571 {
1572     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_INVALID_PARAMETER, "Source is nullptr");
1573     MEDIA_LOG_I("In");
1574 
1575     if (isFlvLiveStream_ && IsRightMediaTrack(videoTrackId_, DemuxerTrackType::VIDEO)) {
1576         FALSE_RETURN_V_NOLOG(!isManualBitRateSetting_.load() || !isAutoSelect, Status::ERROR_UNKNOWN);
1577         if (!isManualBitRateSetting_.load() && !isAutoSelect) {
1578             isManualBitRateSetting_.store(true);
1579         }
1580         FALSE_RETURN_V_NOLOG(GetEnableSampleQueueFlag(), SelectBitrateForNonSQ(0, bitRate));
1581         auto sqIt = sampleQueueMap_.find(videoTrackId_);
1582         FALSE_RETURN_V_MSG_E(sqIt != sampleQueueMap_.end() && sqIt->second, Status::ERROR_WRONG_STATE,
1583             "sampleQueue is nullptr");
1584         return sqIt->second->ReadySwitchBitrate(bitRate);
1585     }
1586     FALSE_RETURN_V(demuxerPluginManager_ != nullptr && streamDemuxer_ != nullptr, Status::ERROR_WRONG_STATE);
1587     if (demuxerPluginManager_->IsDash()) {
1588         if (streamDemuxer_->CanDoChangeStream() == false) {
1589             MEDIA_LOG_W("Wrong state: selecting");
1590             return Status::OK;
1591         }
1592         if (bitRate == demuxerPluginManager_->GetCurrentBitRate()) {
1593             MEDIA_LOG_W("Same bitrate");
1594             return Status::OK;
1595         }
1596         isSelectBitRate_.store(true);
1597     } else {
1598         streamDemuxer_->ResetAllCache();
1599     }
1600 
1601     Status ret = source_->SelectBitRate(bitRate);
1602     if (ret != Status::OK) {
1603         MEDIA_LOG_E("Source select bitrate failed");
1604         if (demuxerPluginManager_->IsDash()) {
1605             isSelectBitRate_.store(false);
1606         }
1607     }
1608     targetBitRate_ = bitRate;
1609     MEDIA_LOG_I("Out");
1610     return ret;
1611 }
1612 
GetStreamMetaInfo() const1613 std::vector<std::shared_ptr<Meta>> MediaDemuxer::GetStreamMetaInfo() const
1614 {
1615     MediaAVCodec::AVCODEC_SYNC_TRACE;
1616     return mediaMetaData_.trackMetas;
1617 }
1618 
GetGlobalMetaInfo()1619 std::shared_ptr<Meta> MediaDemuxer::GetGlobalMetaInfo()
1620 {
1621     AutoLock lock(mapMutex_);
1622     MediaAVCodec::AVCODEC_SYNC_TRACE;
1623     return mediaMetaData_.globalMeta;
1624 }
1625 
GetUserMeta()1626 std::shared_ptr<Meta> MediaDemuxer::GetUserMeta()
1627 {
1628     MediaAVCodec::AVCODEC_SYNC_TRACE;
1629     return demuxerPluginManager_->GetUserMeta();
1630 }
1631 
Flush()1632 Status MediaDemuxer::Flush()
1633 {
1634     MEDIA_LOG_I("In");
1635     ResetDraggingOpenGopCnt();
1636     if (streamDemuxer_) {
1637         streamDemuxer_->Flush();
1638     }
1639 
1640     {
1641         AutoLock lock(mapMutex_);
1642         auto it = bufferQueueMap_.begin();
1643         while (it != bufferQueueMap_.end()) {
1644             int32_t trackId = it->first;
1645             if (trackId != videoTrackId_) {
1646                 bufferQueueMap_[trackId]->Clear();
1647             }
1648             it++;
1649         }
1650 
1651         auto sqIt = sampleQueueMap_.begin();
1652         while (sqIt != sampleQueueMap_.end()) {
1653             int32_t trackId = sqIt->first;
1654             if (sampleQueueMap_[trackId] != nullptr) {
1655                 sampleQueueMap_[trackId]->Clear();
1656             }
1657             sqIt++;
1658         }
1659     }
1660 
1661     if (demuxerPluginManager_) {
1662         if (source_ != nullptr && source_->IsSeekToTimeSupported()) {
1663             demuxerPluginManager_->SetResetEosStatus(true);
1664         }
1665         demuxerPluginManager_->Flush();
1666     }
1667 
1668     InitPtsInfo();
1669     return Status::OK;
1670 }
1671 
StopAllTask()1672 Status MediaDemuxer::StopAllTask()
1673 {
1674     MEDIA_LOG_I("In");
1675     AutoLock lock(mapMutex_);
1676     isDemuxerLoopExecuting_ = false;
1677     if (streamDemuxer_ != nullptr) {
1678         streamDemuxer_->SetIsIgnoreParse(true);
1679     }
1680     auto it = taskMap_.begin();
1681     while (it != taskMap_.end()) {
1682         if (it->second != nullptr) {
1683             it->second->Stop();
1684             it->second = nullptr;
1685         }
1686         it = taskMap_.erase(it);
1687     }
1688     for (auto stIt = sampleConsumerTaskMap_.begin(); stIt != sampleConsumerTaskMap_.end();) {
1689         if (stIt->second != nullptr) {
1690             stIt->second->Stop();
1691         }
1692         stIt = sampleConsumerTaskMap_.erase(stIt);
1693     }
1694     isThreadExit_ = true;
1695     MEDIA_LOG_I("Out");
1696     return Status::OK;
1697 }
1698 
PauseAllTask()1699 Status MediaDemuxer::PauseAllTask()
1700 {
1701     MEDIA_LOG_I("In");
1702     isDemuxerLoopExecuting_ = false;
1703     for (auto &iter : taskMap_) {
1704         if (iter.second != nullptr) {
1705             iter.second->Pause();
1706         }
1707     }
1708 
1709     for (auto &iter : sampleConsumerTaskMap_) {
1710         if (iter.second != nullptr) {
1711             iter.second->Pause();
1712         }
1713     }
1714     if (demuxerPluginManager_) {
1715         demuxerPluginManager_->Pause();
1716     }
1717     MEDIA_LOG_I("Out");
1718     return Status::OK;
1719 }
1720 
PauseAllTaskAsync()1721 Status MediaDemuxer::PauseAllTaskAsync()
1722 {
1723     MEDIA_LOG_I("In");
1724     // To accelerate DemuxerLoop thread to run into PAUSED state
1725     for (auto &iter : taskMap_) {
1726         if (iter.second != nullptr) {
1727             iter.second->PauseAsync();
1728         }
1729     }
1730     for (auto &iter : sampleConsumerTaskMap_) {
1731         if (iter.second != nullptr) {
1732             iter.second->PauseAsync();
1733         }
1734     }
1735     MEDIA_LOG_I("Out");
1736     return Status::OK;
1737 }
1738 
ResumeAllTask()1739 Status MediaDemuxer::ResumeAllTask()
1740 {
1741     MEDIA_LOG_I("In");
1742     isDemuxerLoopExecuting_ = true;
1743     streamDemuxer_->SetIsIgnoreParse(false);
1744 
1745     auto it = bufferQueueMap_.begin();
1746     while (it != bufferQueueMap_.end()) {
1747         StartTaskInner(it->first);
1748         it++;
1749     }
1750     MEDIA_LOG_I("Out");
1751     return Status::OK;
1752 }
1753 
Pause()1754 Status MediaDemuxer::Pause()
1755 {
1756     MEDIA_LOG_I("In");
1757     isPaused_ = true;
1758     if (streamDemuxer_) {
1759         streamDemuxer_->SetIsIgnoreParse(true);
1760         streamDemuxer_->Pause();
1761     }
1762     if (source_) {
1763         source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1764         source_->Pause();
1765     }
1766     if (inPreroll_.load()) {
1767         if (CheckTrackEnabledById(videoTrackId_)) {
1768             taskMap_[videoTrackId_]->PauseAsync();
1769             taskMap_[videoTrackId_]->Pause();
1770             if (GetEnableSampleQueueFlag()) {
1771                 sampleConsumerTaskMap_[videoTrackId_]->PauseAsync();
1772                 sampleConsumerTaskMap_[videoTrackId_]->Pause();
1773             }
1774         }
1775     } else {
1776         PauseAllTaskAsync();
1777         PauseAllTask();
1778     }
1779     if (source_ != nullptr) {
1780         source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1781     }
1782     if (demuxerPluginManager_) {
1783         demuxerPluginManager_->Pause();
1784     }
1785     return Status::OK;
1786 }
1787 
PauseDragging()1788 Status MediaDemuxer::PauseDragging()
1789 {
1790     MEDIA_LOG_I("In");
1791     isPaused_ = true;
1792     if (streamDemuxer_) {
1793         streamDemuxer_->SetIsIgnoreParse(true);
1794         streamDemuxer_->Pause();
1795     }
1796     if (source_) {
1797         source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1798         source_->Pause();
1799     }
1800     if (CheckTrackEnabledById(videoTrackId_)) {
1801             taskMap_[videoTrackId_]->PauseAsync();
1802             taskMap_[videoTrackId_]->Pause();
1803             if (GetEnableSampleQueueFlag()) {
1804                 sampleConsumerTaskMap_[videoTrackId_]->PauseAsync();
1805                 sampleConsumerTaskMap_[videoTrackId_]->Pause();
1806             }
1807     }
1808 
1809     if (source_ != nullptr) {
1810         source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1811     }
1812     return Status::OK;
1813 }
1814 
PauseAudioAlign()1815 Status MediaDemuxer::PauseAudioAlign()
1816 {
1817     MEDIA_LOG_I("PauseDragging");
1818     isPaused_ = true;
1819     if (streamDemuxer_) {
1820         streamDemuxer_->SetIsIgnoreParse(true);
1821         streamDemuxer_->Pause();
1822     }
1823     if (source_) {
1824         source_->SetReadBlockingFlag(false); // Disable source read blocking to prevent pause all task blocking
1825         source_->Pause();
1826     }
1827     if (CheckTrackEnabledById(audioTrackId_)) {
1828             taskMap_[audioTrackId_]->PauseAsync();
1829             taskMap_[audioTrackId_]->Pause();
1830             if (GetEnableSampleQueueFlag()) {
1831                 sampleConsumerTaskMap_[audioTrackId_]->PauseAsync();
1832                 sampleConsumerTaskMap_[audioTrackId_]->Pause();
1833             }
1834     }
1835 
1836     if (source_ != nullptr) {
1837         source_->SetReadBlockingFlag(true); // Enable source read blocking to ensure get wanted data
1838     }
1839     return Status::OK;
1840 }
1841 
PauseTaskByTrackId(int32_t trackId)1842 Status MediaDemuxer::PauseTaskByTrackId(int32_t trackId)
1843 {
1844     MEDIA_LOG_I("In, track %{public}d", trackId);
1845     FALSE_RETURN_V_MSG_E(IsValidTrackId(trackId), Status::ERROR_INVALID_PARAMETER, "Invalid track");
1846 
1847     // To accelerate DemuxerLoop thread to run into PAUSED state
1848     if (CheckTrackEnabledById(trackId)) {
1849             taskMap_[trackId]->PauseAsync();
1850             taskMap_[trackId]->Pause();
1851             if (GetEnableSampleQueueFlag()) {
1852                 sampleConsumerTaskMap_[trackId]->PauseAsync();
1853                 sampleConsumerTaskMap_[trackId]->Pause();
1854             }
1855     }
1856     return Status::OK;
1857 }
1858 
Resume()1859 Status MediaDemuxer::Resume()
1860 {
1861     MEDIA_LOG_I("In");
1862     if (streamDemuxer_) {
1863         streamDemuxer_->Resume();
1864     }
1865     if (source_) {
1866         source_->Resume();
1867     }
1868     if (inPreroll_.load()) {
1869         if (CheckTrackEnabledById(videoTrackId_)) {
1870             if (streamDemuxer_) {
1871                 streamDemuxer_->SetIsIgnoreParse(false);
1872             }
1873             StartTaskInner(videoTrackId_);
1874         }
1875     } else {
1876         ResumeAllTask();
1877     }
1878     isPaused_ = false;
1879     return Status::OK;
1880 }
1881 
ResumeDragging()1882 Status MediaDemuxer::ResumeDragging()
1883 {
1884     MEDIA_LOG_I("In");
1885     ResetDraggingOpenGopCnt();
1886     for (auto item : eosMap_) {
1887         eosMap_[item.first] = false;
1888     }
1889     if (streamDemuxer_) {
1890         streamDemuxer_->Resume();
1891     }
1892     if (source_) {
1893         source_->Resume();
1894     }
1895     if (CheckTrackEnabledById(videoTrackId_)) {
1896         if (streamDemuxer_) {
1897             streamDemuxer_->SetIsIgnoreParse(false);
1898         }
1899         StartTaskInner(videoTrackId_);
1900     }
1901     isPaused_ = false;
1902     return Status::OK;
1903 }
1904 
ResumeAudioAlign()1905 Status MediaDemuxer::ResumeAudioAlign()
1906 {
1907     MEDIA_LOG_I("ResumeAudioAlign");
1908     {
1909         AutoLock lock(mapMutex_);
1910         auto it = bufferQueueMap_.begin();
1911         while (it != bufferQueueMap_.end()) {
1912             int32_t trackId = it->first;
1913             if (trackId == audioTrackId_) {
1914                 bufferQueueMap_[trackId]->Clear();
1915                 auto itSample = sampleQueueMap_.find(trackId);
1916                 if (itSample != sampleQueueMap_.end() && itSample->second != nullptr) {
1917                     itSample->second->Clear();
1918                 }
1919             }
1920             it++;
1921         }
1922     }
1923     if (streamDemuxer_) {
1924         streamDemuxer_->Resume();
1925     }
1926     if (source_) {
1927         source_->Resume();
1928     }
1929     if (CheckTrackEnabledById(audioTrackId_)) {
1930         if (streamDemuxer_) {
1931             streamDemuxer_->SetIsIgnoreParse(false);
1932         }
1933         StartTaskInner(audioTrackId_);
1934     }
1935     isPaused_ = false;
1936     return Status::OK;
1937 }
1938 
ResetInner()1939 void MediaDemuxer::ResetInner()
1940 {
1941     std::map<int32_t, std::shared_ptr<TrackWrapper>> trackMap;
1942     {
1943         AutoLock lock(mapMutex_);
1944         mediaMetaData_.globalMeta.reset();
1945         mediaMetaData_.trackMetas.clear();
1946     }
1947     Stop();
1948     {
1949         AutoLock lock(mapMutex_);
1950         std::swap(trackMap, trackMap_);
1951         bufferQueueMap_.clear();
1952         bufferMap_.clear();
1953         sampleQueueMap_.clear();
1954         localDrmInfos_.clear();
1955     }
1956     // Should perform trackMap_ clear without holding mapMutex_ to avoid dead lock:
1957     // 1. TrackWrapper indirectly holds notifyTask which holds its jobMutex_ firstly when run, then requires mapMutex_.
1958     // 2. Release notifyTask also needs hold its jobMutex_ firstly.
1959     trackMap.clear();
1960 }
1961 
Reset()1962 Status MediaDemuxer::Reset()
1963 {
1964     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Reset");
1965     FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1966     isDemuxerLoopExecuting_ = false;
1967     ResetInner();
1968     for (auto item : eosMap_) {
1969         eosMap_[item.first] = false;
1970     }
1971     for (auto item : requestBufferErrorCountMap_) {
1972         requestBufferErrorCountMap_[item.first] = 0;
1973     }
1974     videoStartTime_ = 0;
1975     streamDemuxer_->ResetAllCache();
1976     isSeekError_.store(false);
1977     return demuxerPluginManager_->Reset();
1978 }
1979 
Start()1980 Status MediaDemuxer::Start()
1981 {
1982     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Start");
1983     MEDIA_LOG_I("In");
1984     FALSE_RETURN_V_MSG_E(useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
1985     FALSE_RETURN_V_MSG_E(isThreadExit_, Status::OK, "Process has been started already");
1986     FALSE_RETURN_V_MSG_E(bufferQueueMap_.size() != 0, Status::OK, "No buffer queue");
1987     for (auto it = eosMap_.begin(); it != eosMap_.end(); it++) {
1988         it->second = false;
1989     }
1990     for (auto it = requestBufferErrorCountMap_.begin(); it != requestBufferErrorCountMap_.end(); it++) {
1991         it->second = 0;
1992     }
1993     InitPtsInfo();
1994     {
1995         std::unique_lock<std::mutex> stopLock(stopMutex_);
1996         isThreadExit_ = false;
1997         isStopped_ = false;
1998     }
1999     isDemuxerLoopExecuting_ = true;
2000     if (inPreroll_.load()) {
2001         if (CheckTrackEnabledById(videoTrackId_)) {
2002             StartTaskInner(videoTrackId_);
2003         }
2004     } else {
2005         auto it = bufferQueueMap_.begin();
2006         while (it != bufferQueueMap_.end()) {
2007             int32_t trackId = it->first;
2008             if (CheckTrackEnabledById(trackId)) {
2009                 StartTaskInner(trackId);
2010             } else {
2011                 MEDIA_LOG_W("Track " PUBLIC_LOG_D32 " task is not exist", trackId);
2012             }
2013             it++;
2014         }
2015     }
2016     source_->Start();
2017     return demuxerPluginManager_->Start();
2018 }
2019 
Preroll()2020 Status MediaDemuxer::Preroll()
2021 {
2022     std::lock_guard<std::mutex> lock(prerollMutex_);
2023     if (inPreroll_.load()) {
2024         return Status::OK;
2025     }
2026     if (!CheckTrackEnabledById(videoTrackId_)) {
2027         return Status::OK;
2028     }
2029     inPreroll_.store(true);
2030     MEDIA_LOG_I("Preroll enter.");
2031     Status ret = Status::OK;
2032     if (isStopped_.load()) {
2033         ret = Start();
2034     } else if (isPaused_.load()) {
2035         ret = Resume();
2036     }
2037     if (ret != Status::OK) {
2038         inPreroll_.store(false);
2039         MEDIA_LOG_E("Preroll failed, ret: %{public}d", ret);
2040     }
2041     return ret;
2042 }
2043 
PausePreroll()2044 Status MediaDemuxer::PausePreroll()
2045 {
2046     std::lock_guard<std::mutex> lock(prerollMutex_);
2047     if (!inPreroll_.load()) {
2048         return Status::OK;
2049     }
2050     MEDIA_LOG_I("PausePreroll enter.");
2051     Status ret = Pause();
2052     inPreroll_.store(false);
2053     return ret;
2054 }
2055 
Stop()2056 Status MediaDemuxer::Stop()
2057 {
2058     MEDIA_LOG_I("In");
2059     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::Stop");
2060     FALSE_RETURN_V_MSG_E(!isThreadExit_, Status::OK, "Thread exit");
2061     if (useBufferQueue_) {
2062         FALSE_RETURN_V_MSG_E(!isStopped_, Status::OK, "Process has been stopped already, ignore");
2063         {
2064             std::unique_lock<std::mutex> stopLock(stopMutex_);
2065             isStopped_ = true;
2066         }
2067         StopAllTask();
2068     }
2069     if (source_ != nullptr) {
2070         source_->Stop();
2071     }
2072     if (streamDemuxer_) {
2073         streamDemuxer_->Stop();
2074     }
2075     if (demuxerPluginManager_) {
2076         demuxerPluginManager_->Stop();
2077     }
2078     return Status::OK;
2079 }
2080 
HasVideo()2081 bool MediaDemuxer::HasVideo()
2082 {
2083     return IsValidTrackId(videoTrackId_);
2084 }
2085 
HasAudio()2086 bool MediaDemuxer::HasAudio()
2087 {
2088     return IsValidTrackId(audioTrackId_);
2089 }
2090 
SetIsCreatedByFilter(bool isCreatedByFilter)2091 void MediaDemuxer::SetIsCreatedByFilter(bool isCreatedByFilter)
2092 {
2093     isCreatedByFilter_ = isCreatedByFilter;
2094 }
2095 
InitMediaMetaData(const Plugins::MediaInfo & mediaInfo)2096 void MediaDemuxer::InitMediaMetaData(const Plugins::MediaInfo& mediaInfo)
2097 {
2098     AutoLock lock(mapMutex_);
2099     mediaMetaData_.globalMeta = std::make_shared<Meta>(mediaInfo.general);
2100     if (mediaMetaData_.globalMeta != nullptr && mediaMetaData_.globalMeta->GetData(Tag::MEDIA_FILE_TYPE, fileType_)) {
2101         MEDIA_LOG_D("FileType " PUBLIC_LOG_D32, static_cast<int32_t>(fileType_));
2102     }
2103     mediaMetaData_.trackMetas.clear();
2104     mediaMetaData_.trackMetas.reserve(mediaInfo.tracks.size());
2105     int32_t trackSize = static_cast<int32_t>(mediaInfo.tracks.size());
2106     for (int32_t index = 0; index < trackSize; index++) {
2107         auto trackMeta = mediaInfo.tracks[index];
2108         mediaMetaData_.trackMetas.emplace_back(std::make_shared<Meta>(trackMeta));
2109     }
2110 }
2111 
InitDefaultTrack(const Plugins::MediaInfo & mediaInfo,int32_t & videoTrackId,int32_t & audioTrackId,int32_t & subtitleTrackId,std::string & videoMime)2112 void MediaDemuxer::InitDefaultTrack(const Plugins::MediaInfo& mediaInfo, int32_t& videoTrackId,
2113     int32_t& audioTrackId, int32_t& subtitleTrackId, std::string& videoMime)
2114 {
2115     AutoLock lock(mapMutex_);
2116     std::string dafaultTrack = "[";
2117     int32_t trackSize = static_cast<int32_t>(mediaInfo.tracks.size());
2118     for (int32_t index = 0; index < trackSize; index++) {
2119         if (demuxerPluginManager_->CheckTrackIsActive(index) == false) {
2120             continue;
2121         }
2122         auto trackMeta = mediaInfo.tracks[index];
2123         std::string mimeType;
2124         bool ret = trackMeta.Get<Tag::MIME_TYPE>(mimeType);
2125         if (ret) {
2126             MEDIA_LOG_D("mimeType: " PUBLIC_LOG_S ", index: " PUBLIC_LOG_D32, mimeType.c_str(), index);
2127         }
2128         if (ret && mimeType.find("video") == 0 &&
2129             !IsTrackDisabled(Plugins::MediaType::VIDEO)) {
2130             isVideoTrackDisabled_ = false;
2131             dafaultTrack += "/V:";
2132             dafaultTrack += std::to_string(index);
2133             videoMime = mimeType;
2134             if (!IsValidTrackId(videoTrackId)) {
2135                 videoTrackId = index;
2136             }
2137             if (!trackMeta.GetData(Tag::MEDIA_START_TIME, videoStartTime_)) {
2138                 MEDIA_LOG_W("Get media start time failed");
2139             }
2140         } else if (ret && mimeType.find("audio") == 0 &&
2141             !IsTrackDisabled(Plugins::MediaType::AUDIO)) {
2142             dafaultTrack += "/A:";
2143             dafaultTrack += std::to_string(index);
2144             if (!IsValidTrackId(audioTrackId)) {
2145                 audioTrackId = index;
2146             }
2147         } else if (ret && IsSubtitleMime(mimeType) &&
2148             !IsTrackDisabled(Plugins::MediaType::SUBTITLE)) {
2149             dafaultTrack += "/S:";
2150             dafaultTrack += std::to_string(index);
2151             if (!IsValidTrackId(subtitleTrackId)) {
2152                 subtitleTrackId = index;
2153             }
2154         } else {}
2155     }
2156     dafaultTrack += "]";
2157     MEDIA_LOG_I(PUBLIC_LOG_S, dafaultTrack.c_str());
2158 }
2159 
IsOffsetValid(int64_t offset) const2160 bool MediaDemuxer::IsOffsetValid(int64_t offset) const
2161 {
2162     if (seekable_ == Plugins::Seekable::SEEKABLE) {
2163         return mediaDataSize_ == 0 || offset <= static_cast<int64_t>(mediaDataSize_);
2164     }
2165     return true;
2166 }
2167 
GetBufferFromUserQueue(int32_t queueIndex,int32_t size)2168 bool MediaDemuxer::GetBufferFromUserQueue(int32_t queueIndex, int32_t size)
2169 {
2170     MEDIA_LOG_DD("In, queue: " PUBLIC_LOG_D32 ", size: " PUBLIC_LOG_D32, queueIndex, size);
2171     if (GetEnableSampleQueueFlag()) {
2172         FALSE_RETURN_V_MSG_E(sampleQueueMap_.count(queueIndex) > 0 && sampleQueueMap_[queueIndex] != nullptr,
2173         false, "UserQueue " PUBLIC_LOG_D32 " is nullptr", queueIndex);
2174     } else {
2175         FALSE_RETURN_V_MSG_E(bufferQueueMap_.count(queueIndex) > 0 && bufferQueueMap_[queueIndex] != nullptr,
2176             false, "UserQueue " PUBLIC_LOG_D32 " is nullptr", queueIndex);
2177     }
2178     bool needSetSmallerSize = queueIndex == videoTrackId_ && hasSetLargeSize_ && !isVideoMuted_ && !needRestore_;
2179     if (needSetSmallerSize && sampleQueueMap_[queueIndex]->IsEmpty()) {
2180         sampleQueueMap_[queueIndex]->SetLargerQueueSize(SampleQueue::MAX_SAMPLE_QUEUE_SIZE);
2181         hasSetLargeSize_ = false;
2182     } else if (needSetSmallerSize) {
2183         return false;
2184     }
2185     bool needControlRead = !HasEosTrack() && queueIndex == videoTrackId_ && (isVideoMuted_ || needRestore_);
2186     if (needControlRead) {
2187         int64_t duration = 0;
2188         mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(duration);
2189         int64_t mediaTime = (duration > 0 && syncCenter_ != nullptr) ?
2190             syncCenter_->GetMediaTimeNow() : lastAudioPtsInMute_;
2191         if (lastVideoPts_ - mediaTime >= MAX_VIDEO_LEAD_TIME_ON_MUTE_US) {
2192             return false;
2193         }
2194     }
2195 
2196     AVBufferConfig avBufferConfig;
2197     if (isTranscoderMode_ && isSkippingAudioDecAndEnc_ && queueIndex == audioTrackId_) {
2198         avBufferConfig.memoryType = MemoryType::SHARED_MEMORY;
2199     }
2200     avBufferConfig.capacity = size + SAMPLE_BUFFER_SIZE_EXTRA;
2201     avBufferConfig.size = size;
2202     Status ret = Status::OK;
2203     if (GetEnableSampleQueueFlag()) {
2204         ret = sampleQueueMap_[queueIndex]->RequestBuffer(bufferMap_[queueIndex], avBufferConfig,
2205         REQUEST_BUFFER_TIMEOUT);
2206         bool needHandleSampleQueue = ret != Status::OK && isVideoMuted_ &&
2207             queueIndex == videoTrackId_ && !needReleaseVideoDecoder_;
2208         if (needHandleSampleQueue) {
2209             HandleVideoSampleQueue();
2210             ret = sampleQueueMap_[queueIndex]->RequestBuffer(bufferMap_[queueIndex], avBufferConfig,
2211                                                              REQUEST_BUFFER_TIMEOUT);
2212         }
2213     } else {
2214         ret = bufferQueueMap_[queueIndex]->RequestBuffer(bufferMap_[queueIndex], avBufferConfig,
2215         REQUEST_BUFFER_TIMEOUT);
2216     }
2217 
2218     RecordErrorCount(queueIndex, ret);
2219 
2220     return ret == Status::OK;
2221 }
2222 
RecordErrorCount(int32_t queueIndex,Status ret)2223 void MediaDemuxer::RecordErrorCount(int32_t queueIndex, Status ret)
2224 {
2225     if (ret != Status::OK) {
2226         requestBufferErrorCountMap_[queueIndex]++;
2227         if ((requestBufferErrorCountMap_[queueIndex] & 0x00000007) == 0) { // log per 8 times fail
2228             MEDIA_LOG_W("Request buffer failed, queue: " PUBLIC_LOG_D32 ", ret:" PUBLIC_LOG_D32
2229                 ", errorCnt:" PUBLIC_LOG_U32, queueIndex,
2230                 static_cast<int32_t>(ret), requestBufferErrorCountMap_[queueIndex]);
2231         }
2232         if (requestBufferErrorCountMap_[queueIndex] >= REQUEST_FAILED_RETRY_TIMES) {
2233             MEDIA_LOG_E("Request failed too many times in 1min");
2234         }
2235     } else {
2236         requestBufferErrorCountMap_[queueIndex] = 0;
2237         MEDIA_LOG_DD("RequestBuffer from UserQueue trackId=" PUBLIC_LOG_D32 ",size=" PUBLIC_LOG_U32, queueIndex, size);
2238     }
2239 }
2240 
HandleSelectTrackStreamSeek(int32_t streamID,int32_t & trackId)2241 void MediaDemuxer::HandleSelectTrackStreamSeek(int32_t streamID, int32_t& trackId)
2242 {
2243     int64_t startTime = 0;
2244     int64_t realSeekTime = 0;
2245     std::string mimeType;
2246     FALSE_RETURN(mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) &&
2247         mediaMetaData_.trackMetas[trackId]->Get<Tag::MEDIA_START_TIME>(startTime));
2248     if (mimeType.find("audio") == 0) {
2249         Status retSeek = demuxerPluginManager_->SingleStreamSeekTo((lastAudioPts_ - startTime) / US_TO_S,
2250             SeekMode::SEEK_CLOSEST_SYNC, streamID, realSeekTime);
2251         MEDIA_LOG_I("Audio lastAudioPts_ " PUBLIC_LOG_D64 " relativePts " PUBLIC_LOG_D64
2252             " realSeekTime " PUBLIC_LOG_D64" ret " PUBLIC_LOG_D32, lastAudioPts_,
2253             lastAudioPts_ - startTime, realSeekTime, static_cast<int32_t>(retSeek));
2254     }
2255     if (mimeType == "application/x-subrip" || mimeType == "text/vtt") {
2256         Status retSeek = demuxerPluginManager_->SingleStreamSeekTo((lastSubtitlePts_ - startTime) / US_TO_S,
2257             SeekMode::SEEK_CLOSEST_SYNC, streamID, realSeekTime);
2258         MEDIA_LOG_I("Subtitle lastSubtitlePts_ " PUBLIC_LOG_D64 " relativePts " PUBLIC_LOG_D64
2259             " realSeekTime " PUBLIC_LOG_D64 " ret " PUBLIC_LOG_D32, lastSubtitlePts_,
2260             lastSubtitlePts_ - startTime, realSeekTime, static_cast<int32_t>(retSeek));
2261     }
2262 }
2263 
HandleSelectTrackChangeStream(int32_t trackId,int32_t newStreamID,int32_t & newTrackId)2264 bool MediaDemuxer::HandleSelectTrackChangeStream(int32_t trackId, int32_t newStreamID, int32_t& newTrackId)
2265 {
2266     StreamType streamType = demuxerPluginManager_->GetStreamTypeByTrackID(trackId);
2267     TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
2268     int32_t currentStreamID = demuxerPluginManager_->GetStreamIDByTrackType(type);
2269     int32_t currentTrackId = trackId;
2270     if (newStreamID == -1 || currentStreamID == -1 || currentStreamID == newStreamID) {
2271         return false;
2272     }
2273     MEDIA_LOG_I("In");
2274     // stop plugin
2275     demuxerPluginManager_->StopPlugin(currentStreamID, streamDemuxer_);
2276 
2277     // start plugin
2278     Status ret = demuxerPluginManager_->StartPlugin(newStreamID, streamDemuxer_);
2279     FALSE_RETURN_V_MSG_E(ret == Status::OK, false, "Start plugin failed");
2280 
2281     // get new mediainfo
2282     Plugins::MediaInfo mediaInfo;
2283     demuxerPluginManager_->UpdateDefaultStreamID(mediaInfo, streamType, newStreamID);
2284     InitMediaMetaData(mediaInfo); // update mediaMetaData_
2285 
2286     // get newStreamID
2287     int32_t newInnerTrackId;
2288     demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId);
2289 
2290     // update track map
2291     demuxerPluginManager_->DeleteTempTrackMapInfo(currentTrackId);
2292     int32_t innerTrackID = demuxerPluginManager_->GetInnerTrackIDByTrackID(newTrackId);
2293     demuxerPluginManager_->UpdateTempTrackMapInfo(newTrackId, newTrackId, innerTrackID);
2294     MEDIA_LOG_I("Updata info");
2295 
2296     InnerSelectTrack(newTrackId);
2297 
2298     HandleSelectTrackStreamSeek(newStreamID, newTrackId);
2299 
2300     // update buffer queue
2301     bufferQueueMap_.insert(std::pair<int32_t, sptr<AVBufferQueueProducer>>(newTrackId,
2302         bufferQueueMap_[currentTrackId]));
2303     bufferMap_.insert(std::pair<int32_t, std::shared_ptr<AVBuffer>>(newTrackId,
2304         bufferMap_[currentTrackId]));
2305     bufferQueueMap_.erase(currentTrackId);
2306     bufferMap_.erase(currentTrackId);
2307 
2308     if (GetEnableSampleQueueFlag()) {
2309         AutoLock lock(mapMutex_);
2310         MEDIA_LOG_I("change TrackType: " PUBLIC_LOG_D32 ", TrackId " PUBLIC_LOG_D32 " >> " PUBLIC_LOG_D32,
2311             static_cast<int32_t>(type), currentTrackId, newTrackId);
2312         FALSE_RETURN_V_MSG_E(newTrackId != currentTrackId, true, "newTrackId equals currentTrackId");
2313         sampleQueueMap_.insert(
2314             std::pair<int32_t, std::shared_ptr<SampleQueue>>(newTrackId, sampleQueueMap_[currentTrackId]));
2315         sampleQueueMap_.erase(currentTrackId);
2316         bool hasSampleQueue = sampleQueueMap_.find(newTrackId) != sampleQueueMap_.end()
2317             && sampleQueueMap_[newTrackId] != nullptr;
2318         FALSE_RETURN_V_MSG_E(hasSampleQueue == true, false, "sampleQueueMap_ in newTrackId is null");
2319         sampleQueueMap_[newTrackId]->UpdateQueueId(newTrackId);
2320     }
2321     MEDIA_LOG_I("Out");
2322     return true;
2323 }
2324 
SelectTrackChangeStream(int32_t trackId)2325 bool MediaDemuxer::SelectTrackChangeStream(int32_t trackId)
2326 {
2327     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::SelectTrackChangeStream");
2328     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Invalid param");
2329     TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
2330     int32_t newStreamID = -1;
2331     if (type == TRACK_AUDIO) {
2332         newStreamID = streamDemuxer_->GetNewAudioStreamID();
2333     } else if (type == TRACK_SUBTITLE) {
2334         newStreamID = streamDemuxer_->GetNewSubtitleStreamID();
2335     } else if (type == TRACK_VIDEO) {
2336         newStreamID = streamDemuxer_->GetNewVideoStreamID();
2337     } else {
2338         MEDIA_LOG_W("Invalid track " PUBLIC_LOG_D32, trackId);
2339         return false;
2340     }
2341 
2342     int32_t newTrackId;
2343     bool ret = HandleSelectTrackChangeStream(trackId, newStreamID, newTrackId);
2344     if (ret && eventReceiver_ != nullptr) {
2345         MEDIA_LOG_I("TrackType: " PUBLIC_LOG_D32 ", TrackId " PUBLIC_LOG_D32 " >> " PUBLIC_LOG_D32,
2346             static_cast<int32_t>(type), trackId, newTrackId);
2347         if (type == TrackType::TRACK_AUDIO) {
2348             audioTrackId_ = newTrackId;
2349             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_AUDIO_TRACK_CHANGE, newTrackId});
2350             shouldCheckAudioFramePts_ = true;
2351         } else if (type == TrackType::TRACK_VIDEO) {
2352             videoTrackId_ = newTrackId;
2353             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_VIDEO_TRACK_CHANGE, newTrackId});
2354         } else if (type == TrackType::TRACK_SUBTITLE) {
2355             subtitleTrackId_ = newTrackId;
2356             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_SUBTITLE_TRACK_CHANGE, newTrackId});
2357             shouldCheckSubtitleFramePts_ = true;
2358         }
2359 
2360         {
2361             std::lock_guard<std::mutex> lock(isSelectTrackMutex_);
2362             if (inSelectTrackType_.find(static_cast<int32_t>(type)) != inSelectTrackType_.end() &&
2363                 inSelectTrackType_[static_cast<int32_t>(type)] == newTrackId) {
2364                 inSelectTrackType_.erase(static_cast<int32_t>(type));
2365             }
2366         }
2367         if (CheckTrackEnabledById(trackId)) {
2368             taskMap_[trackId]->StopAsync(); // stop self
2369             if (GetEnableSampleQueueFlag()) {
2370                 sampleConsumerTaskMap_[trackId]->StopAsync();
2371             }
2372         }
2373     }
2374     return ret;
2375 }
2376 
SelectBitRateChangeStream(int32_t trackId)2377 bool MediaDemuxer::SelectBitRateChangeStream(int32_t trackId)
2378 {
2379     (void) trackId;
2380     FALSE_RETURN_V(IsValidTrackId(videoTrackId_), false);
2381     int32_t currentStreamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(videoTrackId_);
2382     int32_t newStreamID = streamDemuxer_->GetNewVideoStreamID();
2383     if (newStreamID >= 0 && currentStreamID != newStreamID) {
2384         MEDIA_LOG_I("In");
2385         demuxerPluginManager_->StopPlugin(currentStreamID, streamDemuxer_);
2386 
2387         Status ret = demuxerPluginManager_->StartPlugin(newStreamID, streamDemuxer_);
2388         FALSE_RETURN_V_MSG_E(ret == Status::OK, false, "Start plugin failed");
2389 
2390         Plugins::MediaInfo mediaInfo;
2391         demuxerPluginManager_->UpdateDefaultStreamID(mediaInfo, VIDEO, newStreamID);
2392         InitMediaMetaData(mediaInfo); // update mediaMetaData_
2393 
2394         int32_t newInnerTrackId = -1;
2395         int32_t newTrackId = -1;
2396         if (isHlsFmp4_) {
2397             demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId, TRACK_VIDEO);
2398             demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, newTrackId, newInnerTrackId);
2399             newInnerTrackId = -1;
2400             newTrackId = -1;
2401             if (IsValidTrackId(audioTrackId_)) {
2402                 demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId, TRACK_AUDIO);
2403                 demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, newTrackId, newInnerTrackId);
2404             }
2405         } else {
2406             demuxerPluginManager_->GetTrackInfoByStreamID(newStreamID, newTrackId, newInnerTrackId);
2407             demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, newTrackId, newInnerTrackId);
2408         }
2409 
2410         MEDIA_LOG_I("Updata info");
2411         InnerSelectTrack(videoTrackId_);
2412         if (isHlsFmp4_ && IsValidTrackId(audioTrackId_)) {
2413             InnerSelectTrack(audioTrackId_);
2414         }
2415         MEDIA_LOG_I("Out");
2416         return true;
2417     }
2418     return false;
2419 }
2420 
DumpBufferToFile(int32_t trackId,std::shared_ptr<AVBuffer> buffer)2421 void MediaDemuxer::DumpBufferToFile(int32_t trackId, std::shared_ptr<AVBuffer> buffer)
2422 {
2423     std::string mimeType;
2424     if (isDump_) {
2425         if (mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) && mimeType.find("audio") == 0) {
2426                 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_DEMUXER_AUDIO_FILE_NAME, buffer);
2427         }
2428         if (mediaMetaData_.trackMetas[trackId]->Get<Tag::MIME_TYPE>(mimeType) && mimeType.find("video") == 0) {
2429                 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_DEMUXER_VIDEO_FILE_NAME, buffer);
2430         }
2431     }
2432 }
2433 
StartTaskInner(int32_t trackId)2434 void MediaDemuxer::StartTaskInner(int32_t trackId)
2435 {
2436     auto taskIt = taskMap_.find(trackId);
2437     if (taskIt != taskMap_.end() && taskIt->second != nullptr) {
2438         taskIt->second->Start();
2439     } else {
2440         MEDIA_LOG_W("Track " PUBLIC_LOG_D32 " task is not exist", trackId);
2441     }
2442     if (GetEnableSampleQueueFlag()) {
2443         auto sampleConsumerTaskIt = sampleConsumerTaskMap_.find(trackId);
2444         if (sampleConsumerTaskIt != sampleConsumerTaskMap_.end() && sampleConsumerTaskIt->second != nullptr) {
2445             FALSE_RETURN_MSG(trackId != videoTrackId_ || !isVideoMuted_ || needReleaseVideoDecoder_,
2446                 "sampleConsumerV is pause on mute, do not need to start");
2447             sampleConsumerTaskIt->second->Start();
2448         } else {
2449             MEDIA_LOG_W("Track " PUBLIC_LOG_D32 " sampleConsumerTask is not exist", trackId);
2450         }
2451     }
2452 }
2453 
PushBufferToQueue(int32_t trackId,std::shared_ptr<AVBuffer> & buffer,bool available)2454 Status MediaDemuxer::PushBufferToQueue(int32_t trackId, std::shared_ptr<AVBuffer>& buffer, bool available)
2455 {
2456     return GetEnableSampleQueueFlag() ? sampleQueueMap_[trackId]->PushBuffer(buffer, available) :
2457                     bufferQueueMap_[trackId]->PushBuffer(buffer, available);
2458 }
2459 
HandleVideoTrack(int32_t trackId)2460 void MediaDemuxer::HandleVideoTrack(int32_t trackId)
2461 {
2462     if (isVideoMuted_ && (bufferMap_[trackId]->flag_ & static_cast<uint32_t>(Plugins::AVBufferFlag::SYNC_FRAME))) {
2463         // callback release decoder
2464         if (needReleaseVideoDecoder_) {
2465             needReleaseVideoDecoder_ = false;
2466             MEDIA_LOG_I("MediaDemuxer::HandleReadSample read key frame, ReleaseVideoDecoder");
2467             eventReceiver_->OnEvent({"media_demuxer", EventType::EVENT_RELEASE_VIDEO_DECODER, trackId});
2468             bool needPauseSampleConsumer = sampleConsumerTaskMap_.find(videoTrackId_) !=
2469                 sampleConsumerTaskMap_.end() && sampleConsumerTaskMap_[videoTrackId_] != nullptr &&
2470                 sampleConsumerTaskMap_[videoTrackId_]->IsTaskRunning();
2471             if (needPauseSampleConsumer) {
2472                 sampleConsumerTaskMap_[videoTrackId_]->PauseAsync();
2473                 sampleConsumerTaskMap_[videoTrackId_]->Pause();
2474             }
2475             if (!hasSetLargeSize_) {
2476                 sampleQueueMap_[videoTrackId_]->SetLargerQueueSize(SAMPLE_QUEUE_SIZE_ON_MUTE);
2477                 hasSetLargeSize_ = true;
2478             }
2479         }
2480         sampleQueueMap_[trackId]->Clear();
2481     }
2482     lastVideoPts_ = bufferMap_[trackId]->pts_;
2483 }
2484 
HandleReadSample(int32_t trackId)2485 Status MediaDemuxer::HandleReadSample(int32_t trackId)
2486 {
2487     Status ret = InnerReadSample(trackId, bufferMap_[trackId], false);
2488     bool isBufferSizeValid = bufferMap_[trackId] != nullptr ? bufferMap_[trackId]->GetConfig().size > 0 : true;
2489     if (IsRightMediaTrack(trackId, DemuxerTrackType::VIDEO)) {
2490         std::unique_lock<std::mutex> draggingLock(draggingMutex_);
2491         HandleVideoTrack(trackId);
2492         if (VideoStreamReadyCallback_ != nullptr) {
2493             if (ret != Status::OK && ret != Status::END_OF_STREAM) {
2494                 PushBufferToQueue(trackId, bufferMap_[trackId], false);
2495                 MEDIA_LOG_E("Read failed, track " PUBLIC_LOG_D32 ", ret:" PUBLIC_LOG_D32,
2496                     trackId, static_cast<int32_t>(ret));
2497                 return ret;
2498             }
2499             std::shared_ptr<VideoStreamReadyCallback> videoStreamReadyCallback = VideoStreamReadyCallback_;
2500             draggingLock.unlock();
2501             bool isDiscardable = videoStreamReadyCallback->IsVideoStreamDiscardable(bufferMap_[trackId]);
2502             HandleEosDrag(trackId, isDiscardable);
2503             UpdateSyncFrameInfo(bufferMap_[trackId], trackId, isDiscardable);
2504             CopyBufferToDfxBufferQueue(bufferMap_[trackId], !isDiscardable && isBufferSizeValid);
2505             PushBufferToQueue(trackId, bufferMap_[trackId], !isDiscardable && isBufferSizeValid);
2506             return Status::OK;
2507         }
2508     }
2509 
2510     HandleSeek(trackId);
2511     if (ret == Status::OK || ret == Status::END_OF_STREAM) {
2512         if (bufferMap_[trackId]->flag_ & static_cast<uint32_t>(AVBufferFlag::EOS)) {
2513             return HandleTrackEos(trackId);
2514         }
2515         FALSE_GOON_NOEXEC(isAutoMaintainPts_, HandleAutoMaintainPts(trackId, bufferMap_[trackId]));
2516         lastVideoPts_ = trackId == videoTrackId_ ? bufferMap_[trackId]->pts_ : lastVideoPts_;
2517         lastAudioPtsInMute_ = trackId == audioTrackId_ ? bufferMap_[trackId]->pts_ : lastAudioPtsInMute_;
2518         bool isDroppable = IsBufferDroppable(bufferMap_[trackId], trackId);
2519         if (fileType_ == FileType::AVI && trackId == videoTrackId_) {
2520             SetOutputBufferPts(bufferMap_[trackId]);
2521         }
2522         FALSE_GOON_NOEXEC(isTranscoderMode_, TranscoderUpdateOutputBufferPts(trackId, bufferMap_[trackId]));
2523         CopyBufferToDfxBufferQueue(bufferMap_[trackId], !isDroppable && isBufferSizeValid);
2524         PushBufferToQueue(trackId, bufferMap_[trackId], !isDroppable && isBufferSizeValid);
2525     } else {
2526         PushBufferToQueue(trackId, bufferMap_[trackId], false);
2527         MEDIA_LOG_E("Read failed, track " PUBLIC_LOG_D32 ", ret:" PUBLIC_LOG_D32, trackId, static_cast<int32_t>(ret));
2528     }
2529     return ret;
2530 }
2531 
HandleEosDrag(int32_t trackId,bool isDiscardable)2532 void MediaDemuxer::HandleEosDrag(int32_t trackId, bool isDiscardable)
2533 {
2534     if (bufferMap_[trackId]->flag_ & static_cast<uint32_t>(AVBufferFlag::EOS) && !isDiscardable) {
2535         eosMap_[trackId] = true;
2536     }
2537 }
2538 
CopyBufferToDfxBufferQueue(std::shared_ptr<AVBuffer> buffer,bool dropable)2539 void MediaDemuxer::CopyBufferToDfxBufferQueue(std::shared_ptr<AVBuffer> buffer, bool dropable)
2540 {
2541     FALSE_RETURN_NOLOG(dfxBufferQueueProducer_ != nullptr && dfxBufferQueueConsumer_ != nullptr);
2542     FALSE_RETURN_NOLOG(!dropable);
2543     std::shared_ptr<AVBuffer> dfxBuffer = nullptr;
2544     auto config = buffer->GetConfig();
2545     config.memoryType = MemoryType::VIRTUAL_MEMORY;
2546     auto res = dfxBufferQueueProducer_->RequestBuffer(dfxBuffer, config, REQUEST_BUFFER_TIMEOUT);
2547     if (res != Status::OK) {
2548         std::shared_ptr<AVBuffer> tmpBuffer = nullptr;
2549         dfxBufferQueueConsumer_->AcquireBuffer(tmpBuffer);
2550         dfxBufferQueueConsumer_->ReleaseBuffer(tmpBuffer);
2551         res = dfxBufferQueueProducer_->RequestBuffer(dfxBuffer, config, REQUEST_BUFFER_TIMEOUT);
2552     }
2553     FALSE_RETURN(res == Status::OK && dfxBuffer != nullptr);
2554     res = AVBuffer::Clone(buffer, dfxBuffer);
2555     TRUE_LOG(res != Status::OK, MEDIA_LOG_E, "Clone AVBuffer failed, errCode %{public}d", static_cast<int32_t>(res));
2556     dfxBufferQueueProducer_->PushBuffer(dfxBuffer, res == Status::OK);
2557 }
2558 
Sha256HashMemory(const void * data,size_t size)2559 std::string Sha256HashMemory(const void* data, size_t size)
2560 {
2561     unsigned char hash[SHA256_DIGEST_LENGTH];
2562     SHA256_CTX sha256;
2563 
2564     SHA256_Init(&sha256);
2565     SHA256_Update(&sha256, data, size);
2566     SHA256_Final(hash, &sha256);
2567 
2568     static const int32_t setWNum = 2;
2569     std::stringstream ss;
2570     for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
2571         ss << std::hex << std::setw(setWNum) << std::setfill('0') << static_cast<int32_t>(hash[i]);
2572     }
2573     return ss.str();
2574 }
2575 
HandleDecoderErrorFrame(int64_t pts)2576 void MediaDemuxer::HandleDecoderErrorFrame(int64_t pts)
2577 {
2578     FALSE_RETURN_NOLOG(dfxBufferQueueConsumer_ != nullptr && dfxBufferQueueProducer_ != nullptr);
2579     for (std::shared_ptr<AVBuffer> buffer = nullptr; dfxBufferQueueConsumer_->AcquireBuffer(buffer) == Status::OK;) {
2580         ON_SCOPE_EXIT(0) {
2581             dfxBufferQueueConsumer_->ReleaseBuffer(buffer);
2582         };
2583         if (buffer->pts_ == pts) {
2584             FALSE_RETURN_MSG_W(
2585                 buffer->memory_->GetAddr() != nullptr && buffer->memory_->GetSize() > 0, "invalid buffer");
2586             auto hashStr = Sha256HashMemory(buffer->memory_->GetAddr(), buffer->memory_->GetSize());
2587             MEDIA_LOG_E("InputBuffer hash res %{public}s", hashStr.c_str());
2588             return;
2589         }
2590         continue;
2591     }
2592     MEDIA_LOG_E("Cant find buffer with same pts " PUBLIC_LOG_D64 ", maybe Gop is too long", pts);
2593 }
2594 
HandleSeek(int32_t trackId)2595 void MediaDemuxer::HandleSeek(int32_t trackId)
2596 {
2597     if (source_ != nullptr && source_->IsSeekToTimeSupported() && isSeeked_ && HasVideo()) {
2598         if (trackId == videoTrackId_ && isFirstFrameAfterSeek_.load()) {
2599             bool isSyncFrame = (bufferMap_[trackId]->flag_ & static_cast<uint32_t>(AVBufferFlag::SYNC_FRAME)) != 0;
2600             if (!isSyncFrame) {
2601                 MEDIA_LOG_E("The first frame after seeking is not a sync frame");
2602             }
2603             isFirstFrameAfterSeek_.store(false);
2604         }
2605         MEDIA_LOG_I("Seeking, found idr frame track " PUBLIC_LOG_D32, trackId);
2606         isSeeked_ = false;
2607     }
2608 }
2609 
HandleTrackEos(int32_t trackId)2610 Status MediaDemuxer::HandleTrackEos(int32_t trackId)
2611 {
2612     eosMap_[trackId] = true;
2613     if (taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr) {
2614         taskMap_[trackId]->StopAsync();
2615     }
2616     MEDIA_LOG_I("Track eos, track: " PUBLIC_LOG_D32 ", bufferId: " PUBLIC_LOG_U64
2617         ", pts: " PUBLIC_LOG_D64 ", flag: " PUBLIC_LOG_U32, trackId, bufferMap_[trackId]->GetUniqueId(),
2618         bufferMap_[trackId]->pts_, bufferMap_[trackId]->flag_);
2619     PushBufferToQueue(trackId, bufferMap_[trackId], true);
2620     if (trackId == videoTrackId_ && isVideoMuted_) {
2621         ReportEosEvent();
2622     }
2623     return Status::OK;
2624 }
2625 
GenerateDfxBufferQueue(int32_t trackId)2626 Status MediaDemuxer::GenerateDfxBufferQueue(int32_t trackId)
2627 {
2628     FALSE_RETURN_V_NOLOG(enableDfxBufferQueue_ && trackId == videoTrackId_, Status::OK);
2629     dfxBufferQueue_ = AVBufferQueue::Create(DFX_BUFFER_QUEUE_SIZE_MAX, MemoryType::VIRTUAL_MEMORY, "DfxBufferQueue");
2630     dfxBufferQueueProducer_ = dfxBufferQueue_->GetProducer();
2631     dfxBufferQueueConsumer_ = dfxBufferQueue_->GetConsumer();
2632 
2633     static const int32_t normalBufferSize = 256 * 1024;
2634     for (uint32_t i = 0; i < DFX_BUFFER_QUEUE_SIZE_MAX; i++) {
2635         auto avAllocator = AVAllocatorFactory::CreateVirtualAllocator();
2636         std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(avAllocator, normalBufferSize);
2637         FALSE_RETURN_V_MSG_E(buffer != nullptr, Status::ERROR_NO_MEMORY, "CreateAVBuffer failed");
2638         Status status = dfxBufferQueueProducer_->AttachBuffer(buffer, false);
2639         FALSE_RETURN_V_MSG_E(
2640             status == Status::OK, status, "AttachBuffer failed status=" PUBLIC_LOG_D32, static_cast<int32_t>(status));
2641     }
2642     MEDIA_LOG_I("Generate DFX buffer queue success");
2643     return Status::OK;
2644 }
2645 
ReportEosEvent()2646 void MediaDemuxer::ReportEosEvent()
2647 {
2648     MEDIA_LOG_I("MediaDemuxer ReportEOSEvent");
2649     FALSE_RETURN_MSG(eventReceiver_ != nullptr, "MediaDemuxer ReportEOSEvent without eventReceiver_");
2650     Event event {
2651         .srcFilter = "VideoSink",
2652         .type = EventType::EVENT_COMPLETE,
2653     };
2654     eventReceiver_->OnEvent(event);
2655 }
2656 
SetOutputBufferPts(std::shared_ptr<AVBuffer> & outputBuffer)2657 void MediaDemuxer::SetOutputBufferPts(std::shared_ptr<AVBuffer> &outputBuffer)
2658 {
2659     FALSE_RETURN_MSG(outputBuffer != nullptr, "outputBuffer is nullptr.");
2660 
2661     MEDIA_LOG_DD("OutputBuffer PTS: " PUBLIC_LOG_D64 " DTS: " PUBLIC_LOG_D64, outputBuffer->pts_, outputBuffer->dts_);
2662     outputBuffer->pts_ = outputBuffer->dts_;
2663 }
2664 
TranscoderUpdateOutputBufferPts(int32_t trackId,std::shared_ptr<AVBuffer> & outputBuffer)2665 void MediaDemuxer::TranscoderUpdateOutputBufferPts(int32_t trackId, std::shared_ptr<AVBuffer> &outputBuffer)
2666 {
2667     FALSE_RETURN_NOLOG(isTranscoderMode_);
2668     if (transcoderStartPts_ > 0 && outputBuffer != nullptr) {
2669         outputBuffer->pts_ -= transcoderStartPts_;
2670     }
2671 }
2672 
HandleDashChangeStream(int32_t trackId)2673 bool MediaDemuxer::HandleDashChangeStream(int32_t trackId)
2674 {
2675     // the caller should insure demuxerPluginManager_ not nullptr and isDash_ true
2676     FALSE_RETURN_V_MSG_E(streamDemuxer_ != nullptr, false, "Stream is nullptr");
2677 
2678     MEDIA_LOG_D("IN");
2679     TrackType type = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
2680     int32_t currentStreamID = demuxerPluginManager_->GetStreamIDByTrackType(type);
2681     int32_t newStreamID = demuxerPluginManager_->GetStreamDemuxerNewStreamID(type, streamDemuxer_);
2682     bool ret = false;
2683     FALSE_RETURN_V_NOLOG(newStreamID != -1 && currentStreamID != newStreamID, ret);
2684 
2685     MEDIA_LOG_I("Change stream begin, currentStreamID: " PUBLIC_LOG_D32 " newStreamID: " PUBLIC_LOG_D32,
2686         currentStreamID, newStreamID);
2687     if ((trackId == videoTrackId_ || isHlsFmp4_) && demuxerPluginManager_->GetCurrentBitRate() != targetBitRate_) {
2688         ret = SelectBitRateChangeStream(trackId);
2689         if (ret) {
2690             streamDemuxer_->SetChangeFlag(true);
2691             MEDIA_LOG_I("targetBitrate: " PUBLIC_LOG_U32 " currentBitrate: " PUBLIC_LOG_U32, targetBitRate_,
2692                 demuxerPluginManager_->GetCurrentBitRate());
2693             isSelectBitRate_.store(targetBitRate_ != demuxerPluginManager_->GetCurrentBitRate());
2694         }
2695     } else {
2696         isSelectTrack_.store(true);
2697         ret = SelectTrackChangeStream(trackId);
2698         if (ret) {
2699             MEDIA_LOG_I("targetBitrate: " PUBLIC_LOG_U32 " currentBitrate: " PUBLIC_LOG_U32, targetBitRate_,
2700                 demuxerPluginManager_->GetCurrentBitRate());
2701             targetBitRate_ = demuxerPluginManager_->GetCurrentBitRate();
2702             streamDemuxer_->SetChangeFlag(true);
2703         }
2704         isSelectTrack_.store(false);
2705     }
2706     MEDIA_LOG_I("Change stream success");
2707     return ret;
2708 }
2709 
CopyFrameToUserQueue(int32_t trackId)2710 Status MediaDemuxer::CopyFrameToUserQueue(int32_t trackId)
2711 {
2712     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::CopyFrameToUserQueue");
2713     MEDIA_LOG_D("CopyFrameToUserQueue IN, track:" PUBLIC_LOG_D32, trackId);
2714 
2715     int32_t innerTrackID = trackId;
2716     int32_t id = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
2717     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = demuxerPluginManager_->GetPluginByStreamID(id);
2718     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
2719     if (IsNeedMapToInnerTrackID()) {
2720         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
2721     }
2722     GetMemoryUsage(trackId, pluginTemp);
2723     int32_t size = 0;
2724     Status ret = enableAsyncDemuxer_ ?
2725         pluginTemp->GetNextSampleSize(static_cast<uint32_t>(innerTrackID), size, timeout_) :
2726         pluginTemp->GetNextSampleSize(static_cast<uint32_t>(innerTrackID), size);
2727     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_WAIT_TIMEOUT, ret, "Get size timeout " PUBLIC_LOG_D32, trackId);
2728     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_UNKNOWN, ret, "Get size failed for track " PUBLIC_LOG_D32, trackId);
2729     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_AGAIN, ret,
2730         "Get size failed for track " PUBLIC_LOG_D32 ", retry", trackId);
2731     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_NO_MEMORY, ret, "Get size failed for track " PUBLIC_LOG_D32, trackId);
2732     FALSE_RETURN_V_MSG_E(ret != Status::ERROR_WRONG_STATE, ret, " Get size interrupt");
2733     if (demuxerPluginManager_->IsDash() && HandleDashChangeStream(trackId)) {
2734         MEDIA_LOG_I("HandleDashChangeStream success");
2735         return Status::OK;
2736     }
2737 
2738     SetTrackNotifyFlag(trackId, true);
2739     if (!GetBufferFromUserQueue(trackId, size)) {
2740         return Status::ERROR_INVALID_PARAMETER;
2741     }
2742     SetTrackNotifyFlag(trackId, false);
2743     ret = HandleReadSample(trackId);
2744     MEDIA_LOG_DD("CopyFrameToUserQueue Out, track:" PUBLIC_LOG_D32, trackId);
2745     return ret;
2746 }
2747 
InnerReadSample(int32_t trackId,std::shared_ptr<AVBuffer> sample,bool isAVDemuxer)2748 Status MediaDemuxer::InnerReadSample(int32_t trackId, std::shared_ptr<AVBuffer> sample, bool isAVDemuxer)
2749 {
2750     MEDIA_LOG_DD("InnerReadSample In, track " PUBLIC_LOG_D32, trackId);
2751 
2752     int32_t innerTrackID = trackId;
2753     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
2754     if (IsNeedMapToInnerTrackID()) {
2755         int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
2756         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
2757         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
2758         innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
2759     } else {
2760         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(demuxerPluginManager_->GetStreamIDByTrackID(trackId));
2761         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Demuxer plugin is nullptr");
2762     }
2763 
2764     int64_t threshold = trackId == audioTrackId_ ? READSAMPLE_AUIDO_WARNING_MS : READSAMPLE_WARNING_MS;
2765     Status ret = Status::OK;
2766     {
2767         ScopedTimer timer("ReadSample", threshold);
2768         ret = ReadSampleWithPerfRecord(pluginTemp, innerTrackID, sample, isAVDemuxer);
2769     }
2770     if (ret == Status::END_OF_STREAM) {
2771         MEDIA_LOG_I("Read eos for track " PUBLIC_LOG_D32, trackId);
2772     } else if (ret != Status::OK) {
2773         MEDIA_LOG_I("Read error for track " PUBLIC_LOG_D32 ", ret: " PUBLIC_LOG_D32,
2774             trackId, (int32_t)(ret));
2775     }
2776     MEDIA_LOG_D("InnerReadSample Out, track " PUBLIC_LOG_D32, trackId);
2777 
2778     // to get DrmInfo
2779     ProcessDrmInfos();
2780     return ret;
2781 }
2782 
ReadSampleWithPerfRecord(const std::shared_ptr<Plugins::DemuxerPlugin> & pluginTemp,const int32_t & innerTrackID,const std::shared_ptr<AVBuffer> & sample,bool isAVDemuxer)2783 Status MediaDemuxer::ReadSampleWithPerfRecord(const std::shared_ptr<Plugins::DemuxerPlugin> &pluginTemp,
2784     const int32_t &innerTrackID, const std::shared_ptr<AVBuffer> &sample, bool isAVDemuxer)
2785 {
2786     Status ret = Status::OK;
2787     int64_t demuxDuration = 0;
2788     if (isAVDemuxer || !enableAsyncDemuxer_) {
2789         FALSE_RETURN_V_NOLOG(perfRecEnabled_, pluginTemp->ReadSample(static_cast<uint32_t>(innerTrackID), sample));
2790         demuxDuration =
2791             CALC_EXPR_TIME_MS(ret = pluginTemp->ReadSample(static_cast<uint32_t>(innerTrackID), sample));
2792     } else {
2793         FALSE_RETURN_V_NOLOG(perfRecEnabled_,
2794             pluginTemp->ReadSample(static_cast<uint32_t>(innerTrackID), sample, timeout_));
2795         demuxDuration =
2796             CALC_EXPR_TIME_MS(ret = pluginTemp->ReadSample(static_cast<uint32_t>(innerTrackID), sample, timeout_));
2797     }
2798     FALSE_RETURN_V_MSG(eventReceiver_ != nullptr, Status::OK, "Report perf failed, callback is nullptr");
2799     FALSE_RETURN_V_NOLOG(perfRecorder_.Record(demuxDuration) == PerfRecorder::FULL, ret);
2800     eventReceiver_->OnDfxEvent({ "DEMUX", DfxEventType::DFX_INFO_PERF_REPORT, perfRecorder_.GetMainPerfData() });
2801     perfRecorder_.Reset();
2802     return ret;
2803 }
2804 
SetPerfRecEnabled(bool isPerfRecEnabled)2805 Status MediaDemuxer::SetPerfRecEnabled(bool isPerfRecEnabled)
2806 {
2807     MEDIA_LOG_I("widdraw DoSetPerfRecEnabled %{public}d", isPerfRecEnabled);
2808     perfRecEnabled_ = isPerfRecEnabled;
2809     FALSE_RETURN_V_MSG(source_ != nullptr, Status::ERROR_NO_MEMORY, "Source not exist, no memory");
2810     source_->SetPerfRecEnabled(isPerfRecEnabled);
2811     return Status::OK;
2812 }
2813 
GetReadLoopRetryUs(int32_t trackId)2814 int64_t MediaDemuxer::GetReadLoopRetryUs(int32_t trackId)
2815 {
2816     FALSE_RETURN_V_NOLOG(GetEnableSampleQueueFlag(), 0);
2817     FALSE_RETURN_V_NOLOG(isFlvLiveStream_, NEXT_DELAY_TIME_US);
2818     FALSE_RETURN_V_MSG_E(sampleQueueMap_.count(trackId) > 0 && sampleQueueMap_[trackId] != nullptr, NEXT_DELAY_TIME_US,
2819         "sampleQueue " PUBLIC_LOG_D32 " is nullptr", trackId);
2820     uint64_t sampleDuration = sampleQueueMap_[trackId]->GetCacheDuration();
2821     if (sampleDuration <= SAMPLE_FLOW_CONTROL_MIN_SAMPLE_DURATION_US  ||
2822         ((isVideoMuted_ || needRestore_ || hasSetLargeSize_) && trackId == videoTrackId_)) {
2823         return NEXT_DELAY_TIME_US;
2824     }
2825     return static_cast<int64_t>(sampleDuration >> SAMPLE_FLOW_CONTROL_RATE_POW);
2826 }
2827 
DoBeforeEachLoop(int32_t trackId)2828 int64_t MediaDemuxer::DoBeforeEachLoop(int32_t trackId)
2829 {
2830     FALSE_RETURN_V_NOLOG(demuxerPluginManager_ != nullptr, 0);
2831     auto trackType = demuxerPluginManager_->GetTrackTypeByTrackID(trackId);
2832     auto hasRegisteredFunc = funcBeforeReadSampleMap_.find(trackType) != funcBeforeReadSampleMap_.end();
2833     FALSE_RETURN_V_NOLOG(hasRegisteredFunc, 0);
2834     return funcBeforeReadSampleMap_[trackType](trackId);
2835 }
2836 
DoBeforeSubtitleTrackReadLoop(int32_t trackId)2837 int64_t MediaDemuxer::DoBeforeSubtitleTrackReadLoop(int32_t trackId)
2838 {
2839     FALSE_RETURN_V_NOLOG(!demuxerPluginManager_->IsDash() && subStreamDemuxer_ == nullptr, static_cast<int64_t>(0));
2840     auto subtitleStreamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
2841     auto subtitleDemuxerPlugin = demuxerPluginManager_->GetPluginByStreamID(subtitleStreamId);
2842     FALSE_RETURN_V_MSG_E(subtitleDemuxerPlugin != nullptr, RETRY_DELAY_TIME_US,
2843         "Invalid demuxer plugin, unabled to read subtitle sample");
2844     uint32_t cacheSize = 0;
2845     auto res = subtitleDemuxerPlugin->GetCurrentCacheSize(trackId, cacheSize);
2846     // Only if demuxer plugin has subtitle cache can read subtitle sample
2847     if (res == Status::OK && cacheSize > 0) {
2848         MEDIA_LOG_DD("Demuxer plugin has cached subtitle data size " PUBLIC_LOG_U32, cacheSize);
2849         return static_cast<int64_t>(0);
2850     }
2851     MEDIA_LOG_DD("Invalid cache size for subtitle track GetCurrentCacheSize res " PUBLIC_LOG_D32
2852                 " size " PUBLIC_LOG_U32, static_cast<int32_t>(res), cacheSize);
2853     return RETRY_DELAY_TIME_US;
2854 }
2855 
ReadLoop(int32_t trackId)2856 int64_t MediaDemuxer::ReadLoop(int32_t trackId)
2857 {
2858     if (streamDemuxer_->GetIsIgnoreParse() || isStopped_ || isPaused_ || isSeekError_ || isFlvLiveSelectingBitRate_) {
2859         MEDIA_LOG_D("ReadLoop pausing or error, track " PUBLIC_LOG_D32, trackId);
2860         perfRecorder_.Reset();
2861         return 6 * 1000; // sleep 6ms in pausing to avoid useless reading
2862     } else {
2863         auto resPreReadSample = DoBeforeEachLoop(trackId);
2864         FALSE_RETURN_V_NOLOG(resPreReadSample == 0, resPreReadSample);
2865         Status ret = CopyFrameToUserQueue(trackId);
2866         // when read failed, or request always failed in 1min, send error event
2867         bool ignoreError = isStopped_ || isPaused_ || isInterruptNeeded_.load();
2868         if ((ret == Status::ERROR_UNKNOWN && !ignoreError) ||
2869              requestBufferErrorCountMap_[trackId] >= REQUEST_FAILED_RETRY_TIMES) {
2870             MEDIA_LOG_E("Invalid data source, can not get frame");
2871             if (eventReceiver_ != nullptr) {
2872                 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DATA_SOURCE_ERROR_UNKNOWN});
2873             } else {
2874                 MEDIA_LOG_D("EventReceiver is nullptr");
2875             }
2876         }
2877         FALSE_GOON_NOEXEC(ret == Status::ERROR_PACKET_CONVERT_FAILED, HandlePacketConvertError());
2878         FALSE_GOON_NOEXEC(ret == Status::OK, convertErrorTime_.store(0));
2879         bool isNeedRetry = ret == Status::OK || ret == Status::ERROR_AGAIN || ret == Status::ERROR_WAIT_TIMEOUT;
2880         if (isNeedRetry) {
2881             return GetReadLoopRetryUs(trackId);
2882         } else if (ret == Status::ERROR_NO_MEMORY) {
2883             MEDIA_LOG_E("Cache data size is out of limit");
2884             if (eventReceiver_ != nullptr && !isOnEventNoMemory_.load()) {
2885                 isOnEventNoMemory_.store(true);
2886                 eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DEMUXER_BUFFER_NO_MEMORY});
2887             }
2888             return GetEnableSampleQueueFlag() ? NEXT_DELAY_TIME_US : 0;
2889         } else {
2890             MEDIA_LOG_DD("ReadLoop wait, track:" PUBLIC_LOG_D32 ", ret:" PUBLIC_LOG_D32,
2891                 trackId, static_cast<int32_t>(ret));
2892             return RETRY_DELAY_TIME_US; // delay to retry if no frame
2893         }
2894     }
2895 }
2896 
HandlePacketConvertError()2897 void MediaDemuxer::HandlePacketConvertError()
2898 {
2899     ++convertErrorTime_;
2900     TRUE_LOG(convertErrorTime_.load() == 1, MEDIA_LOG_W, "PacketConvert error once");
2901     FALSE_RETURN_NOLOG(convertErrorTime_ >= CONVERT_PACKET_ERROR_MAX_COUNT);
2902     MEDIA_LOG_E("PacketConvertError happened %{public}d times, stream is unsupported!", convertErrorTime_.load());
2903     FALSE_RETURN_MSG(eventReceiver_ != nullptr, "eventReceiver_ is nullptr");
2904     eventReceiver_->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, MSERR_DATA_SOURCE_ERROR_UNKNOWN});
2905 }
2906 
ReadSample(uint32_t trackIndex,std::shared_ptr<AVBuffer> sample)2907 Status MediaDemuxer::ReadSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
2908 {
2909     MediaAVCodec::AVCODEC_SYNC_TRACE;
2910     FALSE_RETURN_V_MSG_E(!useBufferQueue_, Status::ERROR_WRONG_STATE, "Not buffer queue mode");
2911     MEDIA_LOG_DD("ReadSample In");
2912     FALSE_RETURN_V_MSG_E(eosMap_.count(trackIndex) > 0, Status::ERROR_INVALID_OPERATION, "Track has not been selected");
2913     FALSE_RETURN_V_MSG_E(sample != nullptr && sample->memory_!=nullptr, Status::ERROR_INVALID_PARAMETER,
2914         "AVBuffer is nullptr");
2915     if (eosMap_[trackIndex]) {
2916         MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " has reached eos", trackIndex);
2917         sample->flag_ = static_cast<uint32_t>(AVBufferFlag::EOS);
2918         sample->memory_->SetSize(0);
2919         return Status::END_OF_STREAM;
2920     }
2921     Status ret = InnerReadSample(static_cast<int32_t>(trackIndex), sample, true);
2922     if (ret == Status::OK || ret == Status::END_OF_STREAM) {
2923         if (sample->flag_ & static_cast<uint32_t>(AVBufferFlag::EOS)) {
2924             eosMap_[trackIndex] = true;
2925             sample->memory_->SetSize(0);
2926         }
2927         if (sample->flag_ & static_cast<uint32_t>(AVBufferFlag::PARTIAL_FRAME)) {
2928             ret = Status::ERROR_NO_MEMORY;
2929         }
2930     }
2931     return ret;
2932 }
2933 
HandleSourceDrmInfoEvent(const std::multimap<std::string,std::vector<uint8_t>> & info)2934 void MediaDemuxer::HandleSourceDrmInfoEvent(const std::multimap<std::string, std::vector<uint8_t>> &info)
2935 {
2936     MEDIA_LOG_I("In");
2937     std::multimap<std::string, std::vector<uint8_t>> infoUpdated;
2938     bool isUpdated = GetDrmInfosUpdated(info, infoUpdated);
2939     if (isUpdated) {
2940         ReportDrmInfos(infoUpdated);
2941         return;
2942     }
2943     MEDIA_LOG_D("Demuxer filter received source drminfos but not update");
2944 }
2945 
HandleEvent(const Plugins::PluginEvent & event)2946 void MediaDemuxer::HandleEvent(const Plugins::PluginEvent &event)
2947 {
2948     switch (event.type) {
2949         case PluginEventType::CLIENT_ERROR:
2950         case PluginEventType::SERVER_ERROR: {
2951             MEDIA_LOG_E("HandleEvent CLIENT/SERVER_ERROR");
2952             FALSE_RETURN(demuxerPluginManager_ != nullptr);
2953             demuxerPluginManager_->NotifyInitialBufferingEnd(false);
2954             break;
2955         }
2956         case PluginEventType::INITIAL_BUFFER_SUCCESS: {
2957             MEDIA_LOG_I("HandleEvent initial buffer success");
2958             FALSE_RETURN(demuxerPluginManager_ != nullptr);
2959             demuxerPluginManager_->NotifyInitialBufferingEnd(true);
2960             break;
2961         }
2962         default:
2963             break;
2964     }
2965 }
2966 
OnEvent(const Plugins::PluginEvent & event)2967 void MediaDemuxer::OnEvent(const Plugins::PluginEvent &event)
2968 {
2969     MEDIA_LOG_D("In");
2970     HandleEvent(event);
2971     std::weak_ptr<Pipeline::EventReceiver> weakEventReceiver = eventReceiver_;
2972     auto eventReceiver = weakEventReceiver.lock();
2973     if (eventReceiver == nullptr && event.type != PluginEventType::SOURCE_DRM_INFO_UPDATE) {
2974         MEDIA_LOG_D("EventReceiver is nullptr");
2975         return;
2976     }
2977     switch (event.type) {
2978         case PluginEventType::SOURCE_DRM_INFO_UPDATE: {
2979             MEDIA_LOG_D("OnEvent source drmInfo update");
2980             if (Any::IsSameTypeWith<std::multimap<std::string, std::vector<uint8_t>>>(event.param)) {
2981                 HandleSourceDrmInfoEvent(AnyCast<std::multimap<std::string, std::vector<uint8_t>>>(event.param));
2982             }
2983             break;
2984         }
2985         case PluginEventType::CLIENT_ERROR:
2986         case PluginEventType::SERVER_ERROR: {
2987             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_ERROR, event.param});
2988             break;
2989         }
2990         case PluginEventType::CACHED_DURATION: {
2991             MEDIA_LOG_D("OnEvent cached duration");
2992             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_CACHED_DURATION, event.param});
2993             break;
2994         }
2995         case PluginEventType::SOURCE_BITRATE_START: {
2996             MEDIA_LOG_D("OnEvent source bitrate start");
2997             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_SOURCE_BITRATE_START, event.param});
2998             break;
2999         }
3000         case PluginEventType::FLV_AUTO_SELECT_BITRATE: {
3001             MEDIA_LOG_D("OnEvent flv auto select bitrate.");
3002             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_FLV_AUTO_SELECT_BITRATE, event.param});
3003             break;
3004         }
3005         default:
3006             break;
3007     }
3008     OnEventBuffer(event, eventReceiver);
3009 }
3010 
OnEventBuffer(const Plugins::PluginEvent & event,std::shared_ptr<Pipeline::EventReceiver> eventReceiver)3011 void MediaDemuxer::OnEventBuffer(const Plugins::PluginEvent &event,
3012     std::shared_ptr<Pipeline::EventReceiver> eventReceiver)
3013 {
3014     switch (event.type) {
3015         case PluginEventType::BUFFERING_END: {
3016             MEDIA_LOG_D("OnEvent pause");
3017             eventReceiver->OnEvent({"demuxer_filter", EventType::BUFFERING_END, PAUSE});
3018             break;
3019         }
3020         case PluginEventType::BUFFERING_START: {
3021             MEDIA_LOG_D("OnEvent start");
3022             eventReceiver->OnEvent({"demuxer_filter", EventType::BUFFERING_START, START});
3023             break;
3024         }
3025         case PluginEventType::EVENT_BUFFER_PROGRESS: {
3026             MEDIA_LOG_D("OnEvent percent update");
3027             eventReceiver->OnEvent({"demuxer_filter", EventType::EVENT_BUFFER_PROGRESS, event.param});
3028             break;
3029         }
3030         default:
3031             break;
3032     }
3033     OnSeekReadyEvent(event);
3034 }
3035 
OnSeekReadyEvent(const Plugins::PluginEvent & event)3036 void MediaDemuxer::OnSeekReadyEvent(const Plugins::PluginEvent &event)
3037 {
3038     switch (event.type) {
3039         case PluginEventType::DASH_SEEK_READY: {
3040             MEDIA_LOG_D("OnEvent dash seek ready");
3041             OnDashSeekReadyEvent(event);
3042             break;
3043         }
3044         case PluginEventType::HLS_SEEK_READY: {
3045             MEDIA_LOG_D("OnEvent hls seek ready");
3046             OnHlsSeekReadyEvent(event);
3047             break;
3048         }
3049         default:
3050             break;
3051     }
3052 }
3053 
OnDashSeekReadyEvent(const Plugins::PluginEvent & event)3054 void MediaDemuxer::OnDashSeekReadyEvent(const Plugins::PluginEvent &event)
3055 {
3056     MEDIA_LOG_D("Onevent dash seek ready");
3057     std::unique_lock<std::mutex> lock(rebootPluginMutex_);
3058     FALSE_RETURN(Any::IsSameTypeWith<Format>(event.param));
3059     Format param = AnyCast<Format>(event.param);
3060     int32_t currentStreamType = -1;
3061     param.GetIntValue("currentStreamType", currentStreamType);
3062     int32_t isEOS = -1;
3063     param.GetIntValue("isEOS", isEOS);
3064     int32_t currentStreamId = -1;
3065     param.GetIntValue("currentStreamId", currentStreamId);
3066     int64_t seekTimeMs = -1;
3067     param.GetLongValue("seekTime", seekTimeMs);
3068 
3069     bool isValidVideoSeek = seekTimeMs >= 0 && HasVideo();
3070     if (isValidVideoSeek) {
3071         Plugins::Ms2Us(seekTimeMs, videoSeekTime_);
3072         bool isValidVideoSeekTime = videoStartTime_ <= 0 || INT64_MAX - videoStartTime_ >= videoSeekTime_;
3073         if (isValidVideoSeekTime) {
3074             videoSeekTime_ += videoStartTime_;
3075             isInSeekDropAudio_ = true;
3076         }
3077     }
3078 
3079     MEDIA_LOG_D("HandleDashSeekReady, streamType: " PUBLIC_LOG_D32 " streamId: " PUBLIC_LOG_D32 " isEos: "
3080         PUBLIC_LOG_D32 " seekTimeMs: " PUBLIC_LOG_D64, currentStreamType, currentStreamId, isEOS, seekTimeMs);
3081     switch (currentStreamType) {
3082         case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_VID):
3083             seekReadyStreamInfo_[static_cast<int32_t>(StreamType::VIDEO)] = std::make_pair(currentStreamId, isEOS);
3084             break;
3085         case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_AUD):
3086             seekReadyStreamInfo_[static_cast<int32_t>(StreamType::AUDIO)] = std::make_pair(currentStreamId, isEOS);
3087             break;
3088         case static_cast<int32_t>(MediaAVCodec::MediaType::MEDIA_TYPE_SUBTITLE):
3089             seekReadyStreamInfo_[static_cast<int32_t>(StreamType::SUBTITLE)] = std::make_pair(currentStreamId, isEOS);
3090             break;
3091         default:
3092             break;
3093     }
3094     rebootPluginCondition_.notify_all();
3095 }
3096 
OnHlsSeekReadyEvent(const Plugins::PluginEvent & event)3097 void MediaDemuxer::OnHlsSeekReadyEvent(const Plugins::PluginEvent &event)
3098 {
3099     MEDIA_LOG_D("Onevent hls seek ready");
3100     std::unique_lock<std::mutex> lock(rebootPluginMutex_);
3101     FALSE_RETURN(Any::IsSameTypeWith<Format>(event.param));
3102     Format param = AnyCast<Format>(event.param);
3103     int32_t currentStreamType = -1;
3104     param.GetIntValue("currentStreamType", currentStreamType);
3105     int32_t isEOS = -1;
3106     param.GetIntValue("isEOS", isEOS);
3107     int32_t currentStreamId = -1;
3108     param.GetIntValue("currentStreamId", currentStreamId);
3109     MEDIA_LOG_D("HandleHlsSeekReady, streamType: " PUBLIC_LOG_D32 " streamId: " PUBLIC_LOG_D32
3110         " isEos: " PUBLIC_LOG_D32, currentStreamType, currentStreamId, isEOS);
3111     seekReadyStreamInfo_[static_cast<int32_t>(StreamType::MIXED)] = std::make_pair(currentStreamId, isEOS);
3112     rebootPluginCondition_.notify_all();
3113 }
3114 
OnDfxEvent(const Plugins::PluginDfxEvent & event)3115 void MediaDemuxer::OnDfxEvent(const Plugins::PluginDfxEvent &event)
3116 {
3117     FALSE_RETURN_MSG(eventReceiver_ != nullptr, "Dfx event report error, receiver is nullptr");
3118     auto it = DFX_EVENT_MAP.find(event.type);
3119     FALSE_RETURN_MSG(it != DFX_EVENT_MAP.end(), "No mapped dfx event type, src type %{public}d", event.type);
3120     eventReceiver_->OnDfxEvent({ it->second.first, it->second.second, event.param });
3121 }
3122 
OptimizeDecodeSlow(bool isDecodeOptimizationEnabled)3123 Status MediaDemuxer::OptimizeDecodeSlow(bool isDecodeOptimizationEnabled)
3124 {
3125     MEDIA_LOG_I("In");
3126     isDecodeOptimizationEnabled_ = isDecodeOptimizationEnabled;
3127     return Status::OK;
3128 }
3129 
SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit,int32_t trackId)3130 Status MediaDemuxer::SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit,
3131     int32_t trackId)
3132 {
3133     MEDIA_LOG_I("DecoderFramerateUpperLimit=" PUBLIC_LOG_D32 " trackId=" PUBLIC_LOG_D32,
3134         decoderFramerateUpperLimit, trackId);
3135     FALSE_RETURN_V(trackId == videoTrackId_, Status::OK);
3136     FALSE_RETURN_V_MSG_E(decoderFramerateUpperLimit > 0, Status::ERROR_INVALID_PARAMETER,
3137         "SetDecoderFramerateUpperLimit failed, decoderFramerateUpperLimit <= 0");
3138     decoderFramerateUpperLimit_.store(decoderFramerateUpperLimit);
3139     return Status::OK;
3140 }
3141 
SetSpeed(float speed)3142 Status MediaDemuxer::SetSpeed(float speed)
3143 {
3144     MEDIA_LOG_I("Speed=" PUBLIC_LOG_F, speed);
3145     FALSE_RETURN_V_MSG_E(speed > 0, Status::ERROR_INVALID_PARAMETER, "Speed <= 0");
3146     speed_.store(speed);
3147     return Status::OK;
3148 }
3149 
SetFrameRate(double framerate,int32_t trackId)3150 Status MediaDemuxer::SetFrameRate(double framerate, int32_t trackId)
3151 {
3152     MEDIA_LOG_I("Framerate=" PUBLIC_LOG_F " trackId=" PUBLIC_LOG_D32, framerate, trackId);
3153     FALSE_RETURN_V(trackId == videoTrackId_, Status::OK);
3154     FALSE_RETURN_V_MSG_E(framerate > 0, Status::ERROR_INVALID_PARAMETER, "Framerate <= 0");
3155     framerate_.store(framerate);
3156     return Status::OK;
3157 }
3158 
CheckDropAudioFrame(std::shared_ptr<AVBuffer> sample,int32_t trackId)3159 bool MediaDemuxer::CheckDropAudioFrame(std::shared_ptr<AVBuffer> sample, int32_t trackId)
3160 {
3161     if (trackId == audioTrackId_) {
3162         if (isInSeekDropAudio_) {
3163             if (sample->pts_ < videoSeekTime_) {
3164                 MEDIA_LOG_I("isInSeekDropAudio_ Drop audio buffer pts " PUBLIC_LOG_D64, sample->pts_);
3165                 return true;
3166             } else {
3167                 isInSeekDropAudio_ = false;
3168             }
3169         }
3170         if (shouldCheckAudioFramePts_ == false) {
3171             lastAudioPts_ = sample->pts_;
3172             MEDIA_LOG_I("Set last audio pts " PUBLIC_LOG_D64, lastAudioPts_);
3173             return false;
3174         }
3175         if (sample->pts_ <= lastAudioPts_) {
3176             MEDIA_LOG_I("Drop audio buffer pts " PUBLIC_LOG_D64, sample->pts_);
3177             return true;
3178         }
3179         if (shouldCheckAudioFramePts_) {
3180             shouldCheckAudioFramePts_ = false;
3181             lastAudioPts_ = sample->pts_;
3182         }
3183     }
3184     if (trackId == subtitleTrackId_) {
3185         if (shouldCheckSubtitleFramePts_ == false) {
3186             lastSubtitlePts_ = sample->pts_;
3187             MEDIA_LOG_I("Set last subtitle pts " PUBLIC_LOG_D64, lastSubtitlePts_);
3188             return false;
3189         }
3190         if (sample->pts_ <= lastSubtitlePts_) {
3191             MEDIA_LOG_I("Drop subtitle buffer pts " PUBLIC_LOG_D64, sample->pts_);
3192             return true;
3193         }
3194         if (shouldCheckSubtitleFramePts_) {
3195             shouldCheckSubtitleFramePts_ = false;
3196             lastSubtitlePts_ = sample->pts_;
3197         }
3198     }
3199     return false;
3200 }
3201 
IsBufferDroppable(std::shared_ptr<AVBuffer> sample,int32_t trackId)3202 bool MediaDemuxer::IsBufferDroppable(std::shared_ptr<AVBuffer> sample, int32_t trackId)
3203 {
3204     FALSE_GOON_NOEXEC(isDump_, DumpBufferToFile(trackId, sample));
3205 
3206     if (demuxerPluginManager_->IsDash() && (trackId == audioTrackId_ || trackId == subtitleTrackId_)) {
3207         return CheckDropAudioFrame(sample, trackId);
3208     }
3209 
3210     if (trackId != videoTrackId_) {
3211         return false;
3212     }
3213 
3214     FALSE_RETURN_V_NOLOG(!IsOpenGopBufferDroppable(sample, trackId), true);
3215 
3216     if (!isDecodeOptimizationEnabled_.load()) {
3217         return false;
3218     }
3219 
3220     double targetRate = framerate_.load() * speed_.load();
3221     double actualRate = decoderFramerateUpperLimit_.load() * (1 + DECODE_RATE_THRESHOLD);
3222     if (targetRate <= actualRate) {
3223         return false;
3224     }
3225 
3226     bool canDrop = false;
3227     bool ret = sample->meta_->GetData(Media::Tag::VIDEO_BUFFER_CAN_DROP, canDrop);
3228     if (!ret || !canDrop) {
3229         return false;
3230     }
3231 
3232     MEDIA_LOG_DD("Drop buffer, framerate=" PUBLIC_LOG_F " speed=" PUBLIC_LOG_F " decodeUpLimit="
3233         PUBLIC_LOG_D32 " pts=" PUBLIC_LOG_D64, framerate_.load(), speed_.load(),
3234         decoderFramerateUpperLimit_.load(), sample->pts_);
3235     return true;
3236 }
3237 
DisableMediaTrack(Plugins::MediaType mediaType)3238 Status MediaDemuxer::DisableMediaTrack(Plugins::MediaType mediaType)
3239 {
3240     disabledMediaTracks_.emplace(mediaType);
3241     return Status::OK;
3242 }
3243 
IsTrackDisabled(Plugins::MediaType mediaType)3244 bool MediaDemuxer::IsTrackDisabled(Plugins::MediaType mediaType)
3245 {
3246     return !disabledMediaTracks_.empty() && disabledMediaTracks_.find(mediaType) != disabledMediaTracks_.end();
3247 }
3248 
CheckTrackEnabledById(int32_t trackId)3249 bool MediaDemuxer::CheckTrackEnabledById(int32_t trackId)
3250 {
3251     bool hasTrack = IsValidTrackId(trackId);
3252     if (!hasTrack) {
3253         return false;
3254     }
3255     bool hasTask = taskMap_.find(trackId) != taskMap_.end() && taskMap_[trackId] != nullptr;
3256     bool hasSampleQueueTask = sampleConsumerTaskMap_.find(trackId) != sampleConsumerTaskMap_.end() &&
3257                             sampleConsumerTaskMap_[trackId] != nullptr;
3258     if (!hasTask || (GetEnableSampleQueueFlag() && !hasSampleQueueTask)) {
3259         return false;
3260     }
3261 
3262     bool hasBufferQueue = bufferQueueMap_.find(trackId) != bufferQueueMap_.end()
3263         && bufferQueueMap_[trackId] != nullptr;
3264     bool hasSampleQueue = sampleQueueMap_.find(trackId) != sampleQueueMap_.end()
3265         && sampleQueueMap_[trackId] != nullptr;
3266     if (!hasBufferQueue || (GetEnableSampleQueueFlag() && !hasSampleQueue)) {
3267         MEDIA_LOG_I(" not hasBufferQueue or hasSampleQueueTask: TrackId=" PUBLIC_LOG_D32, trackId);
3268         return false;
3269     }
3270     return true;
3271 }
3272 
SetSelectBitRateFlag(bool flag,uint32_t desBitRate)3273 void MediaDemuxer::SetSelectBitRateFlag(bool flag, uint32_t desBitRate)
3274 {
3275     MEDIA_LOG_I("Flag=" PUBLIC_LOG_D32 " desBitRate=" PUBLIC_LOG_U32,
3276         static_cast<int32_t>(flag), desBitRate);
3277     isSelectBitRate_.store(flag);
3278     if (flag) {
3279         targetBitRate_ = desBitRate;
3280     }
3281 }
3282 
CanAutoSelectBitRate()3283 bool MediaDemuxer::CanAutoSelectBitRate()
3284 {
3285     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "Plugin manager is nullptr");
3286     // calculating auto selectbitrate time
3287     return !(isSelectBitRate_.load()) && !(isSelectTrack_.load())
3288         && (targetBitRate_ == demuxerPluginManager_->GetCurrentBitRate());
3289 }
3290 
IsRenderNextVideoFrameSupported()3291 bool MediaDemuxer::IsRenderNextVideoFrameSupported()
3292 {
3293     bool isDataSrcLiveStream = source_ != nullptr && source_->IsNeedPreDownload() &&
3294         source_->GetSeekable() == Plugins::Seekable::UNSEEKABLE;
3295     return IsValidTrackId(videoTrackId_) && !IsTrackDisabled(Plugins::MediaType::VIDEO) &&
3296         !isDataSrcLiveStream && !isFlvLiveStream_;
3297 }
3298 
GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,const uint64_t relativePresentationTimeUs,uint32_t & index)3299 Status MediaDemuxer::GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,
3300     const uint64_t relativePresentationTimeUs, uint32_t &index)
3301 {
3302     MEDIA_LOG_D("In");
3303     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
3304     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
3305     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
3306 
3307     Status ret = pluginTemp->GetIndexByRelativePresentationTimeUs(trackIndex, relativePresentationTimeUs, index);
3308     if (ret != Status::OK) {
3309         MEDIA_LOG_E("Get index failed");
3310     }
3311     return ret;
3312 }
3313 
GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,const uint32_t index,uint64_t & relativePresentationTimeUs)3314 Status MediaDemuxer::GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,
3315     const uint32_t index, uint64_t &relativePresentationTimeUs)
3316 {
3317     MEDIA_LOG_D("In");
3318     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
3319     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = GetCurFFmpegPlugin();
3320     FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_NULL_POINTER, "Demuxer plugin is nullptr");
3321 
3322     Status ret = pluginTemp->GetRelativePresentationTimeUsByIndex(trackIndex, index, relativePresentationTimeUs);
3323     if (ret != Status::OK) {
3324         MEDIA_LOG_E("Get pts failed");
3325     }
3326     return ret;
3327 }
3328 
ResumeDemuxerReadLoop()3329 Status MediaDemuxer::ResumeDemuxerReadLoop()
3330 {
3331     MEDIA_LOG_I("In");
3332     if (isDemuxerLoopExecuting_) {
3333         MEDIA_LOG_I("Has already resumed");
3334         return Status::OK;
3335     }
3336     isDemuxerLoopExecuting_ = true;
3337     return ResumeAllTask();
3338 }
3339 
PauseDemuxerReadLoop()3340 Status MediaDemuxer::PauseDemuxerReadLoop()
3341 {
3342     MEDIA_LOG_I("In");
3343     if (!isDemuxerLoopExecuting_) {
3344         MEDIA_LOG_I("Has already paused");
3345         return Status::OK;
3346     }
3347     isDemuxerLoopExecuting_ = false;
3348     PauseAllTaskAsync();
3349     if (!GetEnableSampleQueueFlag()) {
3350         PauseAllTask();
3351     }
3352     if (demuxerPluginManager_) {
3353         demuxerPluginManager_->Pause();
3354     }
3355     return Status::OK;
3356 }
3357 
SetTranscoderMode()3358 Status MediaDemuxer::SetTranscoderMode()
3359 {
3360     isTranscoderMode_ = true;
3361     return Status::OK;
3362 }
3363 
SetSkippingAudioDecAndEnc()3364 Status MediaDemuxer::SetSkippingAudioDecAndEnc()
3365 {
3366     isSkippingAudioDecAndEnc_ = true;
3367     return Status::OK;
3368 }
3369 
SetCacheLimit(uint32_t limitSize)3370 void MediaDemuxer::SetCacheLimit(uint32_t limitSize)
3371 {
3372     MEDIA_LOG_D("In");
3373     FALSE_RETURN_MSG(demuxerPluginManager_ != nullptr, "Plugin manager is nullptr");
3374     int32_t tempTrackId = (IsValidTrackId(videoTrackId_) ? videoTrackId_ : audioTrackId_);
3375     int32_t streamID = demuxerPluginManager_->GetTmpStreamIDByTrackID(tempTrackId);
3376     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamID);
3377     FALSE_RETURN_MSG(pluginTemp != nullptr, "Demuxer plugin is nullptr");
3378 
3379     pluginTemp->SetCacheLimit(limitSize);
3380 }
3381 
IsVideoEos()3382 bool MediaDemuxer::IsVideoEos()
3383 {
3384     if (!IsValidTrackId(videoTrackId_)) {
3385         return true;
3386     }
3387     return eosMap_[videoTrackId_];
3388 }
3389 
HasEosTrack()3390 bool MediaDemuxer::HasEosTrack()
3391 {
3392     for (auto it = eosMap_.begin(); it != eosMap_.end(); it++) {
3393         if (it->second) {
3394             return true;
3395         }
3396     }
3397     return false;
3398 }
3399 
SetEnableOnlineFdCache(bool isEnableFdCache)3400 void MediaDemuxer::SetEnableOnlineFdCache(bool isEnableFdCache)
3401 {
3402     FALSE_RETURN(source_ != nullptr);
3403     source_->SetEnableOnlineFdCache(isEnableFdCache);
3404 }
3405 
WaitForBufferingEnd()3406 void MediaDemuxer::WaitForBufferingEnd()
3407 {
3408     FALSE_RETURN_MSG(source_ != nullptr, "Source is nullptr");
3409     source_->WaitForBufferingEnd();
3410 }
3411 
GetCurrentVideoTrackId()3412 int32_t MediaDemuxer::GetCurrentVideoTrackId()
3413 {
3414     return videoTrackId_;
3415 }
3416 
SetIsEnableReselectVideoTrack(bool isEnable)3417 void MediaDemuxer::SetIsEnableReselectVideoTrack(bool isEnable)
3418 {
3419     isEnableReselectVideoTrack_  = isEnable;
3420 }
3421 
IsOpenGopBufferDroppable(std::shared_ptr<AVBuffer> sample,int32_t trackId)3422 bool MediaDemuxer::IsOpenGopBufferDroppable(std::shared_ptr<AVBuffer> sample, int32_t trackId)
3423 {
3424     FALSE_RETURN_V_NOLOG(trackId == videoTrackId_ && sample != nullptr, false);
3425     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
3426     if ((sample->flag_ & static_cast<uint32_t>(AVBufferFlag::SYNC_FRAME)) > 0) {
3427         syncFrameInfo_.pts = sample->pts_;
3428         if (syncFrameInfo_.skipOpenGopUnrefFrameCnt > 0) {
3429             syncFrameInfo_.skipOpenGopUnrefFrameCnt--;
3430         }
3431         return false;
3432     }
3433     if (syncFrameInfo_.skipOpenGopUnrefFrameCnt <= 0 || sample->pts_ >= syncFrameInfo_.pts) {
3434         return false;
3435     }
3436     MEDIA_LOG_DD("drop opengop-buffer after dragging, pts: " PUBLIC_LOG_D64 ", i frame pts: "
3437         PUBLIC_LOG_D64, sample->pts_, syncFrameInfo_.pts);
3438     return true;
3439 }
3440 
UpdateSyncFrameInfo(std::shared_ptr<AVBuffer> sample,int32_t trackId,bool isDiscardable)3441 void MediaDemuxer::UpdateSyncFrameInfo(std::shared_ptr<AVBuffer> sample, int32_t trackId, bool isDiscardable)
3442 {
3443     FALSE_RETURN_NOLOG(trackId == videoTrackId_ && sample != nullptr && !isDiscardable);
3444     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
3445     if ((sample->flag_ & static_cast<uint32_t>(AVBufferFlag::SYNC_FRAME)) > 0) {
3446         syncFrameInfo_.pts = sample->pts_;
3447     }
3448 }
3449 
EnterDraggingOpenGopCnt()3450 void MediaDemuxer::EnterDraggingOpenGopCnt()
3451 {
3452     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
3453     syncFrameInfo_.skipOpenGopUnrefFrameCnt = SKIP_NEXT_OPEN_GOP_CNT;
3454 }
3455 
ResetDraggingOpenGopCnt()3456 void MediaDemuxer::ResetDraggingOpenGopCnt()
3457 {
3458     std::lock_guard<std::mutex> lock(syncFrameInfoMutex_);
3459     syncFrameInfo_.skipOpenGopUnrefFrameCnt = 0;
3460 }
3461 
SetApiVersion(int32_t apiVersion)3462 void MediaDemuxer::SetApiVersion(int32_t apiVersion)
3463 {
3464     apiVersion_ = apiVersion;
3465     demuxerPluginManager_->SetApiVersion(apiVersion);
3466 }
3467 
IsLocalFd()3468 bool MediaDemuxer::IsLocalFd()
3469 {
3470     FALSE_RETURN_V_MSG_E(source_ != nullptr, false, "source_ is nullptr");
3471     return source_->IsLocalFd();
3472 }
3473 
RebootPlugin()3474 Status MediaDemuxer::RebootPlugin()
3475 {
3476     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::RebootPlugin");
3477     FALSE_RETURN_V(source_ != nullptr && demuxerPluginManager_ != nullptr && streamDemuxer_ != nullptr,
3478         Status::ERROR_NULL_POINTER);
3479     RestartAndClearBuffer();
3480     Status ret = Status::OK;
3481     int32_t videoStreamID = streamDemuxer_->GetNewVideoStreamID();
3482     demuxerPluginManager_->StopPlugin(videoStreamID, streamDemuxer_);
3483     ret = demuxerPluginManager_->StartPlugin(videoStreamID, streamDemuxer_);
3484     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Start plugin failed" PUBLIC_LOG_D32, videoStreamID);
3485     ret = InnerSelectTrack(static_cast<int32_t>(videoTrackId_));
3486     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "inner select video track failed");
3487     ret = InnerSelectTrack(static_cast<int32_t>(audioTrackId_));
3488     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "inner select audio track failed");
3489     return Status::OK;
3490 }
3491 
AddSampleBufferQueue(int32_t trackId)3492 Status MediaDemuxer::AddSampleBufferQueue(int32_t trackId)
3493 {
3494     std::shared_ptr<SampleQueue> sampleQueue = std::make_shared<SampleQueue>();
3495     FALSE_RETURN_V_MSG_E(sampleQueue != nullptr, Status::ERROR_NO_MEMORY, "SampleQueue create failed");
3496     bool isVideo = IsRightMediaTrack(trackId, DemuxerTrackType::VIDEO);
3497     SampleQueue::Config sampleQueueConfig{};
3498     sampleQueueConfig.isFlvLiveStream_ = isFlvLiveStream_;
3499     sampleQueueConfig.isSupportBitrateSwitch_ = sampleQueueConfig.isFlvLiveStream_ && isVideo;
3500     sampleQueueConfig.queueId_ = trackId;
3501     sampleQueueConfig.bufferCap_ =
3502         isVideo ? SampleQueue::DEFAULT_VIDEO_SAMPLE_BUFFER_CAP : SampleQueue::DEFAULT_SAMPLE_BUFFER_CAP;
3503     Status status = sampleQueue->Init(sampleQueueConfig);
3504     FALSE_RETURN_V_MSG_E(status == Status::OK, status, "SampleQueue Init failed");
3505     sampleQueue->SetSampleQueueCallback(shared_from_this());
3506 
3507     sampleQueueMap_.insert(std::pair<int32_t, std::shared_ptr<SampleQueue>>(trackId, sampleQueue));
3508     MEDIA_LOG_I("AddSampleBufferQueue successfully trackId " PUBLIC_LOG_D32, trackId);
3509     return Status::OK;
3510 }
3511 
SampleConsumerLoop(int32_t trackId)3512 int64_t MediaDemuxer::SampleConsumerLoop(int32_t trackId)
3513 {
3514     MEDIA_LOG_DD("In, SampleConsumerLoop trackId: " PUBLIC_LOG_D32, trackId);
3515     FALSE_RETURN_V_MSG_E(bufferQueueMap_.count(trackId) > 0 && bufferQueueMap_[trackId] != nullptr, RETRY_DELAY_TIME_US,
3516         "BufferQueue " PUBLIC_LOG_D32 " is nullptr", trackId);
3517 
3518     FALSE_RETURN_V_MSG_E(sampleQueueMap_.count(trackId) > 0 && sampleQueueMap_[trackId] != nullptr,
3519         RETRY_DELAY_TIME_US, "SampleQueueMap " PUBLIC_LOG_D32 " is nullptr", trackId);
3520 
3521     auto& sampleQueue = sampleQueueMap_[trackId];
3522     auto& bufferQueue = bufferQueueMap_[trackId];
3523     Status status = Status::OK;
3524 
3525     do {
3526         size_t size = 0;
3527         status = sampleQueue->QuerySizeForNextAcquireBuffer(size);
3528         CHECK_AND_BREAK_LOG_LIMIT_POW2(status == Status::OK, SAMPLE_LOOP_ACQUIRE_FAILED_LOG_POW2,
3529             "QuerySizeForNextAcquireBuffer failed " PUBLIC_LOG_D32, trackId);
3530         UpdateSampleQueueCache();
3531 
3532         SetTrackNotifySampleConsumerFlag(trackId, true);
3533         AVBufferConfig avBufferConfig;
3534         std::shared_ptr<AVBuffer> dstBuffer;
3535         avBufferConfig.capacity = static_cast<int32_t>(size);
3536         avBufferConfig.size = static_cast<int32_t>(size);
3537         status = bufferQueue->RequestBuffer(dstBuffer, avBufferConfig, REQUEST_BUFFER_TIMEOUT);
3538         CHECK_AND_BREAK_LOG_LIMIT_POW2(status == Status::OK, SAMPLE_LOOP_REQUEST_FAILED_LOG_POW2,
3539             "RequestBuffer from bufferQueue failed " PUBLIC_LOG_D32, trackId);
3540         SetTrackNotifySampleConsumerFlag(trackId, false);
3541 
3542         status = sampleQueue->AcquireCopyToDstBuffer(dstBuffer);
3543         status = HandlePushBuffer(trackId, dstBuffer, bufferQueue, status);
3544         CHECK_AND_BREAK_LOG(status == Status::OK, "PushBuffer to bufferQueue failed " PUBLIC_LOG_D32, trackId);
3545     } while (0);
3546     uint32_t retryTime = hasSetLargeSize_ && !isVideoMuted_ && trackId == videoTrackId_ ?
3547                                 NEXT_DELAY_TIME_US : SAMPLE_LOOP_RETRY_TIME_US;
3548     return status == Status::OK ? retryTime : SAMPLE_LOOP_DELAY_TIME_US;
3549 }
3550 
HandlePushBuffer(int32_t trackId,std::shared_ptr<AVBuffer> & dstBuffer,sptr<AVBufferQueueProducer> & bufferQueue,Status status)3551 Status MediaDemuxer::HandlePushBuffer(int32_t trackId, std::shared_ptr<AVBuffer>& dstBuffer,
3552                                       sptr<AVBufferQueueProducer>& bufferQueue, Status status)
3553 {
3554     if (trackId == videoTrackId_ && needReleaseVideoDecoder_) {
3555         Status ret = bufferQueue->PushBuffer(dstBuffer, status == Status::OK);
3556         int64_t duration = 0;
3557         mediaMetaData_.globalMeta->Get<Tag::MEDIA_DURATION>(duration);
3558         int64_t mediaTime = (duration > 0 && syncCenter_ != nullptr) ?
3559             syncCenter_->GetMediaTimeNow() : lastAudioPtsInMute_;
3560         if (dstBuffer->pts_ > mediaTime) {
3561             return Status::ERROR_UNKNOWN;
3562         }
3563         return ret;
3564     }
3565     if (!(needRestore_ && trackId == videoTrackId_ && !isVideoMuted_)) {
3566         return bufferQueue->PushBuffer(dstBuffer, status == Status::OK);
3567     }
3568 
3569     if (!(dstBuffer->flag_ & static_cast<uint32_t>(Plugins::AVBufferFlag::SYNC_FRAME))) {
3570         MEDIA_LOG_I("MediaDemuxer::SampleConsumerLoop throw away buffer trackId: " PUBLIC_LOG_U32 " pts: "
3571             PUBLIC_LOG_U64 " flag is: " PUBLIC_LOG_U32, trackId, (uint64_t)dstBuffer->pts_,
3572             dstBuffer->flag_);
3573         return bufferQueue->PushBuffer(dstBuffer, false);
3574     }
3575 
3576     std::vector<uint8_t> config;
3577     mediaMetaData_.trackMetas[videoTrackId_]->GetData(Tag::MEDIA_CODEC_CONFIG, config);
3578     if (config.size() > 0) {
3579         int32_t size = dstBuffer->memory_->GetSize();
3580         std::vector<uint8_t> memory;
3581         memory.resize(static_cast<size_t>(size) + config.size());
3582         dstBuffer->memory_->Read(memory.data(), size, 0);
3583         bool hasXps = false;
3584         if (size >= static_cast<int32_t>(config.size())) {
3585             hasXps = memcmp(config.data(), memory.data(), config.size()) == 0;
3586         } else {
3587             hasXps = false;
3588         }
3589         if (!hasXps) {
3590             memory.insert(memory.begin(), config.begin(), config.end());
3591             dstBuffer->memory_->Write(memory.data(), memory.size(), 0);
3592             MEDIA_LOG_I("MediaDemuxer::HandlePushBuffer write xps to buffer");
3593         }
3594     }
3595     needRestore_ = false;
3596     return bufferQueue->PushBuffer(dstBuffer, status == Status::OK);
3597 }
3598 
SetSyncCenter(std::shared_ptr<MediaSyncManager> syncCenter)3599 void MediaDemuxer::SetSyncCenter(std::shared_ptr<MediaSyncManager> syncCenter)
3600 {
3601     syncCenter_ = syncCenter;
3602 }
3603 
IsRightMediaTrack(int32_t trackId,DemuxerTrackType type) const3604 bool MediaDemuxer::IsRightMediaTrack(int32_t trackId, DemuxerTrackType type) const
3605 {
3606     FALSE_RETURN_V(IsValidTrackId(trackId), false);
3607     switch (type) {
3608         case DemuxerTrackType::VIDEO:
3609             return trackId == videoTrackId_;
3610         case DemuxerTrackType::AUDIO:
3611             return trackId == audioTrackId_;
3612         case DemuxerTrackType::SUBTITLE:
3613             return trackId == subtitleTrackId_;
3614         default:
3615             return false;
3616     }
3617 }
3618 
GetLastVideoBufferAbsPts(int32_t trackId) const3619 int64_t MediaDemuxer::GetLastVideoBufferAbsPts(int32_t trackId) const
3620 {
3621     if (syncCenter_ == nullptr) {
3622         return HST_TIME_NONE;
3623     }
3624     FALSE_RETURN_V_MSG_E(syncCenter_ != nullptr, HST_TIME_NONE, "syncCenter_ is nullptr");
3625     return syncCenter_->GetLastVideoBufferAbsPts();
3626 }
3627 
UpdateLastVideoBufferAbsPts(int32_t trackId)3628 void MediaDemuxer::UpdateLastVideoBufferAbsPts(int32_t trackId)
3629 {
3630     if (!isFlvLiveStream_ || !IsRightMediaTrack(trackId, DemuxerTrackType::VIDEO)) {
3631         return;
3632     }
3633     int64_t lastVideoBufferAbsPts = GetLastVideoBufferAbsPts(trackId);
3634     if (lastVideoBufferAbsPts == HST_TIME_NONE) {
3635         return;
3636     }
3637     AutoLock lock(mapMutex_);
3638     auto sqIt = sampleQueueMap_.find(trackId);
3639     if (sqIt != sampleQueueMap_.end() && sqIt->second != nullptr) {
3640         sqIt->second->UpdateLastEndSamplePts(lastVideoBufferAbsPts);
3641     }
3642 }
3643 
SelectBitrateForNonSQ(int64_t startPts,uint32_t bitRate)3644 Status MediaDemuxer::SelectBitrateForNonSQ(int64_t startPts, uint32_t bitRate)
3645 {
3646     MEDIA_LOG_I("SelectBitrateForNonSQ startPts=" PUBLIC_LOG_D64 " bitRate=" PUBLIC_LOG_U32, startPts, bitRate);
3647     FALSE_RETURN_V_MSG_E(handleFlvSelectBitrateTask_ != nullptr, Status::ERROR_NULL_POINTER,
3648         "handleFlvSelectBitrateTask_ is nullptr");
3649     FALSE_RETURN_V_MSG_I(!isFlvLiveSelectingBitRate_.load(), Status::OK,
3650         "isFlvLiveSelectingBitRate, ignore this request");
3651     isFlvLiveSelectingBitRate_.store(true);
3652     PauseAllTask();
3653     handleFlvSelectBitrateTask_->SubmitJobOnce([this, startPts, bitRate] {
3654         HandleSelectBitrateForFlvLive(startPts, bitRate);
3655         isFlvLiveSelectingBitRate_.store(false);
3656     });
3657     ResumeAllTask();
3658     return Status::OK;
3659 }
3660 
3661 // now only for the flv living streaming case, callback by SampleQueue
OnSelectBitrateOk(int64_t startPts,uint32_t bitRate)3662 Status MediaDemuxer::OnSelectBitrateOk(int64_t startPts, uint32_t bitRate)
3663 {
3664     MEDIA_LOG_I("OnSelectBitrateOk startPts=" PUBLIC_LOG_D64 " bitRate=" PUBLIC_LOG_U32, startPts, bitRate);
3665     FALSE_RETURN_V_MSG_E(handleFlvSelectBitrateTask_ != nullptr, Status::ERROR_NULL_POINTER,
3666         "handleFlvSelectBitrateTask_ is nullptr");
3667     handleFlvSelectBitrateTask_->SubmitJobOnce([this, startPts, bitRate] {
3668         HandleSelectBitrateForFlvLive(startPts, bitRate);
3669     });
3670     return Status::OK;
3671 }
3672 
OnSampleQueueBufferAvailable(int32_t queueId)3673 Status MediaDemuxer::OnSampleQueueBufferAvailable(int32_t queueId)
3674 {
3675     MEDIA_LOG_DD("OnSampleQueueBufferAvailable queueId=" PUBLIC_LOG_D32, queueId);
3676     FALSE_RETURN_V_MSG_E(notifySampleProduceTask_ != nullptr, Status::ERROR_NULL_POINTER,
3677         "notifySampleProduceTask_ is nullptr");
3678     notifySampleProduceTask_->SubmitJobOnce([demuxerWptr = weak_from_this(), queueId] {
3679         std::shared_ptr<MediaDemuxer> demuxer = demuxerWptr.lock();
3680         if (demuxer != nullptr) {
3681             demuxer->AccelerateTrackTask(queueId);
3682         }
3683     });
3684     return Status::OK;
3685 }
3686 
OnSampleQueueBufferConsume(int32_t queueId)3687 Status MediaDemuxer::OnSampleQueueBufferConsume(int32_t queueId)
3688 {
3689     FALSE_RETURN_V_MSG_E(notifySampleConsumeTask_ != nullptr, Status::ERROR_NULL_POINTER,
3690         "notifySampleConsumeTask_ is nullptr");
3691     notifySampleConsumeTask_->SubmitJobOnce([demuxerWptr = weak_from_this(), queueId] {
3692         std::shared_ptr<MediaDemuxer> demuxer = demuxerWptr.lock();
3693         if (demuxer != nullptr) {
3694             demuxer->NotifySampleQueueBufferConsume(queueId);
3695         }
3696     });
3697     return Status::OK;
3698 }
3699 
NotifySampleQueueBufferConsume(int32_t queueId)3700 Status MediaDemuxer::NotifySampleQueueBufferConsume(int32_t queueId)
3701 {
3702     MEDIA_LOG_DD("NotifySampleQueueBufferConsume queueId=" PUBLIC_LOG_D32, queueId);
3703     int32_t trackId = queueId;
3704     {
3705         std::unique_lock<std::mutex> stopLock(stopMutex_);
3706         if (isStopped_ || isThreadExit_) {
3707             return Status::OK;
3708         }
3709     }
3710     AutoLock lock(mapMutex_);
3711 
3712     auto track = trackMap_.find(trackId);
3713     if (track == trackMap_.end() || track->second == nullptr) {
3714         return Status::ERROR_INVALID_PARAMETER;
3715     }
3716     track->second->SetNotifySampleConsumerFlag(false);
3717 
3718     // accelerate SampleQueue toConsumer
3719     auto sampleConsumerTask = sampleConsumerTaskMap_.find(trackId);
3720     if (sampleConsumerTask == sampleConsumerTaskMap_.end()) {
3721         return Status::OK;
3722     }
3723     sampleConsumerTask->second->UpdateDelayTime();
3724 
3725     return Status::OK;
3726 }
3727 
HandleSelectBitrateForFlvLive(int64_t startPts,uint32_t bitrate)3728 Status MediaDemuxer::HandleSelectBitrateForFlvLive(int64_t startPts, uint32_t bitrate)
3729 {
3730     MediaAVCodec::AVCodecTrace trace("MediaDemuxer::HandleSelectBitrateForFlvLive");
3731     MEDIA_LOG_I("In bitrate=" PUBLIC_LOG_U32 " startPts=" PUBLIC_LOG_D64, bitrate, startPts);
3732     FALSE_RETURN_V(source_ != nullptr && demuxerPluginManager_ != nullptr && streamDemuxer_ != nullptr,
3733         Status::ERROR_NULL_POINTER);
3734 
3735     Status ret = Status::OK;
3736     source_->SetStartPts(startPts / US_TO_MS);
3737     if (isManualBitRateSetting_.load()) {
3738         source_->SelectBitRate(bitrate);
3739     } else {
3740         source_->AutoSelectBitRate(bitrate);
3741     }
3742     MEDIA_LOG_I("source SelectBitrate bitrate=" PUBLIC_LOG_U32 " startPts=" PUBLIC_LOG_D64, bitrate, startPts);
3743 
3744     if (GetEnableSampleQueueFlag()) {
3745         AutoLock lock(mapMutex_);
3746         for (auto &sqIt : sampleQueueMap_) {
3747             FALSE_RETURN_V_MSG_E(
3748                 sqIt.second != nullptr, Status::ERROR_INVALID_STATE, "invalid trackId" PUBLIC_LOG_D32, sqIt.first);
3749             ret = sqIt.second->ResponseForSwitchDone(startPts);
3750             FALSE_RETURN_V_MSG_E(
3751                 ret == Status::OK, ret, "ResponseForSwitchDone failed trackId" PUBLIC_LOG_D64, startPts);
3752         }
3753     }
3754 
3755     int32_t videoStreamID = streamDemuxer_->GetNewVideoStreamID();
3756     demuxerPluginManager_->StopPlugin(videoStreamID, streamDemuxer_);
3757     ret = demuxerPluginManager_->StartPlugin(videoStreamID, streamDemuxer_);
3758     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Start plugin failed" PUBLIC_LOG_D32, videoStreamID);
3759 
3760     // update track map in track id change case
3761     if (demuxerPluginManager_->GetTrackTypeByTrackID(audioTrackId_) == TRACK_VIDEO) {
3762         demuxerPluginManager_->UpdateTempTrackMapInfo(videoTrackId_, videoTrackId_, audioTrackId_);
3763     }
3764     if (demuxerPluginManager_->GetTrackTypeByTrackID(videoTrackId_) == TRACK_AUDIO) {
3765         demuxerPluginManager_->UpdateTempTrackMapInfo(audioTrackId_, audioTrackId_, videoTrackId_);
3766     }
3767 
3768     InnerSelectTrack(static_cast<int32_t>(videoTrackId_));
3769     InnerSelectTrack(static_cast<int32_t>(audioTrackId_));
3770     return ret;
3771 }
3772 
GetCachedDuration()3773 uint64_t MediaDemuxer::GetCachedDuration()
3774 {
3775     FALSE_RETURN_V_MSG_E(source_ != nullptr, 0, "source_ is nullptr");
3776     demuxerCacheDuration_ = GetEnableSampleQueueFlag() ? GetSampleQueueDuration() : 0;
3777     sourceCacheDuration_ = source_->GetCachedDuration();
3778     MEDIA_LOG_I("samplequeue cacheDuration=" PUBLIC_LOG_U64 ", sourceCache=" PUBLIC_LOG_U64, demuxerCacheDuration_,
3779         sourceCacheDuration_);
3780     return sourceCacheDuration_ + demuxerCacheDuration_;
3781 }
3782 
GetSampleQueueDuration()3783 uint64_t MediaDemuxer::GetSampleQueueDuration()
3784 {
3785     uint64_t sampleQueueDration = std::numeric_limits<uint64_t>::max();
3786     {
3787         AutoLock lock(mapMutex_);
3788         FALSE_RETURN_V_MSG_E(sampleQueueMap_.size() > 0, 0, "sampleQueueMap_ empty");
3789         for (auto sqIt = sampleQueueMap_.begin(); sqIt != sampleQueueMap_.end(); sqIt++) {
3790             FALSE_RETURN_V_MSG_E(sqIt->second != nullptr, 0, "sampleQueue empty");
3791             sampleQueueDration = std::min(sqIt->second->GetCacheDuration() / US_TO_MS, sampleQueueDration);
3792         }
3793     }
3794     return sampleQueueDration;
3795 }
3796 
UpdateSampleQueueCache()3797 void MediaDemuxer::UpdateSampleQueueCache()
3798 {
3799     FALSE_RETURN_NOLOG(isFlvLiveStream_);
3800     int64_t currentClockTimeMs = SteadyClock::GetCurrentTimeMs();
3801     if (lastClockTimeMs_ != 0 && currentClockTimeMs - lastClockTimeMs_ < UPDATE_SOURCE_CACHE_MS) {
3802         return;
3803     }
3804     lastClockTimeMs_ = currentClockTimeMs;
3805     demuxerCacheDuration_ = GetSampleQueueDuration();
3806     if (source_) {
3807         source_->SetExtraCache(demuxerCacheDuration_);
3808         MEDIA_LOG_I("samplequeue cacheDuration=" PUBLIC_LOG_U64 ", sourceCache=" PUBLIC_LOG_U64, demuxerCacheDuration_,
3809             source_->GetCachedDuration());
3810     }
3811 }
3812 
RestartAndClearBuffer()3813 void MediaDemuxer::RestartAndClearBuffer()
3814 {
3815     FALSE_RETURN_MSG(source_ != nullptr, "source_ is nullptr");
3816     return source_->RestartAndClearBuffer();
3817 }
3818 
IsFlvLive()3819 bool MediaDemuxer::IsFlvLive()
3820 {
3821     FALSE_RETURN_V_MSG_E(source_ != nullptr, false, "source_ is nullptr");
3822     return source_->IsFlvLive();
3823 }
3824 
IsIgonreBuffering()3825 bool MediaDemuxer::IsIgonreBuffering()
3826 {
3827     MEDIA_LOG_I("IsIgonreBuffering in");
3828     if (!IsRightMediaTrack(videoTrackId_, DemuxerTrackType::VIDEO)) {
3829         return false;
3830     }
3831     AutoLock lock(mapMutex_);
3832     auto sqIt = sampleQueueMap_.find(videoTrackId_);
3833     FALSE_RETURN_V_MSG_E(sqIt != sampleQueueMap_.end() && sqIt->second, false,
3834         "sampleQueue is nullptr");
3835     uint64_t cacheDuration = sqIt->second->GetCacheDuration();
3836     MEDIA_LOG_I("samplequeue cacheDuration=" PUBLIC_LOG_U64, cacheDuration);
3837     return cacheDuration > BUFFERING_WAVELINE_FOR_SAMPLE_QUEUE;
3838 }
3839 
InitEnableSampleQueueFlag()3840 void MediaDemuxer::InitEnableSampleQueueFlag()
3841 {
3842     const std::string sampleQueueTag = "debug.media_service.enable_samplequeue";
3843     std::string enableSampleQueue;
3844     int32_t enableSampleQueueRes = OHOS::system::GetStringParameter(sampleQueueTag, enableSampleQueue, "true");
3845     enableSampleQueue_ = (enableSampleQueue == "true");
3846     MEDIA_LOG_I("InitEnableSampleQueueFlag, enableSampleQueueRes: " PUBLIC_LOG_D32
3847         ", enableSampleQueue_: " PUBLIC_LOG_D32, enableSampleQueueRes, enableSampleQueue_);
3848 }
3849 
InitIsAudioDemuxDecodeAsync()3850 void MediaDemuxer::InitIsAudioDemuxDecodeAsync()
3851 {
3852     // To optimize the performance for audio only MediaSource, perform audio DEMUX and DECODE in the same thread.
3853     // 1. If audiodecoder_async is false, then DEMUX and DECODE run in the same thread.
3854     // 2. or audiodecoder_async is true, but both audiodemux_audiodecode_merged is true and isVideoTrackDisabled_ true,
3855     //    then DEMUX and DECODE run in the same thread.
3856     bool isAudioDeocderAsync =
3857         OHOS::system::GetParameter("debug.media_service.audio.audiodecoder_async", "1") == "1";
3858     bool isAudioDemuxDecodeMergedEnabled =
3859         OHOS::system::GetParameter("debug.media_service.audio.audiodemux_audiodecode_merged", "1") == "1";
3860     isAudioDemuxDecodeAsync_ = isAudioDeocderAsync && !(isAudioDemuxDecodeMergedEnabled && isVideoTrackDisabled_);
3861 
3862     MEDIA_LOG_I_SHORT("isAudioDeocderAsync: " PUBLIC_LOG_D32 ", isAudioDemuxDecodeMergedEnabled: " PUBLIC_LOG_D32
3863         ", isVideoTrackDisabled_: " PUBLIC_LOG_D32 ", isAudioDemuxDecodeAsync_: " PUBLIC_LOG_D32,
3864         isAudioDeocderAsync, isAudioDemuxDecodeMergedEnabled, isVideoTrackDisabled_, isAudioDemuxDecodeAsync_);
3865 }
3866 
IsNeedMapToInnerTrackID()3867 bool MediaDemuxer::IsNeedMapToInnerTrackID()
3868 {
3869     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, false, "demuxerPluginManager_ is nullptr");
3870     return (isFlvLiveStream_ || demuxerPluginManager_->IsDash() ||
3871         demuxerPluginManager_->GetTmpStreamIDByTrackID(subtitleTrackId_) != -1);
3872 }
3873 
GetMemoryUsage(int32_t trackId,std::shared_ptr<Plugins::DemuxerPlugin> & pluginTemp)3874 void MediaDemuxer::GetMemoryUsage(int32_t trackId, std::shared_ptr<Plugins::DemuxerPlugin> &pluginTemp)
3875 {
3876     std::lock_guard<std::mutex> lock(memoryReportLimitMutex_);
3877     FALSE_RETURN_NOLOG(eventReceiver_ != nullptr);
3878     if (memoryReportLimitCount_.find(trackId) == memoryReportLimitCount_.end()) {
3879         memoryReportLimitCount_[trackId] = 1;
3880     } else {
3881         memoryReportLimitCount_[trackId]++;
3882         FALSE_RETURN_NOLOG(memoryReportLimitCount_[trackId] % LIMIT_MEMORY_REPORT_COUNT == 0);
3883         ReportMemoryUsage(trackId, pluginTemp);
3884     }
3885 }
3886 
ReportMemoryUsage(int32_t trackId,std::shared_ptr<Plugins::DemuxerPlugin> & pluginTemp)3887 void MediaDemuxer::ReportMemoryUsage(int32_t trackId, std::shared_ptr<Plugins::DemuxerPlugin> &pluginTemp)
3888 {
3889     uint32_t memoryUsage = 0;
3890     Status ret = pluginTemp->GetCurrentCacheSize(static_cast<uint32_t>(trackId), memoryUsage);
3891     FALSE_RETURN_NOLOG(ret == Status::OK);
3892     trackMemoryUsages_[trackId] = memoryUsage;
3893     eventReceiver_->OnMemoryUsageEvent({"DEMUXER_PLUGIN", DfxEventType::DFX_INFO_MEMORY_USAGE, trackMemoryUsages_});
3894 
3895     auto sampleIter = sampleQueueMap_.find(trackId);
3896     FALSE_RETURN_NOLOG(sampleIter != sampleQueueMap_.end());
3897     memoryUsage = sampleIter->second->GetMemoryUsage();
3898     eventReceiver_->OnMemoryUsageEvent({"SAMPLE_QUEUE", DfxEventType::DFX_INFO_MEMORY_USAGE, memoryUsage});
3899 }
3900 
IsSeekToTimeSupported()3901 bool MediaDemuxer::IsSeekToTimeSupported()
3902 {
3903     return source_ != nullptr && source_->IsSeekToTimeSupported();
3904 }
3905 
GetCurrentCacheSize(uint32_t trackIndex,uint32_t & size)3906 Status MediaDemuxer::GetCurrentCacheSize(uint32_t trackIndex, uint32_t& size)
3907 {
3908     int32_t trackId = static_cast<int32_t>(trackIndex);
3909     MediaAVCodec::AVCODEC_SYNC_TRACE;
3910     FALSE_RETURN_V_MSG_E(demuxerPluginManager_ != nullptr, Status::ERROR_NULL_POINTER, "Plugin manager is nullptr");
3911     std::shared_ptr<Plugins::DemuxerPlugin> pluginTemp = nullptr;
3912     if (IsNeedMapToInnerTrackID()) {
3913         int32_t streamId = demuxerPluginManager_->GetTmpStreamIDByTrackID(trackId);
3914         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
3915         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Plugin is nullptr");
3916         int32_t innerTrackID = demuxerPluginManager_->GetTmpInnerTrackIDByTrackID(trackId);
3917         FALSE_RETURN_V_MSG_E(innerTrackID != INVALID_STREAM_OR_TRACK_ID,
3918             Status::ERROR_INVALID_PARAMETER, "Plugin is nullptr");
3919         trackIndex = static_cast<uint32_t>(innerTrackID);
3920     } else {
3921         int32_t streamId = demuxerPluginManager_->GetStreamIDByTrackID(trackId);
3922         pluginTemp = demuxerPluginManager_->GetPluginByStreamID(streamId);
3923         FALSE_RETURN_V_MSG_E(pluginTemp != nullptr, Status::ERROR_INVALID_PARAMETER, "Plugin is nullptr");
3924     }
3925     return pluginTemp->GetCurrentCacheSize(trackIndex, size);
3926 }
3927 
StopBufferring(bool isAppBackground)3928 Status MediaDemuxer::StopBufferring(bool isAppBackground)
3929 {
3930     FALSE_RETURN_V_MSG_E(source_ != nullptr, Status::ERROR_NULL_POINTER, "source_ is nullptr");
3931     return source_->StopBufferring(isAppBackground);
3932 }
3933 
SetMediaMuted(OHOS::Media::MediaType mediaType,bool isMuted)3934 void MediaDemuxer::SetMediaMuted(OHOS::Media::MediaType mediaType, bool isMuted)
3935 {
3936     if (mediaType == OHOS::Media::MediaType::MEDIA_TYPE_VID) {
3937         needRestore_ = !needReleaseVideoDecoder_ && isVideoMuted_ && !isMuted;
3938         needReleaseVideoDecoder_ = isMuted ? !isVideoMuted_ || needReleaseVideoDecoder_ : false;
3939         isVideoMuted_ = isMuted;
3940         MEDIA_LOG_I("MediaDemuxer::SetMediaMuted " PUBLIC_LOG_U32, isMuted);
3941     }
3942 }
3943 
InitEnableDfxBufferQueue()3944 void MediaDemuxer::InitEnableDfxBufferQueue()
3945 {
3946     const std::string dfxBufferQueueTag = "debug.media_service.enable_dfx_buffer_queue";
3947     enableDfxBufferQueue_ = OHOS::system::GetBoolParameter(dfxBufferQueueTag, false);
3948     MEDIA_LOG_I("enableDfxBufferQueue_ " PUBLIC_LOG_D32, enableDfxBufferQueue_);
3949 }
3950 
NotifyResumeUnMute()3951 void MediaDemuxer::NotifyResumeUnMute()
3952 {
3953     if (sampleConsumerTaskMap_.find(videoTrackId_) != sampleConsumerTaskMap_.end() &&
3954             sampleConsumerTaskMap_[videoTrackId_] != nullptr) {
3955         if (!isVideoMuted_ && !sampleConsumerTaskMap_[videoTrackId_]->IsTaskRunning()) {
3956             sampleConsumerTaskMap_[videoTrackId_]->Start();
3957         }
3958     }
3959 }
3960 
HandleVideoSampleQueue()3961 void MediaDemuxer::HandleVideoSampleQueue()
3962 {
3963     Status ret = sampleQueueMap_[videoTrackId_]->AddQueueSize(SAMPLE_QUEUE_ADD_SIZE_ON_MUTE);
3964     FALSE_RETURN_NOLOG(ret != Status::OK);
3965     std::shared_ptr<AVBuffer> dstBuffer;
3966     ret = sampleQueueMap_[videoTrackId_]->AcquireBuffer(dstBuffer);
3967     FALSE_RETURN_NOLOG(ret == Status::OK);
3968     sampleQueueMap_[videoTrackId_]->ReleaseBuffer(dstBuffer);
3969 }
3970 } // namespace Media
3971 } // namespace OHOS