diff --git a/libavcodec/hevc/filter.c b/libavcodec/hevc/filter.c
index db82f2319f..298f1792b2 100644
--- a/libavcodec/hevc/filter.c
+++ b/libavcodec/hevc/filter.c
@@ -204,7 +204,7 @@ static void copy_vert(uint8_t *dst, const uint8_t *src,
     }
 }
 
-static void copy_CTB_to_hv(const HEVCContext *s, const HEVCSPS *sps,
+static void copy_CTB_to_hv(const HEVCLayerContext *l, const HEVCSPS *sps,
                            const uint8_t *src,
                            ptrdiff_t stride_src, int x, int y, int width, int height,
                            int c_idx, int x_ctb, int y_ctb)
@@ -214,15 +214,15 @@ static void copy_CTB_to_hv(const HEVCContext *s, const HEVCSPS *sps,
     int h = sps->height >> sps->vshift[c_idx];
 
     /* copy horizontal edges */
-    memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh),
+    memcpy(l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh),
         src, width << sh);
-    memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh),
+    memcpy(l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh),
         src + stride_src * (height - 1), width << sh);
 
     /* copy vertical edges */
-    copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src);
+    copy_vert(l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src);
 
-    copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 1) * h + y) << sh), src + ((width - 1) << sh), sh, height, 1 << sh, stride_src);
+    copy_vert(l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 1) * h + y) << sh), src + ((width - 1) << sh), sh, height, 1 << sh, stride_src);
 }
 
 static void restore_tqb_pixels(const HEVCLayerContext *l,
@@ -343,7 +343,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
 
         switch (sao->type_idx[c_idx]) {
         case SAO_BAND:
-            copy_CTB_to_hv(s, sps, src, stride_src, x0, y0, width, height, c_idx,
+            copy_CTB_to_hv(l, sps, src, stride_src, x0, y0, width, height, c_idx,
                            x_ctb, y_ctb);
             if (pps->transquant_bypass_enable_flag ||
                 (sps->pcm_loop_filter_disabled && sps->pcm_enabled)) {
@@ -385,7 +385,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
 
                 dst1 = dst - stride_dst - (left << sh);
                 src1[0] = src - stride_src - (left << sh);
-                src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) * w + x0 - left) << sh);
+                src1[1] = l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) * w + x0 - left) << sh);
                 pos = 0;
                 if (left) {
                     src_idx = (CTB(l->sao, x_ctb-1, y_ctb-1).type_idx[c_idx] ==
@@ -412,7 +412,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
 
                 dst1 = dst + height * stride_dst - (left << sh);
                 src1[0] = src + height * stride_src - (left << sh);
-                src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) * w + x0 - left) << sh);
+                src1[1] = l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) * w + x0 - left) << sh);
                 pos = 0;
                 if (left) {
                     src_idx = (CTB(l->sao, x_ctb-1, y_ctb+1).type_idx[c_idx] ==
@@ -434,7 +434,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
             if (!left_edge) {
                 if (CTB(l->sao, x_ctb-1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
                     copy_vert(dst - (1 << sh),
-                              s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) * h + y0) << sh),
+                              l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) * h + y0) << sh),
                               sh, height, stride_dst, 1 << sh);
                 } else {
                     left_pixels = 1;
@@ -444,7 +444,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
             if (!right_edge) {
                 if (CTB(l->sao, x_ctb+1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
                     copy_vert(dst + (width << sh),
-                              s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) * h + y0) << sh),
+                              l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) * h + y0) << sh),
                               sh, height, stride_dst, 1 << sh);
                 } else {
                     right_pixels = 1;
@@ -456,7 +456,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
                      (width + left_pixels + right_pixels) << sh,
                      height, stride_dst, stride_src);
 
-            copy_CTB_to_hv(s, sps, src, stride_src, x0, y0, width, height, c_idx,
+            copy_CTB_to_hv(l, sps, src, stride_src, x0, y0, width, height, c_idx,
                            x_ctb, y_ctb);
             s->hevcdsp.sao_edge_filter[tab](src, dst, stride_src, sao->offset_val[c_idx],
                                             sao->eo_class[c_idx], width, height);
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index c4e3debae1..e02d5bba72 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -85,6 +85,11 @@ static void pic_arrays_free(HEVCLayerContext *l)
     av_freep(&l->horizontal_bs);
     av_freep(&l->vertical_bs);
 
+    for (int i = 0; i < 3; i++) {
+        av_freep(&l->sao_pixel_buffer_h[i]);
+        av_freep(&l->sao_pixel_buffer_v[i]);
+    }
+
     ff_refstruct_pool_uninit(&l->tab_mvf_pool);
     ff_refstruct_pool_uninit(&l->rpl_tab_pool);
 }
@@ -137,6 +142,24 @@ static int pic_arrays_init(HEVCLayerContext *l, const HEVCSPS *sps)
     if (!l->tab_mvf_pool || !l->rpl_tab_pool)
         goto fail;
 
+    if (sps->sao_enabled) {
+        int c_count = (sps->chroma_format_idc != 0) ? 3 : 1;
+
+        for (int c_idx = 0; c_idx < c_count; c_idx++) {
+            int w = sps->width >> sps->hshift[c_idx];
+            int h = sps->height >> sps->vshift[c_idx];
+            l->sao_pixel_buffer_h[c_idx] =
+                av_malloc((w * 2 * sps->ctb_height) <<
+                          sps->pixel_shift);
+            l->sao_pixel_buffer_v[c_idx] =
+                av_malloc((h * 2 * sps->ctb_width) <<
+                          sps->pixel_shift);
+            if (!l->sao_pixel_buffer_h[c_idx] ||
+                !l->sao_pixel_buffer_v[c_idx])
+                goto fail;
+        }
+    }
+
     return 0;
 
 fail:
@@ -529,7 +552,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
 
 static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
 {
-    int ret, i;
+    int ret;
 
     pic_arrays_free(l);
     s->ps.sps = NULL;
@@ -546,30 +569,6 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
     ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
     ff_videodsp_init (&s->vdsp,    sps->bit_depth);
 
-    for (i = 0; i < 3; i++) {
-        av_freep(&s->sao_pixel_buffer_h[i]);
-        av_freep(&s->sao_pixel_buffer_v[i]);
-    }
-
-    if (sps->sao_enabled && !s->avctx->hwaccel) {
-        int c_count = (sps->chroma_format_idc != 0) ? 3 : 1;
-        int c_idx;
-
-        for(c_idx = 0; c_idx < c_count; c_idx++) {
-            int w = sps->width >> sps->hshift[c_idx];
-            int h = sps->height >> sps->vshift[c_idx];
-            s->sao_pixel_buffer_h[c_idx] =
-                av_malloc((w * 2 * sps->ctb_height) <<
-                          sps->pixel_shift);
-            s->sao_pixel_buffer_v[c_idx] =
-                av_malloc((h * 2 * sps->ctb_width) <<
-                          sps->pixel_shift);
-            if (!s->sao_pixel_buffer_h[c_idx] ||
-                !s->sao_pixel_buffer_v[c_idx])
-                goto fail;
-        }
-    }
-
     s->ps.sps = sps;
     s->vps    = ff_refstruct_ref_c(sps->vps);
 
@@ -577,10 +576,6 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
 
 fail:
     pic_arrays_free(l);
-    for (i = 0; i < 3; i++) {
-        av_freep(&s->sao_pixel_buffer_h[i]);
-        av_freep(&s->sao_pixel_buffer_v[i]);
-    }
     s->ps.sps = NULL;
     return ret;
 }
@@ -3526,7 +3521,6 @@ static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src)
 static av_cold int hevc_decode_free(AVCodecContext *avctx)
 {
     HEVCContext       *s = avctx->priv_data;
-    int i;
 
     for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++)
         pic_arrays_free(&s->layers[i]);
@@ -3539,11 +3533,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
 
     av_freep(&s->md5_ctx);
 
-    for (i = 0; i < 3; i++) {
-        av_freep(&s->sao_pixel_buffer_h[i]);
-        av_freep(&s->sao_pixel_buffer_v[i]);
-    }
-
     ff_container_fifo_free(&s->output_fifo);
 
     for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) {
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index 1a43c3662c..0b5d87b18f 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -466,6 +466,9 @@ typedef struct HEVCLayerContext {
     uint8_t                *horizontal_bs;
     uint8_t                *vertical_bs;
 
+    uint8_t                *sao_pixel_buffer_h[3];
+    uint8_t                *sao_pixel_buffer_v[3];
+
     struct FFRefStructPool *tab_mvf_pool;
     struct FFRefStructPool *rpl_tab_pool;
 } HEVCLayerContext;
@@ -485,8 +488,6 @@ typedef struct HEVCContext {
     uint8_t slice_initialized;
 
     struct ContainerFifo *output_fifo;
-    uint8_t *sao_pixel_buffer_h[3];
-    uint8_t *sao_pixel_buffer_v[3];
 
     HEVCParamSets ps;
     HEVCSEI sei;
