• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_HLS_MEDIA_DOWNLOADER_H
17 #define HISTREAMER_HLS_MEDIA_DOWNLOADER_H
18 
19 #include <mutex>
20 #include <thread>
21 #include "playlist_downloader.h"
22 #include "download/downloader.h"
23 #include "media_downloader.h"
24 #include "osal/utils/ring_buffer.h"
25 #include "osal/utils/steady_clock.h"
26 #include "openssl/aes.h"
27 #include "osal/task/task.h"
28 #include "common/media_source.h"
29 #include <unistd.h>
30 #include "common/media_core.h"
31 #include "utils/media_cached_buffer.h"
32 #include "utils/write_bitrate_caculator.h"
33 #include <utility>
34 #include "osal/task/mutex.h"
35 #include "osal/task/condition_variable.h"
36 
37 namespace OHOS {
38 namespace Media {
39 namespace Plugins {
40 namespace HttpPlugin {
41 
42 enum BufferingTimes : int32_t {
43     FIRST_TIMES = 1,
44     SECOND_TIMES = 2,
45 };
46 
47 enum SLEEP_TIME : int32_t {
48     REQUEST_SLEEP_TIME = 5, // 5ms
49     BUFFERING_SLEEP_TIME = 10, // 10ms
50     CACHE_DATA_SLEEP_TIME = 100, // 100ms
51     BUFFERING_TIME_OUT = 1000, // 100ms
52 };
53 constexpr size_t MIN_BUFFER_SIZE = 5 * 1024 * 1024;
54 
55 class HlsMediaDownloader : public MediaDownloader, public PlayListChangeCallback {
56 public:
57     explicit HlsMediaDownloader(
58         const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>()) noexcept;
59     explicit HlsMediaDownloader(int expectBufferDuration,
60         const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>());
61     explicit HlsMediaDownloader(std::string mimeType,
62         const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>());
63     ~HlsMediaDownloader() override;
64     bool Open(const std::string& url, const std::map<std::string, std::string>& httpHeader) override;
65     void Close(bool isAsync) override;
66     void Pause() override;
67     void Resume() override;
68     Status Read(unsigned char* buff, ReadDataInfo& readDataInfo) override;
69     bool SeekToTime(int64_t seekTime, SeekMode mode) override;
70 
71     size_t GetContentLength() const override;
72     int64_t GetDuration() const override;
73     Seekable GetSeekable() const override;
74     void SetCallback(Callback* cb) override;
75     void OnPlayListChanged(const std::vector<PlayInfo>& playList) override;
76     void SetStatusCallback(StatusCallbackFunc cb) override;
77     bool GetStartedStatus() override;
78     std::vector<uint32_t> GetBitRates() override;
79     bool SelectBitRate(uint32_t bitRate) override;
80     void OnSourceKeyChange(const uint8_t *key, size_t keyLen, const uint8_t *iv) override;
81     void OnDrmInfoChanged(const std::multimap<std::string, std::vector<uint8_t>>& drmInfos) override;
82     void SetIsTriggerAutoMode(bool isAuto) override;
83     void SetReadBlockingFlag(bool isReadBlockingAllowed) override;
84     void SeekToTs(uint64_t seekTime, SeekMode mode);
85     void PutRequestIntoDownloader(const PlayInfo& playInfo);
86     int64_t RequestNewTs(uint64_t seekTime, SeekMode mode, double totalDuration,
87         double hstTime, const PlayInfo& item);
88     void UpdateDownloadFinished(const std::string &url, const std::string& location);
89     void AutoSelectBitrate(uint32_t bitRate);
90     size_t GetTotalBufferSize();
91     void SetInterruptState(bool isInterruptNeeded) override;
92     void GetPlaybackInfo(PlaybackInfo& playbackInfo) override;
93     void ReportBitrateStart(uint32_t bitRate);
94     std::pair<int32_t, int32_t> GetDownloadRateAndSpeed();
95     void GetDownloadInfo(DownloadInfo& downloadInfo) override;
96     std::pair<int32_t, int32_t> GetDownloadInfo() override;
97     void ReportVideoSizeChange();
98     Status SetCurrentBitRate(int32_t bitRate, int32_t streamID) override;
99     size_t GetBufferSize() const override;
100     bool GetPlayable() override;
101     bool GetBufferingTimeOut() override;
102     void SetAppUid(int32_t appUid) override;
103     size_t GetSegmentOffset() override;
104     bool GetHLSDiscontinuity() override;
105     void WaitForBufferingEnd() override;
106 
107 private:
108     void SaveHttpHeader(const std::map<std::string, std::string>& httpHeader);
109     void SetDemuxerState(int32_t streamId) override;
110     void SetDownloadErrorState() override;
111     bool SaveData(uint8_t* data, uint32_t len);
112     Status ReadDelegate(unsigned char* buff, ReadDataInfo& readDataInfo);
113     void ReadCacheBuffer(unsigned char* buff, ReadDataInfo& readDataInfo);
114     bool SaveEncryptData(uint8_t* data, uint32_t len);
115     void InitMediaDownloader();
116     void DownloadRecordHistory(int64_t nowTime);
117     void OnWriteCacheBuffer(uint32_t len);
118     void OnReadBuffer(uint32_t len);
119     double GetAveDownSpeed();
120     uint64_t GetMinBuffer();
121     void DownloadReport();
122     void ReportDownloadSpeed();
123     bool CheckRiseBufferSize();
124     bool CheckPulldownBufferSize();
125 
126     void RiseBufferSize();
127     void DownBufferSize();
128     void ActiveAutoBufferSize();
129     void InActiveAutoBufferSize();
130     uint64_t TransferSizeToBitRate(int width);
131     bool HandleBuffering();
132     bool HandleCache();
133     bool CheckReadStatus();
134     Status CheckPlaylist(unsigned char* buff, ReadDataInfo& readDataInfo);
135     bool CheckBreakCondition();
136     uint32_t GetDecrptyRealLen(uint8_t* writeDataPoint, uint32_t waitLen, uint32_t writeLen);
137     void ResetPlaylistCapacity(size_t size);
138     void PlaylistBackup(const PlayInfo& fragment);
139     void HandleCachedDuration();
140     void UpdateWaterLineAbove();
141     void CalculateBitRate(size_t fragmentSize, double duration);
142     double CalculateCurrentDownloadSpeed();
143     void UpdateCachedPercent(BufferingInfoType infoType);
144     bool CheckBufferingOneSeconds();
145     float GetCacheDuration(float ratio);
146     void HandleFfmpegReadback(uint64_t ffmpegOffset);
147     void SeekToTsForRead(uint32_t currentTsIndex);
148     int64_t RequestNewTsForRead(const PlayInfo& item);
149     void PushPlayInfo(PlayInfo playInfo);
150     void PrepareToSeek();
151     bool CheckDataIntegrity();
152     void HlsInit();
153     bool SaveCacheBufferData(uint8_t* data, uint32_t len);
154     bool ClearChunksOfFragment();
155     size_t GetCrossTsBuffersize();
156 
157 private:
158     size_t totalBufferSize_ {0};
159     std::shared_ptr<Downloader> downloader_;
160     std::shared_ptr<DownloadRequest> downloadRequest_;
161     Callback* callback_ {nullptr};
162     DataSaveFunc dataSave_;
163     StatusCallbackFunc statusCallback_;
164     bool startedPlayStatus_ {false};
165 
166     std::shared_ptr<PlayListDownloader> playlistDownloader_;
167 
168     std::shared_ptr<BlockingQueue<PlayInfo>> playList_;
169     std::map<std::string, bool> fragmentDownloadStart;
170     std::map<std::string, bool> fragmentPushed;
171     std::deque<PlayInfo> backPlayList_;
172     bool isSelectingBitrate_ {false};
173     bool isDownloadStarted_ {false};
174     static constexpr uint64_t DECRYPT_UNIT_LEN = 16;
175     uint8_t afterAlignRemainedBuffer_[DECRYPT_UNIT_LEN] {0};
176     uint64_t afterAlignRemainedLength_ = 0;
177     uint64_t totalLen_ = 0;
178     std::string curUrl_;
179     uint8_t key_[16] = {0};
180     size_t keyLen_ {0};
181     uint8_t iv_[16] = {0};
182     AES_KEY aesKey_;
183     uint8_t decryptCache_[MIN_BUFFER_SIZE] {0};
184     uint8_t decryptBuffer_[MIN_BUFFER_SIZE] {0};
185     uint32_t writeTsIndex_ = 0;
186     bool isAutoSelectBitrate_ {true};
187     uint64_t seekTime_ = 0;
188 
189     uint64_t readTime_ {0};
190 
191     bool isReadFrame_ {false};
192     bool isTimeOut_ {false};
193     bool downloadErrorState_ {false};
194     uint64_t bufferedDuration_ {0};
195     uint64_t currentBitrate_ {1 * 1024 * 1024}; // bps
196     bool userDefinedBufferDuration_ {false};
197     uint64_t expectDuration_ {0};
198     bool autoBufferSize_ {true}; // 默认为false
199     uint64_t lastCheckTime_ {0};
200     uint32_t recordCount_ {0};
201     uint64_t lastRecordTime_ {0};
202     std::atomic<bool> isInterruptNeeded_{false};
203 
204     struct BufferDownRecord {
205         /* data */
206         uint64_t dataBits {0};
207         uint64_t timeoff {0};
208         BufferDownRecord* next {nullptr};
209     };
210     // std::unique_ptr<BufferDownRecord> bufferDownRecord_;
211     BufferDownRecord* bufferDownRecord_ {nullptr};
212     // buffer least
213     struct BufferLeastRecord {
214         uint64_t minDuration {0};
215         BufferLeastRecord* next {nullptr};
216     };
217     // std::unique_ptr<BufferLeastRecord> bufferLeastRecord_;
218     BufferLeastRecord* bufferLeastRecord_ {nullptr};
219     uint64_t lastWriteTime_ {0};
220     uint64_t lastReadTime_ {0};
221     uint64_t lastWriteBit_ {0};
222     SteadyClock steadyClock_;
223 
224     uint64_t totalBits_ {0};        // 总下载量
225 
226     uint64_t lastBits_ {0};         // 上一统计周期的总下载量
227 
228     uint64_t downloadDuringTime_ {0};    // 累计有效下载时长 ms
229 
230     uint64_t downloadBits_ {0};          // 累计有效时间内下载数据量 bit
231     uint32_t changeBitRateCount_ {0};  // 设置码率次数
232     int32_t seekFailedCount_ {0};   // seek失败次数
233     int64_t openTime_ {0};
234     int64_t playDelayTime_ {0};
235     int64_t startDownloadTime_ {0};
236     int32_t avgDownloadSpeed_ {0};
237     bool isDownloadFinish_ {false};
238     double avgSpeedSum_ {0};
239     uint32_t recordSpeedCount_ {0};
240 
241     int64_t lastReportUsageTime_ {0};
242     uint64_t dataUsage_ {0};
243 
244     struct RecordData {
245         double downloadRate {0};
246         uint64_t bufferDuring {0};
247         std::shared_ptr<RecordData> next {nullptr};
248     };
249     std::shared_ptr<RecordData> recordData_ {nullptr};
250     std::map<std::string, std::string> httpHeader_ {};
251     std::atomic<bool> isStopped = false;
252     std::string mimeType_;
253     size_t waterLineAbove_ {0};
254     bool isInterrupt_ {false};
255     std::atomic<bool> isBuffering_ {false};
256     bool isFirstFrameArrived_ {false};
257     std::atomic<bool> isSeekingFlag {false};
258     Mutex switchMutex_ {};
259     bool isLastDecryptWriteError_ {false};
260     uint32_t lastRealLen_ {0};
261 
262     uint64_t lastReadCheckTime_ = 0;
263     uint64_t readTotalBytes_ = 0;
264     uint64_t readRecordDuringTime_ = 0;
265     uint64_t totalDownloadDuringTime_ {0};
266     uint32_t currentBitRate_ {0};
267     int32_t fragmentBitRate_ {0};
268     uint64_t lastDurationReacord_ {0};
269     int32_t lastCachedSize_ {0};
270     std::atomic<bool> isBufferingStart_ {false};
271     std::shared_ptr<CacheMediaChunkBufferImpl> cacheMediaBuffer_;
272     uint64_t readOffset_ {0};
273     uint64_t writeOffset_ {0};
274     std::map<uint32_t, std::pair<uint32_t, bool>> tsStorageInfo_ {};
275     std::atomic<uint32_t> readTsIndex_ {0};
276     std::atomic<bool> canWrite_ {true};
277     uint64_t ffmpegOffset_ = 0;
278     volatile size_t wantedReadLength_ {0};
279     volatile size_t bufferingTime_ {0};
280     FairMutex tsStorageInfoMutex_ {};
281 
282     std::shared_ptr<WriteBitrateCaculator> writeBitrateCaculator_;
283 
284     FairMutex bufferingEndMutex_ {};
285     ConditionVariable bufferingEndCond_;
286 };
287 }
288 }
289 }
290 }
291 #endif