Fix play once video player

This commit is contained in:
2026-04-23 08:36:52 +10:00
parent c625898f61
commit 91bdb3f96b
2 changed files with 21 additions and 6 deletions

View File

@@ -480,10 +480,17 @@ namespace ANSCENTER {
// HW decode path (CFilePlayer) // HW decode path (CFilePlayer)
// ===================================================================== // =====================================================================
if (_hwDecodeActive && _hwPlayer) { 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 (_hwEOF) {
if (_resHeight <= 0 || _resWidth <= 0) { _resHeight = 1080; _resWidth = 1920; } 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; width = _previousImage.cols;
height = _previousImage.rows; height = _previousImage.rows;
if (_previousPTS < std::numeric_limits<int64_t>::max()) _previousPTS++; if (_previousPTS < std::numeric_limits<int64_t>::max()) _previousPTS++;
@@ -620,7 +627,12 @@ namespace ANSCENTER {
_resWidth = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH)); _resWidth = static_cast<int>(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; width = _previousImage.cols;
height = _previousImage.rows; height = _previousImage.rows;

View File

@@ -1499,6 +1499,7 @@ int VideoPlayerClientTest() {
auto start = std::chrono::system_clock::now(); auto start = std::chrono::system_clock::now();
cv::Mat* image = nullptr; // ✅ Use a pointer to hold the allocated image cv::Mat* image = nullptr; // ✅ Use a pointer to hold the allocated image
GetVideoPlayerCVImage(&videoClient, width, height, pts,&image); GetVideoPlayerCVImage(&videoClient, width, height, pts,&image);
std::cout<<"pts: "<<pts<<std::endl;
auto end1 = std::chrono::system_clock::now(); auto end1 = std::chrono::system_clock::now();
auto elapsed1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start); auto elapsed1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start);
if (elapsed1.count() > 0)std::cout << "Time to get image:" << elapsed1.count() << "ms" << std::endl; 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 == 1800) || (index == 2200) || (index == 2500)) { StopFilePlayer(&filePlayerClient); }
if ((index == 2000) || (index == 2300) || (index == 2700)) { StartFilePlayer(&filePlayerClient); } if ((index == 2000) || (index == 2300) || (index == 2700)) { StartFilePlayer(&filePlayerClient); }
if (index > 20000) break;*/ if (index > 20000) break;*/
if (index > 2000) break;
auto start = std::chrono::system_clock::now(); auto start = std::chrono::system_clock::now();
cv::Mat* image = nullptr; cv::Mat* image = nullptr;
GetFilePlayerCVImage(&filePlayerClient, width, height, pts, &image); GetFilePlayerCVImage(&filePlayerClient, width, height, pts, &image);
std::cout<<"pts: "<<pts<<std::endl;
auto end1 = std::chrono::system_clock::now(); auto end1 = std::chrono::system_clock::now();
auto elapsed1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start); auto elapsed1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start);
if (elapsed1.count() > 0) std::cout << "Time to get image:" << elapsed1.count() << "ms" << std::endl; 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.), // resolved inside ANSCV.dll (which is linked against libavcodec etc.),
// so this works without the unit test having to link FFmpeg itself. // so this works without the unit test having to link FFmpeg itself.
//ANSCV_PrintFFmpegLicense_S(); //ANSCV_PrintFFmpegLicense_S();
//FilePlayerClientDoubleDestroy(); FilePlayerClientDoubleDestroy();
FilePlayerClientCVTest(); FilePlayerClientCVTest();
// VideoPlayerClientDoubleDestroy(); VideoPlayerClientDoubleDestroy();
//VideoPlayerClientTest(); VideoPlayerClientTest();
//OpenCVFunctionTest(); //OpenCVFunctionTest();
//GenerateVideo(); //GenerateVideo();
//VideoTestClient(); //VideoTestClient();