Consolidate decoder code by introducing prepare_filter_node().
authorAndre Noll <maan@systemlinux.org>
Sun, 3 Jan 2010 02:00:46 +0000 (03:00 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 3 Jan 2010 02:00:46 +0000 (03:00 +0100)
aacdec_filter.c
buffer_tree.c
buffer_tree.h
filter.h
filter_common.c
mp3dec_filter.c
oggdec_filter.c
wmadec_filter.c

index 0b520da4fa134757d00fd23fd709083a95a44b22..f41fe8b1215800bbff616c3a2efdc87c0b8fa649 100644 (file)
@@ -235,29 +235,13 @@ static void aacdec_post_select(__a_unused struct sched *s, struct task *t)
 
 next_buffer:
        t->error = 0;
-       iqs = btr_get_input_queue_size(btrn);
-       if (iqs < 2048) {
-               if (!btr_no_parent(btrn)) /* wait for more data */
-                       return;
-       }
-       if (btr_bytes_pending(btrn) > AACDEC_MAX_PENDING)
-               return;
-       /* avoid "buffer too small" errors from the decoder */
-       for (;;) {
-               len = btr_next_buffer(btrn, (char **)&inbuf);
-               if (len >= 2048)
-                       break;
-               if (btr_merge(btrn) < 2) /* only one buffer left */
-                       break;
-       }
-       //PARA_CRIT_LOG("next buffer: %zu\n", len);
-       if (len == 0) {
-               if (btr_no_parent(btrn)) {
-                       ret = -E_AACDEC_EOF;
-                       goto err;
-               }
+       ret = prepare_filter_node(btrn, 2048);
+       if (ret < 0)
+               goto err;
+       if (ret == 0)
                return;
-       }
+       len = btr_next_buffer(btrn, (char **)&inbuf);
+       iqs = btr_get_input_queue_size(btrn);
        if (!padd->initialized) {
                unsigned long rate = 0;
                unsigned char channels = 0;
index 2c02c69466f19111241aa835dd2f919cf710ecc0..7e0ec2786c193ae3718664a6436ea611d0eceb06 100644 (file)
@@ -363,3 +363,11 @@ void btr_merge_to(struct btr_node *btrn, size_t dest_size)
                        return;
        }
 }
+
+bool btr_eof(struct btr_node *btrn)
+{
+       char *buf;
+       size_t len = btr_next_buffer(btrn, &buf);
+
+       return (len == 0 && btr_no_parent(btrn));
+}
index 4d3502d52ffd0e3493fbe7c9afa746c3a603d61b..094bfeac94501e46561944591c332f53d39bc53b 100644 (file)
@@ -21,3 +21,4 @@ void btr_pushdown(struct btr_node *btrn);
 void *btr_context(struct btr_node *btrn);
 int btr_merge(struct btr_node *btrn);
 void btr_merge_to(struct btr_node *btrn, size_t dest_size);
+bool btr_eof(struct btr_node *btrn);
index ab187df295b0c67024f5a5dcbf855ed49b06d6c4..ec8631f8a866823c69a32b6d8b5aafe834d38b22 100644 (file)
--- a/filter.h
+++ b/filter.h
@@ -204,6 +204,7 @@ void filter_init(void);
 int check_filter_arg(char *filter_arg, void **conf);
 void filter_post_select(__a_unused struct sched *s, struct task *t);
 void print_filter_helps(int detailed);
+int prepare_filter_node(struct btr_node *btrn, size_t min_len);
 
 static inline void write_int16_host_endian(char *buf, int val)
 {
index 94e553b6e6ae63270cc81fc602b0fd57f1eb67e3..bc5539d0b842a7f81a735a53918c565d4c785d02 100644 (file)
@@ -275,3 +275,23 @@ void print_filter_helps(int detailed)
        }
 
 }
+
+/** 640K ought to be enough for everybody ;) */
+#define FILTER_MAX_PENDING (640 * 1024)
+
+int prepare_filter_node(struct btr_node *btrn, size_t min_len)
+{
+       size_t iqs;
+
+       if (btr_eof(btrn))
+               return -E_FC_EOF;
+       if (btr_bytes_pending(btrn) > FILTER_MAX_PENDING)
+               return 0;
+       iqs = btr_get_input_queue_size(btrn);
+       if (iqs < min_len && !btr_no_parent(btrn))
+               return 0;
+       assert(iqs != 0);
+       /* avoid "buffer too small" errors from the decoder */
+       btr_merge_to(btrn, min_len);
+       return 1;
+}
index 9eed6393c53f58b9bd8fa7e295a14553b7b4f6af..dfec0c4c133591c81c8be1cece951a0ea2a8b48f 100644 (file)
@@ -207,23 +207,21 @@ static void mp3dec_post_select(__a_unused struct sched *s, struct task *t)
        int i, ret;
        struct private_mp3dec_data *pmd = fn->private_data;
        struct btr_node *btrn = fn->btrn;
-       size_t loaded, used, len = btr_get_input_queue_size(btrn);
+       size_t loaded, used, len, iqs;
        char *inbuffer, *outbuffer;
 
+next_buffer:
        pmd->stream.error = 0;
        t->error = 0;
