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 9be5320..907bd81 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;
-       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)
@@ -871,6 +871,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size)
                        wbr = br;
                        if (sz >= dest_size)
                                return;
+                       wb_consumed = br->consumed;
                        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:
-               if (sz1 + sz2 >= dest_size)
+               if (sz1 + sz2 >= dest_size + wb_consumed)
                        break;
        }
        if (!buf2) /* nothing to do */