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_MEDIA_DOWNLOADER_H
17 #define HISTREAMER_DASH_MEDIA_DOWNLOADER_H
18 
19 #include "media_downloader.h"
20 #include "dash_mpd_downloader.h"
21 #include "dash_segment_downloader.h"
22 #include "osal/utils/steady_clock.h"
23 #include "osal/task/task.h"
24 
25 namespace OHOS {
26 namespace Media {
27 namespace Plugins {
28 namespace HttpPlugin {
29 struct DashPreparedAction {
30     int64_t seekPosition_ {-1};
31     DashMpdBitrateParam preparedBitrateParam_;
32     DashMpdTrackParam preparedAudioParam_;
33     DashMpdTrackParam preparedSubtitleParam_;
34 };
35 
36 class DashMediaDownloader : public MediaDownloader, public DashMpdCallback {
37 public:
38     DashMediaDownloader() noexcept;
39     ~DashMediaDownloader() override;
40     bool Open(const std::string& url, const std::map<std::string, std::string>& httpHeader) override;
41     void Close(bool isAsync) override;
42     void Pause() override;
43     void Resume() override;
44     Status Read(unsigned char* buff, ReadDataInfo& readDataInfo) override;
45     bool SeekToTime(int64_t seekTime, SeekMode mode) override;
46 
47     size_t GetContentLength() const override;
48     int64_t GetDuration() const override;
49     Seekable GetSeekable() const override;
50     void SetCallback(Callback* cb) override;
51     void SetStatusCallback(StatusCallbackFunc cb) override;
52     bool GetStartedStatus() override;
53     std::vector<uint32_t> GetBitRates() override;
54     bool SelectBitRate(uint32_t bitrate) override;
55     Status SelectStream(int32_t streamId) override;
56     void SetIsTriggerAutoMode(bool isAuto) override;
57     void SeekToTs(int64_t seekTime);
58     void SetDownloadErrorState() override;
59     void SetPlayStrategy(const std::shared_ptr<PlayStrategy>& playStrategy) override;
60     Status GetStreamInfo(std::vector<StreamInfo>& streams) override;
61 
62     void OnMpdInfoUpdate(DashMpdEvent mpdEvent) override;
63     void OnDrmInfoChanged(const std::multimap<std::string, std::vector<uint8_t>>& drmInfos) override;
64     void UpdateDownloadFinished(int streamId);
65     void SetInterruptState(bool isInterruptNeeded) override;
66     Status SetCurrentBitRate(int32_t bitRate, int32_t streamID) override;
67     void SetDemuxerState(int32_t streamId) override;
68     void GetPlaybackInfo(PlaybackInfo& playbackInfo) override;
69     size_t GetBufferSize() const override;
70     void SetAppUid(int32_t appUid) override;
71     bool GetPlayable() override;
72     bool GetBufferingTimeOut() override;
73 
74 private:
75     void ReceiveMpdStreamInitEvent();
76     void ReceiveMpdParseOkEvent();
77     void VideoSegmentDownloadFinished(int streamId);
78     void GetSegmentToDownload(int downloadStreamId, bool streamSwitchFlag);
79     void CleanVideoSegmentBuffer(bool &bufferCleanFlag, int64_t &remainLastNumberSeq);
80     bool SelectBitrateInternal(bool bufferCleanFlag, int64_t remainLastNumberSeq);
81     bool CheckAutoSelectBitrate(int streamId);
82     uint32_t GetNextBitrate(std::shared_ptr<DashSegmentDownloader> segmentDownloader);
83     bool AutoSelectBitrateInternal(uint32_t bitrate);
84     bool IsSeekingInSwitch();
85     void SeekInternal(int64_t seekTimeMs);
86     Status SelectAudio(const std::shared_ptr<DashStreamDescription> &streamDesc);
87     Status SelectAudioInternal(const std::shared_ptr<DashStreamDescription> &streamDesc);
88     Status SelectSubtitle(const std::shared_ptr<DashStreamDescription> &streamDesc);
89     Status SelectSubtitleInternal(const std::shared_ptr<DashStreamDescription> &streamDesc);
90     bool DoPreparedSwitchBitrate(bool switchBitrateOk, bool &needDownload, int &streamId);
91     bool DoPreparedSwitchAudio(int &streamId);
92     bool DoPreparedSwitchSubtitle(int &streamId);
93     bool DoPreparedSwitchAction(bool switchBitrateOk, bool switchAudioOk, bool switchSubtitleOk, int &streamId);
94     bool DoPreparedAction(int &streamId);
95     void UpdateSegmentIndexAfterSidxParseOk();
96     void ResetBitrateParam();
97     void ResetTrackParam();
98     std::shared_ptr<DashSegmentDownloader> GetSegmentDownloader(int32_t streamId);
99     std::shared_ptr<DashSegmentDownloader> GetSegmentDownloaderByType(MediaAVCodec::MediaType type) const;
100     void OpenInitSegment(const std::shared_ptr<DashStreamDescription> &streamDesc,
101                          const std::shared_ptr<DashSegment> &seg);
102     void HandleSeekReady(int32_t streamType, int32_t streamId, int32_t isEos);
103 
104 private:
105 
106     Callback* callback_ {nullptr};
107     StatusCallbackFunc statusCallback_ {nullptr};
108 
109     std::shared_ptr<DashMpdDownloader> mpdDownloader_ {nullptr};
110     std::vector<std::shared_ptr<DashSegmentDownloader>> segmentDownloaders_;
111 
112     std::atomic<bool> isInterruptNeeded_{false};
113     bool isAutoSelectBitrate_ {true};
114     bool downloadErrorState_ {false};
115     int64_t breakpoint_ {0};
116     DashMpdBitrateParam bitrateParam_;
117     DashMpdTrackParam trackParam_;
118     DashPreparedAction preparedAction_;
119     std::mutex switchMutex_;
120     std::mutex parseSidxMutex_;
121     uint64_t expectDuration_{0};
122 };
123 }
124 }
125 }
126 }
127 #endif