diff options
-rw-r--r-- | gst/videodrop/gstvideodrop.c | 106 | ||||
-rw-r--r-- | gst/videodrop/gstvideodrop.h | 5 |
2 files changed, 95 insertions, 16 deletions
diff --git a/gst/videodrop/gstvideodrop.c b/gst/videodrop/gstvideodrop.c index eedf56be..e3df20a2 100644 --- a/gst/videodrop/gstvideodrop.c +++ b/gst/videodrop/gstvideodrop.c @@ -39,6 +39,7 @@ enum { enum { ARG_0, + ARG_SPEED /* FILL ME */ }; @@ -87,6 +88,18 @@ static void gst_videodrop_class_init (GstVideodropClass *klass); static void gst_videodrop_init (GstVideodrop *videodrop); static void gst_videodrop_chain (GstPad *pad, GstData *_data); +static void gst_videodrop_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gst_videodrop_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static GstElementStateReturn + gst_videodrop_change_state (GstElement *element); + static GstElementClass *parent_class = NULL; /*static guint gst_videodrop_signals[LAST_SIGNAL] = { 0 }; */ @@ -131,7 +144,20 @@ gst_videodrop_base_init (gpointer g_class) static void gst_videodrop_class_init (GstVideodropClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + parent_class = g_type_class_peek_parent (klass); + + g_object_class_install_property (object_class, ARG_SPEED, + g_param_spec_float ("speed", "Speed", + "Output speed (relative to input)", + 0.01, 100, 1, G_PARAM_READWRITE)); + + object_class->set_property = gst_videodrop_set_property; + object_class->get_property = gst_videodrop_get_property; + + element_class->change_state = gst_videodrop_change_state; } #define gst_caps_get_float_range(caps, name, min, max) \ @@ -206,38 +232,90 @@ gst_videodrop_init (GstVideodrop *videodrop) videodrop->inited = FALSE; videodrop->total = videodrop->pass = 0; + videodrop->speed = 1.; } static void -gst_videodrop_chain (GstPad *pad, GstData *_data) +gst_videodrop_chain (GstPad *pad, GstData *data) { - GstBuffer *buf = GST_BUFFER (_data); - GstVideodrop *videodrop; - - GST_DEBUG ("gst_videodrop_chain"); + GstVideodrop *videodrop = GST_VIDEODROP (gst_pad_get_parent (pad)); + GstBuffer *buf; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - videodrop = GST_VIDEODROP (gst_pad_get_parent (pad)); - - if (GST_IS_EVENT (buf)) { - gst_pad_push (videodrop->srcpad, GST_DATA (buf)); + if (GST_IS_EVENT (data)) { + gst_pad_event_default (videodrop->srcpad, GST_EVENT (data)); return; } + buf = GST_BUFFER (data); + videodrop->total++; - while (videodrop->to_fps / videodrop->from_fps > + while (videodrop->to_fps / (videodrop->from_fps * videodrop->speed) > (gfloat) videodrop->pass / videodrop->total) { videodrop->pass++; gst_buffer_ref (buf); + GST_BUFFER_TIMESTAMP (buf) /= videodrop->speed; gst_pad_push (videodrop->srcpad, GST_DATA (buf)); } gst_buffer_unref (buf); } +static void +gst_videodrop_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GstVideodrop *videodrop = GST_VIDEODROP (object); + + switch (prop_id) { + case ARG_SPEED: + videodrop->speed = g_value_get_float (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_videodrop_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GstVideodrop *videodrop = GST_VIDEODROP (object); + + switch (prop_id) { + case ARG_SPEED: + g_value_set_float (value, videodrop->speed); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstElementStateReturn +gst_videodrop_change_state (GstElement *element) +{ + GstVideodrop *videodrop = GST_VIDEODROP (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_READY: + videodrop->inited = FALSE; + videodrop->total = videodrop->pass = 0; + break; + default: + break; + } + + if (parent_class->change_state) + return parent_class->change_state (element); + + return GST_STATE_SUCCESS; +} + static gboolean plugin_init (GstPlugin *plugin) { diff --git a/gst/videodrop/gstvideodrop.h b/gst/videodrop/gstvideodrop.h index f5209842..429be2c4 100644 --- a/gst/videodrop/gstvideodrop.h +++ b/gst/videodrop/gstvideodrop.h @@ -45,8 +45,9 @@ struct _GstVideodrop { /* video state */ gboolean inited; - float from_fps, - to_fps; + gfloat from_fps, + to_fps; + gfloat speed; guint64 pass, total; }; |