From d3af91481ef4a00c26530b7238552666424f0b6f Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 18 Jun 2010 22:46:22 +0200 Subject: [PATCH] Reduce decoder latency. 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 | 1 + buffer_tree.c | 2 +- mp3dec_filter.c | 6 ++++++ oggdec_filter.c | 2 +- wmadec_filter.c | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/aacdec_filter.c b/aacdec_filter.c index 209c9a46..f33f21eb 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -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) { diff --git a/buffer_tree.c b/buffer_tree.c index 1b859f52..3a59f8b5 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -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. diff --git a/mp3dec_filter.c b/mp3dec_filter.c index 3344ea41..35448da7 100644 --- a/mp3dec_filter.c +++ b/mp3dec_filter.c @@ -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); diff --git a/oggdec_filter.c b/oggdec_filter.c index 2f1fb787..1a56b750 100644 --- a/oggdec_filter.c +++ b/oggdec_filter.c @@ -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: diff --git a/wmadec_filter.c b/wmadec_filter.c index 96fb5008..45fda79e 100644 --- a/wmadec_filter.c +++ b/wmadec_filter.c @@ -1279,7 +1279,7 @@ next_buffer: } success: btr_consume(btrn, converted); - goto next_buffer; + return; err: assert(ret < 0); t->error = ret; -- 2.30.2