]> code.delx.au - pulseaudio/commitdiff
sink-input: Fix underrun_for calculation when resampling.
authorUoti Urpala <uau@glyph.nonexistent.invalid>
Sat, 28 Jul 2012 15:24:30 +0000 (18:24 +0300)
committerTanu Kaskinen <tanuk@iki.fi>
Thu, 30 Aug 2012 09:00:35 +0000 (12:00 +0300)
pa_sink_input_seek() calculates output lenth (slength) and
corresponding input length (ilength). During an underrun, the function
generates slength bytes of silence and adds ilength to the
underrun_for value. However, the ilength value may be shortened to
match resampler limits, and there's no corresponding adjustment to
slength. Thus, the length of the generated silence is longer than
resampler output would have been, and underrun_for should be increased
by more than the limited ilength. This error makes the user-visible
since_underrun field in struct pa_timing_info too small. Fix by using
the original value calculated before limiting in this case.

src/pulsecore/sink-input.c

index 4db20175c8bf9b173db1c523479ac792830da729..93887881f8e32bdaf61959ce979a082cedc49be4 100644 (file)
@@ -783,6 +783,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
     pa_bool_t volume_is_norm;
     size_t block_size_max_sink, block_size_max_sink_input;
     size_t ilength;
+    size_t ilength_full;
 
     pa_sink_input_assert_ref(i);
     pa_sink_input_assert_io_context(i);
@@ -816,6 +817,10 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
     } else
         ilength = slength;
 
+    /* Length corresponding to slength (without limiting to
+     * block_size_max_sink_input). */
+    ilength_full = ilength;
+
     if (ilength > block_size_max_sink_input)
         ilength = block_size_max_sink_input;
 
@@ -843,7 +848,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
             pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
             i->thread_info.playing_for = 0;
             if (i->thread_info.underrun_for != (uint64_t) -1)
-                i->thread_info.underrun_for += ilength;
+                i->thread_info.underrun_for += ilength_full;
             break;
         }