From 428a77d6bddab3ea10e31de4b054430c137c8117 Mon Sep 17 00:00:00 2001
From: "Timothy B. Terriberry"
Date: Thu, 16 Dec 2010 16:50:16 -0800
Subject: [PATCH 1/1] More cleanups to compute_allocation().
The bisection search in compute_allocation() was not using the same
method to count psum as interp_bits2pulses, i.e., it did not
include the 64*C< 0)
bits1[j] += trim_offset[j];
step was not also done for bits2, so bits1[j] + bits2[j] would not
be equal to what was computed earlier for the hi line, and would
not be guaranteed to be larger than total.
We now compute both allocation lines in the same manner, and then
obtain bits2 by subtracting them, instead of trying to compute the
offset from bits1 up front.
Finally, there was nothing to stop a bitstream from boosting a band
beyond the number of bits remaining, which means that bits1 would
not produce an allocation less than or equal to total, which means
that some bands would receive a negative allocation in the decoder
when the "left over" negative bits were redistributed to other
bands.
This patch only adds the dynalloc offset to allocation lines greater
than 0, so that an all-zeros floor still exists; the effect is that
a dynalloc boost gets linearly scaled between allocation lines 0 and
1, and is constant (like it was before) after that.
We don't have to add the extra condition to the bisection search,
because it never examines allocation line 0.
This re-writes the indexing in the search to make that explicit;
it was tested and gives exactly the same results in exactly the
same number of iterations as the old search.
---
libcelt/rate.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/libcelt/rate.c b/libcelt/rate.c
index c711fb4f..ba9b8cf0 100644
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -395,9 +395,9 @@ int compute_allocation(const CELTMode *m, int start, int end, const int *offsets
trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1)
<<(LM+BITRES)>>6;
- lo = 0;
- hi = m->nbAllocVectors - 1;
- while (hi-lo != 1)
+ lo = 1;
+ hi = m->nbAllocVectors - 2;
+ do
{
int psum = 0;
int mid = (lo+hi) >> 1;
@@ -406,12 +406,10 @@ int compute_allocation(const CELTMode *m, int start, int end, const int *offsets
int N = m->eBands[j+1]-m->eBands[j];
bits1[j] = C*N*m->allocVectors[mid*len+j]<>2;
if (bits1[j] > 0)
- bits1[j] += trim_offset[j];
- if (bits1[j] < 0)
- bits1[j] = 0;
+ bits1[j] = IMAX(0, bits1[j] + trim_offset[j]);
bits1[j] += offsets[j];
if (bits1[j] >= thresh[j])
- psum += bits1[j];
+ psum += IMIN(bits1[j], 64*C<= C< total)
- hi = mid;
+ hi = mid - 1;
else
- lo = mid;
+ lo = mid + 1;
/*printf ("lo = %d, hi = %d\n", lo, hi);*/
}
+ while (lo <= hi);
+ hi = lo--;
/*printf ("interp between %d and %d\n", lo, hi);*/
for (j=start;jeBands[j+1]-m->eBands[j];
- bits1[j] = (C*N*m->allocVectors[lo*len+j]<>2);
- bits2[j] = (C*N*m->allocVectors[hi*len+j]<>2) - bits1[j];
+ bits1[j] = C*N*m->allocVectors[lo*len+j]<>2;
+ bits2[j] = C*N*m->allocVectors[hi*len+j]<>2;
if (bits1[j] > 0)
- bits1[j] += trim_offset[j];
- if (bits1[j] < 0)
- bits1[j] = 0;
- bits1[j] += offsets[j];
+ bits1[j] = IMAX(0, bits1[j] + trim_offset[j]);
+ if (bits2[j] > 0)
+ bits2[j] = IMAX(0, bits2[j] + trim_offset[j]);
+ if (lo > 0)
+ bits1[j] += offsets[j];
+ bits2[j] += offsets[j];
if (offsets[j]>0)
skip_start = j;
+ bits2[j] -= bits1[j];
}
codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh,
total, skip_rsv, pulses, ebits, fine_priority, len, C, LM, ec, encode, prev);
--
2.11.0