Greetings,
I am attempting to capture a frame from a stream, much like the example listed here: In the part of the code where the actual frame is captured and converted is this:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Administrator
|
you might be able to:
v4l2src name=src ! video/x-raw,framerate=24/1,width=640 ! avenc_bmp ! fakesink might be able to get the bitmap info from there. ----- ------------------------------ Gstreamer 1.12.3 ------------------------------ -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
------------------------------
Gstreamer 1.16.2 ------------------------------ Windows |
Okay, I may have had a few eyes glaze over when I said my code looks like
some code where I included a link. Well, here is actual working code. My problem in in the save_images_cb routine. I can set the caps to "image/png" and the code will extract and save a png coded image file. When I try to save a bitmap with caps defined as "image/bitmap", I get an error from gst_video_convert sample and it prints "Failed converting frame. Error: Cannot find any image encoder for caps image/bitmap". #include <gtk/gtk.h> #include <gst/gst.h> #include <gst/video/video.h> #include <gst/video/videooverlay.h> /* Structure to contain all our information, so we can pass it around */ typedef struct CustomData { GstElement *pipe; GstElement *sink; GstElement *flipper; GstElement *convert; GstElement *caps; GstState state; GstStateChangeReturn ret; } CustomData; void save_images_cb(GtkWidget *widget, CustomData *data) { int i; GstCaps *caps; GstSample *from_sample, *to_sample; GError *err = NULL; GstBuffer *buf; GstMapInfo map_info; char pic_location[50], command_string[256]; g_object_get(data->sink, "last-sample", &from_sample, NULL); if (from_sample == NULL) { printf("Failed getting sample.\n"); return; } caps = gst_caps_from_string ("image/png"); /* caps = gst_caps_from_string ("image/bitmap");*/ /* caps = gst_caps_new_empty_simple ("avenc_bmp"); caps = gst_caps_from_string ("image/x-bitmap");*/ /* if (caps == NULL) { printf("Failed getting caps.\n"); return; } */ to_sample = gst_video_convert_sample (from_sample, caps, GST_CLOCK_TIME_NONE, &err); gst_caps_unref (caps); gst_sample_unref (from_sample); if (to_sample == NULL && err) { printf("Failed converting frame.\n"); printf("Error : %s\n", err->message); return; } /* sprintf(pic_location,"/media/ramdisk/sample_a.bmp");*/ sprintf(pic_location,"/media/ramdisk/sample_a.png"); buf = gst_sample_get_buffer(to_sample); if (gst_buffer_map (buf,&map_info, GST_MAP_READ)) { if (!g_file_set_contents(pic_location, (const char *) map_info.data, map_info.size, &err)){ printf("Could not save image %i.\n", i); } else { sprintf(command_string, "mv /media/ramdisk/sample_a.png /media/ramdisk/sample.png"); /* sprintf(command_string, "mv /media/ramdisk/sample_a.bmp /media/ramdisk/sample.bmp"); */ system(command_string); } } gst_sample_unref (to_sample); } int main(int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; GtkButton *temp_button; GtkWidget *vid_window, *main_window, *big_window, *button_window, *pic_button; int mkdir_status, wd; char cap_string[50]; int i; /* Initialize GTK */ gtk_init (&argc, &argv); /* Initialize GStreamer */ gst_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width(GTK_CONTAINER(main_window),0); g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (gtk_main_quit), NULL); gtk_window_set_default_size (GTK_WINDOW (main_window), 900, 600); gtk_window_set_title(GTK_WINDOW(main_window), "Test Program"); big_window = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); pic_button = gtk_button_new_with_label("Save Image"); g_signal_connect(G_OBJECT(pic_button), "clicked", G_CALLBACK(save_images_cb), (gpointer)&data); button_window = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX(button_window), pic_button, FALSE, FALSE, 0); data.pipe = gst_element_factory_make ("v4l2src", "play1"); data.sink = gst_element_factory_make ("gtksink", "sink1"); /* gst_base_sink_set_last_sample_enabled(GST_BASE_SINK(data.sink),TRUE);*/ data.convert = gst_element_factory_make ("videoconvert", "convert1"); data.caps = gst_element_factory_make ("capsfilter", "caps1"); g_object_set(G_OBJECT(data.pipe), "device", "/dev/video3", NULL); data.flipper = gst_element_factory_make ("videoflip", "videoflip"); /* if (portrait_mode){ g_object_set(G_OBJECT(data.flipper), "method", 3, NULL); } else {*/ g_object_set(G_OBJECT(data.flipper), "method", 0, NULL); /* }*/ sprintf(cap_string, "video/x-raw,width=800,height=480,framerate=25/1"); gst_util_set_object_arg (G_OBJECT (data.caps), "caps", cap_string); if ((!data.pipe) || (!data.sink) || (!data.flipper) || (!data.caps) || (!data.convert)){ g_printerr ("Not all elements could be created.\n"); return 0; } gst_element_link_many(data.pipe, data.caps, data.convert, data.flipper, data.sink); g_object_get (data.sink, "widget", &vid_window, NULL); gtk_widget_set_double_buffered (vid_window, FALSE); gtk_box_pack_start (GTK_BOX(big_window), vid_window, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(big_window), button_window, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (main_window), big_window); gtk_widget_show_all(main_window); ret = gst_element_set_state(data.pipe, GST_STATE_READY); if (ret == GST_STATE_CHANGE_FAILURE) { printf("Could not set pipe to ready.\n"); } else { gst_element_set_state(data.pipe, GST_STATE_PLAYING); gst_element_set_state(data.caps, GST_STATE_PLAYING); gst_element_set_state(data.convert, GST_STATE_PLAYING); gst_element_set_state(data.flipper, GST_STATE_PLAYING); gst_element_set_state(data.sink, GST_STATE_PLAYING); gtk_main (); gst_element_set_state(data.pipe, GST_STATE_NULL); gst_element_set_state(data.caps, GST_STATE_NULL); gst_element_set_state(data.convert, GST_STATE_NULL); gst_element_set_state(data.flipper, GST_STATE_NULL); gst_element_set_state(data.sink, GST_STATE_NULL); gst_object_unref(data.pipe); gst_object_unref(data.caps); gst_object_unref(data.convert); gst_object_unref(data.flipper); gst_object_unref(data.sink); } return 0; } -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On Wed, 20 Dec 2017 15:53:27 -0700 (MST)
jackson80 <[hidden email]> wrote: > Okay, I may have had a few eyes glaze over when I said my code looks like > some code where I included a link. > > Well, here is actual working code. My problem in in the save_images_cb > routine. I can set the caps to "image/png" and the code will extract and > save a png coded image file. When I try to save a bitmap with caps defined > as "image/bitmap", I get an error from gst_video_convert sample and it > prints "Failed converting frame. Error: Cannot find any image encoder for > caps image/bitmap". > $ gst-inspect-1.0 | grep bitmap libav: avenc_bmp: libav BMP (Windows and OS/2 bitmap) encoder libav: avdec_bmp: libav BMP (Windows and OS/2 bitmap) decoder $ gst-inspect-1.0 avenc_bmp | grep image image/bmp It looks like "image/bmp" is the correct capability to pass to gst_video_convert_sample(). Ciao, Antonio -- Antonio Ospite https://ao2.it https://twitter.com/ao2it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I get the same result doing gst-inspect-1.0 with those parameters. VIDEO:/home/user % gst-inspect-1.0 | grep bitmap libav: avdec_bmp: libav BMP (Windows and OS/2 bitmap) decoder libav: avenc_bmp: libav BMP (Windows and OS/2 bitmap) encoder VIDEO:/home/user % gst-inspect-1.0 avenc_bmp | grep image image/bmp The only difference I see is my search has avdec_bmp listed first. Has anyone ever successfully saved a bitmap file from inside a program using gst_video_convert_sample? If I cannot come up with an elegant solution from within gstreamer, I will be forced to either A: create a command line using gst-launch and save with a filesink, or B: Figure out how to take a raw image write a bitmap file myself. Best Regards, Jack On Thu, Dec 21, 2017 at 1:27 AM, Antonio Ospite <[hidden email]> wrote: On Wed, 20 Dec 2017 15:53:27 -0700 (MST) _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On Thu, 21 Dec 2017 13:33:24 -0700
Jack D <[hidden email]> wrote: > I get the same result doing gst-inspect-1.0 with those parameters. > > VIDEO:/home/user % gst-inspect-1.0 | grep bitmap > libav: avdec_bmp: libav BMP (Windows and OS/2 bitmap) decoder > libav: avenc_bmp: libav BMP (Windows and OS/2 bitmap) encoder > VIDEO:/home/user % gst-inspect-1.0 avenc_bmp | grep image > image/bmp > > The only difference I see is my search has avdec_bmp listed first. > Has anyone ever successfully saved a bitmap file from inside a program > using gst_video_convert_sample? Your program should work, I was trying to point out that you have to use image/bmp instead of image/bitmap. Ciao, Antonio -- Antonio Ospite https://ao2.it https://twitter.com/ao2it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I did notice that error on my part but image/bmp or image/bitmap, neither of these work. On Thu, Dec 21, 2017 at 2:25 PM, Antonio Ospite <[hidden email]> wrote: On Thu, 21 Dec 2017 13:33:24 -0700 _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I found a file in gst-plugins-base/gst-libs/gst/pbutils named descriptions.c and listed in the file are image formats with static descriptions. I created a test and from all these 27 formats, only two worked correctly and allowed me to save an image: image/jpeg and image/png. Also, upon closer examination using gst-inspect-1.0, I could only find three elements that state explicitly they encode image files. pnmenc, jpegenc and pngenc. So, is this just a limitation? I can create a bitmap using gst-launch but I cannot create one using gst_video_convert_sample. Is there a guide somewhere that explains using the output of gst-lauinch-1.0 -v, I can take all the srcs and sinks listed and create the correct pipeline in my program? Best Regards, Jack On Thu, Dec 21, 2017 at 3:13 PM, Jack D <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Le 22 déc. 2017 12:40 PM, "Jack D" <[hidden email]> a écrit :
If there is a rationale it is likely the rank, this is printed by gst-inspect. Only ranked element will be autoplug. Jpeg and PNG is by far the majority of the formats in use today.
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Nicolas, do you mean only primary ranked elements will be auto plugged? I get this: % gst-inspect-1.0 avenc_bmp | grep Rank Rank secondary (128) On Fri, Dec 22, 2017 at 2:51 PM, Nicolas Dufresne <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Le 26 déc. 2017 12:02 PM, "Jack D" <[hidden email]> a écrit :
No, any element with rank different then none may be plugged.
So this is not the problem. Have your read the code behind convert sample?
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Looking at gst_video_convert_sample: It first validates inputs and extracts
caps from src; then it calls build_convert_frame_pipepline. This routine creates elements needed for a conversion pipeline. Then this routine calls get_encoder. This immediately calls gst_element_factory_list_get_elements. From the debug output supplied by gst_plugin_feature_list_debug, I can see the only encoders found were jpegenc, pngenc, and pnmenc. Since none of these encoders match bmp, this is where it fails. Is there any other way to see if libav is correctly incorporated with the rest of the gstreamer software? Or do you think I should try manually building a conversion pipeline? -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Le 27 déc. 2017 1:09 PM, "jackson80" <[hidden email]> a écrit : Looking at gst_video_convert_sample: It first validates inputs and extracts To get going, you could build your own, though it could be nice to file a bug, so we can research and fix this eventually. It could be as simple as having the class string (GST feature concept) missing Encoder in it (you'll find this string in gst-inspect, something like Encoder/Video).
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by jackson80
On Wed, 27 Dec 2017 11:06:58 -0700 (MST)
jackson80 <[hidden email]> wrote: > Looking at gst_video_convert_sample: It first validates inputs and extracts > caps from src; then it calls build_convert_frame_pipepline. This routine > creates elements needed for a conversion pipeline. Then this routine calls > get_encoder. This immediately calls gst_element_factory_list_get_elements. > From the debug output supplied by gst_plugin_feature_list_debug, I can see > the only encoders found were jpegenc, pngenc, and pnmenc. Since none of > these encoders match bmp, this is where it fails. > Is there any other way to see if libav is correctly incorporated with the > rest of the gstreamer software? > Or do you think I should try manually building a conversion pipeline? > A simplified version of your test program works here (Debian unstable, GStreamer 1.12.4) and can save bmp files using gst_video_convert_sample(), so you might be experiencing a local problem. IIRC we didn't ask the usual questions: what GStreamer version? What system? I am pasting the test program below: /* * Compile with: * gcc -ggdb test.c $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-video-1.0 gtk+-3.0) */ #include <gtk/gtk.h> #include <gst/gst.h> #include <gst/video/video.h> /* Structure to contain all our information, so we can pass it around */ typedef struct CustomData { GstElement *pipeline; GstElement *source; GstElement *sink; GstElement *convert; GstElement *caps; GstState state; GstStateChangeReturn ret; } CustomData; void save_images_cb(GtkWidget *widget, CustomData *data) { int i; GstCaps *caps; GstSample *from_sample, *to_sample; GError *err = NULL; GstBuffer *buf; GstMapInfo map_info; char pic_location[50], command_string[256]; g_object_get(data->sink, "last-sample", &from_sample, NULL); if (from_sample == NULL) { printf("Failed getting sample.\n"); return; } caps = gst_caps_from_string ("image/bmp"); if (caps == NULL) { printf("Failed getting caps.\n"); return; } to_sample = gst_video_convert_sample (from_sample, caps, GST_CLOCK_TIME_NONE, &err); gst_caps_unref (caps); gst_sample_unref (from_sample); if (to_sample == NULL && err) { printf("Failed converting frame.\n"); printf("Error : %s\n", err->message); return; } sprintf(pic_location,"/tmp/sample_a.bmp"); buf = gst_sample_get_buffer(to_sample); if (gst_buffer_map (buf,&map_info, GST_MAP_READ)) { if (!g_file_set_contents(pic_location, (const char *) map_info.data, map_info.size, &err)){ printf("Could not save image %i.\n", i); } } gst_sample_unref (to_sample); } int main(int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; GtkButton *temp_button; GtkWidget *vid_window, *main_window, *big_window, *button_window, *pic_button; int mkdir_status, wd; GstCaps *caps; int i; /* Initialize GTK */ gtk_init (&argc, &argv); /* Initialize GStreamer */ gst_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width(GTK_CONTAINER(main_window),0); g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (gtk_main_quit), NULL); gtk_window_set_default_size (GTK_WINDOW (main_window), 900, 600); gtk_window_set_title(GTK_WINDOW(main_window), "Test Program"); big_window = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); pic_button = gtk_button_new_with_label("Save Image"); g_signal_connect(G_OBJECT(pic_button), "clicked", G_CALLBACK(save_images_cb), (gpointer)&data); button_window = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX(button_window), pic_button, FALSE, FALSE, 0); data.pipeline = gst_pipeline_new("video-pipeline"); data.source = gst_element_factory_make ("videotestsrc", "play1"); data.sink = gst_element_factory_make ("gtksink", "sink1"); /* gst_base_sink_set_last_sample_enabled(GST_BASE_SINK(data.sink),TRUE);*/ data.convert = gst_element_factory_make ("videoconvert", "convert1"); data.caps = gst_element_factory_make ("capsfilter", "caps1"); caps = gst_caps_from_string("video/x-raw,width=800,height=480,framerate=25/1"); g_object_set(G_OBJECT(data.caps), "caps", caps, NULL); gst_caps_unref(caps); if ((!data.pipeline) || (!data.source) || (!data.sink) || (!data.caps) || (!data.convert)){ g_printerr ("Not all elements could be created.\n"); return 0; } gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.caps, data.convert, data.sink, NULL); gst_element_link_many(data.source, data.caps, data.convert, data.sink, NULL); g_object_get (data.sink, "widget", &vid_window, NULL); gtk_box_pack_start (GTK_BOX(big_window), vid_window, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(big_window), button_window, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (main_window), big_window); gtk_widget_show_all(main_window); ret = gst_element_set_state(data.pipeline, GST_STATE_READY); if (ret == GST_STATE_CHANGE_FAILURE) { printf("Could not set pipe to ready.\n"); } else { gst_element_set_state(data.pipeline, GST_STATE_PLAYING); gtk_main (); gst_element_set_state(data.pipeline, GST_STATE_NULL); gst_object_unref(data.pipeline); gst_object_unref(data.source); gst_object_unref(data.caps); gst_object_unref(data.convert); gst_object_unref(data.sink); } return 0; } -- Antonio Ospite https://ao2.it https://twitter.com/ao2it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I am using GStreamer 1.6.3, Centos 4.7.5 It may be a local problem as the test program you provided gave me the same error message: Failed converting frame. Error : Cannot find any image encoder for caps image/bmp I was able to build my own pipeline and save an image, essentially using the same code as gst_video_convert_sample and the other routines below that. In build_convert_frame_pipeline, for the get_encoder part, I used GstElementFactory *bitmap_factory = gst_element_factory_find("avenc_bmp"); GstElement *encoder = gst_element_factory_create(bitmap_factory, "bitmap_elem"); Then I used encoder as it already appeared in build_convert_frame_pipeline. I am going to test with some newer versions of GStreamer, but I had hoped to keep 1.6.3 as it has proven to be very stable for my applications. On Fri, Dec 29, 2017 at 5:37 AM, Antonio Ospite <[hidden email]> wrote: On Wed, 27 Dec 2017 11:06:58 -0700 (MST) _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |