Conversion of cv::Mat to GstBuffer
Michael Gruner
michael.gruner at ridgerun.com
Wed Mar 13 14:10:39 UTC 2019
Hi Saurabh
Yo may convert from a cv::Mat to a GstBuffer without a memory copy by using gst_buffer_new_wrapped:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#gst-buffer-new-wrapped
Something like:
buffer = gst_buffer_new_wrapped (mat.data, mat.total()*mat.elemSize());
In order to make a cv::Mat from a GstBuffer you first need to take the data out of the buffer.
GstMapInfo info;
gst_buffer_map (buffer, &info, GST_MAP_READ); // or write
mat = cv::Mat(height, width, CV_8C3, map.data); // change your format accordingly
...
gst_buffer_unmap (buffer, &info);
Hope it helps.
Michael
www.ridgerun.com
> On Mar 13, 2019, at 7:15 AM, Saurabh Bora <saurabh9bora at gmail.com> wrote:
>
> Hi Experts!!,
>
> I am trying to read opencv images locally and push them into gstreamer pipeline. I am using appsrc element with "need-data" signal attached to call-back function.
> Please look at the code below.
>
> //------------------------------------------------------------------------------------------------------
> #include <gst/gst.h>
> #include <opencv2/opencv.hpp>
> #include <opencv2/highgui.hpp>
>
> static GMainLoop *loop;
>
> static void
> cb_need_data(GstElement *appsrc,
> guint unused_size,
> gpointer user_data)
> {
> static GstClockTime timestamp = 0;
> GstBuffer *buffer;
> guint size, depth, height, width, step, channels;
> GstFlowReturn ret;
> guchar *data1;
> GstMapInfo map;
>
> cv::Mat img = cv::imread("C:/Users/212730892.LOGON/Desktop/lena.jpg");
> height = img.size().height;
> width = img.size().width;
> //step = img.widthStep;
> channels = img.channels();
> //depth = img->depth;
> data1 = (guchar *)img.data;
> size = height * width* channels;
>
> // Copy cv::Mat to GstBuffer
> buffer = gst_buffer_new_allocate(NULL, size, NULL);
> gst_buffer_map(buffer, &map, GST_MAP_WRITE);
> memcpy((guchar *)map.data, data1, gst_buffer_get_size(buffer));
>
> //Convert GstBuffer back to cv::Mat and write it, to check if data was correctly copied. //This is where I get to know that data is not correct.
> cv::Mat img2(cv::Size(134, 134), CV_8UC3, (char*)(buffer));
> cv::imwrite("C:/Users/212730892.LOGON/Desktop/dummy1.jpg", img2);
>
> GST_BUFFER_PTS(buffer) = timestamp;
> GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 2);
>
> timestamp += GST_BUFFER_DURATION(buffer);
>
> g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
> //gst_buffer_unref(buffer);
>
> if (ret != GST_FLOW_OK) {
> /* something wrong, stop pushing */
> g_main_loop_quit(loop);
> }
> }
>
> gint
> main(gint argc,
> gchar *argv[])
> {
> GstElement *pipeline, *appsrc, *conv, *videosink;
>
> /* init GStreamer */
> gst_init(&argc, &argv);
> loop = g_main_loop_new(NULL, FALSE);
>
> /* setup pipeline */
> pipeline = gst_pipeline_new("pipeline");
> appsrc = gst_element_factory_make("appsrc", "source");
> conv = gst_element_factory_make("videoconvert", "conv");
> videosink = gst_element_factory_make("autovideosink", "videosink");
>
> /* setup */
> g_object_set(G_OBJECT(appsrc), "caps",
> gst_caps_new_simple("video/x-raw",
> "format", G_TYPE_STRING, "RGB",
> "width", G_TYPE_INT, 134,
> "height", G_TYPE_INT, 134,
> "framerate", GST_TYPE_FRACTION, 1, 1,
> NULL), NULL);
> gst_bin_add_many(GST_BIN(pipeline), appsrc, conv, videosink, NULL);
> gst_element_link_many(appsrc, conv, videosink, NULL);
> //g_object_set (videosink, "device", "/dev/video0", NULL);
> /* setup appsrc */
> g_object_set(G_OBJECT(appsrc),
> "stream-type", 0,
> "format", GST_FORMAT_TIME, NULL);
> g_signal_connect(appsrc, "need-data", G_CALLBACK(cb_need_data), NULL);
>
> /* play */
> gst_element_set_state(pipeline, GST_STATE_PLAYING);
> g_main_loop_run(loop);
>
> if (gst_element_set_state(pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE)
> {
> g_printerr("Unable to set the pipeline to the playing state.\n");
> }
>
> // Free resources
> gst_object_unref(GST_OBJECT(pipeline));
> g_main_loop_unref(loop);
>
> return 0;
> }
> //-------------------------------------------------------------------------------------------------------------------------------------
>
> In cb_need_data, the part where copying I am copying to GstBuffer seems to be wrong and it does not work as expected.
> Can anyone, please help me understand, how can I copy the image data perfectly and pass it downstream to other elements without losing any data?
>
> --
> Thanks and Regards,
> Saurabh Bora
>
> PH NO : 7038166900
> EMAIL : saurabh9bora at gmail.com
> saurabh9bora at outlook.com
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20190313/7013bb77/attachment-0001.html>
More information about the gstreamer-devel
mailing list