mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-25 16:48:11 +00:00
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:
parent
09c2e02b0a
commit
ee345636bc
5 changed files with 49 additions and 15 deletions
14
ChangeLog
14
ChangeLog
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue