return mixer_background_type;
}
+typedef struct _GstGLMixerControlBindingProxy GstGLMixerControlBindingProxy;
+typedef struct _GstGLMixerControlBindingProxyClass
+ GstGLMixerControlBindingProxyClass;
+
+struct _GstGLMixerControlBindingProxy
+{
+ GstControlBinding parent;
+
+ GstObject *ref_object;
+ const gchar *property_name;
+};
+
+struct _GstGLMixerControlBindingProxyClass
+{
+ GstControlBindingClass parent_class;
+};
+
+GType gst_gl_mixer_control_binding_proxy_get_type (void);
+#define GST_TYPE_GL_MIXER_CONTROL_BINDING \
+ (gst_gl_mixer_control_binding_proxy_get_type())
+
+G_DEFINE_TYPE (GstGLMixerControlBindingProxy,
+ gst_gl_mixer_control_binding_proxy, GST_TYPE_CONTROL_BINDING);
+
+static void
+gst_gl_mixer_control_binding_proxy_init (GstGLMixerControlBindingProxy * self)
+{
+}
+
+static gboolean
+gst_gl_mixer_control_binding_proxy_sync_values (GstControlBinding * binding,
+ GstObject * object, GstClockTime timestamp, GstClockTime last_sync)
+{
+ GstGLMixerControlBindingProxy *self = (GstGLMixerControlBindingProxy *)
+ binding;
+ GstControlBinding *ref_binding;
+ gboolean ret = TRUE;
+
+ ref_binding = gst_object_get_control_binding (self->ref_object,
+ self->property_name);
+
+ if (ref_binding) {
+ ret = gst_control_binding_sync_values (ref_binding, self->ref_object,
+ timestamp, last_sync);
+ gst_object_unref (ref_binding);
+ }
+
+ return ret;
+}
+
+static GValue *
+gst_gl_mixer_control_binding_proxy_get_value (GstControlBinding * binding,
+ GstClockTime timestamp)
+{
+ GstGLMixerControlBindingProxy *self = (GstGLMixerControlBindingProxy *)
+ binding;
+ GstControlBinding *ref_binding;
+ GValue *ret = NULL;
+
+ ref_binding = gst_object_get_control_binding (self->ref_object,
+ self->property_name);
+
+ if (ref_binding) {
+ ret = gst_control_binding_get_value (ref_binding, timestamp);
+ gst_object_unref (ref_binding);
+ }
+
+ return ret;
+}
+
+static gboolean
+gst_gl_mixer_control_binding_proxy_get_value_array (GstControlBinding * binding,
+ GstClockTime timestamp, GstClockTime interval, guint n_values,
+ gpointer values)
+{
+ GstGLMixerControlBindingProxy *self = (GstGLMixerControlBindingProxy *)
+ binding;
+ GstControlBinding *ref_binding;
+ gboolean ret = FALSE;
+
+ ref_binding = gst_object_get_control_binding (self->ref_object,
+ self->property_name);
+
+ if (ref_binding) {
+ ret = gst_control_binding_get_value_array (ref_binding, timestamp,
+ interval, n_values, values);
+ gst_object_unref (ref_binding);
+ }
+
+ return ret;
+}
+
+static gboolean
+gst_gl_mixer_control_binding_proxy_get_g_value_array (GstControlBinding *
+ binding, GstClockTime timestamp, GstClockTime interval, guint n_values,
+ GValue * values)
+{
+ GstGLMixerControlBindingProxy *self = (GstGLMixerControlBindingProxy *)
+ binding;
+ GstControlBinding *ref_binding;
+ gboolean ret = FALSE;
+
+ ref_binding = gst_object_get_control_binding (self->ref_object,
+ self->property_name);
+
+ if (ref_binding) {
+ ret = gst_control_binding_get_g_value_array (ref_binding, timestamp,
+ interval, n_values, values);
+ gst_object_unref (ref_binding);
+ }
+
+ return ret;
+}
+
+
+static void
+ gst_gl_mixer_control_binding_proxy_class_init
+ (GstGLMixerControlBindingProxyClass * klass)
+{
+ GstControlBindingClass *cb_class = GST_CONTROL_BINDING_CLASS (klass);
+
+ cb_class->sync_values = gst_gl_mixer_control_binding_proxy_sync_values;
+ cb_class->get_value = gst_gl_mixer_control_binding_proxy_get_value;
+ cb_class->get_value_array =
+ gst_gl_mixer_control_binding_proxy_get_value_array;
+ cb_class->get_g_value_array =
+ gst_gl_mixer_control_binding_proxy_get_g_value_array;
+}
+
+static GstControlBinding *
+gst_gl_mixer_control_binding_proxy_new (GstObject * object,
+ const gchar * property_name, GstObject * ref_object,
+ const gchar * ref_property_name)
+{
+ GstGLMixerControlBindingProxy *self =
+ g_object_new (GST_TYPE_GL_MIXER_CONTROL_BINDING, "object", object,
+ "name", property_name, NULL);
+
+ self->ref_object = ref_object;
+ self->property_name = ref_property_name;
+
+ return (GstControlBinding *) self;
+}
+
+
#define DEFAULT_PAD_XPOS 0
#define DEFAULT_PAD_YPOS 0
#define DEFAULT_PAD_WIDTH 0
static void gst_gl_video_mixer_input_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
-static GstFlowReturn gst_gl_video_mixer_input_chain (GstPad * pad,
- GstObject * parent, GstBuffer * buffer);
-static GstFlowReturn gst_gl_video_mixer_input_event (GstPad * pad,
- GstObject * parent, GstEvent * event);
-
typedef struct _GstGLVideoMixerInput GstGLVideoMixerInput;
typedef GstGhostPadClass GstGLVideoMixerInputClass;
static void
gst_gl_video_mixer_input_init (GstGLVideoMixerInput * self)
{
- GstPad *pad = GST_PAD (self);
-
- gst_pad_set_event_function (pad, gst_gl_video_mixer_input_event);
}
static void
g_object_set_property (G_OBJECT (self->mixer_pad), pspec->name, value);
}
-static GstFlowReturn
-gst_gl_video_mixer_input_chain (GstPad * pad, GstObject * parent,
- GstBuffer * buffer)
-{
- GstGLVideoMixerInput *self = (GstGLVideoMixerInput *) pad;
- GstClockTime timestamp, stream_time;
-// gdouble alpha;
-
- timestamp = GST_BUFFER_TIMESTAMP (buffer);
-
- stream_time =
- gst_segment_to_stream_time (&self->segment, GST_FORMAT_TIME, timestamp);
-
- gst_object_sync_values (GST_OBJECT (self), stream_time);
-#if 0
- /* FIXME: implement no-upload on alpha = 0 */
- g_object_get (self, "alpha", &alpha, NULL);
-
- if (alpha <= 0.0) {
- GST_DEBUG_OBJECT (self, "dropping buffer %" GST_PTR_FORMAT
- " due to alpha value %f", buffer, alpha);
- gst_buffer_unref (buffer);
- return GST_FLOW_OK;
- }
-#endif
- return gst_proxy_pad_chain_default (pad, parent, buffer);
-}
-
-static GstFlowReturn
-gst_gl_video_mixer_input_event (GstPad * pad, GstObject * parent,
- GstEvent * event)
-{
- GstGLVideoMixerInput *self = (GstGLVideoMixerInput *) pad;
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEGMENT:
- gst_event_copy_segment (event, &self->segment);
- break;
- default:
- break;
- }
-
- return gst_pad_event_default (pad, parent, event);
-}
-
static GstGhostPad *
_create_video_mixer_input (GstGLMixerBin * self, GstPad * mixer_pad)
{
g_object_new (gst_gl_video_mixer_input_get_type (), "name",
GST_OBJECT_NAME (mixer_pad), "direction", GST_PAD_DIRECTION (mixer_pad),
NULL);
+ GstControlBinding *cb;
if (!gst_ghost_pad_construct (GST_GHOST_PAD (input))) {
gst_object_unref (input);
return NULL;
}
-
- gst_pad_set_chain_function (GST_PAD (input), gst_gl_video_mixer_input_chain);
+#define ADD_PROXY_CONTROL_BINDING(prop) \
+ cb = gst_gl_mixer_control_binding_proxy_new (GST_OBJECT (input), \
+ G_STRINGIFY (prop), GST_OBJECT (mixer_pad), G_STRINGIFY (prop)); \
+ gst_object_add_control_binding (GST_OBJECT (input), cb)
+
+ ADD_PROXY_CONTROL_BINDING (zorder);
+ ADD_PROXY_CONTROL_BINDING (xpos);
+ ADD_PROXY_CONTROL_BINDING (ypos);
+ ADD_PROXY_CONTROL_BINDING (width);
+ ADD_PROXY_CONTROL_BINDING (height);
+ ADD_PROXY_CONTROL_BINDING (alpha);
+
+#undef ADD_PROXY_CONTROL_BINDING
input->mixer_pad = mixer_pad;