From b5b2bfa33a71ea80500500dae9ef8f58f226718d Mon Sep 17 00:00:00 2001 From: xiangtongtong Date: Sat, 6 Sep 2025 15:02:44 +0800 Subject: [PATCH 1/4] hls add Signed-off-by: xiangtongtong --- interfaces/plugin/source_plugin.h | 4 +++ .../media_engine/modules/source/source.cpp | 6 ++++ services/media_engine/modules/source/source.h | 1 + .../http_source/hls/hls_media_downloader.cpp | 35 +++++++++++++++++-- .../http_source/hls/hls_media_downloader.h | 4 +++ .../source/http_source/http_source_plugin.cpp | 6 ++++ .../source/http_source/http_source_plugin.h | 1 + .../source/http_source/media_downloader.h | 5 +++ .../http_source/monitor/download_monitor.cpp | 6 ++++ .../http_source/monitor/download_monitor.h | 1 + 10 files changed, 66 insertions(+), 3 deletions(-) diff --git a/interfaces/plugin/source_plugin.h b/interfaces/plugin/source_plugin.h index 353b87747..0ce705d3d 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 c8326e4f6..96bc62672 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 cd7193cd3..beffafd13 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 fcad2ab3d..dab722617 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,7 +2265,9 @@ 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, + 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); 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 bd2508387..79566bbcd 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 @@ -324,6 +324,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 4192d9e10..080a0bb29 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 fdae45363..b06772124 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 6fae2a541..6c8c1ee64 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 ca2538c56..a9815c38a 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 091486b15..34396edeb 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(); -- Gitee From 34ef3b502a35c8eddc8a3e4383fe4da9e77c6aa2 Mon Sep 17 00:00:00 2001 From: xiangtongtong Date: Sat, 6 Sep 2025 15:27:02 +0800 Subject: [PATCH 2/4] hls add Signed-off-by: xiangtongtong --- .../plugins/source/http_source/hls/hls_media_downloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 dab722617..ecf62b237 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 @@ -2266,9 +2266,9 @@ void HlsMediaDownloader::HandleSeekReady(int32_t streamType, int32_t streamId, i seekReadyInfo.PutIntValue("currentStreamId", streamId); seekReadyInfo.PutIntValue("isEOS", isEos); seekReadyInfo.PutLongValue("seekStartTimePos", seekStartTimePos_); - MEDIA_LOG_D("StreamType: " PUBLIC_LOG_D32 " StreamId: " PUBLIC_LOG_D32 " isEOS: " + MEDIA_LOG_D("StreamType: " PUBLIC_LOG_D32 " StreamId: " PUBLIC_LOG_D32 " isEOS: " PUBLIC_LOG_D32 " seekStartTimePos: " PUBLIC_LOG_D64, - streamType, streamId, isEos); + streamType, streamId, isEos, seekStartTimePos_); if (callback_ != nullptr) { callback_->OnEvent({PluginEventType::HLS_SEEK_READY, seekReadyInfo, "hls_seek_ready"}); } -- Gitee From f4714da1701d21a232f6a47b5a4c315b047678c3 Mon Sep 17 00:00:00 2001 From: xiangtongtong Date: Sat, 6 Sep 2025 15:29:43 +0800 Subject: [PATCH 3/4] hls add Signed-off-by: xiangtongtong --- .../plugins/source/http_source/hls/hls_media_downloader.h | 1 + 1 file changed, 1 insertion(+) 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 79566bbcd..a22b55b06 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); -- Gitee From 4643e539bef0dec5d4ffa7ccdeb9a713cfb18073 Mon Sep 17 00:00:00 2001 From: xiangtongtong Date: Sat, 6 Sep 2025 17:29:48 +0800 Subject: [PATCH 4/4] hls add Signed-off-by: xiangtongtong --- test/unittest/hls_test/hls_media_downloader_unit_test.cpp | 2 ++ 1 file changed, 2 insertions(+) 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 7060b7fe8..8c9904c8c 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); -- Gitee