GStreamer-1.2.1 appsink opencv-2.4.7 buffers and IplImage conversion

lebies debeer.leon at gmail.com
Mon Jan 13 04:58:24 PST 2014


After much googling and a bit of hit-n-miss, I'm having difficulty converting
an appsink buffer to IplImage (in C). I'm also on a steep learning curve
with both GStreamer and OpenCV, so please bear with me :).

I seem to be getting the buffer and suspect it may have something to do with
converting to an IplImage,
but I have no idea this is the case. I might not be getting the buffer at
all! All I do know is I get the messages and land in the callback
(newbuffer).

Here's the code I have thus far:

#define CAPS "video/x-raw,format=RGB,width=640,height=360"

const char app_sink_name[] = "sink";

GstFlowReturn newbuffer(GstAppSink * app_sink, gpointer user_data)
{
	gint width=640, height=360;
	GdkPixbuf* pixbuf;
	GstMapInfo map;

	//g_print ("newbuffer...\n");

	GstSample *sample = gst_app_sink_pull_sample ((GstAppSink*)app_sink);

	/* if we have a buffer now, convert it to a pixbuf. */
	if (sample) {

		g_print ("have sample...\n");

		/* create pixmap from buffer and save, gstreamer video buffers have a
stride
		* that is rounded up to the nearest multiple of 4 */
		buffer = gst_sample_get_buffer (sample);
		gst_buffer_map (buffer, &map, GST_MAP_READ);

		pixbuf = gdk_pixbuf_new_from_data (map.data,
						GDK_COLORSPACE_RGB, FALSE, 8, width, height,
						GST_ROUND_UP_4 (width * 3), NULL, NULL);

		IplImage* frame = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
	 	frame->widthStep = width * 3;
		frame->imageData = (char*) pixbuf;

		cvShowImage("gst", frame);

		cvWaitKey(0);

		cvReleaseImage( &frame );
		cvDestroyWindow( "gst" );

		/* let's see what we have in the pixbuf */
		gdk_pixbuf_save (pixbuf, "/home/user/workspace/gsttut/Debug/snap.png",
"png", &error, NULL);

		gst_buffer_unmap (buffer, &map);

		g_main_loop_quit(loop);
		g_main_loop_unref(loop);

	}

	return GST_FLOW_OK;
}



int
main (int argc, char *argv[])
{
	cvNamedWindow("gst", CV_WINDOW_AUTOSIZE);

	gst_init (&argc, &argv);

	loop = g_main_loop_new (NULL, FALSE);
	if (argc != 2) {
		g_print ("usage: %s <rtspsrc>\n",
		argv[0]);
		exit (-1);
	}


	/* create a new pipeline */
        pipeline = gst_pipeline_new("pipeline");

	video/x-raw,format=RGB,width=640,height=480 !"
	descr = g_strdup_printf ("rtspsrc location=%s do-timestamp=true
is_live=true protocols=tcp ! rtph264depay ! avdec_h264 ! videoconvert !
videoscale ! "
		"appsink name=sink caps=\"" CAPS "\"", argv[1]);
	pipeline = gst_parse_launch (descr, &error);
	if (error != NULL) {
		g_print ("could not construct pipeline: %s\n", error->message);
		g_error_free (error);
		exit (-1);
	}

	/* watch for messages on the pipeline's bus (note that this will only
	* work like this when a GLib main loop is running) */
	bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
	gst_bus_add_watch (bus, bus_call, loop);
	gst_object_unref (bus);

	sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
	gst_app_sink_set_emit_signals ((GstAppSink*)sink, TRUE);
	gst_app_sink_set_drop((GstAppSink*)sink, TRUE);
	gst_app_sink_set_max_buffers((GstAppSink*)sink, 1);


	/* start PLAYING */
	ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
	if (ret == GST_STATE_CHANGE_FAILURE) {
		GstMessage *msg;

		g_print ("Failed to start up pipeline!\n");

		/* check if there is an error message with details on the bus */
		msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
		if (msg) {
			GError *err = NULL;

			gst_message_parse_error (msg, &err, NULL);
			g_print ("ERROR: %s\n", err->message);
			g_error_free (err);
			gst_message_unref (msg);
		}
		return -1;
	}

	callbacks.eos = NULL;
	callbacks.new_preroll = NULL;
	callbacks.new_sample = newbuffer;
	gst_app_sink_set_callbacks((GstAppSink *)
gst_bin_get_by_name(GST_BIN(pipeline), app_sink_name), &callbacks, NULL,
NULL);


	/* create a mainloop that runs/iterates the default GLib main context
	* (context NULL), in other words: makes the context check if anything
	* it watches for has happened. When a message has been posted on the
	* bus, the default main context will automatically call our
	* my_bus_callback() function to notify us of that message.
	* The main loop will be run until someone calls g_main_loop_quit()
	*/
   g_main_loop_run (loop);

  /* clean up */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  g_main_loop_unref (loop);

}

And here are the images I get:
http://imgur.com/HTBme6G,vilRCR9 <http://imgur.com/HTBme6G,vilRCR9> 
http://imgur.com/HTBme6G,vilRCR9

There are no errors compiling or linking, and the program runs error-free.

Thanks in advance for any help.




--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/GStreamer-1-2-1-appsink-opencv-2-4-7-buffers-and-IplImage-conversion-tp4664627.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list