[FFmpeg-devel] [PATCH] libavcodec/opus: Add NULL pointer check for incoming data; avoid segfault

Rostislav Pehlivanov atomnuker at gmail.com
Thu Nov 23 03:02:22 EET 2017


On 23 November 2017 at 00:53, Colin NG <colin_ng at hotmail.com> wrote:

> ---
> Fix for ticket 7674
>
>  libavcodec/opus_pvq.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c
> index f98b85d..02ccd69 100644
> --- a/libavcodec/opus_pvq.c
> +++ b/libavcodec/opus_pvq.c
> @@ -504,6 +504,9 @@ static av_always_inline uint32_t
> quant_band_template(CeltPVQ *pvq, CeltFrame *f,
>      int longblocks = (B0 == 1);
>      uint32_t cm = 0;
>
> +     if (!X)
> +        return cm;
> +
>      if (N == 1) {
>          float *x = X;
>          for (i = 0; i <= stereo; i++) {
> @@ -795,7 +798,7 @@ static av_always_inline uint32_t
> quant_band_template(CeltPVQ *pvq, CeltFrame *f,
>              f->remaining2 -= curr_bits;
>          }
>
> -        if (q != 0) {
> +        if (X && !q) {
>              /* Finally do the actual (de)quantization */
>              if (quant) {
>                  cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7))
> << ((q >> 3) - 1),
> @@ -902,6 +905,9 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f,
> OpusRangeCoder *rc, int b
>      float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] <<
> f->size);
>      OPUS_RC_CHECKPOINT_SPAWN(rc);
>
> +    if (!X && !Y)
> +        return 0.0f;
> +
>      memcpy(X, X_orig, band_size*sizeof(float));
>      if (Y)
>          memcpy(Y, Y_orig, band_size*sizeof(float));
> @@ -911,7 +917,6 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f,
> OpusRangeCoder *rc, int b
>          int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band);
>          b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] +
> curr_balance), 14);
>      }
> -
>      if (f->dual_stereo) {
>          pvq->encode_band(pvq, f, rc, band, X, NULL, band_size, b / 2,
> f->blocks, NULL,
>                           f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]);
> @@ -925,7 +930,12 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame
> *f, OpusRangeCoder *rc, int b
>
>      for (i = 0; i < band_size; i++) {
>          err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]);
> -        err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]);
> +    }
> +
> +   if (Y) {
> +        for (i = 0; i < band_size; i++) {
> +            err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]);
> +        }
>      }
>
>      dist = sqrtf(err_x) + sqrtf(err_y);
> --
> 2.7.4
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>


I actually found out about this bug while working on it a few days ago but
wanted to wait until I got the opus_rc and some opusenc_psy improvements
fully done.
Pushed my fix for mono. I disagree with the rest. There should always be a
channel of audio (X) to analyze.


More information about the ffmpeg-devel mailing list