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

jackson80 jackstuff3 at gmail.com
Wed Dec 20 22:53:27 UTC 2017


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/


More information about the gstreamer-devel mailing list