gst-libs/gst/audio/gstbaseaudiosrc.*: Allow othe clocks than the internal clock to be used for the pipeline.

Original commit message from CVS:
* gst-libs/gst/audio/gstbaseaudiosrc.c:
(gst_base_audio_src_class_init), (gst_base_audio_src_init),
(gst_base_audio_src_provide_clock),
(gst_base_audio_src_set_property),
(gst_base_audio_src_get_property), (gst_base_audio_src_create):
* gst-libs/gst/audio/gstbaseaudiosrc.h:
Allow othe clocks than the internal clock to be used for the pipeline.
Add property to disable clock provide.
API: GstBaseAudioSrc::provide-clock
This commit is contained in:
Wim Taymans 2007-09-10 22:10:54 +00:00
parent 3df6b8ad42
commit c942252430
3 changed files with 89 additions and 36 deletions

View file

@ -1,3 +1,15 @@
2007-09-10 Wim Taymans <wim.taymans@gmail.com>
* gst-libs/gst/audio/gstbaseaudiosrc.c:
(gst_base_audio_src_class_init), (gst_base_audio_src_init),
(gst_base_audio_src_provide_clock),
(gst_base_audio_src_set_property),
(gst_base_audio_src_get_property), (gst_base_audio_src_create):
* gst-libs/gst/audio/gstbaseaudiosrc.h:
Allow othe clocks than the internal clock to be used for the pipeline.
Add property to disable clock provide.
API: GstBaseAudioSrc::provide-clock
2007-09-10 Stefan Kost <ensonic@users.sf.net>
* gst/playback/gstdecodebin2.c:

View file

@ -45,6 +45,14 @@
GST_DEBUG_CATEGORY_STATIC (gst_base_audio_src_debug);
#define GST_CAT_DEFAULT gst_base_audio_src_debug
#define GST_BASE_AUDIO_SRC_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_AUDIO_SRC, GstBaseAudioSrcPrivate))
struct _GstBaseAudioSrcPrivate
{
gboolean provide_clock;
};
/* BaseAudioSrc signals and args */
enum
{
@ -54,12 +62,14 @@ enum
#define DEFAULT_BUFFER_TIME ((200 * GST_MSECOND) / GST_USECOND)
#define DEFAULT_LATENCY_TIME ((10 * GST_MSECOND) / GST_USECOND)
#define DEFAULT_PROVIDE_CLOCK TRUE
enum
{
PROP_0,
PROP_BUFFER_TIME,
PROP_LATENCY_TIME,
PROP_PROVIDE_CLOCK
};
static void
@ -88,8 +98,6 @@ static GstStateChangeReturn gst_base_audio_src_change_state (GstElement *
element, GstStateChange transition);
static GstClock *gst_base_audio_src_provide_clock (GstElement * elem);
static gboolean gst_base_audio_src_set_clock (GstElement * elem,
GstClock * clock);
static GstClockTime gst_base_audio_src_get_time (GstClock * clock,
GstBaseAudioSrc * src);
@ -124,6 +132,8 @@ gst_base_audio_src_class_init (GstBaseAudioSrcClass * klass)
gstbasesrc_class = (GstBaseSrcClass *) klass;
gstpushsrc_class = (GstPushSrcClass *) klass;
g_type_class_add_private (klass, sizeof (GstBaseAudioSrcPrivate));
gobject_class->set_property =
GST_DEBUG_FUNCPTR (gst_base_audio_src_set_property);
gobject_class->get_property =
@ -140,12 +150,15 @@ gst_base_audio_src_class_init (GstBaseAudioSrcClass * klass)
"Audio latency in microseconds", 1,
G_MAXINT64, DEFAULT_LATENCY_TIME, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_PROVIDE_CLOCK,
g_param_spec_boolean ("provide-clock", "Provide Clock",
"Provide a clock to be used as the global pipeline clock",
DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE));
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_base_audio_src_change_state);
gstelement_class->provide_clock =
GST_DEBUG_FUNCPTR (gst_base_audio_src_provide_clock);
gstelement_class->set_clock =
GST_DEBUG_FUNCPTR (gst_base_audio_src_set_clock);
gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_base_audio_src_setcaps);
gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_base_audio_src_event);
@ -162,8 +175,11 @@ static void
gst_base_audio_src_init (GstBaseAudioSrc * baseaudiosrc,
GstBaseAudioSrcClass * g_class)
{
baseaudiosrc->priv = GST_BASE_AUDIO_SRC_GET_PRIVATE (baseaudiosrc);
baseaudiosrc->buffer_time = DEFAULT_BUFFER_TIME;
baseaudiosrc->latency_time = DEFAULT_LATENCY_TIME;
baseaudiosrc->priv->provide_clock = DEFAULT_PROVIDE_CLOCK;
/* reset blocksize we use latency time to calculate a more useful
* value based on negotiated format. */
GST_BASE_SRC (baseaudiosrc)->blocksize = 0;
@ -196,30 +212,6 @@ gst_base_audio_src_dispose (GObject * object)
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static gboolean
gst_base_audio_src_set_clock (GstElement * elem, GstClock * clock)
{
GstBaseAudioSrc *src;
src = GST_BASE_AUDIO_SRC (elem);
/* FIXME, we cannot slave to another clock yet, better fail
* than to give a bad user experience (tm). */
if (clock && clock != src->clock)
goto wrong_clock;
return TRUE;
/* ERRORS */
wrong_clock:
{
/* no error message, this method is called with the parent
* lock helt.. sigh.. long live recursive locks.. */
GST_DEBUG_OBJECT (src, "Cannot operate with this clock.");
return FALSE;
}
}
static GstClock *
gst_base_audio_src_provide_clock (GstElement * elem)
{
@ -235,7 +227,12 @@ gst_base_audio_src_provide_clock (GstElement * elem)
if (!gst_ring_buffer_is_acquired (src->ringbuffer))
goto wrong_state;
GST_OBJECT_LOCK (src);
if (!src->priv->provide_clock)
goto clock_disabled;
clock = GST_CLOCK_CAST (gst_object_ref (src->clock));
GST_OBJECT_UNLOCK (src);
return clock;
@ -245,6 +242,12 @@ wrong_state:
GST_DEBUG_OBJECT (src, "ringbuffer not acquired");
return NULL;
}
clock_disabled:
{
GST_DEBUG_OBJECT (src, "clock provide disabled");
GST_OBJECT_UNLOCK (src);
return NULL;
}
}
static GstClockTime
@ -300,6 +303,11 @@ gst_base_audio_src_set_property (GObject * object, guint prop_id,
case PROP_LATENCY_TIME:
src->latency_time = g_value_get_int64 (value);
break;
case PROP_PROVIDE_CLOCK:
GST_OBJECT_LOCK (src);
src->priv->provide_clock = g_value_get_boolean (value);
GST_OBJECT_UNLOCK (src);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -321,6 +329,11 @@ gst_base_audio_src_get_property (GObject * object, guint prop_id,
case PROP_LATENCY_TIME:
g_value_set_int64 (value, src->latency_time);
break;
case PROP_PROVIDE_CLOCK:
GST_OBJECT_LOCK (src);
g_value_set_boolean (value, src->priv->provide_clock);
GST_OBJECT_UNLOCK (src);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -533,23 +546,26 @@ gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
GstBuffer *buf;
guchar *data;
guint samples;
guint samples, total_samples;
guint64 sample;
gint bps;
GstRingBuffer *ringbuffer;
GstRingBufferSpec *spec;
guint read;
GstClockTime timestamp;
GstClock *clock;
ringbuffer = src->ringbuffer;
spec = &ringbuffer->spec;
if (G_UNLIKELY (!gst_ring_buffer_is_acquired (ringbuffer)))
goto wrong_state;
bps = ringbuffer->spec.bytes_per_sample;
bps = spec->bytes_per_sample;
if ((length == 0 && bsrc->blocksize == 0) || length == -1)
/* no length given, use the default segment size */
length = ringbuffer->spec.segsize;
length = spec->segsize;
else
/* make sure we round down to an integral number of samples */
length -= length % bps;
@ -570,7 +586,7 @@ gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
GST_DEBUG_OBJECT (src, "reading from sample %" G_GUINT64_FORMAT, sample);
/* get the number of samples to read */
samples = length / bps;
total_samples = samples = length / bps;
/* FIXME, using a bufferpool would be nice here */
buf = gst_buffer_new_and_alloc (length);
@ -608,13 +624,35 @@ gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
* where we are slaved to another clock. We currently refuse to accept
* any other clock than the one we provide, so this code is fine for
* now. */
timestamp =
gst_util_uint64_scale_int (sample, GST_SECOND, ringbuffer->spec.rate);
GST_OBJECT_LOCK (src);
clock = GST_ELEMENT_CLOCK (src);
if (clock == src->clock) {
timestamp = gst_util_uint64_scale_int (sample, GST_SECOND, spec->rate);
} else {
GstClockTime base_time, latency;
/* take running time of the clock */
timestamp = gst_clock_get_time (clock);
base_time = GST_ELEMENT_CAST (src)->base_time;
if (timestamp > base_time)
timestamp -= base_time;
else
timestamp = 0;
/* subtract latency */
latency = gst_util_uint64_scale_int (total_samples, GST_SECOND, spec->rate);
if (timestamp > latency)
timestamp -= latency;
else
timestamp = 0;
}
GST_OBJECT_UNLOCK (src);
GST_BUFFER_TIMESTAMP (buf) = timestamp;
src->next_sample = sample + samples;
GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (src->next_sample,
GST_SECOND, ringbuffer->spec.rate) - GST_BUFFER_TIMESTAMP (buf);
GST_SECOND, spec->rate) - GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_OFFSET (buf) = sample;
GST_BUFFER_OFFSET_END (buf) = sample + samples;

View file

@ -57,6 +57,7 @@ G_BEGIN_DECLS
typedef struct _GstBaseAudioSrc GstBaseAudioSrc;
typedef struct _GstBaseAudioSrcClass GstBaseAudioSrcClass;
typedef struct _GstBaseAudioSrcPrivate GstBaseAudioSrcPrivate;
/**
* GstBaseAudioSrc:
@ -81,7 +82,9 @@ struct _GstBaseAudioSrc {
GstClock *clock;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
GstBaseAudioSrcPrivate *priv;
gpointer _gst_reserved[GST_PADDING - 1];
};
/**