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