gst-libs/gst/audio/: Improve debugging.

Original commit message from CVS:
* gst-libs/gst/audio/gstaudiosink.c: (audioringbuffer_thread_func):
* gst-libs/gst/audio/gstaudiosrc.c: (audioringbuffer_thread_func):
Improve debugging.
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_query), (gst_base_audio_sink_event),
(gst_base_audio_sink_render), (gst_base_audio_sink_async_play):
Improve latency and clock slaving calculations.
Improve slave clock calibration.
* gst-libs/gst/audio/gstringbuffer.c:
(gst_ring_buffer_commit_full):
When we are asked to render N sample to 0 bytes, return N.
This commit is contained in:
Wim Taymans 2007-03-01 17:01:43 +00:00
parent 1d0e1586d8
commit 85c7eeecc3
5 changed files with 84 additions and 44 deletions

View file

@ -1,3 +1,19 @@
2007-03-01 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/gstaudiosink.c: (audioringbuffer_thread_func):
* gst-libs/gst/audio/gstaudiosrc.c: (audioringbuffer_thread_func):
Improve debugging.
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_query), (gst_base_audio_sink_event),
(gst_base_audio_sink_render), (gst_base_audio_sink_async_play):
Improve latency and clock slaving calculations.
Improve slave clock calibration.
* gst-libs/gst/audio/gstringbuffer.c:
(gst_ring_buffer_commit_full):
When we are asked to render N sample to 0 bytes, return N.
2007-03-01 Wim Taymans <wim@fluendo.com> 2007-03-01 Wim Taymans <wim@fluendo.com>
* ext/alsa/gstalsasink.c: (gst_alsasink_class_init), * ext/alsa/gstalsasink.c: (gst_alsasink_class_init),

View file

@ -207,7 +207,7 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf)); sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
csink = GST_AUDIO_SINK_GET_CLASS (sink); csink = GST_AUDIO_SINK_GET_CLASS (sink);
GST_DEBUG ("enter thread"); GST_DEBUG_OBJECT (sink, "enter thread");
writefunc = csink->write; writefunc = csink->write;
if (writefunc == NULL) if (writefunc == NULL)
@ -224,10 +224,11 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
left = len; left = len;
do { do {
written = writefunc (sink, readptr + written, left); written = writefunc (sink, readptr + written, left);
GST_LOG ("transfered %d bytes of %d from segment %d", written, left, GST_LOG_OBJECT (sink, "transfered %d bytes of %d from segment %d",
readseg); written, left, readseg);
if (written < 0 || written > left) { if (written < 0 || written > left) {
GST_WARNING ("error writing data (reason: %s), skipping segment", GST_WARNING_OBJECT (sink,
"error writing data (reason: %s), skipping segment",
g_strerror (errno)); g_strerror (errno));
break; break;
} }
@ -243,18 +244,18 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
GST_OBJECT_LOCK (abuf); GST_OBJECT_LOCK (abuf);
if (!abuf->running) if (!abuf->running)
goto stop_running; goto stop_running;
GST_DEBUG ("signal wait"); GST_DEBUG_OBJECT (sink, "signal wait");
GST_AUDIORING_BUFFER_SIGNAL (buf); GST_AUDIORING_BUFFER_SIGNAL (buf);
GST_DEBUG ("wait for action"); GST_DEBUG_OBJECT (sink, "wait for action");
GST_AUDIORING_BUFFER_WAIT (buf); GST_AUDIORING_BUFFER_WAIT (buf);
GST_DEBUG ("got signal"); GST_DEBUG_OBJECT (sink, "got signal");
if (!abuf->running) if (!abuf->running)
goto stop_running; goto stop_running;
GST_DEBUG ("continue running"); GST_DEBUG_OBJECT (sink, "continue running");
GST_OBJECT_UNLOCK (abuf); GST_OBJECT_UNLOCK (abuf);
} }
} }
GST_DEBUG ("exit thread"); GST_DEBUG_OBJECT (sink, "exit thread");
return; return;

View file

@ -203,7 +203,7 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf)); src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
csrc = GST_AUDIO_SRC_GET_CLASS (src); csrc = GST_AUDIO_SRC_GET_CLASS (src);
GST_DEBUG ("enter thread"); GST_DEBUG_OBJECT (src, "enter thread");
readfunc = csrc->read; readfunc = csrc->read;
if (readfunc == NULL) if (readfunc == NULL)
@ -219,11 +219,12 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
left = len; left = len;
do { do {
GST_DEBUG ("transfer %d bytes to segment %d", left, readseg);
read = readfunc (src, readptr + read, left); read = readfunc (src, readptr + read, left);
GST_DEBUG ("transfered %d bytes", read); GST_LOG_OBJECT (src, "transfered %d bytes of %d to segment %d", read,
left, readseg);
if (read < 0 || read > left) { if (read < 0 || read > left) {
GST_WARNING ("error reading data (reason: %s), skipping segment", GST_WARNING_OBJECT (src,
"error reading data (reason: %s), skipping segment",
g_strerror (errno)); g_strerror (errno));
break; break;
} }
@ -236,18 +237,18 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
GST_OBJECT_LOCK (abuf); GST_OBJECT_LOCK (abuf);
if (!abuf->running) if (!abuf->running)
goto stop_running; goto stop_running;
GST_DEBUG ("signal wait"); GST_DEBUG_OBJECT (src, "signal wait");
GST_AUDIORING_BUFFER_SIGNAL (buf); GST_AUDIORING_BUFFER_SIGNAL (buf);
GST_DEBUG ("wait for action"); GST_DEBUG_OBJECT (src, "wait for action");
GST_AUDIORING_BUFFER_WAIT (buf); GST_AUDIORING_BUFFER_WAIT (buf);
GST_DEBUG ("got signal"); GST_DEBUG_OBJECT (src, "got signal");
if (!abuf->running) if (!abuf->running)
goto stop_running; goto stop_running;
GST_DEBUG ("continue running"); GST_DEBUG_OBJECT (src, "continue running");
GST_OBJECT_UNLOCK (abuf); GST_OBJECT_UNLOCK (abuf);
} }
} }
GST_DEBUG ("exit thread"); GST_DEBUG_OBJECT (src, "exit thread");
return; return;

View file

@ -558,7 +558,7 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event)
gst_event_parse_new_segment_full (event, NULL, &rate, NULL, NULL, gst_event_parse_new_segment_full (event, NULL, &rate, NULL, NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
GST_DEBUG_OBJECT (sink, "new rate of %f", rate); GST_DEBUG_OBJECT (sink, "new segment rate of %f", rate);
break; break;
} }
default: default:
@ -746,6 +746,11 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
render_start += base_time; render_start += base_time;
render_stop += base_time; render_stop += base_time;
/* compensate for latency */
latency = gst_base_sink_get_latency (bsink);
GST_DEBUG_OBJECT (sink,
"compensating for latency %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));
slaved = clock != sink->provided_clock; slaved = clock != sink->provided_clock;
if (slaved) { if (slaved) {
/* get calibration parameters to compensate for speed and offset differences /* get calibration parameters to compensate for speed and offset differences
@ -753,39 +758,56 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal, gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
&crate_num, &crate_denom); &crate_num, &crate_denom);
cinternal += latency;
GST_DEBUG_OBJECT (sink, "internal %" GST_TIME_FORMAT " external %" GST_DEBUG_OBJECT (sink, "internal %" GST_TIME_FORMAT " external %"
GST_TIME_FORMAT " %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_FORMAT " %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f",
GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal), crate_num, GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal), crate_num,
crate_denom, (gdouble) crate_num / crate_denom); crate_denom, (gdouble) crate_num / crate_denom);
if (crate_num == 0)
crate_denom = crate_num = 1;
/* bring to our slaved clock time */ /* bring to our slaved clock time */
if (render_start >= cexternal) if (render_start >= cexternal) {
render_start = render_start =
gst_util_uint64_scale (render_start - cexternal, crate_denom, gst_util_uint64_scale (render_start - cexternal, crate_denom,
crate_num) + cinternal; crate_num);
else render_start += cinternal;
render_start = } else {
cinternal - gst_util_uint64_scale (cexternal - render_start, render_start = gst_util_uint64_scale (cexternal - render_start,
crate_denom, crate_num); crate_denom, crate_num);
if (cinternal > render_start)
if (render_stop >= cexternal) render_start = cinternal - render_start;
render_stop =
gst_util_uint64_scale (render_stop - cexternal, crate_denom,
crate_num) + cinternal;
else else
render_stop = render_start = 0;
cinternal - gst_util_uint64_scale (cexternal - render_stop,
crate_denom, crate_num);
} }
/* compensate for latency */ if (render_stop >= cexternal) {
latency = gst_base_sink_get_latency (bsink); render_stop =
render_start += latency; gst_util_uint64_scale (render_stop - cexternal, crate_denom,
render_stop += latency; crate_num);
render_stop += cinternal;
} else {
render_stop = gst_util_uint64_scale (cexternal - render_stop,
crate_denom, crate_num);
if (cinternal > render_stop)
render_stop = cinternal - render_stop;
else
render_stop = 0;
}
GST_DEBUG_OBJECT (sink, GST_DEBUG_OBJECT (sink,
"render: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT, "after slaving: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop)); GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
} else {
render_start += latency;
render_stop += latency;
GST_DEBUG_OBJECT (sink,
"after latency: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
}
/* and bring the time to the rate corrected offset in the buffer */ /* and bring the time to the rate corrected offset in the buffer */
render_start = gst_util_uint64_scale_int (render_start, render_start = gst_util_uint64_scale_int (render_start,
@ -1016,7 +1038,7 @@ static GstStateChangeReturn
gst_base_audio_sink_async_play (GstBaseSink * basesink) gst_base_audio_sink_async_play (GstBaseSink * basesink)
{ {
GstClock *clock; GstClock *clock;
GstClockTime time, base; GstClockTime itime, etime;
GstBaseAudioSink *sink; GstBaseAudioSink *sink;
sink = GST_BASE_AUDIO_SINK (basesink); sink = GST_BASE_AUDIO_SINK (basesink);
@ -1034,18 +1056,18 @@ gst_base_audio_sink_async_play (GstBaseSink * basesink)
if (clock != sink->provided_clock) { if (clock != sink->provided_clock) {
GstClockTime rate_num, rate_denom; GstClockTime rate_num, rate_denom;
base = GST_ELEMENT_CAST (sink)->base_time; etime = gst_clock_get_time (clock) - GST_ELEMENT_CAST (sink)->base_time;
time = gst_clock_get_internal_time (sink->provided_clock); itime = gst_clock_get_internal_time (sink->provided_clock);
GST_DEBUG_OBJECT (sink, GST_DEBUG_OBJECT (sink,
"time: %" GST_TIME_FORMAT " base: %" GST_TIME_FORMAT, "internal time: %" GST_TIME_FORMAT " external time: %" GST_TIME_FORMAT,
GST_TIME_ARGS (time), GST_TIME_ARGS (base)); GST_TIME_ARGS (itime), GST_TIME_ARGS (etime));
/* FIXME, this is not yet accurate enough for smooth playback */ /* FIXME, this is not yet accurate enough for smooth playback */
gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate_num, gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate_num,
&rate_denom); &rate_denom);
/* Does not work yet. */ /* Does not work yet. */
gst_clock_set_calibration (sink->provided_clock, time, base, gst_clock_set_calibration (sink->provided_clock, itime, etime,
rate_num, rate_denom); rate_num, rate_denom);
gst_clock_set_master (sink->provided_clock, clock); gst_clock_set_master (sink->provided_clock, clock);

View file

@ -1309,7 +1309,7 @@ gst_ring_buffer_commit_full (GstRingBuffer * buf, guint64 * sample,
gboolean reverse; gboolean reverse;
if (G_UNLIKELY (in_samples == 0 || out_samples == 0)) if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
return 0; return in_samples;
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1); g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
g_return_val_if_fail (buf->data != NULL, -1); g_return_val_if_fail (buf->data != NULL, -1);