mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
fpsdisplaysink: expose video sink using a property
Exposes the internally used sink as video-sink property and makes the default one to be autovideosink instead of the hardcoded xvimagesink Fixes #604280
This commit is contained in:
parent
4aded03c5e
commit
4111d6321f
2 changed files with 74 additions and 14 deletions
|
@ -75,6 +75,7 @@ enum
|
||||||
ARG_0,
|
ARG_0,
|
||||||
ARG_SYNC,
|
ARG_SYNC,
|
||||||
ARG_TEXT_OVERLAY,
|
ARG_TEXT_OVERLAY,
|
||||||
|
ARG_VIDEO_SINK,
|
||||||
/* FILL ME */
|
/* FILL ME */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,6 +112,11 @@ fps_display_sink_class_init (GstFPSDisplaySinkClass * klass)
|
||||||
"Wether to use text-overlay", TRUE,
|
"Wether to use text-overlay", TRUE,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
|
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_klass, ARG_VIDEO_SINK,
|
||||||
|
g_param_spec_object ("video-sink",
|
||||||
|
"video-sink",
|
||||||
|
"Video sink to use", GST_TYPE_ELEMENT, G_PARAM_READWRITE));
|
||||||
|
|
||||||
gstelement_klass->change_state = fps_display_sink_change_state;
|
gstelement_klass->change_state = fps_display_sink_change_state;
|
||||||
|
|
||||||
gst_element_class_add_pad_template (gstelement_klass,
|
gst_element_class_add_pad_template (gstelement_klass,
|
||||||
|
@ -164,23 +170,43 @@ on_video_sink_data_flow (GstPad * pad, GstMiniObject * mini_obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fps_display_sink_init (GstFPSDisplaySink * self,
|
update_sub_sink (GstElement * sink, gpointer data)
|
||||||
GstFPSDisplaySinkClass * g_class)
|
{
|
||||||
|
g_object_set (sink, "sync", *((gboolean *) data), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_video_sink (GstFPSDisplaySink * self, GstElement * video_sink)
|
||||||
{
|
{
|
||||||
GstPad *sink_pad;
|
GstPad *sink_pad;
|
||||||
|
GstIterator *iterator;
|
||||||
|
|
||||||
self->sync = FALSE;
|
if (self->video_sink) {
|
||||||
self->use_text_overlay = TRUE;
|
|
||||||
|
|
||||||
/* create child elements */
|
/* remove pad probe */
|
||||||
self->video_sink =
|
sink_pad = gst_element_get_static_pad (self->video_sink, "sink");
|
||||||
gst_element_factory_make ("xvimagesink", "fps-display-video_sink");
|
gst_pad_remove_data_probe (sink_pad, self->data_probe_id);
|
||||||
if (!self->video_sink) {
|
gst_object_unref (sink_pad);
|
||||||
GST_ERROR_OBJECT (self, "element could not be created");
|
self->data_probe_id = -1;
|
||||||
return;
|
|
||||||
|
/* remove ghost pad */
|
||||||
|
gst_element_remove_pad (GST_ELEMENT (self), self->ghost_pad);
|
||||||
|
|
||||||
|
/* remove old sink */
|
||||||
|
gst_bin_remove (GST_BIN (self), self->video_sink);
|
||||||
|
gst_object_unref (self->video_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_set (self->video_sink, "sync", self->sync, NULL);
|
/* create child elements */
|
||||||
|
self->video_sink = video_sink;
|
||||||
|
|
||||||
|
if (G_OBJECT_TYPE (self->video_sink) == GST_TYPE_BIN) {
|
||||||
|
iterator = gst_bin_iterate_sinks (GST_BIN (self->video_sink));
|
||||||
|
gst_iterator_foreach (iterator, (GFunc) update_sub_sink,
|
||||||
|
(void *) &self->sync);
|
||||||
|
gst_iterator_free (iterator);
|
||||||
|
} else
|
||||||
|
g_object_set (self->video_sink, "sync", self->sync, NULL);
|
||||||
|
|
||||||
/* take a ref before bin takes the ownership */
|
/* take a ref before bin takes the ownership */
|
||||||
gst_object_ref (self->video_sink);
|
gst_object_ref (self->video_sink);
|
||||||
|
@ -193,10 +219,30 @@ fps_display_sink_init (GstFPSDisplaySink * self,
|
||||||
|
|
||||||
/* attach or pad probe */
|
/* attach or pad probe */
|
||||||
sink_pad = gst_element_get_static_pad (self->video_sink, "sink");
|
sink_pad = gst_element_get_static_pad (self->video_sink, "sink");
|
||||||
gst_pad_add_data_probe (sink_pad, G_CALLBACK (on_video_sink_data_flow),
|
self->data_probe_id = gst_pad_add_data_probe (sink_pad,
|
||||||
(gpointer) self);
|
G_CALLBACK (on_video_sink_data_flow), (gpointer) self);
|
||||||
gst_object_unref (sink_pad);
|
gst_object_unref (sink_pad);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fps_display_sink_init (GstFPSDisplaySink * self,
|
||||||
|
GstFPSDisplaySinkClass * g_class)
|
||||||
|
{
|
||||||
|
GstElement *video_sink;
|
||||||
|
|
||||||
|
self->sync = FALSE;
|
||||||
|
self->use_text_overlay = TRUE;
|
||||||
|
|
||||||
|
video_sink = gst_element_factory_make ("autovideosink",
|
||||||
|
"fps-display-video_sink");
|
||||||
|
if (!video_sink) {
|
||||||
|
GST_ERROR_OBJECT (self, "element could not be created");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_video_sink (self, video_sink);
|
||||||
|
|
||||||
self->query = gst_query_new_position (GST_FORMAT_TIME);
|
self->query = gst_query_new_position (GST_FORMAT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,11 +387,18 @@ fps_display_sink_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (object);
|
GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (object);
|
||||||
|
GstIterator *iterator;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_SYNC:
|
case ARG_SYNC:
|
||||||
self->sync = g_value_get_boolean (value);
|
self->sync = g_value_get_boolean (value);
|
||||||
g_object_set (self->video_sink, "sync", self->sync, NULL);
|
if (G_OBJECT_TYPE (self->video_sink) == GST_TYPE_BIN) {
|
||||||
|
iterator = gst_bin_iterate_sinks (GST_BIN (self->video_sink));
|
||||||
|
gst_iterator_foreach (iterator, (GFunc) update_sub_sink,
|
||||||
|
(void *) &self->sync);
|
||||||
|
gst_iterator_free (iterator);
|
||||||
|
} else
|
||||||
|
g_object_set (self->video_sink, "sync", self->sync, NULL);
|
||||||
break;
|
break;
|
||||||
case ARG_TEXT_OVERLAY:
|
case ARG_TEXT_OVERLAY:
|
||||||
self->use_text_overlay = g_value_get_boolean (value);
|
self->use_text_overlay = g_value_get_boolean (value);
|
||||||
|
@ -360,6 +413,9 @@ fps_display_sink_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ARG_VIDEO_SINK:
|
||||||
|
update_video_sink (self, (GstElement *) g_value_get_object (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -379,6 +435,9 @@ fps_display_sink_get_property (GObject * object, guint prop_id,
|
||||||
case ARG_TEXT_OVERLAY:
|
case ARG_TEXT_OVERLAY:
|
||||||
g_value_set_boolean (value, self->use_text_overlay);
|
g_value_set_boolean (value, self->use_text_overlay);
|
||||||
break;
|
break;
|
||||||
|
case ARG_VIDEO_SINK:
|
||||||
|
g_value_set_object (value, self->video_sink);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct _GstFPSDisplaySink
|
||||||
GstClockTime next_ts;
|
GstClockTime next_ts;
|
||||||
|
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
|
guint data_probe_id;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
gboolean sync;
|
gboolean sync;
|
||||||
|
|
Loading…
Reference in a new issue