From 91bdb3f96bc16f2c08da8ee6ccde8805e57de4f9 Mon Sep 17 00:00:00 2001 From: Tuan Nghia Nguyen Date: Thu, 23 Apr 2026 08:36:52 +1000 Subject: [PATCH] Fix play once video player --- modules/ANSCV/ANSVideoPlayer.cpp | 18 +++++++++++++++--- tests/ANSCV-UnitTest/ANSCV-UnitTest.cpp | 9 ++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/modules/ANSCV/ANSVideoPlayer.cpp b/modules/ANSCV/ANSVideoPlayer.cpp index 45ba697..70712b7 100644 --- a/modules/ANSCV/ANSVideoPlayer.cpp +++ b/modules/ANSCV/ANSVideoPlayer.cpp @@ -480,10 +480,17 @@ namespace ANSCENTER { // HW decode path (CFilePlayer) // ===================================================================== if (_hwDecodeActive && _hwPlayer) { - // EOF: return black frame (same behavior as cv::VideoCapture path) + // EOF: return black frame with monotonically-increasing PTS so the + // caller can tell playback is still alive (not hung). Allocate the + // black buffer once and reuse it on repeat EOF calls — avoids a + // ~6 MB reallocation per GetImage() tick at 1080p. if (_hwEOF) { if (_resHeight <= 0 || _resWidth <= 0) { _resHeight = 1080; _resWidth = 1920; } - _previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0)); + if (_previousImage.empty() || + _previousImage.rows != _resHeight || _previousImage.cols != _resWidth || + _previousImage.type() != CV_8UC3) { + _previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0)); + } width = _previousImage.cols; height = _previousImage.rows; if (_previousPTS < std::numeric_limits::max()) _previousPTS++; @@ -620,7 +627,12 @@ namespace ANSCENTER { _resWidth = static_cast(cap.get(cv::CAP_PROP_FRAME_WIDTH)); } - _previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0)); + // Reuse cached black buffer on repeat EOF ticks (~6 MB alloc avoided at 1080p). + if (_previousImage.empty() || + _previousImage.rows != _resHeight || _previousImage.cols != _resWidth || + _previousImage.type() != CV_8UC3) { + _previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0)); + } width = _previousImage.cols; height = _previousImage.rows; diff --git a/tests/ANSCV-UnitTest/ANSCV-UnitTest.cpp b/tests/ANSCV-UnitTest/ANSCV-UnitTest.cpp index 8e0b87f..507253a 100644 --- a/tests/ANSCV-UnitTest/ANSCV-UnitTest.cpp +++ b/tests/ANSCV-UnitTest/ANSCV-UnitTest.cpp @@ -1499,6 +1499,7 @@ int VideoPlayerClientTest() { auto start = std::chrono::system_clock::now(); cv::Mat* image = nullptr; // ✅ Use a pointer to hold the allocated image GetVideoPlayerCVImage(&videoClient, width, height, pts,&image); + std::cout<<"pts: "<(end1 - start); if (elapsed1.count() > 0)std::cout << "Time to get image:" << elapsed1.count() << "ms" << std::endl; @@ -1579,9 +1580,11 @@ int FilePlayerClientCVTest() { if ((index == 1800) || (index == 2200) || (index == 2500)) { StopFilePlayer(&filePlayerClient); } if ((index == 2000) || (index == 2300) || (index == 2700)) { StartFilePlayer(&filePlayerClient); } if (index > 20000) break;*/ + if (index > 2000) break; auto start = std::chrono::system_clock::now(); cv::Mat* image = nullptr; GetFilePlayerCVImage(&filePlayerClient, width, height, pts, &image); + std::cout<<"pts: "<(end1 - start); if (elapsed1.count() > 0) std::cout << "Time to get image:" << elapsed1.count() << "ms" << std::endl; @@ -1644,10 +1647,10 @@ int main() // resolved inside ANSCV.dll (which is linked against libavcodec etc.), // so this works without the unit test having to link FFmpeg itself. //ANSCV_PrintFFmpegLicense_S(); - //FilePlayerClientDoubleDestroy(); + FilePlayerClientDoubleDestroy(); FilePlayerClientCVTest(); - // VideoPlayerClientDoubleDestroy(); - //VideoPlayerClientTest(); + VideoPlayerClientDoubleDestroy(); + VideoPlayerClientTest(); //OpenCVFunctionTest(); //GenerateVideo(); //VideoTestClient();