On 2012-02-13 19:42:45 +0100, Kostya Shishkov wrote:
> Since quantisation matrices are stored in context, decoding slices with
> different quantisers in parallel leads to unpredictable content of
> aforementioned matrices and wrong output picture thereof.
> ---
> Spotted while working on encoder.
> ---
>  libavcodec/proresdec.c |   23 ++++++++++++-----------
>  1 files changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c
> index 3095824..207fd97 100644
> --- a/libavcodec/proresdec.c
> +++ b/libavcodec/proresdec.c
> @@ -43,7 +43,10 @@ typedef struct {
>      int slice_num;
>      int x_pos, y_pos;
>      int slice_width;
> +    int prev_slice_sf;               ///< scalefactor of the previous 
> decoded slice
>      DECLARE_ALIGNED(16, DCTELEM, blocks)[8 * 4 * 64];
> +    DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
> +    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
>  } ProresThreadData;
>  
>  typedef struct {
> @@ -57,9 +60,6 @@ typedef struct {
>      uint8_t    qmat_luma[64];            ///< dequantization matrix for luma
>      uint8_t    qmat_chroma[64];          ///< dequantization matrix for 
> chroma
>      int        qmat_changed;             ///< 1 - global quantization 
> matrices changed
> -    int        prev_slice_sf;            ///< scalefactor of the previous 
> decoded slice
> -    DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
> -    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
>      int        total_slices;            ///< total number of slices in a 
> picture
>      ProresThreadData *slice_data;
>      int        pic_num;
> @@ -94,7 +94,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
>      ctx->scantable_type = -1;   // set scantable type to uninitialized
>      memset(ctx->qmat_luma, 4, 64);
>      memset(ctx->qmat_chroma, 4, 64);
> -    ctx->prev_slice_sf = 0;
>  
>      return 0;
>  }
> @@ -272,9 +271,11 @@ static int decode_picture_header(ProresContext *ctx, 
> const uint8_t *buf,
>  
>      for (i = 0; i < num_slices; i++) {
>          ctx->slice_data[i].index = data_ptr;
> +        ctx->slice_data[i].prev_slice_sf = 0;
>          data_ptr += AV_RB16(index_ptr + i * 2);
>      }
>      ctx->slice_data[i].index = data_ptr;
> +    ctx->slice_data[i].prev_slice_sf = 0;
>  
>      if (data_ptr > buf + data_size) {
>          av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
> @@ -509,11 +510,11 @@ static int decode_slice(AVCodecContext *avctx, void 
> *tdata)
>  
>      /* scale quantization matrixes according with slice's scale factor */
>      /* TODO: this can be SIMD-optimized a lot */
> -    if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
> -        ctx->prev_slice_sf = sf;
> +    if (ctx->qmat_changed || sf != td->prev_slice_sf) {
> +        td->prev_slice_sf = sf;
>          for (i = 0; i < 64; i++) {
> -            ctx->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = 
> ctx->qmat_luma[i]   * sf;
> -            ctx->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = 
> ctx->qmat_chroma[i] * sf;
> +            td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = 
> ctx->qmat_luma[i]   * sf;
> +            td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = 
> ctx->qmat_chroma[i] * sf;
>          }
>      }
>  
> @@ -522,7 +523,7 @@ static int decode_slice(AVCodecContext *avctx, void 
> *tdata)
>                         (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
>                                      (mb_x_pos << 5)), y_linesize,
>                         mbs_per_slice, 4, slice_width_factor + 2,
> -                       ctx->qmat_luma_scaled);
> +                       td->qmat_luma_scaled);
>  
>      /* decode U chroma plane */
>      decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
> @@ -530,7 +531,7 @@ static int decode_slice(AVCodecContext *avctx, void 
> *tdata)
>                                      (mb_x_pos << ctx->mb_chroma_factor)),
>                         u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
>                         slice_width_factor + ctx->chroma_factor - 1,
> -                       ctx->qmat_chroma_scaled);
> +                       td->qmat_chroma_scaled);
>  
>      /* decode V chroma plane */
>      decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
> @@ -539,7 +540,7 @@ static int decode_slice(AVCodecContext *avctx, void 
> *tdata)
>                                      (mb_x_pos << ctx->mb_chroma_factor)),
>                         v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
>                         slice_width_factor + ctx->chroma_factor - 1,
> -                       ctx->qmat_chroma_scaled);
> +                       td->qmat_chroma_scaled);
>  
>      return 0;
>  }

looks good

Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to