static void fps_display_sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (object); switch (prop_id) { case PROP_SYNC: self->sync = g_value_get_boolean (value); fps_display_sink_update_sink_sync (self); break; case PROP_TEXT_OVERLAY: self->use_text_overlay = g_value_get_boolean (value); if (self->text_overlay) { if (!self->use_text_overlay) { GST_DEBUG_OBJECT (self, "text-overlay set to false"); g_object_set (self->text_overlay, "text", "", "silent", TRUE, NULL); } else { GST_DEBUG_OBJECT (self, "text-overlay set to true"); g_object_set (self->text_overlay, "silent", FALSE, NULL); } } break; case PROP_VIDEO_SINK: /* FIXME should we add a state-lock or a lock around here? * need to check if it is possible that a state change NULL->READY can * happen while this code is executing on a different thread */ if (GST_STATE (self) != GST_STATE_NULL) { g_warning ("Can't set video-sink property of fpsdisplaysink if not on " "NULL state"); break; } update_video_sink (self, (GstElement *) g_value_get_object (value)); break; case PROP_FPS_UPDATE_INTERVAL: self->fps_update_interval = GST_MSECOND * (GstClockTime) g_value_get_int (value); break; case PROP_SIGNAL_FPS_MEASUREMENTS: self->signal_measurements = g_value_get_boolean (value); break; case PROP_SILENT: self->silent = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstStateChangeReturn fps_display_sink_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (self->video_sink == NULL) { GstElement *video_sink; GST_DEBUG_OBJECT (self, "No video sink set, creating autovideosink"); video_sink = gst_element_factory_make ("autovideosink", "fps-display-video_sink"); update_video_sink (self, video_sink); } if (self->video_sink != NULL) { fps_display_sink_start (self); } else { GST_ELEMENT_ERROR (self, LIBRARY, INIT, ("No video sink set and autovideosink is not available"), (NULL)); ret = GST_STATE_CHANGE_FAILURE; } break; case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_PLAYING: /* reinforce our sync to children, as they might have changed * internally */ fps_display_sink_update_sink_sync (self); break; default: break; } ret = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state, (element, transition), GST_STATE_CHANGE_SUCCESS); switch (transition) { case GST_STATE_CHANGE_READY_TO_NULL: fps_display_sink_stop (self); break; default: break; } return ret; }
static void update_video_sink (GstFPSDisplaySink * self, GstElement * video_sink) { GstPad *sink_pad; if (self->video_sink) { /* remove pad probe */ sink_pad = gst_element_get_static_pad (self->video_sink, "sink"); gst_pad_remove_probe (sink_pad, self->data_probe_id); gst_object_unref (sink_pad); self->data_probe_id = -1; /* remove ghost pad target */ gst_ghost_pad_set_target (GST_GHOST_PAD (self->ghost_pad), NULL); /* remove old sink */ gst_bin_remove (GST_BIN (self), self->video_sink); gst_object_unref (self->video_sink); } /* create child elements */ self->video_sink = video_sink; if (self->video_sink == NULL) return; fps_display_sink_update_sink_sync (self); /* take a ref before bin takes the ownership */ gst_object_ref (self->video_sink); gst_bin_add (GST_BIN (self), self->video_sink); /* attach or pad probe */ sink_pad = gst_element_get_static_pad (self->video_sink, "sink"); self->data_probe_id = gst_pad_add_probe (sink_pad, GST_PAD_PROBE_TYPE_DATA_BOTH, on_video_sink_data_flow, (gpointer) self, NULL); gst_object_unref (sink_pad); }