[FFmpeg-devel,3/4] opus: Add Special Hybrid Folding (per RFC8251)

Submitted by Andrew D'Addesio on Dec. 2, 2017, 5:46 p.m.

Details

Message ID 20171202174659.1064-3-modchipv12@gmail.com
State New
Headers show

Commit Message

Andrew D'Addesio Dec. 2, 2017, 5:46 p.m.
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>
---
 libavcodec/opus_celt.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

Comments

Michael Niedermayer Dec. 3, 2017, 2:17 a.m.
On Sat, Dec 02, 2017 at 11:46:58AM -0600, Andrew D'Addesio wrote:
> 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>
> ---
>  libavcodec/opus_celt.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)

this is missing fate updates:
TEST    opus-testvector05
TEST    opus-testvector06
stddev:  117.55 PSNR: 54.92 MAXDIFF: 3275 bytes:  4803840/  4803840
stddev: |117.55 - 106| >= 3
Test opus-testvector06 failed. Look at tests/data/fate/opus-testvector06.err for details.
make: *** [fate-opus-testvector06] Error 1
make: *** Waiting for unfinished jobs....
stddev:  111.41 PSNR: 55.39 MAXDIFF: 2630 bytes:  5216640/  5216640
stddev: |111.41 - 108| >= 3
Test opus-testvector05 failed. Look at tests/data/fate/opus-testvector05.err for details.
make: *** [fate-opus-testvector05] Error 1

[...]
Rostislav Pehlivanov Dec. 4, 2017, 7:38 a.m.
On 2 December 2017 at 17:46, Andrew D'Addesio <modchipv12@gmail.com> wrote:

> 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>
> ---
>  libavcodec/opus_celt.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
> index ff56041..2bbb96b 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++) {
> --
> 2.15.1.windows.2
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

Pushed, updated fate stddev scores, new decoded samples should be uploaded
to fate soon too.
James Almer Dec. 6, 2017, 7:42 p.m.
On 12/2/2017 2:46 PM, Andrew D'Addesio wrote:
> 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>
> ---
>  libavcodec/opus_celt.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
> index ff56041..2bbb96b 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++) {

Valgrind apparently complains about this commit, as i mentioned in
another reply to this thread (I wrongly thought it had been the one by
Rostislav at first).

http://fate.ffmpeg.org/history.cgi?slot=x86_64-archlinux-gcc-valgrind

Tests fate-opus-testvector05 and fate-opus-testvector06 if you configure
ffmpeg with --valgrind=valgrind --disable-stripping --disable-optimizations.

Patch hide | download patch | download mbox

diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
index ff56041..2bbb96b 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++) {