Refactor project structure
This commit is contained in:
861
modules/ANSCV/ANSFilePlayer.cpp
Normal file
861
modules/ANSCV/ANSFilePlayer.cpp
Normal file
@@ -0,0 +1,861 @@
|
||||
#include "ANSFilePlayer.h"
|
||||
#include "ANSMatRegistry.h"
|
||||
#include "ANSGpuFrameOps.h"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/frame.h>
|
||||
#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() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_url = "";
|
||||
_imageRotateDeg = 0;
|
||||
_isPlaying = false;
|
||||
_lastJpegImage = "";
|
||||
_pLastFrame.release();
|
||||
if (_playerClient) {
|
||||
_playerClient->close();
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogError("ANSFILEPLAYER::Destroy. Exception:", e.what(), __FILE__, __LINE__);
|
||||
}
|
||||
catch (...) {
|
||||
_logger.LogError("ANSFILEPLAYER::Destroy.", "Unknown exception", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
void ANSFILEPLAYER::CheckLicense() {
|
||||
std::lock_guard<std::recursive_mutex> 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<std::recursive_mutex> 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<std::recursive_mutex> lock(_mutex);
|
||||
_playerClient->setBbox(bbox);
|
||||
}
|
||||
void ANSFILEPLAYER::SetCrop(bool crop) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
_playerClient->setCrop(crop);
|
||||
}
|
||||
bool ANSFILEPLAYER::Setup() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
return _playerClient->open(_url);
|
||||
}
|
||||
bool ANSFILEPLAYER::Reconnect() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
_playerClient->close();
|
||||
Setup();
|
||||
return Start();
|
||||
}
|
||||
bool ANSFILEPLAYER::Start() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
_isPlaying = _playerClient->play();
|
||||
return _isPlaying;
|
||||
}
|
||||
bool ANSFILEPLAYER::Stop() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (_playerClient->pause()) {
|
||||
_isPlaying = false;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSFILEPLAYER::IsPaused() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
return _playerClient->isPaused();
|
||||
}
|
||||
bool ANSFILEPLAYER::IsPlaying() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
return _playerClient->isPlaying();
|
||||
}
|
||||
bool ANSFILEPLAYER::IsRecording() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
return _playerClient->isRecording();
|
||||
}
|
||||
std::string ANSFILEPLAYER::GetJpegImage(int& width, int& height, int64_t& pts) {
|
||||
std::lock_guard<std::recursive_mutex> 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<std::recursive_mutex> 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<std::recursive_mutex> lock(_mutex);
|
||||
_displayWidth = width;
|
||||
_displayHeight = height;
|
||||
}
|
||||
cv::Mat ANSFILEPLAYER::GetInferenceImage() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
return _inferenceImage;
|
||||
}
|
||||
void ANSFILEPLAYER::EnableAudio(bool status) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
_playerClient->enableAudio(status);
|
||||
}
|
||||
void ANSFILEPLAYER::SetAudioVolume(int volume) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
_playerClient->setVolume(volume);
|
||||
}
|
||||
std::string ANSFILEPLAYER::MatToBinaryData(const cv::Mat& image) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!image.empty()) {
|
||||
if ((image.data != nullptr) && (image.u != nullptr)) {
|
||||
try {
|
||||
std::vector<uchar> 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<ANSCENTER::ANSFILEPLAYER>();
|
||||
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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER> 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<int>((*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<AVFrame*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<int>(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<AVFrame*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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<ANSCENTER::ANSFILEPLAYER*>(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 (...) { }
|
||||
}
|
||||
Reference in New Issue
Block a user