mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
Implement something to make video play faster/slower
Original commit message from CVS: Implement something to make video play faster/slower
This commit is contained in:
parent
d04fb4dc6c
commit
1c1767f82e
2 changed files with 95 additions and 16 deletions
|
@ -39,6 +39,7 @@ enum {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ARG_0,
|
ARG_0,
|
||||||
|
ARG_SPEED
|
||||||
/* FILL ME */
|
/* 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_init (GstVideodrop *videodrop);
|
||||||
static void gst_videodrop_chain (GstPad *pad, GstData *_data);
|
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 GstElementClass *parent_class = NULL;
|
||||||
/*static guint gst_videodrop_signals[LAST_SIGNAL] = { 0 }; */
|
/*static guint gst_videodrop_signals[LAST_SIGNAL] = { 0 }; */
|
||||||
|
|
||||||
|
@ -131,7 +144,20 @@ gst_videodrop_base_init (gpointer g_class)
|
||||||
static void
|
static void
|
||||||
gst_videodrop_class_init (GstVideodropClass *klass)
|
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);
|
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) \
|
#define gst_caps_get_float_range(caps, name, min, max) \
|
||||||
|
@ -206,38 +232,90 @@ gst_videodrop_init (GstVideodrop *videodrop)
|
||||||
|
|
||||||
videodrop->inited = FALSE;
|
videodrop->inited = FALSE;
|
||||||
videodrop->total = videodrop->pass = 0;
|
videodrop->total = videodrop->pass = 0;
|
||||||
|
videodrop->speed = 1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_videodrop_chain (GstPad *pad, GstData *_data)
|
gst_videodrop_chain (GstPad *pad, GstData *data)
|
||||||
{
|
{
|
||||||
GstBuffer *buf = GST_BUFFER (_data);
|
GstVideodrop *videodrop = GST_VIDEODROP (gst_pad_get_parent (pad));
|
||||||
GstVideodrop *videodrop;
|
GstBuffer *buf;
|
||||||
|
|
||||||
GST_DEBUG ("gst_videodrop_chain");
|
if (GST_IS_EVENT (data)) {
|
||||||
|
gst_pad_event_default (videodrop->srcpad, GST_EVENT (data));
|
||||||
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));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = GST_BUFFER (data);
|
||||||
|
|
||||||
videodrop->total++;
|
videodrop->total++;
|
||||||
while (videodrop->to_fps / videodrop->from_fps >
|
while (videodrop->to_fps / (videodrop->from_fps * videodrop->speed) >
|
||||||
(gfloat) videodrop->pass / videodrop->total) {
|
(gfloat) videodrop->pass / videodrop->total) {
|
||||||
videodrop->pass++;
|
videodrop->pass++;
|
||||||
gst_buffer_ref (buf);
|
gst_buffer_ref (buf);
|
||||||
|
GST_BUFFER_TIMESTAMP (buf) /= videodrop->speed;
|
||||||
gst_pad_push (videodrop->srcpad, GST_DATA (buf));
|
gst_pad_push (videodrop->srcpad, GST_DATA (buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unref (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
|
static gboolean
|
||||||
plugin_init (GstPlugin *plugin)
|
plugin_init (GstPlugin *plugin)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,8 +45,9 @@ struct _GstVideodrop {
|
||||||
|
|
||||||
/* video state */
|
/* video state */
|
||||||
gboolean inited;
|
gboolean inited;
|
||||||
float from_fps,
|
gfloat from_fps,
|
||||||
to_fps;
|
to_fps;
|
||||||
|
gfloat speed;
|
||||||
guint64 pass, total;
|
guint64 pass, total;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue