summaryrefslogtreecommitdiff
path: root/tests/examples
diff options
context:
space:
mode:
authorYouness Alaoui <youness.alaoui@collabora.co.uk>2012-09-10 16:09:26 -0400
committerOlivier CrΓͺte <olivier.crete@collabora.com>2012-09-10 16:09:26 -0400
commit1ba24e1306dd1623bae3400e12e073c9f6fc8d51 (patch)
treefe2df82a40468ac40fe25a58fc7479a7e2e3a3d4 /tests/examples
parent1ef529601b0a9dfd9d278e37dbe141f21b9b8525 (diff)
UVC H264 plugin
Diffstat (limited to 'tests/examples')
-rw-r--r--tests/examples/Makefile.am10
-rw-r--r--tests/examples/uvch264/Makefile.am36
-rw-r--r--tests/examples/uvch264/boolean_property.glade94
-rw-r--r--tests/examples/uvch264/enum_property.glade88
-rw-r--r--tests/examples/uvch264/enum_property_gtk2.glade88
-rw-r--r--tests/examples/uvch264/int_property.glade147
-rw-r--r--tests/examples/uvch264/test-uvch264.c673
-rw-r--r--tests/examples/uvch264/window.glade345
8 files changed, 1479 insertions, 2 deletions
diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am
index eef73e6c9..d166a6605 100644
--- a/tests/examples/Makefile.am
+++ b/tests/examples/Makefile.am
@@ -1,5 +1,11 @@
+if USE_UVCH264
+UVCH264_DIR=uvch264
+else
+UVCH264_DIR=
+endif
+
if HAVE_GTK
-GTK_EXAMPLES=mxf scaletempo camerabin2
+GTK_EXAMPLES=mxf scaletempo camerabin2 $(UVCH264_DIR)
else
GTK_EXAMPLES=
endif
@@ -13,6 +19,6 @@ endif
OPENCV_EXAMPLES=opencv
SUBDIRS= $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES)
-DIST_SUBDIRS= camerabin2 directfb mxf scaletempo opencv
+DIST_SUBDIRS= camerabin2 directfb mxf scaletempo opencv uvch264
include $(top_srcdir)/common/parallel-subdirs.mak
diff --git a/tests/examples/uvch264/Makefile.am b/tests/examples/uvch264/Makefile.am
new file mode 100644
index 000000000..e02b88821
--- /dev/null
+++ b/tests/examples/uvch264/Makefile.am
@@ -0,0 +1,36 @@
+TEST_UVCH264_GLADE_FILES = window.glade \
+ boolean_property.glade \
+ enum_property.glade \
+ int_property.glade
+
+if HAVE_GTK
+
+TEST_UVCH264_EXAMPLES = test-uvch264
+
+test_uvch264_SOURCES = test-uvch264.c
+test_uvch264_CFLAGS = \
+ $(GST_PLUGINS_BAD_CFLAGS) \
+ $(GST_PLUGINS_BASE_CFLAGS) \
+ $(GST_VIDEO_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(GMODULE_EXPORT_CFLAGS) \
+ -DGST_USE_UNSTABLE_API
+test_uvch264_LDADD = \
+ $(GST_PLUGINS_BASE_LIBS) \
+ $(GST_VIDEO_LIBS) \
+ $(GST_LIBS) \
+ -lgstinterfaces-@GST_MAJORMINOR@ \
+ $(GTK_LIBS) \
+ $(GMODULE_EXPORT_LIBS)
+
+noinst_DATA = $(TEST_UVCH264_GLADE_FILES)
+
+else
+TEST_UVCH264_EXAMPLES =
+endif
+
+noinst_PROGRAMS = $(TEST_UVCH264_EXAMPLES)
+
+EXTRA_DIST = $(TEST_UVCH264_GLADE_FILES)
+
diff --git a/tests/examples/uvch264/boolean_property.glade b/tests/examples/uvch264/boolean_property.glade
new file mode 100644
index 000000000..d391a58c6
--- /dev/null
+++ b/tests/examples/uvch264/boolean_property.glade
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkHBox" id="boolean-property">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">18</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="value">
+ <property name="label" translatable="yes"> Disabled </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="toggled" handler="on_button_toggled" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="get">
+ <property name="label" translatable="yes">Get</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_get_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="set">
+ <property name="label" translatable="yes">Set</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_set_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label66">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Default</property>
+ <property name="width_chars">8</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default">
+ <property name="label" translatable="yes"> Disabled </property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="toggled" handler="on_button_toggled" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/tests/examples/uvch264/enum_property.glade b/tests/examples/uvch264/enum_property.glade
new file mode 100644
index 000000000..0dfb9747f
--- /dev/null
+++ b/tests/examples/uvch264/enum_property.glade
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkHBox" id="enum-property">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">18</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="value">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="get">
+ <property name="label" translatable="yes">Get</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_get_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="set">
+ <property name="label" translatable="yes">Set</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_set_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label72">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Default</property>
+ <property name="width_chars">8</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="default">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/tests/examples/uvch264/enum_property_gtk2.glade b/tests/examples/uvch264/enum_property_gtk2.glade
new file mode 100644
index 000000000..487efbe5c
--- /dev/null
+++ b/tests/examples/uvch264/enum_property_gtk2.glade
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkHBox" id="enum-property">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">18</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="value">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="get">
+ <property name="label" translatable="yes">Get</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_get_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="set">
+ <property name="label" translatable="yes">Set</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_set_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label72">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Default</property>
+ <property name="width_chars">8</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="default">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/tests/examples/uvch264/int_property.glade b/tests/examples/uvch264/int_property.glade
new file mode 100644
index 000000000..422ce1cdc
--- /dev/null
+++ b/tests/examples/uvch264/int_property.glade
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkHBox" id="int-property">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">18</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="value">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">10</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="get">
+ <property name="label" translatable="yes">Get</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_get_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="set">
+ <property name="label" translatable="yes">Set</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_set_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Minimum</property>
+ <property name="width_chars">8</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="minimum">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">10</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Default</property>
+ <property name="width_chars">8</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="default">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">10</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Maximum</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="maximum">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">10</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/tests/examples/uvch264/test-uvch264.c b/tests/examples/uvch264/test-uvch264.c
new file mode 100644
index 000000000..78d8ac110
--- /dev/null
+++ b/tests/examples/uvch264/test-uvch264.c
@@ -0,0 +1,673 @@
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
+#include <gst/video/video.h>
+
+#define WINDOW_GLADE "window.glade"
+#define INT_PROPERTY_GLADE "int_property.glade"
+#define ENUM_PROPERTY_GLADE "enum_property.glade"
+#define BOOL_PROPERTY_GLADE "boolean_property.glade"
+
+#define PROPERTY_TO_VBOX \
+ properties[i].dynamic ? GTK_BOX (dynamic_vbox) : GTK_BOX (static_vbox)
+
+#define GET_WIDGET(object, type, name) \
+ type (gtk_builder_get_object ((object)->builder, name))
+
+#define GET_PROP_WIDGET(type, name) GET_WIDGET (&(properties[i]), type, name)
+
+static guint h264_xid, preview_xid;
+
+typedef struct
+{
+ GtkBuilder *builder;
+ GstElement *src;
+ enum
+ { NONE, INT, ENUM, BOOL } type;
+ const gchar *property_name;
+ gboolean readonly;
+ gboolean dynamic;
+} Prop;
+
+typedef struct
+{
+ GtkBuilder *builder;
+ GstElement *bin;
+ GstElement *src;
+ GstElement *identity;
+ GstElement *vid_capsfilter;
+ GstElement *vf_capsfilter;
+} Main;
+
+Prop properties[] = {
+ {NULL, NULL, INT, "initial-bitrate", FALSE, FALSE},
+ {NULL, NULL, INT, "slice-units", FALSE, FALSE},
+ {NULL, NULL, ENUM, "slice-mode", FALSE, FALSE},
+ {NULL, NULL, INT, "iframe-period", FALSE, FALSE},
+ {NULL, NULL, ENUM, "usage-type", FALSE, FALSE},
+ {NULL, NULL, ENUM, "entropy", FALSE, FALSE},
+ {NULL, NULL, BOOL, "enable-sei", FALSE, FALSE},
+ {NULL, NULL, INT, "num-reorder-frames", FALSE, FALSE},
+ {NULL, NULL, BOOL, "preview-flipped", FALSE, FALSE},
+ {NULL, NULL, INT, "leaky-bucket-size", FALSE, FALSE},
+ {NULL, NULL, INT, "num-clock-samples", FALSE, TRUE},
+ {NULL, NULL, ENUM, "rate-control", FALSE, TRUE},
+ {NULL, NULL, BOOL, "fixed-framerate", FALSE, TRUE},
+ {NULL, NULL, INT, "max-mbps", TRUE, TRUE},
+ {NULL, NULL, INT, "level-idc", FALSE, TRUE},
+ {NULL, NULL, INT, "peak-bitrate", FALSE, TRUE},
+ {NULL, NULL, INT, "average-bitrate", FALSE, TRUE},
+ {NULL, NULL, INT, "min-iframe-qp", FALSE, TRUE},
+ {NULL, NULL, INT, "max-iframe-qp", FALSE, TRUE},
+ {NULL, NULL, INT, "min-pframe-qp", FALSE, TRUE},
+ {NULL, NULL, INT, "max-pframe-qp", FALSE, TRUE},
+ {NULL, NULL, INT, "min-bframe-qp", FALSE, TRUE},
+ {NULL, NULL, INT, "max-bframe-qp", FALSE, TRUE},
+ {NULL, NULL, INT, "ltr-buffer-size", FALSE, TRUE},
+ {NULL, NULL, INT, "ltr-encoder-control", FALSE, TRUE},
+};
+
+static void set_drop_probability (Main * self);
+static void get_all_properties (void);
+static void probe_all_properties (gboolean playing);
+
+/* Callbacks */
+void on_button_toggled (GtkToggleButton * button, gpointer user_data);
+void on_get_button_clicked (GtkButton * button, gpointer user_data);
+void on_set_button_clicked (GtkButton * button, gpointer user_data);
+void on_button_ready_clicked (GtkButton * button, gpointer user_data);
+void on_button_null_clicked (GtkButton * button, gpointer user_data);
+void on_button_playing_clicked (GtkButton * button, gpointer user_data);
+void on_iframe_button_clicked (GtkButton * button, gpointer user_data);
+void on_renegotiate_button_clicked (GtkButton * button, gpointer user_data);
+void on_start_capture_button_clicked (GtkButton * button, gpointer user_data);
+void on_stop_capture_button_clicked (GtkButton * button, gpointer user_data);
+void on_window_destroyed (GtkWindow * window, gpointer user_data);
+
+static GstEvent *
+new_upstream_force_key_unit (GstClockTime running_time,
+ gboolean all_headers, guint count)
+{
+ GstEvent *force_key_unit_event;
+ GstStructure *s;
+
+ s = gst_structure_new ("GstForceKeyUnit",
+ "running-time", GST_TYPE_CLOCK_TIME, running_time,
+ "all-headers", G_TYPE_BOOLEAN, all_headers,
+ "count", G_TYPE_UINT, count, NULL);
+ force_key_unit_event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s);
+
+ return force_key_unit_event;
+}
+
+void
+on_get_button_clicked (GtkButton * button, gpointer user_data)
+{
+ Prop *property = user_data;
+
+ switch (property->type) {
+ case INT:
+ {
+ gchar *val;
+ gint val_int;
+ g_object_get (property->src, property->property_name, &val_int, NULL);
+ val = g_strdup_printf ("%d", val_int);
+ gtk_entry_set_text (GET_WIDGET (property, GTK_ENTRY, "value"), val);
+ g_free (val);
+ }
+ break;
+ case ENUM:
+ {
+ GParamSpec *param;
+ gint val;
+
+ g_object_get (property->src, property->property_name, &val, NULL);
+ param = g_object_class_find_property (G_OBJECT_GET_CLASS (property->src),
+ property->property_name);
+ if (G_IS_PARAM_SPEC_ENUM (param)) {
+ GEnumValue *values;
+ guint i = 0;
+
+ values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
+
+ while (values[i].value_name) {
+ if (values[i].value == val) {
+ gtk_combo_box_set_active (GET_WIDGET (property,
+ (GtkComboBox *), "value"), i);
+ break;
+ }
+ i++;
+ }
+ }
+ }
+ break;
+ case BOOL:
+ {
+ gboolean val;
+
+ g_object_get (property->src, property->property_name, &val, NULL);
+ gtk_toggle_button_set_active (GET_WIDGET (property,
+ (GtkToggleButton *), "value"), val);
+ }
+ break;
+ case NONE:
+ default:
+ break;
+ }
+}
+
+void
+on_set_button_clicked (GtkButton * button, gpointer user_data)
+{
+ Prop *property = user_data;
+
+ switch (property->type) {
+ case INT:
+ {
+ int val_int;
+ const gchar *val;
+
+ val = gtk_entry_get_text (GET_WIDGET (property, GTK_ENTRY, "value"));
+ val_int = (int) g_ascii_strtoll (val, NULL, 0);
+ g_object_set (property->src, property->property_name, val_int, NULL);
+ }
+ break;
+ case ENUM:
+ {
+ GParamSpec *param;
+
+ param = g_object_class_find_property (G_OBJECT_GET_CLASS (property->src),
+ property->property_name);
+ if (G_IS_PARAM_SPEC_ENUM (param)) {
+ GEnumValue *values;
+ guint val = 0;
+
+ values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
+
+ val = gtk_combo_box_get_active (GET_WIDGET (property,
+ (GtkComboBox *), "value"));
+ g_object_set (property->src, property->property_name,
+ values[val].value, NULL);
+ }
+ }
+ break;
+ case BOOL:
+ {
+ gboolean val;
+
+ val = gtk_toggle_button_get_active (GET_WIDGET (property,
+ (GtkToggleButton *), "value"));
+ g_object_set (property->src, property->property_name, val, NULL);
+ }
+ break;
+ case NONE:
+ default:
+ break;
+ }
+ get_all_properties ();
+}
+
+void
+on_button_toggled (GtkToggleButton * button, gpointer user_data)
+{
+ if (gtk_toggle_button_get_active (button))
+ gtk_button_set_label (GTK_BUTTON (button), " Enabled ");
+ else
+ gtk_button_set_label (GTK_BUTTON (button), " Disabled ");
+}
+
+static gboolean
+set_caps (Main * self, gboolean send_event)
+{
+ const gchar *h264_filter;
+ const gchar *raw_filter;
+ GstCaps *h264_caps = NULL;
+ GstCaps *raw_caps = NULL;
+ gboolean ret = TRUE;
+
+ h264_filter = gtk_entry_get_text (GET_WIDGET (self, GTK_ENTRY, "h264_caps"));
+ raw_filter =
+ gtk_entry_get_text (GET_WIDGET (self, GTK_ENTRY, "preview_caps"));
+ if (h264_filter)
+ h264_caps = gst_caps_from_string (h264_filter);
+ if (raw_filter)
+ raw_caps = gst_caps_from_string (raw_filter);
+
+ g_debug ("H264 caps : %s", gst_caps_to_string (h264_caps));
+ g_debug ("Preview caps : %s", gst_caps_to_string (raw_caps));
+ if (!h264_caps || !raw_caps) {
+ g_debug ("Invalid caps");
+ ret = FALSE;
+ goto end;
+ }
+
+ g_object_set (self->vid_capsfilter, "caps", h264_caps, NULL);
+ g_object_set (self->vf_capsfilter, "caps", raw_caps, NULL);
+
+ if (send_event) {
+ gst_element_send_event (GST_ELEMENT (self->src),
+ gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
+ gst_structure_new ("renegotiate", NULL)));
+ }
+
+end:
+ if (h264_caps)
+ gst_caps_unref (h264_caps);
+ if (raw_caps)
+ gst_caps_unref (raw_caps);
+
+ return ret;
+}
+
+void
+on_button_ready_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+
+ set_caps (self, FALSE);
+ gst_element_set_state (self->bin, GST_STATE_READY);
+ probe_all_properties (FALSE);
+ get_all_properties ();
+}
+
+void
+on_button_null_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+
+ gst_element_set_state (self->bin, GST_STATE_NULL);
+ probe_all_properties (FALSE);
+ get_all_properties ();
+}
+
+void
+on_button_playing_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+
+ if (gst_element_set_state (self->bin, GST_STATE_PLAYING) ==
+ GST_STATE_CHANGE_FAILURE) {
+ g_debug ("Unable to go to state PLAYING");
+ }
+ set_caps (self, FALSE);
+ probe_all_properties (TRUE);
+ get_all_properties ();
+
+ set_drop_probability (self);
+}
+
+void
+on_iframe_button_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+ GstEvent *event;
+ gboolean pps_sps;
+
+ set_drop_probability (self);
+ pps_sps = gtk_toggle_button_get_active (GET_WIDGET (self, (GtkToggleButton *),
+ "pps_sps"));
+
+ event = new_upstream_force_key_unit (GST_CLOCK_TIME_NONE, pps_sps, 0);
+ gst_element_send_event (GST_ELEMENT (self->src), event);
+}
+
+void
+on_renegotiate_button_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+
+ set_caps (self, TRUE);
+ probe_all_properties (GST_STATE (self->bin) >= GST_STATE_PAUSED);
+ get_all_properties ();
+}
+
+void
+on_start_capture_button_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+
+ set_caps (self, FALSE);
+ g_signal_emit_by_name (G_OBJECT (self->src), "start-capture", NULL);
+ probe_all_properties (GST_STATE (self->bin) >= GST_STATE_PAUSED);
+ get_all_properties ();
+}
+
+void
+on_stop_capture_button_clicked (GtkButton * button, gpointer user_data)
+{
+ Main *self = user_data;
+
+ set_caps (self, FALSE);
+ g_signal_emit_by_name (G_OBJECT (self->src), "stop-capture", NULL);
+ probe_all_properties (GST_STATE (self->bin) >= GST_STATE_PAUSED);
+ get_all_properties ();
+}
+
+void
+on_window_destroyed (GtkWindow * window, gpointer user_data)
+{
+ gtk_main_quit ();
+}
+
+static gboolean
+_bus_callback (GstBus * bus, GstMessage * message, gpointer user_data)
+{
+ const GstStructure *s = gst_message_get_structure (message);
+ GstObject *source = NULL;
+
+ if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT &&
+ gst_structure_has_name (s, "prepare-xwindow-id")) {
+ source = GST_MESSAGE_SRC (message);
+ if (!g_strcmp0 (gst_object_get_name (source), "h264_sink"))
+ gst_x_overlay_set_window_handle (GST_X_OVERLAY (source), h264_xid);
+ else
+ gst_x_overlay_set_window_handle (GST_X_OVERLAY (source), preview_xid);
+ }
+
+ return TRUE;
+}
+
+static void
+set_drop_probability (Main * self)
+{
+ const gchar *drop;
+ gdouble drop_probability = 0.0;
+
+ drop = gtk_entry_get_text (GET_WIDGET (self, GTK_ENTRY, "drop"));
+ drop_probability = g_ascii_strtod (drop, NULL);
+ g_debug ("Setting drop probability to : %f", drop_probability);
+ g_object_set (self->identity, "drop-probability", drop_probability, NULL);
+}
+
+static void
+get_all_properties (void)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (properties); i++)
+ on_get_button_clicked (NULL, &properties[i]);
+
+}
+
+static void
+probe_all_properties (gboolean playing)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (properties); i++) {
+ gboolean return_value, changeable, default_bool;
+ guint mask, minimum, maximum, default_int;
+ GParamSpec *param;
+
+ /* When playing, ignore static controls */
+ if (playing && !properties[i].dynamic)
+ continue;
+
+ switch (properties[i].type) {
+ case INT:
+ g_signal_emit_by_name (G_OBJECT (properties[i].src), "get-int-setting",
+ properties[i].property_name, &minimum, &default_int, &maximum,
+ &return_value, NULL);
+ if (return_value) {
+ gchar *min, *def, *max;
+
+ min = g_strdup_printf ("%d", minimum);
+ def = g_strdup_printf ("%d", default_int);
+ max = g_strdup_printf ("%d", maximum);
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "minimum"), min);
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "default"), def);
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "maximum"), max);
+ g_free (min);
+ g_free (def);
+ g_free (max);
+ } else {
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "minimum"), "");
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "default"), "");
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "maximum"), "");
+ }
+ break;
+ case ENUM:
+ g_signal_emit_by_name (G_OBJECT (properties[i].src), "get-enum-setting",
+ properties[i].property_name, &mask, &default_int, &return_value,
+ NULL);
+ param =
+ g_object_class_find_property (G_OBJECT_GET_CLASS (properties
+ [i].src), properties[i].property_name);
+ if (G_IS_PARAM_SPEC_ENUM (param)) {
+ GEnumValue *values;
+ guint j = 0;
+
+ values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
+
+ if (return_value) {
+ while (values[j].value_name) {
+ if (values[j].value == default_int) {
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "default"),
+ values[j].value_name);
+ break;
+ }
+ j++;
+ }
+ } else {
+ gtk_entry_set_text (GET_PROP_WIDGET (GTK_ENTRY, "default"), "");
+ }
+
+ j = 0;
+ while (values[j].value_name) {
+#if !GTK_CHECK_VERSION (2, 24, 0)
+ gtk_combo_box_remove_text (GET_PROP_WIDGET ((GtkComboBox *),
+ "value"), 0);
+#else
+ gtk_combo_box_text_remove (GET_PROP_WIDGET ((GtkComboBoxText *),
+ "value"), 0);
+#endif
+ j++;
+ }
+
+ j = 0;
+ while (values[j].value_name) {
+ gchar *val;
+ if (return_value && (mask & (1 << values[j].value)) != 0)
+ val = g_strdup_printf ("**%s**", values[j].value_name);
+ else
+ val = g_strdup (values[j].value_name);
+
+#if !GTK_CHECK_VERSION (2, 24, 0)
+ gtk_combo_box_append_text (GET_PROP_WIDGET ((GtkComboBox *),
+ "value"), val);
+#else
+ gtk_combo_box_text_append_text (GET_PROP_WIDGET ((GtkComboBoxText
+ *), "value"), val);
+#endif
+ g_free (val);
+ j++;
+ }
+ }
+ break;
+ case BOOL:
+ g_signal_emit_by_name (G_OBJECT (properties[i].src),
+ "get-boolean-setting", properties[i].property_name,
+ &changeable, &default_bool, &return_value, NULL);
+ if (return_value) {
+ gtk_widget_set_sensitive (GET_PROP_WIDGET (GTK_WIDGET, "value"),
+ changeable);
+ gtk_widget_set_sensitive (GET_PROP_WIDGET (GTK_WIDGET, "get"),
+ changeable);
+ gtk_widget_set_sensitive (GET_PROP_WIDGET (GTK_WIDGET, "set"),
+ changeable);
+ gtk_toggle_button_set_active (GET_PROP_WIDGET ((GtkToggleButton *),
+ "default"), default_bool);
+ }
+ break;
+ case NONE:
+ default:
+ break;
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ Main self = { NULL, NULL, NULL, NULL };
+ GstBus *bus = NULL;
+ GtkWidget *window, *static_vbox, *dynamic_vbox, *da;
+ gchar *drop;
+ gdouble drop_probability;
+ GdkWindow *gdk_win = NULL;
+ const char *device = "/dev/video0";
+ GError *error = NULL;
+ int i;
+
+ gtk_init (&argc, &argv);
+ gst_init (&argc, &argv);
+
+ if (argc > 1)
+ device = argv[1];
+ else
+ g_print ("Usage : %s [device]\nUsing default device : %s\n",
+ argv[0], device);
+
+
+ self.bin = gst_parse_launch ("uvch264_src name=src src.vidsrc ! queue ! "
+ "capsfilter name=vid_cf ! identity name=identity ! ffdec_h264 ! "
+ "xvimagesink name=h264_sink async=false "
+ "src.vfsrc ! queue ! capsfilter name=vf_cf ! "
+ "xvimagesink name=preview_sink async=false", NULL);
+
+ if (!self.bin)
+ return -1;
+
+ /* Listen to the bus for messages */
+ bus = gst_element_get_bus (self.bin);
+ gst_bus_add_watch (bus, _bus_callback, self.bin);
+ gst_object_unref (bus);
+
+ self.src = gst_bin_get_by_name (GST_BIN (self.bin), "src");
+ self.identity = gst_bin_get_by_name (GST_BIN (self.bin), "identity");
+ self.vid_capsfilter = gst_bin_get_by_name (GST_BIN (self.bin), "vid_cf");
+ self.vf_capsfilter = gst_bin_get_by_name (GST_BIN (self.bin), "vf_cf");
+
+ self.builder = gtk_builder_new ();
+ gtk_builder_add_from_file (self.builder, WINDOW_GLADE, &error);
+ if (error) {
+ g_debug ("Unable to load glade file : %s", error->message);
+ goto end;
+ }
+ gtk_builder_connect_signals (self.builder, &self);
+
+ g_object_get (self.identity, "drop-probability", &drop_probability, NULL);
+ drop = g_strdup_printf ("%f", drop_probability);
+ gtk_entry_set_text (GET_WIDGET (&self, GTK_ENTRY, "drop"), drop);
+ g_free (drop);
+ window = GET_WIDGET (&self, GTK_WIDGET, "window");
+ static_vbox = GET_WIDGET (&self, GTK_WIDGET, "static");
+ dynamic_vbox = GET_WIDGET (&self, GTK_WIDGET, "dynamic");
+ da = GET_WIDGET (&self, GTK_WIDGET, "h264");
+ gtk_widget_realize (da);
+ gdk_win = gtk_widget_get_window (da);
+ h264_xid = GDK_WINDOW_XID (gdk_win);
+ da = GET_WIDGET (&self, GTK_WIDGET, "preview");
+ gtk_widget_realize (da);
+ gdk_win = gtk_widget_get_window (da);
+ preview_xid = GDK_WINDOW_XID (gdk_win);
+
+ set_caps (&self, FALSE);
+
+ g_object_set (self.src, "device", device, NULL);
+ if (gst_element_set_state (self.bin, GST_STATE_READY) ==
+ GST_STATE_CHANGE_FAILURE) {
+ g_debug ("Unable to go to state READY");
+ goto end;
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (properties); i++) {
+ switch (properties[i].type) {
+ case INT:
+ properties[i].src = self.src;
+ properties[i].builder = gtk_builder_new ();
+ gtk_builder_add_from_file (properties[i].builder, INT_PROPERTY_GLADE,
+ NULL);
+ gtk_builder_connect_signals (properties[i].builder, &properties[i]);
+ gtk_box_pack_start (PROPERTY_TO_VBOX,
+ GET_PROP_WIDGET (GTK_WIDGET, "int-property"), TRUE, TRUE, 2);
+ gtk_label_set_label (GET_PROP_WIDGET (GTK_LABEL, "label"),
+ properties[i].property_name);
+ if (properties[i].readonly)
+ gtk_widget_set_sensitive (GET_PROP_WIDGET (GTK_WIDGET, "set"), FALSE);
+ break;
+ case ENUM:
+ properties[i].src = self.src;
+ properties[i].builder = gtk_builder_new ();
+#if !GTK_CHECK_VERSION (2, 24, 0)
+ gtk_builder_add_from_file (properties[i].builder,
+ "enum_property_gtk2.glade", NULL);
+#else
+ gtk_builder_add_from_file (properties[i].builder, ENUM_PROPERTY_GLADE,
+ NULL);
+#endif
+ gtk_builder_connect_signals (properties[i].builder, &properties[i]);
+ gtk_box_pack_start (PROPERTY_TO_VBOX,
+ GET_PROP_WIDGET (GTK_WIDGET, "enum-property"), TRUE, TRUE, 2);
+ gtk_label_set_label (GET_PROP_WIDGET (GTK_LABEL, "label"),
+ properties[i].property_name);
+#if !GTK_CHECK_VERSION (2, 24, 0)
+ {
+ GtkComboBox *combo_box;
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+
+ combo_box = GET_PROP_WIDGET ((GtkComboBox *), "value");
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
+ "text", 0, NULL);
+ }
+#endif
+ if (properties[i].readonly)
+ gtk_widget_set_sensitive (GET_PROP_WIDGET (GTK_WIDGET, "set"), FALSE);
+ break;
+ case BOOL:
+ properties[i].src = self.src;
+ properties[i].builder = gtk_builder_new ();
+ gtk_builder_add_from_file (properties[i].builder, BOOL_PROPERTY_GLADE,
+ NULL);
+ gtk_builder_connect_signals (properties[i].builder, &properties[i]);
+ gtk_box_pack_start (PROPERTY_TO_VBOX,
+ GET_PROP_WIDGET (GTK_WIDGET, "boolean-property"), TRUE, TRUE, 2);
+ gtk_label_set_label (GET_PROP_WIDGET (GTK_LABEL, "label"),
+ properties[i].property_name);
+ if (properties[i].readonly)
+ gtk_widget_set_sensitive (GET_PROP_WIDGET (GTK_WIDGET, "set"), FALSE);
+ break;
+ case NONE:
+ default:
+ break;
+ }
+ }
+ probe_all_properties (FALSE);
+ get_all_properties ();
+
+ gtk_widget_show (window);
+ gtk_main ();
+
+end:
+ g_object_unref (G_OBJECT (self.builder));
+ for (i = 0; i < G_N_ELEMENTS (properties); i++) {
+ if (properties[i].builder)
+ g_object_unref (G_OBJECT (properties[i].builder));
+ }
+ gst_element_set_state (self.bin, GST_STATE_NULL);
+ gst_object_unref (self.src);
+ gst_object_unref (self.identity);
+ gst_object_unref (self.vid_capsfilter);
+ gst_object_unref (self.vf_capsfilter);
+ gst_object_unref (self.bin);
+
+ return 0;
+}
diff --git a/tests/examples/uvch264/window.glade b/tests/examples/uvch264/window.glade
new file mode 100644
index 000000000..8b7624a9f
--- /dev/null
+++ b/tests/examples/uvch264/window.glade
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkWindow" id="window">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Test for uvch264_src</property>
+ <signal name="destroy" handler="on_window_destroyed" swapped="no"/>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkVBox" id="vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHBox" id="box26">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label" translatable="yes">State NULL</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_button_null_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button51">
+ <property name="label" translatable="yes">State READY</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_button_ready_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button52">
+ <property name="label" translatable="yes">State PLAYING</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_button_playing_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button3">
+ <property name="label" translatable="yes">Start capture</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_start_capture_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button4">
+ <property name="label" translatable="yes">Stop capture</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_stop_capture_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button5">
+ <property name="label" translatable="yes">Renegotiate</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_renegotiate_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Static controls</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="static">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Dynamic controls</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="dynamic">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Drop probability % (between 0.0 and 1.0)</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="drop">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="pps_sps">
+ <property name="label" translatable="yes">With SPS/PPS</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label" translatable="yes">Request keyframe</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="on_iframe_button_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">H264</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="h264_caps">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="text" translatable="yes">video/x-h264,width=640,height=480,profile=constrained-baseline,stream-format=bytestream,framerate=15/1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="h264">
+ <property name="width_request">320</property>
+ <property name="height_request">240</property>
+ <property name="visible">True</property>
+ <property name="app_paintable">True</property>
+ <property name="can_focus">False</property>
+ <property name="double_buffered">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Preview</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="preview_caps">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="text" translatable="yes">video/x-raw-yuv,width=320,height=240,format=(fourcc)YUY2,framerate=15/1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="width_request">320</property>
+ <property name="height_request">240</property>
+ <property name="visible">True</property>
+ <property name="app_paintable">True</property>
+ <property name="can_focus">False</property>
+ <property name="double_buffered">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>