[FFmpeg-devel] [PATCH 5/6] opus_celt: rename structures to better names and reorganize them

Rostislav Pehlivanov atomnuker at gmail.com
Wed Feb 1 05:13:08 EET 2017


This is meant to be applied on top of my previous patch which
split PVQ into celt_pvq.c and made opus_celt.h

Essentially nothing has been changed other than renaming CeltFrame
to CeltBlock (CeltFrame had absolutely nothing at all to do with
a frame) and CeltContext to CeltFrame.
3 variables have been put in CeltFrame as they make more sense
there rather than being passed around as arguments.
The coefficients have been moved to the CeltBlock structure
(why the hell were they in CeltContext and not in CeltFrame??).

Now the encoder would be able to use the exact context the decoder
uses (plus a couple of extra fields in there).

FATE passes, no slowdowns, etc.

Signed-off-by: Rostislav Pehlivanov <atomnuker at gmail.com>
---
 libavcodec/opus.h      |  22 +-
 libavcodec/opus_celt.c | 722 ++++++++++++++++++++++++-------------------------
 libavcodec/opus_celt.h |  91 ++++---
 libavcodec/opus_pvq.c  |  50 ++--
 libavcodec/opus_pvq.h  |   2 +-
 libavcodec/opusdec.c   |   7 +-
 libavcodec/opustab.c   |   4 +
 libavcodec/opustab.h   |   4 +
 8 files changed, 459 insertions(+), 443 deletions(-)

diff --git a/libavcodec/opus.h b/libavcodec/opus.h
index be042497ea..c3cbaec35d 100644
--- a/libavcodec/opus.h
+++ b/libavcodec/opus.h
@@ -62,7 +62,9 @@ static const uint8_t opus_default_extradata[30] = {
 enum OpusMode {
     OPUS_MODE_SILK,
     OPUS_MODE_HYBRID,
-    OPUS_MODE_CELT
+    OPUS_MODE_CELT,
+
+    OPUS_MODE_NB
 };
 
 enum OpusBandwidth {
@@ -70,12 +72,14 @@ enum OpusBandwidth {
     OPUS_BANDWIDTH_MEDIUMBAND,
     OPUS_BANDWIDTH_WIDEBAND,
     OPUS_BANDWIDTH_SUPERWIDEBAND,
-    OPUS_BANDWIDTH_FULLBAND
+    OPUS_BANDWIDTH_FULLBAND,
+
+    OPUS_BANDWITH_NB
 };
 
 typedef struct SilkContext SilkContext;
 
-typedef struct CeltContext CeltContext;
+typedef struct CeltFrame CeltFrame;
 
 typedef struct OpusPacket {
     int packet_size;                /**< packet size */
@@ -100,7 +104,7 @@ typedef struct OpusStreamContext {
     OpusRangeCoder rc;
     OpusRangeCoder redundancy_rc;
     SilkContext *silk;
-    CeltContext *celt;
+    CeltFrame *celt;
     AVFloatDSPContext *fdsp;
 
     float silk_buf[2][960];
@@ -185,14 +189,4 @@ int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
                               enum OpusBandwidth bandwidth, int coded_channels,
                               int duration_ms);
 
-int ff_celt_init(AVCodecContext *avctx, CeltContext **s, int output_channels);
-
-void ff_celt_free(CeltContext **s);
-
-void ff_celt_flush(CeltContext *s);
-
-int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc,
-                         float **output, int coded_channels, int frame_size,
-                         int startband,  int endband);
-
 #endif /* AVCODEC_OPUS_H */
diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
index 71ef8965e2..af3c100e6e 100644
--- a/libavcodec/opus_celt.c
+++ b/libavcodec/opus_celt.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2012 Andrew D'Addesio
  * Copyright (c) 2013-2014 Mozilla Corporation
+ * Copyright (c) 2016 Rostislav Pehlivanov <atomnuker at gmail.com>
  *
  * This file is part of FFmpeg.
  *
@@ -28,7 +29,7 @@
 #include "opustab.h"
 #include "opus_pvq.h"
 
-static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc)
+static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
 {
     int i, j;
     float prev[2] = {0};
@@ -38,29 +39,29 @@ static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc)
     /* use the 2D z-transform to apply prediction in both */
     /* the time domain (alpha) and the frequency domain (beta) */
 
-    if (opus_rc_tell(rc)+3 <= s->framebits && ff_opus_rc_dec_log(rc, 3)) {
+    if (opus_rc_tell(rc)+3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
         /* intra frame */
         alpha = 0;
         beta  = 1.0f - 4915.0f/32768.0f;
-        model = ff_celt_coarse_energy_dist[s->duration][1];
+        model = ff_celt_coarse_energy_dist[f->size][1];
     } else {
-        alpha = ff_celt_alpha_coef[s->duration];
-        beta  = 1.0f - ff_celt_beta_coef[s->duration];
-        model = ff_celt_coarse_energy_dist[s->duration][0];
+        alpha = ff_celt_alpha_coef[f->size];
+        beta  = 1.0f - ff_celt_beta_coef[f->size];
+        model = ff_celt_coarse_energy_dist[f->size][0];
     }
 
     for (i = 0; i < CELT_MAX_BANDS; i++) {
-        for (j = 0; j < s->coded_channels; j++) {
-            CeltFrame *frame = &s->frame[j];
+        for (j = 0; j < f->channels; j++) {
+            CeltBlock *block = &f->block[j];
             float value;
             int available;
 
-            if (i < s->startband || i >= s->endband) {
-                frame->energy[i] = 0.0;
+            if (i < f->start_band || i >= f->end_band) {
+                block->energy[i] = 0.0;
                 continue;
             }
 
-            available = s->framebits - opus_rc_tell(rc);
+            available = f->framebits - opus_rc_tell(rc);
             if (available >= 15) {
                 /* decode using a Laplace distribution */
                 int k = FFMIN(i, 20) << 1;
@@ -72,82 +73,81 @@ static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc)
                 value = -(float)ff_opus_rc_dec_log(rc, 1);
             } else value = -1;
 
-            frame->energy[i] = FFMAX(-9.0f, frame->energy[i]) * alpha + prev[j] + value;
+            block->energy[i] = FFMAX(-9.0f, block->energy[i]) * alpha + prev[j] + value;
             prev[j] += beta * value;
         }
     }
 }
 
-static void celt_decode_fine_energy(CeltContext *s, OpusRangeCoder *rc)
+static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc)
 {
     int i;
-    for (i = s->startband; i < s->endband; i++) {
+    for (i = f->start_band; i < f->end_band; i++) {
         int j;
-        if (!s->fine_bits[i])
+        if (!f->fine_bits[i])
             continue;
 
-        for (j = 0; j < s->coded_channels; j++) {
-            CeltFrame *frame = &s->frame[j];
+        for (j = 0; j < f->channels; j++) {
+            CeltBlock *block = &f->block[j];
             int q2;
             float offset;
-            q2 = ff_opus_rc_get_raw(rc, s->fine_bits[i]);
-            offset = (q2 + 0.5f) * (1 << (14 - s->fine_bits[i])) / 16384.0f - 0.5f;
-            frame->energy[i] += offset;
+            q2 = ff_opus_rc_get_raw(rc, f->fine_bits[i]);
+            offset = (q2 + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f - 0.5f;
+            block->energy[i] += offset;
         }
     }
 }
 
-static void celt_decode_final_energy(CeltContext *s, OpusRangeCoder *rc,
-                                     int bits_left)
+static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc)
 {
     int priority, i, j;
+    int bits_left = f->framebits - opus_rc_tell(rc);
 
     for (priority = 0; priority < 2; priority++) {
-        for (i = s->startband; i < s->endband && bits_left >= s->coded_channels; i++) {
-            if (s->fine_priority[i] != priority || s->fine_bits[i] >= CELT_MAX_FINE_BITS)
+        for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) {
+            if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
                 continue;
 
-            for (j = 0; j < s->coded_channels; j++) {
+            for (j = 0; j < f->channels; j++) {
                 int q2;
                 float offset;
                 q2 = ff_opus_rc_get_raw(rc, 1);
-                offset = (q2 - 0.5f) * (1 << (14 - s->fine_bits[i] - 1)) / 16384.0f;
-                s->frame[j].energy[i] += offset;
+                offset = (q2 - 0.5f) * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f;
+                f->block[j].energy[i] += offset;
                 bits_left--;
             }
         }
     }
 }
 
-static void celt_decode_tf_changes(CeltContext *s, OpusRangeCoder *rc,
-                                   int transient)
+static void celt_decode_tf_changes(CeltFrame *f, OpusRangeCoder *rc)
 {
     int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit;
-    int consumed, bits = transient ? 2 : 4;
+    int consumed, bits = f->transient ? 2 : 4;
 
     consumed = opus_rc_tell(rc);
-    tf_select_bit = (s->duration != 0 && consumed+bits+1 <= s->framebits);
+    tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits);
 
-    for (i = s->startband; i < s->endband; i++) {
-        if (consumed+bits+tf_select_bit <= s->framebits) {
+    for (i = f->start_band; i < f->end_band; i++) {
+        if (consumed+bits+tf_select_bit <= f->framebits) {
             diff ^= ff_opus_rc_dec_log(rc, bits);
             consumed = opus_rc_tell(rc);
             tf_changed |= diff;
         }
-        s->tf_change[i] = diff;
-        bits = transient ? 4 : 5;
+        f->tf_change[i] = diff;
+        bits = f->transient ? 4 : 5;
     }
 
-    if (tf_select_bit && ff_celt_tf_select[s->duration][transient][0][tf_changed] !=
-                         ff_celt_tf_select[s->duration][transient][1][tf_changed])
+    if (tf_select_bit && ff_celt_tf_select[f->size][f->transient][0][tf_changed] !=
+                         ff_celt_tf_select[f->size][f->transient][1][tf_changed])
         tf_select = ff_opus_rc_dec_log(rc, 1);
 
-    for (i = s->startband; i < s->endband; i++) {
-        s->tf_change[i] = ff_celt_tf_select[s->duration][transient][tf_select][s->tf_change[i]];
+    for (i = f->start_band; i < f->end_band; i++) {
+        f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
     }
 }
 
-static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
+static void celt_decode_allocation(CeltFrame *f, OpusRangeCoder *rc)
 {
     // approx. maximum bit allocation for each band before boost/trim
     int cap[CELT_MAX_BANDS];
@@ -157,14 +157,14 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
     int bits2[CELT_MAX_BANDS];
     int trim_offset[CELT_MAX_BANDS];
 
-    int skip_startband = s->startband;
+    int skip_start_band = f->start_band;
     int dynalloc       = 6;
     int alloctrim      = 5;
     int extrabits      = 0;
 
-    int skip_bit            = 0;
-    int intensitystereo_bit = 0;
-    int dualstereo_bit      = 0;
+    int skip_bit             = 0;
+    int intensity_stereo_bit = 0;
+    int dual_stereo_bit      = 0;
 
     int remaining, bandbits;
     int low, high, total, done;
@@ -175,25 +175,25 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
     consumed = opus_rc_tell(rc);
 
     /* obtain spread flag */
-    s->spread = CELT_SPREAD_NORMAL;
-    if (consumed + 4 <= s->framebits)
-        s->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread);
+    f->spread = CELT_SPREAD_NORMAL;
+    if (consumed + 4 <= f->framebits)
+        f->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread);
 
     /* generate static allocation caps */
     for (i = 0; i < CELT_MAX_BANDS; i++) {
-        cap[i] = (ff_celt_static_caps[s->duration][s->coded_channels - 1][i] + 64)
-                 * ff_celt_freq_range[i] << (s->coded_channels - 1) << s->duration >> 2;
+        cap[i] = (ff_celt_static_caps[f->size][f->channels - 1][i] + 64)
+                 * ff_celt_freq_range[i] << (f->channels - 1) << f->size >> 2;
     }
 
     /* obtain band boost */
-    totalbits = s->framebits << 3; // convert to 1/8 bits
+    totalbits = f->framebits << 3; // convert to 1/8 bits
     consumed = opus_rc_tell_frac(rc);
-    for (i = s->startband; i < s->endband; i++) {
+    for (i = f->start_band; i < f->end_band; i++) {
         int quanta, band_dynalloc;
 
         boost[i] = 0;
 
-        quanta = ff_celt_freq_range[i] << (s->coded_channels - 1) << s->duration;
+        quanta = ff_celt_freq_range[i] << (f->channels - 1) << f->size;
         quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta));
         band_dynalloc = dynalloc;
         while (consumed + (band_dynalloc<<3) < totalbits && boost[i] < cap[i]) {
@@ -216,12 +216,12 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
         alloctrim = ff_opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);
 
     /* anti-collapse bit reservation */
-    totalbits = (s->framebits << 3) - opus_rc_tell_frac(rc) - 1;
-    s->anticollapse_bit = 0;
-    if (s->blocks > 1 && s->duration >= 2 &&
-        totalbits >= ((s->duration + 2) << 3))
-        s->anticollapse_bit = 1 << 3;
-    totalbits -= s->anticollapse_bit;
+    totalbits = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1;
+    f->anticollapse_needed = 0;
+    if (f->blocks > 1 && f->size >= 2 &&
+        totalbits >= ((f->size + 2) << 3))
+        f->anticollapse_needed = 1 << 3;
+    totalbits -= f->anticollapse_needed;
 
     /* band skip bit reservation */
     if (totalbits >= 1 << 3)
@@ -229,33 +229,33 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
     totalbits -= skip_bit;
 
     /* intensity/dual stereo bit reservation */
-    if (s->coded_channels == 2) {
-        intensitystereo_bit = ff_celt_log2_frac[s->endband - s->startband];
-        if (intensitystereo_bit <= totalbits) {
-            totalbits -= intensitystereo_bit;
+    if (f->channels == 2) {
+        intensity_stereo_bit = ff_celt_log2_frac[f->end_band - f->start_band];
+        if (intensity_stereo_bit <= totalbits) {
+            totalbits -= intensity_stereo_bit;
             if (totalbits >= 1 << 3) {
-                dualstereo_bit = 1 << 3;
+                dual_stereo_bit = 1 << 3;
                 totalbits -= 1 << 3;
             }
         } else
-            intensitystereo_bit = 0;
+            intensity_stereo_bit = 0;
     }
 
-    for (i = s->startband; i < s->endband; i++) {
-        int trim     = alloctrim - 5 - s->duration;
-        int band     = ff_celt_freq_range[i] * (s->endband - i - 1);
-        int duration = s->duration + 3;
-        int scale    = duration + s->coded_channels - 1;
+    for (i = f->start_band; i < f->end_band; i++) {
+        int trim     = alloctrim - 5 - f->size;
+        int band     = ff_celt_freq_range[i] * (f->end_band - i - 1);
+        int duration = f->size + 3;
+        int scale    = duration + f->channels - 1;
 
         /* PVQ minimum allocation threshold, below this value the band is
          * skipped */
         threshold[i] = FFMAX(3 * ff_celt_freq_range[i] << duration >> 4,
-                             s->coded_channels << 3);
+                             f->channels << 3);
 
         trim_offset[i] = trim * (band << scale) >> 6;
 
-        if (ff_celt_freq_range[i] << s->duration == 1)
-            trim_offset[i] -= s->coded_channels << 3;
+        if (ff_celt_freq_range[i] << f->size == 1)
+            trim_offset[i] -= f->channels << 3;
     }
 
     /* bisection */
@@ -265,9 +265,9 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
         int center = (low + high) >> 1;
         done = total = 0;
 
-        for (i = s->endband - 1; i >= s->startband; i--) {
+        for (i = f->end_band - 1; i >= f->start_band; i--) {
             bandbits = ff_celt_freq_range[i] * ff_celt_static_alloc[center][i]
-                       << (s->coded_channels - 1) << s->duration >> 2;
+                       << (f->channels - 1) << f->size >> 2;
 
             if (bandbits)
                 bandbits = FFMAX(0, bandbits + trim_offset[i]);
@@ -276,8 +276,8 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
             if (bandbits >= threshold[i] || done) {
                 done = 1;
                 total += FFMIN(bandbits, cap[i]);
-            } else if (bandbits >= s->coded_channels << 3)
-                total += s->coded_channels << 3;
+            } else if (bandbits >= f->channels << 3)
+                total += f->channels << 3;
         }
 
         if (total > totalbits)
@@ -287,12 +287,12 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
     }
     high = low--;
 
-    for (i = s->startband; i < s->endband; i++) {
+    for (i = f->start_band; i < f->end_band; i++) {
         bits1[i] = ff_celt_freq_range[i] * ff_celt_static_alloc[low][i]
-                   << (s->coded_channels - 1) << s->duration >> 2;
+                   << (f->channels - 1) << f->size >> 2;
         bits2[i] = high >= CELT_VECTORS ? cap[i] :
                    ff_celt_freq_range[i] * ff_celt_static_alloc[high][i]
-                   << (s->coded_channels - 1) << s->duration >> 2;
+                   << (f->channels - 1) << f->size >> 2;
 
         if (bits1[i])
             bits1[i] = FFMAX(0, bits1[i] + trim_offset[i]);
@@ -303,7 +303,7 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
         bits2[i] += boost[i];
 
         if (boost[i])
-            skip_startband = i;
+            skip_start_band = i;
         bits2[i] = FFMAX(0, bits2[i] - bits1[i]);
     }
 
@@ -314,14 +314,14 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
         int center = (low + high) >> 1;
         done = total = 0;
 
-        for (j = s->endband - 1; j >= s->startband; j--) {
+        for (j = f->end_band - 1; j >= f->start_band; j--) {
             bandbits = bits1[j] + (center * bits2[j] >> CELT_ALLOC_STEPS);
 
             if (bandbits >= threshold[j] || done) {
                 done = 1;
                 total += FFMIN(bandbits, cap[j]);
-            } else if (bandbits >= s->coded_channels << 3)
-                total += s->coded_channels << 3;
+            } else if (bandbits >= f->channels << 3)
+                total += f->channels << 3;
         }
         if (total > totalbits)
             high = center;
@@ -330,26 +330,26 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
     }
 
     done = total = 0;
-    for (i = s->endband - 1; i >= s->startband; i--) {
+    for (i = f->end_band - 1; i >= f->start_band; i--) {
         bandbits = bits1[i] + (low * bits2[i] >> CELT_ALLOC_STEPS);
 
         if (bandbits >= threshold[i] || done)
             done = 1;
         else
-            bandbits = (bandbits >= s->coded_channels << 3) ?
-                       s->coded_channels << 3 : 0;
+            bandbits = (bandbits >= f->channels << 3) ?
+                       f->channels << 3 : 0;
 
         bandbits     = FFMIN(bandbits, cap[i]);
-        s->pulses[i] = bandbits;
+        f->pulses[i] = bandbits;
         total      += bandbits;
     }
 
     /* band skipping */
-    for (s->codedbands = s->endband; ; s->codedbands--) {
+    for (f->coded_bands = f->end_band; ; f->coded_bands--) {
         int allocation;
-        j = s->codedbands - 1;
+        j = f->coded_bands - 1;
 
-        if (j == skip_startband) {
+        if (j == skip_start_band) {
             /* all remaining bands are not skipped */
             totalbits += skip_bit;
             break;
@@ -357,14 +357,14 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
 
         /* determine the number of bits available for coding "do not skip" markers */
         remaining   = totalbits - total;
-        bandbits    = remaining / (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[s->startband]);
-        remaining  -= bandbits  * (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[s->startband]);
-        allocation  = s->pulses[j] + bandbits * ff_celt_freq_range[j]
-                      + FFMAX(0, remaining - (ff_celt_freq_bands[j] - ff_celt_freq_bands[s->startband]));
+        bandbits    = remaining / (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
+        remaining  -= bandbits  * (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
+        allocation  = f->pulses[j] + bandbits * ff_celt_freq_range[j]
+                      + FFMAX(0, remaining - (ff_celt_freq_bands[j] - ff_celt_freq_bands[f->start_band]));
 
         /* a "do not skip" marker is only coded if the allocation is
            above the chosen threshold */
-        if (allocation >= FFMAX(threshold[j], (s->coded_channels + 1) <<3 )) {
+        if (allocation >= FFMAX(threshold[j], (f->channels + 1) <<3 )) {
             if (ff_opus_rc_dec_log(rc, 1))
                 break;
 
@@ -373,43 +373,43 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
         }
 
         /* the band is skipped, so reclaim its bits */
-        total -= s->pulses[j];
-        if (intensitystereo_bit) {
-            total -= intensitystereo_bit;
-            intensitystereo_bit = ff_celt_log2_frac[j - s->startband];
-            total += intensitystereo_bit;
+        total -= f->pulses[j];
+        if (intensity_stereo_bit) {
+            total -= intensity_stereo_bit;
+            intensity_stereo_bit = ff_celt_log2_frac[j - f->start_band];
+            total += intensity_stereo_bit;
         }
 
-        total += s->pulses[j] = (allocation >= s->coded_channels << 3) ?
-                              s->coded_channels << 3 : 0;
+        total += f->pulses[j] = (allocation >= f->channels << 3) ?
+                              f->channels << 3 : 0;
     }
 
     /* obtain stereo flags */
-    s->intensitystereo = 0;
-    s->dualstereo      = 0;
-    if (intensitystereo_bit)
-        s->intensitystereo = s->startband +
-                          ff_opus_rc_dec_uint(rc, s->codedbands + 1 - s->startband);
-    if (s->intensitystereo <= s->startband)
-        totalbits += dualstereo_bit; /* no intensity stereo means no dual stereo */
-    else if (dualstereo_bit)
-        s->dualstereo = ff_opus_rc_dec_log(rc, 1);
+    f->intensity_stereo = 0;
+    f->dual_stereo      = 0;
+    if (intensity_stereo_bit)
+        f->intensity_stereo = f->start_band +
+                          ff_opus_rc_dec_uint(rc, f->coded_bands + 1 - f->start_band);
+    if (f->intensity_stereo <= f->start_band)
+        totalbits += dual_stereo_bit; /* no intensity stereo means no dual stereo */
+    else if (dual_stereo_bit)
+        f->dual_stereo = ff_opus_rc_dec_log(rc, 1);
 
     /* supply the remaining bits in this frame to lower bands */
     remaining = totalbits - total;
-    bandbits  = remaining / (ff_celt_freq_bands[s->codedbands] - ff_celt_freq_bands[s->startband]);
-    remaining -= bandbits * (ff_celt_freq_bands[s->codedbands] - ff_celt_freq_bands[s->startband]);
-    for (i = s->startband; i < s->codedbands; i++) {
+    bandbits  = remaining / (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
+    remaining -= bandbits * (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
+    for (i = f->start_band; i < f->coded_bands; i++) {
         int bits = FFMIN(remaining, ff_celt_freq_range[i]);
 
-        s->pulses[i] += bits + bandbits * ff_celt_freq_range[i];
+        f->pulses[i] += bits + bandbits * ff_celt_freq_range[i];
         remaining    -= bits;
     }
 
-    for (i = s->startband; i < s->codedbands; i++) {
-        int N = ff_celt_freq_range[i] << s->duration;
+    for (i = f->start_band; i < f->coded_bands; i++) {
+        int N = ff_celt_freq_range[i] << f->size;
         int prev_extra = extrabits;
-        s->pulses[i] += extrabits;
+        f->pulses[i] += extrabits;
 
         if (N > 1) {
             int dof;        // degrees of freedom
@@ -419,83 +419,83 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
                             // totalbits/dof
             int fine_bits, max_bits;
 
-            extrabits = FFMAX(0, s->pulses[i] - cap[i]);
-            s->pulses[i] -= extrabits;
+            extrabits = FFMAX(0, f->pulses[i] - cap[i]);
+            f->pulses[i] -= extrabits;
 
             /* intensity stereo makes use of an extra degree of freedom */
-            dof = N * s->coded_channels
-                  + (s->coded_channels == 2 && N > 2 && !s->dualstereo && i < s->intensitystereo);
-            temp = dof * (ff_celt_log_freq_range[i] + (s->duration<<3));
+            dof = N * f->channels
+                  + (f->channels == 2 && N > 2 && !f->dual_stereo && i < f->intensity_stereo);
+            temp = dof * (ff_celt_log_freq_range[i] + (f->size<<3));
             offset = (temp >> 1) - dof * CELT_FINE_OFFSET;
             if (N == 2) /* dof=2 is the only case that doesn't fit the model */
                 offset += dof<<1;
 
             /* grant an additional bias for the first and second pulses */
-            if (s->pulses[i] + offset < 2 * (dof << 3))
+            if (f->pulses[i] + offset < 2 * (dof << 3))
                 offset += temp >> 2;
-            else if (s->pulses[i] + offset < 3 * (dof << 3))
+            else if (f->pulses[i] + offset < 3 * (dof << 3))
                 offset += temp >> 3;
 
-            fine_bits = (s->pulses[i] + offset + (dof << 2)) / (dof << 3);
-            max_bits  = FFMIN((s->pulses[i]>>3) >> (s->coded_channels - 1),
+            fine_bits = (f->pulses[i] + offset + (dof << 2)) / (dof << 3);
+            max_bits  = FFMIN((f->pulses[i]>>3) >> (f->channels - 1),
                               CELT_MAX_FINE_BITS);
 
             max_bits  = FFMAX(max_bits, 0);
 
-            s->fine_bits[i] = av_clip(fine_bits, 0, max_bits);
+            f->fine_bits[i] = av_clip(fine_bits, 0, max_bits);
 
             /* if fine_bits was rounded down or capped,
                give priority for the final fine energy pass */
-            s->fine_priority[i] = (s->fine_bits[i] * (dof<<3) >= s->pulses[i] + offset);
+            f->fine_priority[i] = (f->fine_bits[i] * (dof<<3) >= f->pulses[i] + offset);
 
             /* the remaining bits are assigned to PVQ */
-            s->pulses[i] -= s->fine_bits[i] << (s->coded_channels - 1) << 3;
+            f->pulses[i] -= f->fine_bits[i] << (f->channels - 1) << 3;
         } else {
             /* all bits go to fine energy except for the sign bit */
-            extrabits = FFMAX(0, s->pulses[i] - (s->coded_channels << 3));
-            s->pulses[i] -= extrabits;
-            s->fine_bits[i] = 0;
-            s->fine_priority[i] = 1;
+            extrabits = FFMAX(0, f->pulses[i] - (f->channels << 3));
+            f->pulses[i] -= extrabits;
+            f->fine_bits[i] = 0;
+            f->fine_priority[i] = 1;
         }
 
         /* hand back a limited number of extra fine energy bits to this band */
         if (extrabits > 0) {
-            int fineextra = FFMIN(extrabits >> (s->coded_channels + 2),
-                                  CELT_MAX_FINE_BITS - s->fine_bits[i]);
-            s->fine_bits[i] += fineextra;
+            int fineextra = FFMIN(extrabits >> (f->channels + 2),
+                                  CELT_MAX_FINE_BITS - f->fine_bits[i]);
+            f->fine_bits[i] += fineextra;
 
-            fineextra <<= s->coded_channels + 2;
-            s->fine_priority[i] = (fineextra >= extrabits - prev_extra);
+            fineextra <<= f->channels + 2;
+            f->fine_priority[i] = (fineextra >= extrabits - prev_extra);
             extrabits -= fineextra;
         }
     }
-    s->remaining = extrabits;
+    f->remaining = extrabits;
 
     /* skipped bands dedicate all of their bits for fine energy */
-    for (; i < s->endband; i++) {
-        s->fine_bits[i]     = s->pulses[i] >> (s->coded_channels - 1) >> 3;
-        s->pulses[i]        = 0;
-        s->fine_priority[i] = s->fine_bits[i] < 1;
+    for (; i < f->end_band; i++) {
+        f->fine_bits[i]     = f->pulses[i] >> (f->channels - 1) >> 3;
+        f->pulses[i]        = 0;
+        f->fine_priority[i] = f->fine_bits[i] < 1;
     }
 }
 
-static void celt_denormalize(CeltContext *s, CeltFrame *frame, float *data)
+static void celt_denormalize(CeltFrame *f, CeltBlock *block, float *data)
 {
     int i, j;
 
-    for (i = s->startband; i < s->endband; i++) {
-        float *dst = data + (ff_celt_freq_bands[i] << s->duration);
-        float norm = exp2(frame->energy[i] + ff_celt_mean_energy[i]);
+    for (i = f->start_band; i < f->end_band; i++) {
+        float *dst = data + (ff_celt_freq_bands[i] << f->size);
+        float norm = exp2(block->energy[i] + ff_celt_mean_energy[i]);
 
-        for (j = 0; j < ff_celt_freq_range[i] << s->duration; j++)
+        for (j = 0; j < ff_celt_freq_range[i] << f->size; j++)
             dst[j] *= norm;
     }
 }
 
-static void celt_postfilter_apply_transition(CeltFrame *frame, float *data)
+static void celt_postfilter_apply_transition(CeltBlock *block, float *data)
 {
-    const int T0 = frame->pf_period_old;
-    const int T1 = frame->pf_period;
+    const int T0 = block->pf_period_old;
+    const int T1 = block->pf_period;
 
     float g00, g01, g02;
     float g10, g11, g12;
@@ -504,16 +504,16 @@ static void celt_postfilter_apply_transition(CeltFrame *frame, float *data)
 
     int i;
 
-    if (frame->pf_gains[0]     == 0.0 &&
-        frame->pf_gains_old[0] == 0.0)
+    if (block->pf_gains[0]     == 0.0 &&
+        block->pf_gains_old[0] == 0.0)
         return;
 
-    g00 = frame->pf_gains_old[0];
-    g01 = frame->pf_gains_old[1];
-    g02 = frame->pf_gains_old[2];
-    g10 = frame->pf_gains[0];
-    g11 = frame->pf_gains[1];
-    g12 = frame->pf_gains[2];
+    g00 = block->pf_gains_old[0];
+    g01 = block->pf_gains_old[1];
+    g02 = block->pf_gains_old[2];
+    g10 = block->pf_gains[0];
+    g11 = block->pf_gains[1];
+    g12 = block->pf_gains[2];
 
     x1 = data[-T1 + 1];
     x2 = data[-T1];
@@ -537,20 +537,19 @@ static void celt_postfilter_apply_transition(CeltFrame *frame, float *data)
     }
 }
 
-static void celt_postfilter_apply(CeltFrame *frame,
-                                  float *data, int len)
+static void celt_postfilter_apply(CeltBlock *block, float *data, int len)
 {
-    const int T = frame->pf_period;
+    const int T = block->pf_period;
     float g0, g1, g2;
     float x0, x1, x2, x3, x4;
     int i;
 
-    if (frame->pf_gains[0] == 0.0 || len <= 0)
+    if (block->pf_gains[0] == 0.0 || len <= 0)
         return;
 
-    g0 = frame->pf_gains[0];
-    g1 = frame->pf_gains[1];
-    g2 = frame->pf_gains[2];
+    g0 = block->pf_gains[0];
+    g1 = block->pf_gains[1];
+    g2 = block->pf_gains[2];
 
     x4 = data[-T - 2];
     x3 = data[-T - 1];
@@ -569,31 +568,31 @@ static void celt_postfilter_apply(CeltFrame *frame,
     }
 }
 
-static void celt_postfilter(CeltContext *s, CeltFrame *frame)
+static void celt_postfilter(CeltFrame *f, CeltBlock *block)
 {
-    int len = s->blocksize * s->blocks;
+    int len = f->blocksize * f->blocks;
 
-    celt_postfilter_apply_transition(frame, frame->buf + 1024);
+    celt_postfilter_apply_transition(block, block->buf + 1024);
 
-    frame->pf_period_old = frame->pf_period;
-    memcpy(frame->pf_gains_old, frame->pf_gains, sizeof(frame->pf_gains));
+    block->pf_period_old = block->pf_period;
+    memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
 
-    frame->pf_period = frame->pf_period_new;
-    memcpy(frame->pf_gains, frame->pf_gains_new, sizeof(frame->pf_gains));
+    block->pf_period = block->pf_period_new;
+    memcpy(block->pf_gains, block->pf_gains_new, sizeof(block->pf_gains));
 
     if (len > CELT_OVERLAP) {
-        celt_postfilter_apply_transition(frame, frame->buf + 1024 + CELT_OVERLAP);
-        celt_postfilter_apply(frame, frame->buf + 1024 + 2 * CELT_OVERLAP,
+        celt_postfilter_apply_transition(block, block->buf + 1024 + CELT_OVERLAP);
+        celt_postfilter_apply(block, block->buf + 1024 + 2 * CELT_OVERLAP,
                               len - 2 * CELT_OVERLAP);
 
-        frame->pf_period_old = frame->pf_period;
-        memcpy(frame->pf_gains_old, frame->pf_gains, sizeof(frame->pf_gains));
+        block->pf_period_old = block->pf_period;
+        memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
     }
 
-    memmove(frame->buf, frame->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float));
+    memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float));
 }
 
-static int parse_postfilter(CeltContext *s, OpusRangeCoder *rc, int consumed)
+static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
 {
     static const float postfilter_taps[3][3] = {
         { 0.3066406250f, 0.2170410156f, 0.1296386719f },
@@ -602,10 +601,10 @@ static int parse_postfilter(CeltContext *s, OpusRangeCoder *rc, int consumed)
     };
     int i;
 
-    memset(s->frame[0].pf_gains_new, 0, sizeof(s->frame[0].pf_gains_new));
-    memset(s->frame[1].pf_gains_new, 0, sizeof(s->frame[1].pf_gains_new));
+    memset(f->block[0].pf_gains_new, 0, sizeof(f->block[0].pf_gains_new));
+    memset(f->block[1].pf_gains_new, 0, sizeof(f->block[1].pf_gains_new));
 
-    if (s->startband == 0 && consumed + 16 <= s->framebits) {
+    if (f->start_band == 0 && consumed + 16 <= f->framebits) {
         int has_postfilter = ff_opus_rc_dec_log(rc, 1);
         if (has_postfilter) {
             float gain;
@@ -614,16 +613,16 @@ static int parse_postfilter(CeltContext *s, OpusRangeCoder *rc, int consumed)
             octave = ff_opus_rc_dec_uint(rc, 6);
             period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1;
             gain   = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1);
-            tapset = (opus_rc_tell(rc) + 2 <= s->framebits) ?
+            tapset = (opus_rc_tell(rc) + 2 <= f->framebits) ?
                      ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0;
 
             for (i = 0; i < 2; i++) {
-                CeltFrame *frame = &s->frame[i];
+                CeltBlock *block = &f->block[i];
 
-                frame->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
-                frame->pf_gains_new[0] = gain * postfilter_taps[tapset][0];
-                frame->pf_gains_new[1] = gain * postfilter_taps[tapset][1];
-                frame->pf_gains_new[2] = gain * postfilter_taps[tapset][2];
+                block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
+                block->pf_gains_new[0] = gain * postfilter_taps[tapset][0];
+                block->pf_gains_new[1] = gain * postfilter_taps[tapset][1];
+                block->pf_gains_new[2] = gain * postfilter_taps[tapset][2];
             }
         }
 
@@ -633,11 +632,11 @@ static int parse_postfilter(CeltContext *s, OpusRangeCoder *rc, int consumed)
     return consumed;
 }
 
-static void process_anticollapse(CeltContext *s, CeltFrame *frame, float *X)
+static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X)
 {
     int i, j, k;
 
-    for (i = s->startband; i < s->endband; i++) {
+    for (i = f->start_band; i < f->end_band; i++) {
         int renormalize = 0;
         float *xptr;
         float prev[2];
@@ -646,64 +645,65 @@ static void process_anticollapse(CeltContext *s, CeltFrame *frame, float *X)
         int depth;
 
         /* depth in 1/8 bits */
-        depth = (1 + s->pulses[i]) / (ff_celt_freq_range[i] << s->duration);
+        depth = (1 + f->pulses[i]) / (ff_celt_freq_range[i] << f->size);
         thresh = exp2f(-1.0 - 0.125f * depth);
-        sqrt_1 = 1.0f / sqrtf(ff_celt_freq_range[i] << s->duration);
+        sqrt_1 = 1.0f / sqrtf(ff_celt_freq_range[i] << f->size);
 
-        xptr = X + (ff_celt_freq_bands[i] << s->duration);
+        xptr = X + (ff_celt_freq_bands[i] << f->size);
 
-        prev[0] = frame->prev_energy[0][i];
-        prev[1] = frame->prev_energy[1][i];
-        if (s->coded_channels == 1) {
-            CeltFrame *frame1 = &s->frame[1];
+        prev[0] = block->prev_energy[0][i];
+        prev[1] = block->prev_energy[1][i];
+        if (f->channels == 1) {
+            CeltBlock *block1 = &f->block[1];
 
-            prev[0] = FFMAX(prev[0], frame1->prev_energy[0][i]);
-            prev[1] = FFMAX(prev[1], frame1->prev_energy[1][i]);
+            prev[0] = FFMAX(prev[0], block1->prev_energy[0][i]);
+            prev[1] = FFMAX(prev[1], block1->prev_energy[1][i]);
         }
-        Ediff = frame->energy[i] - FFMIN(prev[0], prev[1]);
+        Ediff = block->energy[i] - FFMIN(prev[0], prev[1]);
         Ediff = FFMAX(0, Ediff);
 
         /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
         short blocks don't have the same energy as long */
         r = exp2(1 - Ediff);
-        if (s->duration == 3)
+        if (f->size == 3)
             r *= M_SQRT2;
         r = FFMIN(thresh, r) * sqrt_1;
-        for (k = 0; k < 1 << s->duration; k++) {
+        for (k = 0; k < 1 << f->size; k++) {
             /* Detect collapse */
-            if (!(frame->collapse_masks[i] & 1 << k)) {
+            if (!(block->collapse_masks[i] & 1 << k)) {
                 /* Fill with noise */
                 for (j = 0; j < ff_celt_freq_range[i]; j++)
-                    xptr[(j << s->duration) + k] = (celt_rng(s) & 0x8000) ? r : -r;
+                    xptr[(j << f->size) + k] = (celt_rng(f) & 0x8000) ? r : -r;
                 renormalize = 1;
             }
         }
 
         /* We just added some energy, so we need to renormalize */
         if (renormalize)
-            celt_renormalize_vector(xptr, ff_celt_freq_range[i] << s->duration, 1.0f);
+            celt_renormalize_vector(xptr, ff_celt_freq_range[i] << f->size, 1.0f);
     }
 }
 
-static void celt_decode_bands(CeltContext *s, OpusRangeCoder *rc)
+static void celt_decode_bands(CeltFrame *f, OpusRangeCoder *rc)
 {
     float lowband_scratch[8 * 22];
     float norm[2 * 8 * 100];
 
-    int totalbits = (s->framebits << 3) - s->anticollapse_bit;
+    int totalbits = (f->framebits << 3) - f->anticollapse_needed;
 
     int update_lowband = 1;
     int lowband_offset = 0;
 
     int i, j;
 
-    memset(s->coeffs, 0, sizeof(s->coeffs));
+    memset(f->block[0].coeffs, 0, sizeof(f->block[0].coeffs));
+    memset(f->block[1].coeffs, 0, sizeof(f->block[0].coeffs));
 
-    for (i = s->startband; i < s->endband; i++) {
-        int band_offset = ff_celt_freq_bands[i] << s->duration;
-        int band_size   = ff_celt_freq_range[i] << s->duration;
-        float *X = s->coeffs[0] + band_offset;
-        float *Y = (s->coded_channels == 2) ? s->coeffs[1] + band_offset : NULL;
+    for (i = f->start_band; i < f->end_band; i++) {
+        int band_offset = ff_celt_freq_bands[i] << f->size;
+        int band_size   = ff_celt_freq_range[i] << f->size;
+        float *X = f->block[0].coeffs + band_offset;
+        float *Y = (f->channels == 2) ? f->block[1].coeffs + band_offset : NULL;
 
         int consumed = opus_rc_tell_frac(rc);
         float *norm2 = norm + 8 * 100;
@@ -712,27 +712,27 @@ static void celt_decode_bands(CeltContext *s, OpusRangeCoder *rc)
         int b;
 
         /* Compute how many bits we want to allocate to this band */
-        if (i != s->startband)
-            s->remaining -= consumed;
-        s->remaining2 = totalbits - consumed - 1;
-        if (i <= s->codedbands - 1) {
-            int curr_balance = s->remaining / FFMIN(3, s->codedbands-i);
-            b = av_clip_uintp2(FFMIN(s->remaining2 + 1, s->pulses[i] + curr_balance), 14);
+        if (i != f->start_band)
+            f->remaining -= consumed;
+        f->remaining2 = totalbits - consumed - 1;
+        if (i <= f->coded_bands - 1) {
+            int curr_balance = f->remaining / FFMIN(3, f->coded_bands-i);
+            b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14);
         } else
             b = 0;
 
-        if (ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[s->startband] &&
+        if (ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] &&
             (update_lowband || lowband_offset == 0))
             lowband_offset = i;
 
         /* Get a conservative estimate of the collapse_mask's for the bands we're
         going to be folding from. */
-        if (lowband_offset != 0 && (s->spread != CELT_SPREAD_AGGRESSIVE ||
-                                    s->blocks > 1 || s->tf_change[i] < 0)) {
+        if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE ||
+                                    f->blocks > 1 || f->tf_change[i] < 0)) {
             int foldstart, foldend;
 
             /* This ensures we never repeat spectral content within one band */
-            effective_lowband = FFMAX(ff_celt_freq_bands[s->startband],
+            effective_lowband = FFMAX(ff_celt_freq_bands[f->start_band],
                                       ff_celt_freq_bands[lowband_offset] - ff_celt_freq_range[i]);
             foldstart = lowband_offset;
             while (ff_celt_freq_bands[--foldstart] > effective_lowband);
@@ -741,260 +741,260 @@ static void celt_decode_bands(CeltContext *s, OpusRangeCoder *rc)
 
             cm[0] = cm[1] = 0;
             for (j = foldstart; j < foldend; j++) {
-                cm[0] |= s->frame[0].collapse_masks[j];
-                cm[1] |= s->frame[s->coded_channels - 1].collapse_masks[j];
+                cm[0] |= f->block[0].collapse_masks[j];
+                cm[1] |= f->block[f->channels - 1].collapse_masks[j];
             }
         } else
             /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost
             always) be non-zero.*/
-            cm[0] = cm[1] = (1 << s->blocks) - 1;
+            cm[0] = cm[1] = (1 << f->blocks) - 1;
 
-        if (s->dualstereo && i == s->intensitystereo) {
+        if (f->dual_stereo && i == f->intensity_stereo) {
             /* Switch off dual stereo to do intensity */
-            s->dualstereo = 0;
-            for (j = ff_celt_freq_bands[s->startband] << s->duration; j < band_offset; j++)
+            f->dual_stereo = 0;
+            for (j = ff_celt_freq_bands[f->start_band] << f->size; j < band_offset; j++)
                 norm[j] = (norm[j] + norm2[j]) / 2;
         }
 
-        if (s->dualstereo) {
-            cm[0] = ff_celt_decode_band(s, rc, i, X, NULL, band_size, b / 2, s->blocks,
-                                        effective_lowband != -1 ? norm + (effective_lowband << s->duration) : NULL, s->duration,
+        if (f->dual_stereo) {
+            cm[0] = ff_celt_decode_band(f, rc, i, X, NULL, band_size, b / 2, f->blocks,
+                                        effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
                                         norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]);
 
-            cm[1] = ff_celt_decode_band(s, rc, i, Y, NULL, band_size, b/2, s->blocks,
-                                        effective_lowband != -1 ? norm2 + (effective_lowband << s->duration) : NULL, s->duration,
+            cm[1] = ff_celt_decode_band(f, rc, i, Y, NULL, band_size, b/2, f->blocks,
+                                        effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL, f->size,
                                         norm2 + band_offset, 0, 1.0f, lowband_scratch, cm[1]);
         } else {
-            cm[0] = ff_celt_decode_band(s, rc, i, X, Y, band_size, b, s->blocks,
-                                        effective_lowband != -1 ? norm + (effective_lowband << s->duration) : NULL, s->duration,
+            cm[0] = ff_celt_decode_band(f, rc, i, X, Y, band_size, b, f->blocks,
+                                        effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
                                         norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]|cm[1]);
             cm[1] = cm[0];
         }
 
-        s->frame[0].collapse_masks[i]                     = (uint8_t)cm[0];
-        s->frame[s->coded_channels - 1].collapse_masks[i] = (uint8_t)cm[1];
-        s->remaining += s->pulses[i] + consumed;
+        f->block[0].collapse_masks[i]               = (uint8_t)cm[0];
+        f->block[f->channels - 1].collapse_masks[i] = (uint8_t)cm[1];
+        f->remaining += f->pulses[i] + consumed;
 
         /* Update the folding position only as long as we have 1 bit/sample depth */
         update_lowband = (b > band_size << 3);
     }
 }
 
-int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc,
-                         float **output, int coded_channels, int frame_size,
-                         int startband,  int endband)
+int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
+                         float **output, int channels, int frame_size,
+                         int start_band,  int end_band)
 {
     int i, j;
-
     int consumed;           // bits of entropy consumed thus far for this frame
-    int silence = 0;
-    int transient = 0;
-    int anticollapse = 0;
     MDCT15Context *imdct;
     float imdct_scale = 1.0;
 
-    if (coded_channels != 1 && coded_channels != 2) {
-        av_log(s->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n",
-               coded_channels);
+    if (channels != 1 && channels != 2) {
+        av_log(f->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n",
+               channels);
         return AVERROR_INVALIDDATA;
     }
-    if (startband < 0 || startband > endband || endband > CELT_MAX_BANDS) {
-        av_log(s->avctx, AV_LOG_ERROR, "Invalid start/end band: %d %d\n",
-               startband, endband);
+    if (start_band < 0 || start_band > end_band || end_band > CELT_MAX_BANDS) {
+        av_log(f->avctx, AV_LOG_ERROR, "Invalid start/end band: %d %d\n",
+               start_band, end_band);
         return AVERROR_INVALIDDATA;
     }
 
-    s->flushed        = 0;
-    s->coded_channels = coded_channels;
-    s->startband      = startband;
-    s->endband        = endband;
-    s->framebits      = rc->rb.bytes * 8;
-
-    s->duration = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
-    if (s->duration > CELT_MAX_LOG_BLOCKS ||
-        frame_size != CELT_SHORT_BLOCKSIZE * (1 << s->duration)) {
-        av_log(s->avctx, AV_LOG_ERROR, "Invalid CELT frame size: %d\n",
+    f->silence        = 0;
+    f->transient      = 0;
+    f->anticollapse   = 0;
+    f->flushed        = 0;
+    f->channels       = channels;
+    f->start_band     = start_band;
+    f->end_band       = end_band;
+    f->framebits      = rc->rb.bytes * 8;
+
+    f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
+    if (f->size > CELT_MAX_LOG_BLOCKS ||
+        frame_size != CELT_SHORT_BLOCKSIZE * (1 << f->size)) {
+        av_log(f->avctx, AV_LOG_ERROR, "Invalid CELT frame size: %d\n",
                frame_size);
         return AVERROR_INVALIDDATA;
     }
 
-    if (!s->output_channels)
-        s->output_channels = coded_channels;
+    if (!f->output_channels)
+        f->output_channels = channels;
 
-    memset(s->frame[0].collapse_masks, 0, sizeof(s->frame[0].collapse_masks));
-    memset(s->frame[1].collapse_masks, 0, sizeof(s->frame[1].collapse_masks));
+    memset(f->block[0].collapse_masks, 0, sizeof(f->block[0].collapse_masks));
+    memset(f->block[1].collapse_masks, 0, sizeof(f->block[1].collapse_masks));
 
     consumed = opus_rc_tell(rc);
 
     /* obtain silence flag */
-    if (consumed >= s->framebits)
-        silence = 1;
+    if (consumed >= f->framebits)
+        f->silence = 1;
     else if (consumed == 1)
-        silence = ff_opus_rc_dec_log(rc, 15);
+        f->silence = ff_opus_rc_dec_log(rc, 15);
 
 
-    if (silence) {
-        consumed = s->framebits;
-        rc->total_bits += s->framebits - opus_rc_tell(rc);
+    if (f->silence) {
+        consumed = f->framebits;
+        rc->total_bits += f->framebits - opus_rc_tell(rc);
     }
 
     /* obtain post-filter options */
-    consumed = parse_postfilter(s, rc, consumed);
+    consumed = parse_postfilter(f, rc, consumed);
 
     /* obtain transient flag */
-    if (s->duration != 0 && consumed+3 <= s->framebits)
-        transient = ff_opus_rc_dec_log(rc, 3);
+    if (f->size != 0 && consumed+3 <= f->framebits)
+        f->transient = ff_opus_rc_dec_log(rc, 3);
 
-    s->blocks    = transient ? 1 << s->duration : 1;
-    s->blocksize = frame_size / s->blocks;
+    f->blocks    = f->transient ? 1 << f->size : 1;
+    f->blocksize = frame_size / f->blocks;
 
-    imdct = s->imdct[transient ? 0 : s->duration];
+    imdct = f->imdct[f->transient ? 0 : f->size];
 
-    if (coded_channels == 1) {
+    if (channels == 1) {
         for (i = 0; i < CELT_MAX_BANDS; i++)
-            s->frame[0].energy[i] = FFMAX(s->frame[0].energy[i], s->frame[1].energy[i]);
+            f->block[0].energy[i] = FFMAX(f->block[0].energy[i], f->block[1].energy[i]);
     }
 
-    celt_decode_coarse_energy(s, rc);
-    celt_decode_tf_changes   (s, rc, transient);
-    celt_decode_allocation   (s, rc);
-    celt_decode_fine_energy  (s, rc);
-    celt_decode_bands        (s, rc);
+    celt_decode_coarse_energy(f, rc);
+    celt_decode_tf_changes   (f, rc);
+    celt_decode_allocation   (f, rc);
+    celt_decode_fine_energy  (f, rc);
+    celt_decode_bands        (f, rc);
 
-    if (s->anticollapse_bit)
-        anticollapse = ff_opus_rc_get_raw(rc, 1);
+    if (f->anticollapse_needed)
+        f->anticollapse = ff_opus_rc_get_raw(rc, 1);
 
-    celt_decode_final_energy(s, rc, s->framebits - opus_rc_tell(rc));
+    celt_decode_final_energy(f, rc);
 
     /* apply anti-collapse processing and denormalization to
      * each coded channel */
-    for (i = 0; i < s->coded_channels; i++) {
-        CeltFrame *frame = &s->frame[i];
+    for (i = 0; i < f->channels; i++) {
+        CeltBlock *block = &f->block[i];
 
-        if (anticollapse)
-            process_anticollapse(s, frame, s->coeffs[i]);
+        if (f->anticollapse)
+            process_anticollapse(f, block, f->block[i].coeffs);
 
-        celt_denormalize(s, frame, s->coeffs[i]);
+        celt_denormalize(f, block, f->block[i].coeffs);
     }
 
     /* stereo -> mono downmix */
-    if (s->output_channels < s->coded_channels) {
-        s->dsp->vector_fmac_scalar(s->coeffs[0], s->coeffs[1], 1.0, FFALIGN(frame_size, 16));
+    if (f->output_channels < f->channels) {
+        f->dsp->vector_fmac_scalar(f->block[0].coeffs, f->block[1].coeffs, 1.0, FFALIGN(frame_size, 16));
         imdct_scale = 0.5;
-    } else if (s->output_channels > s->coded_channels)
-        memcpy(s->coeffs[1], s->coeffs[0], frame_size * sizeof(float));
+    } else if (f->output_channels > f->channels)
+        memcpy(f->block[1].coeffs, f->block[0].coeffs, frame_size * sizeof(float));
 
-    if (silence) {
+    if (f->silence) {
         for (i = 0; i < 2; i++) {
-            CeltFrame *frame = &s->frame[i];
+            CeltBlock *block = &f->block[i];
 
-            for (j = 0; j < FF_ARRAY_ELEMS(frame->energy); j++)
-                frame->energy[j] = CELT_ENERGY_SILENCE;
+            for (j = 0; j < FF_ARRAY_ELEMS(block->energy); j++)
+                block->energy[j] = CELT_ENERGY_SILENCE;
         }
-        memset(s->coeffs, 0, sizeof(s->coeffs));
+        memset(f->block[0].coeffs, 0, sizeof(f->block[0].coeffs));
+        memset(f->block[1].coeffs, 0, sizeof(f->block[1].coeffs));
     }
 
     /* transform and output for each output channel */
-    for (i = 0; i < s->output_channels; i++) {
-        CeltFrame *frame = &s->frame[i];
-        float m = frame->deemph_coeff;
+    for (i = 0; i < f->output_channels; i++) {
+        CeltBlock *block = &f->block[i];
+        float m = block->emph_coeff;
 
         /* iMDCT and overlap-add */
-        for (j = 0; j < s->blocks; j++) {
-            float *dst  = frame->buf + 1024 + j * s->blocksize;
+        for (j = 0; j < f->blocks; j++) {
+            float *dst  = block->buf + 1024 + j * f->blocksize;
 
-            imdct->imdct_half(imdct, dst + CELT_OVERLAP / 2, s->coeffs[i] + j,
-                              s->blocks, imdct_scale);
-            s->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
+            imdct->imdct_half(imdct, dst + CELT_OVERLAP / 2, f->block[i].coeffs + j,
+                              f->blocks, imdct_scale);
+            f->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
                                        ff_celt_window, CELT_OVERLAP / 2);
         }
 
         /* postfilter */
-        celt_postfilter(s, frame);
+        celt_postfilter(f, block);
 
         /* deemphasis and output scaling */
         for (j = 0; j < frame_size; j++) {
-            float tmp = frame->buf[1024 - frame_size + j] + m;
-            m = tmp * CELT_DEEMPH_COEFF;
+            float tmp = block->buf[1024 - frame_size + j] + m;
+            m = tmp * CELT_EMPH_COEFF;
             output[i][j] = tmp / 32768.;
         }
-        frame->deemph_coeff = m;
+        block->emph_coeff = m;
     }
 
-    if (coded_channels == 1)
-        memcpy(s->frame[1].energy, s->frame[0].energy, sizeof(s->frame[0].energy));
+    if (channels == 1)
+        memcpy(f->block[1].energy, f->block[0].energy, sizeof(f->block[0].energy));
 
     for (i = 0; i < 2; i++ ) {
-        CeltFrame *frame = &s->frame[i];
+        CeltBlock *block = &f->block[i];
 
-        if (!transient) {
-            memcpy(frame->prev_energy[1], frame->prev_energy[0], sizeof(frame->prev_energy[0]));
-            memcpy(frame->prev_energy[0], frame->energy,         sizeof(frame->prev_energy[0]));
+        if (!f->transient) {
+            memcpy(block->prev_energy[1], block->prev_energy[0], sizeof(block->prev_energy[0]));
+            memcpy(block->prev_energy[0], block->energy,         sizeof(block->prev_energy[0]));
         } else {
             for (j = 0; j < CELT_MAX_BANDS; j++)
-                frame->prev_energy[0][j] = FFMIN(frame->prev_energy[0][j], frame->energy[j]);
+                block->prev_energy[0][j] = FFMIN(block->prev_energy[0][j], block->energy[j]);
         }
 
-        for (j = 0; j < s->startband; j++) {
-            frame->prev_energy[0][j] = CELT_ENERGY_SILENCE;
-            frame->energy[j]         = 0.0;
+        for (j = 0; j < f->start_band; j++) {
+            block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
+            block->energy[j]         = 0.0;
         }
-        for (j = s->endband; j < CELT_MAX_BANDS; j++) {
-            frame->prev_energy[0][j] = CELT_ENERGY_SILENCE;
-            frame->energy[j]         = 0.0;
+        for (j = f->end_band; j < CELT_MAX_BANDS; j++) {
+            block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
+            block->energy[j]         = 0.0;
         }
     }
 
-    s->seed = rc->range;
+    f->seed = rc->range;
 
     return 0;
 }
 
-void ff_celt_flush(CeltContext *s)
+void ff_celt_flush(CeltFrame *f)
 {
     int i, j;
 
-    if (s->flushed)
+    if (f->flushed)
         return;
 
     for (i = 0; i < 2; i++) {
-        CeltFrame *frame = &s->frame[i];
+        CeltBlock *block = &f->block[i];
 
         for (j = 0; j < CELT_MAX_BANDS; j++)
-            frame->prev_energy[0][j] = frame->prev_energy[1][j] = CELT_ENERGY_SILENCE;
+            block->prev_energy[0][j] = block->prev_energy[1][j] = CELT_ENERGY_SILENCE;
 
-        memset(frame->energy, 0, sizeof(frame->energy));
-        memset(frame->buf,    0, sizeof(frame->buf));
+        memset(block->energy, 0, sizeof(block->energy));
+        memset(block->buf,    0, sizeof(block->buf));
 
-        memset(frame->pf_gains,     0, sizeof(frame->pf_gains));
-        memset(frame->pf_gains_old, 0, sizeof(frame->pf_gains_old));
-        memset(frame->pf_gains_new, 0, sizeof(frame->pf_gains_new));
+        memset(block->pf_gains,     0, sizeof(block->pf_gains));
+        memset(block->pf_gains_old, 0, sizeof(block->pf_gains_old));
+        memset(block->pf_gains_new, 0, sizeof(block->pf_gains_new));
 
-        frame->deemph_coeff = 0.0;
+        block->emph_coeff = 0.0;
     }
-    s->seed = 0;
+    f->seed = 0;
 
-    s->flushed = 1;
+    f->flushed = 1;
 }
 
-void ff_celt_free(CeltContext **ps)
+void ff_celt_free(CeltFrame **f)
 {
-    CeltContext *s = *ps;
+    CeltFrame *frm = *f;
     int i;
 
-    if (!s)
+    if (!frm)
         return;
 
-    for (i = 0; i < FF_ARRAY_ELEMS(s->imdct); i++)
-        ff_mdct15_uninit(&s->imdct[i]);
+    for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++)
+        ff_mdct15_uninit(&frm->imdct[i]);
 
-    av_freep(&s->dsp);
-    av_freep(ps);
+    av_freep(&frm->dsp);
+    av_freep(f);
 }
 
-int ff_celt_init(AVCodecContext *avctx, CeltContext **ps, int output_channels)
+int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels)
 {
-    CeltContext *s;
+    CeltFrame *frm;
     int i, ret;
 
     if (output_channels != 1 && output_channels != 2) {
@@ -1003,31 +1003,31 @@ int ff_celt_init(AVCodecContext *avctx, CeltContext **ps, int output_channels)
         return AVERROR(EINVAL);
     }
 
-    s = av_mallocz(sizeof(*s));
-    if (!s)
+    frm = av_mallocz(sizeof(*frm));
+    if (!frm)
         return AVERROR(ENOMEM);
 
-    s->avctx           = avctx;
-    s->output_channels = output_channels;
+    frm->avctx           = avctx;
+    frm->output_channels = output_channels;
 
-    for (i = 0; i < FF_ARRAY_ELEMS(s->imdct); i++) {
-        ret = ff_mdct15_init(&s->imdct[i], 1, i + 3, -1.0f);
+    for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++) {
+        ret = ff_mdct15_init(&frm->imdct[i], 1, i + 3, -1.0f);
         if (ret < 0)
             goto fail;
     }
 
-    s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
-    if (!s->dsp) {
+    frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+    if (!frm->dsp) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
 
-    ff_celt_flush(s);
+    ff_celt_flush(frm);
 
-    *ps = s;
+    *f = frm;
 
     return 0;
 fail:
-    ff_celt_free(&s);
+    ff_celt_free(&frm);
     return ret;
 }
diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h
index e9b5946642..1378d85df3 100644
--- a/libavcodec/opus_celt.h
+++ b/libavcodec/opus_celt.h
@@ -24,6 +24,8 @@
 #ifndef AVCODEC_OPUS_CELT_H
 #define AVCODEC_OPUS_CELT_H
 
+#include <float.h>
+
 #include "opus.h"
 
 #include "mdct15.h"
@@ -37,7 +39,7 @@
 #define CELT_NORM_SCALE              16384
 #define CELT_QTHETA_OFFSET           4
 #define CELT_QTHETA_OFFSET_TWOPHASE  16
-#define CELT_DEEMPH_COEFF            0.85000610f
+#define CELT_EMPH_COEFF              0.85000610f
 #define CELT_POSTFILTER_MINPERIOD    15
 #define CELT_ENERGY_SILENCE          (-28.0f)
 
@@ -48,7 +50,16 @@ enum CeltSpread {
     CELT_SPREAD_AGGRESSIVE
 };
 
-typedef struct CeltFrame {
+enum CeltBlockSize {
+    CELT_BLOCK_120,
+    CELT_BLOCK_240,
+    CELT_BLOCK_480,
+    CELT_BLOCK_960,
+
+    CELT_BLOCK_NB
+};
+
+typedef struct CeltBlock {
     float energy[CELT_MAX_BANDS];
     float prev_energy[2][CELT_MAX_BANDS];
 
@@ -56,50 +67,46 @@ typedef struct CeltFrame {
 
     /* buffer for mdct output + postfilter */
     DECLARE_ALIGNED(32, float, buf)[2048];
+    DECLARE_ALIGNED(32, float, coeffs)[CELT_MAX_FRAME_SIZE];
 
     /* postfilter parameters */
-    int pf_period_new;
+    int   pf_period_new;
     float pf_gains_new[3];
-    int pf_period;
+    int   pf_period;
     float pf_gains[3];
-    int pf_period_old;
+    int   pf_period_old;
     float pf_gains_old[3];
 
-    float deemph_coeff;
-} CeltFrame;
+    float emph_coeff;
+} CeltBlock;
 
-struct CeltContext {
+typedef struct CeltFrame {
     // constant values that do not change during context lifetime
-    AVCodecContext    *avctx;
-    MDCT15Context     *imdct[4];
-    AVFloatDSPContext  *dsp;
+    AVCodecContext      *avctx;
+    MDCT15Context       *imdct[4];
+    AVFloatDSPContext   *dsp;
+    CeltBlock           block[2];
+    int channels;
     int output_channels;
 
-    // values that have inter-frame effect and must be reset on flush
-    CeltFrame frame[2];
-    uint32_t seed;
+    enum CeltBlockSize size;
+    int start_band;
+    int end_band;
+    int coded_bands;
+    int transient;
+    int blocks;        /* number of iMDCT blocks in the frame, depends on transient */
+    int blocksize;     /* size of each block */
+    int silence;       /* Frame is filled with silence */
+    int anticollapse_needed; /* Whether to expect an anticollapse bit */
+    int anticollapse;  /* Encoded anticollapse bit */
+    int intensity_stereo;
+    int dual_stereo;
     int flushed;
-
-    // values that only affect a single frame
-    int coded_channels;
-    int framebits;
-    int duration;
-
-    /* number of iMDCT blocks in the frame */
-    int blocks;
-    /* size of each block */
-    int blocksize;
-
-    int startband;
-    int endband;
-    int codedbands;
-
-    int anticollapse_bit;
-
-    int intensitystereo;
-    int dualstereo;
+    uint32_t seed;
     enum CeltSpread spread;
 
+    /* Bit allocation */
+    int framebits;
     int remaining;
     int remaining2;
     int fine_bits    [CELT_MAX_BANDS];
@@ -107,15 +114,14 @@ struct CeltContext {
     int pulses       [CELT_MAX_BANDS];
     int tf_change    [CELT_MAX_BANDS];
 
-    DECLARE_ALIGNED(32, float, coeffs)[2][CELT_MAX_FRAME_SIZE];
     DECLARE_ALIGNED(32, float, scratch)[22 * 8]; // MAX(ff_celt_freq_range) * 1<<CELT_MAX_LOG_BLOCKS
-};
+} CeltFrame;
 
 /* LCG for noise generation */
-static av_always_inline uint32_t celt_rng(CeltContext *s)
+static av_always_inline uint32_t celt_rng(CeltFrame *f)
 {
-    s->seed = 1664525 * s->seed + 1013904223;
-    return s->seed;
+    f->seed = 1664525 * f->seed + 1013904223;
+    return f->seed;
 }
 
 static av_always_inline void celt_renormalize_vector(float *X, int N, float gain)
@@ -130,4 +136,13 @@ static av_always_inline void celt_renormalize_vector(float *X, int N, float gain
         X[i] *= g;
 }
 
+int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels);
+
+void ff_celt_free(CeltFrame **f);
+
+void ff_celt_flush(CeltFrame *f);
+
+int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, float **output,
+                         int coded_channels, int frame_size, int startband, int endband);
+
 #endif /* AVCODEC_OPUS_CELT_H */
diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c
index 142c74da71..a39330b7e4 100644
--- a/libavcodec/opus_pvq.c
+++ b/libavcodec/opus_pvq.c
@@ -375,7 +375,7 @@ static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint3
     return celt_extract_collapse_mask(y, N, blocks);
 }
 
-uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
+uint32_t ff_celt_decode_band(CeltFrame *f, OpusRangeCoder *rc, const int band,
                              float *X, float *Y, int N, int b, uint32_t blocks,
                              float *lowband, int duration, float *lowband_out, int level,
                              float gain, float *lowband_scratch, int fill)
@@ -403,9 +403,9 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
         float *x = X;
         for (i = 0; i <= dualstereo; i++) {
             int sign = 0;
-            if (s->remaining2 >= 1<<3) {
+            if (f->remaining2 >= 1<<3) {
                 sign           = ff_opus_rc_get_raw(rc, 1);
-                s->remaining2 -= 1 << 3;
+                f->remaining2 -= 1 << 3;
                 b             -= 1 << 3;
             }
             x[0] = sign ? -1.0f : 1.0f;
@@ -417,7 +417,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
     }
 
     if (!dualstereo && level == 0) {
-        int tf_change = s->tf_change[band];
+        int tf_change = f->tf_change[band];
         int k;
         if (tf_change > 0)
             recombine = tf_change;
@@ -454,7 +454,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
 
         /* Reorganize the samples in time order instead of frequency order */
         if (B0 > 1 && lowband)
-            celt_deinterleave_hadamard(s->scratch, lowband, N_B >> recombine,
+            celt_deinterleave_hadamard(f->scratch, lowband, N_B >> recombine,
                                        B0 << recombine, longblocks);
     }
 
@@ -485,7 +485,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
         pulse_cap = ff_celt_log_freq_range[band] + duration * 8;
         offset = (pulse_cap >> 1) - (dualstereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE :
                                                           CELT_QTHETA_OFFSET);
-        qn = (dualstereo && band >= s->intensitystereo) ? 1 :
+        qn = (dualstereo && band >= f->intensity_stereo) ? 1 :
              celt_compute_qn(N, b, offset, pulse_cap, dualstereo);
         tell = opus_rc_tell_frac(rc);
         if (qn != 1) {
@@ -501,7 +501,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
             /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.
             Let's do that at higher complexity */
         } else if (dualstereo) {
-            inv = (b > 2 << 3 && s->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0;
+            inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0;
             itheta = 0;
         }
         qalloc = opus_rc_tell_frac(rc) - tell;
@@ -542,7 +542,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
             sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0;
             mbits -= sbits;
             c = (itheta > 8192);
-            s->remaining2 -= qalloc+sbits;
+            f->remaining2 -= qalloc+sbits;
 
             x2 = c ? Y : X;
             y2 = c ? X : Y;
@@ -551,7 +551,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
             sign = 1 - 2 * sign;
             /* We use orig_fill here because we want to fold the side, but if
             itheta==16384, we'll have cleared the low bits of fill. */
-            cm = ff_celt_decode_band(s, rc, band, x2, NULL, N, mbits, blocks,
+            cm = ff_celt_decode_band(f, rc, band, x2, NULL, N, mbits, blocks,
                                      lowband, duration, lowband_out, level, gain,
                                      lowband_scratch, orig_fill);
             /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
@@ -588,7 +588,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
             }
             mbits = av_clip((b - delta) / 2, 0, b);
             sbits = b - mbits;
-            s->remaining2 -= qalloc;
+            f->remaining2 -= qalloc;
 
             if (lowband && !dualstereo)
                 next_lowband2 = lowband + N; /* >32-bit split case */
@@ -600,40 +600,40 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
             else
                 next_level = level + 1;
 
-            rebalance = s->remaining2;
+            rebalance = f->remaining2;
             if (mbits >= sbits) {
                 /* In stereo mode, we do not apply a scaling to the mid
                  * because we need the normalized mid for folding later */
-                cm = ff_celt_decode_band(s, rc, band, X, NULL, N, mbits, blocks,
+                cm = ff_celt_decode_band(f, rc, band, X, NULL, N, mbits, blocks,
                                          lowband, duration, next_lowband_out1,
                                          next_level, dualstereo ? 1.0f : (gain * mid),
                                          lowband_scratch, fill);
 
-                rebalance = mbits - (rebalance - s->remaining2);
+                rebalance = mbits - (rebalance - f->remaining2);
                 if (rebalance > 3 << 3 && itheta != 0)
                     sbits += rebalance - (3 << 3);
 
                 /* For a stereo split, the high bits of fill are always zero,
                  * so no folding will be done to the side. */
-                cm |= ff_celt_decode_band(s, rc, band, Y, NULL, N, sbits, blocks,
+                cm |= ff_celt_decode_band(f, rc, band, Y, NULL, N, sbits, blocks,
                                           next_lowband2, duration, NULL,
                                           next_level, gain * side, NULL,
                                           fill >> blocks) << ((B0 >> 1) & (dualstereo - 1));
             } else {
                 /* For a stereo split, the high bits of fill are always zero,
                  * so no folding will be done to the side. */
-                cm = ff_celt_decode_band(s, rc, band, Y, NULL, N, sbits, blocks,
+                cm = ff_celt_decode_band(f, rc, band, Y, NULL, N, sbits, blocks,
                                          next_lowband2, duration, NULL,
                                          next_level, gain * side, NULL,
                                          fill >> blocks) << ((B0 >> 1) & (dualstereo - 1));
 
-                rebalance = sbits - (rebalance - s->remaining2);
+                rebalance = sbits - (rebalance - f->remaining2);
                 if (rebalance > 3 << 3 && itheta != 16384)
                     mbits += rebalance - (3 << 3);
 
                 /* In stereo mode, we do not apply a scaling to the mid because
                  * we need the normalized mid for folding later */
-                cm |= ff_celt_decode_band(s, rc, band, X, NULL, N, mbits, blocks,
+                cm |= ff_celt_decode_band(f, rc, band, X, NULL, N, mbits, blocks,
                                           lowband, duration, next_lowband_out1,
                                           next_level, dualstereo ? 1.0f : (gain * mid),
                                           lowband_scratch, fill);
@@ -643,19 +643,19 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
         /* This is the basic no-split case */
         uint32_t q         = celt_bits2pulses(cache, b);
         uint32_t curr_bits = celt_pulses2bits(cache, q);
-        s->remaining2 -= curr_bits;
+        f->remaining2 -= curr_bits;
 
         /* Ensures we can never bust the budget */
-        while (s->remaining2 < 0 && q > 0) {
-            s->remaining2 += curr_bits;
+        while (f->remaining2 < 0 && q > 0) {
+            f->remaining2 += curr_bits;
             curr_bits      = celt_pulses2bits(cache, --q);
-            s->remaining2 -= curr_bits;
+            f->remaining2 -= curr_bits;
         }
 
         if (q != 0) {
             /* Finally do the actual quantization */
             cm = celt_alg_unquant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
-                                  s->spread, blocks, gain);
+                                  f->spread, blocks, gain);
         } else {
             /* If there's no pulse, fill the band anyway */
             int j;
@@ -668,13 +668,13 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
                 if (!lowband) {
                     /* Noise */
                     for (j = 0; j < N; j++)
-                        X[j] = (((int32_t)celt_rng(s)) >> 20);
+                        X[j] = (((int32_t)celt_rng(f)) >> 20);
                     cm = cm_mask;
                 } else {
                     /* Folded spectrum */
                     for (j = 0; j < N; j++) {
                         /* About 48 dB below the "normal" folding level */
-                        X[j] = lowband[j] + (((celt_rng(s)) & 0x8000) ? 1.0f / 256 : -1.0f / 256);
+                        X[j] = lowband[j] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256);
                     }
                     cm = fill;
                 }
@@ -697,7 +697,7 @@ uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
 
         /* Undo the sample reorganization going from time order to frequency order */
         if (B0 > 1)
-            celt_interleave_hadamard(s->scratch, X, N_B>>recombine,
+            celt_interleave_hadamard(f->scratch, X, N_B>>recombine,
                                      B0<<recombine, longblocks);
 
         /* Undo time-freq changes that we did earlier */
diff --git a/libavcodec/opus_pvq.h b/libavcodec/opus_pvq.h
index 1083f35db9..0354a3c960 100644
--- a/libavcodec/opus_pvq.h
+++ b/libavcodec/opus_pvq.h
@@ -27,7 +27,7 @@
 #include "opus_celt.h"
 
 /* Decodes a band using PVQ */
-uint32_t ff_celt_decode_band(CeltContext *s, OpusRangeCoder *rc, const int band,
+uint32_t ff_celt_decode_band(CeltFrame *f, OpusRangeCoder *rc, const int band,
                              float *X, float *Y, int N, int b, uint32_t blocks,
                              float *lowband, int duration, float *lowband_out, int level,
                              float gain, float *lowband_scratch, int fill);
diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c
index 556acfe2df..1110302f9c 100644
--- a/libavcodec/opusdec.c
+++ b/libavcodec/opusdec.c
@@ -48,6 +48,7 @@
 #include "mathops.h"
 #include "opus.h"
 #include "opustab.h"
+#include "opus_celt.h"
 
 static const uint16_t silk_frame_duration_ms[16] = {
     10, 20, 40, 60,
@@ -63,8 +64,6 @@ static const int silk_resample_delay[] = {
     4, 8, 11, 11, 11
 };
 
-static const uint8_t celt_band_end[] = { 13, 17, 17, 19, 21 };
-
 static int get_silk_samplerate(int config)
 {
     if (config < 4)
@@ -168,7 +167,7 @@ static int opus_decode_redundancy(OpusStreamContext *s, const uint8_t *data, int
     ret = ff_celt_decode_frame(s->celt, &s->redundancy_rc,
                                s->redundancy_output,
                                s->packet.stereo + 1, 240,
-                               0, celt_band_end[s->packet.bandwidth]);
+                               0, ff_celt_band_end[s->packet.bandwidth]);
     if (ret < 0)
         goto fail;
 
@@ -279,7 +278,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size
                                    s->packet.stereo + 1,
                                    s->packet.frame_duration,
                                    (s->packet.mode == OPUS_MODE_HYBRID) ? 17 : 0,
-                                   celt_band_end[s->packet.bandwidth]);
+                                   ff_celt_band_end[s->packet.bandwidth]);
         if (ret < 0)
             return ret;
 
diff --git a/libavcodec/opustab.c b/libavcodec/opustab.c
index cfe56ba94f..02d548e71a 100644
--- a/libavcodec/opustab.c
+++ b/libavcodec/opustab.c
@@ -22,6 +22,10 @@
 
 #include "opustab.h"
 
+const uint8_t ff_opus_default_coupled_streams[] = { 0, 1, 1, 2, 2, 2, 2, 3 };
+
+const uint8_t ff_celt_band_end[] = { 13, 17, 17, 19, 21 };
+
 const uint16_t ff_silk_model_stereo_s1[] = {
     256,   7,   9,  10,  11,  12,  22,  46,  54,  55,  56,  59,  82, 174, 197, 200,
     201, 202, 210, 234, 244, 245, 246, 247, 249, 256
diff --git a/libavcodec/opustab.h b/libavcodec/opustab.h
index e6527c0270..b6be073659 100644
--- a/libavcodec/opustab.h
+++ b/libavcodec/opustab.h
@@ -27,6 +27,10 @@
 
 #include <stdint.h>
 
+extern const uint8_t  ff_celt_band_end[];
+
+extern const uint8_t  ff_opus_default_coupled_streams[];
+
 extern const uint16_t ff_silk_model_stereo_s1[];
 extern const uint16_t ff_silk_model_stereo_s2[];
 extern const uint16_t ff_silk_model_stereo_s3[];
-- 
2.11.0.483.g087da7b7c



More information about the ffmpeg-devel mailing list