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