17.11.2015 12:13, arun at accosted.net wrote: > From: Arun Raghavan <git at arunraghavan.net> > > The drain reporting improvements that were added to alsa-sink were only > being applied to directly connected sink inputs. This patch makes the > same logic also recurse down the filter hierarchy, so drains are > acknowledged more accurately (and not late) even if there is a filter > sink in between. > > Also does some minor reorganisation of the code and sprinkles in some > comments as documentation. Thanks for the patch. Do I understand correctly that it supersedes this one? http://thread.gmane.org/gmane.comp.audio.pulseaudio.general/21582 -- Alexander E. Patrakov > --- > src/pulsecore/sink.c | 38 +++++++++++++++++++++++++++++++------- > 1 file changed, 31 insertions(+), 7 deletions(-) > > diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c > index 9ddb527..0b44fc7 100644 > --- a/src/pulsecore/sink.c > +++ b/src/pulsecore/sink.c > @@ -950,18 +950,42 @@ size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) { > > PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) { > size_t uf = i->thread_info.underrun_for_sink; > - if (uf == 0) > - continue; > - if (uf >= left_to_play) { > - if (pa_sink_input_process_underrun(i)) > - continue; > + > + /* Propagate down the filter tree */ > + if (i->origin_sink) { > + size_t filter_result, left_to_play_origin; > + > + /* The recursive call works in the origin sink domain ... */ > + left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec); > + > + /* .. and returns the time to sleep before waking up. We need the > + * underrun duration for comparisons, so we undo the subtraction on > + * the return value... */ > + filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin); > + > + /* ... and convert it back to the master sink domain */ > + filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec); > + > + /* Remember the longest underrun so far */ > + if (filter_result > result) > + result = filter_result; > } > - else if (uf > result) > + > + if (uf == 0) { > + /* No underrun here, move on */ > + continue; > + } else if (uf >= left_to_play) { > + /* The sink has possibly consumed all the data the sink input provided */ > + pa_sink_input_process_underrun(i); > + } else if (uf > result) { > + /* Remember the longest underrun so far */ > result = uf; > + } > } > > if (result > 0) > - pa_log_debug("Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", (long) result, (long) left_to_play - result); > + pa_log_debug("%s: Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", s->name, > + (long) result, (long) left_to_play - result); > return left_to_play - result; > } > > -- Alexander E. Patrakov