diff --git a/interfaces/plugin/source_plugin.h b/interfaces/plugin/source_plugin.h index 353b877473b215bbc1b9cc4c4ea6e08d49c9fd4a..0ce705d3de0fa5523fee261bc5e27f7d9705e21c 100644 --- a/interfaces/plugin/source_plugin.h +++ b/interfaces/plugin/source_plugin.h @@ -299,6 +299,10 @@ public: { return 0; } + virtual bool IsHlsEnd() + { + return false; + } }; /// Source plugin api major number. diff --git a/services/media_engine/modules/source/source.cpp b/services/media_engine/modules/source/source.cpp index c8326e4f68d99ac491ebb584b484b3930ed3e761..96bc62672deb4d1e4a185df07c2e3da53d2f7fa2 100644 --- a/services/media_engine/modules/source/source.cpp +++ b/services/media_engine/modules/source/source.cpp @@ -642,5 +642,11 @@ Status Source::StopBufferring(bool isAppBackground) FALSE_RETURN_V_MSG_E(plugin_ != nullptr, Status::ERROR_NULL_POINTER, "plugin_ is nullptr"); return plugin_->StopBufferring(isAppBackground); } + +bool Source::IsHlsEnd() +{ + FALSE_RETURN_V_MSG_E(plugin_ != nullptr, false, "plugin_ is nullptr"); + return plugin_->IsHlsEnd(); +} } // namespace Media } // namespace OHOS \ No newline at end of file diff --git a/services/media_engine/modules/source/source.h b/services/media_engine/modules/source/source.h index cd7193cd33b1379aa032396f412bf9174c1ea2fc..beffafd13bc7aa42a082ddf951de6bfd78ef173c 100644 --- a/services/media_engine/modules/source/source.h +++ b/services/media_engine/modules/source/source.h @@ -132,6 +132,7 @@ public: bool IsHlsFmp4(); uint64_t GetMemorySize(); Status StopBufferring(bool isAppBackground); + bool IsHlsEnd(); private: Status InitPlugin(const std::shared_ptr& source); 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 fcad2ab3d60c852b631808cac63654f33042fa58..ecf62b237a5c6ff2e537e56f93f9c41fec70a5e3 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 @@ -448,6 +448,10 @@ bool HlsMediaDownloader::HandleCache() void HlsMediaDownloader::HandleFfmpegReadback(uint64_t ffmpegOffset) { + if (notNeedReadBack_.load()) { + ffmpegOffset_ = ffmpegOffset; + return; + } if (curStreamId_ > 0 && isNeedResetOffset_.load()) { ffmpegOffset_ = ffmpegOffset; return; @@ -550,6 +554,11 @@ Status HlsMediaDownloader::ReadDelegate(unsigned char* buff, ReadDataInfo& readD MEDIA_LOG_D("HLS Read in: wantReadLength " PUBLIC_LOG_D32 ", readOffset: " PUBLIC_LOG_U64 " readTsIndex: " PUBLIC_LOG_U32 " bufferSize: " PUBLIC_LOG_U64, readDataInfo.wantReadLength_, readOffset_, readTsIndex_.load(), GetCrossTsBuffersize()); + if (isTsEnd_.load()) { + MEDIA_LOG_I("HLS READ TS END"); + isTsEnd_.store(false); + return Status::END_OF_STREAM; + } readDataInfo.isEos_ = CheckReadStatus(); if (readDataInfo.isEos_ && GetBufferSize() == 0 && readTsIndex_ + 1 == backPlayList_.size() && tsStorageInfo_.find(readTsIndex_) != tsStorageInfo_.end() && @@ -634,6 +643,10 @@ void HlsMediaDownloader::ReadCacheBuffer(unsigned char* buff, ReadDataInfo& read tsStorageInfo_[readTsIndex_].second == true) { uint64_t tsEndOffset = SpliceOffset(readTsIndex_, tsStorageInfo_[readTsIndex_].first); if (readOffset_ >= tsEndOffset) { + if (GetHLSDiscontinuity()) { + isTsEnd_.store(true); + notNeedReadBack_.store(true); + } RemoveFmp4PaddingData(buff, readDataInfo); readTsIndex_++; cacheMediaBuffer_->ClearFragmentBeforeOffset(SpliceOffset(readTsIndex_, 0)); @@ -647,7 +660,8 @@ void HlsMediaDownloader::ReadCacheBuffer(unsigned char* buff, ReadDataInfo& read return; } } - if (readDataInfo.realReadLength_ < readDataInfo.wantReadLength_ && readTsIndex_ != backPlayList_.size()) { + if (!GetHLSDiscontinuity() && readDataInfo.realReadLength_ < readDataInfo.wantReadLength_ + && readTsIndex_ != backPlayList_.size()) { uint32_t crossFragLen = readDataInfo.wantReadLength_ - readDataInfo.realReadLength_; uint32_t crossReadLen = cacheMediaBuffer_->Read(buff + readDataInfo.realReadLength_, readOffset_, crossFragLen); @@ -793,6 +807,7 @@ bool HlsMediaDownloader::SeekToTime(int64_t seekTime, SeekMode mode) HandleSeekReady(MediaAVCodec::MediaType::MEDIA_TYPE_VID, curStreamId_, CheckBreakCondition()); MEDIA_LOG_I("HLS SeekToTime end\n"); isSeekingFlag = false; + notNeedReadBack_.store(false); return true; } @@ -1338,10 +1353,12 @@ int64_t HlsMediaDownloader::RequestNewTs(uint64_t seekTime, SeekMode mode, doubl } else { int64_t startTimePos = 0; double lastTotalDuration = totalDuration - hstTime; - if (static_cast(lastTotalDuration) < seekTime) { + if (static_cast(lastTotalDuration) <= seekTime) { startTimePos = static_cast(seekTime) - static_cast(lastTotalDuration); + seekStartTimePos_ = lastTotalDuration; if (startTimePos > (int64_t)(hstTime / HALF_DIVIDE) && (&item != &backPlayList_.back())) { // 2 writeTsIndex_++; + seekStartTimePos_ = totalDuration; MEDIA_LOG_I("writeTsIndex, RequestNewTs update writeTsIndex " PUBLIC_LOG_U32, writeTsIndex_); return -1; } @@ -2248,8 +2265,10 @@ void HlsMediaDownloader::HandleSeekReady(int32_t streamType, int32_t streamId, i seekReadyInfo.PutIntValue("currentStreamType", streamType); seekReadyInfo.PutIntValue("currentStreamId", streamId); seekReadyInfo.PutIntValue("isEOS", isEos); - MEDIA_LOG_D("StreamType: " PUBLIC_LOG_D32 " StreamId: " PUBLIC_LOG_D32 " isEOS: " PUBLIC_LOG_D32, - streamType, streamId, isEos); + seekReadyInfo.PutLongValue("seekStartTimePos", seekStartTimePos_); + MEDIA_LOG_D("StreamType: " PUBLIC_LOG_D32 " StreamId: " PUBLIC_LOG_D32 " isEOS: " + PUBLIC_LOG_D32 " seekStartTimePos: " PUBLIC_LOG_D64, + streamType, streamId, isEos, seekStartTimePos_); if (callback_ != nullptr) { callback_->OnEvent({PluginEventType::HLS_SEEK_READY, seekReadyInfo, "hls_seek_ready"}); } @@ -2280,6 +2299,16 @@ uint64_t HlsMediaDownloader::GetMemorySize() { return memorySize_; } + +bool HlsMediaDownloader::IsHlsEnd() +{ + if (CheckReadStatus() && GetBufferSize() == 0 && readTsIndex_ + 1 == backPlayList_.size() && + tsStorageInfo_.find(readTsIndex_) != tsStorageInfo_.end() && + tsStorageInfo_[readTsIndex_].second) { + return true; + } + return false; +} } } } 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 bd250838770af2e9176a5caa2ce16eebf458c271..a22b55b06f0cb0256e359a479c807cefaa5750db 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 @@ -114,6 +114,7 @@ public: bool IsHlsFmp4() override; uint64_t GetMemorySize() override; std::string GetContentType() override; + bool IsHlsEnd() override; private: void SaveHttpHeader(const std::map& httpHeader); @@ -324,6 +325,10 @@ private: std::atomic isNeedReadHeader_ {false}; std::atomic isNeedResetOffset_ {false}; uint64_t memorySize_ {0}; + + int64_t seekStartTimePos_ {0}; + std::atomic isTsEnd_ {false}; + std::atomic notNeedReadBack_ {false}; }; } } 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 4192d9e102cc77b6ef2d3d4eb22a9d62a3cbd071..080a0bb292cd68bb2d53b1106748c43a92f93eda 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 @@ -630,6 +630,12 @@ std::string HttpSourcePlugin::GetCurUrl() FALSE_RETURN_V_MSG_E(downloader_ != nullptr, 0, "downloader_ is nullptr"); return downloader_->GetCurUrl(); } + +bool HttpSourcePlugin::IsHlsEnd() +{ + FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); + return downloader_->IsHlsEnd(); +} } } } 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 fdae4536364cafed0b869cad33b355685c47dc91..b06772124e30738ab384be933f4866b2de98d873 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 @@ -75,6 +75,7 @@ public: bool IsHlsFmp4() override; uint64_t GetMemorySize() override; std::string GetContentType() override; + bool IsHlsEnd() override; private: void CloseUri(bool isAsync = false); 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 6fae2a54183944a7518c03aaba5cd050c95e07d4..6c8c1ee64e69ffed2a4728dd054852138a4306ae 100644 --- a/services/media_engine/plugins/source/http_source/media_downloader.h +++ b/services/media_engine/plugins/source/http_source/media_downloader.h @@ -217,6 +217,11 @@ public: { return ""; } + + virtual bool IsHlsEnd() + { + return false; + } }; } } 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 ca2538c56d7e2f7c80bdd2818e25e58a1e48d2e4..a9815c38a0eef3a9ec5706fe4baa80d62b5cd8c0 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 @@ -544,6 +544,12 @@ std::string DownloadMonitor::GetCurUrl() FALSE_RETURN_V(downloader_ != nullptr, ""); return downloader_->GetCurUrl(); } + +bool DownloadMonitor::IsHlsEnd() +{ + FALSE_RETURN_V_MSG_E(downloader_ != nullptr, false, "downloader_ is nullptr"); + return downloader_->IsHlsEnd(); +} } } } 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 091486b1553677e83447efcd44b23e9086532710..34396edeb32a45eb7e8576c0d2d4fec815d293b1 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 @@ -92,6 +92,7 @@ public: uint64_t GetMemorySize() override; std::string GetContentType() override; std::string GetCurUrl() override; + bool IsHlsEnd() override; private: int64_t HttpMonitorLoop(); diff --git a/test/unittest/hls_test/hls_media_downloader_unit_test.cpp b/test/unittest/hls_test/hls_media_downloader_unit_test.cpp index 7060b7fe83140b876f2d09a8b2c5a154e639543e..8c9904c8c6c2cd68c5f74c719be8c0526c2fa185 100644 --- a/test/unittest/hls_test/hls_media_downloader_unit_test.cpp +++ b/test/unittest/hls_test/hls_media_downloader_unit_test.cpp @@ -1724,6 +1724,7 @@ HWTEST_F(HlsMediaDownloaderUnitTest, READ_DELEGATE_001, TestSize.Level1) EXPECT_EQ(downloader->ReadDelegate(buffer, readDataInfo), Status::END_OF_STREAM); readDataInfo.wantReadLength_ = 4096; EXPECT_EQ(downloader->ReadDelegate(buffer, readDataInfo), Status::OK); + EXPECT_EQ(downloader->IsHlsEnd(), false); EXPECT_EQ(downloader->writeTsIndex_, 0); downloader->isBuffering_ = true; @@ -1734,6 +1735,7 @@ HWTEST_F(HlsMediaDownloaderUnitTest, READ_DELEGATE_001, TestSize.Level1) downloader->readTsIndex_ = 1; downloader->tsStorageInfo_[downloader->readTsIndex_] = std::make_pair(0, true); EXPECT_EQ(downloader->ReadDelegate(buffer, readDataInfo), Status::END_OF_STREAM); + EXPECT_EQ(downloader->IsHlsEnd(), true); downloader->isInterruptNeeded_ = true; EXPECT_EQ(downloader->ReadDelegate(buffer, readDataInfo), Status::END_OF_STREAM);