1 /* 2 * Copyright (c) 2024-2024 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 #ifndef HISTREAMER_DASH_MPD_DOWNLOADER_H 17 #define HISTREAMER_DASH_MPD_DOWNLOADER_H 18 19 #include "dash_common.h" 20 #include "dash_mpd_def.h" 21 #include "dash_mpd_parser.h" 22 #include "dash_mpd_manager.h" 23 #include "dash_period_manager.h" 24 #include "dash_adpt_set_manager.h" 25 #include "dash_representation_manager.h" 26 #include "download/downloader.h" 27 #include "media_downloader.h" 28 #include "meta/media_types.h" 29 30 namespace OHOS { 31 namespace Media { 32 namespace Plugins { 33 namespace HttpPlugin { 34 35 using DashMpdEvent = enum DashMpdEvent { 36 DASH_MPD_EVENT_OPEN_OK, 37 DASH_MPD_EVENT_STREAM_INIT, 38 DASH_MPD_EVENT_PARSE_OK 39 }; 40 41 enum DashMpdGetRet { 42 DASH_MPD_GET_ERROR, 43 DASH_MPD_GET_DONE, // get segment normal 44 DASH_MPD_GET_UNDONE, // get segment null, as segment list is empty 45 DASH_MPD_GET_FINISH // get segment finish 46 }; 47 48 using DashMpdSwitchType = enum DashMpdSwitchType { 49 DASH_MPD_SWITCH_TYPE_NONE, 50 DASH_MPD_SWITCH_TYPE_AUTO, 51 DASH_MPD_SWITCH_TYPE_SMOOTH 52 }; 53 54 struct DashMpdBitrateParam { DashMpdBitrateParamDashMpdBitrateParam55 DashMpdBitrateParam() 56 { 57 waitSegmentFinish_ = false; 58 waitSidxFinish_ = false; 59 streamId_ = -1; 60 bitrate_ = 0; 61 type_ = DASH_MPD_SWITCH_TYPE_NONE; 62 position_ = -1; 63 nextSegTime_ = 0; 64 } 65 66 bool waitSegmentFinish_; 67 bool waitSidxFinish_; 68 int streamId_; 69 unsigned int bitrate_; 70 DashMpdSwitchType type_; 71 int64_t position_; 72 unsigned int nextSegTime_; 73 }; 74 75 struct DashMpdTrackParam { DashMpdTrackParamDashMpdTrackParam76 DashMpdTrackParam() 77 { 78 waitSidxFinish_ = false; 79 isEnd_ = false; 80 type_ = MediaAVCodec::MediaType::MEDIA_TYPE_AUD; 81 streamId_ = -1; 82 position_ = -1; 83 nextSegTime_ = 0; 84 } 85 86 bool waitSidxFinish_; 87 bool isEnd_; 88 MediaAVCodec::MediaType type_; 89 int streamId_; 90 int64_t position_; 91 unsigned int nextSegTime_; 92 }; 93 94 struct MediaSegSampleInfo { MediaSegSampleInfoMediaSegSampleInfo95 MediaSegSampleInfo() 96 { 97 segCount_ = 0; 98 segDuration_ = 0; 99 } 100 101 int segCount_; 102 unsigned int segDuration_; 103 std::string mediaUrl_; 104 }; 105 106 struct DashMpdCallback { 107 virtual ~DashMpdCallback() = default; 108 virtual void OnMpdInfoUpdate(DashMpdEvent mpdEvent) = 0; 109 virtual void OnDrmInfoChanged(const std::multimap<std::string, std::vector<uint8_t>>& drmInfos) = 0; 110 }; 111 112 class DashMpdDownloader { 113 public: 114 explicit DashMpdDownloader(std::shared_ptr<MediaSourceLoaderCombinations> sourceLoader = nullptr); 115 virtual ~DashMpdDownloader() noexcept; 116 117 void Open(const std::string &url); 118 void Close(bool isAsync); 119 void SetStatusCallback(StatusCallbackFunc cb); 120 void SetMpdCallback(DashMpdCallback *callback); 121 int64_t GetDuration() const; 122 Seekable GetSeekable() const; 123 std::vector<uint32_t> GetBitRates() const; 124 std::vector<uint32_t> GetBitRatesByHdr(bool isHdr) const; 125 int64_t SeekToTs(int streamId, int64_t seekTime, std::shared_ptr<DashSegment> &seg) const; 126 void UpdateDownloadFinished(const std::string &url); 127 int GetInUseVideoStreamId() const; 128 DashMpdGetRet GetNextSegmentByStreamId(int streamId, std::shared_ptr<DashSegment> &seg); 129 DashMpdGetRet GetBreakPointSegment(int streamId, int64_t breakpoint, std::shared_ptr<DashSegment> &seg); 130 DashMpdGetRet GetNextVideoStream(DashMpdBitrateParam ¶m, int &streamId); 131 DashMpdGetRet GetNextTrackStream(DashMpdTrackParam ¶m); 132 Status GetStreamInfo(std::vector<StreamInfo> &streams); 133 std::shared_ptr<DashStreamDescription> GetStreamByStreamId(int streamId); 134 std::shared_ptr<DashStreamDescription> GetUsingStreamByType(MediaAVCodec::MediaType type); 135 std::shared_ptr<DashInitSegment> GetInitSegmentByStreamId(int streamId); 136 void SetCurrentNumberSeqByStreamId(int streamId, int64_t numberSeq); 137 void UpdateCurrentNumberSeqByTime(const std::shared_ptr<DashStreamDescription> &streamDesc, uint32_t nextSegTime); 138 void SetHdrStart(bool isHdrStart); 139 void SetInitResolution(unsigned int width, unsigned int height); 140 void SetDefaultLang(const std::string &lang, MediaAVCodec::MediaType type); 141 void SetInterruptState(bool isInterruptNeeded); 142 std::string GetUrl() const; 143 std::string GetContentType(); 144 145 private: 146 void ParseManifest(); 147 void ParseSidx(); 148 void OpenStream(std::shared_ptr<DashStreamDescription> stream); 149 void DoOpen(const std::string &url, int64_t startRange = -1, int64_t endRange = -1); 150 uint32_t SaveData(uint8_t *data, uint32_t len, bool notBlock); 151 void SetOndemandSegBase(); 152 bool SetOndemandSegBase(std::list<DashAdptSetInfo *> adptSetList); 153 bool SetOndemandSegBase(std::list<DashRepresentationInfo *> repList); 154 bool CheckToDownloadSidxWithInitSeg(std::shared_ptr<DashStreamDescription> streamDesc); 155 bool GetStreamsInfoInMpd(); 156 void GetStreamsInfoInPeriod(DashPeriodInfo *periodInfo, unsigned int periodIndex, const std::string &mpdBaseUrl); 157 void GetStreamsInfoInAdptSet(DashAdptSetInfo *adptSetInfo, const std::string &periodBaseUrl, 158 DashStreamDescription &streamDesc); 159 unsigned int GetResolutionDelta(unsigned int width, unsigned int height); 160 bool IsChoosedVideoStream(const std::shared_ptr<DashStreamDescription> &choosedStream, 161 const std::shared_ptr<DashStreamDescription> ¤tStream); 162 bool IsNearToInitResolution(const std::shared_ptr<DashStreamDescription> &choosedStream, 163 const std::shared_ptr<DashStreamDescription> ¤tStream); 164 bool IsLangMatch(const std::string &lang, MediaAVCodec::MediaType type); 165 bool ChooseStreamToPlay(MediaAVCodec::MediaType type); 166 unsigned int GetSegTimeBySeq(const std::vector<std::shared_ptr<DashSegment>> &segments, int64_t segSeq); 167 DashSegmentInitValue GetSegmentsInMpd(std::shared_ptr<DashStreamDescription> streamDesc); 168 DashSegmentInitValue GetSegmentsInPeriod(DashPeriodInfo *periodInfo, const std::string &mpdBaseUrl, 169 std::shared_ptr<DashStreamDescription> streamDesc); 170 DashSegmentInitValue GetSegmentsInAdptSet(DashAdptSetInfo *adptSetInfo, const std::string &periodBaseUrl, 171 std::shared_ptr<DashStreamDescription> streamDesc); 172 DashSegmentInitValue GetSegmentsInRepresentation(DashRepresentationInfo *repInfo, const std::string &adptSetBaseUrl, 173 std::shared_ptr<DashStreamDescription> streamDesc); 174 DashSegmentInitValue GetSegmentsByPeriodInfo(DashPeriodInfo *periodInfo, DashAdptSetInfo *adptSetInfo, 175 std::string &periodBaseUrl, 176 std::shared_ptr<DashStreamDescription> streamDesc); 177 DashSegmentInitValue GetSegmentsByAdptSetInfo(const DashAdptSetInfo *adptSetInfo, 178 const DashRepresentationInfo *repInfo, 179 std::string &baseUrl, 180 std::shared_ptr<DashStreamDescription> streamDesc); 181 DashRepresentationInfo *GetRepresemtationFromAdptSet(DashAdptSetInfo *adptSetInfo, unsigned int repIndex); 182 183 DashSegmentInitValue GetSegmentsWithSegTemplate(const DashSegTmpltInfo *segTmpltInfo, std::string id, 184 std::shared_ptr<DashStreamDescription> streamDesc); 185 DashSegmentInitValue GetSegmentsWithTmpltStatic(const DashSegTmpltInfo *segTmpltInfo, const std::string &mediaUrl, 186 std::shared_ptr<DashStreamDescription> streamDesc); 187 DashSegmentInitValue GetSegmentsWithTmpltDurationStatic(const DashSegTmpltInfo *segTmpltInfo, 188 const std::string &mediaUrl, unsigned int timeScale, 189 std::shared_ptr<DashStreamDescription> desc); 190 DashSegmentInitValue GetSegmentsWithTmpltTimelineStatic(const DashSegTmpltInfo *segTmpltInfo, 191 const std::string &mediaUrl, unsigned int timeScale, 192 std::shared_ptr<DashStreamDescription> desc); 193 DashSegmentInitValue GetSegmentsInOneTimeline(const DashSegTimeline *timeline, const MediaSegSampleInfo &sampleInfo, 194 int64_t &segmentSeq, uint64_t &startTime, 195 std::shared_ptr<DashStreamDescription> streamDesc); 196 197 DashSegmentInitValue GetSegmentsWithSegList(const DashSegListInfo *segListInfo, const std::string &baseUrl, 198 std::shared_ptr<DashStreamDescription> streamDesc); 199 void GetSegDurationFromTimeline(unsigned int periodDuration, unsigned int timeScale, 200 const DashMultSegBaseInfo *multSegBaseInfo, std::list<unsigned int> &durationList); 201 int GetSegCountFromTimeline(DashList<DashSegTimeline *>::iterator &it, 202 const DashList<DashSegTimeline *>::iterator &end, 203 unsigned int periodDuration, unsigned int timeScale, uint64_t startTime); 204 205 DashSegmentInitValue GetSegmentsWithBaseUrl(std::list<std::string> baseUrlList, 206 std::shared_ptr<DashStreamDescription> streamDesc); 207 208 bool GetInitSegFromPeriod(const std::string &periodBaseUrl, const std::string &repId, 209 std::shared_ptr<DashStreamDescription> streamDesc); 210 bool GetInitSegFromAdptSet(const std::string &adptSetBaseUrl, const std::string &repId, 211 std::shared_ptr<DashStreamDescription> streamDesc); 212 bool GetInitSegFromRepresentation(const std::string &repBaseUrl, const std::string &repId, 213 std::shared_ptr<DashStreamDescription> streamDesc); 214 DashMpdGetRet GetSegmentsInNewStream(std::shared_ptr<DashStreamDescription> destStream); 215 void UpdateInitSegUrl(std::shared_ptr<DashStreamDescription> streamDesc, const DashUrlType *urlType, 216 int segTmpltFlag, 217 std::string representationID); 218 219 bool PutStreamToDownload(); 220 void GetDrmInfos(std::vector<DashDrmInfo>& drmInfos); 221 void ProcessDrmInfos(); 222 void GetDrmInfos(const std::string &drmId, const DashList<DashDescriptor *> &contentProtections, 223 std::vector<DashDrmInfo> &drmInfoList); 224 void BuildDashSegment(std::list<std::shared_ptr<SubSegmentIndex>> &subSegIndexList) const; 225 void GetStreamDescriptions(const std::string &periodBaseUrl, DashStreamDescription &streamDesc, 226 const std::string &adptSetBaseUrl, 227 std::list<DashRepresentationInfo *> &repList); 228 void GetAdpDrmInfos(std::vector<DashDrmInfo> &drmInfos, DashPeriodInfo *const &periodInfo, 229 const std::string &periodDrmId); 230 231 private: 232 std::string url_ {}; 233 std::string downloadContent_ {}; // mpd content or sidx content 234 std::string defaultAudioLang_ {}; 235 std::string defaultSubtitleLang_ {}; 236 DashMpdCallback* callback_ {nullptr}; 237 std::shared_ptr<Downloader> downloader_ {nullptr}; 238 std::shared_ptr<DownloadRequest> downloadRequest_ {nullptr}; 239 std::shared_ptr<DashMpdParser> mpdParser_ {nullptr}; 240 std::shared_ptr<DashMpdManager> mpdManager_ {nullptr}; 241 std::shared_ptr<DashPeriodManager> periodManager_ {nullptr}; 242 std::shared_ptr<DashAdptSetManager> adptSetManager_ {nullptr}; 243 std::shared_ptr<DashRepresentationManager> representationManager_ {nullptr}; 244 DashMpdInfo* mpdInfo_ {nullptr}; 245 unsigned int duration_ {0}; 246 std::vector<std::shared_ptr<DashStreamDescription>> streamDescriptions_; 247 std::shared_ptr<DashStreamDescription> currentDownloadStream_ {nullptr}; 248 DataSaveFunc dataSave_ {nullptr}; 249 StatusCallbackFunc statusCallback_ {nullptr}; 250 bool ondemandSegBase_ {false}; 251 bool notifyOpenOk_ {false}; 252 bool isHdrStart_ {false}; 253 unsigned int initResolution_ {0}; 254 std::atomic<bool> isInterruptNeeded_{false}; 255 std::vector<DashDrmInfo> localDrmInfos_; 256 }; 257 } 258 } 259 } 260 } 261 #endif