RE: CUDA GstBuffer output buffer with OpenCV GpuMat

Seungha Yang via gstreamer-devel <[email protected]>
Newsgroups gmane.comp.video.gstreamer.devel
Message-ID <[email protected]>
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 <[email protected]> On Behalf Of Richard Pickler via gstreamer-devel
Sent: Thursday, June 8, 2023 10:05 PM
To: [email protected]
Cc: Richard Pickler <[email protected]>
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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.