diff mbox series

[FFmpeg-devel,09/42] lavc/hevcdec: move HEVCContext.bs_{width, height} to HEVCLayerContext

Message ID 20240827154041.13846-11-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/42] lavu/opt: add API for setting array-type option values | expand

Checks

Context Check Description
yinshiyou/make_fate_loongarch64 success Make fate finished
yinshiyou/make_loongarch64 warning New warnings during build
andriy/make_fate_x86 success Make fate finished
andriy/make_x86 warning New warnings during build

Commit Message

Anton Khirnov Aug. 27, 2024, 3:04 p.m. UTC
---
 libavcodec/hevc/filter.c  | 43 ++++++++++++-----------
 libavcodec/hevc/hevcdec.c | 73 ++++++++++++++++++++++-----------------
 libavcodec/hevc/hevcdec.h | 14 +++++---
 3 files changed, 73 insertions(+), 57 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/hevc/filter.c b/libavcodec/hevc/filter.c
index 56e354b486..18c73dc2fa 100644
--- a/libavcodec/hevc/filter.c
+++ b/libavcodec/hevc/filter.c
@@ -495,7 +495,7 @@  static int get_pcm(const HEVCSPS *sps, const uint8_t *is_pcm, int x, int y)
                     (tc_offset & -2),                                   \
                     0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
 
