#include "ANSFilePlayer.h" #include "ANSMatRegistry.h" #include "ANSGpuFrameOps.h" #include #include #include #include #include #include "media_codec.h" static bool ansfileplayerLicenceValid = false; // Global once_flag to protect license checking static std::once_flag ansfileplayerLicenseOnceFlag; namespace ANSCENTER { #define CHECK_CUDA(call) do { \ cudaError_t err = call; \ if (err != cudaSuccess) { \ std::cout<<"CUDA error: " + std::string(cudaGetErrorString(err)); \ } \ } while (0) #define CHECK_NVJPEG(call) do { \ nvjpegStatus_t status = call; \ if (status != NVJPEG_STATUS_SUCCESS) { \ std::cout <<"nvJPEG error: " + std::to_string(status); \ } \ } while (0) ANSFILEPLAYER::ANSFILEPLAYER() { _url = ""; _imageRotateDeg = 0; _imageWidth = 0; _imageHeight = 0; _pts = 0; _isPlaying = false; _lastJpegImage = ""; } ANSFILEPLAYER::~ANSFILEPLAYER() noexcept { try { Destroy(); } catch (...) {} } void ANSFILEPLAYER::Destroy() { decltype(_playerClient) clientToClose; { std::lock_guard lock(_mutex); try { _url = ""; _imageRotateDeg = 0; _isPlaying = false; _lastJpegImage = ""; _pLastFrame.release(); clientToClose = std::move(_playerClient); } catch (const std::exception& e) { _logger.LogError("ANSFILEPLAYER::Destroy. Exception:", e.what(), __FILE__, __LINE__); } catch (...) { _logger.LogError("ANSFILEPLAYER::Destroy.", "Unknown exception", __FILE__, __LINE__); } } if (clientToClose) { clientToClose->close(); } } void ANSFILEPLAYER::CheckLicense() { std::lock_guard lock(_mutex); try { _licenseValid = ANSCENTER::ANSLicenseHelper::LicenseVerification(_licenseKey, 1007, "ANSCV");//Default productId=1005 } catch (std::exception& e) { this->_logger.LogFatal("ANSFILEPLAYER::CheckLicense. Error:", e.what(), __FILE__, __LINE__); } } bool ANSFILEPLAYER::Init(std::string licenseKey, std::string url) { std::lock_guard lock(_mutex); _licenseKey = licenseKey; CheckLicense(); if (!_licenseValid) { this->_logger.LogError("ANSFILEPLAYER::Init.", "Invalid license", __FILE__, __LINE__); return false; } //network_init(); //sys_buf_init(200); //rtsp_parse_buf_init(200); //http_msg_buf_init(200); _url = url; return Setup(); } void ANSFILEPLAYER::SetBBox(cv::Rect bbox) { std::lock_guard lock(_mutex); _playerClient->setBbox(bbox); } void ANSFILEPLAYER::SetCrop(bool crop) { std::lock_guard lock(_mutex); _playerClient->setCrop(crop); } bool ANSFILEPLAYER::Setup() { std::lock_guard lock(_mutex); return _playerClient->open(_url); } bool ANSFILEPLAYER::Reconnect() { { std::lock_guard lock(_mutex); _isPlaying = false; } _playerClient->close(); std::lock_guard lock(_mutex); Setup(); return Start(); } bool ANSFILEPLAYER::Start() { std::lock_guard lock(_mutex); _isPlaying = _playerClient->play(); return _isPlaying; } bool ANSFILEPLAYER::Stop() { decltype(_playerClient.get()) player = nullptr; { std::lock_guard lock(_mutex); player = _playerClient.get(); } if (player && player->pause()) { std::lock_guard lock(_mutex); _isPlaying = false; return true; } return false; } bool ANSFILEPLAYER::IsPaused() { std::lock_guard lock(_mutex); return _playerClient->isPaused(); } bool ANSFILEPLAYER::IsPlaying() { std::lock_guard lock(_mutex); return _playerClient->isPlaying(); } bool ANSFILEPLAYER::IsRecording() { std::lock_guard lock(_mutex); return _playerClient->isRecording(); } std::string ANSFILEPLAYER::GetJpegImage(int& width, int& height, int64_t& pts) { std::lock_guard lock(_mutex); // If the player is playing, process the frame if (_isPlaying) { // Get a new frame from the player client _lastJpegImage = _playerClient->getJpegImage(width, height, pts); // Update internal state variables _pts = pts; _imageWidth = width; _imageHeight = height; // Return the frame return _lastJpegImage; } // If the player is not playing, return the last known frame else { width = _imageWidth; height = _imageHeight; pts = _pts; return _lastJpegImage; } } cv::Mat ANSFILEPLAYER::GetImage(int& width, int& height, int64_t& pts) { std::lock_guard lock(_mutex); if (!_isPlaying) { width = _imageWidth; height = _imageHeight; pts = _pts; return _pLastFrame; } _pLastFrame.release(); int imgW = 0, imgH = 0; _pLastFrame = _playerClient->getImage(imgW, imgH, pts); if (_pLastFrame.empty()) { width = _imageWidth; height = _imageHeight; pts = _pts; return _pLastFrame; } cv::Mat result = _pLastFrame; // Apply rotation if needed if (_imageRotateDeg >= 1 && _imageRotateDeg != 0) { cv::Point2f center(imgW / 2.0f, imgH / 2.0f); cv::Mat rotMat = cv::getRotationMatrix2D(center, _imageRotateDeg, 1.0); cv::Mat rotated; cv::warpAffine(result, rotated, rotMat, result.size(), cv::INTER_CUBIC, cv::BORDER_CONSTANT, cv::Scalar()); result = rotated; } // Store full-res for inference (before display resize) _inferenceImage = result; // Resize for display if display resolution is set if (_displayWidth > 0 && _displayHeight > 0 && (result.cols != _displayWidth || result.rows != _displayHeight)) { cv::Mat displayResult; cv::resize(result, displayResult, cv::Size(_displayWidth, _displayHeight), 0, 0, cv::INTER_LINEAR); result = displayResult; } _pts = pts; width = result.cols; height = result.rows; _imageWidth = width; _imageHeight = height; return result; } void ANSFILEPLAYER::SetDisplayResolution(int width, int height) { std::lock_guard lock(_mutex); _displayWidth = width; _displayHeight = height; } cv::Mat ANSFILEPLAYER::GetInferenceImage() { std::lock_guard lock(_mutex); return _inferenceImage; } void ANSFILEPLAYER::EnableAudio(bool status) { std::lock_guard lock(_mutex); _playerClient->enableAudio(status); } void ANSFILEPLAYER::SetAudioVolume(int volume) { std::lock_guard lock(_mutex); _playerClient->setVolume(volume); } std::string ANSFILEPLAYER::MatToBinaryData(const cv::Mat& image) { std::lock_guard lock(_mutex); if (!image.empty()) { if ((image.data != nullptr) && (image.u != nullptr)) { try { std::vector imageData; bool success = cv::imencode(".jpg", image, imageData); if (!success) { this->_logger.LogError("ANSFILEPLAYER::MatToBinaryData. Error:", "Failed to encode the image.", __FILE__, __LINE__); return ""; } std::string binaryData(imageData.begin(), imageData.end()); return binaryData; } catch (const std::exception& e) { this->_logger.LogFatal("ANSFILEPLAYER::MatToBinaryData. Error:", e.what(), __FILE__, __LINE__); return ""; } catch (...) { this->_logger.LogFatal("ANSFILEPLAYER::MatToBinaryData. Error:", "Caught unknown exception!", __FILE__, __LINE__); return ""; } } else return ""; } else return ""; } static void VerifyGlobalANSFPLicense(const std::string& licenseKey) { try { ansfileplayerLicenceValid = ANSCENTER::ANSLicenseHelper::LicenseVerification(licenseKey, 1007, "ANSCV");//Default productId=1005 if (!ansfileplayerLicenceValid) { // we also support ANSTS license ansfileplayerLicenceValid = ANSCENTER::ANSLicenseHelper::LicenseVerification(licenseKey, 1003, "ANSVIS");//Default productId=1003 (ANSVIS) } if (!ansfileplayerLicenceValid) { // we also support ANSTS license ansfileplayerLicenceValid = ANSCENTER::ANSLicenseHelper::LicenseVerification(licenseKey, 1008, "ANSTS");//Default productId=1008 (ANSTS) } } catch (std::exception& e) { ansfileplayerLicenceValid = false; } } } extern "C" __declspec(dllexport) int CreateANSFilePlayerHandle(ANSCENTER::ANSFILEPLAYER** Handle, const char* licenseKey, const char* url) { if (!Handle || !licenseKey || !url) return -1; try { auto ptr = std::make_unique(); bool result = ptr->Init(licenseKey, url); if (result) { *Handle = ptr.release(); extern void anscv_unregister_handle(void*); extern void anscv_register_handle(void*, void(*)(void*)); anscv_register_handle(*Handle, [](void* p) { auto* h = static_cast(p); try { h->Stop(); } catch (...) {} try { h->Destroy(); } catch (...) {} try { delete h; } catch (...) {} }); return 1; } *Handle = nullptr; return 0; } catch (...) { return 0; } } extern "C" __declspec(dllexport) int ReleaseANSFilePlayerHandle(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { extern void anscv_unregister_handle(void*); anscv_unregister_handle(*Handle); // Destructor calls Destroy() — no need to call it explicitly (avoids double-destroy) std::unique_ptr ptr(*Handle); *Handle = nullptr; return 0; } catch (...) { if (Handle) *Handle = nullptr; return 0; } } extern "C" __declspec(dllexport) int GetFilePlayerStrImage(ANSCENTER::ANSFILEPLAYER** Handle, int& width, int& height, int64_t& timeStamp, std::string& jpegImage) { if (Handle == nullptr || *Handle == nullptr) return -1; try { jpegImage = (*Handle)->GetJpegStringImage(width, height, timeStamp); if (!jpegImage.empty()) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error getting image data from FilePlayer client: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int GetFilePlayerImage(ANSCENTER::ANSFILEPLAYER** Handle, int& width, int& height, int64_t& timeStamp, LStrHandle jpegImage) { if (Handle == nullptr || *Handle == nullptr) return -1; try { std::string jpegString = (*Handle)->GetJpegStringImage(width, height, timeStamp); int size = jpegString.length(); if (size > 0) { MgErr error; // Resize the jpegImage handle to hold the image data error = DSSetHandleSize(jpegImage, sizeof(int32) + size * sizeof(uChar)); // Check if resizing the handle was successful if (error == noErr) { // Set the size of the image in the handle (*jpegImage)->cnt = size; // Use memcpy to copy the data from the std::string to the LStrHandle's str buffer memcpy((*jpegImage)->str, jpegString.c_str(), size); // Return success return 1; } else { // Return failure if there was an error in resizing the handle std::cerr << "Error resizing jpegImage handle: " << error << std::endl; return 0; } } else { // If the JPEG image string is empty, return failure std::cerr << "No image data retrieved from FilePlayer client." << std::endl; return 0; } } catch (const std::exception& e) { std::cerr << "Error getting image data from FilePlayer client: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int GetFilePlayerCVImage(ANSCENTER::ANSFILEPLAYER** Handle, int& width, int& height, int64_t& timeStamp, cv::Mat** image) { if (!Handle || !(*Handle) || !image) { std::cerr << "Error: Invalid input parameters in GetFilePlayerCVImage." << std::endl; return -1; } try { cv::Mat img = (*Handle)->GetImage(width, height, timeStamp); if (img.empty()) { return 0; } anscv_mat_replace(image, std::move(img)); // Attach NV12/CUDA frames to registry for inference zero-copy (same as ANSRTSP/ANSVideoPlayer). // CFilePlayer inherits getNV12Frame()/getCudaHWFrame() from CVideoPlayer. int gpuIdx = (*Handle)->_playerClient->getHWDecodingGpuIndex(); AVFrame* cudaHW = (*Handle)->_playerClient->getCudaHWFrame(); if (cudaHW) { AVFrame* cpuNV12 = (*Handle)->_playerClient->getNV12Frame(); gpu_frame_attach_cuda(*image, cudaHW, gpuIdx, timeStamp, cpuNV12); } else { AVFrame* nv12 = (*Handle)->_playerClient->getNV12Frame(); if (nv12) { gpu_frame_attach(*image, nv12, gpuIdx, timeStamp); } else { // CPU-only fallback: attach full-res BGR clone for ANSRTYOLO cv::Mat infImg = (*Handle)->GetInferenceImage(); if (!infImg.empty() && infImg.data != (*image)->data) { (*Handle)->_inferenceClonePrev = (*Handle)->_inferenceCloneCurr; (*Handle)->_inferenceCloneCurr = infImg.clone(); GpuFrameData data{}; data.avframe = nullptr; data.yPlane = (*Handle)->_inferenceCloneCurr.data; data.uvPlane = nullptr; data.yLinesize = static_cast((*Handle)->_inferenceCloneCurr.step[0]); data.uvLinesize = 0; data.width = (*Handle)->_inferenceCloneCurr.cols; data.height = (*Handle)->_inferenceCloneCurr.rows; data.pixelFormat = 1000; // ANSCV_PIX_FMT_BGR24 data.gpuIndex = -1; data.pts = timeStamp; data.isCudaDevicePtr = false; data.cpuAvframe = nullptr; data.cpuYPlane = nullptr; data.cpuUvPlane = nullptr; data.cpuYLinesize = 0; data.cpuUvLinesize = 0; ANSGpuFrameRegistry::instance().attach(*image, std::move(data)); auto pending = ANSGpuFrameRegistry::instance().drain_pending(); for (void* p : pending) { AVFrame* stale = static_cast(p); av_frame_free(&stale); } } } } return 1; } catch (const cv::Exception& e) { std::cerr << "OpenCV exception in GetFilePlayerCVImage: " << e.what() << std::endl; return -2; } catch (const std::exception& e) { std::cerr << "Exception in GetFilePlayerCVImage: " << e.what() << std::endl; return -2; } catch (...) { std::cerr << "Unknown exception in GetFilePlayerCVImage" << std::endl; return -2; } } extern "C" __declspec(dllexport) int StartFilePlayer(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool result = (*Handle)->Start(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error starting file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int ReconnectFilePlayer(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool result = (*Handle)->Reconnect(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error reconnecting file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int StopFilePlayer(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool result = (*Handle)->Stop(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error stopping file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int IsFilePlayerPaused(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool result = (*Handle)->IsPaused(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error checking if file player is paused: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int IsFilePlayerRunning(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool result = (*Handle)->IsPlaying(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error checking if file player is running: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int IsFilePlayerRecording(ANSCENTER::ANSFILEPLAYER** Handle) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool result = (*Handle)->IsRecording(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error checking if file player is recording: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) void SetFilePlayerAudioVolume(ANSCENTER::ANSFILEPLAYER** Handle, int volume) { if (Handle == nullptr || *Handle == nullptr) return; try { (*Handle)->SetAudioVolume(volume); } catch (...) { } } extern "C" __declspec(dllexport) void EnableFilePlayerAudioVolume(ANSCENTER::ANSFILEPLAYER** Handle, int status) { if (Handle == nullptr || *Handle == nullptr) return; try { bool audioStatus = false; if (status == 1)audioStatus = true; (*Handle)->EnableAudio(audioStatus); } catch (const std::exception& e) { std::cerr << "Error enabling audio for file player: " << e.what() << std::endl; } catch (...) { } } extern "C" __declspec(dllexport) void SetFilePlayerImageRotation(ANSCENTER::ANSFILEPLAYER** Handle, double rotationAngle) { if (Handle == nullptr || *Handle == nullptr) return; try { (*Handle)->SetImageRotate(rotationAngle); } catch (...) { } } extern "C" __declspec(dllexport) int SetBBoxFilePlayer(ANSCENTER::ANSFILEPLAYER** Handle, int x, int y, int width, int height) { if (Handle == nullptr || *Handle == nullptr) return -1; try { cv::Rect bbox(x, y, width, height); (*Handle)->SetBBox(bbox); return 1; } catch (const std::exception& e) { std::cerr << "Error setting bounding box for file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int SetCropFlagFilePlayer(ANSCENTER::ANSFILEPLAYER** Handle, int cropFlag) { if (Handle == nullptr || *Handle == nullptr) return -1; try { bool crop = false; if (cropFlag == 1)crop = true; (*Handle)->SetCrop(crop); return 1; } catch (const std::exception& e) { std::cerr << "Error setting crop flag for file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } // ============================================================================ // V2 functions: accept uint64_t handleVal by value (LabVIEW-safe) // ============================================================================ extern "C" __declspec(dllexport) int GetFilePlayerImage_V2(uint64_t handleVal, int& width, int& height, int64_t& timeStamp, LStrHandle jpegImage) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { std::string jpegString = h->GetJpegStringImage(width, height, timeStamp); int size = jpegString.length(); if (size > 0) { MgErr error; error = DSSetHandleSize(jpegImage, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*jpegImage)->cnt = size; memcpy((*jpegImage)->str, jpegString.c_str(), size); return 1; } else { std::cerr << "Error resizing jpegImage handle: " << error << std::endl; return 0; } } else { std::cerr << "No image data retrieved from FilePlayer client." << std::endl; return 0; } } catch (const std::exception& e) { std::cerr << "Error getting image data from FilePlayer client: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int GetFilePlayerCVImage_V2(uint64_t handleVal, int& width, int& height, int64_t& timeStamp, cv::Mat** image) { auto* h = reinterpret_cast(handleVal); if (!h || !image) return -1; try { cv::Mat img = h->GetImage(width, height, timeStamp); if (img.empty()) { return 0; } anscv_mat_replace(image, std::move(img)); // NV12/CUDA registry attach (same as V1) int gpuIdx = h->_playerClient->getHWDecodingGpuIndex(); AVFrame* cudaHW = h->_playerClient->getCudaHWFrame(); if (cudaHW) { AVFrame* cpuNV12 = h->_playerClient->getNV12Frame(); gpu_frame_attach_cuda(*image, cudaHW, gpuIdx, timeStamp, cpuNV12); } else { AVFrame* nv12 = h->_playerClient->getNV12Frame(); if (nv12) { gpu_frame_attach(*image, nv12, gpuIdx, timeStamp); } else { cv::Mat infImg = h->GetInferenceImage(); if (!infImg.empty() && infImg.data != (*image)->data) { h->_inferenceClonePrev = h->_inferenceCloneCurr; h->_inferenceCloneCurr = infImg.clone(); GpuFrameData data{}; data.avframe = nullptr; data.yPlane = h->_inferenceCloneCurr.data; data.uvPlane = nullptr; data.yLinesize = static_cast(h->_inferenceCloneCurr.step[0]); data.uvLinesize = 0; data.width = h->_inferenceCloneCurr.cols; data.height = h->_inferenceCloneCurr.rows; data.pixelFormat = 1000; data.gpuIndex = -1; data.pts = timeStamp; data.isCudaDevicePtr = false; data.cpuAvframe = nullptr; data.cpuYPlane = nullptr; data.cpuUvPlane = nullptr; data.cpuYLinesize = 0; data.cpuUvLinesize = 0; ANSGpuFrameRegistry::instance().attach(*image, std::move(data)); auto pending = ANSGpuFrameRegistry::instance().drain_pending(); for (void* p : pending) { AVFrame* stale = static_cast(p); av_frame_free(&stale); } } } } return 1; } catch (const cv::Exception& e) { std::cerr << "OpenCV exception in GetFilePlayerCVImage_V2: " << e.what() << std::endl; return -2; } catch (const std::exception& e) { std::cerr << "Exception in GetFilePlayerCVImage_V2: " << e.what() << std::endl; return -2; } catch (...) { std::cerr << "Unknown exception in GetFilePlayerCVImage_V2" << std::endl; return -2; } } extern "C" __declspec(dllexport) int StartFilePlayer_V2(uint64_t handleVal) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool result = h->Start(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error starting file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int ReconnectFilePlayer_V2(uint64_t handleVal) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool result = h->Reconnect(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error reconnecting file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int StopFilePlayer_V2(uint64_t handleVal) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool result = h->Stop(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error stopping file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int IsFilePlayerPaused_V2(uint64_t handleVal) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool result = h->IsPaused(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error checking if file player is paused: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int IsFilePlayerRunning_V2(uint64_t handleVal) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool result = h->IsPlaying(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error checking if file player is running: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int IsFilePlayerRecording_V2(uint64_t handleVal) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool result = h->IsRecording(); if (result) return 1; else return 0; } catch (const std::exception& e) { std::cerr << "Error checking if file player is recording: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) void SetFilePlayerAudioVolume_V2(uint64_t handleVal, int volume) { auto* h = reinterpret_cast(handleVal); if (!h) return; try { h->SetAudioVolume(volume); } catch (...) { } } extern "C" __declspec(dllexport) void EnableFilePlayerAudioVolume_V2(uint64_t handleVal, int status) { auto* h = reinterpret_cast(handleVal); if (!h) return; try { bool audioStatus = false; if (status == 1) audioStatus = true; h->EnableAudio(audioStatus); } catch (const std::exception& e) { std::cerr << "Error enabling audio for file player: " << e.what() << std::endl; } catch (...) { } } extern "C" __declspec(dllexport) void SetFilePlayerImageRotation_V2(uint64_t handleVal, double rotationAngle) { auto* h = reinterpret_cast(handleVal); if (!h) return; try { h->SetImageRotate(rotationAngle); } catch (...) { } } extern "C" __declspec(dllexport) int SetBBoxFilePlayer_V2(uint64_t handleVal, int x, int y, int width, int height) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { cv::Rect bbox(x, y, width, height); h->SetBBox(bbox); return 1; } catch (const std::exception& e) { std::cerr << "Error setting bounding box for file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) int SetCropFlagFilePlayer_V2(uint64_t handleVal, int cropFlag) { auto* h = reinterpret_cast(handleVal); if (!h) return -1; try { bool crop = false; if (cropFlag == 1) crop = true; h->SetCrop(crop); return 1; } catch (const std::exception& e) { std::cerr << "Error setting crop flag for file player: " << e.what() << std::endl; return -1; } catch (...) { return -1; } } extern "C" __declspec(dllexport) void SetFilePlayerDisplayResolution(ANSCENTER::ANSFILEPLAYER** Handle, int width, int height) { if (Handle == nullptr || *Handle == nullptr) return; try { (*Handle)->SetDisplayResolution(width, height); } catch (...) { } }