Conversion of cv::Mat to GstBuffer

Saurabh Bora saurabh9bora at gmail.com
Wed Mar 13 13:15:01 UTC 2019


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20190313/d8cb5061/attachment.html>


More information about the gstreamer-devel mailing list