-static void deblocking_filter_CTB(const HEVCContext *s,
+static void deblocking_filter_CTB(const HEVCContext *s, const HEVCLayerContext *l,
                                   const HEVCPPS *pps, const HEVCSPS *sps,
                                   int x0, int y0)
 {
@@ -546,8 +546,8 @@  static void deblocking_filter_CTB(const HEVCContext *s,
     for (y = y0; y < y_end; y += 8) {
         // vertical filtering luma
         for (x = x0 ? x0 : 8; x < x_end; x += 8) {
-            const int bs0 = s->vertical_bs[(x +  y      * s->bs_width) >> 2];
-            const int bs1 = s->vertical_bs[(x + (y + 4) * s->bs_width) >> 2];
+            const int bs0 = s->vertical_bs[(x +  y      * l->bs_width) >> 2];
+            const int bs1 = s->vertical_bs[(x + (y + 4) * l->bs_width) >> 2];
             if (bs0 || bs1) {
                 const int qp = (get_qPy(sps, s->qp_y_tab, x - 1, y) +
                                 get_qPy(sps, s->qp_y_tab, x,     y) + 1) >> 1;
@@ -575,8 +575,8 @@  static void deblocking_filter_CTB(const HEVCContext *s,
 
         // horizontal filtering luma
         for (x = x0 ? x0 - 8 : 0; x < x_end2; x += 8) {
-            const int bs0 = s->horizontal_bs[( x      + y * s->bs_width) >> 2];
-            const int bs1 = s->horizontal_bs[((x + 4) + y * s->bs_width) >> 2];
+            const int bs0 = s->horizontal_bs[( x      + y * l->bs_width) >> 2];
+            const int bs1 = s->horizontal_bs[((x + 4) + y * l->bs_width) >> 2];
             if (bs0 || bs1) {
                 const int qp = (get_qPy(sps, s->qp_y_tab, x, y - 1) +
                                 get_qPy(sps, s->qp_y_tab, x, y)     + 1) >> 1;
@@ -610,8 +610,8 @@  static void deblocking_filter_CTB(const HEVCContext *s,
             // vertical filtering chroma
             for (y = y0; y < y_end; y += (8 * v)) {
                 for (x = x0 ? x0 : 8 * h; x < x_end; x += (8 * h)) {
-                    const int bs0 = s->vertical_bs[(x +  y            * s->bs_width) >> 2];
-                    const int bs1 = s->vertical_bs[(x + (y + (4 * v)) * s->bs_width) >> 2];
+                    const int bs0 = s->vertical_bs[(x +  y            * l->bs_width) >> 2];
+                    const int bs1 = s->vertical_bs[(x + (y + (4 * v)) * l->bs_width) >> 2];
 
                     if ((bs0 == 2) || (bs1 == 2)) {
                         const int qp0 = (get_qPy(sps, s->qp_y_tab, x - 1, y) +
@@ -644,8 +644,8 @@  static void deblocking_filter_CTB(const HEVCContext *s,
                 if (x_end != sps->width)
                     x_end2 = x_end - 8 * h;
                 for (x = x0 ? x0 - 8 * h : 0; x < x_end2; x += (8 * h)) {
-                    const int bs0 = s->horizontal_bs[( x          + y * s->bs_width) >> 2];
-                    const int bs1 = s->horizontal_bs[((x + 4 * h) + y * s->bs_width) >> 2];
+                    const int bs0 = s->horizontal_bs[( x          + y * l->bs_width) >> 2];
+                    const int bs1 = s->horizontal_bs[((x + 4 * h) + y * l->bs_width) >> 2];
                     if ((bs0 == 2) || (bs1 == 2)) {
                         const int qp0 = bs0 == 2 ? (get_qPy(sps, s->qp_y_tab, x,           y - 1) +
                                                     get_qPy(sps, s->qp_y_tab, x,           y)     + 1) >> 1 : 0;
@@ -736,7 +736,8 @@  static int boundary_strength(const HEVCContext *s, const MvField *curr, const Mv
     return 1;
 }
 
-void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *pps,
+void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                                           const HEVCPPS *pps,
                                            int x0, int y0, int log2_trafo_size)
 {
     const HEVCSPS *const sps = pps->sps;
@@ -784,7 +785,7 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *
                     bs = 1;
                 else
                     bs = boundary_strength(s, curr, top, rpl_top);
-                s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
+                s->horizontal_bs[((x0 + i) + y0 * l->bs_width) >> 2] = bs;
             }
     }
 
@@ -822,7 +823,7 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *
                     bs = 1;
                 else
                     bs = boundary_strength(s, curr, left, rpl_left);
-                s->vertical_bs[(x0 + (y0 + i) * s->bs_width) >> 2] = bs;
+                s->vertical_bs[(x0 + (y0 + i) * l->bs_width) >> 2] = bs;
             }
     }
 
@@ -840,7 +841,7 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *
                 const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
 
                 bs = boundary_strength(s, curr, top, rpl);
-                s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
+                s->horizontal_bs[((x0 + i) + (y0 + j) * l->bs_width) >> 2] = bs;
             }
         }
 
@@ -855,7 +856,7 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *
                 const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
 
                 bs = boundary_strength(s, curr, left, rpl);
-                s->vertical_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
+                s->vertical_bs[((x0 + i) + (y0 + j) * l->bs_width) >> 2] = bs;
             }
         }
     }
@@ -865,7 +866,8 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *
 #undef CB
 #undef CR
 
-void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCPPS *pps,
+void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                        const HEVCPPS *pps,
                         int x, int y, int ctb_size)
 {
     const HEVCSPS   *const sps = pps->sps;
@@ -883,7 +885,7 @@  void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCPPS *pps,
         skip = 1;
 
     if (!skip)
-        deblocking_filter_CTB(s, pps, sps, x, y);
+        deblocking_filter_CTB(s, l, pps, sps, x, y);
     if (sps->sao_enabled && !skip) {
         int y_end = y >= sps->height - ctb_size;
         if (y && x)
@@ -904,15 +906,16 @@  void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCPPS *pps,
         ff_progress_frame_report(&s->cur_frame->tf, y + ctb_size - 4);
 }
 
-void ff_hevc_hls_filters(HEVCLocalContext *lc, const HEVCPPS *pps,
+void ff_hevc_hls_filters(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                         const HEVCPPS *pps,
                          int x_ctb, int y_ctb, int ctb_size)
 {
     int x_end = x_ctb >= pps->sps->width  - ctb_size;
     int y_end = y_ctb >= pps->sps->height - ctb_size;
     if (y_ctb && x_ctb)
-        ff_hevc_hls_filter(lc, pps, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
+        ff_hevc_hls_filter(lc, l, pps, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
     if (y_ctb && x_end)
-        ff_hevc_hls_filter(lc, pps, x_ctb, y_ctb - ctb_size, ctb_size);
+        ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb - ctb_size, ctb_size);
     if (x_ctb && y_end)
-        ff_hevc_hls_filter(lc, pps, x_ctb - ctb_size, y_ctb, ctb_size);
+        ff_hevc_hls_filter(lc, l, pps, x_ctb - ctb_size, y_ctb, ctb_size);
 }
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index b44bc93507..4978aa745c 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -90,7 +90,7 @@  static void pic_arrays_free(HEVCContext *s)
 }
 
 /* allocate arrays that depend on frame dimensions */
-static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
+static int pic_arrays_init(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
 {
     int log2_min_cb_size = sps->log2_min_cb_size;
     int width            = sps->width;
@@ -100,8 +100,8 @@  static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
     int ctb_count        = sps->ctb_width * sps->ctb_height;
     int min_pu_size      = sps->min_pu_width * sps->min_pu_height;
 
-    s->bs_width  = (width  >> 2) + 1;
-    s->bs_height = (height >> 2) + 1;
+    l->bs_width  = (width  >> 2) + 1;
+    l->bs_height = (height >> 2) + 1;
 
     s->sao           = av_calloc(ctb_count, sizeof(*s->sao));
     s->deblock       = av_calloc(ctb_count, sizeof(*s->deblock));
@@ -127,8 +127,8 @@  static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
     if (!s->qp_y_tab || !s->filter_slice_edges || !s->tab_slice_address)
         goto fail;
 
-    s->horizontal_bs = av_calloc(s->bs_width, s->bs_height);
-    s->vertical_bs   = av_calloc(s->bs_width, s->bs_height);
+    s->horizontal_bs = av_calloc(l->bs_width, l->bs_height);
+    s->vertical_bs   = av_calloc(l->bs_width, l->bs_height);
     if (!s->horizontal_bs || !s->vertical_bs)
         goto fail;
 
@@ -527,7 +527,7 @@  static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
     return ff_get_format(s->avctx, pix_fmts);
 }
 
-static int set_sps(HEVCContext *s, const HEVCSPS *sps)
+static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
 {
     int ret, i;
 
@@ -538,7 +538,7 @@  static int set_sps(HEVCContext *s, const HEVCSPS *sps)
     if (!sps)
         return 0;
 
-    ret = pic_arrays_init(s, sps);
+    ret = pic_arrays_init(s, l, sps);
     if (ret < 0)
         goto fail;
 
@@ -1317,6 +1317,7 @@  static void set_deblocking_bypass(const HEVCContext *s, const HEVCSPS *sps,
 }
 
 static int hls_transform_tree(HEVCLocalContext *lc,
+                              const HEVCLayerContext *l,
                               const HEVCPPS *pps, const HEVCSPS *sps,
                               int x0, int y0,
                               int xBase, int yBase, int cb_xBase, int cb_yBase,
@@ -1391,7 +1392,7 @@  static int hls_transform_tree(HEVCLocalContext *lc,
 
 #define SUBDIVIDE(x, y, idx)                                                    \
 do {                                                                            \
-    ret = hls_transform_tree(lc, pps, sps,                                      \
+    ret = hls_transform_tree(lc, l, pps, sps,                                   \
                              x, y, x0, y0, cb_xBase, cb_yBase, log2_cb_size,    \
                              log2_trafo_size - 1, trafo_depth + 1, idx,         \
                              cbf_cb, cbf_cr);                                   \
@@ -1434,7 +1435,7 @@  do {
                 }
         }
         if (!s->sh.disable_deblocking_filter_flag) {
-            ff_hevc_deblocking_boundary_strengths(lc, pps, x0, y0, log2_trafo_size);
+            ff_hevc_deblocking_boundary_strengths(lc, l, pps, x0, y0, log2_trafo_size);
             if (pps->transquant_bypass_enable_flag &&
                 lc->cu.cu_transquant_bypass_flag)
                 set_deblocking_bypass(s, sps, x0, y0, log2_trafo_size);
@@ -1443,8 +1444,8 @@  do {
     return 0;
 }
 
-static int hls_pcm_sample(HEVCLocalContext *lc, const HEVCPPS *pps,
-                          int x0, int y0, int log2_cb_size)
+static int hls_pcm_sample(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                          const HEVCPPS *pps, int x0, int y0, int log2_cb_size)
 {
     const HEVCContext *const s = lc->parent;
     const HEVCSPS   *const sps = pps->sps;
@@ -1465,7 +1466,7 @@  static int hls_pcm_sample(HEVCLocalContext *lc, const HEVCPPS *pps,
     int ret;
 
     if (!s->sh.disable_deblocking_filter_flag)
-        ff_hevc_deblocking_boundary_strengths(lc, pps, x0, y0, log2_cb_size);
+        ff_hevc_deblocking_boundary_strengths(lc, l, pps, x0, y0, log2_cb_size);
 
     ret = init_get_bits(&gb, pcm, length);
     if (ret < 0)
@@ -2200,6 +2201,7 @@  static void intra_prediction_unit_default_value(HEVCLocalContext *lc,
 }
 
 static int hls_coding_unit(HEVCLocalContext *lc, const HEVCContext *s,
+                           const HEVCLayerContext *l,
                            const HEVCPPS *pps, const HEVCSPS *sps,
                            int x0, int y0, int log2_cb_size)
 {
@@ -2255,7 +2257,7 @@  static int hls_coding_unit(HEVCLocalContext *lc, const HEVCContext *s,
         intra_prediction_unit_default_value(lc, sps, x0, y0, log2_cb_size);
 
         if (!s->sh.disable_deblocking_filter_flag)
-            ff_hevc_deblocking_boundary_strengths(lc, pps, x0, y0, log2_cb_size);
+            ff_hevc_deblocking_boundary_strengths(lc, l, pps, x0, y0, log2_cb_size);
     } else {
         int pcm_flag = 0;
 
@@ -2276,7 +2278,7 @@  static int hls_coding_unit(HEVCLocalContext *lc, const HEVCContext *s,
             }
             if (pcm_flag) {
                 intra_prediction_unit_default_value(lc, sps, x0, y0, log2_cb_size);
-                ret = hls_pcm_sample(lc, pps, x0, y0, log2_cb_size);
+                ret = hls_pcm_sample(lc, l, pps, x0, y0, log2_cb_size);
                 if (sps->pcm_loop_filter_disabled)
                     set_deblocking_bypass(s, sps, x0, y0, log2_cb_size);
 
@@ -2353,14 +2355,14 @@  static int hls_coding_unit(HEVCLocalContext *lc, const HEVCContext *s,
                 lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?
                                          sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
                                          sps->max_transform_hierarchy_depth_inter;
-                ret = hls_transform_tree(lc, pps, sps, x0, y0, x0, y0, x0, y0,
+                ret = hls_transform_tree(lc, l, pps, sps, x0, y0, x0, y0, x0, y0,
                                          log2_cb_size,
                                          log2_cb_size, 0, 0, cbf, cbf);
                 if (ret < 0)
                     return ret;
             } else {
                 if (!s->sh.disable_deblocking_filter_flag)
-                    ff_hevc_deblocking_boundary_strengths(lc, pps, x0, y0, log2_cb_size);
+                    ff_hevc_deblocking_boundary_strengths(lc, l, pps, x0, y0, log2_cb_size);
             }
         }
     }
@@ -2385,6 +2387,7 @@  static int hls_coding_unit(HEVCLocalContext *lc, const HEVCContext *s,
 }
 
 static int hls_coding_quadtree(HEVCLocalContext *lc,
+                               const HEVCLayerContext *l,
                                const HEVCPPS *pps, const HEVCSPS *sps,
                                int x0, int y0,
                                int log2_cb_size, int cb_depth)
@@ -2421,23 +2424,27 @@  static int hls_coding_quadtree(HEVCLocalContext *lc,
 
         int more_data = 0;
 
-        more_data = hls_coding_quadtree(lc, pps, sps, x0, y0, log2_cb_size - 1, cb_depth + 1);
+        more_data = hls_coding_quadtree(lc, l, pps, sps,
+                                        x0, y0, log2_cb_size - 1, cb_depth + 1);
         if (more_data < 0)
             return more_data;
 
         if (more_data && x1 < sps->width) {
-            more_data = hls_coding_quadtree(lc, pps, sps, x1, y0, log2_cb_size - 1, cb_depth + 1);
+            more_data = hls_coding_quadtree(lc, l, pps, sps,
+                                            x1, y0, log2_cb_size - 1, cb_depth + 1);
             if (more_data < 0)
                 return more_data;
         }
         if (more_data && y1 < sps->height) {
-            more_data = hls_coding_quadtree(lc, pps, sps, x0, y1, log2_cb_size - 1, cb_depth + 1);
+            more_data = hls_coding_quadtree(lc, l, pps, sps,
+                                            x0, y1, log2_cb_size - 1, cb_depth + 1);
             if (more_data < 0)
                 return more_data;
         }
         if (more_data && x1 < sps->width &&
             y1 < sps->height) {
-            more_data = hls_coding_quadtree(lc, pps, sps, x1, y1, log2_cb_size - 1, cb_depth + 1);
+            more_data = hls_coding_quadtree(lc, l, pps, sps,
+                                            x1, y1, log2_cb_size - 1, cb_depth + 1);
             if (more_data < 0)
                 return more_data;
         }
@@ -2452,7 +2459,7 @@  static int hls_coding_quadtree(HEVCLocalContext *lc,
         else
             return 0;
     } else {
-        ret = hls_coding_unit(lc, s, pps, sps, x0, y0, log2_cb_size);
+        ret = hls_coding_unit(lc, s, l, pps, sps, x0, y0, log2_cb_size);
         if (ret < 0)
             return ret;
         if ((!((x0 + cb_size) %
@@ -2524,6 +2531,7 @@  static void hls_decode_neighbour(HEVCLocalContext *lc,
 static int hls_decode_entry(HEVCContext *s, GetBitContext *gb)
 {
     HEVCLocalContext *const lc = &s->local_ctx[0];
+    const HEVCLayerContext *const l = &s->layers[s->cur_layer];
     const HEVCPPS   *const pps = s->pps;
     const HEVCSPS   *const sps = pps->sps;
     const uint8_t *slice_data = gb->buffer + s->sh.data_offset;
@@ -2555,7 +2563,7 @@  static int hls_decode_entry(HEVCContext *s, GetBitContext *gb)
         s->deblock[ctb_addr_rs].tc_offset   = s->sh.tc_offset;
         s->filter_slice_edges[ctb_addr_rs]  = s->sh.slice_loop_filter_across_slices_enabled_flag;
 
-        more_data = hls_coding_quadtree(lc, pps, sps, x_ctb, y_ctb, sps->log2_ctb_size, 0);
+        more_data = hls_coding_quadtree(lc, l, pps, sps, x_ctb, y_ctb, sps->log2_ctb_size, 0);
         if (more_data < 0) {
             s->tab_slice_address[ctb_addr_rs] = -1;
             return more_data;
@@ -2564,12 +2572,12 @@  static int hls_decode_entry(HEVCContext *s, GetBitContext *gb)
 
         ctb_addr_ts++;
         ff_hevc_save_states(lc, pps, ctb_addr_ts);
-        ff_hevc_hls_filters(lc, pps, x_ctb, y_ctb, ctb_size);
+        ff_hevc_hls_filters(lc, l, pps, x_ctb, y_ctb, ctb_size);
     }
 
     if (x_ctb + ctb_size >= sps->width &&
         y_ctb + ctb_size >= sps->height)
-        ff_hevc_hls_filter(lc, pps, x_ctb, y_ctb, ctb_size);
+        ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb, ctb_size);
 
     return ctb_addr_ts;
 }
@@ -2579,6 +2587,7 @@  static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist,
 {
     HEVCLocalContext *lc = &((HEVCLocalContext*)hevc_lclist)[self_id];
     const HEVCContext *const s = lc->parent;
+    const HEVCLayerContext *const l = &s->layers[s->cur_layer];
     const HEVCPPS   *const pps = s->pps;
     const HEVCSPS   *const sps = pps->sps;
     int ctb_size    = 1 << sps->log2_ctb_size;
@@ -2617,7 +2626,7 @@  static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist,
             goto error;
         hls_sao_param(lc, pps, sps,
                       x_ctb >> sps->log2_ctb_size, y_ctb >> sps->log2_ctb_size);
-        more_data = hls_coding_quadtree(lc, pps, sps, x_ctb, y_ctb, sps->log2_ctb_size, 0);
+        more_data = hls_coding_quadtree(lc, l, pps, sps, x_ctb, y_ctb, sps->log2_ctb_size, 0);
 
         if (more_data < 0) {
             ret = more_data;
@@ -2628,7 +2637,7 @@  static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist,
 
         ff_hevc_save_states(lc, pps, ctb_addr_ts);
         ff_thread_report_progress2(s->avctx, ctb_row, thread, 1);
-        ff_hevc_hls_filters(lc, pps, x_ctb, y_ctb, ctb_size);
+        ff_hevc_hls_filters(lc, l, pps, x_ctb, y_ctb, ctb_size);
 
         if (!more_data && (x_ctb+ctb_size) < sps->width && ctb_row != s->sh.num_entry_point_offsets) {
             /* Casting const away here is safe, because it is an atomic operation. */
@@ -2638,7 +2647,7 @@  static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist,
         }
 
         if ((x_ctb+ctb_size) >= sps->width && (y_ctb+ctb_size) >= sps->height ) {
-            ff_hevc_hls_filter(lc, pps, x_ctb, y_ctb, ctb_size);
+            ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb, ctb_size);
             ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
             return ctb_addr_ts;
         }
@@ -2913,7 +2922,7 @@  static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l)
 
     if (sps->vps != s->vps && l != &s->layers[0]) {
         av_log(s->avctx, AV_LOG_ERROR, "VPS changed in a non-base layer\n");
-        set_sps(s, NULL, AV_PIX_FMT_NONE);
+        set_sps(s, l, NULL);
         return AVERROR_INVALIDDATA;
     }
 
@@ -2923,7 +2932,7 @@  static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l)
 
         ff_hevc_clear_refs(l);
 
-        ret = set_sps(s, sps);
+        ret = set_sps(s, l, sps);
         if (ret < 0)
             return ret;
 
@@ -2937,8 +2946,8 @@  static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l)
         new_sequence = 1;
     }
 
-    memset(s->horizontal_bs, 0, s->bs_width * s->bs_height);
-    memset(s->vertical_bs,   0, s->bs_width * s->bs_height);
+    memset(s->horizontal_bs, 0, l->bs_width * l->bs_height);
+    memset(s->vertical_bs,   0, l->bs_width * l->bs_height);
     memset(s->cbf_luma,      0, sps->min_tb_width * sps->min_tb_height);
     memset(s->is_pcm,        0, (sps->min_pu_width + 1) * (sps->min_pu_height + 1));
     memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address));
@@ -3627,7 +3636,7 @@  static int hevc_update_thread_context(AVCodecContext *dst,
     ff_refstruct_unref(&s->pps);
 
     if (s->ps.sps != s0->ps.sps)
-        if ((ret = set_sps(s, s0->ps.sps)) < 0)
+        if ((ret = set_sps(s, &s->layers[0], s0->ps.sps)) < 0)
             return ret;
 
     s->poc_tid0   = s0->poc_tid0;
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index be5d76c183..18b15e7dc1 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -440,6 +440,9 @@  typedef struct HEVCLocalContext {
 
 typedef struct HEVCLayerContext {
     HEVCFrame               DPB[32];
+
+    int                     bs_width;
+    int                     bs_height;
 } HEVCLayerContext;
 
 typedef struct HEVCContext {
@@ -484,8 +487,6 @@  typedef struct HEVCContext {
     int slice_idx; ///< number of the slice being currently decoded
     int eos;       ///< current packet contains an EOS/EOB NAL
     int last_eos;  ///< last packet contains an EOS/EOB NAL
-    int bs_width;
-    int bs_height;
 
     // NoRaslOutputFlag associated with the last IRAP frame
     int no_rasl_output_flag;
@@ -649,13 +650,16 @@  void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, const HEVCPPS *pps,
                               int nPbW, int nPbH, int log2_cb_size,
                               int part_idx, int merge_idx,
                               MvField *mv, int mvp_lx_flag, int LX);
-void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCPPS *pps,
+void ff_hevc_hls_filter(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                        const HEVCPPS *pps,
                         int x, int y, int ctb_size);
-void ff_hevc_hls_filters(HEVCLocalContext *lc, const HEVCPPS *pps,
+void ff_hevc_hls_filters(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                         const HEVCPPS *pps,
                          int x_ctb, int y_ctb, int ctb_size);
 void ff_hevc_set_qPy(HEVCLocalContext *lc, const HEVCPPS *pps,
                      int xBase, int yBase, int log2_cb_size);
-void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCPPS *pps,
+void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCLayerContext *l,
+                                           const HEVCPPS *pps,
                                            int x0, int y0, int log2_trafo_size);
 int ff_hevc_cu_qp_delta_sign_flag(HEVCLocalContext *lc);
 int ff_hevc_cu_qp_delta_abs(HEVCLocalContext *lc);