Fix Video Player that support generate black image when finish playing video (reach the end of video)
This commit is contained in:
@@ -253,7 +253,7 @@ namespace ANSCENTER {
|
||||
_hwPlayer->play(); // starts read/video/audio threads
|
||||
_hwEOF = false;
|
||||
_hwFrameCount = 0;
|
||||
_hwLastPts = 0;
|
||||
_hwLastElapseMs = 0;
|
||||
_isPlaying = true;
|
||||
|
||||
// Wait for first frame outside the mutex to let decode threads run
|
||||
@@ -311,7 +311,7 @@ namespace ANSCENTER {
|
||||
_hwCudaAccel = false;
|
||||
_hwEOF = false;
|
||||
_hwFrameCount = 0;
|
||||
_hwLastPts = 0;
|
||||
_hwLastElapseMs = 0;
|
||||
}
|
||||
else {
|
||||
// --- cv::VideoCapture fallback ---
|
||||
@@ -525,10 +525,14 @@ namespace ANSCENTER {
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// EOF detection: CFilePlayer auto-loops, but ANSVideoPlayer should stop.
|
||||
// Detect when PTS wraps backwards (CFilePlayer seeked to start for looping).
|
||||
if (_hwFrameCount > 10 && _hwLastPts > 0 && imgPts < _hwLastPts - 1000) {
|
||||
// Position wrapped back to start → video reached end
|
||||
// EOF detection: CFilePlayer auto-loops via av_seek_frame on AVERROR_EOF
|
||||
// (file_player.cpp:434), so ANSVideoPlayer must detect the wrap itself.
|
||||
// imgPts from getImage() is a monotonic call-counter, not a real PTS —
|
||||
// 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;
|
||||
if (_resHeight <= 0 || _resWidth <= 0) { _resHeight = imgH; _resWidth = imgW; }
|
||||
_previousImage = cv::Mat(_resHeight, _resWidth, CV_8UC3, cv::Scalar(0, 0, 0));
|
||||
@@ -540,7 +544,7 @@ namespace ANSCENTER {
|
||||
return _previousImage;
|
||||
}
|
||||
|
||||
_hwLastPts = imgPts; // track for EOF detection (PTS wrap)
|
||||
_hwLastElapseMs = elapseMs;
|
||||
|
||||
cv::Mat result = frame; // CFilePlayer returns owned Mat (already cloned internally)
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
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
|
||||
{
|
||||
protected:
|
||||
@@ -49,7 +50,7 @@ namespace ANSCENTER
|
||||
bool _hwCudaAccel = false; // true = NVIDIA CUDA zero-copy available
|
||||
bool _hwEOF = false; // true when video reached end of file
|
||||
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() noexcept;
|
||||
[[nodiscard]] bool Init(std::string licenseKey, std::string url);
|
||||
|
||||
Reference in New Issue
Block a user