diff --git a/services/media_engine/plugins/source/http_source/download/app_client.h b/services/media_engine/plugins/source/http_source/download/app_client.h index fd956d2cc947501b41a52e1a0dcfad4e86d64e93..77127ed53c8c9515e2804bee16e18de6f95194be 100644 --- a/services/media_engine/plugins/source/http_source/download/app_client.h +++ b/services/media_engine/plugins/source/http_source/download/app_client.h @@ -84,8 +84,8 @@ private: int dataInFlight_ {0}; long startPos_ {0}; int len_ {0}; - std::string redirectUrl_ {}; - int64_t curOffset_ {}; + std::string redirectUrl_ {""}; + int64_t curOffset_ {-2}; }; } } diff --git a/services/media_engine/plugins/source/http_source/download/downloader.cpp b/services/media_engine/plugins/source/http_source/download/downloader.cpp index 1c08c0fcde5e6aca661234066d43ebd3870617f8..d0ae3507e1a5f12397ef12aef925809c3c5b37b5 100644 --- a/services/media_engine/plugins/source/http_source/download/downloader.cpp +++ b/services/media_engine/plugins/source/http_source/download/downloader.cpp @@ -509,13 +509,6 @@ bool Downloader::Retry(const std::shared_ptr& request) "not Retry, client null or isDestructor or isInterruptNeeded"); if (isAppBackground_) { Pause(true); - { - AutoLock lk(deinitMutex_); - if (client_ != nullptr) { - client_->Deinit(); - client_ = nullptr; - } - } MEDIA_LOG_I("Retry avoid, forground to background."); return true; } @@ -683,6 +676,39 @@ void Downloader::HandleRedirect(Status& ret) } } +void Downloader::HandleResponseCb(int32_t clientCode, int32_t serverCode, Status& ret) +{ + currentRequest_->clientError_ = clientCode; + currentRequest_->serverError_ = serverCode; + + HandleRedirect(ret); + + if (isDestructor_) { + return; + } + if (currentRequest_->preRequestSize_ == FIRST_REQUEST_SIZE && !currentRequest_->isFirstRangeRequestReady_ + && currentRequest_->serverError_ == SERVER_RANGE_ERROR_CODE) { + MEDIA_LOG_I("first request is above filesize, need retry."); + currentRequest_->startPos_ = 0; + currentRequest_->requestSize_ = MIN_REQUEST_SIZE; + currentRequest_->isHeaderUpdated_ = false; + currentRequest_->isFirstRangeRequestReady_ = true; + currentRequest_->headerInfo_.fileContentLen = 0; + return; + } + if (ret == Status::OK) { + HandleRetOK(); + } else { + PauseLoop(true); + MEDIA_LOG_E("Client request data failed. ret = " PUBLIC_LOG_D32 ", clientCode = " PUBLIC_LOG_D32 + ", request queue size: " PUBLIC_LOG_U64, static_cast(ret), + static_cast(clientCode), static_cast(requestQue_->Size())); + HandleRetErrorCode(); + std::shared_ptr unused; + currentRequest_->statusCallback_(DownloadStatus::PARTTAL_DOWNLOAD, unused, currentRequest_); + } +} + void Downloader::RequestData() { MediaAVCodec::AVCodecTrace trace("Downloader::HttpDownloadLoop, startPos: " @@ -703,38 +729,14 @@ void Downloader::RequestData() } auto handleResponseCb = [this](int32_t clientCode, int32_t serverCode, Status ret) { - currentRequest_->clientError_ = clientCode; - currentRequest_->serverError_ = serverCode; - - HandleRedirect(ret); - - if (isDestructor_) { - return; - } - if (currentRequest_->preRequestSize_ == FIRST_REQUEST_SIZE && !currentRequest_->isFirstRangeRequestReady_ - && currentRequest_->serverError_ == SERVER_RANGE_ERROR_CODE) { - MEDIA_LOG_I("first request is above filesize, need retry."); - currentRequest_->startPos_ = 0; - currentRequest_->requestSize_ = MIN_REQUEST_SIZE; - currentRequest_->isHeaderUpdated_ = false; - currentRequest_->isFirstRangeRequestReady_ = true; - currentRequest_->headerInfo_.fileContentLen = 0; - return; - } - if (ret == Status::OK) { - HandleRetOK(); - } else { - PauseLoop(true); - MEDIA_LOG_E("Client request data failed. ret = " PUBLIC_LOG_D32 ", clientCode = " PUBLIC_LOG_D32 - ",request queue size: " PUBLIC_LOG_U64, static_cast(ret), - static_cast(clientCode), static_cast(requestQue_->Size())); - HandleRetErrorCode(); - std::shared_ptr unused; - currentRequest_->statusCallback_(DownloadStatus::PARTTAL_DOWNLOAD, unused, currentRequest_); - } + HandleResponseCb(clientCode, serverCode, ret); }; MEDIA_LOG_I("0x%{public}06" PRIXPTR " RequestData enter.", FAKE_POINTER(this)); - client_->RequestData(startPos, currentRequest_->requestSize_, sourceInfo, handleResponseCb); + int len = currentRequest_->requestSize_; + if (currentRequest_->requestWholeFile_) { + len = 0; + } + client_->RequestData(startPos, len, sourceInfo, handleResponseCb); MEDIA_LOG_I("0x%{public}06" PRIXPTR " RequestData end.", FAKE_POINTER(this)); } @@ -910,7 +912,7 @@ void Downloader::HandleFileContentLen(HeaderInfo* header) if (header->contentLen > 0) { MEDIA_LOG_W("Unsupported range, use content length as content file length, contentLen: " PUBLIC_LOG_D32, static_cast(header->contentLen)); - header->fileContentLen = header->contentLen; + header->fileContentLen = static_cast(header->contentLen); } else { MEDIA_LOG_D("fileContentLen and contentLen are both zero."); } @@ -1181,12 +1183,15 @@ void Downloader::SetInterruptState(bool isInterruptNeeded) AutoLock lock(sleepMutex_); isInterruptNeeded_ = isInterruptNeeded; } + if (currentRequest_ != nullptr) { + currentRequest_->isInterruptNeeded_ = isInterruptNeeded; + } if (isInterruptNeeded) { MEDIA_LOG_I("SetInterruptState, Notify."); sleepCond_.NotifyOne(); } - if (currentRequest_ != nullptr) { - currentRequest_->isInterruptNeeded_ = isInterruptNeeded; + if (sourceLoader_ != nullptr) { + client_->Close(false); } NotifyLoopPause(); } @@ -1232,21 +1237,19 @@ void Downloader::StopBufferring() MediaAVCodec::AVCodecTrace trace("Downloader::StopBufferring"); FALSE_RETURN_MSG(task_ != nullptr && currentRequest_ != nullptr, "task or request is null"); if (isAppBackground_) { + FALSE_RETURN_NOLOG(client_ != nullptr); + MEDIA_LOG_I("StopBufferring: is task not running."); + client_->Close(false); + client_->Deinit(); { - AutoLock lk(deinitMutex_); - FALSE_RETURN_NOLOG(!task_->IsTaskRunning() && client_ != nullptr); - MEDIA_LOG_I("StopBufferring: is task not running."); - isClientClose_ = true; - client_->Close(false); - client_->Deinit(); + AutoLock lk(operatorMutex_); client_ = nullptr; } } else { { - AutoLock lk(deinitMutex_); - if (isClientClose_ && client_ == nullptr) { + AutoLock lk(operatorMutex_); + if (client_ == nullptr) { MEDIA_LOG_I("StopBufferring: restart task."); - isClientClose_ = false; client_ = NetworkClient::GetInstance(&RxHeaderData, &RxBodyData, this); client_->Init(); client_->Open(currentRequest_->url_, currentRequest_->httpHeader_, diff --git a/services/media_engine/plugins/source/http_source/download/downloader.h b/services/media_engine/plugins/source/http_source/download/downloader.h index b9bbd421af300bd7f1fbb3a20944271d555feec5..4a017d2da93aae14d23523baa9ee4dfa436306f7 100644 --- a/services/media_engine/plugins/source/http_source/download/downloader.h +++ b/services/media_engine/plugins/source/http_source/download/downloader.h @@ -220,6 +220,7 @@ private: void RequestData(); void HandlePlayingFinish(); void HandleRetOK(); + void HandleResponseCb(int32_t clientCode, int32_t serverCode, Status& ret); static size_t RxBodyData(void* buffer, size_t size, size_t nitems, void* userParam); static size_t RxHeaderData(void* buffer, size_t size, size_t nitems, void* userParam); static bool HandleContentRange(HeaderInfo* info, char* key, char* next, size_t size, size_t nitems); @@ -272,7 +273,6 @@ private: std::shared_ptr loadingReques_; bool isNotBlock_ {false}; std::string appPreviousRequestUrl_ {}; - FairMutex deinitMutex_ {}; std::string contentType_; bool isContentTypeUpdated_{false}; ConditionVariable sleepCond_; diff --git a/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.cpp b/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.cpp index 0ebf03a3bb8cf1e12fffbf0d6d7eaadd847e7e6c..3b323b2915e0a729705d63e186371bdc8787d96b 100644 --- a/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.cpp +++ b/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.cpp @@ -709,7 +709,8 @@ Status HlsMediaDownloader::Read(unsigned char* buff, ReadDataInfo& readDataInfo) double readDuration = static_cast(readRecordDuringTime_) / SECOND_TO_MILLISECONDS; if (readDuration > ZERO_THRESHOLD) { double readSpeed = readTotalBytes_ * BYTES_TO_BIT / readDuration; // bps - readBitrate_ = static_cast(readSpeed); // bps + int32_t temp = static_cast(readSpeed); + readBitrate_ = temp > 0 ? static_cast(temp) : readBitrate_; MEDIA_LOG_D("Current read speed: " PUBLIC_LOG_D32 " Kbit/s,Current buffer size: " PUBLIC_LOG_U64 " KByte", static_cast(readSpeed / KILO), static_cast(GetBufferSize() / KILO)); MediaAVCodec::AVCodecTrace trace("HlsMediaDownloader::Read, read speed: " + @@ -1209,7 +1210,7 @@ void HlsMediaDownloader::DownloadReport() // Remaining playable time: s uint64_t bufferDuration = 0; if (readBitrate_ > 0) { - bufferDuration = bufferedDuration_ / readBitrate_; + bufferDuration = bufferedDuration_ / static_cast(readBitrate_); } else { bufferDuration = bufferedDuration_ / CURRENT_BIT_RATE; } @@ -1744,7 +1745,7 @@ void HlsMediaDownloader::GetPlaybackInfo(PlaybackInfo& playbackInfo) size_t remainingBuffer = GetBufferSize(); uint64_t bufferDuration = 0; if (readBitrate_ > 0) { - bufferDuration = static_cast(remainingBuffer) / readBitrate_; + bufferDuration = static_cast(remainingBuffer) / static_cast(readBitrate_); } else { bufferDuration = static_cast(remainingBuffer) / CURRENT_BIT_RATE; } @@ -1794,7 +1795,7 @@ Status HlsMediaDownloader::SetCurrentBitRate(int32_t bitRate, int32_t streamID) currentBitRate_ = -1; // -1 } else { int32_t playlistBitrate = static_cast(playlistDownloader_->GetCurBitrate()); - currentBitRate_ = std::max(playlistBitrate, bitRate); + currentBitRate_ = std::max(playlistBitrate, static_cast(bitRate)); MEDIA_LOG_I("HLS playlistBitrate: " PUBLIC_LOG_D32 " currentBitRate: " PUBLIC_LOG_D32, playlistBitrate, currentBitRate_); } @@ -1807,7 +1808,7 @@ Status HlsMediaDownloader::SetCurrentBitRate(int32_t bitRate, int32_t streamID) void HlsMediaDownloader::CalculateBitRate(size_t fragmentSize, double duration) { - if (fragmentSize == 0 || duration == 0) { + if (fragmentSize == 0 || duration < ZERO_THRESHOLD) { return; } double divisorFragmentSize = (static_cast(fragmentSize) / static_cast(ONE_SECONDS)) @@ -2004,6 +2005,9 @@ bool HlsMediaDownloader::IsCachedInitSizeReady(int32_t wantInitSize) bool HlsMediaDownloader::GetPlayable() { + if (isBuffering_) { + return false; + } if (!isFirstFrameArrived_) { return false; } @@ -2183,11 +2187,6 @@ uint64_t HlsMediaDownloader::GetCachedDuration() return cachedDuration_; } -uint64_t HlsMediaDownloader::GetMemorySize() -{ - return memorySize_; -} - bool HlsMediaDownloader::CheckLoopTimeout(int64_t loopStartTime) { int64_t now = loopInterruptClock_.ElapsedSeconds(); @@ -2273,6 +2272,11 @@ size_t HlsMediaDownloader::GetTotalTsBuffersize() PUBLIC_LOG_U32 " offset: " PUBLIC_LOG_U64, readTsIndex_.load(), tsIndex, offset); return totalBufferSize; } + +uint64_t HlsMediaDownloader::GetMemorySize() +{ + return memorySize_; +} } } } diff --git a/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.h b/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.h index 618625caed1b3b1134bf63ba94c69b01745a3535..2ef7bb3cabfc770641816a5716416be9233891b1 100644 --- a/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.h +++ b/services/media_engine/plugins/source/http_source/hls/hls_media_downloader.h @@ -106,13 +106,13 @@ public: Status StopBufferring(bool isAppBackground) override; void WaitForBufferingEnd() override; void SetIsReportedErrorCode() override; - bool SetInitialBufferSize(int32_t offset, int32_t size) override; void SetPlayStrategy(const std::shared_ptr& playStrategy) override; + bool SetInitialBufferSize(int32_t offset, int32_t size) override; void NotifyInitSuccess() override; uint64_t GetCachedDuration() override; - uint64_t GetMemorySize() override; Status GetStreamInfo(std::vector& streams) override; bool IsHlsFmp4() override; + uint64_t GetMemorySize() override; std::string GetContentType() override; private: @@ -311,19 +311,19 @@ private: double bufferDurationForPlaying_ {0}; uint64_t waterlineForPlaying_ {0}; std::atomic isDemuxerInitSuccess_ {false}; + std::atomic isTimeoutErrorNotified_ {false}; size_t timeoutInterval_ = 0; std::shared_ptr sourceLoader_; - std::atomic isTimeoutErrorNotified_ {false}; std::atomic isNeedResume_ {false}; uint64_t cachedDuration_ {0}; - uint64_t memorySize_ {0}; SteadyClock loopInterruptClock_; std::map tsStreamIdInfo_ {}; uint32_t curStreamId_ {0}; std::atomic isNeedReadHeader_ {false}; std::atomic isNeedResetOffset_ {false}; + uint64_t memorySize_ {0}; }; } } diff --git a/services/media_engine/plugins/source/http_source/hls/playlist_downloader.cpp b/services/media_engine/plugins/source/http_source/hls/playlist_downloader.cpp index e1f857f81a60aca38d7ec8ffcdcf3e5975e2be4c..eadf606bee2dcce03dac02aef7f9bbae5f985169 100644 --- a/services/media_engine/plugins/source/http_source/hls/playlist_downloader.cpp +++ b/services/media_engine/plugins/source/http_source/hls/playlist_downloader.cpp @@ -54,7 +54,7 @@ void PlayListDownloader::PlayListDownloaderInit() updateTask_->RegisterJob([this] { UpdateManifest(); size_t updateTime = GetLiveUpdateGap(); - if (updateTime > 0) { + if (updateTime > 0 && updateTime > static_cast(PLAYLIST_UPDATE_RATE)) { return updateTime; } return static_cast(PLAYLIST_UPDATE_RATE); diff --git a/services/media_engine/plugins/source/http_source/http/http_media_downloader.cpp b/services/media_engine/plugins/source/http_source/http/http_media_downloader.cpp index 34a55f7359986a2712874f4dcc77d5fa53f621dc..92c12416bdcaf95e6620e446a6c492d38f0aaf86 100644 --- a/services/media_engine/plugins/source/http_source/http/http_media_downloader.cpp +++ b/services/media_engine/plugins/source/http_source/http/http_media_downloader.cpp @@ -42,6 +42,7 @@ constexpr int START_PLAY_WATER_LINE = 512 * 1024; constexpr int DATA_USAGE_NTERVAL = 300 * 1000; constexpr double ZERO_THRESHOLD = 1e-9; constexpr size_t PLAY_WATER_LINE = 5 * 1024; +constexpr size_t FLV_PLAY_WATER_LINE = 20 * 1024; constexpr size_t DEFAULT_WATER_LINE_ABOVE = 48 * 10 * 1024; constexpr int FIVE_MICROSECOND = 5; constexpr int32_t ONE_HUNDRED_MILLIONSECOND = 100; @@ -55,7 +56,7 @@ constexpr int32_t ONE_SECONDS = 1000; constexpr int32_t TWO_SECONDS = 2000; constexpr int32_t TEN_MILLISECONDS = 10; constexpr float WATER_LINE_ABOVE_LIMIT_RATIO = 0.6; -constexpr float CACHE_LEVEL_1 = 2; +constexpr float CACHE_LEVEL_1 = 0.5; constexpr float DEFAULT_CACHE_TIME = 5; constexpr size_t MAX_BUFFERING_TIME_OUT = 30 * 1000; constexpr size_t MAX_BUFFERING_TIME_OUT_DELAY = 60 * 1000; @@ -152,6 +153,7 @@ HttpMediaDownloader::HttpMediaDownloader(std::string url, uint32_t expectBufferD timeoutInterval_ = MAX_BUFFERING_TIME_OUT; writeBitrateCaculator_ = std::make_shared(); steadyClock_.Reset(); + loopInterruptClock_.Reset(); waterLineAbove_ = PLAY_WATER_LINE; recordData_ = std::make_shared(); } @@ -375,6 +377,9 @@ bool HttpMediaDownloader::StartBufferingCheck(unsigned int& wantReadLength) size_t fileRemain = 0; size_t fileContenLen = downloadRequest_->GetFileContentLength(); cacheWaterLine = std::max(static_cast(wantReadLength), PLAY_WATER_LINE); + if (isRingBuffer_) { + cacheWaterLine = std::max(static_cast(wantReadLength), FLV_PLAY_WATER_LINE); + } if (fileContenLen > readOffset_) { fileRemain = fileContenLen - readOffset_; cacheWaterLine = std::min(fileRemain, cacheWaterLine); @@ -493,7 +498,11 @@ Status HttpMediaDownloader::ReadCacheBuffer(unsigned char* buff, ReadDataInfo& r PUBLIC_LOG_ZU, readDataInfo.wantReadLength_, readOffset_, remain); size_t hasReadSize = 0; wantedReadLength_ = static_cast(readDataInfo.wantReadLength_); + int64_t loopStartTime = loopInterruptClock_.ElapsedSeconds(); while (hasReadSize < readDataInfo.wantReadLength_ && !isInterruptNeeded_.load()) { + if (CheckLoopTimeout(loopStartTime)) { + break; + } Status tempStatus = ReadCacheBufferLoop(buff, readDataInfo); if (tempStatus != Status::ERROR_UNKNOWN) { return tempStatus; @@ -827,7 +836,7 @@ bool HttpMediaDownloader::HandleSeekHit(int64_t offset) { MEDIA_LOG_D("HTTP Seek hit."); if (!isLargeOffsetSpan_ && cacheMediaBuffer_->IsReadSplit(offset) && isNeedClearHasRead_) { - MEDIA_LOG_D("HTTP seek hit return, because IsReadSplit"); + MEDIA_LOG_D("HTTP seek hit return, because IsReadSplit."); return true; } size_t fileContentLength = downloadRequest_->GetFileContentLength(); @@ -854,7 +863,7 @@ bool HttpMediaDownloader::HandleSeekHit(int64_t offset) return true; } -bool HttpMediaDownloader::SeekCacheBuffer(int64_t offset) +bool HttpMediaDownloader::SeekCacheBuffer(int64_t offset, bool& isSeekHit) { readOffset_ = static_cast(offset); if (cacheMediaBuffer_->GetBufferSize(offset) == 0 && offset < 500) { // 500 @@ -871,15 +880,17 @@ bool HttpMediaDownloader::SeekCacheBuffer(int64_t offset) size_t remain = cacheMediaBuffer_->GetBufferSize(offset); MEDIA_LOG_I("HTTP Seek: buffer size " PUBLIC_LOG_ZU ", offset " PUBLIC_LOG_D64, remain, offset); if (remain > 0) { + isSeekHit = true; return HandleSeekHit(offset); } + isSeekHit = false; MEDIA_LOG_I("HTTP Seek miss."); - size_t fileContenLen = downloadRequest_->GetFileContentLength(); - isNeedClearHasRead_ = fileContenLen > LARGE_VIDEO_THRESHOLD ? true : false; + size_t fileContentLength = downloadRequest_->GetFileContentLength(); + isNeedClearHasRead_ = fileContentLength > LARGE_VIDEO_THRESHOLD ? true : false; uint64_t diff = static_cast(offset) > writeOffset_ ? - static_cast(offset) - writeOffset_ : 0; + static_cast(offset) - writeOffset_ : 0; if (diff > 0 && diff < ALLOW_SEEK_MIN_SIZE && sourceLoader_ == nullptr) { isSeekWait_ = true; MEDIA_LOG_I("HTTP Seek miss, diff is too small so return and wait."); @@ -888,12 +899,12 @@ bool HttpMediaDownloader::SeekCacheBuffer(int64_t offset) return ChangeDownloadPos(false); } -bool HttpMediaDownloader::SeekToPos(int64_t offset) +bool HttpMediaDownloader::SeekToPos(int64_t offset, bool& isSeekHit) { if (isRingBuffer_) { return SeekRingBuffer(offset); } else { - return SeekCacheBuffer(offset); + return SeekCacheBuffer(offset, isSeekHit); } } @@ -1634,6 +1645,7 @@ void HttpMediaDownloader::ClearCacheBuffer() cacheMediaBuffer_->Clear(); isNeedDropData_ = false; downloader_->Seek(readOffset_); + writeOffset_ = readOffset_; downloader_->Resume(); uint64_t freeSize = cacheMediaBuffer_->GetFreeSize(); MEDIA_LOG_I("HTTP ClearCacheBuffer end, freeSize: " PUBLIC_LOG_U64, freeSize); @@ -1732,6 +1744,46 @@ void HttpMediaDownloader::NotifyInitSuccess() bufferingTime_ = static_cast(steadyClock_.ElapsedMilliseconds()); } +uint64_t HttpMediaDownloader::GetCachedDuration() +{ + MEDIA_LOG_I("HTTP GetCachedDuration: " PUBLIC_LOG_U64, cachedDuration_); + return cachedDuration_; +} + +void HttpMediaDownloader::RestartAndClearBuffer() +{ + FALSE_RETURN_MSG(downloader_ != nullptr, "downloader_ is nullptr"); + FALSE_RETURN_MSG(ringBuffer_ != nullptr || cacheMediaBuffer_ != nullptr, "buffer is nullptr"); + MEDIA_LOG_I("HTTP RestartAndClearBuffer in."); + { + AutoLock lk(bufferingEndMutex_); + isBuffering_.store(false); + bufferingEndCond_.NotifyAll(); + } + isAllowResume_.store(true); + if (isRingBuffer_) { + ringBuffer_->SetActive(false); + downloader_->Pause(); + ringBuffer_->SetActive(true); + MEDIA_LOG_I("HTTP clear ringbuffer done."); + } else { + downloader_->Pause(); + cacheMediaBuffer_->Clear(); + MEDIA_LOG_I("HTTP clear cachebuffer done."); + } + downloader_->Resume(); + isAllowResume_.store(true); + MEDIA_LOG_I("HTTP RestartAndClearBuffer out."); +} + +bool HttpMediaDownloader::IsFlvLive() +{ + FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); + FALSE_RETURN_V_MSG_E(downloadRequest_ != nullptr, false, "downloadRequest_ is nullptr"); + size_t fileContenLen = downloadRequest_->GetFileContentLength(); + return fileContenLen == 0 && isRingBuffer_; +} + void HttpMediaDownloader::SetStartPts(int64_t startPts) { flvStartPts_ = startPts; @@ -1848,52 +1900,16 @@ uint32_t HttpMediaDownloader::GetResolutionDelta(uint32_t width, uint32_t height } } -uint64_t HttpMediaDownloader::GetCachedDuration() -{ - MEDIA_LOG_I("HTTP GetCachedDuration: " PUBLIC_LOG_U64, cachedDuration_); - return cachedDuration_; -} - -void HttpMediaDownloader::RestartAndClearBuffer() -{ - FALSE_RETURN_MSG(downloader_ != nullptr, "downloader_ is nullptr"); - FALSE_RETURN_MSG(ringBuffer_ != nullptr || cacheMediaBuffer_ != nullptr, "buffer is nullptr"); - MEDIA_LOG_I("HTTP RestartAndClearBuffer in."); - { - AutoLock lk(bufferingEndMutex_); - isBuffering_.store(false); - bufferingEndCond_.NotifyAll(); - } - isAllowResume_.store(true); - if (isRingBuffer_) { - ringBuffer_->SetActive(false); - downloader_->Pause(); - ringBuffer_->SetActive(true); - MEDIA_LOG_I("HTTP clear ringbuffer done."); - } else { - downloader_->Pause(); - cacheMediaBuffer_->Clear(); - MEDIA_LOG_I("HTTP clear cachebuffer done."); - } - downloader_->Resume(); - isAllowResume_.store(false); - MEDIA_LOG_I("HTTP RestartAndClearBuffer out."); -} - -bool HttpMediaDownloader::IsFlvLive() -{ - FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); - FALSE_RETURN_V_MSG_E(downloadRequest_ != nullptr, false, "downloadRequest_ is nullptr"); - size_t fileContenLen = downloadRequest_->GetFileContentLength(); - return fileContenLen == 0 && isRingBuffer_; -} - -uint64_t HttpMediaDownloader::GetMemorySize() +bool HttpMediaDownloader::CheckLoopTimeout(int64_t startLoopTime) { - if (totalBufferSize_ <= 0) { - return 0; + int64_t now = loopInterruptClock_.ElapsedSeconds(); + int64_t loopDuration = now > startLoopTime ? now - startLoopTime : 0; + bool isLoopTimeout = loopDuration > LOOP_TIMEOUT ? true : false; + if (isLoopTimeout) { + SetDownloadErrorState(); + MEDIA_LOG_E("loop timeout"); } - return static_cast(totalBufferSize_); + return isLoopTimeout; } void HttpMediaDownloader::SetIsTriggerAutoMode(bool isAuto) @@ -1988,6 +2004,14 @@ void HttpMediaDownloader::ClearBuffer() } } +uint64_t HttpMediaDownloader::GetMemorySize() +{ + if (totalBufferSize_ <= 0) { + return 0; + } + return static_cast(totalBufferSize_); +} + std::string HttpMediaDownloader::GetCurUrl() { FALSE_RETURN_V_MSG_E(downloadRequest_ != nullptr, "", "currentRequest_ is nullptr"); @@ -1997,7 +2021,6 @@ std::string HttpMediaDownloader::GetCurUrl() } return downloadRequest_->GetUrl(); } - } } } diff --git a/services/media_engine/plugins/source/http_source/http/http_media_downloader.h b/services/media_engine/plugins/source/http_source/http/http_media_downloader.h index 82e465c5116405cfa48bf0e82b839d974b28f19f..1a80a6852b23de10751243325cf8ffc3bf9589b2 100644 --- a/services/media_engine/plugins/source/http_source/http/http_media_downloader.h +++ b/services/media_engine/plugins/source/http_source/http/http_media_downloader.h @@ -45,7 +45,7 @@ public: void Pause() override; void Resume() override; Status Read(unsigned char* buff, ReadDataInfo& readDataInfo) override; - bool SeekToPos(int64_t offset) override; + bool SeekToPos(int64_t offset, bool& isSeekHit) override; size_t GetContentLength() const override; int64_t GetDuration() const override; Seekable GetSeekable() const override; @@ -94,18 +94,18 @@ public: bool SetInitialBufferSize(int32_t offset, int32_t size) override; void SetPlayStrategy(const std::shared_ptr& playStrategy) override; void NotifyInitSuccess() override; + uint64_t GetCachedDuration() override; + void RestartAndClearBuffer() override; + bool IsFlvLive() override; void SetStartPts(int64_t startPts) override; void SetExtraCache(uint64_t cacheDuration) override; bool SelectBitRate(uint32_t bitRate) override; bool AutoSelectBitRate(uint32_t bitRate) override; void SetMediaStreams(const MediaStreamList& mediaStreams) override; - uint64_t GetCachedDuration() override; - void RestartAndClearBuffer() override; - bool IsFlvLive() override; - uint64_t GetMemorySize() override; std::string GetContentType() override; void SetIsTriggerAutoMode(bool isAuto) override; void ClearBuffer() override; + uint64_t GetMemorySize() override; std::string GetCurUrl() override; private: @@ -121,7 +121,7 @@ private: Status ReadCacheBufferLoop(unsigned char* buff, ReadDataInfo& readDataInfo); Status ReadCacheBuffer(unsigned char* buff, ReadDataInfo& readDataInfo); bool SeekRingBuffer(int64_t offset); - bool SeekCacheBuffer(int64_t offset); + bool SeekCacheBuffer(int64_t offset, bool& isSeekHit); void InitRingBuffer(uint32_t expectBufferDuration); void InitCacheBuffer(uint32_t expectBufferDuration); @@ -154,6 +154,7 @@ private: bool IsNearToInitResolution(const std::shared_ptr &choosedStream, const std::shared_ptr ¤tStream); uint32_t GetResolutionDelta(uint32_t width, uint32_t height); + bool CheckLoopTimeout(int64_t startLoopTime); bool CheckAutoSelectBitrate(); bool IsAutoSelectConditionOk(); void WaitCacheBufferInit(); @@ -241,24 +242,24 @@ private: double bufferDurationForPlaying_ {0}; uint64_t waterlineForPlaying_ {0}; std::atomic isDemuxerInitSuccess_ {false}; - + std::atomic isTimeoutErrorNotified_ {false}; size_t timeoutInterval_ = 0; std::shared_ptr sourceLoader_; - int64_t flvStartPts_ {0}; - uint64_t extraCache_ {0}; - MediaStreamList playMediaStreams_; - std::atomic isSelectingBitrate_ {false}; - std::shared_ptr defaultStream_ {nullptr}; - uint32_t initResolution_ {0}; - std::atomic isTimeoutErrorNotified_ {false}; std::atomic isNeedResume_ {false}; size_t totalConsumeSize_ {0}; FairMutex savedataMutex_ {}; - uint64_t cachedDuration_ {0}; - std::atomic isAllowResume_ {false}; bool isCacheBufferInited_ {false}; ConditionVariable sleepCond_; FairMutex sleepMutex_; + uint64_t cachedDuration_ {0}; + std::atomic isAllowResume_ {false}; + int64_t flvStartPts_ {0}; + uint64_t extraCache_ {0}; + MediaStreamList playMediaStreams_; + std::atomic isSelectingBitrate_ {false}; + std::shared_ptr defaultStream_ {nullptr}; + uint32_t initResolution_ {0}; + SteadyClock loopInterruptClock_; std::atomic isAutoSelectBitrate_ {true}; std::deque downloadSpeeds_; uint32_t videoBitrate_ {0}; diff --git a/services/media_engine/plugins/source/http_source/http_source_plugin.cpp b/services/media_engine/plugins/source/http_source/http_source_plugin.cpp index 1aef59a3b272c5ec6d8701820a2b9b1ee2e7ed9d..d4a719c370af9ca5b5f97d00767b144a6821378c 100644 --- a/services/media_engine/plugins/source/http_source/http_source_plugin.cpp +++ b/services/media_engine/plugins/source/http_source/http_source_plugin.cpp @@ -381,7 +381,8 @@ Status HttpSourcePlugin::SeekTo(uint64_t offset) } FALSE_RETURN_V(offset <= downloader_->GetContentLength(), Status::ERROR_INVALID_PARAMETER); } - FALSE_RETURN_V(downloader_->SeekToPos(offset), Status::ERROR_UNKNOWN); + bool isSeekHit = false; + FALSE_RETURN_V(downloader_->SeekToPos(offset, isSeekHit), Status::ERROR_UNKNOWN); return Status::OK; } @@ -594,18 +595,18 @@ bool HttpSourcePlugin::IsFlvLive() return downloader_->IsFlvLive(); } -uint64_t HttpSourcePlugin::GetMemorySize() -{ - FALSE_RETURN_V_MSG_E(downloader_ != nullptr, 0, "downloader_ is nullptr"); - return downloader_->GetMemorySize(); -} - bool HttpSourcePlugin::IsHlsFmp4() { FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); return downloader_->IsHlsFmp4(); } +uint64_t HttpSourcePlugin::GetMemorySize() +{ + FALSE_RETURN_V_MSG_E(downloader_ != nullptr, 0, "downloader_ is nullptr"); + return downloader_->GetMemorySize(); +} + std::string HttpSourcePlugin::GetCurUrl() { FALSE_RETURN_V_MSG_E(downloader_ != nullptr, 0, "downloader_ is nullptr"); diff --git a/services/media_engine/plugins/source/http_source/http_source_plugin.h b/services/media_engine/plugins/source/http_source/http_source_plugin.h index 409aa0bb0faf14f5425475554f49b1952416ac49..fdae4536364cafed0b869cad33b355685c47dc91 100644 --- a/services/media_engine/plugins/source/http_source/http_source_plugin.h +++ b/services/media_engine/plugins/source/http_source/http_source_plugin.h @@ -72,8 +72,8 @@ public: uint64_t GetCachedDuration() override; void RestartAndClearBuffer() override; bool IsFlvLive() override; - uint64_t GetMemorySize() override; bool IsHlsFmp4() override; + uint64_t GetMemorySize() override; std::string GetContentType() override; private: diff --git a/services/media_engine/plugins/source/http_source/media_downloader.h b/services/media_engine/plugins/source/http_source/media_downloader.h index 11703801f9dfae3a0fa0bd25330df9a002319d22..415191866638092fc6e3acc2b565ca2783027f78 100644 --- a/services/media_engine/plugins/source/http_source/media_downloader.h +++ b/services/media_engine/plugins/source/http_source/media_downloader.h @@ -48,7 +48,7 @@ public: virtual void Pause() = 0; virtual void Resume() = 0; virtual Status Read(unsigned char* buff, ReadDataInfo& readDataInfo) = 0; - virtual bool SeekToPos(int64_t offset) + virtual bool SeekToPos(int64_t offset, bool& isSeekHit) { MEDIA_LOG_E("SeekToPos is unimplemented."); return false; @@ -56,7 +56,7 @@ public: virtual size_t GetBufferSize() const = 0; virtual bool GetPlayable() { - return true; + return false; } virtual bool GetBufferingTimeOut() = 0; virtual size_t GetContentLength() const = 0; @@ -171,6 +171,15 @@ public: } virtual void NotifyInitSuccess() {} + virtual uint64_t GetCachedDuration() + { + return 0; + } + virtual void RestartAndClearBuffer() {} + virtual bool IsFlvLive() + { + return false; + } virtual void SetStartPts(int64_t startPts) { @@ -186,19 +195,6 @@ public: { MEDIA_LOG_W("SetMediaStreams is unimplemented."); } - virtual uint64_t GetCachedDuration() - { - return 0; - } - virtual void RestartAndClearBuffer() {} - virtual bool IsFlvLive() - { - return false; - } - virtual uint64_t GetMemorySize() - { - return 0; - } virtual std::string GetContentType() { return ""; @@ -211,6 +207,12 @@ public: { return false; } + + virtual uint64_t GetMemorySize() + { + return 0; + } + virtual std::string GetCurUrl() { return ""; diff --git a/services/media_engine/plugins/source/http_source/monitor/download_monitor.cpp b/services/media_engine/plugins/source/http_source/monitor/download_monitor.cpp index 3e3baace44c85739efe81b1a5067730c84d3b972..d4de1de9c4366576bf7eb5f4109f593bd3f67bc6 100644 --- a/services/media_engine/plugins/source/http_source/monitor/download_monitor.cpp +++ b/services/media_engine/plugins/source/http_source/monitor/download_monitor.cpp @@ -23,7 +23,6 @@ namespace Plugins { namespace HttpPlugin { namespace { constexpr int RETRY_TIMES_TO_REPORT_ERROR = 10; - constexpr int RETRY_THRESHOLD = 1; constexpr int APP_DOWNLOAD_RETRY_TIMES = 60; constexpr int SERVER_ERROR_THRESHOLD = 500; constexpr int32_t READ_LOG_FEQUENCE = 50; @@ -144,14 +143,16 @@ Status DownloadMonitor::Read(unsigned char* buff, ReadDataInfo& readDataInfo) return ret; } -bool DownloadMonitor::SeekToPos(int64_t offset) +bool DownloadMonitor::SeekToPos(int64_t offset, bool& isSeekHIt) { isPlaying_ = true; - { + bool isSeekHit = false; + bool res = downloader_->SeekToPos(offset, isSeekHit); + if (!isSeekHit) { AutoLock lock(taskMutex_); retryTasks_.clear(); } - return downloader_->SeekToPos(offset); + return res; } size_t DownloadMonitor::GetContentLength() const @@ -216,23 +217,23 @@ void DownloadMonitor::NotifyError(int32_t clientErrorCode, int32_t serverErrorCo MEDIA_LOG_E("callback_ is nullptr, notify error failed."); return; } - if (serverErrorCode != 0) { + if (clientErrorCode != 0) { int32_t errorCode = MediaServiceErrCode::MSERR_DATA_SOURCE_IO_ERROR; - GetServerMediaServiceErrorCode(serverErrorCode, errorCode); + GetClientMediaServiceErrorCode(clientErrorCode, errorCode); if (downloader_ != nullptr) { downloader_->SetIsReportedErrorCode(); } - callback_->OnEvent({PluginEventType::SERVER_ERROR, {errorCode}, "server error"}); - MEDIA_LOG_E("Notify http server error, code " PUBLIC_LOG_D32, serverErrorCode); + callback_->OnEvent({PluginEventType::SERVER_ERROR, {errorCode}, "client error"}); + MEDIA_LOG_E("Notify http client error, code " PUBLIC_LOG_D32, clientErrorCode); } - if (clientErrorCode != 0) { + if (serverErrorCode != 0) { int32_t errorCode = MediaServiceErrCode::MSERR_DATA_SOURCE_IO_ERROR; - GetClientMediaServiceErrorCode(clientErrorCode, errorCode); + GetServerMediaServiceErrorCode(serverErrorCode, errorCode); if (downloader_ != nullptr) { downloader_->SetIsReportedErrorCode(); } - callback_->OnEvent({PluginEventType::SERVER_ERROR, {errorCode}, "client error"}); - MEDIA_LOG_E("Notify http client error, code " PUBLIC_LOG_D32, clientErrorCode); + callback_->OnEvent({PluginEventType::SERVER_ERROR, {errorCode}, "server error"}); + MEDIA_LOG_E("Notify http server error, code " PUBLIC_LOG_D32, serverErrorCode); } } @@ -242,9 +243,12 @@ bool DownloadMonitor::NeedRetry(const std::shared_ptr& request) int serverError = request->GetServerError(); auto retryTimes = request->GetRetryTimes(); isNeedClearBuffer_ = serverError == REDIRECT_CODE; - std::set notRetryErrorSet = {400, 401}; MEDIA_LOG_I("NeedRetry: clientError = " PUBLIC_LOG_D32 ", serverError = " PUBLIC_LOG_D32 ", retryTimes = " PUBLIC_LOG_D32 ",", clientError, serverError, retryTimes); + if (CLIENT_NOT_RETRY_ERROR_CODES.find(static_cast(clientError)) != CLIENT_NOT_RETRY_ERROR_CODES.end()) { + MEDIA_LOG_I("Client error code is 23 or 992, not retry."); + return false; + } if (downloader_ != nullptr && downloader_->IsNotRetry(request)) { // flv living NotifyError(clientError, serverError); @@ -255,10 +259,7 @@ bool DownloadMonitor::NeedRetry(const std::shared_ptr& request) if (clientError == 0 && serverError == 0) { return false; } - if (CLIENT_NOT_RETRY_ERROR_CODES.find(clientError) != CLIENT_NOT_RETRY_ERROR_CODES.end()) { - return false; - } - if (retryTimes <= RETRY_THRESHOLD || (GetPlayable() && !GetReadTimeOut(clientError == -1))) { // -1: NOT_READY + if ((GetPlayable() && !GetReadTimeOut(clientError == -1))) { // -1: NOT_READY return true; } @@ -481,6 +482,24 @@ void DownloadMonitor::NotifyInitSuccess() downloader_->NotifyInitSuccess(); } +uint64_t DownloadMonitor::GetCachedDuration() +{ + FALSE_RETURN_V_MSG_E(downloader_ != nullptr, 0, "downloader_ is nullptr"); + return downloader_->GetCachedDuration(); +} + +void DownloadMonitor::RestartAndClearBuffer() +{ + FALSE_RETURN_MSG(downloader_ != nullptr, "downloader_ is nullptr"); + return downloader_->RestartAndClearBuffer(); +} + +bool DownloadMonitor::IsFlvLive() +{ + FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); + return downloader_->IsFlvLive(); +} + void DownloadMonitor::SetStartPts(int64_t startPts) { if (downloader_) { @@ -502,22 +521,10 @@ void DownloadMonitor::SetMediaStreams(const MediaStreamList& mediaStreams) } } -uint64_t DownloadMonitor::GetCachedDuration() -{ - FALSE_RETURN_V_MSG_E(downloader_ != nullptr, 0, "downloader_ is nullptr"); - return downloader_->GetCachedDuration(); -} - -void DownloadMonitor::RestartAndClearBuffer() -{ - FALSE_RETURN_MSG(downloader_ != nullptr, "downloader_ is nullptr"); - return downloader_->RestartAndClearBuffer(); -} - -bool DownloadMonitor::IsFlvLive() +bool DownloadMonitor::IsHlsFmp4() { FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); - return downloader_->IsFlvLive(); + return downloader_->IsHlsFmp4(); } std::string DownloadMonitor::GetContentType() @@ -532,12 +539,6 @@ uint64_t DownloadMonitor::GetMemorySize() return downloader_->GetMemorySize(); } -bool DownloadMonitor::IsHlsFmp4() -{ - FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); - return downloader_->IsHlsFmp4(); -} - std::string DownloadMonitor::GetCurUrl() { FALSE_RETURN_V(downloader_ != nullptr, ""); diff --git a/services/media_engine/plugins/source/http_source/monitor/download_monitor.h b/services/media_engine/plugins/source/http_source/monitor/download_monitor.h index 153b3cccebe2927643b5874d865371a5ff4830b7..680df33efbe69960baf33ae37fe8af9b4a9d5a5e 100644 --- a/services/media_engine/plugins/source/http_source/monitor/download_monitor.h +++ b/services/media_engine/plugins/source/http_source/monitor/download_monitor.h @@ -47,7 +47,7 @@ public: bool Open(const std::string& url, const std::map& httpHeader) override; void Close(bool isAsync) override; Status Read(unsigned char* buff, ReadDataInfo& readDataInfo) override; - bool SeekToPos(int64_t offset) override; + bool SeekToPos(int64_t offset, bool& isSeekHIt) override; void Pause() override; void Resume() override; size_t GetContentLength() const override; @@ -88,8 +88,8 @@ public: uint64_t GetCachedDuration() override; void RestartAndClearBuffer() override; bool IsFlvLive() override; - uint64_t GetMemorySize() override; bool IsHlsFmp4() override; + uint64_t GetMemorySize() override; std::string GetContentType() override; std::string GetCurUrl() override; diff --git a/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.cpp b/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.cpp index 7ed28785a4869089de11d5d84ed1e68e6e4180fe..f815d9e9ac8cc267faf3bd6e43f29ceaa9509d5e 100644 --- a/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.cpp +++ b/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.cpp @@ -26,9 +26,6 @@ namespace OHOS { namespace Media { -namespace { -constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_STREAM_SOURCE, "HiStreamer" }; -} constexpr size_t CACHE_FRAGMENT_MAX_NUM_DEFAULT = 300; // Maximum number of fragment nodes constexpr size_t CACHE_FRAGMENT_MAX_NUM_LARGE = 10; // Maximum number of fragment nodes constexpr size_t CACHE_FRAGMENT_MIN_NUM_DEFAULT = 3; // Minimum number of fragment nodes @@ -994,6 +991,33 @@ void CacheMediaChunkBufferImpl::Dump(uint64_t param) void CacheMediaChunkBufferImpl::DumpInner(uint64_t param) { (void)param; + MEDIA_LOG_D("cacheBuff total buffer size : " PUBLIC_LOG_U64, totalBuffSize_); + MEDIA_LOG_D("cacheBuff total chunk size : " PUBLIC_LOG_U32, chunkSize_); + MEDIA_LOG_D("cacheBuff total chunk num : " PUBLIC_LOG_U32, chunkMaxNum_); + MEDIA_LOG_D("cacheBuff total read size : " PUBLIC_LOG_U64, totalReadSize_); + MEDIA_LOG_D("cacheBuff read size factor : " PUBLIC_LOG_F, initReadSizeFactor_); + MEDIA_LOG_D("cacheBuff free chunk num : " PUBLIC_LOG_ZU, freeChunks_.size()); + MEDIA_LOG_D("cacheBuff fragment num : " PUBLIC_LOG_ZU, fragmentCacheBuffer_.size()); + for (auto const & fragment : fragmentCacheBuffer_) { + MEDIA_LOG_D("cacheBuff - fragment offset : " PUBLIC_LOG_U64, fragment.offsetBegin); + MEDIA_LOG_D("cacheBuff fragment length : " PUBLIC_LOG_D64, fragment.dataLength); + MEDIA_LOG_D("cacheBuff chunk num : " PUBLIC_LOG_ZU, fragment.chunks.size()); + MEDIA_LOG_D("cacheBuff access length : " PUBLIC_LOG_U64, fragment.accessLength); + MEDIA_LOG_D("cacheBuff read size : " PUBLIC_LOG_U64, fragment.totalReadSize); + if (fragment.accessPos != fragment.chunks.end()) { + auto &chunkInfo = *fragment.accessPos; + MEDIA_LOG_D("cacheBuff access offset: " PUBLIC_LOG_D64 ", len: " PUBLIC_LOG_U32, + chunkInfo->offset, chunkInfo->dataLength); + } else { + MEDIA_LOG_D("cacheBuff access ended"); + } + if (!fragment.chunks.empty()) { + auto &chunkInfo = fragment.chunks.back(); + MEDIA_LOG_D("cacheBuff last chunk offset: " PUBLIC_LOG_D64 ", len: " PUBLIC_LOG_U32, + chunkInfo->offset, chunkInfo->dataLength); + } + MEDIA_LOG_D("cacheBuff "); + } } bool CacheMediaChunkBufferImpl::CheckLoopTimeout(int64_t loopStartTime) @@ -1112,9 +1136,9 @@ bool CacheMediaChunkBufferImpl::ClearMiddleReadFragment(uint64_t minOffset, uint if (iter->accessLength <= chunkSize_) { continue; } - MEDIA_LOG_D("ClearMiddleReadFragment, minOffset " PUBLIC_LOG_U64 " maxOffset " - PUBLIC_LOG_U64 " offsetBegin: " PUBLIC_LOG_U64 " dataLength: " PUBLIC_LOG_U64 " accessLength " - PUBLIC_LOG_U64, minOffset, maxOffset, iter->offsetBegin, iter->dataLength, iter->accessLength); + MEDIA_LOG_D("ClearMiddleReadFragment, minOffset: " PUBLIC_LOG_U64 " maxOffset: " + PUBLIC_LOG_U64 " offsetBegin: " PUBLIC_LOG_U64 " dataLength: " PUBLIC_LOG_D64 " accessLength " + PUBLIC_LOG_D64, minOffset, maxOffset, iter->offsetBegin, iter->dataLength, iter->accessLength); auto& fragment = *iter; uint32_t chunksSize = fragment.chunks.size(); for (uint32_t i = 0; i < chunksSize; ++i) { diff --git a/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.h b/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.h index 1b6f7ff55c1d1c272128fbadaac46ecc15566c03..1a19486a0439a4870b3df27aebb427ef70c1723d 100644 --- a/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.h +++ b/services/media_engine/plugins/source/http_source/utils/media_cached_buffer.h @@ -31,7 +31,7 @@ namespace Media { constexpr uint32_t CHUNK_SIZE = 16 * 1024; constexpr uint64_t MAX_CACHE_BUFFER_SIZE = 19 * 1024 * 1024; constexpr int64_t LOOP_TIMEOUT = 60; // s - +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_STREAM_SOURCE, "HiStreamer" }; using Clock = std::chrono::steady_clock; using TimePoint = Clock::time_point; using namespace std::chrono; @@ -129,11 +129,14 @@ protected: } } int64_t loopStartTime = loopInterruptClock_.ElapsedSeconds(); + bool isTimeOut = false; auto fragmentCachePos = std::find_if(fragmentCacheBuffer_.begin(), fragmentCacheBuffer_.end(), - [offset, pred, loopStartTime, this](const auto& fragment) { + [offset, pred, &isTimeOut, &loopStartTime, this](const auto& fragment) { int64_t now = this->loopInterruptClock_.ElapsedSeconds(); int64_t loopDuration = now > loopStartTime ? now - loopStartTime : 0; if (loopDuration > LOOP_TIMEOUT) { + isTimeOut = true; + MEDIA_LOG_E("loop timeout"); return true; } if (pred(offset, fragment.offsetBegin, fragment.offsetBegin + fragment.dataLength)) { @@ -141,6 +144,9 @@ protected: } return false; }); + if (isTimeOut) { + return fragmentCacheBuffer_.end(); + } return fragmentCachePos; } diff --git a/test/unittest/hls_test/m3u8_unit_test.cpp b/test/unittest/hls_test/m3u8_unit_test.cpp index e89ea41963dd831402ba062598427e403dc0f33a..68401785e2ccac19e4b09bc86c790c6ff3ddc95d 100644 --- a/test/unittest/hls_test/m3u8_unit_test.cpp +++ b/test/unittest/hls_test/m3u8_unit_test.cpp @@ -595,4 +595,27 @@ HWTEST_F(M3u8UnitTest, IS_NEAR_TO_INIT_RESOLUTION_001, TestSize.Level1) EXPECT_EQ(master->IsNearToInitResolution(choosedStream, nullptr), false); EXPECT_EQ(master->IsNearToInitResolution(nullptr, nullptr), false); } + +HWTEST_F(M3u8UnitTest, SetInterruptState_001, TestSize.Level1) +{ + std::string url = "http://example.com/test.m3u8"; + auto m3u8 = std::make_shared(testUri, ""); + m3u8->uri_ = url; + m3u8->keyUri_ = std::make_shared(url); + m3u8->DownloadKey(); + m3u8->DownloadMap(url, 0, 0); + EXPECT_NE(m3u8->downloadHeaderRequest_, nullptr); + EXPECT_NE(m3u8->downloadRequest_, nullptr); + std::shared_ptr master = std::make_shared("", url); + master->StartParsing(); + auto stream = std::make_shared("test", url, + std::make_shared(url, "test")); + master->defaultVariant_ = stream; + master->defaultVariant_->m3u8_ = nullptr; + master->SetInterruptState(true); + EXPECT_NE(master->defaultVariant_, nullptr); + master->defaultVariant_ = nullptr; + master->SetInterruptState(true); + EXPECT_EQ(master->defaultVariant_, nullptr); +} } \ No newline at end of file diff --git a/test/unittest/http_source_test/http_media_downloader_unit_test.cpp b/test/unittest/http_source_test/http_media_downloader_unit_test.cpp index dd9c51cdd92e4ee1bb2254f282fd6af31abb4ef2..3e4b3c4c162b194ee1e34db68495af43e54cfda8 100644 --- a/test/unittest/http_source_test/http_media_downloader_unit_test.cpp +++ b/test/unittest/http_source_test/http_media_downloader_unit_test.cpp @@ -223,9 +223,10 @@ HWTEST_F(HttpMediaDownloaderUnitTest, TEST_OPEN_URL, TestSize.Level1) HWTEST_F(HttpMediaDownloaderUnitTest, TEST_SEEK, TestSize.Level1) { MP4httpMediaDownloader->GetSeekable(); - bool result = MP4httpMediaDownloader->SeekToPos(100); + bool isSeekHit = false; + bool result = MP4httpMediaDownloader->SeekToPos(100, isSeekHit); EXPECT_TRUE(result); - result = MP4httpMediaDownloader->SeekToPos(10000000); + result = MP4httpMediaDownloader->SeekToPos(10000000, isSeekHit); EXPECT_TRUE(result); } @@ -333,7 +334,8 @@ HWTEST_F(HttpMediaDownloaderUnitTest, TEST_OPEN_URL_MP4_DOWNLOADINFO, TestSize.L HWTEST_F(HttpMediaDownloaderUnitTest, TEST_SEEK_FLV, TestSize.Level1) { FLVhttpMediaDownloader->GetSeekable(); - bool result = FLVhttpMediaDownloader->SeekToPos(100); + bool isSeekHit = false; + bool result = FLVhttpMediaDownloader->SeekToPos(100, isSeekHit); FLVhttpMediaDownloader->SetReadBlockingFlag(true); EXPECT_TRUE(result); } @@ -464,7 +466,8 @@ HWTEST_F(HttpMediaDownloaderUnitTest, TEST_FLC_SEEK, TestSize.Level1) httpMediaDownloader->downloadErrorState_ = true; httpMediaDownloader->Read(buff, readDataInfo); OSAL::SleepFor(1000); - httpMediaDownloader->SeekToPos(100 * 1024 * 1024); + bool isSeekHit = false; + httpMediaDownloader->SeekToPos(100 * 1024 * 1024, isSeekHit); httpMediaDownloader->Close(true); httpMediaDownloader = nullptr; EXPECT_GE(readDataInfo.realReadLength_, 0);