mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 13:06:23 +00:00
glvideomixer: Add GstControlBinding proxy
This is used to proxy GstControlBinding to the pad on the parent object. This avoid having to sync the values in the proxy pad, this is too early if you have a queue between the pad and the actual aggregation operation. https://bugzilla.gnome.org/show_bug.cgi?id=734060
This commit is contained in:
parent
86fb628d09
commit
6edf8dbaa6
1 changed files with 158 additions and 54 deletions
|
@ -71,6 +71,151 @@ gst_gl_video_mixer_background_get_type (void)
|
|||
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
|
||||
|
@ -94,11 +239,6 @@ static void gst_gl_video_mixer_input_get_property (GObject * object,
|
|||
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;
|
||||
|
||||
|
@ -118,9 +258,6 @@ G_DEFINE_TYPE (GstGLVideoMixerInput, gst_gl_video_mixer_input,
|
|||
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
|
||||
|
@ -177,51 +314,6 @@ gst_gl_video_mixer_input_set_property (GObject * object, guint prop_id,
|
|||
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)
|
||||
{
|
||||
|
@ -229,13 +321,25 @@ _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;
|
||||
}
|
||||
#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)
|
||||
|
||||
gst_pad_set_chain_function (GST_PAD (input), gst_gl_video_mixer_input_chain);
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue