Reduce decoder latency.
authorAndre Noll <maan@systemlinux.org>
Fri, 18 Jun 2010 20:46:22 +0000 (22:46 +0200)
committerAndre Noll <maan@systemlinux.org>
Fri, 18 Jun 2010 20:46:22 +0000 (22:46 +0200)
If large/many FEC slices are used, the decoder gets large amounts of
data in one chunk. Currently it decodes as much as it can which may
take several 100 milliseconds on slow machines -- enough to cause
buffer underruns for the alsa writer.

This patch teaches the decoders to convert only a small amount of data
in one go in order to give the other buffer tree nodes a chance to run.

aacdec_filter.c
buffer_tree.c
mp3dec_filter.c
oggdec_filter.c
wmadec_filter.c

index 209c9a4674adfba61f82f8d6e8fac05ec37ccff3..f33f21eb7a63479e87c17cafb1d7fad0f6bce19b 100644 (file)
@@ -112,6 +112,7 @@ next_buffer:
                return;
        btr_merge(btrn, fn->min_iqs);
        len = btr_next_buffer(btrn, (char **)&inbuf);
+       len = PARA_MAX(len, (size_t)8192);
        consumed = 0;
        iqs = btr_get_input_queue_size(btrn);
        if (!padd->initialized) {
index 1b859f520ebf4aa16d0a13df897395d97da423d9..3a59f8b5e2e20fa20c94117dd31e2655101936cf 100644 (file)
@@ -1067,7 +1067,7 @@ struct btr_node *btr_search_node(const char *name, struct btr_node *root)
 }
 
 /** 640K ought to be enough for everybody ;) */
-#define BTRN_MAX_PENDING (640 * 1024)
+#define BTRN_MAX_PENDING (96 * 1024)
 
 /**
  * Return the current state of a buffer tree node.
index 3344ea4198595e22629b392b2d90041fdee06c8b..35448da7e22f67c84e2fb08d8f1ba6b15de2d49f 100644 (file)
@@ -140,6 +140,12 @@ next_buffer:
                return;
        btr_merge(btrn, fn->min_iqs);
        len = btr_next_buffer(btrn, &inbuffer);
+       /*
+        * Decode at most 8K in one go to give the post_select() functions of
+        * other buffer tree nodes a chance to run. This is necessary to avoid
+        * buffer underruns on slow machines.
+        */
+       len = PARA_MIN(len, (size_t)8192);
        mad_stream_buffer(&pmd->stream, (unsigned char *)inbuffer, len);
 next_frame:
        ret = mad_header_decode(&pmd->frame.header, &pmd->stream);
index 2f1fb787814742ed4d503612b0728d5d8158aaa4..1a56b750a94507c67ef9e49de635b453ac313d8e 100644 (file)
@@ -227,7 +227,7 @@ static void ogg_post_select(__a_unused struct sched *s, struct task *t)
                if (read_ret < 0)
                        goto out;
                btr_add_output(out, read_ret, btrn);
-               if (btr_get_output_queue_size(btrn) > 640 * 1024)
+               if (btr_get_output_queue_size(btrn) > 128 * 1024)
                        return; /* enough data for the moment */
        }
 out:
index 96fb50082d2bff52ba082904341851048c66c6ef..45fda79e7e7359a0535bd0a932ec03ad944b23fe 100644 (file)
@@ -1279,7 +1279,7 @@ next_buffer:
        }
 success:
        btr_consume(btrn, converted);
-       goto next_buffer;
+       return;
 err:
        assert(ret < 0);
        t->error = ret;