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