-       if (btr_bytes_pending(btrn) > MP3DEC_MAX_PENDING)
-               return;
-       if (need_bad_data_delay(pmd, len))
+       iqs = btr_get_input_queue_size(btrn);
+       if (need_bad_data_delay(pmd, iqs))
                return;
-       if (len <= pmd->input_len_barrier && btr_no_parent(btrn)) {
-               ret = -E_MP3DEC_EOF;
+       ret = prepare_filter_node(btrn, pmd->input_len_barrier);
+       if (ret < 0)
                goto err;
-       }
-next_buffer:
-       len = btr_next_buffer(btrn, &inbuffer);
-       if (len == 0)
+       if (ret == 0)
                return;
+       len = btr_next_buffer(btrn, &inbuffer);
        mad_stream_buffer(&pmd->stream, (unsigned char *)inbuffer, len);
 next_frame:
        ret = mad_header_decode(&pmd->frame.header, &pmd->stream);
@@ -231,10 +229,12 @@ next_frame:
                used = used_mad_buffer_bytes(&pmd->stream, len);
                btr_consume(btrn, used);
                if (pmd->stream.error == MAD_ERROR_BUFLEN) {
-                       pmd->input_len_barrier = len - used;
-                       ret = btr_merge(btrn);
-                       if (ret != 2)
-                               return;
+                       if (len == iqs && btr_no_parent(btrn)) {
+                               ret = -E_MP3DEC_EOF;
+                               goto err;
+                       }
+                       pmd->input_len_barrier += 100;
+                       goto next_buffer;
                } else if (pmd->stream.error != MAD_ERROR_LOSTSYNC)
                        PARA_DEBUG_LOG("header decode: %s\n",
                                mad_stream_errorstr(&pmd->stream));
index fc03077bf4fc65505affd7db301f0b3dae4fd67c..f968bf142b2af5afc822c69a9c6ea36469f5a9d5 100644 (file)
@@ -43,6 +43,7 @@ struct private_oggdec_data {
        unsigned int channels;
        /** Current sample rate in Hz. */
        unsigned int samplerate;
+       size_t min_iqs;
 };
 
 static size_t cb_read_nobtr(void *buf, size_t size, size_t nmemb, void *datasource)
@@ -202,12 +203,19 @@ static void ogg_post_select(__a_unused struct sched *s, struct task *t)
        struct filter_node *fn = container_of(t, struct filter_node, task);
        struct private_oggdec_data *pod = fn->private_data;
        struct btr_node *btrn = fn->btrn;
-       size_t iqs = btr_get_input_queue_size(btrn);
+       size_t iqs, len;
        int ret;
+       char *in;
 
        t->error = 0;
-       if (!pod->vf && iqs) {
-               struct oggdec_filter_args_info *conf = fn->conf;
+       ret = prepare_filter_node(btrn, pod->min_iqs);
+       if (ret < 0)
+               goto err;
+       if (ret == 0)
+               return;
+       len = btr_next_buffer(btrn, &in);
+       iqs = btr_get_input_queue_size(btrn);
+       if (!pod->vf) {
                int oret;
 
                pod->vf = para_malloc(sizeof(struct OggVorbis_File));
@@ -218,10 +226,10 @@ static void ogg_post_select(__a_unused struct sched *s, struct task *t)
                        ovc); /* the ov_open_callbacks */
                if (oret == OV_ENOTVORBIS || oret == OV_EBADHEADER) {
                        /* this might be due to the input buffer being too small */
-                       int ib = 1024 * conf->initial_buffer_arg; /* initial buffer */
-                       if (iqs < ib) {
+                       if (!btr_no_parent(btrn)) {
                                free(pod->vf);
                                pod->vf = NULL;
+                               pod->min_iqs = iqs + 1;
                                return;
                        }
                        ret = (oret == OV_ENOTVORBIS)?
index 4bbc24137e7e64f0af2246b515417cc3e6665c5c..7681a762115317f0c6c01c7a7759734110c07ed4 100644 (file)
@@ -1249,25 +1249,21 @@ static void wmadec_post_select(__a_unused struct sched *s, struct task *t)
        int ret, converted = 0;
        struct private_wmadec_data *pwd = fn->private_data;
        struct btr_node *btrn = fn->btrn;
-       size_t iqs, len, min_len;
+       size_t len, min_len;
        char *in;
 
        min_len = pwd? WMA_FRAME_SKIP + pwd->ahi.block_align : 8192;
 next_buffer:
        t->error = 0;
-       if (btr_bytes_pending(btrn) > WMADEC_MAX_PENDING)
+       ret = prepare_filter_node(btrn, min_len);
+       if (ret < 0)
+               goto err;
+       if (ret == 0)
                return;
-       iqs = btr_get_input_queue_size(btrn);
-       if (iqs < min_len) {
-               if (!btr_no_parent(btrn)) /* wait for more data */
-                       return;
-               ret = -E_WMADEC_EOF;
+       len = btr_next_buffer(btrn, (char **)&in);
+       ret = -E_WMADEC_EOF;
+       if (len < min_len)
                goto err;
-       }
-       /* avoid "buffer too small" errors from the decoder */
-       btr_merge_to(btrn, min_len);
-       len = btr_next_buffer(btrn, &in);
-       assert(len >= min_len);
        if (!pwd) {
                ret = wma_decode_init(in, len, &pwd);
                if (ret < 0)