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

Antonio Ospite ao2 at ao2.it
Fri Dec 29 12:37:20 UTC 2017


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?


More information about the gstreamer-devel mailing list