Trying to encode a captured frame as a Bitmap (.bmp)

Jack D jackstuff3 at gmail.com
Fri Dec 29 16:18:44 UTC 2017


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 <ao2 at ao2.it> wrote:

> On Wed, 27 Dec 2017 11:06:58 -0700 (MST)
> jackson80 <jackstuff3 at gmail.com> 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?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20171229/9093e486/attachment-0001.html>


More information about the gstreamer-devel mailing list