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 }