Fix NV12 crash issue when recreate camera object
This commit is contained in:
@@ -40,33 +40,34 @@ namespace ANSCENTER {
|
||||
catch (...) {}
|
||||
}
|
||||
void ANSVIDEOPLAYER::Destroy() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// --- HW decode cleanup ---
|
||||
if (_hwPlayer) {
|
||||
try {
|
||||
_hwPlayer->stop();
|
||||
_hwPlayer->close();
|
||||
} catch (...) {}
|
||||
_hwPlayer.reset(); // releases CFilePlayer + HWDecoderPool slot
|
||||
}
|
||||
_hwDecodeActive = false;
|
||||
_hwGpuIndex = -1;
|
||||
_hwCudaAccel = false;
|
||||
_hwEOF = false;
|
||||
_hwFrameCount = 0;
|
||||
// Move HW player out of lock scope — close() does CUDA cleanup
|
||||
// (cuArrayDestroy/cuMemFree) which must not run under _mutex
|
||||
// to avoid deadlocking with nvcuda64 SRW lock held by inference.
|
||||
decltype(_hwPlayer) hwPlayerToClose;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
if (_hwPlayer) {
|
||||
try { _hwPlayer->stop(); } catch (...) {}
|
||||
}
|
||||
hwPlayerToClose = std::move(_hwPlayer);
|
||||
_hwDecodeActive = false;
|
||||
_hwGpuIndex = -1;
|
||||
_hwCudaAccel = false;
|
||||
_hwEOF = false;
|
||||
_hwFrameCount = 0;
|
||||
|
||||
// --- cv::VideoCapture cleanup ---
|
||||
_previousImage.release();
|
||||
_inferenceImage.release();
|
||||
_inferenceCloneCurr.release();
|
||||
_inferenceClonePrev.release();
|
||||
_lastJpegImage = "";
|
||||
_isPlaying = false;
|
||||
_resWidth = 0;
|
||||
_resHeight = 0;
|
||||
_currentFrame = 0;
|
||||
_previousPTS = 0;
|
||||
// --- cv::VideoCapture cleanup ---
|
||||
_previousImage.release();
|
||||
_inferenceImage.release();
|
||||
_inferenceCloneCurr.release();
|
||||
_inferenceClonePrev.release();
|
||||
_lastJpegImage = "";
|
||||
_isPlaying = false;
|
||||
_resWidth = 0;
|
||||
_resHeight = 0;
|
||||
_currentFrame = 0;
|
||||
_previousPTS = 0;
|
||||
if (cap.isOpened()) {
|
||||
cap.release();
|
||||
}
|
||||
@@ -77,6 +78,13 @@ namespace ANSCENTER {
|
||||
catch (...) {
|
||||
_logger.LogError("ANSVIDEOPLAYER::Destroy.", "Unknown exception", __FILE__, __LINE__);
|
||||
}
|
||||
} // end lock scope
|
||||
|
||||
// CUDA cleanup happens here, outside the mutex
|
||||
if (hwPlayerToClose) {
|
||||
try { hwPlayerToClose->close(); } catch (...) {}
|
||||
hwPlayerToClose.reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void VerifyGlobalANSVPLicense(const std::string& licenseKey) {
|
||||
@@ -187,15 +195,25 @@ namespace ANSCENTER {
|
||||
}
|
||||
|
||||
bool ANSVIDEOPLAYER::Reconnect() {
|
||||
// HW decoder close() does CUDA cleanup — run outside _mutex
|
||||
// to avoid deadlocking with nvcuda64 SRW lock held by inference.
|
||||
decltype(_hwPlayer) hwPlayerToClose;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
_isPlaying = false; // GetImage() returns cached frame while we reconnect
|
||||
if (_hwPlayer) {
|
||||
try { _hwPlayer->stop(); } catch (...) {}
|
||||
hwPlayerToClose = std::move(_hwPlayer);
|
||||
}
|
||||
}
|
||||
if (hwPlayerToClose) {
|
||||
try { hwPlayerToClose->close(); } catch (...) {}
|
||||
hwPlayerToClose.reset();
|
||||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_currentFrame = 0;
|
||||
|
||||
// --- HW decode: destroy and re-setup ---
|
||||
if (_hwPlayer) {
|
||||
try { _hwPlayer->stop(); _hwPlayer->close(); } catch (...) {}
|
||||
_hwPlayer.reset();
|
||||
}
|
||||
_hwDecodeActive = false;
|
||||
_hwGpuIndex = -1;
|
||||
_hwCudaAccel = false;
|
||||
@@ -266,41 +284,48 @@ namespace ANSCENTER {
|
||||
}
|
||||
}
|
||||
bool ANSVIDEOPLAYER::Stop() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// --- HW decode path ---
|
||||
if (_hwDecodeActive && _hwPlayer) {
|
||||
_hwPlayer->stop();
|
||||
_isPlaying = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- cv::VideoCapture fallback ---
|
||||
if (cap.isOpened()) {
|
||||
try {
|
||||
double frame_pos = cap.get(cv::CAP_PROP_POS_FRAMES);
|
||||
if (frame_pos >= 0) {
|
||||
_currentFrame = static_cast<int64_t>(frame_pos);
|
||||
}
|
||||
else {
|
||||
_currentFrame = 0;
|
||||
this->_logger.LogError("ANSVIDEOPLAYER::Stop. Exception occurred:", "Unable to retrieve current frame position", __FILE__, __LINE__);
|
||||
}
|
||||
decltype(_hwPlayer.get()) hwPlayer = nullptr;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// --- HW decode path ---
|
||||
if (_hwDecodeActive && _hwPlayer) {
|
||||
_isPlaying = false;
|
||||
hwPlayer = _hwPlayer.get();
|
||||
// stop() called outside the lock below; skip cap path
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogError("ANSVIDEOPLAYER::Stop. Exception occurred:", e.what(), __FILE__, __LINE__);
|
||||
_currentFrame = 0;
|
||||
else {
|
||||
// --- cv::VideoCapture fallback ---
|
||||
if (cap.isOpened()) {
|
||||
try {
|
||||
double frame_pos = cap.get(cv::CAP_PROP_POS_FRAMES);
|
||||
if (frame_pos >= 0) {
|
||||
_currentFrame = static_cast<int64_t>(frame_pos);
|
||||
}
|
||||
else {
|
||||
_currentFrame = 0;
|
||||
this->_logger.LogError("ANSVIDEOPLAYER::Stop. Exception occurred:", "Unable to retrieve current frame position", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogError("ANSVIDEOPLAYER::Stop. Exception occurred:", e.what(), __FILE__, __LINE__);
|
||||
_currentFrame = 0;
|
||||
}
|
||||
cap.release();
|
||||
}
|
||||
_isPlaying = false;
|
||||
return true;
|
||||
}
|
||||
cap.release();
|
||||
}
|
||||
_isPlaying = false;
|
||||
return true;
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogError("ANSVIDEOPLAYER::Stop. Exception occurred:", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogError("ANSVIDEOPLAYER::Stop. Exception occurred:", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
if (hwPlayer) {
|
||||
hwPlayer->stop();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void ANSVIDEOPLAYER::SetBBox(cv::Rect bbox) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
Reference in New Issue
Block a user