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 #define HST_LOG_TAG "HttpMediaDownloader"
16 
17 #include "http/http_media_downloader.h"
18 #include <arpa/inet.h>
19 #include <netdb.h>
20 #include <regex>
21 #include "network/network_typs.h"
22 #include "common/media_core.h"
23 #include "avcodec_trace.h"
24 
25 namespace OHOS {
26 namespace Media {
27 namespace Plugins {
28 namespace HttpPlugin {
29 namespace {
30 #ifdef OHOS_LITE
31 constexpr int RING_BUFFER_SIZE = 5 * 48 * 1024;
32 constexpr int WATER_LINE = RING_BUFFER_SIZE / 30; // 30 WATER_LINE:8192
33 #else
34 constexpr int RING_BUFFER_SIZE = 5 * 1024 * 1024;
35 constexpr int MAX_BUFFER_SIZE = 19 * 1024 * 1024;
36 constexpr int WATER_LINE = 8192; //  WATER_LINE:8192
37 constexpr int CURRENT_BIT_RATE = 1 * 1024 * 1024;
38 #endif
39 constexpr uint32_t SAMPLE_INTERVAL = 1000; // Sample time interval, ms
40 constexpr int START_PLAY_WATER_LINE = 512 * 1024;
41 constexpr int DATA_USAGE_NTERVAL = 300 * 1000;
42 constexpr double ZERO_THRESHOLD = 1e-9;
43 constexpr size_t PLAY_WATER_LINE = 5 * 1024;
44 constexpr size_t DEFAULT_WATER_LINE_ABOVE = 48 * 10 * 1024;
45 constexpr int FIVE_MICROSECOND = 5;
46 constexpr int ONE_HUNDRED_MILLIONSECOND = 100;
47 constexpr int32_t SAVE_DATA_LOG_FREQUENCE = 50;
48 constexpr int IS_DOWNLOAD_MIN_BIT = 100;
49 constexpr uint32_t DURATION_CHANGE_AMOUT_MILLIONSECOND = 500;
50 constexpr int32_t DEFAULT_BIT_RATE = 1638400;
51 constexpr int UPDATE_CACHE_STEP = 5 * 1024;
52 constexpr size_t MIN_WATER_LINE_ABOVE = 10 * 1024;
53 constexpr int32_t ONE_SECONDS = 1000;
54 constexpr int32_t TWO_SECONDS = 2000;
55 constexpr int32_t TEN_MILLISECONDS = 10;
56 constexpr float WATER_LINE_ABOVE_LIMIT_RATIO = 0.6;
57 constexpr float CACHE_LEVEL_1 = 0.3;
58 constexpr float DEFAULT_CACHE_TIME = 5;
59 constexpr size_t MAX_BUFFERING_TIME_OUT = 30 * 1000;
60 constexpr size_t MAX_WATER_LINE_ABOVE = 8 * 1024 * 1024;
61 constexpr uint32_t OFFSET_NOT_UPDATE_THRESHOLD = 8;
62 constexpr float DOWNLOAD_WATER_LINE_RATIO = 0.90;
63 constexpr uint32_t ALLOW_SEEK_MIN_SIZE = 1 * 1024 * 1024;
64 constexpr uint64_t ALLOW_CLEAR_MIDDLE_DATA_MIN_SIZE = 2 * 1024 * 1024;
65 constexpr size_t AUDIO_WATER_LINE_ABOVE = 16 * 1024;
66 constexpr uint32_t CLEAR_SAVE_DATA_SIZE = 1 * 1024 * 1024;
67 constexpr size_t LARGE_OFFSET_SPAN_THRESHOLD = 10 * 1024 * 1024;
68 constexpr int32_t STATE_CHANGE_THRESHOLD = 2;
69 constexpr size_t LARGE_VIDEO_THRESHOLD = 18 * 1024 * 1024;
70 }
71 
HttpMediaDownloader(std::string url)72 HttpMediaDownloader::HttpMediaDownloader(std::string url)
73 {
74     if (static_cast<int32_t>(url.find(".flv")) != -1) {
75         MEDIA_LOG_I("HTTP isflv.");
76         isRingBuffer_ = true;
77     }
78 
79     if (isRingBuffer_) {
80         ringBuffer_ = std::make_shared<RingBuffer>(RING_BUFFER_SIZE);
81         ringBuffer_->Init();
82     } else {
83         cacheMediaBuffer_ = std::make_shared<CacheMediaChunkBufferImpl>();
84         cacheMediaBuffer_->Init(MAX_CACHE_BUFFER_SIZE, CHUNK_SIZE);
85         totalBufferSize_ = MAX_CACHE_BUFFER_SIZE;
86         MEDIA_LOG_I("HTTP setting buffer size: " PUBLIC_LOG_U64, MAX_CACHE_BUFFER_SIZE);
87     }
88     isBuffering_ = true;
89     bufferingTime_ = static_cast<size_t>(steadyClock_.ElapsedMilliseconds());
90     downloader_ = std::make_shared<Downloader>("http");
91     writeBitrateCaculator_ = std::make_shared<WriteBitrateCaculator>();
92     steadyClock_.Reset();
93     waterLineAbove_ = PLAY_WATER_LINE;
94     recordData_ = std::make_shared<RecordData>();
95 }
96 
InitRingBuffer(uint32_t expectBufferDuration)97 void HttpMediaDownloader::InitRingBuffer(uint32_t expectBufferDuration)
98 {
99     int totalBufferSize = CURRENT_BIT_RATE * static_cast<int32_t>(expectBufferDuration);
100     if (totalBufferSize < RING_BUFFER_SIZE) {
101         MEDIA_LOG_I("HTTP Failed setting ring buffer size: " PUBLIC_LOG_D32 ". already lower than the min buffer size: "
102         PUBLIC_LOG_D32 ", setting buffer size: " PUBLIC_LOG_D32 ". ",
103         totalBufferSize, RING_BUFFER_SIZE, RING_BUFFER_SIZE);
104         ringBuffer_ = std::make_shared<RingBuffer>(RING_BUFFER_SIZE);
105         totalBufferSize_ = RING_BUFFER_SIZE;
106     } else if (totalBufferSize > MAX_BUFFER_SIZE) {
107         MEDIA_LOG_I("HTTP Failed setting ring buffer size: " PUBLIC_LOG_D32 ". already exceed the max buffer size: "
108         PUBLIC_LOG_D32 ", setting buffer size: " PUBLIC_LOG_D32 ". ",
109         totalBufferSize, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
110         ringBuffer_ = std::make_shared<RingBuffer>(MAX_BUFFER_SIZE);
111         totalBufferSize_ = MAX_BUFFER_SIZE;
112     } else {
113         ringBuffer_ = std::make_shared<RingBuffer>(totalBufferSize);
114         totalBufferSize_ = totalBufferSize;
115         MEDIA_LOG_I("HTTP Success setted ring buffer size: " PUBLIC_LOG_D32, totalBufferSize);
116     }
117     ringBuffer_->Init();
118 }
119 
InitCacheBuffer(uint32_t expectBufferDuration)120 void HttpMediaDownloader::InitCacheBuffer(uint32_t expectBufferDuration)
121 {
122     int totalBufferSize = CURRENT_BIT_RATE * static_cast<int32_t>(expectBufferDuration);
123     cacheMediaBuffer_ = std::make_shared<CacheMediaChunkBufferImpl>();
124     if (totalBufferSize < RING_BUFFER_SIZE) {
125         MEDIA_LOG_I("HTTP Failed setting cache buffer size: " PUBLIC_LOG_D32
126                     ". already lower than the min buffer size: " PUBLIC_LOG_D32
127                     ", setting buffer size: " PUBLIC_LOG_D32 ". ", totalBufferSize,
128                     RING_BUFFER_SIZE, RING_BUFFER_SIZE);
129         cacheMediaBuffer_->Init(RING_BUFFER_SIZE, CHUNK_SIZE);
130         totalBufferSize_ = RING_BUFFER_SIZE;
131     } else if (totalBufferSize > MAX_BUFFER_SIZE) {
132         MEDIA_LOG_I("HTTP Failed setting cache buffer size: " PUBLIC_LOG_D32 ". already exceed the max buffer size: "
133         PUBLIC_LOG_D32 ", setting buffer size: " PUBLIC_LOG_D32 ". ",
134         totalBufferSize, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
135         cacheMediaBuffer_->Init(MAX_BUFFER_SIZE, CHUNK_SIZE);
136         totalBufferSize_ = MAX_BUFFER_SIZE;
137     } else {
138         cacheMediaBuffer_->Init(totalBufferSize, CHUNK_SIZE);
139         totalBufferSize_ = totalBufferSize;
140         MEDIA_LOG_I("HTTP Success setted cache buffer size: " PUBLIC_LOG_D32, totalBufferSize);
141     }
142 }
143 
HttpMediaDownloader(std::string url,uint32_t expectBufferDuration)144 HttpMediaDownloader::HttpMediaDownloader(std::string url, uint32_t expectBufferDuration)
145 {
146     if (static_cast<int32_t>(url.find(".flv")) != -1) {
147         MEDIA_LOG_I("HTTP isflv.");
148         isRingBuffer_ = true;
149     }
150     if (isRingBuffer_) {
151         InitRingBuffer(expectBufferDuration);
152     } else {
153         InitCacheBuffer(expectBufferDuration);
154     }
155     isBuffering_ = true;
156     bufferingTime_ = static_cast<size_t>(steadyClock_.ElapsedMilliseconds());
157     downloader_ = std::make_shared<Downloader>("http");
158     writeBitrateCaculator_ = std::make_shared<WriteBitrateCaculator>();
159     steadyClock_.Reset();
160     waterLineAbove_ = PLAY_WATER_LINE;
161     recordData_ = std::make_shared<RecordData>();
162 }
163 
~HttpMediaDownloader()164 HttpMediaDownloader::~HttpMediaDownloader()
165 {
166     MEDIA_LOG_I("0x%{public}06" PRIXPTR " ~HttpMediaDownloader dtor", FAKE_POINTER(this));
167     Close(false);
168 }
169 
Open(const std::string & url,const std::map<std::string,std::string> & httpHeader)170 bool HttpMediaDownloader::Open(const std::string& url, const std::map<std::string, std::string>& httpHeader)
171 {
172     MEDIA_LOG_I("HTTP Open download");
173     isDownloadFinish_ = false;
174     openTime_ = steadyClock_.ElapsedMilliseconds();
175     auto saveData =  [this] (uint8_t*&& data, uint32_t&& len) {
176         return SaveData(std::forward<decltype(data)>(data), std::forward<decltype(len)>(len));
177     };
178     FALSE_RETURN_V(statusCallback_ != nullptr, false);
179     auto realStatusCallback = [this] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
180                                   std::shared_ptr<DownloadRequest>& request) {
181         if (isRingBuffer_ && callback_ && request->GetFileContentLengthNoWait() == 0) {
182             callback_->OnEvent({PluginEventType::CLIENT_ERROR, {NetworkClientErrorCode::ERROR_TIME_OUT}, "read"});
183             return;
184         }
185         statusCallback_(status, downloader_, std::forward<decltype(request)>(request));
186     };
187     auto downloadDoneCallback = [this] (const std::string &url, const std::string& location) {
188         if (downloadRequest_ != nullptr && downloadRequest_->IsEos()
189             && (totalBits_ / BYTES_TO_BIT) >= downloadRequest_->GetFileContentLengthNoWait()) {
190             isDownloadFinish_ = true;
191         }
192         int64_t nowTime = steadyClock_.ElapsedMilliseconds();
193         double downloadTime = (static_cast<double>(nowTime) - static_cast<double>(startDownloadTime_)) /
194             SECOND_TO_MILLIONSECOND;
195         if (downloadTime > ZERO_THRESHOLD) {
196             avgDownloadSpeed_ = totalBits_ / downloadTime;
197         }
198         MEDIA_LOG_D("HTTP Download done, average download speed: " PUBLIC_LOG_D32 " bit/s",
199             static_cast<int32_t>(avgDownloadSpeed_));
200         MEDIA_LOG_I("HTTP Download done, data usage: " PUBLIC_LOG_U64 " bits in " PUBLIC_LOG_D64 "ms",
201             totalBits_, static_cast<int64_t>(downloadTime * SECOND_TO_MILLIONSECOND));
202         HandleBuffering();
203     };
204     RequestInfo requestInfo;
205     requestInfo.url = url;
206     requestInfo.httpHeader = httpHeader;
207     downloadRequest_ = std::make_shared<DownloadRequest>(saveData, realStatusCallback, requestInfo);
208     downloadRequest_->SetDownloadDoneCb(downloadDoneCallback);
209     downloader_->Download(downloadRequest_, -1); // -1
210     if (isRingBuffer_) {
211         ringBuffer_->SetMediaOffset(0);
212     }
213 
214     writeBitrateCaculator_->StartClock();
215     downloader_->Start();
216     return true;
217 }
218 
Close(bool isAsync)219 void HttpMediaDownloader::Close(bool isAsync)
220 {
221     if (isRingBuffer_) {
222         ringBuffer_->SetActive(false);
223     }
224     isInterrupt_ = true;
225     if (downloader_) {
226         downloader_->Stop(isAsync);
227     }
228     cvReadWrite_.NotifyOne();
229     if (!isDownloadFinish_) {
230         int64_t nowTime = steadyClock_.ElapsedMilliseconds();
231         double downloadTime = (static_cast<double>(nowTime) - static_cast<double>(startDownloadTime_)) /
232             SECOND_TO_MILLIONSECOND;
233         if (downloadTime > ZERO_THRESHOLD) {
234             avgDownloadSpeed_ = totalBits_ / downloadTime;
235         }
236         MEDIA_LOG_D("HTTP Download close, average download speed: " PUBLIC_LOG_D32 " bit/s",
237             static_cast<int32_t>(avgDownloadSpeed_));
238         MEDIA_LOG_D("HTTP Download close, data usage: " PUBLIC_LOG_U64 " bits in " PUBLIC_LOG_D64 "ms",
239             totalBits_, static_cast<int64_t>(downloadTime * SECOND_TO_MILLIONSECOND));
240     }
241 }
242 
Pause()243 void HttpMediaDownloader::Pause()
244 {
245     if (isRingBuffer_) {
246         bool cleanData = GetSeekable() != Seekable::SEEKABLE;
247         ringBuffer_->SetActive(false, cleanData);
248     }
249     isInterrupt_ = true;
250     downloader_->Pause();
251     cvReadWrite_.NotifyOne();
252 }
253 
Resume()254 void HttpMediaDownloader::Resume()
255 {
256     if (isRingBuffer_) {
257         ringBuffer_->SetActive(true);
258     }
259     isInterrupt_ = false;
260     downloader_->Resume();
261     cvReadWrite_.NotifyOne();
262 }
263 
OnClientErrorEvent()264 void HttpMediaDownloader::OnClientErrorEvent()
265 {
266     if (callback_ != nullptr) {
267         MEDIA_LOG_I("HTTP Read time out, OnEvent");
268         callback_->OnEvent({PluginEventType::CLIENT_ERROR, {NetworkClientErrorCode::ERROR_TIME_OUT}, "read"});
269     }
270 }
271 
HandleBuffering()272 bool HttpMediaDownloader::HandleBuffering()
273 {
274     if (!isBuffering_ || downloadRequest_->IsChunkedVod()) {
275         bufferingTime_ = 0;
276         return false;
277     }
278     size_t fileRemain = 0;
279     if (downloadRequest_ != nullptr) {
280         size_t fileContenLen = downloadRequest_->GetFileContentLength();
281         if (fileContenLen > readOffset_) {
282             fileRemain = fileContenLen - readOffset_;
283             waterLineAbove_ = std::min(fileRemain, waterLineAbove_);
284         }
285     }
286     UpdateWaterLineAbove();
287     UpdateCachedPercent(BufferingInfoType::BUFFERING_PERCENT);
288     {
289         AutoLock lk(bufferingEndMutex_);
290         if (!canWrite_) {
291             MEDIA_LOG_I("HTTP canWrite_ false");
292             isBuffering_ = false;
293         }
294         if (GetCurrentBufferSize() >= waterLineAbove_) {
295             MEDIA_LOG_I("HTTP Buffer is enough, bufferSize:" PUBLIC_LOG_ZU " waterLineAbove: " PUBLIC_LOG_ZU
296                 " avgDownloadSpeed: " PUBLIC_LOG_F, GetCurrentBufferSize(), waterLineAbove_, avgDownloadSpeed_);
297             isBuffering_ = false;
298         }
299         if (HandleBreak()) {
300             isBuffering_ = false;
301         }
302         if (!isBuffering_) {
303             MEDIA_LOG_I("HandleBuffering bufferingEndCond NotifyAll.");
304             bufferingEndCond_.NotifyAll();
305         }
306     }
307     if (!isBuffering_ && !isFirstFrameArrived_) {
308         bufferingTime_ = 0;
309     }
310     if (!isBuffering_ && isFirstFrameArrived_ && callback_ != nullptr) {
311         MEDIA_LOG_I("HTTP CacheData onEvent BUFFERING_END, bufferSize: " PUBLIC_LOG_ZU ", waterLineAbove_: "
312         PUBLIC_LOG_ZU ", isBuffering: " PUBLIC_LOG_D32 ", canWrite: " PUBLIC_LOG_D32,
313             GetCurrentBufferSize(), waterLineAbove_, isBuffering_.load(), canWrite_.load());
314         UpdateCachedPercent(BufferingInfoType::BUFFERING_END);
315         callback_->OnEvent({PluginEventType::BUFFERING_END, {BufferingInfoType::BUFFERING_END}, "end"});
316         bufferingTime_ = 0;
317     }
318     MEDIA_LOG_D("HTTP HandleBuffering bufferSize: " PUBLIC_LOG_ZU ", waterLineAbove_: " PUBLIC_LOG_ZU
319         ", isBuffering: " PUBLIC_LOG_D32 ", canWrite: " PUBLIC_LOG_D32,
320         GetCurrentBufferSize(), waterLineAbove_, isBuffering_.load(), canWrite_.load());
321     return isBuffering_.load();
322 }
323 
StartBufferingCheck(unsigned int & wantReadLength)324 bool HttpMediaDownloader::StartBufferingCheck(unsigned int& wantReadLength)
325 {
326     if (!isFirstFrameArrived_) {
327         if (GetCurrentBufferSize() >= wantReadLength || HandleBreak()) {
328             MEDIA_LOG_I("HTTP buffersize is ok.");
329             return false;
330         } else {
331             waterLineAbove_ = wantReadLength;
332             return true;
333         }
334     }
335     if (HandleBreak() || isBuffering_) {
336         return false;
337     }
338     if (!isRingBuffer_ && cacheMediaBuffer_ != nullptr && !isLargeOffsetSpan_ &&
339         cacheMediaBuffer_->IsReadSplit(readOffset_) && isNeedClearHasRead_) {
340         MEDIA_LOG_I("HTTP IsReadSplit, StartBuffering return, readOffset_ " PUBLIC_LOG_ZU, readOffset_);
341         wantReadLength = std::min(static_cast<size_t>(wantReadLength), GetCurrentBufferSize());
342         return false;
343     }
344     size_t cacheWaterLine = 0;
345     size_t fileRemain = 0;
346     size_t fileContenLen = downloadRequest_->GetFileContentLength();
347     cacheWaterLine = std::max(static_cast<size_t>(wantReadLength), PLAY_WATER_LINE);
348     if (fileContenLen > readOffset_) {
349         fileRemain = fileContenLen - readOffset_;
350         cacheWaterLine = std::min(fileRemain, cacheWaterLine);
351     }
352     if (GetCurrentBufferSize() >= cacheWaterLine) {
353         return false;
354     }
355     if (!canWrite_.load() && GetCurrentBufferSize() >= wantReadLength) {
356         return false;
357     }
358     return true;
359 }
360 
StartBuffering(unsigned int & wantReadLength)361 bool HttpMediaDownloader::StartBuffering(unsigned int& wantReadLength)
362 {
363     if (!StartBufferingCheck(wantReadLength)) {
364         return false;
365     }
366     if (!canWrite_.load()) { // Clear cacheBuffer when we can neither read nor write.
367         ClearCacheBuffer();
368         canWrite_ = true;
369     }
370     isBuffering_ = true;
371     bufferingTime_ = static_cast<size_t>(steadyClock_.ElapsedMilliseconds());
372     if (!isFirstFrameArrived_) {
373         return true;
374     }
375     MEDIA_LOG_I("HTTP CacheData OnEvent BUFFERING_START, waterLineAbove: " PUBLIC_LOG_ZU " bufferSize "
376         PUBLIC_LOG_ZU " readOffset: " PUBLIC_LOG_ZU " writeOffset: " PUBLIC_LOG_ZU, waterLineAbove_,
377         GetCurrentBufferSize(), readOffset_, writeOffset_);
378     callback_->OnEvent({PluginEventType::BUFFERING_START, {BufferingInfoType::BUFFERING_START}, "start"});
379     UpdateCachedPercent(BufferingInfoType::BUFFERING_START);
380     return true;
381 }
382 
ReadRingBuffer(unsigned char * buff,ReadDataInfo & readDataInfo)383 Status HttpMediaDownloader::ReadRingBuffer(unsigned char* buff, ReadDataInfo& readDataInfo)
384 {
385     size_t fileContentLength = downloadRequest_->GetFileContentLength();
386     uint64_t mediaOffset = ringBuffer_->GetMediaOffset();
387     if (fileContentLength > mediaOffset) {
388         uint64_t remain = fileContentLength - mediaOffset;
389         readDataInfo.wantReadLength_ = remain < readDataInfo.wantReadLength_ ? remain :
390             readDataInfo.wantReadLength_;
391     }
392     readDataInfo.realReadLength_ = 0;
393     wantedReadLength_ = static_cast<size_t>(readDataInfo.wantReadLength_);
394     while (ringBuffer_->GetSize() < readDataInfo.wantReadLength_ && !isInterruptNeeded_.load()) {
395         if (downloadRequest_ != nullptr) {
396             readDataInfo.isEos_ = downloadRequest_->IsEos();
397         }
398         if (readDataInfo.isEos_) {
399             return CheckIsEosRingBuffer(buff, readDataInfo);
400         }
401         bool isClosed = downloadRequest_->IsClosed();
402         if (isClosed && ringBuffer_->GetSize() == 0) {
403             MEDIA_LOG_I("HttpMediaDownloader read return, isClosed: " PUBLIC_LOG_D32, isClosed);
404             readDataInfo.realReadLength_ = 0;
405             return Status::END_OF_STREAM;
406         }
407         Task::SleepInTask(FIVE_MICROSECOND);
408     }
409     if (isInterruptNeeded_.load()) {
410         readDataInfo.realReadLength_ = 0;
411         return Status::END_OF_STREAM;
412     }
413     readDataInfo.realReadLength_ = ringBuffer_->ReadBuffer(buff, readDataInfo.wantReadLength_, 2);  // wait 2 times
414     MEDIA_LOG_D("HTTP ReadRingBuffer: wantReadLength " PUBLIC_LOG_D32 ", realReadLength " PUBLIC_LOG_D32 ", isEos "
415                  PUBLIC_LOG_D32, readDataInfo.wantReadLength_, readDataInfo.realReadLength_, readDataInfo.isEos_);
416     return Status::OK;
417 }
418 
ReadCacheBufferLoop(unsigned char * buff,ReadDataInfo & readDataInfo)419 Status HttpMediaDownloader::ReadCacheBufferLoop(unsigned char* buff, ReadDataInfo& readDataInfo)
420 {
421     FALSE_RETURN_V(downloadRequest_ != nullptr, Status::ERROR_UNKNOWN);
422     readDataInfo.isEos_ = downloadRequest_->IsEos();
423     if (readDataInfo.isEos_ || GetDownloadErrorState()) {
424         return CheckIsEosCacheBuffer(buff, readDataInfo);
425     }
426     bool isClosed = downloadRequest_->IsClosed();
427     if (isClosed && cacheMediaBuffer_->GetBufferSize(readOffset_) == 0) {
428         MEDIA_LOG_I("Http read return, isClosed: " PUBLIC_LOG_D32, isClosed);
429         readDataInfo.realReadLength_ = 0;
430         return Status::END_OF_STREAM;
431     }
432     return Status::ERROR_UNKNOWN;
433 }
434 
ReadCacheBuffer(unsigned char * buff,ReadDataInfo & readDataInfo)435 Status HttpMediaDownloader::ReadCacheBuffer(unsigned char* buff, ReadDataInfo& readDataInfo)
436 {
437     size_t remain = cacheMediaBuffer_->GetBufferSize(readOffset_);
438     MediaAVCodec::AVCodecTrace trace("HttpMediaDownloader::Read, readOffset: " + std::to_string(readOffset_) +
439         ", expectedLen: " + std::to_string(readDataInfo.wantReadLength_) + ", bufferSize: " + std::to_string(remain));
440     size_t hasReadSize = 0;
441     wantedReadLength_ = static_cast<size_t>(readDataInfo.wantReadLength_);
442     while (hasReadSize < readDataInfo.wantReadLength_ && !isInterruptNeeded_.load()) {
443         Status tempStatus = ReadCacheBufferLoop(buff, readDataInfo);
444         if (tempStatus != Status::ERROR_UNKNOWN) {
445             return tempStatus;
446         }
447         auto size = cacheMediaBuffer_->Read(buff + hasReadSize, readOffset_ + hasReadSize,
448                                             readDataInfo.wantReadLength_ - hasReadSize);
449         if (size == 0) {
450             Task::SleepInTask(FIVE_MICROSECOND); // 5
451         } else {
452             hasReadSize += size;
453         }
454     }
455     if (hasReadSize > 0 || (!isLargeOffsetSpan_ && !isNeedClearHasRead_)) {
456         canWrite_ = true;
457     }
458     if (isInterruptNeeded_.load()) {
459         readDataInfo.realReadLength_ = hasReadSize;
460         return Status::END_OF_STREAM;
461     }
462     readDataInfo.realReadLength_ = hasReadSize;
463     readOffset_ += hasReadSize;
464     isMinAndMaxOffsetUpdate_ = false;
465     isSeekWait_ = false;
466     MEDIA_LOG_D("HTTP Read Success: wantReadLength " PUBLIC_LOG_D32 ", realReadLength " PUBLIC_LOG_D32 ", isEos "
467         PUBLIC_LOG_D32 " readOffset_ " PUBLIC_LOG_ZU, readDataInfo.wantReadLength_,
468         readDataInfo.realReadLength_, readDataInfo.isEos_, readOffset_);
469     return Status::OK;
470 }
471 
HandleDownloadWaterLine()472 void HttpMediaDownloader::HandleDownloadWaterLine()
473 {
474     if (downloader_ == nullptr || !isFirstFrameArrived_ || isBuffering_ || isLargeOffsetSpan_) {
475         return;
476     }
477     if (!isNeedClearHasRead_) {
478         return;
479     }
480     uint64_t freeSize = cacheMediaBuffer_->GetFreeSize();
481     size_t cachedDataSize = static_cast<size_t>(totalBufferSize_) > freeSize ?
482         static_cast<size_t>(totalBufferSize_) - freeSize : 0;
483     size_t downloadWaterLine = static_cast<size_t>(DOWNLOAD_WATER_LINE_RATIO *
484         static_cast<float>(totalBufferSize_));
485     if (canWrite_.load()) {
486         if (cachedDataSize >= downloadWaterLine) {
487             canWrite_ = false;
488             MEDIA_LOG_D("HTTP downloadWaterLine above, stop write, downloadWaterLine: " PUBLIC_LOG_ZU,
489                 downloadWaterLine);
490         }
491     } else {
492         if (cachedDataSize < downloadWaterLine) {
493             canWrite_ = true;
494             MEDIA_LOG_D("HTTP downloadWaterLine below, resume write, downloadWaterLine: " PUBLIC_LOG_ZU,
495                 downloadWaterLine);
496         }
497     }
498 }
499 
CheckDownloadPos(unsigned int wantReadLength)500 void HttpMediaDownloader::CheckDownloadPos(unsigned int wantReadLength)
501 {
502     size_t writeOffsetTmp = writeOffset_;
503     size_t remain = GetCurrentBufferSize();
504     if ((!isLargeOffsetSpan_ && cacheMediaBuffer_->IsReadSplit(readOffset_) && isNeedClearHasRead_) ||
505         (isSeekWait_ && canWrite_)) {
506         MEDIA_LOG_I("HTTP CheckDownloadPos return, IsReadSplit.");
507         return;
508     }
509     if (remain < wantReadLength && isServerAcceptRange_ &&
510         (writeOffsetTmp < readOffset_ || writeOffsetTmp > readOffset_ + remain)) {
511         MEDIA_LOG_I("HTTP CheckDownloadPos, change download pos.");
512         ChangeDownloadPos(remain > 0);
513     }
514 }
515 
ReadDelegate(unsigned char * buff,ReadDataInfo & readDataInfo)516 Status HttpMediaDownloader::ReadDelegate(unsigned char* buff, ReadDataInfo& readDataInfo)
517 {
518     if (isRingBuffer_) {
519         FALSE_RETURN_V_MSG(ringBuffer_ != nullptr, Status::END_OF_STREAM, "ringBuffer_ = nullptr");
520         FALSE_RETURN_V_MSG(!isInterruptNeeded_.load(), Status::END_OF_STREAM, "isInterruptNeeded");
521         FALSE_RETURN_V_MSG(readDataInfo.wantReadLength_ > 0, Status::END_OF_STREAM, "wantReadLength_ <= 0");
522         if (isBuffering_ && GetBufferingTimeOut() && callback_) {
523             MEDIA_LOG_I("HTTP ringbuffer read time out.");
524             callback_->OnEvent({PluginEventType::CLIENT_ERROR, {NetworkClientErrorCode::ERROR_TIME_OUT}, "read"});
525             return Status::END_OF_STREAM;
526         }
527         if (isBuffering_ && !downloadRequest_->IsChunkedVod() && CheckBufferingOneSeconds()) {
528             MEDIA_LOG_I("HTTP Return error again.");
529             return Status::ERROR_AGAIN;
530         }
531         if (StartBuffering(readDataInfo.wantReadLength_)) {
532             return Status::ERROR_AGAIN;
533         }
534         return ReadRingBuffer(buff, readDataInfo);
535     } else {
536         FALSE_RETURN_V_MSG(cacheMediaBuffer_ != nullptr, Status::END_OF_STREAM, "cacheMediaBuffer_ = nullptr");
537         FALSE_RETURN_V_MSG(!isInterruptNeeded_.load(), Status::END_OF_STREAM, "isInterruptNeeded");
538         FALSE_RETURN_V_MSG(readDataInfo.wantReadLength_ > 0, Status::END_OF_STREAM, "wantReadLength_ <= 0");
539         if (isBuffering_ && GetBufferingTimeOut() && callback_) {
540             MEDIA_LOG_I("HTTP cachebuffer read time out.");
541             callback_->OnEvent({PluginEventType::CLIENT_ERROR, {NetworkClientErrorCode::ERROR_TIME_OUT}, "read"});
542             return Status::END_OF_STREAM;
543         }
544         if (isBuffering_ && !downloadRequest_->IsChunkedVod() && canWrite_ && CheckBufferingOneSeconds()) {
545             MEDIA_LOG_I("HTTP Return error again.");
546             return Status::ERROR_AGAIN;
547         }
548         UpdateMinAndMaxReadOffset();
549         CheckDownloadPos(readDataInfo.wantReadLength_);
550         ClearHasReadBuffer();
551         if (StartBuffering(readDataInfo.wantReadLength_)) {
552             return Status::ERROR_AGAIN;
553         }
554         Status res = ReadCacheBuffer(buff, readDataInfo);
555         HandleDownloadWaterLine();
556         return res;
557     }
558 }
559 
Read(unsigned char * buff,ReadDataInfo & readDataInfo)560 Status HttpMediaDownloader::Read(unsigned char* buff, ReadDataInfo& readDataInfo)
561 {
562     uint64_t now = static_cast<uint64_t>(steadyClock_.ElapsedMilliseconds());
563     auto ret = ReadDelegate(buff, readDataInfo);
564     readTotalBytes_ += readDataInfo.realReadLength_;
565     if (now > lastReadCheckTime_ && now - lastReadCheckTime_ > SAMPLE_INTERVAL) {
566         readRecordDuringTime_ = now - lastReadCheckTime_;   // ms
567         double readDuration = static_cast<double>(readRecordDuringTime_) / SECOND_TO_MILLIONSECOND; // s
568         if (readDuration > ZERO_THRESHOLD) {
569             double readSpeed = static_cast<double>(readTotalBytes_ * BYTES_TO_BIT) / readDuration; // bps
570             currentBitrate_ = static_cast<uint64_t>(readSpeed);     // bps
571             size_t curBufferSize = GetCurrentBufferSize();
572             MEDIA_LOG_D("HTTP Current read speed: " PUBLIC_LOG_D32 " Kbit/s,Current buffer size: " PUBLIC_LOG_U64
573             " KByte", static_cast<int32_t>(readSpeed / 1024), static_cast<uint64_t>(curBufferSize / 1024));
574             MediaAVCodec::AVCodecTrace trace("HttpMediaDownloader::Read, read speed: " +
575                 std::to_string(readSpeed) + " bit/s, bufferSize: " + std::to_string(curBufferSize) + " Byte");
576             readTotalBytes_ = 0;
577         }
578         lastReadCheckTime_ = now;
579         readRecordDuringTime_ = 0;
580     }
581 
582     return ret;
583 }
584 
CheckIsEosRingBuffer(unsigned char * buff,ReadDataInfo & readDataInfo)585 Status HttpMediaDownloader::CheckIsEosRingBuffer(unsigned char* buff, ReadDataInfo& readDataInfo)
586 {
587     if (ringBuffer_->GetSize() == 0) {
588         MEDIA_LOG_I("HTTP read return, isEos: " PUBLIC_LOG_D32, readDataInfo.isEos_);
589         return readDataInfo.realReadLength_ == 0 ? Status::END_OF_STREAM : Status::OK;
590     } else {
591         readDataInfo.realReadLength_ = ringBuffer_->ReadBuffer(buff, readDataInfo.wantReadLength_, 2); // 2
592         return Status::OK;
593     }
594 }
595 
CheckIsEosCacheBuffer(unsigned char * buff,ReadDataInfo & readDataInfo)596 Status HttpMediaDownloader::CheckIsEosCacheBuffer(unsigned char* buff, ReadDataInfo& readDataInfo)
597 {
598     if (cacheMediaBuffer_->GetBufferSize(readOffset_) == 0) {
599         MEDIA_LOG_I("HttpMediaDownloader read return, isEos: " PUBLIC_LOG_D32, readDataInfo.isEos_);
600         if (readDataInfo.realReadLength_ > 0 && isLargeOffsetSpan_) {
601             canWrite_ = true;
602         }
603         return readDataInfo.realReadLength_ == 0 ? Status::END_OF_STREAM : Status::OK;
604     } else {
605         readDataInfo.realReadLength_ = cacheMediaBuffer_->Read(buff, readOffset_, readDataInfo.wantReadLength_);
606         readOffset_ += readDataInfo.realReadLength_;
607         if (isLargeOffsetSpan_) {
608             canWrite_ = true;
609         }
610         isMinAndMaxOffsetUpdate_ = false;
611         isSeekWait_ = false;
612         MEDIA_LOG_D("HTTP read return, isEos: " PUBLIC_LOG_D32, readDataInfo.isEos_);
613         return Status::OK;
614     }
615 }
616 
SeekRingBuffer(int64_t offset)617 bool HttpMediaDownloader::SeekRingBuffer(int64_t offset)
618 {
619     FALSE_RETURN_V(ringBuffer_ != nullptr, false);
620     MEDIA_LOG_I("HTTP Seek in, buffer size " PUBLIC_LOG_ZU ", offset " PUBLIC_LOG_D64, ringBuffer_->GetSize(), offset);
621     if (ringBuffer_->Seek(offset)) {
622         MEDIA_LOG_I("HTTP ringBuffer_ seek success.");
623         return true;
624     }
625     ringBuffer_->SetActive(false); // First clear buffer, avoid no available buffer then task pause never exit.
626     downloader_->Pause();
627     ringBuffer_->Clear();
628     ringBuffer_->SetActive(true);
629     bool result = downloader_->Seek(offset);
630     if (result) {
631         ringBuffer_->SetMediaOffset(offset);
632     } else {
633         MEDIA_LOG_D("HTTP Seek failed");
634     }
635     downloader_->Resume();
636     return result;
637 }
638 
UpdateMinAndMaxReadOffset()639 void HttpMediaDownloader::UpdateMinAndMaxReadOffset()
640 {
641     if ((!isLargeOffsetSpan_ && isMinAndMaxOffsetUpdate_) || !isNeedClearHasRead_) {
642         return;
643     }
644     uint64_t readOffsetTmp = static_cast<uint64_t>(readOffset_);
645     if (GetCurrentBufferSize() == 0 && readOffsetTmp < minReadOffset_) {
646         maxReadOffset_ = readOffsetTmp;
647         minReadOffset_ = readOffsetTmp;
648         maxOffsetNotUpdateCount_ = 0;
649         minOffsetNotUpdateCount_ = 0;
650         ClearCacheBuffer();
651         return;
652     }
653 
654     if (maxReadOffset_ < readOffsetTmp) {
655         maxReadOffset_ = readOffsetTmp;
656         maxOffsetNotUpdateCount_ = 0;
657     } else {
658         maxOffsetNotUpdateCount_++;
659     }
660     if (maxOffsetNotUpdateCount_ > OFFSET_NOT_UPDATE_THRESHOLD) {
661         maxReadOffset_ = readOffsetTmp;
662         minReadOffset_ = readOffsetTmp;
663         maxOffsetNotUpdateCount_ = 0;
664     }
665     if (readOffsetTmp < maxReadOffset_ && readOffsetTmp > minReadOffset_) {
666         minReadOffset_ = readOffsetTmp;
667         minOffsetNotUpdateCount_ = 0;
668     } else {
669         minOffsetNotUpdateCount_++;
670     }
671     if (minOffsetNotUpdateCount_ > OFFSET_NOT_UPDATE_THRESHOLD) {
672         minReadOffset_ = readOffsetTmp;
673         minOffsetNotUpdateCount_ = 0;
674     }
675 
676     minReadOffset_ = std::min(minReadOffset_, static_cast<uint64_t>(readOffsetTmp));
677     minReadOffset_ = std::min(minReadOffset_, maxReadOffset_);
678     isMinAndMaxOffsetUpdate_ = true;
679 
680     uint64_t span = maxReadOffset_ > minReadOffset_ ? maxReadOffset_ - minReadOffset_ : 0;
681     if (span > LARGE_OFFSET_SPAN_THRESHOLD) {
682         isLargeOffsetSpan_ = true;
683         cacheMediaBuffer_->SetIsLargeOffsetSpan(true);
684         canWrite_ = true;
685     } else if (stateChangeCount_ <= STATE_CHANGE_THRESHOLD) {
686         isLargeOffsetSpan_ = false;
687         cacheMediaBuffer_->SetIsLargeOffsetSpan(false);
688         stateChangeCount_++;
689     }
690     MEDIA_LOG_D("HTTP UpdateMinAndMaxReadOffset, readOffset: " PUBLIC_LOG_U64 " minReadOffset_: "
691         PUBLIC_LOG_U64 " maxReadOffset_: " PUBLIC_LOG_U64, readOffsetTmp, minReadOffset_, maxReadOffset_);
692 }
693 
ChangeDownloadPos(bool isSeekHit)694 bool HttpMediaDownloader::ChangeDownloadPos(bool isSeekHit)
695 {
696     MEDIA_LOG_D("HTTP ChangeDownloadPos in, offset: " PUBLIC_LOG_ZU, readOffset_);
697 
698     uint64_t seekOffset = readOffset_;
699     if (isSeekHit) {
700         isNeedDropData_ = true;
701         downloader_->Pause();
702         isNeedDropData_ = false;
703         seekOffset += GetCurrentBufferSize();
704         size_t fileContentLength = downloadRequest_->GetFileContentLength();
705         if (seekOffset >= static_cast<uint64_t>(fileContentLength)) {
706             MEDIA_LOG_W("HTTP seekOffset invalid, readOffset " PUBLIC_LOG_ZU " seekOffset " PUBLIC_LOG_U64
707                 " fileContentLength " PUBLIC_LOG_ZU, readOffset_, seekOffset, fileContentLength);
708             return true;
709         }
710     } else {
711         isNeedClean_ = true;
712         downloader_->Pause();
713         isNeedClean_ = false;
714     }
715 
716     isHitSeeking_ = true;
717     bool result = downloader_->Seek(seekOffset);
718     isHitSeeking_ = false;
719     if (result) {
720         writeOffset_ = static_cast<size_t>(seekOffset);
721     } else {
722         MEDIA_LOG_E("HTTP Downloader seek fail.");
723     }
724     downloader_->Resume();
725     MEDIA_LOG_D("HTTP ChangeDownloadPos out, seekOffset" PUBLIC_LOG_U64, seekOffset);
726     return result;
727 }
728 
HandleSeekHit(int64_t offset)729 bool HttpMediaDownloader::HandleSeekHit(int64_t offset)
730 {
731     MEDIA_LOG_D("HTTP Seek hit.");
732     if (!isLargeOffsetSpan_ && cacheMediaBuffer_->IsReadSplit(offset) && isNeedClearHasRead_) {
733         MEDIA_LOG_D("HTTP seek hit return, because IsReadSplit");
734         return true;
735     }
736     size_t fileContentLength = downloadRequest_->GetFileContentLength();
737     size_t downloadOffset = static_cast<size_t>(offset) + cacheMediaBuffer_->GetBufferSize(offset);
738     if (downloadOffset >= fileContentLength) {
739         MEDIA_LOG_W("HTTP downloadOffset invalid, offset " PUBLIC_LOG_D64 " downloadOffset " PUBLIC_LOG_ZU
740             " fileContentLength " PUBLIC_LOG_ZU, offset, downloadOffset, fileContentLength);
741         return true;
742     }
743 
744     size_t changeDownloadPosThreshold = DEFAULT_WATER_LINE_ABOVE;
745     if (!isLargeOffsetSpan_ && static_cast<size_t>(offset) < maxReadOffset_) {
746         changeDownloadPosThreshold = AUDIO_WATER_LINE_ABOVE;
747     }
748 
749     if (writeOffset_ != downloadOffset && cacheMediaBuffer_->GetBufferSize(offset) < changeDownloadPosThreshold) {
750         MEDIA_LOG_I("HTTP HandleSeekHit ChangeDownloadPos, writeOffset_: " PUBLIC_LOG_ZU " downloadOffset: "
751             PUBLIC_LOG_ZU " bufferSize: " PUBLIC_LOG_ZU, writeOffset_, downloadOffset,
752             cacheMediaBuffer_->GetBufferSize(offset));
753         return ChangeDownloadPos(true);
754     } else {
755         MEDIA_LOG_D("HTTP Seek hit, continue download.");
756     }
757     return true;
758 }
759 
SeekCacheBuffer(int64_t offset)760 bool HttpMediaDownloader::SeekCacheBuffer(int64_t offset)
761 {
762     readOffset_ = static_cast<size_t>(offset);
763     cacheMediaBuffer_->Seek(offset); // Notify the cacheBuffer where to read.
764     UpdateMinAndMaxReadOffset();
765 
766     if (!isServerAcceptRange_) {
767         MEDIA_LOG_D("HTTP Don't support range, return true.");
768         return true;
769     }
770 
771     size_t remain = cacheMediaBuffer_->GetBufferSize(offset);
772     MEDIA_LOG_I("HTTP Seek: buffer size " PUBLIC_LOG_ZU ", offset " PUBLIC_LOG_D64, remain, offset);
773     if (remain > 0) {
774         return HandleSeekHit(offset);
775     }
776     MEDIA_LOG_I("HTTP Seek miss.");
777 
778     size_t fileContenLen = downloadRequest_->GetFileContentLength();
779     isNeedClearHasRead_ = fileContenLen > LARGE_VIDEO_THRESHOLD ? true : false;
780 
781     uint64_t diff = static_cast<size_t>(offset) > writeOffset_ ?
782         static_cast<size_t>(offset) - writeOffset_ : 0;
783     if (diff > 0 && diff < ALLOW_SEEK_MIN_SIZE) {
784         isSeekWait_ = true;
785         MEDIA_LOG_I("HTTP Seek miss, diff is too small so return and wait.");
786         return true;
787     }
788     return ChangeDownloadPos(false);
789 }
790 
SeekToPos(int64_t offset)791 bool HttpMediaDownloader::SeekToPos(int64_t offset)
792 {
793     if (isRingBuffer_) {
794         return SeekRingBuffer(offset);
795     } else {
796         return SeekCacheBuffer(offset);
797     }
798 }
799 
GetContentLength() const800 size_t HttpMediaDownloader::GetContentLength() const
801 {
802     if (downloadRequest_->IsClosed()) {
803         return 0; // 0
804     }
805     return downloadRequest_->GetFileContentLength();
806 }
807 
GetDuration() const808 int64_t HttpMediaDownloader::GetDuration() const
809 {
810     return 0;
811 }
812 
GetSeekable() const813 Seekable HttpMediaDownloader::GetSeekable() const
814 {
815     return downloadRequest_->IsChunked(isInterruptNeeded_);
816 }
817 
SetCallback(Callback * cb)818 void HttpMediaDownloader::SetCallback(Callback* cb)
819 {
820     callback_ = cb;
821 }
822 
SetStatusCallback(StatusCallbackFunc cb)823 void HttpMediaDownloader::SetStatusCallback(StatusCallbackFunc cb)
824 {
825     statusCallback_ = cb;
826 }
827 
GetStartedStatus()828 bool HttpMediaDownloader::GetStartedStatus()
829 {
830     return startedPlayStatus_;
831 }
832 
SetReadBlockingFlag(bool isReadBlockingAllowed)833 void HttpMediaDownloader::SetReadBlockingFlag(bool isReadBlockingAllowed)
834 {
835     if (isRingBuffer_) {
836         FALSE_RETURN(ringBuffer_ != nullptr);
837         ringBuffer_->SetReadBlocking(isReadBlockingAllowed);
838     }
839 }
840 
SaveRingBufferData(uint8_t * data,uint32_t len)841 bool HttpMediaDownloader::SaveRingBufferData(uint8_t* data, uint32_t len)
842 {
843     FALSE_RETURN_V(ringBuffer_->WriteBuffer(data, len), false);
844     cvReadWrite_.NotifyOne();
845     size_t bufferSize = ringBuffer_->GetSize();
846     double ratio = (static_cast<double>(bufferSize)) / RING_BUFFER_SIZE;
847     if ((bufferSize >= WATER_LINE ||
848         bufferSize >= downloadRequest_->GetFileContentLength() / 2) && !aboveWaterline_) { // 2
849         aboveWaterline_ = true;
850         MEDIA_LOG_I("HTTP Send http aboveWaterline event, ringbuffer ratio " PUBLIC_LOG_F, ratio);
851         if (callback_ != nullptr) {
852             callback_->OnEvent({PluginEventType::ABOVE_LOW_WATERLINE, {ratio}, "http"});
853         }
854         startedPlayStatus_ = true;
855     } else if (bufferSize < WATER_LINE && aboveWaterline_) {
856         aboveWaterline_ = false;
857         MEDIA_LOG_I("HTTP Send http belowWaterline event, ringbuffer ratio " PUBLIC_LOG_F, ratio);
858         if (callback_ != nullptr) {
859             callback_->OnEvent({PluginEventType::BELOW_LOW_WATERLINE, {ratio}, "http"});
860         }
861     }
862     return true;
863 }
864 
SaveData(uint8_t * data,uint32_t len)865 bool HttpMediaDownloader::SaveData(uint8_t* data, uint32_t len)
866 {
867     if (cacheMediaBuffer_ == nullptr && ringBuffer_ == nullptr) {
868         return false;
869     }
870     OnWriteBuffer(len);
871     bool ret = true;
872     if (isRingBuffer_) {
873         ret = SaveRingBufferData(data, len);
874     } else {
875         ret = SaveCacheBufferData(data, len);
876         HandleDownloadWaterLine();
877     }
878     HandleBuffering();
879     return ret;
880 }
881 
SaveCacheBufferData(uint8_t * data,uint32_t len)882 bool HttpMediaDownloader::SaveCacheBufferData(uint8_t* data, uint32_t len)
883 {
884     if (isNeedClean_) {
885         return true;
886     }
887 
888     isServerAcceptRange_ = downloadRequest_->IsServerAcceptRange();
889 
890     size_t hasWriteSize = 0;
891     while (hasWriteSize < len && !isInterruptNeeded_.load() && !isInterrupt_.load()) {
892         if (isNeedClean_) {
893             MEDIA_LOGI_LIMIT(SAVE_DATA_LOG_FREQUENCE, "isNeedClean true.");
894             return true;
895         }
896         size_t res = cacheMediaBuffer_->Write(data + hasWriteSize, writeOffset_, len - hasWriteSize);
897         writeOffset_ += res;
898         hasWriteSize += res;
899         writeBitrateCaculator_->UpdateWriteBytes(res);
900         MEDIA_LOGI_LIMIT(SAVE_DATA_LOG_FREQUENCE, "HTTP writeOffset " PUBLIC_LOG_ZU " res "
901             PUBLIC_LOG_ZU, writeOffset_, res);
902         if ((isLargeOffsetSpan_ || canWrite_.load()) && (res > 0 || hasWriteSize == len)) {
903             HandleCachedDuration();
904             writeBitrateCaculator_->StartClock();
905             uint64_t writeTime  = writeBitrateCaculator_->GetWriteTime() / SECOND_TO_MILLIONSECOND;
906             if (writeTime > ONE_SECONDS) {
907                 writeBitrateCaculator_->ResetClock();
908             }
909             continue;
910         }
911         MEDIA_LOG_W("HTTP CacheMediaBuffer full.");
912         writeBitrateCaculator_->StopClock();
913         canWrite_ = false;
914         HandleBuffering();
915         while (!isInterrupt_.load() && !isNeedClean_.load() && !canWrite_.load() && !isInterruptNeeded_.load()) {
916             MEDIA_LOGI_LIMIT(SAVE_DATA_LOG_FREQUENCE, "HTTP CacheMediaBuffer full, waiting seek or read.");
917             if (isHitSeeking_ || isNeedDropData_) {
918                 canWrite_ = true;
919                 return true;
920             }
921             OSAL::SleepFor(ONE_HUNDRED_MILLIONSECOND);
922         }
923         canWrite_ = true;
924     }
925     if (isInterruptNeeded_.load() || isInterrupt_.load()) {
926         MEDIA_LOG_I("HTTP isInterruptNeeded true, return false.");
927         return false;
928     }
929     return true;
930 }
931 
OnWriteBuffer(uint32_t len)932 void HttpMediaDownloader::OnWriteBuffer(uint32_t len)
933 {
934     if (startDownloadTime_ == 0) {
935         int64_t nowTime = steadyClock_.ElapsedMilliseconds();
936         startDownloadTime_ = nowTime;
937         lastReportUsageTime_ = nowTime;
938     }
939     uint32_t writeBits = len * BYTES_TO_BIT;
940     totalBits_ += writeBits;
941     dataUsage_ += writeBits;
942     if ((totalBits_ > START_PLAY_WATER_LINE) && (playDelayTime_ == 0)) {
943         auto startPlayTime = steadyClock_.ElapsedMilliseconds();
944         playDelayTime_ = startPlayTime - openTime_;
945         MEDIA_LOG_D("HTTP Start play delay time: " PUBLIC_LOG_D64, playDelayTime_);
946     }
947     DownloadReport();
948 }
949 
CalculateCurrentDownloadSpeed()950 double HttpMediaDownloader::CalculateCurrentDownloadSpeed()
951 {
952     double downloadRate = 0;
953     double tmpNumerator = static_cast<double>(downloadBits_);
954     double tmpDenominator = static_cast<double>(downloadDuringTime_) / SECOND_TO_MILLIONSECOND;
955     totalDownloadDuringTime_ += downloadDuringTime_;
956     if (tmpDenominator > ZERO_THRESHOLD) {
957         downloadRate = tmpNumerator / tmpDenominator;
958         avgDownloadSpeed_ = downloadRate;
959         downloadDuringTime_ = 0;
960         downloadBits_ = 0;
961     }
962     return downloadRate;
963 }
964 
DownloadReport()965 void HttpMediaDownloader::DownloadReport()
966 {
967     uint64_t now = static_cast<uint64_t>(steadyClock_.ElapsedMilliseconds());
968     if ((static_cast<int64_t>(now) - lastCheckTime_) > static_cast<int64_t>(SAMPLE_INTERVAL)) {
969         uint64_t curDownloadBits = totalBits_ - lastBits_;
970         if (curDownloadBits >= IS_DOWNLOAD_MIN_BIT) {
971             downloadDuringTime_ = now - static_cast<uint64_t>(lastCheckTime_);
972             downloadBits_ = curDownloadBits;
973             double downloadRate = CalculateCurrentDownloadSpeed();
974             // remaining buffer size
975             size_t remainingBuffer = GetCurrentBufferSize();    // Byte
976             MEDIA_LOG_D("Current download speed : " PUBLIC_LOG_D32 " Kbit/s,Current buffer size : " PUBLIC_LOG_U64
977                 " KByte", static_cast<int32_t>(downloadRate / 1024), static_cast<uint64_t>(remainingBuffer / 1024));
978             MediaAVCodec::AVCodecTrace trace("HttpMediaDownloader::DownloadReport, download speed: " +
979                 std::to_string(downloadRate) + " bit/s, bufferSize: " + std::to_string(remainingBuffer) + " Byte");
980             // Remaining playable time: s
981             uint64_t bufferDuration = 0;
982             if (currentBitrate_ > 0) {
983                 bufferDuration = static_cast<uint64_t>(remainingBuffer * BYTES_TO_BIT) / currentBitrate_;
984             } else {
985                 bufferDuration = static_cast<uint64_t>(remainingBuffer * BYTES_TO_BIT) / CURRENT_BIT_RATE;
986             }
987             if (recordData_ != nullptr) {
988                 recordData_->downloadRate = downloadRate;
989                 recordData_->bufferDuring = bufferDuration;
990             }
991         }
992         lastBits_ = totalBits_;
993         lastCheckTime_ = static_cast<int64_t>(now);
994     }
995 
996     if (!isDownloadFinish_ && (static_cast<int64_t>(now) - lastReportUsageTime_) > DATA_USAGE_NTERVAL) {
997         MEDIA_LOG_D("Data usage: " PUBLIC_LOG_U64 " bits in " PUBLIC_LOG_D32 "ms", dataUsage_, DATA_USAGE_NTERVAL);
998         dataUsage_ = 0;
999         lastReportUsageTime_ = static_cast<int64_t>(now);
1000     }
1001 }
1002 
SetDemuxerState(int32_t streamId)1003 void HttpMediaDownloader::SetDemuxerState(int32_t streamId)
1004 {
1005     MEDIA_LOG_I("HTTP SetDemuxerState");
1006     isFirstFrameArrived_ = true;
1007 }
1008 
SetDownloadErrorState()1009 void HttpMediaDownloader::SetDownloadErrorState()
1010 {
1011     MEDIA_LOG_I("HTTP SetDownloadErrorState");
1012     downloadErrorState_ = true;
1013     if (callback_ != nullptr && !isReportedErrorCode_) {
1014         callback_->OnEvent({PluginEventType::CLIENT_ERROR, {NetworkClientErrorCode::ERROR_NOT_RETRY}, "read"});
1015     }
1016     Close(true);
1017 }
1018 
SetInterruptState(bool isInterruptNeeded)1019 void HttpMediaDownloader::SetInterruptState(bool isInterruptNeeded)
1020 {
1021     MEDIA_LOG_I("SetInterruptState: " PUBLIC_LOG_D32, isInterruptNeeded);
1022     {
1023         AutoLock lk(bufferingEndMutex_);
1024         isInterruptNeeded_ = isInterruptNeeded;
1025         if (isInterruptNeeded_) {
1026             MEDIA_LOG_I("SetInterruptState, bufferingEndCond NotifyAll.");
1027             bufferingEndCond_.NotifyAll();
1028         }
1029     }
1030     if (ringBuffer_ != nullptr && isInterruptNeeded) {
1031         ringBuffer_->SetActive(false);
1032     }
1033     if (downloader_ != nullptr) {
1034         downloader_->SetInterruptState(isInterruptNeeded);
1035     }
1036 }
1037 
GetBufferSize() const1038 size_t HttpMediaDownloader::GetBufferSize() const
1039 {
1040     return GetCurrentBufferSize();
1041 }
1042 
GetBuffer()1043 RingBuffer& HttpMediaDownloader::GetBuffer()
1044 {
1045     return *ringBuffer_;
1046 }
1047 
GetReadFrame()1048 bool HttpMediaDownloader::GetReadFrame()
1049 {
1050     return isFirstFrameArrived_;
1051 }
1052 
GetDownloadErrorState()1053 bool HttpMediaDownloader::GetDownloadErrorState()
1054 {
1055     return downloadErrorState_;
1056 }
1057 
GetStatusCallbackFunc()1058 StatusCallbackFunc HttpMediaDownloader::GetStatusCallbackFunc()
1059 {
1060     return statusCallback_;
1061 }
1062 
GetDownloadInfo(DownloadInfo & downloadInfo)1063 void HttpMediaDownloader::GetDownloadInfo(DownloadInfo& downloadInfo)
1064 {
1065     if (recordSpeedCount_ == 0) {
1066         MEDIA_LOG_E("HttpMediaDownloader is 0, can't get avgDownloadRate");
1067         downloadInfo.avgDownloadRate = 0;
1068     } else {
1069         downloadInfo.avgDownloadRate = avgSpeedSum_ / recordSpeedCount_;
1070     }
1071     downloadInfo.avgDownloadSpeed = avgDownloadSpeed_;
1072     downloadInfo.totalDownLoadBits = totalBits_;
1073     downloadInfo.isTimeOut = isTimeOut_;
1074 }
1075 
GetDownloadInfo()1076 std::pair<int32_t, int32_t> HttpMediaDownloader::GetDownloadInfo()
1077 {
1078     MEDIA_LOG_I("HttpMediaDownloader::GetDownloadInfo.");
1079     if (recordSpeedCount_ == 0) {
1080         MEDIA_LOG_E("recordSpeedCount is 0, can't get avgDownloadRate");
1081         return std::make_pair(0, static_cast<int32_t>(avgDownloadSpeed_));
1082     }
1083     auto rateAndSpeed = std::make_pair(avgSpeedSum_ / recordSpeedCount_, static_cast<int32_t>(avgDownloadSpeed_));
1084     return rateAndSpeed;
1085 }
1086 
GetDownloadRateAndSpeed()1087 std::pair<int32_t, int32_t> HttpMediaDownloader::GetDownloadRateAndSpeed()
1088 {
1089     MEDIA_LOG_I("HttpMediaDownloader::GetDownloadRateAndSpeed.");
1090     if (recordSpeedCount_ == 0) {
1091         MEDIA_LOG_E("recordSpeedCount is 0, can't get avgDownloadRate");
1092         return std::make_pair(0, static_cast<int32_t>(avgDownloadSpeed_));
1093     }
1094     auto rateAndSpeed = std::make_pair(avgSpeedSum_ / recordSpeedCount_, static_cast<int32_t>(avgDownloadSpeed_));
1095     return rateAndSpeed;
1096 }
1097 
GetPlaybackInfo(PlaybackInfo & playbackInfo)1098 void HttpMediaDownloader::GetPlaybackInfo(PlaybackInfo& playbackInfo)
1099 {
1100     if (downloader_ != nullptr) {
1101         downloader_->GetIp(playbackInfo.serverIpAddress);
1102     }
1103     double tmpDownloadTime = static_cast<double>(totalDownloadDuringTime_) / SECOND_TO_MILLIONSECOND;
1104     if (tmpDownloadTime > ZERO_THRESHOLD) {
1105         playbackInfo.averageDownloadRate = static_cast<int64_t>(totalBits_ / tmpDownloadTime);
1106     } else {
1107         playbackInfo.averageDownloadRate = 0;
1108     }
1109     playbackInfo.isDownloading = isDownloadFinish_ ? false : true;
1110     if (recordData_ != nullptr) {
1111         playbackInfo.downloadRate = static_cast<int64_t>(recordData_->downloadRate);
1112         size_t remainingBuffer = GetCurrentBufferSize();
1113         uint64_t bufferDuration = 0;
1114         if (currentBitrate_ > 0) {
1115             bufferDuration = static_cast<uint64_t>(remainingBuffer * BYTES_TO_BIT) / currentBitrate_;
1116         } else {
1117             bufferDuration = static_cast<uint64_t>(remainingBuffer * BYTES_TO_BIT) / CURRENT_BIT_RATE;
1118         }
1119         playbackInfo.bufferDuration = static_cast<int64_t>(bufferDuration);
1120     } else {
1121         playbackInfo.downloadRate = 0;
1122         playbackInfo.bufferDuration = 0;
1123     }
1124 }
1125 
HandleBreak()1126 bool HttpMediaDownloader::HandleBreak()
1127 {
1128     if (downloadErrorState_) {
1129         MEDIA_LOG_I("HTTP HandleBreak, downloadErrorState true.");
1130         return true;
1131     }
1132     if (downloadRequest_ == nullptr) {
1133         MEDIA_LOG_I("HTTP HandleBreak, downloadRequest is nullptr.");
1134         return true;
1135     }
1136     if (callback_ == nullptr) {
1137         MEDIA_LOG_I("HTTP HandleBreak, callback is nullptr.");
1138         return true;
1139     }
1140     if (downloadRequest_->IsEos()) {
1141         MEDIA_LOG_I("HTTP HandleBreak, isEos");
1142         return true;
1143     }
1144     if (downloadRequest_->IsClosed()) {
1145         MEDIA_LOG_I("HTTP HandleBreak, IsClosed");
1146         return true;
1147     }
1148     if (downloadRequest_->IsChunkedVod()) {
1149         MEDIA_LOG_I("HTTP HandleBreak, IsChunkedVod");
1150         return true;
1151     }
1152     return false;
1153 }
1154 
GetCurrentBufferSize() const1155 size_t HttpMediaDownloader::GetCurrentBufferSize() const
1156 {
1157     size_t bufferSize = 0;
1158     if (isRingBuffer_) {
1159         if (ringBuffer_ != nullptr) {
1160             bufferSize = ringBuffer_->GetSize();
1161         }
1162     } else {
1163         if (cacheMediaBuffer_ != nullptr) {
1164             bufferSize = cacheMediaBuffer_->GetBufferSize(readOffset_);
1165         }
1166     }
1167     return bufferSize;
1168 }
1169 
SetCurrentBitRate(int32_t bitRate,int32_t streamID)1170 Status HttpMediaDownloader::SetCurrentBitRate(int32_t bitRate, int32_t streamID)
1171 {
1172     MEDIA_LOG_I("HTTP SetCurrentBitRate: " PUBLIC_LOG_D32, bitRate);
1173     if (bitRate <= 0) {
1174         currentBitRate_ = DEFAULT_BIT_RATE;
1175     } else {
1176         currentBitRate_ = std::max(currentBitRate_, bitRate);
1177     }
1178     return Status::OK;
1179 }
1180 
HandleCachedDuration()1181 void HttpMediaDownloader::HandleCachedDuration()
1182 {
1183     if (currentBitRate_ <= 0 || callback_ == nullptr) {
1184         return;
1185     }
1186     uint64_t cachedDuration = static_cast<uint64_t>((static_cast<int64_t>(GetCurrentBufferSize()) *
1187         BYTES_TO_BIT * SECOND_TO_MILLIONSECOND) / static_cast<int64_t>(currentBitRate_));
1188     // Subtraction of unsigned integers requires size comparison first.
1189     if ((cachedDuration > lastDurationReacord_ &&
1190         cachedDuration - lastDurationReacord_ > DURATION_CHANGE_AMOUT_MILLIONSECOND) ||
1191         (lastDurationReacord_ > cachedDuration &&
1192         lastDurationReacord_ - cachedDuration > DURATION_CHANGE_AMOUT_MILLIONSECOND)) {
1193         MEDIA_LOG_D("HTTP OnEvent cachedDuration: " PUBLIC_LOG_U64, cachedDuration);
1194         callback_->OnEvent({PluginEventType::CACHED_DURATION, {cachedDuration}, "buffering_duration"});
1195         lastDurationReacord_ = cachedDuration;
1196     }
1197 }
1198 
UpdateCachedPercent(BufferingInfoType infoType)1199 void HttpMediaDownloader::UpdateCachedPercent(BufferingInfoType infoType)
1200 {
1201     if (waterLineAbove_ == 0 || callback_ == nullptr) {
1202         MEDIA_LOG_E("UpdateCachedPercent: ERROR");
1203         return;
1204     }
1205     if (infoType == BufferingInfoType::BUFFERING_START) {
1206         lastCachedSize_ = 0;
1207         isBufferingStart_ = true;
1208         return;
1209     }
1210     if (infoType == BufferingInfoType::BUFFERING_END) {
1211         lastCachedSize_ = 0;
1212         isBufferingStart_ = false;
1213         return;
1214     }
1215     if (infoType != BufferingInfoType::BUFFERING_PERCENT || !isBufferingStart_) {
1216         return;
1217     }
1218     int32_t bufferSize = static_cast<int32_t>(GetCurrentBufferSize());
1219     if (bufferSize < lastCachedSize_) {
1220         return;
1221     }
1222     int32_t deltaSize = bufferSize - lastCachedSize_;
1223     if (deltaSize >= static_cast<int32_t>(UPDATE_CACHE_STEP)) {
1224         int percent = (bufferSize >= static_cast<int32_t>(waterLineAbove_)) ?
1225                         100 : bufferSize * 100 / static_cast<int32_t>(waterLineAbove_); // 100
1226         callback_->OnEvent({PluginEventType::EVENT_BUFFER_PROGRESS, {percent}, "buffer percent"});
1227         lastCachedSize_ = bufferSize;
1228     }
1229 }
1230 
CheckBufferingOneSeconds()1231 bool HttpMediaDownloader::CheckBufferingOneSeconds()
1232 {
1233     MEDIA_LOG_I("HTTP CheckBufferingOneSeconds in");
1234     int32_t sleepTime = 0;
1235     // return error again 1 time 1s, avoid ffmpeg error
1236     while (sleepTime < TWO_SECONDS && !isInterruptNeeded_.load()) {
1237         if (!isBuffering_) {
1238             break;
1239         }
1240         if (HandleBreak()) {
1241             isBuffering_ = false;
1242             break;
1243         }
1244         OSAL::SleepFor(TEN_MILLISECONDS);
1245         sleepTime += TEN_MILLISECONDS;
1246     }
1247     MEDIA_LOG_I("HTTP CheckBufferingOneSeconds out");
1248     return isBuffering_.load();
1249 }
1250 
SetAppUid(int32_t appUid)1251 void HttpMediaDownloader::SetAppUid(int32_t appUid)
1252 {
1253     if (downloader_) {
1254         downloader_->SetAppUid(appUid);
1255     }
1256 }
1257 
GetCacheDuration(float ratio)1258 float HttpMediaDownloader::GetCacheDuration(float ratio)
1259 {
1260     if (ratio >= 1) {
1261         return CACHE_LEVEL_1;
1262     }
1263     return DEFAULT_CACHE_TIME;
1264 }
1265 
UpdateWaterLineAbove()1266 void HttpMediaDownloader::UpdateWaterLineAbove()
1267 {
1268     if (!isFirstFrameArrived_) {
1269         return;
1270     }
1271     size_t waterLineAbove = DEFAULT_WATER_LINE_ABOVE;
1272     if (currentBitRate_ > 0) {
1273         float cacheTime = 0;
1274         uint64_t writeBitrate = writeBitrateCaculator_->GetWriteBitrate();
1275         if (writeBitrate > 0) {
1276             float ratio = static_cast<float>(writeBitrate) / currentBitRate_;
1277             cacheTime = GetCacheDuration(ratio);
1278         } else {
1279             cacheTime = DEFAULT_CACHE_TIME;
1280         }
1281         waterLineAbove = static_cast<size_t>(cacheTime * currentBitRate_ / BYTES_TO_BIT);
1282         waterLineAbove = std::max(MIN_WATER_LINE_ABOVE, waterLineAbove);
1283     } else {
1284         MEDIA_LOG_D("UpdateWaterLineAbove default: " PUBLIC_LOG_ZU, waterLineAbove);
1285     }
1286     waterLineAbove_ = waterLineAbove;
1287 
1288     if (readOffset_ < maxReadOffset_) {
1289         waterLineAbove_ = DEFAULT_WATER_LINE_ABOVE;
1290     }
1291 
1292     size_t fileRemain = 0;
1293     if (downloadRequest_ != nullptr) {
1294         size_t fileContenLen = downloadRequest_->GetFileContentLength();
1295         if (fileContenLen > readOffset_) {
1296             fileRemain = fileContenLen - readOffset_;
1297             waterLineAbove_ = std::min(fileRemain, waterLineAbove_);
1298         }
1299     }
1300 
1301     waterLineAbove_ = std::min(waterLineAbove_, static_cast<size_t>(MAX_CACHE_BUFFER_SIZE *
1302         WATER_LINE_ABOVE_LIMIT_RATIO));
1303     waterLineAbove_ = std::min(waterLineAbove_, MAX_WATER_LINE_ABOVE);
1304     MEDIA_LOG_D("UpdateWaterLineAbove: " PUBLIC_LOG_ZU " writeBitrate: " PUBLIC_LOG_U64 " readBitrate: "
1305         PUBLIC_LOG_D32, waterLineAbove_, writeBitrateCaculator_->GetWriteBitrate(), currentBitRate_);
1306 }
1307 
GetPlayable()1308 bool HttpMediaDownloader::GetPlayable()
1309 {
1310     if (isBuffering_) {
1311         return false;
1312     }
1313     if (!isFirstFrameArrived_) {
1314         return false;
1315     }
1316     size_t wantedLength = wantedReadLength_;
1317     size_t waterLine = wantedLength > 0 ? std::max(PLAY_WATER_LINE, wantedLength) : 0;
1318     return waterLine == 0 ? GetBufferSize() > waterLine : GetBufferSize() >= waterLine;
1319 }
1320 
GetBufferingTimeOut()1321 bool HttpMediaDownloader::GetBufferingTimeOut()
1322 {
1323     if (bufferingTime_ == 0) {
1324         return false;
1325     } else {
1326         size_t now = static_cast<size_t>(steadyClock_.ElapsedMilliseconds());
1327         return now >= bufferingTime_ ? now - bufferingTime_ >= MAX_BUFFERING_TIME_OUT : false;
1328     }
1329 }
1330 
GetReadTimeOut()1331 bool HttpMediaDownloader::GetReadTimeOut()
1332 {
1333     size_t now = static_cast<size_t>(steadyClock_.ElapsedMilliseconds());
1334     return (now >= readTime_) ? (now - readTime_ >= MAX_BUFFERING_TIME_OUT) : false;
1335 }
1336 
WaitForBufferingEnd()1337 void HttpMediaDownloader::WaitForBufferingEnd()
1338 {
1339     AutoLock lk(bufferingEndMutex_);
1340     FALSE_RETURN_MSG(isBuffering_.load(), "isBuffering false.");
1341     MEDIA_LOG_I("WaitForBufferingEnd");
1342     bufferingEndCond_.Wait(lk, [this]() {
1343         MEDIA_LOG_I("Wait in, isBuffering: " PUBLIC_LOG_D32 " isInterruptNeeded: " PUBLIC_LOG_D32,
1344             isBuffering_.load(), isInterruptNeeded_.load());
1345         return !isBuffering_.load() || isInterruptNeeded_.load();
1346     });
1347 }
1348 
ClearHasReadBuffer()1349 bool HttpMediaDownloader::ClearHasReadBuffer()
1350 {
1351     if (!isFirstFrameArrived_ || cacheMediaBuffer_ == nullptr || isLargeOffsetSpan_) {
1352         return false;
1353     }
1354     if (isNeedClearHasRead_) {
1355         return false;
1356     }
1357     uint64_t minOffset = std::min(minReadOffset_, static_cast<uint64_t>(writeOffset_));
1358     uint64_t clearOffset = minOffset > CLEAR_SAVE_DATA_SIZE ? minOffset - CLEAR_SAVE_DATA_SIZE : 0;
1359     bool res = false;
1360     res = cacheMediaBuffer_->ClearFragmentBeforeOffset(clearOffset);
1361     res = cacheMediaBuffer_->ClearChunksOfFragment(clearOffset) || res;
1362     uint64_t minClearOffset = minOffset + CLEAR_SAVE_DATA_SIZE;
1363     uint64_t maxClearOffset = maxReadOffset_ > CLEAR_SAVE_DATA_SIZE ? maxReadOffset_ - CLEAR_SAVE_DATA_SIZE : 0;
1364     uint64_t diff = maxClearOffset > minClearOffset ? maxClearOffset - minClearOffset : 0;
1365     if (diff > ALLOW_CLEAR_MIDDLE_DATA_MIN_SIZE) {
1366         res = cacheMediaBuffer_->ClearMiddleReadFragment(minClearOffset, maxClearOffset) || res;
1367     }
1368     MEDIA_LOG_D("HTTP ClearHasReadBuffer, res: " PUBLIC_LOG_D32 " clearOffset: " PUBLIC_LOG_U64 " minClearOffset: "
1369         PUBLIC_LOG_U64 " maxClearOffset: " PUBLIC_LOG_U64, res, clearOffset, minClearOffset, maxClearOffset);
1370     return res;
1371 }
1372 
ClearCacheBuffer()1373 void HttpMediaDownloader::ClearCacheBuffer()
1374 {
1375     if (cacheMediaBuffer_ == nullptr || downloader_ == nullptr) {
1376         return;
1377     }
1378     MEDIA_LOG_I("HTTP ClearCacheBuffer begin.");
1379     isNeedDropData_ = true;
1380     downloader_->Pause();
1381     cacheMediaBuffer_->Clear();
1382     isNeedDropData_ = false;
1383     downloader_->Seek(readOffset_);
1384     downloader_->Resume();
1385     uint64_t freeSize = cacheMediaBuffer_->GetFreeSize();
1386     MEDIA_LOG_I("HTTP ClearCacheBuffer end, freeSize: " PUBLIC_LOG_U64, freeSize);
1387 }
1388 
SetIsReportedErrorCode()1389 void HttpMediaDownloader::SetIsReportedErrorCode()
1390 {
1391     isReportedErrorCode_ = true;
1392 }
1393 }
1394 }
1395 }
1396 }