Fix Video Player that support generate black image when finish playing video (reach the end of video)
This commit is contained in:
@@ -92,7 +92,10 @@
|
|||||||
"Bash(git submodule *)",
|
"Bash(git submodule *)",
|
||||||
"Bash(git rm *)",
|
"Bash(git rm *)",
|
||||||
"Bash(rm -rf .git/modules/3rdparty/libyuv)",
|
"Bash(rm -rf .git/modules/3rdparty/libyuv)",
|
||||||
"Bash(git add *)"
|
"Bash(git add *)",
|
||||||
|
"Read(//c/ProgramData/Jh7O7nUe7vS/Models/EngineModels/B-IN_ANS_VehicleDetection_v2.0_67345015/**)",
|
||||||
|
"Bash(xxd)",
|
||||||
|
"Bash(icacls \"C:\\\\ProgramData\\\\Jh7O7nUe7vS\\\\Models\\\\EngineModels\\\\B-IN_ANS_VehicleDetection_v2.0_67345015\\\\train_last.onnx\")"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ namespace ANSCENTER {
|
|||||||
_hwPlayer->play(); // starts read/video/audio threads
|
_hwPlayer->play(); // starts read/video/audio threads
|
||||||
_hwEOF = false;
|
_hwEOF = false;
|
||||||
_hwFrameCount = 0;
|
_hwFrameCount = 0;
|
||||||
_hwLastPts = 0;
|
_hwLastElapseMs = 0;
|
||||||
_isPlaying = true;
|
_isPlaying = true;
|
||||||
|
|
||||||
// Wait for first frame outside the mutex to let decode threads run
|
// Wait for first frame outside the mutex to let decode threads run
|
||||||
@@ -311,7 +311,7 @@ namespace ANSCENTER {
|
|||||||
_hwCudaAccel = false;
|
_hwCudaAccel = false;
|
||||||
_hwEOF = false;
|
_hwEOF = false;
|
||||||
_hwFrameCount = 0;
|
_hwFrameCount = 0;
|
||||||
_hwLastPts = 0;
|
_hwLastElapseMs = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// --- cv::VideoCapture fallback ---
|
// --- cv::VideoCapture fallback ---
|
||||||
@@ -525,10 +525,14 @@ namespace ANSCENTER {
|
|||||||
__FILE__, __LINE__);
|
__FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF detection: CFilePlayer auto-loops, but ANSVideoPlayer should stop.
|
// EOF detection: CFilePlayer auto-loops via av_seek_frame on AVERROR_EOF
|
||||||
// Detect when PTS wraps backwards (CFilePlayer seeked to start for looping).
|
// (file_player.cpp:434), so ANSVideoPlayer must detect the wrap itself.
|
||||||
if (_hwFrameCount > 10 && _hwLastPts > 0 && imgPts < _hwLastPts - 1000) {
|
// imgPts from getImage() is a monotonic call-counter, not a real PTS —
|
||||||
// Position wrapped back to start → video reached end
|
// use getElapse() (ms of real video position, updated from packet.pts
|
||||||
|
// in file_player.cpp:608). When the file loops, elapse drops back to ~0.
|
||||||
|
const int64_t elapseMs = _hwPlayer->getElapse();
|
||||||
|
if (_hwFrameCount > 10 && _hwLastElapseMs > 0 &&
|
||||||
|
elapseMs + 500 < _hwLastElapseMs) {
|
||||||
_hwEOF = true;
|
_hwEOF = true;
|
||||||
if (_resHeight <= 0 || _resWidth <= 0) { _resHeight = imgH; _resWidth = imgW; }
|
if (_resHeight <= 0 || _resWidth <= 0) { _resHeight = imgH; _resWidth = imgW; }
|
||||||
_previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0));
|
_previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0));
|
||||||
@@ -540,7 +544,7 @@ namespace ANSCENTER {
|
|||||||
return _previousImage;
|
return _previousImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hwLastPts = imgPts; // track for EOF detection (PTS wrap)
|
_hwLastElapseMs = elapseMs;
|
||||||
|
|
||||||
cv::Mat result = frame; // CFilePlayer returns owned Mat (already cloned internally)
|
cv::Mat result = frame; // CFilePlayer returns owned Mat (already cloned internally)
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
namespace ANSCENTER
|
namespace ANSCENTER
|
||||||
{
|
{
|
||||||
|
// This class only allow to run 1 (to the end of video) then it will generate blank dark image
|
||||||
class ANSVIDEOPLAYER_API ANSVIDEOPLAYER
|
class ANSVIDEOPLAYER_API ANSVIDEOPLAYER
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@@ -49,7 +50,7 @@ namespace ANSCENTER
|
|||||||
bool _hwCudaAccel = false; // true = NVIDIA CUDA zero-copy available
|
bool _hwCudaAccel = false; // true = NVIDIA CUDA zero-copy available
|
||||||
bool _hwEOF = false; // true when video reached end of file
|
bool _hwEOF = false; // true when video reached end of file
|
||||||
int64_t _hwFrameCount = 0; // frame counter for EOF detection
|
int64_t _hwFrameCount = 0; // frame counter for EOF detection
|
||||||
int64_t _hwLastPts = 0; // last video PTS for EOF wrap detection
|
int64_t _hwLastElapseMs = 0; // last CFilePlayer elapse (ms); EOF detected when it wraps backwards
|
||||||
ANSVIDEOPLAYER();
|
ANSVIDEOPLAYER();
|
||||||
~ANSVIDEOPLAYER() noexcept;
|
~ANSVIDEOPLAYER() noexcept;
|
||||||
[[nodiscard]] bool Init(std::string licenseKey, std::string url);
|
[[nodiscard]] bool Init(std::string licenseKey, std::string url);
|
||||||
|
|||||||
@@ -1491,11 +1491,11 @@ int VideoPlayerClientTest() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
index++;
|
index++;
|
||||||
std::cout << "Index=" << index << std::endl;
|
std::cout << "Index=" << index << std::endl;
|
||||||
if ((index == 200) || (index == 800) || (index == 1200)) { StopVideoPlayer(&videoClient); }
|
/*if ((index == 200) || (index == 800) || (index == 1200)) { StopVideoPlayer(&videoClient); }
|
||||||
if ((index == 400) || (index == 1000) || (index == 1500)) { StartVideoPlayer(&videoClient); }
|
if ((index == 400) || (index == 1000) || (index == 1500)) { StartVideoPlayer(&videoClient); }
|
||||||
if ((index == 1800) || (index == 2200) || (index == 2500)) { StopVideoPlayer(&videoClient); }
|
if ((index == 1800) || (index == 2200) || (index == 2500)) { StopVideoPlayer(&videoClient); }
|
||||||
if ((index == 2000) || (index == 2300) || (index == 2700)) { StartVideoPlayer(&videoClient); }
|
if ((index == 2000) || (index == 2300) || (index == 2700)) { StartVideoPlayer(&videoClient); }
|
||||||
if (index > 20000) break;
|
if (index > 20000) break;*/
|
||||||
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);
|
||||||
@@ -1574,11 +1574,11 @@ int FilePlayerClientCVTest() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
index++;
|
index++;
|
||||||
std::cout << "Index=" << index << std::endl;
|
std::cout << "Index=" << index << std::endl;
|
||||||
if ((index == 200) || (index == 800) || (index == 1200)) { StopFilePlayer(&filePlayerClient); }
|
/*if ((index == 200) || (index == 800) || (index == 1200)) { StopFilePlayer(&filePlayerClient); }
|
||||||
if ((index == 400) || (index == 1000) || (index == 1500)) { StartFilePlayer(&filePlayerClient); }
|
if ((index == 400) || (index == 1000) || (index == 1500)) { StartFilePlayer(&filePlayerClient); }
|
||||||
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;*/
|
||||||
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);
|
||||||
@@ -1645,17 +1645,16 @@ int main()
|
|||||||
// 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();
|
||||||
//VideoPlayerClientTest();
|
//VideoPlayerClientTest();
|
||||||
//VideoPlayerClientDoubleDestroy();
|
|
||||||
// VideoPlayerClientTest();
|
|
||||||
//OpenCVFunctionTest();
|
//OpenCVFunctionTest();
|
||||||
//GenerateVideo();
|
//GenerateVideo();
|
||||||
//VideoTestClient();
|
//VideoTestClient();
|
||||||
// TestGetImage();
|
// TestGetImage();
|
||||||
//PureOpenCV();
|
//PureOpenCV();
|
||||||
// RSTPTestClient();
|
// RSTPTestClient();
|
||||||
RSTPTestCVClient();
|
//RSTPTestCVClient();
|
||||||
//TestCreateImageFromJpegStringFile();
|
//TestCreateImageFromJpegStringFile();
|
||||||
//TestCreateImageFromFile();
|
//TestCreateImageFromFile();
|
||||||
//for (int i = 0; i < 100; i++) {
|
//for (int i = 0; i < 100; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user