So, i’m trying to make a camera class a bit like cv::VideoCapture that uses libArgus to map a cuda buffer to a GpuMat. The important bits of my code are
A capture method, that returns a unique_ptr to a Frame, which wraps a mapped buffer.
std::unique_ptr<Frame> NvCvCam::capture() {
CUgraphicsResource tmp_res = nullptr;
... checks that the producer thread is ok here ...
DEBUG << "nvcvcam:Getting an image from the EGLStream.";
auto err = cuEGLStreamConsumerAcquireFrame(&_cuda_conn, &tmp_res, &_cuda_stream, -1)
if (err) {
ERROR << "nvcvcam:Could not get image from the EglStream becuase: "
<< error_string(err) << ".";
return nullptr;
}
DEBUG << "nvcvcam:Returning Frame.";
return std::make_unique<Frame>(tmp_res, _cuda_conn, _cuda_stream);
}
The frame ctor:
Frame::Frame(CUgraphicsResource resource,
CUeglStreamConnection conn,
cudaStream_t stream)
: _resource(resource), _conn(conn), _stream(stream), _raw_frame{}, _mat() {
CUresult cu_err;
DEBUG << "frame:Mapping from resource.";
cu_err = cuGraphicsResourceGetMappedEglFrame(&_raw_frame, resource, 0, 0);
if (cu_err) {
ERROR << "frame:Could not map CUgraphicsResource to CUeglFrame becuase: "
<< error_string(cu_err) << ".";
return;
}
... debug and stream syncronize here ...
// map the data to a GpuMat
_mat = cv::cuda::GpuMat(_raw_frame.height, _raw_frame.width, CV_16SC1,
_raw_frame.frame.pPitch[0], _raw_frame.pitch);
}
The frame dtor:
Frame::~Frame() {
CUresult cu_err;
DEBUG << "frame:releasing resource in stream " << (size_t)_stream;
cu_err = cuEGLStreamConsumerReleaseFrame(&_conn, _resource, &_stream);
if (cu_err) {
ERROR << "frame:Could not release resource because: "
<< error_string(cu_err) << "(" << cu_err << ").";
std::terminate();
}
}
So, the capture works, ctor works, GpuMat is !empty()
, but when I release the frame, i get:
[2021-02-23 11:45:34.124095][debug]: frame:releasing resource in stream 368095401344
[2021-02-23 11:45:34.124573][error]: frame:Could not release resource because: an illegal memory access was encountered(700).
terminate called without an active exception
Aborted (core dumped)
Few other notes: the EGL stream is set to EGL_STREAM_MODE_MAILBOX
. Requests are made continuously in the producer’s main loop with icapturesession->capture(request.get())
.
Any clues as to what I am doing wrong? My C++ is not as good as my Python, so it’s entirely possible i’m missing something basic. I’d appreciate any help at all. Full source code for this WIP is here for anybody curious. Feedback welcome.
I do need the raw bayer and lowest latency possible, otherwise I would just use narguscamerasrc
. A full gstreamer pipeline through cv::VideoCapture with the conversion that implies is way too slow for my client’s purposes.