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