[FFmpeg-cvslog] h264: move the quantizers into the per-slice context

Anton Khirnov git at videolan.org
Sat Mar 21 13:34:49 CET 2015


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Sat Jan 17 22:28:46 2015 +0100| [d231e84b06a9964c840cff4e228509f706165fb6] | committer: Anton Khirnov

h264: move the quantizers into the per-slice context

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d231e84b06a9964c840cff4e228509f706165fb6
---

 libavcodec/dxva2_h264.c       |    2 +-
 libavcodec/h264.h             |   15 ++++++-----
 libavcodec/h264_cabac.c       |   48 ++++++++++++++++++----------------
 libavcodec/h264_cavlc.c       |   43 ++++++++++++++++---------------
 libavcodec/h264_loopfilter.c  |   57 ++++++++++++++++++++++++++---------------
 libavcodec/h264_mb.c          |   10 +++++---
 libavcodec/h264_mb_template.c |   26 +++++++++----------
 libavcodec/h264_mvpred.h      |    4 +--
 libavcodec/h264_slice.c       |   42 +++++++++++++++---------------
 libavcodec/svq3.c             |   16 +++++++-----
 libavcodec/vaapi_h264.c       |    2 +-
 11 files changed, 145 insertions(+), 120 deletions(-)

diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index cb033a2..dbc5087 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -276,7 +276,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
         }
     }
     slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
-    slice->slice_qp_delta    = h->qscale - h->pps.init_qp;
+    slice->slice_qp_delta    = sl->qscale - h->pps.init_qp;
     slice->redundant_pic_cnt = h->redundant_pic_count;
     if (h->slice_type == AV_PICTURE_TYPE_B)
         slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index a8e1101..1820ca5 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -299,6 +299,9 @@ typedef struct H264Picture {
 typedef struct H264SliceContext {
     struct H264Context *h264;
 
+    int qscale;
+    int chroma_qp[2];   // QPc
+
     // Weighted pred stuff
     int use_weight;
     int use_weight_chroma;
@@ -332,7 +335,6 @@ typedef struct H264Context {
     int            nb_slice_ctx;
 
     int pixel_shift;    ///< 0 for 8-bit H264, 1 for high-bit-depth H264
-    int chroma_qp[2];   // QPc
 
     int qp_thresh;      ///< QP threshold to skip loopfilter
 
@@ -341,7 +343,6 @@ typedef struct H264Context {
     ptrdiff_t linesize, uvlinesize;
     int chroma_x_shift, chroma_y_shift;
 
-    int qscale;
     int droppable;
     int coded_picture_number;
     int low_delay;
@@ -804,15 +805,15 @@ void ff_h264_decode_init_vlc(void);
  * Decode a macroblock
  * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR on error
  */
-int ff_h264_decode_mb_cavlc(H264Context *h);
+int ff_h264_decode_mb_cavlc(H264Context *h, H264SliceContext *sl);
 
 /**
  * Decode a CABAC coded macroblock
  * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR on error
  */
-int ff_h264_decode_mb_cabac(H264Context *h);
+int ff_h264_decode_mb_cabac(H264Context *h, H264SliceContext *sl);
 
-void ff_h264_init_cabac_states(H264Context *h);
+void ff_h264_init_cabac_states(H264Context *h, H264SliceContext *sl);
 
 void h264_init_dequant_tables(H264Context *h);
 
@@ -820,10 +821,10 @@ void ff_h264_direct_dist_scale_factor(H264Context *const h);
 void ff_h264_direct_ref_list_init(H264Context *const h);
 void ff_h264_pred_direct_motion(H264Context *const h, int *mb_type);
 
-void ff_h264_filter_mb_fast(H264Context *h, int mb_x, int mb_y,
+void ff_h264_filter_mb_fast(H264Context *h, H264SliceContext *sl, int mb_x, int mb_y,
                             uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
                             unsigned int linesize, unsigned int uvlinesize);
-void ff_h264_filter_mb(H264Context *h, int mb_x, int mb_y,
+void ff_h264_filter_mb(H264Context *h, H264SliceContext *sl, int mb_x, int mb_y,
                        uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
                        unsigned int linesize, unsigned int uvlinesize);
 
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 0ad8ac0..5699bce 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -1261,10 +1261,11 @@ static const int8_t cabac_context_init_PB[3][1024][2] =
     }
 };
 
-void ff_h264_init_cabac_states(H264Context *h) {
+void ff_h264_init_cabac_states(H264Context *h, H264SliceContext *sl)
+{
     int i;
     const int8_t (*tab)[2];
-    const int slice_qp = av_clip(h->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
+    const int slice_qp = av_clip(sl->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_I ) tab = cabac_context_init_I;
     else                                 tab = cabac_context_init_PB[h->cabac_init_idc];
@@ -1830,12 +1831,14 @@ static av_always_inline void decode_cabac_residual_nondc(H264Context *h,
     decode_cabac_residual_nondc_internal( h, block, cat, n, scantable, qmul, max_coeff );
 }
 
-static av_always_inline void decode_cabac_luma_residual( H264Context *h, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p )
+static av_always_inline void decode_cabac_luma_residual(H264Context *h, H264SliceContext *sl,
+                                                        const uint8_t *scan, const uint8_t *scan8x8,
+                                                        int pixel_shift, int mb_type, int cbp, int p)
 {
     static const uint8_t ctx_cat[4][3] = {{0,6,10},{1,7,11},{2,8,12},{5,9,13}};
     const uint32_t *qmul;
     int i8x8, i4x4;
-    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
     if( IS_INTRA16x16( mb_type ) ) {
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -1880,7 +1883,8 @@ static av_always_inline void decode_cabac_luma_residual( H264Context *h, const u
  * Decode a macroblock.
  * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
  */
-int ff_h264_decode_mb_cabac(H264Context *h) {
+int ff_h264_decode_mb_cabac(H264Context *h, H264SliceContext *sl)
+{
     int mb_xy;
     int mb_type, partition_count, cbp = 0;
     int dct8x8_allowed= h->pps.transform_8x8_mode;
@@ -1906,7 +1910,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
                     h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
             }
 
-            decode_mb_skip(h);
+            decode_mb_skip(h, sl);
 
             h->cbp_table[mb_xy] = 0;
             h->chroma_pred_mode_table[mb_xy] = 0;
@@ -2323,11 +2327,11 @@ decode_intra_mb:
         const uint32_t *qmul;
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= h->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
-            scan= h->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8 = sl->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
+            scan    = sl->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= h->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
-            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8 = sl->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
+            scan    = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
         // decode_cabac_mb_dqp
@@ -2350,20 +2354,20 @@ decode_intra_mb:
             else
                 val= -((val + 1)>>1);
             h->last_qscale_diff = val;
-            h->qscale += val;
-            if(((unsigned)h->qscale) > max_qp){
-                if(h->qscale<0) h->qscale+= max_qp+1;
-                else            h->qscale-= max_qp+1;
+            sl->qscale += val;
+            if (((unsigned)sl->qscale) > max_qp){
+                if (sl->qscale < 0) sl->qscale += max_qp + 1;
+                else                sl->qscale -= max_qp + 1;
             }
-            h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
-            h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
+            sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+            sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
         }else
             h->last_qscale_diff=0;
 
-        decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 0);
+        decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 0);
         if (CHROMA444(h)) {
-            decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 1);
-            decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 2);
+            decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 1);
+            decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 2);
         } else if (CHROMA422(h)) {
             if( cbp&0x30 ){
                 int c;
@@ -2377,7 +2381,7 @@ decode_intra_mb:
                 int c, i, i8x8;
                 for( c = 0; c < 2; c++ ) {
                     int16_t *mb = h->mb + (16*(16 + 16*c) << pixel_shift);
-                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];
+                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];
                     for (i8x8 = 0; i8x8 < 2; i8x8++) {
                         for (i = 0; i < 4; i++) {
                             const int index = 16 + 16 * c + 8*i8x8 + i;
@@ -2400,7 +2404,7 @@ decode_intra_mb:
             if( cbp&0x20 ) {
                 int c, i;
                 for( c = 0; c < 2; c++ ) {
-                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];
+                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];
                     for( i = 0; i < 4; i++ ) {
                         const int index = 16 + 16 * c + i;
                         decode_cabac_residual_nondc(h, h->mb + (16*index << pixel_shift), 4, index, scan + 1, qmul, 15);
@@ -2418,7 +2422,7 @@ decode_intra_mb:
         h->last_qscale_diff = 0;
     }
 
-    h->cur_pic.qscale_table[mb_xy] = h->qscale;
+    h->cur_pic.qscale_table[mb_xy] = sl->qscale;
     write_back_non_zero_count(h);
 
     return 0;
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 0ab0355..0c517f1 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -623,9 +623,9 @@ static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, in
     return 0;
 }
 
-static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
+static av_always_inline int decode_luma_residual(H264Context *h, H264SliceContext *sl, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
     int i4x4, i8x8;
-    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
     if(IS_INTRA16x16(mb_type)){
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -689,7 +689,8 @@ static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *
     }
 }
 
-int ff_h264_decode_mb_cavlc(H264Context *h){
+int ff_h264_decode_mb_cavlc(H264Context *h, H264SliceContext *sl)
+{
     int mb_xy;
     int partition_count;
     unsigned int mb_type, cbp;
@@ -711,7 +712,7 @@ int ff_h264_decode_mb_cavlc(H264Context *h){
                 if(h->mb_skip_run==0)
                     h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
             }
-            decode_mb_skip(h);
+            decode_mb_skip(h, sl);
             return 0;
         }
     }
@@ -1082,38 +1083,38 @@ decode_intra_mb:
         const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= h->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
-            scan= h->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8 = sl->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
+            scan    = sl->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= h->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
-            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8 = sl->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
+            scan    = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
         dquant= get_se_golomb(&h->gb);
 
-        h->qscale += dquant;
+        sl->qscale += dquant;
 
-        if(((unsigned)h->qscale) > max_qp){
-            if(h->qscale<0) h->qscale+= max_qp+1;
-            else            h->qscale-= max_qp+1;
-            if(((unsigned)h->qscale) > max_qp){
+        if (((unsigned)sl->qscale) > max_qp){
+            if (sl->qscale < 0) sl->qscale += max_qp + 1;
+            else                sl->qscale -= max_qp+1;
+            if (((unsigned)sl->qscale) > max_qp){
                 av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, h->mb_x, h->mb_y);
                 return -1;
             }
         }
 
-        h->chroma_qp[0]= get_chroma_qp(h, 0, h->qscale);
-        h->chroma_qp[1]= get_chroma_qp(h, 1, h->qscale);
+        sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+        sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
 
-        if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){
+        if ((ret = decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ) {
             return -1;
         }
         h->cbp_table[mb_xy] |= ret << 12;
         if (CHROMA444(h)) {
-            if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){
+            if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ) {
                 return -1;
             }
-            if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){
+            if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ) {
                 return -1;
             }
         } else if (CHROMA422(h)) {
@@ -1128,7 +1129,7 @@ decode_intra_mb:
 
             if(cbp&0x20){
                 for(chroma_idx=0; chroma_idx<2; chroma_idx++){
-                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
+                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[chroma_idx]];
                     int16_t *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
                     for (i8x8 = 0; i8x8 < 2; i8x8++) {
                         for (i4x4 = 0; i4x4 < 4; i4x4++) {
@@ -1153,7 +1154,7 @@ decode_intra_mb:
 
             if(cbp&0x20){
                 for(chroma_idx=0; chroma_idx<2; chroma_idx++){
-                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
+                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[chroma_idx]];
                     for(i4x4=0; i4x4<4; i4x4++){
                         const int index= 16 + 16*chroma_idx + i4x4;
                         if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){
@@ -1171,7 +1172,7 @@ decode_intra_mb:
         fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
         fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
     }
-    h->cur_pic.qscale_table[mb_xy] = h->qscale;
+    h->cur_pic.qscale_table[mb_xy] = sl->qscale;
     write_back_non_zero_count(h);
 
     return 0;
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index a15130c..f645728 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -415,10 +415,14 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
     }
 }
 
-void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
+void ff_h264_filter_mb_fast(H264Context *h, H264SliceContext *sl,
+                            int mb_x, int mb_y, uint8_t *img_y,
+                            uint8_t *img_cb, uint8_t *img_cr,
+                            unsigned int linesize, unsigned int uvlinesize)
+{
     assert(!FRAME_MBAFF(h));
     if(!h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) {
-        ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
+        ff_h264_filter_mb(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
         return;
     }
 
@@ -462,7 +466,14 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
     return v;
 }
 
-static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir) {
+static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl,
+                                           int mb_x, int mb_y,
+                                           uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
+                                           unsigned int linesize, unsigned int uvlinesize,
+                                           int mb_xy, int mb_type, int mvy_limit,
+                                           int first_vertical_edge_done, int a, int b,
+                                           int chroma, int dir)
+{
     int edge;
     int chroma_qp_avg[2];
     int chroma444 = CHROMA444(h);
@@ -518,8 +529,8 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
                 tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
                 { int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (sl->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (sl->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
                 if (chroma) {
                     if (chroma444) {
                         filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
@@ -581,8 +592,8 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             if(bS[0]+bS[1]+bS[2]+bS[3]){
                 qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbm_xy] + 1) >> 1;
                 tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (sl->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (sl->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
                 if( dir == 0 ) {
                     filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
                     if (chroma) {
@@ -668,11 +679,11 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
             if (chroma) {
                 if (chroma444) {
-                    filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
-                    filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+                    filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
+                    filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
                 } else if( (edge&1) == 0 ) {
-                    filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
-                    filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+                    filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
+                    filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
                 }
             }
         } else {
@@ -680,18 +691,18 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
                 if (deblock_edge)
                     filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
                 if (chroma) {
-                    filter_mb_edgech(&img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
-                    filter_mb_edgech(&img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+                    filter_mb_edgech(&img_cb[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
+                    filter_mb_edgech(&img_cr[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
                 }
             } else {
                 filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
                 if (chroma) {
                     if (chroma444) {
-                        filter_mb_edgeh (&img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
-                        filter_mb_edgeh (&img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+                        filter_mb_edgeh (&img_cb[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
+                        filter_mb_edgeh (&img_cr[4*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
                     } else if ((edge&1) == 0) {
-                        filter_mb_edgech(&img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
-                        filter_mb_edgech(&img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+                        filter_mb_edgech(&img_cb[2*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[0], a, b, h, 0);
+                        filter_mb_edgech(&img_cr[2*edge*uvlinesize], uvlinesize, bS, sl->chroma_qp[1], a, b, h, 0);
                     }
                 }
             }
@@ -699,7 +710,11 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
     }
 }
 
-void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
+void ff_h264_filter_mb(H264Context *h, H264SliceContext *sl,
+                       int mb_x, int mb_y,
+                       uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
+                       unsigned int linesize, unsigned int uvlinesize)
+{
     const int mb_xy= mb_x + mb_y*h->mb_stride;
     const int mb_type = h->cur_pic.mb_type[mb_xy];
     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
@@ -817,13 +832,13 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
     {
         int dir;
         for (dir = 0; dir < 2; dir++)
-            filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize,
+            filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize,
                           uvlinesize, mb_xy, mb_type, mvy_limit,
                           dir ? 0 : first_vertical_edge_done, a, b,
                           chroma, dir);
     }
 #else
-    filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, a, b, chroma, 0);
-    filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0,                        a, b, chroma, 1);
+    filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, a, b, chroma, 0);
+    filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0,                        a, b, chroma, 1);
 #endif
 }
diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c
index b2899b6..86beb19 100644
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -605,6 +605,7 @@ static av_always_inline void dctcoef_set(int16_t *mb, int high_bit_depth,
 }
 
 static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
+                                                       H264SliceContext *sl,
                                                        int mb_type, int is_h264,
                                                        int simple,
                                                        int transform_bypass,
@@ -616,7 +617,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
     void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
     void (*idct_dc_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
-    int qscale = p == 0 ? h->qscale : h->chroma_qp[p - 1];
+    int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
     block_offset += 16 * p;
     if (IS_INTRA4x4(mb_type)) {
         if (IS_8x8DCT(mb_type)) {
@@ -720,7 +721,8 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
     }
 }
 
-static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
+static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, H264SliceContext *sl,
+                                                    int mb_type,
                                                     int is_h264, int simple,
                                                     int transform_bypass,
                                                     int pixel_shift,
@@ -784,7 +786,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                     // FIXME benchmark weird rule, & below
                     uint8_t *const ptr = dest_y + block_offset[i];
                     ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize,
-                                       h->qscale, IS_INTRA(mb_type) ? 1 : 0);
+                                       sl->qscale, IS_INTRA(mb_type) ? 1 : 0);
                 }
         }
     }
@@ -807,7 +809,7 @@ void ff_h264_hl_decode_mb(H264Context *h, H264SliceContext *sl)
     const int mb_xy   = h->mb_xy;
     const int mb_type = h->cur_pic.mb_type[mb_xy];
     int is_complex    = CONFIG_SMALL || h->is_complex ||
-                        IS_INTRA_PCM(mb_type) || h->qscale == 0;
+                        IS_INTRA_PCM(mb_type) || sl->qscale == 0;
 
     if (CHROMA444(h)) {
         if (is_complex || h->pixel_shift)
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index 262ad0c..4805f69 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -50,7 +50,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl)
     int linesize, uvlinesize /*dct_offset*/;
     int i, j;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
+    const int transform_bypass = !SIMPLE && (sl->qscale == 0 && h->sps.transform_bypass);
     /* is_h264 should always be true if SVQ3 is disabled. */
     const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || h->avctx->codec_id == AV_CODEC_ID_H264;
     void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
@@ -167,7 +167,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl)
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cr, uvlinesize);
             }
 
-            hl_decode_mb_predict_luma(h, mb_type, is_h264, SIMPLE,
+            hl_decode_mb_predict_luma(h, sl, mb_type, is_h264, SIMPLE,
                                       transform_bypass, PIXEL_SHIFT,
                                       block_offset, linesize, dest_y, 0);
 
@@ -190,7 +190,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl)
             }
         }
 
-        hl_decode_mb_idct_luma(h, mb_type, is_h264, SIMPLE, transform_bypass,
+        hl_decode_mb_idct_luma(h, sl, mb_type, is_h264, SIMPLE, transform_bypass,
                                PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
 
         if ((SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) &&
@@ -231,11 +231,11 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl)
                 if (is_h264) {
                     int qp[2];
                     if (chroma422) {
-                        qp[0] = h->chroma_qp[0] + 3;
-                        qp[1] = h->chroma_qp[1] + 3;
+                        qp[0] = sl->chroma_qp[0] + 3;
+                        qp[1] = sl->chroma_qp[1] + 3;
                     } else {
-                        qp[0] = h->chroma_qp[0];
-                        qp[1] = h->chroma_qp[1];
+                        qp[0] = sl->chroma_qp[0];
+                        qp[1] = sl->chroma_qp[1];
                     }
                     if (h->non_zero_count_cache[scan8[CHROMA_DC_BLOCK_INDEX + 0]])
                         h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16 * 16 * 1 << PIXEL_SHIFT),
@@ -248,16 +248,16 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl)
                                               h->non_zero_count_cache);
                 } else if (CONFIG_SVQ3_DECODER) {
                     h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16 * 16 * 1,
-                                                           h->dequant4_coeff[IS_INTRA(mb_type) ? 1 : 4][h->chroma_qp[0]][0]);
+                                                           h->dequant4_coeff[IS_INTRA(mb_type) ? 1 : 4][sl->chroma_qp[0]][0]);
                     h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 16 * 16 * 2,
-                                                           h->dequant4_coeff[IS_INTRA(mb_type) ? 2 : 5][h->chroma_qp[1]][0]);
+                                                           h->dequant4_coeff[IS_INTRA(mb_type) ? 2 : 5][sl->chroma_qp[1]][0]);
                     for (j = 1; j < 3; j++) {
                         for (i = j * 16; i < j * 16 + 4; i++)
                             if (h->non_zero_count_cache[scan8[i]] || h->mb[i * 16]) {
                                 uint8_t *const ptr = dest[j - 1] + block_offset[i];
                                 ff_svq3_add_idct_c(ptr, h->mb + i * 16,
                                                    uvlinesize,
-                                                   ff_h264_chroma_qp[0][h->qscale + 12] - 12, 2);
+                                                   ff_h264_chroma_qp[0][sl->qscale + 12] - 12, 2);
                             }
                     }
                 }
@@ -282,7 +282,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h, H264SliceContext
     int linesize;
     int i, j, p;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
+    const int transform_bypass = !SIMPLE && (sl->qscale == 0 && h->sps.transform_bypass);
     const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
 
     for (p = 0; p < plane_count; p++) {
@@ -347,7 +347,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h, H264SliceContext
                                linesize, 1, 1, SIMPLE, PIXEL_SHIFT);
 
             for (p = 0; p < plane_count; p++)
-                hl_decode_mb_predict_luma(h, mb_type, 1, SIMPLE,
+                hl_decode_mb_predict_luma(h, sl, mb_type, 1, SIMPLE,
                                           transform_bypass, PIXEL_SHIFT,
                                           block_offset, linesize, dest[p], p);
 
@@ -363,7 +363,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h, H264SliceContext
         }
 
         for (p = 0; p < plane_count; p++)
-            hl_decode_mb_idct_luma(h, mb_type, 1, SIMPLE, transform_bypass,
+            hl_decode_mb_idct_luma(h, sl, mb_type, 1, SIMPLE, transform_bypass,
                                    PIXEL_SHIFT, block_offset, linesize,
                                    dest[p], p);
     }
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index f7c3887..e89e91e 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -794,7 +794,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
 /**
  * decodes a P_SKIP or B_SKIP macroblock
  */
-static void av_unused decode_mb_skip(H264Context *h)
+static void av_unused decode_mb_skip(H264Context *h, H264SliceContext *sl)
 {
     const int mb_xy = h->mb_xy;
     int mb_type     = 0;
@@ -822,7 +822,7 @@ static void av_unused decode_mb_skip(H264Context *h)
 
     write_back_motion(h, mb_type);
     h->cur_pic.mb_type[mb_xy]      = mb_type;
-    h->cur_pic.qscale_table[mb_xy] = h->qscale;
+    h->cur_pic.qscale_table[mb_xy] = sl->qscale;
     h->slice_table[mb_xy]            = h->slice_num;
     h->prev_mb_skipped               = 1;
 }
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d6ae9e7..4e0384b 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1663,9 +1663,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
         av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
         return AVERROR_INVALIDDATA;
     }
-    h->qscale       = tmp;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
+    sl->qscale       = tmp;
+    sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+    sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
     // FIXME qscale / qp ... stuff
     if (h->slice_type == AV_PICTURE_TYPE_SP)
         get_bits1(&h->gb); /* sp_for_switch_flag */
@@ -1790,7 +1790,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
                h->cur_pic_ptr->field_poc[0],
                h->cur_pic_ptr->field_poc[1],
                h->ref_count[0], h->ref_count[1],
-               h->qscale,
+               sl->qscale,
                h->deblocking_filter,
                h->slice_alpha_c0_offset, h->slice_beta_offset,
                sl->use_weight,
@@ -2048,7 +2048,7 @@ static int fill_filter_caches(H264Context *h, int mb_type)
     return 0;
 }
 
-static void loop_filter(H264Context *h, int start_x, int end_x)
+static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int end_x)
 {
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize, mb_x, mb_y;
@@ -2098,14 +2098,14 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
                                  uvlinesize, 0);
                 if (fill_filter_caches(h, mb_type))
                     continue;
-                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);
-                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);
+                sl->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);
+                sl->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);
 
                 if (FRAME_MBAFF(h)) {
-                    ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr,
+                    ff_h264_filter_mb(h, sl, mb_x, mb_y, dest_y, dest_cb, dest_cr,
                                       linesize, uvlinesize);
                 } else {
-                    ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb,
+                    ff_h264_filter_mb_fast(h, sl, mb_x, mb_y, dest_y, dest_cb,
                                            dest_cr, linesize, uvlinesize);
                 }
             }
@@ -2113,8 +2113,8 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
     h->slice_type   = old_slice_type;
     h->mb_x         = end_x;
     h->mb_y         = end_mb_y - FRAME_MBAFF(h);
-    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
+    sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+    sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
 }
 
 static void predict_field_decoding_flag(H264Context *h)
@@ -2193,11 +2193,11 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                               h->gb.buffer + get_bits_count(&h->gb) / 8,
                               (get_bits_left(&h->gb) + 7) / 8);
 
-        ff_h264_init_cabac_states(h);
+        ff_h264_init_cabac_states(h, sl);
 
         for (;;) {
             // START_TIMER
-            int ret = ff_h264_decode_mb_cabac(h);
+            int ret = ff_h264_decode_mb_cabac(h, sl);
             int eos;
             // STOP_TIMER("decode_mb_cabac")
 
@@ -2208,7 +2208,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             if (ret >= 0 && FRAME_MBAFF(h)) {
                 h->mb_y++;
 
-                ret = ff_h264_decode_mb_cabac(h);
+                ret = ff_h264_decode_mb_cabac(h, sl);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h, sl);
@@ -2221,7 +2221,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
                              h->mb_y, ER_MB_END);
                 if (h->mb_x >= lf_x_start)
-                    loop_filter(h, lf_x_start, h->mb_x + 1);
+                    loop_filter(h, sl, lf_x_start, h->mb_x + 1);
                 return 0;
             }
             if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
@@ -2235,7 +2235,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             }
 
             if (++h->mb_x >= h->mb_width) {
-                loop_filter(h, lf_x_start, h->mb_x);
+                loop_filter(h, sl, lf_x_start, h->mb_x);
                 h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
                 ++h->mb_y;
@@ -2252,13 +2252,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
                              h->mb_y, ER_MB_END);
                 if (h->mb_x > lf_x_start)
-                    loop_filter(h, lf_x_start, h->mb_x);
+                    loop_filter(h, sl, lf_x_start, h->mb_x);
                 return 0;
             }
         }
     } else {
         for (;;) {
-            int ret = ff_h264_decode_mb_cavlc(h);
+            int ret = ff_h264_decode_mb_cavlc(h, sl);
 
             if (ret >= 0)
                 ff_h264_hl_decode_mb(h, sl);
@@ -2266,7 +2266,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF(h)) {
                 h->mb_y++;
-                ret = ff_h264_decode_mb_cavlc(h);
+                ret = ff_h264_decode_mb_cavlc(h, sl);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h, sl);
@@ -2282,7 +2282,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             }
 
             if (++h->mb_x >= h->mb_width) {
-                loop_filter(h, lf_x_start, h->mb_x);
+                loop_filter(h, sl, lf_x_start, h->mb_x);
                 h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
                 ++h->mb_y;
@@ -2317,7 +2317,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                     er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
                                  h->mb_x - 1, h->mb_y, ER_MB_END);
                     if (h->mb_x > lf_x_start)
