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 DashMpdDownloader(); 115 virtual ~DashMpdDownloader(); 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 void 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 144 private: 145 void ParseManifest(); 146 void ParseSidx(); 147 void OpenStream(std::shared_ptr<DashStreamDescription> stream); 148 void DoOpen(const std::string &url, int64_t startRange = -1, int64_t endRange = -1); 149 bool SaveData(uint8_t *data, uint32_t len); 150 void SetOndemandSegBase(); 151 bool SetOndemandSegBase(std::list<DashAdptSetInfo *> adptSetList); 152 bool SetOndemandSegBase(std::list<DashRepresentationInfo *> repList); 153 bool CheckToDownloadSidxWithInitSeg(std::shared_ptr<DashStreamDescription> streamDesc); 154 bool GetStreamsInfoInMpd(); 155 void GetStreamsInfoInPeriod(DashPeriodInfo *periodInfo, unsigned int periodIndex, const std::string &mpdBaseUrl); 156 void GetStreamsInfoInAdptSet(DashAdptSetInfo *adptSetInfo, const std::string &periodBaseUrl, 157 DashStreamDescription &streamDesc); 158 unsigned int GetResolutionDelta(unsigned int width, unsigned int height); 159 bool IsChoosedVideoStream(const std::shared_ptr<DashStreamDescription> &choosedStream, 160 const std::shared_ptr<DashStreamDescription> ¤tStream); 161 bool IsNearToInitResolution(const std::shared_ptr<DashStreamDescription> &choosedStream, 162 const std::shared_ptr<DashStreamDescription> ¤tStream); 163 bool IsLangMatch(const std::string &lang, MediaAVCodec::MediaType type); 164 bool ChooseStreamToPlay(MediaAVCodec::MediaType type); 165 unsigned int GetSegTimeBySeq(const std::vector<std::shared_ptr<DashSegment>> &segments, int64_t segSeq); 166 DashSegmentInitValue GetSegmentsInMpd(std::shared_ptr<DashStreamDescription> streamDesc); 167 DashSegmentInitValue GetSegmentsInPeriod(DashPeriodInfo *periodInfo, const std::string &mpdBaseUrl, 168 std::shared_ptr<DashStreamDescription> streamDesc); 169 DashSegmentInitValue GetSegmentsInAdptSet(DashAdptSetInfo *adptSetInfo, const std::string &periodBaseUrl, 170 std::shared_ptr<DashStreamDescription> streamDesc); 171 DashSegmentInitValue GetSegmentsInRepresentation(DashRepresentationInfo *repInfo, const std::string &adptSetBaseUrl, 172 std::shared_ptr<DashStreamDescription> streamDesc); 173 DashSegmentInitValue GetSegmentsByPeriodInfo(DashPeriodInfo *periodInfo, DashAdptSetInfo *adptSetInfo, 174 std::string &periodBaseUrl, 175 std::shared_ptr<DashStreamDescription> streamDesc); 176 DashSegmentInitValue GetSegmentsByAdptSetInfo(const DashAdptSetInfo *adptSetInfo, 177 const DashRepresentationInfo *repInfo, 178 std::string &baseUrl, 179 std::shared_ptr<DashStreamDescription> streamDesc); 180 DashRepresentationInfo *GetRepresemtationFromAdptSet(DashAdptSetInfo *adptSetInfo, unsigned int repIndex); 181 182 DashSegmentInitValue GetSegmentsWithSegTemplate(const DashSegTmpltInfo *segTmpltInfo, std::string id, 183 std::shared_ptr<DashStreamDescription> streamDesc); 184 DashSegmentInitValue GetSegmentsWithTmpltStatic(const DashSegTmpltInfo *segTmpltInfo, const std::string &mediaUrl, 185 std::shared_ptr<DashStreamDescription> streamDesc); 186 DashSegmentInitValue GetSegmentsWithTmpltDurationStatic(const DashSegTmpltInfo *segTmpltInfo, 187 const std::string &mediaUrl, unsigned int timeScale, 188 std::shared_ptr<DashStreamDescription> desc); 189 DashSegmentInitValue GetSegmentsWithTmpltTimelineStatic(const DashSegTmpltInfo *segTmpltInfo, 190 const std::string &mediaUrl, unsigned int timeScale, 191 std::shared_ptr<DashStreamDescription> desc); 192 DashSegmentInitValue GetSegmentsInOneTimeline(const DashSegTimeline *timeline, const MediaSegSampleInfo &sampleInfo, 193 int64_t &segmentSeq, uint64_t &startTime, 194 std::shared_ptr<DashStreamDescription> streamDesc); 195 196 DashSegmentInitValue GetSegmentsWithSegList(const DashSegListInfo *segListInfo, const std::string &baseUrl, 197 std::shared_ptr<DashStreamDescription> streamDesc); 198 void GetSegDurationFromTimeline(unsigned int periodDuration, unsigned int timeScale, 199 const DashMultSegBaseInfo *multSegBaseInfo, std::list<unsigned int> &durationList); 200 int GetSegCountFromTimeline(DashList<DashSegTimeline *>::iterator &it, 201 const DashList<DashSegTimeline *>::iterator &end, 202 unsigned int periodDuration, unsigned int timeScale, uint64_t startTime); 203 204 DashSegmentInitValue GetSegmentsWithBaseUrl(std::list<std::string> baseUrlList, 205 std::shared_ptr<DashStreamDescription> streamDesc); 206 207 bool GetInitSegFromPeriod(const std::string &periodBaseUrl, const std::string &repId, 208 std::shared_ptr<DashStreamDescription> streamDesc); 209 bool GetInitSegFromAdptSet(const std::string &adptSetBaseUrl, const std::string &repId, 210 std::shared_ptr<DashStreamDescription> streamDesc); 211 bool GetInitSegFromRepresentation(const std::string &repBaseUrl, const std::string &repId, 212 std::shared_ptr<DashStreamDescription> streamDesc); 213 DashMpdGetRet GetSegmentsInNewStream(std::shared_ptr<DashStreamDescription> destStream); 214 void UpdateInitSegUrl(std::shared_ptr<DashStreamDescription> streamDesc, const DashUrlType *urlType, 215 int segTmpltFlag, 216 std::string representationID); 217 218 bool PutStreamToDownload(); 219 void GetDrmInfos(std::vector<DashDrmInfo>& drmInfos); 220 void ProcessDrmInfos(); 221 void GetDrmInfos(const std::string &drmId, const DashList<DashDescriptor *> &contentProtections, 222 std::vector<DashDrmInfo> &drmInfoList); 223 void BuildDashSegment(std::list<std::shared_ptr<SubSegmentIndex>> &subSegIndexList) const; 224 void GetStreamDescriptions(const std::string &periodBaseUrl, DashStreamDescription &streamDesc, 225 const std::string &adptSetBaseUrl, 226 std::list<DashRepresentationInfo *> &repList); 227 void GetAdpDrmInfos(std::vector<DashDrmInfo> &drmInfos, DashPeriodInfo *const &periodInfo, 228 const std::string &periodDrmId); 229 230 private: 231 std::string url_ {}; 232 std::string downloadContent_ {}; // mpd content or sidx content 233 std::string defaultAudioLang_ {}; 234 std::string defaultSubtitleLang_ {}; 235 DashMpdCallback* callback_ {nullptr}; 236 std::shared_ptr<Downloader> downloader_ {nullptr}; 237 std::shared_ptr<DownloadRequest> downloadRequest_ {nullptr}; 238 std::shared_ptr<DashMpdParser> mpdParser_ {nullptr}; 239 std::shared_ptr<DashMpdManager> mpdManager_ {nullptr}; 240 std::shared_ptr<DashPeriodManager> periodManager_ {nullptr}; 241 std::shared_ptr<DashAdptSetManager> adptSetManager_ {nullptr}; 242 std::shared_ptr<DashRepresentationManager> representationManager_ {nullptr}; 243 DashMpdInfo* mpdInfo_ {nullptr}; 244 unsigned int duration_ {0}; 245 std::vector<std::shared_ptr<DashStreamDescription>> streamDescriptions_; 246 std::shared_ptr<DashStreamDescription> currentDownloadStream_ {nullptr}; 247 DataSaveFunc dataSave_ {nullptr}; 248 StatusCallbackFunc statusCallback_ {nullptr}; 249 bool ondemandSegBase_ {false}; 250 bool notifyOpenOk_ {false}; 251 bool isHdrStart_ {false}; 252 unsigned int initResolution_ {0}; 253 std::atomic<bool> isInterruptNeeded_{false}; 254 std::vector<DashDrmInfo> localDrmInfos_; 255 }; 256 } 257 } 258 } 259 } 260 #endif