]> code.delx.au - pulseaudio/commitdiff
resampler: Never return zero for max block size
authorTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Wed, 28 Aug 2013 11:11:54 +0000 (14:11 +0300)
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Sun, 8 Sep 2013 08:10:10 +0000 (11:10 +0300)
With very low input sample rates the memory pool max block size may
not be big enough, in which case we should return the size of one
frame. Returning zero caused crashing.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=68616
src/pulsecore/resampler.c

index 5599035f6ddd54c4bd0d1b4e876b4a9902f91173..4480823629ead72fa669e22d821957cdc63d03e2 100644 (file)
@@ -534,7 +534,23 @@ size_t pa_resampler_max_block_size(pa_resampler *r) {
     if (r->remap_buf_contains_leftover_data)
         frames -= r->remap_buf.length / (r->w_sz * r->o_ss.channels);
 
-    return ((uint64_t) frames * r->i_ss.rate / max_ss.rate) * r->i_fz;
+    block_size_max = ((uint64_t) frames * r->i_ss.rate / max_ss.rate) * r->i_fz;
+
+    if (block_size_max > 0)
+        return block_size_max;
+    else
+        /* A single input frame may result in so much output that it doesn't
+         * fit in one standard memblock (e.g. converting 1 Hz to 44100 Hz). In
+         * this case the max block size will be set to one frame, and some
+         * memory will be probably be allocated with malloc() instead of using
+         * the memory pool.
+         *
+         * XXX: Should we support this case at all? We could also refuse to
+         * create resamplers whose max block size would exceed the memory pool
+         * block size. In this case also updating the resampler rate should
+         * fail if the new rate would cause an excessive max block size (in
+         * which case the stream would probably have to be killed). */
+        return r->i_fz;
 }
 
 void pa_resampler_reset(pa_resampler *r) {