I am trying to duplicate the following pipeline through a C program
gst-launch-1.0 v4l2src device=/dev/video0 ! 'video/x-raw,width=800,height=480' ! gtksink The C program nearly duplicates the output of this command line pipeline. The problem is the video is fuzzy or unfocused. I can run them side by side and the action is precise, just the command line output is clear and pristine and the c code output is bad. Since the C code is relatively short, I'll include it here. Thanks, Jack #include <string.h> #include <gtk/gtk.h> #include <gst/gst.h> #include <gst/video/videooverlay.h> #include <gdk/gdk.h> #define vid_caps "video/x-raw,width=800,height=480" /* Structure to contain all our information, so we can pass it around */ typedef struct _CustomData { GstElement *pipeline; /* Pipeline */ GstElement *playbin; /* Source */ GstElement *playsink; /* Sink */ GstElement *sink; /* sink to hold video */ GstState state; /* Current state of the pipeline */ } CustomData; /* This function is called when the PLAY button is clicked */ static void play_cb (GtkButton *button, CustomData *data) { gst_element_set_state (data->pipeline, GST_STATE_PLAYING); } /* This function is called when the PAUSE button is clicked */ static void pause_cb (GtkButton *button, CustomData *data) { gst_element_set_state (data->pipeline, GST_STATE_PAUSED); } /* This function is called when the STOP button is clicked */ static void stop_cb (GtkButton *button, CustomData *data) { gst_element_set_state (data->pipeline, GST_STATE_READY); } /* This function is called when the main window is closed */ static void delete_event_cb (GtkWidget *widget, GdkEvent *event, CustomData *data) { stop_cb (NULL, data); gtk_main_quit (); } /* This creates all the GTK+ widgets that compose our application, and registers the callbacks */ static void create_ui (CustomData *data) { GtkWidget *main_window; /* The uppermost window, containing all other windows */ GtkWidget *video_window; /* The drawing area where the video will be shown */ GtkWidget *main_box; /* VBox to hold main_hbox and the controls */ GtkWidget *main_hbox; /* HBox to hold the video_window and the stream info text widget */ GtkWidget *controls; /* HBox to hold the buttons and the slider */ GtkWidget *play_button, *pause_button, *stop_button; /* Buttons */ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (delete_event_cb), data); g_object_get (data->playsink, "widget", &video_window, NULL); gtk_widget_set_double_buffered (video_window, FALSE); play_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PLAY); g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), data); pause_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PAUSE); g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), data); controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (controls), play_button, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (controls), pause_button, FALSE, FALSE, 2); main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (main_hbox), video_window, TRUE, TRUE, 0); main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start (GTK_BOX (main_box), main_hbox, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (main_box), controls, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (main_window), main_box); gtk_window_set_default_size (GTK_WINDOW (main_window), 640, 480); gtk_widget_show_all (main_window); } /* This function is called when an End-Of-Stream message is posted on the bus. * We just set the pipeline to READY (which stops playback) */ static void eos_cb (GstBus *bus, GstMessage *msg, CustomData *data) { g_print ("End-Of-Stream reached.\n"); gst_element_set_state (data->pipeline, GST_STATE_READY); } int main(int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; GstBus *bus; GError **parse_error; GstCaps *video_caps; gboolean link_ok; /* Initialize GTK */ gtk_init (&argc, &argv); /* Initialize GStreamer */ gst_init (&argc, &argv); /* Initialize our data structure */ memset (&data, 0, sizeof (data)); /* Create the elements */ data.pipeline = gst_pipeline_new ("pipeline"); data.playbin = gst_element_factory_make ("v4l2src", "source"); data.playsink = gst_element_factory_make ("gtksink", "playsink"); video_caps = gst_caps_from_string(vid_caps); // printf("Vid caps %s.\n", vid_caps); if (!data.playbin || !data.pipeline || !data.playsink || !video_caps) { g_printerr ("Not all elements could be created.\n"); return -1; } /* Set the URI to play */ g_object_set (G_OBJECT(data.playbin), "device", "/dev/video0", NULL); gst_bin_add (GST_BIN(data.pipeline), data.playbin); gst_bin_add (GST_BIN(data.pipeline), data.playsink); if (!(gst_element_link(data.playbin, data.playsink))) { g_printerr ("Unable to link the source and the sink.\n"); gst_object_unref (data.pipeline); return -1; } gst_element_link_many (data.playbin, data.playsink, NULL); link_ok = gst_element_link_filtered (data.playbin, data.playsink, video_caps); gst_caps_unref(video_caps); if (!link_ok) { g_warning("Failed to link playbin and playsink with caps"); } /* Create the GUI */ create_ui (&data); /* Start playing */ ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); gst_object_unref (data.pipeline); return -1; } /* Start the GTK main loop. We will not regain control until gtk_main_quit is called. */ gtk_main (); /* Free resources */ gst_element_set_state (data.pipeline, GST_STATE_NULL); gst_object_unref (data.pipeline); return 0; } _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hello, Jack
I don`t really get your question. Can you be more specific, please? Also more details will be useful.
Mikl From: gstreamer-devel <[hidden email]> on behalf of Jack D <[hidden email]>
Sent: Wednesday, November 16, 2016 12:04:36 AM To: Discussion of the development of and with GStreamer Subject: Deconstructing a pipeline I am trying to duplicate the following pipeline through a C program
gst-launch-1.0 v4l2src device=/dev/video0 ! 'video/x-raw,width=800,height=480' ! gtksink
The C program nearly duplicates the output of this command line pipeline. The problem is the video is fuzzy or unfocused.
I can run them side by side and the action is precise, just the command line output is clear and pristine and the c code output is bad.
Since the C code is relatively short, I'll include it here.
Thanks,
Jack
#include <string.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
#include <gdk/gdk.h>
#define vid_caps "video/x-raw,width=800,height=480"
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData {
GstElement *pipeline; /* Pipeline */
GstElement *playbin; /* Source */
GstElement *playsink; /* Sink */
GstElement *sink; /* sink to hold video */
GstState state; /* Current state of the pipeline */
} CustomData;
/* This function is called when the PLAY button is clicked */
static void play_cb (GtkButton *button, CustomData *data) {
gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
}
/* This function is called when the PAUSE button is clicked */
static void pause_cb (GtkButton *button, CustomData *data) {
gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
}
/* This function is called when the STOP button is clicked */
static void stop_cb (GtkButton *button, CustomData *data) {
gst_element_set_state (data->pipeline, GST_STATE_READY);
}
/* This function is called when the main window is closed */
static void delete_event_cb (GtkWidget *widget, GdkEvent *event, CustomData *data) {
stop_cb (NULL, data);
gtk_main_quit ();
}
/* This creates all the GTK+ widgets that compose our application, and registers the callbacks */
static void create_ui (CustomData *data) {
GtkWidget *main_window; /* The uppermost window, containing all other windows */
GtkWidget *video_window; /* The drawing area where the video will be shown */
GtkWidget *main_box; /* VBox to hold main_hbox and the controls */
GtkWidget *main_hbox; /* HBox to hold the video_window and the stream info text widget */
GtkWidget *controls; /* HBox to hold the buttons and the slider */
GtkWidget *play_button, *pause_button, *stop_button; /* Buttons */
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (delete_event_cb), data);
g_object_get (data->playsink, "widget", &video_window, NULL);
gtk_widget_set_double_buffered (video_window, FALSE);
play_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PLAY);
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), data);
pause_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PAUSE);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), data);
controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (controls), play_button, FALSE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (controls), pause_button, FALSE, FALSE, 2);
main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (main_hbox), video_window, TRUE, TRUE, 0);
main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (main_box), main_hbox, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_box), controls, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (main_window), main_box);
gtk_window_set_default_size (GTK_WINDOW (main_window), 640, 480);
gtk_widget_show_all (main_window);
}
/* This function is called when an End-Of-Stream message is posted on the bus.
* We just set the pipeline to READY (which stops playback) */
static void eos_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
g_print ("End-Of-Stream reached.\n");
gst_element_set_state (data->pipeline, GST_STATE_READY);
}
int main(int argc, char *argv[]) {
CustomData data;
GstStateChangeReturn ret;
GstBus *bus;
GError **parse_error;
GstCaps *video_caps;
gboolean link_ok;
/* Initialize GTK */
gtk_init (&argc, &argv);
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Initialize our data structure */
memset (&data, 0, sizeof (data));
/* Create the elements */
data.pipeline = gst_pipeline_new ("pipeline");
data.playbin = gst_element_factory_make ("v4l2src", "source");
data.playsink = gst_element_factory_make ("gtksink", "playsink");
video_caps = gst_caps_from_string(vid_caps);
// printf("Vid caps %s.\n", vid_caps);
if (!data.playbin || !data.pipeline || !data.playsink || !video_caps) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Set the URI to play */
g_object_set (G_OBJECT(data.playbin), "device", "/dev/video0", NULL);
gst_bin_add (GST_BIN(data.pipeline), data.playbin);
gst_bin_add (GST_BIN(data.pipeline), data.playsink);
if (!(gst_element_link(data.playbin, data.playsink))) {
g_printerr ("Unable to link the source and the sink.\n");
gst_object_unref (data.pipeline);
return -1;
}
gst_element_link_many (data.playbin, data.playsink, NULL);
link_ok = gst_element_link_filtered (data.playbin, data.playsink, video_caps);
gst_caps_unref(video_caps);
if (!link_ok) {
g_warning("Failed to link playbin and playsink with caps");
}
/* Create the GUI */
create_ui (&data);
/* Start playing */
ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (data.pipeline);
return -1;
}
/* Start the GTK main loop. We will not regain control until gtk_main_quit is called. */
gtk_main ();
/* Free resources */
gst_element_set_state (data.pipeline, GST_STATE_NULL);
gst_object_unref (data.pipeline);
return 0;
}
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by jackson80
> if (!(gst_element_link(data.playbin, data.playsink))) {
> g_printerr ("Unable to link the source and the sink.\n"); > gst_object_unref (data.pipeline); > return -1; > } > > gst_element_link_many (data.playbin, data.playsink, NULL); > link_ok = gst_element_link_filtered (data.playbin, data.playsink, > video_caps); > gst_caps_unref(video_caps); > > if (!link_ok) { > g_warning("Failed to link playbin and playsink with caps"); > } > You are trying to link the same elements multiple times. Try linking just once with caps. Are you sure that your camera supports resolution 800x480. Shouldn't this be 800x600 or 640x480 ? I had to add a videoconvert between playbin and playsink to get your code to work with my USB camera (Logitech C310) as it doesn't support.BGR. Hope this helps. Regards Mandar Joshi _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Thank you, Mandar Joshi, the suggestion to only link once with caps solved my problem. And regarding the resolution, I am looking at the output from a video capture card that is currently set to the resolution of an odd size display. Hopefully, I will be able to capture the output and allow observation of the output at the same time. Thanks again, Jack On Thu, Nov 17, 2016 at 6:16 AM, Mandar Joshi <[hidden email]> wrote: > if (!(gst_element_link(data. _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |