[FFmpeg-devel] [PATCH] opusdec: do not fail when LBRR frames are present

Anton Khirnov anton at khirnov.net
Thu Oct 1 12:18:36 EEST 2020


Quoting Lynne (2020-09-11 20:53:16)
> On 11/09/2020 19:37, Anton Khirnov wrote:
> > Decode and discard them.
> > 
> > Fixes ticket 4641.
> > ---
> >  libavcodec/opus_silk.c | 28 ++++++++++++++++++++--------
> >  libavcodec/opustab.c   |  3 +++
> >  libavcodec/opustab.h   |  3 +++
> >  3 files changed, 26 insertions(+), 8 deletions(-)
> > 
> > diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c
> > index 2fcbf3b9d3..c683b25a20 100644
> > --- a/libavcodec/opus_silk.c
> > +++ b/libavcodec/opus_silk.c
> > @@ -506,7 +506,8 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
> >  #define LTP_ORDER 5
> >  
> >  static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
> > -                              int frame_num, int channel, int coded_channels, int active, int active1)
> > +                              int frame_num, int channel, int coded_channels,
> > +                              int active, int active1, int redundant)
> >  {
> >      /* per frame */
> >      int voiced;       // combines with active to indicate inactive, active, or active+voiced
> > @@ -665,8 +666,8 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
> >      silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high,
> >                             active, voiced);
> >  
> > -    /* skip synthesising the side channel if we want mono-only */
> > -    if (s->output_channels == channel)
> > +    /* skip synthesising the output if we do not need it */
> > +    if (s->output_channels == channel || redundant)
> >          return;
> 
> Maybe add a small TODO in the comment to actually implement error recovery?
> 
> 
> >  
> >      /* generate the output signal */
> > @@ -814,15 +815,26 @@ int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
> >              active[i][j] = ff_opus_rc_dec_log(rc, 1);
> >  
> >          redundancy[i] = ff_opus_rc_dec_log(rc, 1);
> > -        if (redundancy[i]) {
> > -            avpriv_report_missing_feature(s->avctx, "LBRR frames");
> > -            return AVERROR_PATCHWELCOME;
> > -        }
> >      }
> >  
> > +    /* read the per-frame LBRR flags */
> > +    for (i = 0; i < coded_channels; i++)
> > +        if (redundancy[i] && duration_ms > 20) {
> > +            redundancy[i] = ff_opus_rc_dec_cdf(rc, duration_ms == 40 ?
> > +                                                   ff_silk_model_lbrr_flags_40 : ff_silk_model_lbrr_flags_60);
> > +        }
> > +
> > +    /* decode the LBRR frames */
> > +    for (i = 0; i < nb_frames; i++)
> > +        for (j = 0; j < coded_channels; j++)
> > +            if (redundancy[j] & (1 << i)) {
> > +                int active1 = (j == 0 && !(redundancy[1] & (1 << i))) ? 0 : 1;
> > +                silk_decode_frame(s, rc, i, j, coded_channels, 1, active1, 1);
> > +            }
> 
> nit: add brackets to the nb_frames loop
> 
> Apart from that LGTM.

Applied comments and pushed

-- 
Anton Khirnov


More information about the ffmpeg-devel mailing list