gst-libs/gst/audio/: Make sure the audio clock always returns an increasing value.

Original commit message from CVS:
* gst-libs/gst/audio/TODO:
* gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init),
(gst_audio_clock_get_internal_time):
* gst-libs/gst/audio/gstaudioclock.h:
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_init), (gst_base_audio_sink_dispose),
(gst_base_audio_sink_get_time), (gst_base_audio_sink_event),
(gst_base_audio_sink_render),
(gst_base_audio_sink_create_ringbuffer),
(gst_base_audio_sink_change_state):
Make sure the audio clock always returns an increasing value.
This commit is contained in:
Wim Taymans 2005-07-20 09:08:05 +00:00
parent 09c2e02b0a
commit ee345636bc
5 changed files with 49 additions and 15 deletions

View file

@ -1,3 +1,17 @@
2005-07-20 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/TODO:
* gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init),
(gst_audio_clock_get_internal_time):
* gst-libs/gst/audio/gstaudioclock.h:
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_init), (gst_base_audio_sink_dispose),
(gst_base_audio_sink_get_time), (gst_base_audio_sink_event),
(gst_base_audio_sink_render),
(gst_base_audio_sink_create_ringbuffer),
(gst_base_audio_sink_change_state):
Make sure the audio clock always returns an increasing value.
2005-07-19 Andy Wingo <wingo@pobox.com> 2005-07-19 Andy Wingo <wingo@pobox.com>
* gst/videotestsrc/: Cleanups. * gst/videotestsrc/: Cleanups.

View file

@ -7,4 +7,4 @@ TODO
is parsed correctly. is parsed correctly.
- implement seek/query/convert - implement seek/query/convert
- implement getrange scheduling - implement getrange scheduling
- on EOS, only post EOS when the complete ringbuffer has been played.

View file

@ -81,6 +81,8 @@ static void
gst_audio_clock_init (GstAudioClock * clock) gst_audio_clock_init (GstAudioClock * clock)
{ {
gst_object_set_name (GST_OBJECT (clock), "GstAudioClock"); gst_object_set_name (GST_OBJECT (clock), "GstAudioClock");
clock->last_time = 0;
} }
GstClock * GstClock *
@ -100,6 +102,13 @@ static GstClockTime
gst_audio_clock_get_internal_time (GstClock * clock) gst_audio_clock_get_internal_time (GstClock * clock)
{ {
GstAudioClock *aclock = GST_AUDIO_CLOCK (clock); GstAudioClock *aclock = GST_AUDIO_CLOCK (clock);
GstClockTime result;
return aclock->func (clock, aclock->user_data); result = aclock->func (clock, aclock->user_data);
if (result == GST_CLOCK_TIME_NONE)
result = aclock->last_time;
else
aclock->last_time = result;
return result;
} }

View file

@ -51,6 +51,8 @@ struct _GstAudioClock {
GstAudioClockGetTimeFunc func; GstAudioClockGetTimeFunc func;
gpointer user_data; gpointer user_data;
GstClockTime last_time;
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };

View file

@ -62,6 +62,8 @@ static GstElementStateReturn gst_base_audio_sink_change_state (GstElement *
static GstClock *gst_base_audio_sink_get_clock (GstElement * elem); static GstClock *gst_base_audio_sink_get_clock (GstElement * elem);
static GstClockTime gst_base_audio_sink_get_time (GstClock * clock, static GstClockTime gst_base_audio_sink_get_time (GstClock * clock,
GstBaseAudioSink * sink); GstBaseAudioSink * sink);
static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data,
guint len, gpointer user_data);
static GstFlowReturn gst_base_audio_sink_preroll (GstBaseSink * bsink, static GstFlowReturn gst_base_audio_sink_preroll (GstBaseSink * bsink,
GstBuffer * buffer); GstBuffer * buffer);
@ -126,8 +128,10 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink)
baseaudiosink->buffer_time = DEFAULT_BUFFER_TIME; baseaudiosink->buffer_time = DEFAULT_BUFFER_TIME;
baseaudiosink->latency_time = DEFAULT_LATENCY_TIME; baseaudiosink->latency_time = DEFAULT_LATENCY_TIME;
baseaudiosink->clock = gst_audio_clock_new ("clock", baseaudiosink->clock = gst_audio_clock_new ("clock",
(GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink); (GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink);
} }
static void static void
@ -141,6 +145,10 @@ gst_base_audio_sink_dispose (GObject * object)
gst_object_unref (sink->clock); gst_object_unref (sink->clock);
sink->clock = NULL; sink->clock = NULL;
if (sink->ringbuffer)
gst_object_unref (sink->ringbuffer);
sink->ringbuffer = NULL;
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -161,7 +169,7 @@ gst_base_audio_sink_get_time (GstClock * clock, GstBaseAudioSink * sink)
GstClockTime result; GstClockTime result;
if (sink->ringbuffer == NULL || sink->ringbuffer->spec.rate == 0) if (sink->ringbuffer == NULL || sink->ringbuffer->spec.rate == 0)
return 0; return GST_CLOCK_TIME_NONE;
/* our processed samples are always increasing */ /* our processed samples are always increasing */
samples = gst_ring_buffer_samples_done (sink->ringbuffer); samples = gst_ring_buffer_samples_done (sink->ringbuffer);
@ -288,6 +296,8 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event)
gst_ring_buffer_pause (sink->ringbuffer); gst_ring_buffer_pause (sink->ringbuffer);
} }
break; break;
case GST_EVENT_EOS:
break;
default: default:
break; break;
} }
@ -335,7 +345,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->discont_start)); GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->discont_start));
/* samples should be rendered based on their timestamp. All samples /* samples should be rendered based on their timestamp. All samples
* arriving before the discont_start are to be trown away */ * arriving before the discont_start are to be thrown away */
/* FIXME, for now we drop the sample completely, we should /* FIXME, for now we drop the sample completely, we should
* in fact clip the sample. Same for the segment_stop, actually. */ * in fact clip the sample. Same for the segment_stop, actually. */
if (time < bsink->discont_start) if (time < bsink->discont_start)
@ -369,10 +379,10 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
wrong_state: wrong_state:
{ {
GST_DEBUG ("ringbuffer in wrong state"); GST_DEBUG ("ringbuffer not negotiated");
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
("sink not negotiated."), (NULL)); ("sink not negotiated."), ("sink not negotiated."));
return GST_FLOW_ERROR; return GST_FLOW_NOT_NEGOTIATED;
} }
} }
@ -386,14 +396,13 @@ gst_base_audio_sink_create_ringbuffer (GstBaseAudioSink * sink)
if (bclass->create_ringbuffer) if (bclass->create_ringbuffer)
buffer = bclass->create_ringbuffer (sink); buffer = bclass->create_ringbuffer (sink);
if (buffer) { if (buffer)
gst_object_set_parent (GST_OBJECT (buffer), GST_OBJECT (sink)); gst_object_set_parent (GST_OBJECT (buffer), GST_OBJECT (sink));
}
return buffer; return buffer;
} }
void static void
gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len, gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len,
gpointer user_data) gpointer user_data)
{ {
@ -411,9 +420,11 @@ gst_base_audio_sink_change_state (GstElement * element)
case GST_STATE_NULL_TO_READY: case GST_STATE_NULL_TO_READY:
break; break;
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
if (sink->ringbuffer == NULL) {
sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink); sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink);
gst_ring_buffer_set_callback (sink->ringbuffer, gst_ring_buffer_set_callback (sink->ringbuffer,
gst_base_audio_sink_callback, sink); gst_base_audio_sink_callback, sink);
}
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
break; break;
@ -430,8 +441,6 @@ gst_base_audio_sink_change_state (GstElement * element)
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
gst_ring_buffer_stop (sink->ringbuffer); gst_ring_buffer_stop (sink->ringbuffer);
gst_ring_buffer_release (sink->ringbuffer); gst_ring_buffer_release (sink->ringbuffer);
gst_object_unref (sink->ringbuffer);
sink->ringbuffer = NULL;
gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL); gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL);
break; break;
case GST_STATE_READY_TO_NULL: case GST_STATE_READY_TO_NULL: