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