Backport from https://phabricator.services.mozilla.com/D216919

--- Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_av1.c
+++ Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_av1.c
@@ -14,16 +14,17 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/frame.h"
+#include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
 #include "hwconfig.h"
 #include "vaapi_decode.h"
 #include "internal.h"
 #include "av1dec.h"
 #include "thread.h"
 
 typedef struct VAAPIAV1FrameRef {
@@ -38,16 +39,19 @@
      * For film grain case, VAAPI generate 2 output for each frame,
      * current_frame will not apply film grain, and will be used for
      * references for next frames. Maintain the reference list without
      * applying film grain here. And current_display_picture will be
      * used to apply film grain and push to downstream.
     */
     VAAPIAV1FrameRef ref_tab[AV1_NUM_REF_FRAMES];
     AVFrame *tmp_frame;
+
+    int nb_slice_params;
+    VASliceParameterBufferAV1 *slice_params;
 } VAAPIAV1DecContext;
 
 static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf)
 {
     if (vf)
         return ff_vaapi_get_surface_id(vf->f);
     else
         return VA_INVALID_SURFACE;
@@ -104,16 +108,18 @@
     av_frame_free(&ctx->tmp_frame);
 
     for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) {
         if (ctx->ref_tab[i].frame->buf[0])
             ff_thread_release_buffer(avctx, ctx->ref_tab[i].frame);
         av_frame_free(&ctx->ref_tab[i].frame);
     }
 
+    av_freep(&ctx->slice_params);
+
     return ff_vaapi_decode_uninit(avctx);
 }
 
 
 static int vaapi_av1_start_frame(AVCodecContext *avctx,
                                  av_unused const uint8_t *buffer,
                                  av_unused uint32_t size)
 {
@@ -400,43 +406,56 @@
 }
 
 static int vaapi_av1_decode_slice(AVCodecContext *avctx,
                                   const uint8_t *buffer,
                                   uint32_t size)
 {
     const AV1DecContext *s = avctx->priv_data;
     VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private;
-    VASliceParameterBufferAV1 slice_param;
-    int err = 0;
+    VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data;
+    int err, nb_params;
 
-    for (int i = s->tg_start; i <= s->tg_end; i++) {
-        memset(&slice_param, 0, sizeof(VASliceParameterBufferAV1));
+    nb_params = s->tg_end - s->tg_start + 1;
+    if (ctx->nb_slice_params < nb_params) {
+	ctx->slice_params = av_realloc_array(ctx->slice_params,
+					     nb_params,
+					     sizeof(*ctx->slice_params));
+	if (!ctx->slice_params) {
+	    ctx->nb_slice_params = 0;
+	    err = AVERROR(ENOMEM);
+	    goto fail;
+	}
+	ctx->nb_slice_params = nb_params;
+    }
 
-        slice_param = (VASliceParameterBufferAV1) {
+    for (int i = s->tg_start; i <= s->tg_end; i++) {
+        ctx->slice_params[i - s->tg_start] = (VASliceParameterBufferAV1) {
             .slice_data_size   = s->tile_group_info[i].tile_size,
             .slice_data_offset = s->tile_group_info[i].tile_offset,
             .slice_data_flag   = VA_SLICE_DATA_FLAG_ALL,
             .tile_row          = s->tile_group_info[i].tile_row,
             .tile_column       = s->tile_group_info[i].tile_column,
             .tg_start          = s->tg_start,
             .tg_end            = s->tg_end,
         };
-
-        err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &slice_param,
-                                                sizeof(VASliceParameterBufferAV1),
-                                                buffer,
-                                                size);
-        if (err) {
-            ff_vaapi_decode_cancel(avctx, pic);
-            return err;
-        }
     }
 
+    err = ff_vaapi_decode_make_slice_buffer(avctx, pic, ctx->slice_params, nb_params,
+					    sizeof(VASliceParameterBufferAV1),
+					    buffer,
+					    size);
+    if (err)
+	goto fail;
+
     return 0;
+
+fail:
+    ff_vaapi_decode_cancel(avctx, pic);
+    return err;
 }
 
 const AVHWAccel ff_av1_vaapi_hwaccel = {
     .name                 = "av1_vaapi",
     .type                 = AVMEDIA_TYPE_VIDEO,
     .id                   = AV_CODEC_ID_AV1,
     .pix_fmt              = AV_PIX_FMT_VAAPI,
     .start_frame          = vaapi_av1_start_frame,
--- Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_decode.c
+++ Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_decode.c
@@ -56,16 +56,17 @@
            "is %#x.\n", type, size, buffer);
     return 0;
 }
 
 
 int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
                                       VAAPIDecodePicture *pic,
                                       const void *params_data,
+                                      int nb_params,
                                       size_t params_size,
                                       const void *slice_data,
                                       size_t slice_size)
 {
     VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
     VAStatus vas;
     int index;
 
@@ -84,17 +85,17 @@
             return AVERROR(ENOMEM);
     }
     av_assert0(pic->nb_slices + 1 <= pic->slices_allocated);
 
     index = 2 * pic->nb_slices;
 
     vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
                          VASliceParameterBufferType,
-                         params_size, 1, (void*)params_data,
+                         params_size, nb_params, (void*)params_data,
                          &pic->slice_buffers[index]);
     if (vas != VA_STATUS_SUCCESS) {
         av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
                "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas));
         return AVERROR(EIO);
     }
 
     av_log(avctx, AV_LOG_DEBUG, "Slice %d param buffer (%zu bytes) "
--- Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_decode.h
+++ Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_decode.h
@@ -68,16 +68,17 @@
                                       VAAPIDecodePicture *pic,
                                       int type,
                                       const void *data,
                                       size_t size);
 
 int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
                                       VAAPIDecodePicture *pic,
                                       const void *params_data,
+                                      int nb_params,
                                       size_t params_size,
                                       const void *slice_data,
                                       size_t slice_size);
 
 int ff_vaapi_decode_issue(AVCodecContext *avctx,
                           VAAPIDecodePicture *pic);
 int ff_vaapi_decode_cancel(AVCodecContext *avctx,
                            VAAPIDecodePicture *pic);
--- Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_vp8.c
+++ Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_vp8.c
@@ -204,17 +204,17 @@
                               s->coder_state_at_header_end.bit_count - 8),
         .num_of_partitions = s->num_coeff_partitions + 1,
     };
 
     sp.partition_size[0] = s->header_partition_size - ((sp.macroblock_offset + 7) / 8);
     for (i = 0; i < 8; i++)
         sp.partition_size[i+1] = s->coeff_partition_size[i];
 
-    err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, sizeof(sp), data, data_size);
+    err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, 1, sizeof(sp), data, data_size);
     if (err)
         goto fail;
 
     return 0;
 
 fail:
     ff_vaapi_decode_cancel(avctx, pic);
     return err;
--- Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_vp9.c
+++ Waterfox-G6.0.17/media/ffvpx/libavcodec/vaapi_vp9.c
@@ -153,17 +153,17 @@
             .chroma_dc_quant_scale         = h->h.segmentation.feat[i].qmul[1][0],
             .chroma_ac_quant_scale         = h->h.segmentation.feat[i].qmul[1][1],
         };
 
         memcpy(slice_param.seg_param[i].filter_level, h->h.segmentation.feat[i].lflvl, sizeof(slice_param.seg_param[i].filter_level));
     }
 
     err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
-                                            &slice_param, sizeof(slice_param),
+                                            &slice_param, 1, sizeof(slice_param),
                                             buffer, size);
     if (err) {
         ff_vaapi_decode_cancel(avctx, pic);
         return err;
     }
 
     return 0;
 }
