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