mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
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:
parent
1d0e1586d8
commit
85c7eeecc3
5 changed files with 84 additions and 44 deletions
16
ChangeLog
16
ChangeLog
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue