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 209c9a4..f33f21e 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 1b859f5..3a59f8b 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 3344ea4..35448da 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 2f1fb78..1a56b75 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 96fb500..45fda79 100644 (file)
@@ -1279,7 +1279,7 @@ next_buffer:
        }
 success:
        btr_consume(btrn, converted);
-       goto next_buffer;
+       return;
 err:
        assert(ret < 0);
        t->error = ret;