/* * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MEDIA_DEMUXER_H #define MEDIA_DEMUXER_H #include #include #include #include #include #include "osal/task/condition_variable.h" #include "avcodec_common.h" #include "buffer/avbuffer.h" #include "common/media_source.h" #include "common/seek_callback.h" #include "demuxer/type_finder.h" #include "filter/filter.h" #include "meta/media_types.h" #include "osal/task/autolock.h" #include "osal/task/task.h" #include "plugin/plugin_base.h" #include "plugin/plugin_info.h" #include "plugin/plugin_time.h" #include "plugin/demuxer_plugin.h" namespace OHOS { namespace Media { namespace { constexpr uint32_t TRACK_ID_DUMMY = std::numeric_limits::max(); constexpr int32_t DEFAULT_DECODE_FRAMERATE_UPPER_LIMIT = 120; } using MediaSource = OHOS::Media::Plugins::MediaSource; class BaseStreamDemuxer; class DemuxerPluginManager; class Source; class AVBufferQueueProducer; class MediaDemuxer : public std::enable_shared_from_this, public Plugins::Callback { public: explicit MediaDemuxer(); ~MediaDemuxer() override; Status SetDataSource(const std::shared_ptr &source); Status SetSubtitleSource(const std::shared_ptr &source); void SetBundleName(const std::string& bundleName); Status SetOutputBufferQueue(int32_t trackId, const sptr& producer); std::shared_ptr GetGlobalMetaInfo() const; std::vector> GetStreamMetaInfo() const; std::shared_ptr GetUserMeta(); Status SeekTo(int64_t seekTime, Plugins::SeekMode mode, int64_t& realSeekTime); Status Reset(); Status Start(); Status Stop(); Status Pause(); Status PauseDragging(); Status PauseAudioAlign(); Status Resume(); Status ResumeDragging(); Status ResumeAudioAlign(); Status Flush(); Status Preroll(); Status PausePreroll(); Status StartTask(int32_t trackId); Status SelectTrack(int32_t trackId); Status UnselectTrack(int32_t trackId); Status ReadSample(uint32_t trackId, std::shared_ptr sample); Status GetBitRates(std::vector &bitRates); Status SelectBitRate(uint32_t bitRate); Status GetDownloadInfo(DownloadInfo& downloadInfo); Status GetPlaybackInfo(PlaybackInfo& playbackInfo); Status GetMediaKeySystemInfo(std::multimap> &infos); void SetDrmCallback(const std::shared_ptr &callback); void OnEvent(const Plugins::PluginEvent &event) override; void OnSeekReadyEvent(const Plugins::PluginEvent &event); std::map> GetBufferQueueProducerMap(); Status PauseTaskByTrackId(int32_t trackId); bool IsRenderNextVideoFrameSupported(); void SetEventReceiver(const std::shared_ptr &receiver); bool GetDuration(int64_t& durationMs); void SetPlayerId(const std::string &playerId); void SetInterruptState(bool isInterruptNeeded); void SetDumpInfo(bool isDump, uint64_t instanceId); Status OptimizeDecodeSlow(bool isDecodeOptimizationEnabled); Status SetDecoderFramerateUpperLimit(int32_t decoderFramerateUpperLimit, uint32_t trackId); Status SetSpeed(float speed); Status SetFrameRate(double frameRate, uint32_t trackId); bool IsLocalDrmInfosExisted(); Status DisableMediaTrack(Plugins::MediaType mediaType); void OnBufferAvailable(uint32_t trackId); void SetSelectBitRateFlag(bool flag, uint32_t desBitRate) override; bool CanAutoSelectBitRate() override; void OnDumpInfo(int32_t fd); bool IsRefParserSupported(); Status StartReferenceParser(int64_t startTimeMs, bool isForward = true); Status GetFrameLayerInfo(std::shared_ptr videoSample, FrameLayerInfo &frameLayerInfo); Status GetFrameLayerInfo(uint32_t frameId, FrameLayerInfo &frameLayerInfo); Status GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo); bool IsVideoEos(); bool HasEosTrack(); Status GetIFramePos(std::vector &IFramePos); Status Dts2FrameId(int64_t dts, uint32_t &frameId, bool offset = true); void RegisterVideoStreamReadyCallback(const std::shared_ptr &callback); void DeregisterVideoStreamReadyCallback(); Status GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex, const uint64_t relativePresentationTimeUs, uint32_t &index); Status GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex, const uint32_t index, uint64_t &relativePresentationTimeUs); Status ResumeDemuxerReadLoop(); Status PauseDemuxerReadLoop(); void SetCacheLimit(uint32_t limitSize); void SetEnableOnlineFdCache(bool isEnableFdCache); void WaitForBufferingEnd(); int32_t GetCurrentVideoTrackId(); uint32_t GetTargetVideoTrackId(std::vector> trackInfos); void SetIsEnableReselectVideoTrack(bool isEnable); bool IsHasMultiVideoTrack(); private: class AVBufferQueueProducerListener; class TrackWrapper; struct MediaMetaData { std::vector> trackMetas; std::shared_ptr globalMeta; }; struct MaintainBaseInfo { int64_t segmentOffset = -1; int64_t basePts = -1; int64_t lastPts = 0; }; bool isHttpSource_ = false; std::string videoMime_{}; void InitMediaMetaData(const Plugins::MediaInfo& mediaInfo); void InitDefaultTrack(const Plugins::MediaInfo& mediaInfo, uint32_t& videoTrackId, uint32_t& audioTrackId, uint32_t& subtitleTrackId, std::string& videoMime); std::shared_ptr GetTrackMeta(uint32_t trackId); Status AddDemuxerCopyTask(uint32_t trackId, TaskType type); Status StopAllTask(); Status PauseAllTask(); Status ResumeAllTask(); void AccelerateTrackTask(uint32_t trackId); void SetTrackNotifyFlag(uint32_t trackId, bool isNotifyNeeded); void ResetInner(); bool GetDrmInfosUpdated(const std::multimap> &newInfos, std::multimap> &result); Status ProcessDrmInfos(); void HandleSourceDrmInfoEvent(const std::multimap> &info); Status ReportDrmInfos(const std::multimap> &info); bool HasVideo(); void DumpBufferToFile(uint32_t trackId, std::shared_ptr buffer); bool IsBufferDroppable(std::shared_ptr sample, uint32_t trackId); void CheckDropAudioFrame(std::shared_ptr sample, uint32_t trackId); bool IsTrackDisabled(Plugins::MediaType mediaType); bool CheckTrackEnabledById(uint32_t trackId); bool HandleDashChangeStream(uint32_t trackId); Status SeekToTimeAfter(); bool SelectBitRateChangeStream(uint32_t trackId); bool SelectTrackChangeStream(uint32_t trackId); bool HandleSelectTrackChangeStream(int32_t trackId, int32_t newStreamID, int32_t& newTrackId); std::shared_ptr GetCurFFmpegPlugin(); Plugins::Seekable seekable_; Plugins::Seekable subSeekable_; std::string uri_; std::string SubtitleUri_; uint64_t mediaDataSize_ = 0; uint64_t subMediaDataSize_; std::shared_ptr mediaSource_; std::shared_ptr source_; std::shared_ptr subtitleSource_; MediaMetaData mediaMetaData_; int64_t ReadLoop(uint32_t trackId); Status CopyFrameToUserQueue(uint32_t trackId); bool GetBufferFromUserQueue(uint32_t queueIndex, uint32_t size = 0); Status InnerReadSample(uint32_t trackId, std::shared_ptr); Status InnerSelectTrack(int32_t trackId); Status HandleReadSample(uint32_t trackId); int64_t ParserRefInfo(); void TryRecvParserTask(); Status HandleSelectTrack(int32_t trackId); Status HandleDashSelectTrack(int32_t trackId); Status DoSelectTrack(int32_t trackId, int32_t curTrackId); Status HandleRebootPlugin(int32_t trackId, bool& isRebooted); bool DashCheckChangeStream(uint32_t trackId); bool IsSubtitleMime(const std::string& mime); Status InnerPrepare(); Status HandleAutoMaintainPts(uint32_t trackId, std::shared_ptr sample); Status InitPtsInfo(); Mutex mapMutex_{}; std::map> trackMap_; std::map> bufferQueueMap_; std::map> bufferMap_; std::map eosMap_; std::map requestBufferErrorCountMap_; std::atomic isThreadExit_ = true; bool useBufferQueue_ = false; bool isAccurateSeekForHLS_ = false; int64_t videoStartTime_{0}; std::shared_mutex drmMutex{}; std::mutex isSelectTrackMutex_{}; std::mutex rebootPluginMutex_{}; std::multimap> localDrmInfos_; std::shared_ptr drmCallback_; std::map> taskMap_; std::shared_ptr eventReceiver_; int64_t lastSeekTime_{Plugins::HST_TIME_NONE}; bool isSeeked_{false}; uint32_t videoTrackId_{TRACK_ID_DUMMY}; uint32_t audioTrackId_{TRACK_ID_DUMMY}; uint32_t subtitleTrackId_{TRACK_ID_DUMMY}; bool firstAudio_{true}; std::atomic isStopped_ = true; std::atomic isPaused_ = false; std::shared_ptr streamDemuxer_; std::shared_ptr subStreamDemuxer_; std::string bundleName_ {}; std::string playerId_; int64_t duration_ {0}; std::atomic isDecodeOptimizationEnabled_ {false}; std::atomic speed_ {1.0f}; std::atomic framerate_ {0.0}; std::atomic decoderFramerateUpperLimit_ {DEFAULT_DECODE_FRAMERATE_UPPER_LIMIT}; std::unordered_set disabledMediaTracks_ {}; std::string subtitlePluginName_; std::shared_ptr subtitlePlugin_; std::shared_ptr subtitleMediaSource_; bool isDump_ = false; std::shared_ptr demuxerPluginManager_; std::atomic isSelectBitRate_ = false; uint32_t targetBitRate_ = 0; std::string dumpPrefix_ = ""; std::unique_ptr parserRefInfoTask_; bool isFirstParser_ = true; bool isParserTaskEnd_ = false; std::atomic isOnEventNoMemory_ = false; std::atomic isSeekError_ = false; std::shared_ptr VideoStreamReadyCallback_ = nullptr; std::mutex draggingMutex_ {}; std::atomic isDemuxerLoopExecuting_ {false}; std::atomic isFirstFrameAfterSeek_ {false}; std::mutex prerollMutex_ {}; std::atomic inPreroll_ = false; std::map inSelectTrackType_{}; std::map> seekReadyStreamInfo_{}; std::condition_variable rebootPluginCondition_; std::atomic isSelectTrack_ = false; std::atomic shouldCheckAudioFramePts_ = false; int64_t lastAudioPts_ = 0; std::atomic shouldCheckSubtitleFramePts_ = false; int64_t lastSubtitlePts_ = 0; std::atomic isInterruptNeeded_ {false}; bool isAutoMaintainPts_ = false; std::map> maintainBaseInfos_; bool isEnableReselectVideoTrack_ {false}; int32_t videoTrackCount_ = 0; uint32_t targetVideoTrackId_ {TRACK_ID_DUMMY}; }; } // namespace Media } // namespace OHOS #endif // MEDIA_DEMUXER_H