CUDA GstBuffer output buffer with OpenCV GpuMat
Richard Pickler
rpickler at gmail.com
Sat Jun 10 06:05:46 UTC 2023
I got it working, and I just wanted to close the loop on this in cse
someone is searching around for it in the future. The only mistake I had
was how I got the data pointer. After changing that to
GST_VIDEO_FRAME_PLANE_DATA, it all worked!
cv::cuda::GpuMat gpu_out(
cv::Size(
GST_VIDEO_FRAME_WIDTH(&out_frame),
GST_VIDEO_FRAME_HEIGHT(&out_frame)
),
CV_8UC3,
GST_VIDEO_FRAME_PLANE_DATA(&out_frame, 0),
GST_VIDEO_FRAME_PLANE_STRIDE(&out_frame, 0));
On Thu, Jun 8, 2023 at 5:57 PM Richard Pickler <rpickler at gmail.com> wrote:
> Thanks for the speedy reply. I've replaced the standard buffer_map with
> the following
>
>
> GstVideoFrame out_frame;
> if (!gst_video_frame_map (&out_frame, &debayer->info, outbuf,
> (GstMapFlags)(GST_MAP_WRITE | GST_MAP_CUDA))) {
> //gst_video_frame_unmap (&in_frame);
> GST_ERROR_OBJECT (debayer, "Failed to map output buffer");
> std::cout << "Failed to map output buffer" << std::endl;
> return GST_FLOW_ERROR;
> }
>
> And the gpuMat initialization:
>
> cv::cuda::GpuMat gpu_out(
> cv::Size(
> GST_VIDEO_FRAME_WIDTH(&out_frame),
> GST_VIDEO_FRAME_HEIGHT(&out_frame)),
> CV_8UC3,
> (char*) out_frame.data,
> GST_VIDEO_FRAME_PLANE_STRIDE(&out_frame, 0));
>
> But no such luck. Now I am the proud recipient of black frames.
>
> You're correct that the stride is different. 5760 vs 6144 on my 1920 wide
> image. That seems to cause the demosaic function to overrun and cause a
> memory exception in cuda. I then changed the gpumat initialization to:
>
>
> cv::cuda::GpuMat gpu_out(
> cv::Size(
> out_frame.map[0].size / GST_VIDEO_FRAME_HEIGHT(&out_frame) / 3,
> GST_VIDEO_FRAME_HEIGHT(&out_frame)),
> CV_8UC3,
> (char*) out_frame.data,
> GST_VIDEO_FRAME_PLANE_STRIDE(&out_frame, 0));
>
> Which doesn't crash, but also doesn't produce an image.
>
> (sorry for duplicate. I forgot to reply-all)
>
> On Thu, Jun 8, 2023 at 2:22 PM Seungha Yang <seungha at centricular.com>
> wrote:
>
>> Hi,
>>
>>
>>
>> GstCudaMemory’s stride is likely different from default one.
>>
>> You will need to use gst_video_frame_map() and
>> GST_VIDEO_FRAME_PLANE_STRIDE(frame, 0), or GstCudaMemory.info.stride[0]
>>
>>
>>
>> Regards,
>>
>> Seungha
>>
>>
>>
>> *From:* gstreamer-devel <gstreamer-devel-bounces at lists.freedesktop.org> *On
>> Behalf Of *Richard Pickler via gstreamer-devel
>> *Sent:* Thursday, June 8, 2023 10:05 PM
>> *To:* gstreamer-devel at lists.freedesktop.org
>> *Cc:* Richard Pickler <rpickler at gmail.com>
>> *Subject:* CUDA GstBuffer output buffer with OpenCV GpuMat
>>
>>
>>
>> I'm struggling to use the recent cuda improvements in gstreamer, using an
>> OpenCV GpuMat to write to a CUDAMemory outbuf. I'm was successful in
>> getting an appropriate buffer through decide/propose_allocation, but simply
>> cannot seem to write to a buffer properly. In my transform function below,
>> I'm able to map the buffer and have the demosaic function run properly, but
>> the output stream comes out garbage. I placed a simple cv::imwrite in the
>> code, and sure enough, the data comes through the function properly, it's
>> just not in a structure that gstreamer is happy with.
>>
>>
>>
>> Any ideas? I've been pounding my head against this wall for a couple
>> days now.
>>
>>
>>
>> static GstFlowReturn
>> debayer_transform(GstBaseTransform *base,
>> GstBuffer *inbuf, GstBuffer *outbuf)
>> {
>> Debayer *debayer = DEBAYER(base);
>> GstCudaBaseTransform *btrans = GST_CUDA_BASE_TRANSFORM (base);
>>
>> if (gst_buffer_n_memory (outbuf) != 1) {
>> GST_ERROR_OBJECT (debayer, "Invalid output buffer");
>> return GST_FLOW_ERROR;
>> }
>>
>> GstMemory *mem;
>> mem = gst_buffer_peek_memory (outbuf, 0);
>> if (!gst_is_cuda_memory (mem)) {
>> GST_ERROR_OBJECT (debayer, "Input buffer is not CUDA");
>> std::cout << "Input buffer is not cuda" << std::endl;
>> return GST_FLOW_ERROR;
>> }
>>
>> GstMapInfo map;
>> if(!gst_buffer_map(inbuf, &map, GST_MAP_READ))
>> {
>> std::cout << "Can't map" << std::endl;
>> return GST_FLOW_ERROR;
>> }
>>
>> GstMapInfo outmap;
>> if(!gst_buffer_map(outbuf, &outmap, (GstMapFlags)(GST_MAP_WRITE |
>> GST_MAP_CUDA)))
>> {
>> std::cout << "Can't map" << std::endl;
>> return GST_FLOW_ERROR;
>> }
>>
>> cv::Mat in(
>> cv::Size(debayer->info.width, debayer->info.height), CV_8UC1,
>> (char*) map.data);
>>
>> cv::cuda::GpuMat gpu_in;
>>
>> cv::cuda::GpuMat gpu_out(
>> cv::Size(debayer->info.width, debayer->info.height),
>> CV_8UC3,
>> (char*) outmap.data, debayer->info.stride[0]);
>>
>> gpu_in.upload(in);
>> cv::cuda::demosaicing(gpu_in, gpu_out, cv::COLOR_BayerRG2BGR);
>> cv::Mat out(gpu_out);
>> cv::imwrite("foo.jpg", out);
>>
>> gst_buffer_unmap(inbuf, &map);
>> gst_buffer_unmap(outbuf, &outmap);
>> return GST_FLOW_OK;
>> }
>>
>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20230610/41c9392f/attachment.htm>
More information about the gstreamer-devel
mailing list