-                        loop_filter(h, lf_x_start, h->mb_x);
+                        loop_filter(h, sl, lf_x_start, h->mb_x);
 
                     return 0;
                 } else {
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index aa2911d..e6e4b0d 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -481,6 +481,7 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
 static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 {
     H264Context *h = &s->h;
+    H264SliceContext *sl = &h->slice_ctx[0];
     int i, j, k, m, dir, mode;
     int cbp = 0;
     uint32_t vlc;
@@ -697,10 +698,10 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
     }
     if (IS_INTRA16x16(mb_type) ||
         (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
-        h->qscale += svq3_get_se_golomb(&h->gb);
+        sl->qscale += svq3_get_se_golomb(&h->gb);
 
-        if (h->qscale > 31u) {
-            av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", h->qscale);
+        if (sl->qscale > 31u) {
+            av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", sl->qscale);
             return -1;
         }
     }
@@ -716,7 +717,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 
     if (cbp) {
         const int index = IS_INTRA16x16(mb_type) ? 1 : 0;
-        const int type  = ((h->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
+        const int type  = ((sl->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
 
         for (i = 0; i < 4; i++)
             if ((cbp & (1 << i))) {
@@ -772,6 +773,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx)
 {
     SVQ3Context *s = avctx->priv_data;
     H264Context *h    = &s->h;
+    H264SliceContext *sl = &h->slice_ctx[0];
     const int mb_xy   = h->mb_xy;
     int i, header;
     unsigned slice_id;
@@ -826,7 +828,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx)
     }
 
     h->slice_num      = get_bits(&h->gb, 8);
-    h->qscale         = get_bits(&h->gb, 5);
+    sl->qscale         = get_bits(&h->gb, 5);
     s->adaptive_quant = get_bits1(&h->gb);
 
     /* unknown fields */
@@ -891,7 +893,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
     avctx->pix_fmt     = AV_PIX_FMT_YUVJ420P;
     avctx->color_range = AVCOL_RANGE_JPEG;
 
-    h->chroma_qp[0] = h->chroma_qp[1] = 4;
+    h->slice_ctx[0].chroma_qp[0] = h->slice_ctx[0].chroma_qp[1] = 4;
     h->chroma_x_shift = h->chroma_y_shift = 1;
 
     s->halfpel_flag  = 1;
@@ -1194,7 +1196,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
                "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
                av_get_picture_type_char(h->pict_type),
                s->halfpel_flag, s->thirdpel_flag,
-               s->adaptive_quant, h->qscale, h->slice_num);
+               s->adaptive_quant, h->slice_ctx[0].qscale, h->slice_num);
 
     if (avctx->skip_frame >= AVDISCARD_NONREF && h->pict_type == AV_PICTURE_TYPE_B ||
         avctx->skip_frame >= AVDISCARD_NONKEY && h->pict_type != AV_PICTURE_TYPE_I ||
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index d910dba..d88b548 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -334,7 +334,7 @@ static int vaapi_h264_decode_slice(AVCodecContext *avctx,
     slice_param->num_ref_idx_l0_active_minus1   = h->list_count > 0 ? h->ref_count[0] - 1 : 0;
     slice_param->num_ref_idx_l1_active_minus1   = h->list_count > 1 ? h->ref_count[1] - 1 : 0;
     slice_param->cabac_init_idc                 = h->cabac_init_idc;
-    slice_param->slice_qp_delta                 = h->qscale - h->pps.init_qp;
+    slice_param->slice_qp_delta                 = sl->qscale - h->pps.init_qp;
     slice_param->disable_deblocking_filter_idc  = h->deblocking_filter < 2 ? !h->deblocking_filter : h->deblocking_filter;
     slice_param->slice_alpha_c0_offset_div2     = h->slice_alpha_c0_offset / 2;
     slice_param->slice_beta_offset_div2         = h->slice_beta_offset     / 2;




More information about the ffmpeg-cvslog mailing list