btr: Fix a nasty thinko in merge_input_pool().
authorAndre Noll <maan@systemlinux.org>
Tue, 2 Mar 2010 06:10:00 +0000 (07:10 +0100)
committerAndre Noll <maan@systemlinux.org>
Tue, 2 Mar 2010 06:10:00 +0000 (07:10 +0100)
We must take into account the number of bytes already consumed from the wrap buffer.
Otherwise, we might end up not merging as much as we must,  which may cause errors
in the child nodes.

This bug was quite hard to hit, but it did bite the aac decoder reliably when used in audiod
with UDP + FEC.

buffer_tree.c

index 9be53201f76c9400a320688cde6540c4ca227d05..907bd812617900edfa9fb0882b7c3512d79b85e7 100644 (file)
@@ -854,7 +854,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size)
        struct btr_buffer_reference *br, *wbr = NULL;
        int num_refs; /* including wrap buffer */
        char *buf, *buf1 = NULL, *buf2 = NULL;
        struct btr_buffer_reference *br, *wbr = NULL;
        int num_refs; /* including wrap buffer */
        char *buf, *buf1 = NULL, *buf2 = NULL;
-       size_t sz, sz1 = 0, sz2 = 0;
+       size_t sz, sz1 = 0, sz2 = 0, wb_consumed = 0;
 
        br = get_first_input_br(btrn);
        if (!br || br_available_bytes(br) >= dest_size)
 
        br = get_first_input_br(btrn);
        if (!br || br_available_bytes(br) >= dest_size)
@@ -871,6 +871,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size)
                        wbr = br;
                        if (sz >= dest_size)
                                return;
                        wbr = br;
                        if (sz >= dest_size)
                                return;
+                       wb_consumed = br->consumed;
                        continue;
                }
                if (!buf1) {
                        continue;
                }
                if (!buf1) {
@@ -890,7 +891,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size)
                assert(buf2 + sz2 == buf);
                sz2 += sz;
 next:
                assert(buf2 + sz2 == buf);
                sz2 += sz;
 next:
-               if (sz1 + sz2 >= dest_size)
+               if (sz1 + sz2 >= dest_size + wb_consumed)
                        break;
        }
        if (!buf2) /* nothing to do */
                        break;
        }
        if (!buf2) /* nothing to do */