mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 23:48:53 +00:00
More work on the audiosink, mostly debugging and a race in shutdown.
Original commit message from CVS: * docs/design-audiosinks.txt: * gst-libs/gst/audio/TODO: * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_get_type), (gst_audioringbuffer_class_init), (audioringbuffer_thread_func), (gst_audioringbuffer_init), (gst_audioringbuffer_acquire), (gst_audioringbuffer_release), (gst_audioringbuffer_play), (gst_audioringbuffer_stop), (gst_audioringbuffer_delay), (gst_audiosink_class_init), (gst_audiosink_create_ringbuffer): * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_baseaudiosink_class_init), (gst_baseaudiosink_init), (gst_baseaudiosink_get_clock), (gst_baseaudiosink_get_time), (gst_baseaudiosink_set_property), (build_linear_format), (debug_spec_caps), (debug_spec_buffer), (gst_baseaudiosink_setcaps), (gst_baseaudiosink_get_times), (gst_baseaudiosink_event), (gst_baseaudiosink_preroll), (gst_baseaudiosink_render), (gst_baseaudiosink_create_ringbuffer), (gst_baseaudiosink_callback), (gst_baseaudiosink_change_state): * gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_get_type), (gst_ringbuffer_set_callback), (gst_ringbuffer_acquire), (gst_ringbuffer_release), (gst_ringbuffer_play), (gst_ringbuffer_pause), (gst_ringbuffer_stop), (gst_ringbuffer_delay), (gst_ringbuffer_played_samples), (gst_ringbuffer_set_sample), (wait_segment), (gst_ringbuffer_commit), (gst_ringbuffer_prepare_read), (gst_ringbuffer_advance), (gst_ringbuffer_clear): More work on the audiosink, mostly debugging and a race in shutdown.
This commit is contained in:
parent
fc5d296de2
commit
658bd2cac6
6 changed files with 58 additions and 20 deletions
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
2005-05-05 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* docs/design-audiosinks.txt:
|
||||||
|
* gst-libs/gst/audio/TODO:
|
||||||
|
* gst-libs/gst/audio/gstaudiosink.c:
|
||||||
|
(gst_audioringbuffer_get_type), (gst_audioringbuffer_class_init),
|
||||||
|
(audioringbuffer_thread_func), (gst_audioringbuffer_init),
|
||||||
|
(gst_audioringbuffer_acquire), (gst_audioringbuffer_release),
|
||||||
|
(gst_audioringbuffer_play), (gst_audioringbuffer_stop),
|
||||||
|
(gst_audioringbuffer_delay), (gst_audiosink_class_init),
|
||||||
|
(gst_audiosink_create_ringbuffer):
|
||||||
|
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||||
|
(gst_baseaudiosink_class_init), (gst_baseaudiosink_init),
|
||||||
|
(gst_baseaudiosink_get_clock), (gst_baseaudiosink_get_time),
|
||||||
|
(gst_baseaudiosink_set_property), (build_linear_format),
|
||||||
|
(debug_spec_caps), (debug_spec_buffer),
|
||||||
|
(gst_baseaudiosink_setcaps), (gst_baseaudiosink_get_times),
|
||||||
|
(gst_baseaudiosink_event), (gst_baseaudiosink_preroll),
|
||||||
|
(gst_baseaudiosink_render), (gst_baseaudiosink_create_ringbuffer),
|
||||||
|
(gst_baseaudiosink_callback), (gst_baseaudiosink_change_state):
|
||||||
|
* gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_get_type),
|
||||||
|
(gst_ringbuffer_set_callback), (gst_ringbuffer_acquire),
|
||||||
|
(gst_ringbuffer_release), (gst_ringbuffer_play),
|
||||||
|
(gst_ringbuffer_pause), (gst_ringbuffer_stop),
|
||||||
|
(gst_ringbuffer_delay), (gst_ringbuffer_played_samples),
|
||||||
|
(gst_ringbuffer_set_sample), (wait_segment),
|
||||||
|
(gst_ringbuffer_commit), (gst_ringbuffer_prepare_read),
|
||||||
|
(gst_ringbuffer_advance), (gst_ringbuffer_clear):
|
||||||
|
More work on the audiosink, mostly debugging and a race in
|
||||||
|
shutdown.
|
||||||
|
|
||||||
2005-04-28 Wim Taymans <wim@fluendo.com>
|
2005-04-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind),
|
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind),
|
||||||
|
|
|
@ -49,8 +49,8 @@ Design:
|
||||||
The ringbuffer is a contiguous piece of memory divided into segtotal
|
The ringbuffer is a contiguous piece of memory divided into segtotal
|
||||||
pieces of segments. Each segment has segsize bytes.
|
pieces of segments. Each segment has segsize bytes.
|
||||||
|
|
||||||
play position write position
|
play position
|
||||||
v v
|
v
|
||||||
+---+---+---+-------------------------------------+----------+
|
+---+---+---+-------------------------------------+----------+
|
||||||
+ 0 | 1 | 2 | .... | segtotal |
|
+ 0 | 1 | 2 | .... | segtotal |
|
||||||
+---+---+---+-------------------------------------+----------+
|
+---+---+---+-------------------------------------+----------+
|
||||||
|
@ -58,14 +58,9 @@ Design:
|
||||||
segsize bytes = N samples * bytes_per_sample.
|
segsize bytes = N samples * bytes_per_sample.
|
||||||
|
|
||||||
|
|
||||||
The ringbuffer has a play and write position, which is expressed in
|
The ringbuffer has a play position, which is expressed in
|
||||||
segments. The play position is where the device is currently reading
|
segments. The play position is where the device is currently reading
|
||||||
samples and the write position is where new samples can be written
|
samples from the buffer.
|
||||||
into the buffer.
|
|
||||||
|
|
||||||
The latency of the ringbuffer is the distance between the play and
|
|
||||||
write position. The lowest latency is the size of a segment, thus
|
|
||||||
smaller segment sizes allow for lower latency.
|
|
||||||
|
|
||||||
The ringbuffer can be put to the PLAYING or STOPPED state.
|
The ringbuffer can be put to the PLAYING or STOPPED state.
|
||||||
|
|
||||||
|
@ -85,6 +80,12 @@ Design:
|
||||||
The ringbuffer is implemented with lockfree atomic operations, especially
|
The ringbuffer is implemented with lockfree atomic operations, especially
|
||||||
on the reading side so that low-latency operations are possible.
|
on the reading side so that low-latency operations are possible.
|
||||||
|
|
||||||
|
Whenever new samples are to be put into the ringbuffer, the position of the
|
||||||
|
read pointer is taken. The required write position is taken and the diff
|
||||||
|
is made between the required qnd actual position. If the defference is <0,
|
||||||
|
the sample is too late. If the difference is bigger than segtotal, the
|
||||||
|
writing part has to wait for the play pointer to advance.
|
||||||
|
|
||||||
|
|
||||||
Scheduling:
|
Scheduling:
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,8 @@ TODO
|
||||||
|
|
||||||
- audio base classes:
|
- audio base classes:
|
||||||
- GstBaseAudioSink
|
- GstBaseAudioSink
|
||||||
- parse caps into rinbuffer spec, also mase sure surround sound
|
- parse caps into rinbuffer spec, also make sure surround sound
|
||||||
is parsed correctly.
|
is parsed correctly.
|
||||||
- implement seek/query/convert
|
- implement seek/query/convert
|
||||||
- implement clocks
|
|
||||||
- implement getrange scheduling
|
- implement getrange scheduling
|
||||||
- GstRingBuffer
|
|
||||||
- copy samples to right position in ringbuffer
|
|
||||||
|
|
||||||
|
|
|
@ -183,16 +183,15 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
|
||||||
gst_ringbuffer_advance (buf, 1);
|
gst_ringbuffer_advance (buf, 1);
|
||||||
} else {
|
} else {
|
||||||
GST_LOCK (abuf);
|
GST_LOCK (abuf);
|
||||||
|
if (!abuf->running)
|
||||||
|
goto stop_running;
|
||||||
GST_DEBUG ("signal wait");
|
GST_DEBUG ("signal wait");
|
||||||
GST_AUDIORINGBUFFER_SIGNAL (buf);
|
GST_AUDIORINGBUFFER_SIGNAL (buf);
|
||||||
GST_DEBUG ("wait for action");
|
GST_DEBUG ("wait for action");
|
||||||
GST_AUDIORINGBUFFER_WAIT (buf);
|
GST_AUDIORINGBUFFER_WAIT (buf);
|
||||||
GST_DEBUG ("got signal");
|
GST_DEBUG ("got signal");
|
||||||
if (!abuf->running) {
|
if (!abuf->running)
|
||||||
GST_UNLOCK (abuf);
|
goto stop_running;
|
||||||
GST_DEBUG ("stop running");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GST_DEBUG ("continue running");
|
GST_DEBUG ("continue running");
|
||||||
GST_UNLOCK (abuf);
|
GST_UNLOCK (abuf);
|
||||||
}
|
}
|
||||||
|
@ -207,6 +206,12 @@ no_function:
|
||||||
GST_DEBUG ("no write function, exit thread");
|
GST_DEBUG ("no write function, exit thread");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
stop_running:
|
||||||
|
{
|
||||||
|
GST_UNLOCK (abuf);
|
||||||
|
GST_DEBUG ("stop running, exit thread");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -65,7 +65,7 @@ static GstFlowReturn gst_baseaudiosink_preroll (GstBaseSink * bsink,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_baseaudiosink_render (GstBaseSink * bsink,
|
static GstFlowReturn gst_baseaudiosink_render (GstBaseSink * bsink,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
static void gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event);
|
static gboolean gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event);
|
||||||
static void gst_baseaudiosink_get_times (GstBaseSink * bsink,
|
static void gst_baseaudiosink_get_times (GstBaseSink * bsink,
|
||||||
GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
|
GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
|
||||||
static gboolean gst_baseaudiosink_setcaps (GstBaseSink * bsink, GstCaps * caps);
|
static gboolean gst_baseaudiosink_setcaps (GstBaseSink * bsink, GstCaps * caps);
|
||||||
|
@ -425,7 +425,7 @@ gst_baseaudiosink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
|
||||||
*end = GST_CLOCK_TIME_NONE;
|
*end = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event)
|
gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstBaseAudioSink *sink = GST_BASEAUDIOSINK (bsink);
|
GstBaseAudioSink *sink = GST_BASEAUDIOSINK (bsink);
|
||||||
|
@ -458,6 +458,7 @@ gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
|
|
@ -222,6 +222,9 @@ gst_ringbuffer_release (GstRingBuffer * buf)
|
||||||
if (rclass->release)
|
if (rclass->release)
|
||||||
res = rclass->release (buf);
|
res = rclass->release (buf);
|
||||||
|
|
||||||
|
/* signal any waiters */
|
||||||
|
GST_RINGBUFFER_SIGNAL (buf);
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
buf->acquired = TRUE;
|
buf->acquired = TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue