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