summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew D'Addesio <modchipv12@gmail.com>2017-12-02 11:46:58 -0600
committerRostislav Pehlivanov <atomnuker@gmail.com>2017-12-04 07:28:45 +0000
commitfe05f93013c4a3616926fa9370be2d9c93a94659 (patch)
tree4b16d3bea38b53a1e9fc28942809ff478dc01074
parentde052ea454e06f2c1aab4e06cca0012cf80f2630 (diff)
downloadffmpeg-fe05f93013c4a3616926fa9370be2d9c93a94659.tar.gz
opus: Add Special Hybrid Folding (per RFC8251)
This decoder-side change, introduced in RFC 8251 (section 9), slightly improves the decoded quality of 16kbps speech in Hybrid Mode. Differences can be seen/heard in testvector05.bit, testvector06.bit, and testvector12.bit in the RFC 6716/8251 testvectors found here: https://people.xiph.org/~greg/opus_testvectors/ Signed-off-by: Andrew D'Addesio <modchipv12@gmail.com>
-rw-r--r--libavcodec/opus_celt.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
index ff56041ea6..2bbb96bded 100644
--- a/libavcodec/opus_celt.c
+++ b/libavcodec/opus_celt.c
@@ -712,10 +712,22 @@ static void celt_decode_bands(CeltFrame *f, OpusRangeCoder *rc)
b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14);
}
- if (ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] &&
- (update_lowband || lowband_offset == 0))
+ if ((ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] ||
+ i == f->start_band + 1) && (update_lowband || lowband_offset == 0))
lowband_offset = i;
+ if (i == f->start_band + 1) {
+ /* Special Hybrid Folding (RFC 8251 section 9). Copy the first band into
+ the second to ensure the second band never has to use the LCG. */
+ int offset = 8 * ff_celt_freq_bands[i];
+ int count = 8 * (ff_celt_freq_range[i] - ff_celt_freq_range[i-1]);
+
+ memcpy(&norm[offset], &norm[offset - count], count * sizeof(float));
+
+ if (f->channels == 2)
+ memcpy(&norm2[offset], &norm2[offset - count], count * sizeof(float));
+ }
+
/* Get a conservative estimate of the collapse_mask's for the bands we're
going to be folding from. */
if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE ||
@@ -728,7 +740,7 @@ static void celt_decode_bands(CeltFrame *f, OpusRangeCoder *rc)
foldstart = lowband_offset;
while (ff_celt_freq_bands[--foldstart] > effective_lowband);
foldend = lowband_offset - 1;
- while (ff_celt_freq_bands[++foldend] < effective_lowband + ff_celt_freq_range[i]);
+ while (++foldend < i && ff_celt_freq_bands[foldend] < effective_lowband + ff_celt_freq_range[i]);
cm[0] = cm[1] = 0;
for (j = foldstart; j < foldend; j++) {