mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
and make it handle more than one channel.
Original commit message from CVS: Fix speed element and make it chain-based (fixes #156467), and make it handle more than one channel.
This commit is contained in:
parent
d7af68b7c8
commit
909da9fb04
6 changed files with 228 additions and 156 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2005-02-10 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst/speed/Makefile.am:
|
||||
* gst/speed/demo-mp3.c: (main):
|
||||
* gst/speed/filter.func:
|
||||
* gst/speed/gstspeed.c: (speed_link), (speed_parse_caps),
|
||||
(speed_class_init), (speed_init), (speed_chain_int16),
|
||||
(speed_chain_float32), (speed_chain), (speed_set_property),
|
||||
(speed_get_property), (speed_change_state):
|
||||
* gst/speed/gstspeed.h:
|
||||
Fix speed element and make it chain-based (fixes #156467),
|
||||
and make it handle more than one channel.
|
||||
|
||||
2005-02-10 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
|
||||
* ext/dts/gstdtsdec.c: (gst_dtsdec_init), (gst_dtsdec_channels),
|
||||
|
|
|
@ -6,7 +6,7 @@ libgstspeed_la_CFLAGS = $(GST_CFLAGS)
|
|||
libgstspeed_la_LIBADD =
|
||||
libgstspeed_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
noinst_HEADERS = gstspeed.h filter.func
|
||||
noinst_HEADERS = gstspeed.h
|
||||
|
||||
if HAVE_GTK
|
||||
noinst_PROGRAMS = demo-mp3
|
||||
|
|
|
@ -37,7 +37,7 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window, *vbox, *hscale, *button;
|
||||
GstElement *filesrc, *mad, *stereo2mono, *speed, *audiosink, *pipeline;
|
||||
GstElement *filesrc, *mad, *audioconvert, *speed, *audiosink, *pipeline;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
gtk_init (&argc, &argv);
|
||||
|
@ -65,18 +65,17 @@ main (int argc, char **argv)
|
|||
|
||||
filesrc = gst_element_factory_make ("filesrc", "filesrc");
|
||||
mad = gst_element_factory_make ("mad", "mad");
|
||||
stereo2mono = gst_element_factory_make ("stereo2mono", "stereo2mono");
|
||||
audioconvert = gst_element_factory_make ("audioconvert", "audioconvert0");
|
||||
speed = gst_element_factory_make ("speed", "speed");
|
||||
audiosink = gst_element_factory_make (DEFAULT_AUDIOSINK, "audiosink");
|
||||
g_object_set (audiosink, "fragment", 0x00180008, NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (gtk_range_get_adjustment (GTK_RANGE
|
||||
(hscale))), "value_changed", G_CALLBACK (set_speed), speed);
|
||||
|
||||
pipeline = gst_pipeline_new ("app");
|
||||
gst_bin_add_many (GST_BIN (pipeline), filesrc, mad, stereo2mono, speed,
|
||||
gst_bin_add_many (GST_BIN (pipeline), filesrc, mad, audioconvert, speed,
|
||||
audiosink, NULL);
|
||||
gst_element_link_many (filesrc, mad, stereo2mono, speed, audiosink, NULL);
|
||||
gst_element_link_many (filesrc, mad, audioconvert, speed, audiosink, NULL);
|
||||
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- Mode: c; c-basic-offset: 2 -*- */
|
||||
_FORMAT *in_data, *out_data;
|
||||
static gint64 offset = 0, timestamp = 0;
|
||||
|
||||
/* get a buffer here so that we can have something to interpolate
|
||||
* against for the first few samples if speed < 0.5 */
|
||||
in_data = (_FORMAT*) GST_BUFFER_DATA(in);
|
||||
nin = GST_BUFFER_SIZE(in)/sizeof(_FORMAT);
|
||||
lower = in_data[0];
|
||||
i_float = 0.5 * (speed - 1.0);
|
||||
i = i_float + 1.0; /* ciel(i_float) for ints */
|
||||
|
||||
do {
|
||||
speed = filter->speed; /* update this, it might have changed */
|
||||
|
||||
out = gst_buffer_new();
|
||||
GST_BUFFER_DATA(out) = (gchar*) g_new(_FORMAT,SPEED_BUFSIZE/sizeof(_FORMAT));
|
||||
GST_BUFFER_SIZE(out) = SPEED_BUFSIZE;
|
||||
out_data = (_FORMAT*) GST_BUFFER_DATA(out);
|
||||
nout = GST_BUFFER_SIZE(out) / sizeof(_FORMAT);
|
||||
GST_BUFFER_TIMESTAMP (out) = timestamp;
|
||||
offset += nout;
|
||||
timestamp = offset * GST_SECOND / filter->rate;
|
||||
|
||||
for (j=0; j<nout; j++) {
|
||||
/* index of upper bounds of interpolation for
|
||||
* new sample, got it by trial&error on the chalkboard */
|
||||
i_float += speed;
|
||||
i = i_float + 1.0; /* ciel(i_float) for ints */
|
||||
|
||||
while (i >= nin) {
|
||||
i = i % nin;
|
||||
i_float = i_float - nin;
|
||||
lower = in_data[nin-1];
|
||||
gst_buffer_unref(in);
|
||||
in = GST_BUFFER (gst_pad_pull (filter->sinkpad));
|
||||
|
||||
while (GST_IS_EVENT (in)) {
|
||||
gst_pad_event_default (filter->srcpad, GST_EVENT (in));
|
||||
in = GST_BUFFER (gst_pad_pull (filter->sinkpad));
|
||||
}
|
||||
|
||||
in_data = (_FORMAT*) GST_BUFFER_DATA(in);
|
||||
nin = GST_BUFFER_SIZE(in) / sizeof(_FORMAT);
|
||||
}
|
||||
|
||||
if (i>0)
|
||||
lower = in_data[i-1];
|
||||
|
||||
interp = i_float - floor(i_float);
|
||||
|
||||
out_data[j] = lower*(1-interp) + in_data[i]*interp;
|
||||
|
||||
lower = in_data[i];
|
||||
}
|
||||
|
||||
gst_pad_push(filter->srcpad, GST_DATA (out));
|
||||
|
||||
gst_element_yield (element);
|
||||
} while (TRUE);
|
|
@ -29,46 +29,49 @@
|
|||
|
||||
#include "gstspeed.h"
|
||||
|
||||
/* buffer size to make if no bufferpool is available, must be divisible by
|
||||
* sizeof(gfloat) */
|
||||
#define SPEED_BUFSIZE 4096
|
||||
/* number of buffers to allocate per chunk in sink buffer pool */
|
||||
#define SPEED_NUMBUF 6
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails speed_details = GST_ELEMENT_DETAILS ("Speed",
|
||||
"Filter/Effect/Audio",
|
||||
"Set speed/pitch on audio/raw streams (resampler)",
|
||||
"Andy Wingo <apwingo@eos.ncsu.edu>");
|
||||
"Andy Wingo <apwingo@eos.ncsu.edu>, "
|
||||
"Tim-Philipp Müller <tim@centricular.net>");
|
||||
|
||||
|
||||
/* Filter signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_SPEED
|
||||
};
|
||||
|
||||
/* assumption here: sizeof (gfloat) = 4 */
|
||||
#define GST_SPEED_AUDIO_CAPS \
|
||||
"audio/x-raw-float, " \
|
||||
"rate = (int) [ 1, MAX ], " \
|
||||
"channels = (int) [ 1, MAX ], " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"width = (int) 32, " \
|
||||
"buffer-frames = (int) 0; " \
|
||||
\
|
||||
"audio/x-raw-int, " \
|
||||
"rate = (int) [ 1, MAX ], " \
|
||||
"channels = (int) [ 1, MAX ], " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"width = (int) 16, " \
|
||||
"depth = (int) 16, " \
|
||||
"signed = (boolean) true"
|
||||
|
||||
static GstStaticPadTemplate gst_speed_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
|
||||
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS)
|
||||
GST_STATIC_CAPS (GST_SPEED_AUDIO_CAPS)
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_speed_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
|
||||
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS)
|
||||
GST_STATIC_CAPS (GST_SPEED_AUDIO_CAPS)
|
||||
);
|
||||
|
||||
static void speed_base_init (gpointer g_class);
|
||||
|
@ -82,11 +85,11 @@ static void speed_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
|
||||
static gboolean speed_parse_caps (GstSpeed * filter, const GstCaps * caps);
|
||||
|
||||
static void speed_loop (GstElement * element);
|
||||
static void speed_chain (GstPad * pad, GstData * data);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static GstElementStateReturn speed_change_state (GstElement * element);
|
||||
|
||||
/*static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; */
|
||||
static GstElementClass *parent_class; /* NULL */
|
||||
|
||||
static GstPadLinkReturn
|
||||
speed_link (GstPad * pad, const GstCaps * caps)
|
||||
|
@ -97,7 +100,7 @@ speed_link (GstPad * pad, const GstCaps * caps)
|
|||
filter = GST_SPEED (gst_pad_get_parent (pad));
|
||||
g_return_val_if_fail (filter != NULL, GST_PAD_LINK_REFUSED);
|
||||
g_return_val_if_fail (GST_IS_SPEED (filter), GST_PAD_LINK_REFUSED);
|
||||
otherpad = (pad == filter->srcpad ? filter->sinkpad : filter->srcpad);
|
||||
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
|
||||
|
||||
if (!speed_parse_caps (filter, caps))
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
|
@ -117,29 +120,31 @@ speed_parse_caps (GstSpeed * filter, const GstCaps * caps)
|
|||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
mimetype = gst_structure_get_name (structure);
|
||||
if (strcmp (mimetype, "audio/x-raw-float") == 0)
|
||||
filter->format = GST_SPEED_FORMAT_FLOAT;
|
||||
else if (strcmp (mimetype, "audio/x-raw-int") == 0)
|
||||
filter->format = GST_SPEED_FORMAT_INT;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
ret = gst_structure_get_int (structure, "rate", &filter->rate);
|
||||
ret &= gst_structure_get_int (structure, "channels", &filter->channels);
|
||||
ret &= gst_structure_get_int (structure, "width", &filter->width);
|
||||
ret &= gst_structure_get_int (structure, "endianness", &filter->endianness);
|
||||
|
||||
filter->buffer_frames = 0;
|
||||
gst_structure_get_int (structure, "buffer-frames", &filter->buffer_frames);
|
||||
|
||||
mimetype = gst_structure_get_name (structure);
|
||||
|
||||
if (strcmp (mimetype, "audio/x-raw-int") == 0) {
|
||||
filter->format = GST_SPEED_FORMAT_INT;
|
||||
ret &= gst_structure_get_int (structure, "depth", &filter->depth);
|
||||
ret &= gst_structure_get_boolean (structure, "signed", &filter->is_signed);
|
||||
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
|
||||
filter->format = GST_SPEED_FORMAT_FLOAT;
|
||||
if (filter->format == GST_SPEED_FORMAT_FLOAT) {
|
||||
filter->sample_size = filter->channels * filter->width / 8;
|
||||
} else {
|
||||
return FALSE;
|
||||
/* our caps only allow width == depth for now */
|
||||
filter->sample_size = filter->channels * filter->width / 8;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
GType
|
||||
gst_speed_get_type (void)
|
||||
{
|
||||
|
@ -180,11 +185,13 @@ static void
|
|||
speed_class_init (GstSpeedClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
gobject_class->set_property = speed_set_property;
|
||||
gobject_class->get_property = speed_get_property;
|
||||
gstelement_class->change_state = speed_change_state;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SPEED,
|
||||
g_param_spec_float ("speed", "speed", "speed",
|
||||
|
@ -198,73 +205,165 @@ speed_init (GstSpeed * filter)
|
|||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_speed_sink_template), "sink");
|
||||
gst_pad_set_link_function (filter->sinkpad, speed_link);
|
||||
gst_pad_set_chain_function (filter->sinkpad, speed_chain);
|
||||
gst_pad_set_getcaps_function (filter->sinkpad, gst_pad_proxy_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
|
||||
|
||||
filter->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_speed_src_template), "src");
|
||||
gst_pad_set_link_function (filter->srcpad, speed_link);
|
||||
gst_pad_set_getcaps_function (filter->srcpad, gst_pad_proxy_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
|
||||
|
||||
gst_element_set_loop_function (GST_ELEMENT (filter), speed_loop);
|
||||
filter->offset = 0;
|
||||
filter->timestamp = 0;
|
||||
filter->sample_size = 0;
|
||||
}
|
||||
|
||||
static inline guint
|
||||
speed_chain_int16 (GstSpeed * filter, GstBuffer * in_buf, GstBuffer * out_buf,
|
||||
guint c, guint in_samples)
|
||||
{
|
||||
gint16 *in_data, *out_data;
|
||||
gfloat interp, lower, i_float;
|
||||
guint i, j;
|
||||
|
||||
in_data = ((gint16 *) GST_BUFFER_DATA (in_buf)) + c;
|
||||
out_data = ((gint16 *) GST_BUFFER_DATA (out_buf)) + c;
|
||||
|
||||
lower = in_data[0];
|
||||
i_float = 0.5 * (filter->speed - 1.0);
|
||||
i = (guint) ceil (i_float);
|
||||
j = 0;
|
||||
|
||||
while (i < in_samples) {
|
||||
interp = i_float - floor (i_float);
|
||||
|
||||
out_data[j * filter->channels] =
|
||||
lower * (1 - interp) + in_data[i * filter->channels] * interp;
|
||||
|
||||
lower = in_data[i * filter->channels];
|
||||
|
||||
i_float += filter->speed;
|
||||
i = (guint) ceil (i_float);
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
static inline guint
|
||||
speed_chain_float32 (GstSpeed * filter, GstBuffer * in_buf, GstBuffer * out_buf,
|
||||
guint c, guint in_samples)
|
||||
{
|
||||
gfloat *in_data, *out_data;
|
||||
gfloat interp, lower, i_float;
|
||||
guint i, j;
|
||||
|
||||
in_data = ((gfloat *) GST_BUFFER_DATA (in_buf)) + c;
|
||||
out_data = ((gfloat *) GST_BUFFER_DATA (out_buf)) + c;
|
||||
|
||||
lower = in_data[0];
|
||||
i_float = 0.5 * (filter->speed - 1.0);
|
||||
i = (guint) ceil (i_float);
|
||||
j = 0;
|
||||
|
||||
while (i < in_samples) {
|
||||
interp = i_float - floor (i_float);
|
||||
|
||||
out_data[j * filter->channels] =
|
||||
lower * (1 - interp) + in_data[i * filter->channels] * interp;
|
||||
|
||||
lower = in_data[i * filter->channels];
|
||||
|
||||
i_float += filter->speed;
|
||||
i = (guint) ceil (i_float);
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
static void
|
||||
speed_loop (GstElement * element)
|
||||
speed_chain (GstPad * pad, GstData * data)
|
||||
{
|
||||
GstSpeed *filter = GST_SPEED (element);
|
||||
GstBuffer *in, *out;
|
||||
guint i, j, nin, nout;
|
||||
gfloat interp, speed, lower, i_float;
|
||||
GstBuffer *in_buf, *out_buf;
|
||||
GstSpeed *filter;
|
||||
guint c, in_samples, out_samples, out_size;
|
||||
|
||||
g_return_if_fail (filter != NULL);
|
||||
g_return_if_fail (pad != NULL);
|
||||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
filter = GST_SPEED (GST_OBJECT_PARENT (pad));
|
||||
g_return_if_fail (GST_IS_SPEED (filter));
|
||||
|
||||
i = j = 0;
|
||||
speed = filter->speed;
|
||||
if (GST_IS_EVENT (data)) {
|
||||
switch (GST_EVENT_TYPE (GST_EVENT (data))) {
|
||||
case GST_EVENT_DISCONTINUOUS:
|
||||
{
|
||||
gint64 timestamp, offset;
|
||||
|
||||
in = GST_BUFFER (gst_pad_pull (filter->sinkpad));
|
||||
|
||||
if (GST_IS_EVENT (in)) {
|
||||
gst_pad_event_default (filter->sinkpad, GST_EVENT (in));
|
||||
if (gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES,
|
||||
×tamp)
|
||||
&& gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES,
|
||||
&offset)) {
|
||||
filter->offset = offset;
|
||||
filter->timestamp = timestamp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gst_pad_event_default (pad, GST_EVENT (data));
|
||||
return;
|
||||
}
|
||||
|
||||
while (GST_IS_EVENT (in)) {
|
||||
gst_pad_event_default (filter->srcpad, GST_EVENT (in));
|
||||
in = GST_BUFFER (gst_pad_pull (filter->sinkpad));
|
||||
in_buf = GST_BUFFER (data);
|
||||
|
||||
out_size = ceil ((gfloat) GST_BUFFER_SIZE (in_buf) / filter->speed);
|
||||
out_buf = gst_pad_alloc_buffer (filter->srcpad, -1, out_size);
|
||||
|
||||
in_samples = GST_BUFFER_SIZE (in_buf) / filter->sample_size;
|
||||
|
||||
out_samples = 0;
|
||||
|
||||
for (c = 0; c < filter->channels; ++c) {
|
||||
if (filter->format == GST_SPEED_FORMAT_INT) {
|
||||
out_samples = speed_chain_int16 (filter, in_buf, out_buf, c, in_samples);
|
||||
} else {
|
||||
out_samples =
|
||||
speed_chain_float32 (filter, in_buf, out_buf, c, in_samples);
|
||||
}
|
||||
}
|
||||
|
||||
/* this is a bit nasty, but hey, it's what you've got to do to keep the same
|
||||
* algorithm and multiple data types in c. */
|
||||
if (filter->format == GST_SPEED_FORMAT_FLOAT) {
|
||||
#define _FORMAT gfloat
|
||||
#include "filter.func"
|
||||
#undef _FORMAT
|
||||
} else if (filter->format == GST_SPEED_FORMAT_INT && filter->width == 16) {
|
||||
#define _FORMAT gint16
|
||||
#include "filter.func"
|
||||
#undef _FORMAT
|
||||
} else if (filter->format == GST_SPEED_FORMAT_INT && filter->width == 8) {
|
||||
#define _FORMAT gint8
|
||||
#include "filter.func"
|
||||
#undef _FORMAT
|
||||
} else {
|
||||
GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION, (NULL),
|
||||
("format wasn't negotiated before chain function"));
|
||||
gst_element_yield (element);
|
||||
}
|
||||
GST_BUFFER_SIZE (out_buf) = out_samples * filter->sample_size;
|
||||
|
||||
GST_BUFFER_OFFSET (out_buf) = filter->offset;
|
||||
GST_BUFFER_TIMESTAMP (out_buf) = filter->timestamp;
|
||||
|
||||
filter->offset += GST_BUFFER_SIZE (out_buf) / filter->sample_size;
|
||||
filter->timestamp = filter->offset * GST_SECOND / filter->rate;
|
||||
|
||||
GST_BUFFER_DURATION (out_buf) =
|
||||
filter->timestamp - GST_BUFFER_TIMESTAMP (out_buf);
|
||||
|
||||
gst_pad_push (filter->srcpad, GST_DATA (out_buf));
|
||||
|
||||
gst_buffer_unref (in_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
speed_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstSpeed *filter;
|
||||
GstSpeed *filter = (GstSpeed *) object;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_SPEED (object));
|
||||
filter = GST_SPEED (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SPEED:
|
||||
|
@ -279,11 +378,9 @@ static void
|
|||
speed_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstSpeed *filter;
|
||||
GstSpeed *filter = (GstSpeed *) object;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_SPEED (object));
|
||||
filter = GST_SPEED (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SPEED:
|
||||
|
@ -295,6 +392,29 @@ speed_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
speed_change_state (GstElement * element)
|
||||
{
|
||||
GstSpeed *speed = GST_SPEED (element);
|
||||
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
break;
|
||||
case GST_STATE_READY_TO_PAUSED:
|
||||
speed->offset = 0;
|
||||
speed->timestamp = 0;
|
||||
speed->sample_size = 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)
|
||||
{
|
||||
|
|
|
@ -47,23 +47,23 @@ enum _GstSpeedFormat {
|
|||
};
|
||||
|
||||
struct _GstSpeed {
|
||||
GstElement element;
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad, *srcpad;
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
gfloat speed;
|
||||
gfloat speed;
|
||||
|
||||
/* valid for both int and float */
|
||||
gint64 offset;
|
||||
gint64 timestamp;
|
||||
|
||||
guint rate;
|
||||
guint channels;
|
||||
guint width;
|
||||
guint buffer_frames;
|
||||
|
||||
guint sample_size;
|
||||
GstSpeedFormat format;
|
||||
guint rate;
|
||||
guint channels;
|
||||
guint width;
|
||||
guint endianness;
|
||||
guint buffer_frames;
|
||||
|
||||
/* valid only for format==GST_SPEED_FORMAT_INT */
|
||||
guint depth;
|
||||
gboolean is_signed;
|
||||
};
|
||||
|
||||
struct _GstSpeedClass {
|
||||
|
|
Loading…
Reference in a new issue