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;
 }
-- 
1.7.0.4

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

Reply via email to