diff --git a/libavcodec/aic.c b/libavcodec/aic.c
index c95bdae1ed..552e7e9c10 100644
--- a/libavcodec/aic.c
+++ b/libavcodec/aic.c
@@ -391,7 +391,6 @@ static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     uint32_t off;
     int x, y, ret;
     int slice_size;
-    ThreadFrame frame = { .f = data };
 
     ctx->frame            = data;
     ctx->frame->pict_type = AV_PICTURE_TYPE_I;
@@ -410,7 +409,7 @@ static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return ret;
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, ctx->frame, 0)) < 0)
         return ret;
 
     bytestream2_init(&gb, buf + AIC_HDR_SIZE,
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 67fc2a3e41..bac7543020 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -270,10 +270,9 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
         return AVERROR_INVALIDDATA;
     }
     if (!alac->nb_samples) {
-        ThreadFrame tframe = { .f = frame };
         /* get output buffer */
         frame->nb_samples = output_samples;
-        if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
             return ret;
     } else if (output_samples != alac->nb_samples) {
         av_log(avctx, AV_LOG_ERROR, "sample count mismatch: %"PRIu32" != %d\n",
diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 62d459cded..b354d8d03c 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -27,6 +27,7 @@
 #include "hwconfig.h"
 #include "internal.h"
 #include "profiles.h"
+#include "thread.h"
 
 /**< same with Div_Lut defined in spec 7.11.3.7 */
 static const uint16_t div_lut[AV1_DIV_LUT_NUM] = {
@@ -569,7 +570,7 @@ static int get_pixel_format(AVCodecContext *avctx)
 
 static void av1_frame_unref(AVCodecContext *avctx, AV1Frame *f)
 {
-    ff_thread_release_buffer(avctx, &f->tf);
+    ff_thread_release_buffer(avctx, f->f);
     av_buffer_unref(&f->hwaccel_priv_buf);
     f->hwaccel_picture_private = NULL;
     av_buffer_unref(&f->header_ref);
@@ -591,10 +592,10 @@ static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *s
 
     dst->raw_frame_header = src->raw_frame_header;
 
-    if (!src->tf.f->buf[0])
+    if (!src->f->buf[0])
         return 0;
 
-    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    ret = av_frame_ref(dst->f, src->f);
     if (ret < 0)
         goto fail;
 
@@ -637,10 +638,10 @@ static av_cold int av1_decode_free(AVCodecContext *avctx)
 
     for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
         av1_frame_unref(avctx, &s->ref[i]);
-        av_frame_free(&s->ref[i].tf.f);
+        av_frame_free(&s->ref[i].f);
     }
     av1_frame_unref(avctx, &s->cur_frame);
-    av_frame_free(&s->cur_frame.tf.f);
+    av_frame_free(&s->cur_frame.f);
 
     av_buffer_unref(&s->seq_ref);
     av_buffer_unref(&s->header_ref);
@@ -741,16 +742,16 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
     s->pix_fmt = AV_PIX_FMT_NONE;
 
     for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
-        s->ref[i].tf.f = av_frame_alloc();
-        if (!s->ref[i].tf.f) {
+        s->ref[i].f = av_frame_alloc();
+        if (!s->ref[i].f) {
             av_log(avctx, AV_LOG_ERROR,
                    "Failed to allocate reference frame buffer %d.\n", i);
             return AVERROR(ENOMEM);
         }
     }
 
-    s->cur_frame.tf.f = av_frame_alloc();
-    if (!s->cur_frame.tf.f) {
+    s->cur_frame.f = av_frame_alloc();
+    if (!s->cur_frame.f) {
         av_log(avctx, AV_LOG_ERROR,
                "Failed to allocate current frame buffer.\n");
         return AVERROR(ENOMEM);
@@ -803,10 +804,10 @@ static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f)
         return ret;
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, f->f, AV_GET_BUFFER_FLAG_REF)) < 0)
         goto fail;
 
-    frame = f->tf.f;
+    frame = f->f;
     frame->key_frame = header->frame_type == AV1_FRAME_KEY;
 
     switch (header->frame_type) {
@@ -905,7 +906,7 @@ static int set_output_frame(AVCodecContext *avctx, AVFrame *frame,
                             const AVPacket *pkt, int *got_frame)
 {
     AV1DecContext *s = avctx->priv_data;
-    const AVFrame *srcframe = s->cur_frame.tf.f;
+    const AVFrame *srcframe = s->cur_frame.f;
     int ret;
 
     // TODO: all layers
@@ -1101,7 +1102,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
                     goto end;
                 }
 
-                if (s->cur_frame.tf.f->buf[0]) {
+                if (s->cur_frame.f->buf[0]) {
                     ret = set_output_frame(avctx, frame, pkt, got_frame);
                     if (ret < 0)
                         av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n");
@@ -1121,7 +1122,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
             s->cur_frame.spatial_id  = header->spatial_id;
             s->cur_frame.temporal_id = header->temporal_id;
 
-            if (avctx->hwaccel && s->cur_frame.tf.f->buf[0]) {
+            if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
                 ret = avctx->hwaccel->start_frame(avctx, unit->data,
                                                   unit->data_size);
                 if (ret < 0) {
@@ -1148,7 +1149,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
             if (ret < 0)
                 goto end;
 
-            if (avctx->hwaccel && s->cur_frame.tf.f->buf[0]) {
+            if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
                 ret = avctx->hwaccel->decode_slice(avctx,
                                                    raw_tile_group->tile_data.data,
                                                    raw_tile_group->tile_data.data_size);
@@ -1171,7 +1172,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
         }
 
         if (raw_tile_group && (s->tile_num == raw_tile_group->tg_end + 1)) {
-            if (avctx->hwaccel && s->cur_frame.tf.f->buf[0]) {
+            if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
                 ret = avctx->hwaccel->end_frame(avctx);
                 if (ret < 0) {
                     av_log(avctx, AV_LOG_ERROR, "HW accel end frame fail.\n");
@@ -1185,7 +1186,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
                 goto end;
             }
 
-            if (s->raw_frame_header->show_frame && s->cur_frame.tf.f->buf[0]) {
+            if (s->raw_frame_header->show_frame && s->cur_frame.f->buf[0]) {
                 ret = set_output_frame(avctx, frame, pkt, got_frame);
                 if (ret < 0) {
                     av_log(avctx, AV_LOG_ERROR, "Set output frame error\n");
diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h
index 4e140588b9..82c7084e99 100644
--- a/libavcodec/av1dec.h
+++ b/libavcodec/av1dec.h
@@ -24,14 +24,14 @@
 #include <stdint.h>
 
 #include "libavutil/buffer.h"
+#include "libavutil/frame.h"
 #include "libavutil/pixfmt.h"
 #include "avcodec.h"
 #include "cbs.h"
 #include "cbs_av1.h"
-#include "thread.h"
 
 typedef struct AV1Frame {
-    ThreadFrame tf;
+    AVFrame *f;
 
     AVBufferRef *hwaccel_priv_buf;
     void *hwaccel_picture_private;
diff --git a/libavcodec/bitpacked_dec.c b/libavcodec/bitpacked_dec.c
index 69fea9c366..fa554d99af 100644
--- a/libavcodec/bitpacked_dec.c
+++ b/libavcodec/bitpacked_dec.c
@@ -65,12 +65,11 @@ static int bitpacked_decode_yuv422p10(AVCodecContext *avctx, AVFrame *frame,
 {
     uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 20;
     uint64_t packet_size = (uint64_t)avpkt->size * 8;
-    ThreadFrame tframe = { .f = frame };
     GetBitContext bc;
     uint16_t *y, *u, *v;
     int ret, i, j;
 
-    ret = ff_thread_get_buffer(avctx, &tframe, 0);
+    ret = ff_thread_get_buffer(avctx, frame, 0);
     if (ret < 0)
         return ret;
 
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index ac7826250f..ff38106fac 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -378,8 +378,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
     CFHDContext *s = avctx->priv_data;
     CFHDDSPContext *dsp = &s->dsp;
     GetByteContext gb;
-    ThreadFrame frame = { .f = data };
-    AVFrame *pic = data;
+    AVFrame *const pic = data;
     int ret = 0, i, j, plane, got_buffer = 0;
     int16_t *coeff_data;
 
@@ -681,10 +680,9 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
                     return AVERROR_INVALIDDATA;
                 avctx->height = height;
             }
-            frame.f->width =
-            frame.f->height = 0;
+            pic->width = pic->height = 0;
 
-            if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+            if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
                 return ret;
 
             s->coded_width = 0;
@@ -692,10 +690,9 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
             s->coded_format = AV_PIX_FMT_NONE;
             got_buffer = 1;
         } else if (tag == FrameIndex && data == 1 && s->sample_type == 1 && s->frame_type == 2) {
-            frame.f->width =
-            frame.f->height = 0;
+            pic->width = pic->height = 0;
 
-            if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+            if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
                 return ret;
             s->coded_width = 0;
             s->coded_height = 0;
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index 41b3a4ef83..2ad5d77adc 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -360,7 +360,6 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
 {
     CLLCContext *ctx = avctx->priv_data;
     AVFrame *pic = data;
-    ThreadFrame frame = { .f = data };
     uint8_t *src = avpkt->data;
     uint32_t info_tag, info_offset;
     int data_size;
@@ -424,7 +423,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
         avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
         avctx->bits_per_raw_sample = 8;
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
             return ret;
 
         ret = decode_yuv_frame(ctx, &gb, pic);
@@ -437,7 +436,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
         avctx->pix_fmt             = AV_PIX_FMT_RGB24;
         avctx->bits_per_raw_sample = 8;
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
             return ret;
 
         ret = decode_rgb24_frame(ctx, &gb, pic);
@@ -449,7 +448,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
         avctx->pix_fmt             = AV_PIX_FMT_ARGB;
         avctx->bits_per_raw_sample = 8;
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
             return ret;
 
         ret = decode_argb_frame(ctx, &gb, pic);
diff --git a/libavcodec/cri.c b/libavcodec/cri.c
index dfea24d979..3b2c955dd8 100644
--- a/libavcodec/cri.c
+++ b/libavcodec/cri.c
@@ -174,7 +174,6 @@ static int cri_decode_frame(AVCodecContext *avctx, void *data,
 {
     CRIContext *s = avctx->priv_data;
     GetByteContext *gb = &s->gb;
-    ThreadFrame frame = { .f = data };
     int ret, bps, hflip = 0, vflip = 0;
     AVFrameSideData *rotation;
     int compressed = 0;
@@ -318,7 +317,7 @@ skip:
     if (!s->data || !s->data_size)
         return AVERROR_INVALIDDATA;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     avctx->bits_per_raw_sample = bps;
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 9ecd220e7f..78c7b72730 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -618,7 +618,6 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     DNXHDContext *ctx = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     AVFrame *picture = data;
     int first_field = 1;
     int ret, i;
@@ -650,7 +649,7 @@ decode_coding_unit:
         return ret;
 
     if (first_field) {
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, picture, 0)) < 0)
             return ret;
         picture->pict_type = AV_PICTURE_TYPE_I;
         picture->key_frame = 1;
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index b72a67d01c..03249d6fa3 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -612,7 +612,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *data,
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     DVVideoContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
+    AVFrame *const frame = data;
     const uint8_t *vsc_pack;
     int apt, is16_9, ret;
     const AVDVProfile *sys;
@@ -633,9 +633,9 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *data,
         s->sys = sys;
     }
 
-    s->frame            = frame.f;
-    frame.f->key_frame  = 1;
-    frame.f->pict_type  = AV_PICTURE_TYPE_I;
+    s->frame            = frame;
+    frame->key_frame    = 1;
+    frame->pict_type    = AV_PICTURE_TYPE_I;
     avctx->pix_fmt      = s->sys->pix_fmt;
     avctx->framerate    = av_inv_q(s->sys->time_base);
 
@@ -652,20 +652,20 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *data,
         ff_set_sar(avctx, s->sys->sar[is16_9]);
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     /* Determine the codec's field order from the packet */
     if ( *vsc_pack == dv_video_control ) {
         if (avctx->height == 720) {
-            frame.f->interlaced_frame = 0;
-            frame.f->top_field_first = 0;
+            frame->interlaced_frame = 0;
+            frame->top_field_first = 0;
         } else if (avctx->height == 1080) {
-            frame.f->interlaced_frame = 1;
-            frame.f->top_field_first = (vsc_pack[3] & 0x40) == 0x40;
+            frame->interlaced_frame = 1;
+            frame->top_field_first = (vsc_pack[3] & 0x40) == 0x40;
         } else {
-            frame.f->interlaced_frame = (vsc_pack[3] & 0x10) == 0x10;
-            frame.f->top_field_first = !(vsc_pack[3] & 0x40);
+            frame->interlaced_frame = (vsc_pack[3] & 0x10) == 0x10;
+            frame->top_field_first = !(vsc_pack[3] & 0x40);
         }
     }
 
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index 914131e742..ff40f29b86 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -93,7 +93,6 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
                                 const uint8_t *src, int src_size,
                                 int id, int bpp, uint32_t vflipped)
 {
-    ThreadFrame frame = { .f = pic };
     int h;
     uint8_t *dst;
     int ret;
@@ -104,7 +103,7 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
     }
 
     avctx->pix_fmt = id;
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     do_vflip(avctx, pic, vflipped);
@@ -125,7 +124,6 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
                                 const uint8_t *src, int src_size,
                                 uint32_t vflipped)
 {
-    ThreadFrame frame = { .f = pic };
     int h, w;
     uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
     int height, width, hmargin, vmargin;
@@ -138,7 +136,7 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
     }
 
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     do_vflip(avctx, pic, vflipped);
@@ -221,7 +219,6 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
                                 const uint8_t *src, int src_size,
                                 uint32_t vflipped)
 {
-    ThreadFrame frame = { .f = pic };
     int h, w;
     uint8_t *Y1, *Y2, *U, *V;
     int height, width, hmargin, vmargin;
@@ -234,7 +231,7 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
     }
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     do_vflip(avctx, pic, vflipped);
@@ -294,7 +291,6 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
                                 const uint8_t *src, int src_size,
                                 uint32_t vflipped)
 {
-    ThreadFrame frame = { .f = pic };
     int h, w;
     uint8_t *Y, *U, *V;
     int ret;
@@ -305,7 +301,7 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
     }
 
     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     do_vflip(avctx, pic, vflipped);
@@ -430,7 +426,6 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
                             enum AVPixelFormat fmt,
                             uint32_t vflipped)
 {
-    ThreadFrame frame = { .f = pic };
     GetByteContext gb, gb_check;
     GetBitContext  gb2;
     int nslices, slice, line = 0;
@@ -457,7 +452,7 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
         return AVERROR_INVALIDDATA;
 
     avctx->pix_fmt = fmt;
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     do_vflip(avctx, pic, vflipped);
diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c
index 5f17347913..e2c0cde85e 100644
--- a/libavcodec/dxv.c
+++ b/libavcodec/dxv.c
@@ -1042,7 +1042,7 @@ static int dxv_decode(AVCodecContext *avctx, void *data,
                       int *got_frame, AVPacket *avpkt)
 {
     DXVContext *ctx = avctx->priv_data;
-    ThreadFrame tframe;
+    AVFrame *const frame = data;
     GetByteContext *gbc = &ctx->gbc;
     int (*decompress_tex)(AVCodecContext *avctx);
     const char *msgcomp, *msgtext;
@@ -1211,18 +1211,17 @@ static int dxv_decode(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
     }
 
-    tframe.f = data;
-    ret = ff_thread_get_buffer(avctx, &tframe, 0);
+    ret = ff_thread_get_buffer(avctx, frame, 0);
     if (ret < 0)
         return ret;
 
     /* Now decompress the texture with the standard functions. */
     avctx->execute2(avctx, decompress_texture_thread,
-                    tframe.f, NULL, ctx->slice_count);
+                    frame, NULL, ctx->slice_count);
 
     /* Frame is ready to be output. */
-    tframe.f->pict_type = AV_PICTURE_TYPE_I;
-    tframe.f->key_frame = 1;
+    frame->pict_type = AV_PICTURE_TYPE_I;
+    frame->key_frame = 1;
     *got_frame = 1;
 
     return avpkt->size;
diff --git a/libavcodec/dxva2_av1.c b/libavcodec/dxva2_av1.c
index 8a912bf6c1..7b4483f855 100644
--- a/libavcodec/dxva2_av1.c
+++ b/libavcodec/dxva2_av1.c
@@ -72,7 +72,7 @@ static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *c
     pp->max_width  = seq->max_frame_width_minus_1 + 1;
     pp->max_height = seq->max_frame_height_minus_1 + 1;
 
-    pp->CurrPicTextureIndex = ff_dxva2_get_surface_index(avctx, ctx, h->cur_frame.tf.f);
+    pp->CurrPicTextureIndex = ff_dxva2_get_surface_index(avctx, ctx, h->cur_frame.f);
     pp->superres_denom      = frame_header->use_superres ? frame_header->coded_denom + AV1_SUPERRES_DENOM_MIN : AV1_SUPERRES_NUM;
     pp->bitdepth            = get_bit_depth_from_seq(seq);
     pp->seq_profile         = seq->seq_profile;
@@ -132,7 +132,7 @@ static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *c
     memset(pp->RefFrameMapTextureIndex, 0xFF, sizeof(pp->RefFrameMapTextureIndex));
     for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
         int8_t ref_idx = frame_header->ref_frame_idx[i];
-        AVFrame *ref_frame = h->ref[ref_idx].tf.f;
+        AVFrame *ref_frame = h->ref[ref_idx].f;
 
         pp->frame_refs[i].width  = ref_frame->width;
         pp->frame_refs[i].height = ref_frame->height;
@@ -146,7 +146,7 @@ static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *c
         }
     }
     for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
-        AVFrame *ref_frame = h->ref[i].tf.f;
+        AVFrame *ref_frame = h->ref[i].f;
         if (ref_frame->buf[0])
             pp->RefFrameMapTextureIndex[i] = ff_dxva2_get_surface_index(avctx, ctx, ref_frame);
     }
@@ -436,7 +436,7 @@ static int dxva2_av1_end_frame(AVCodecContext *avctx)
     if (ctx_pic->bitstream_size <= 0)
         return -1;
 
-    ret = ff_dxva2_common_end_frame(avctx, h->cur_frame.tf.f,
+    ret = ff_dxva2_common_end_frame(avctx, h->cur_frame.f,
                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
                                     NULL, 0,
                                     commit_bitstream_and_slice_buffer);
diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
index 664a765659..bb770ff674 100644
--- a/libavcodec/error_resilience.h
+++ b/libavcodec/error_resilience.h
@@ -24,7 +24,7 @@
 
 #include "avcodec.h"
 #include "me_cmp.h"
-#include "thread.h"
+#include "threadframe.h"
 
 ///< current MB is the first after a resync marker
 #define VP_START               1
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 0d5b3467d1..8b04fab951 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -2027,7 +2027,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 {
     EXRContext *s = avctx->priv_data;
     GetByteContext *gb = &s->gb;
-    ThreadFrame frame = { .f = data };
     AVFrame *picture = data;
     uint8_t *ptr;
 
@@ -2149,7 +2148,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         s->scan_lines_per_block;
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, picture, 0)) < 0)
         return ret;
 
     if (bytestream2_get_bytes_left(gb)/8 < nb_blocks)
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index 8ffe5ab433..b1585dbd03 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -38,7 +38,7 @@
 #include "mathops.h"
 #include "put_bits.h"
 #include "rangecoder.h"
-#include "thread.h"
+#include "threadframe.h"
 
 #ifdef __INTEL_COMPILER
 #undef av_flatten
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 45ecf3152e..201630167d 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -37,6 +37,7 @@
 #include "golomb.h"
 #include "mathops.h"
 #include "ffv1.h"
+#include "thread.h"
 #include "threadframe.h"
 
 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 09051cc663..f224fa7621 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -559,7 +559,6 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     AVFrame *frame     = data;
-    ThreadFrame tframe = { .f = data };
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     FLACContext *s = avctx->priv_data;
@@ -618,7 +617,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->blocksize;
-    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index b3262a4b23..18e85eed41 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -140,7 +140,6 @@ static int decode_frame(AVCodecContext *avctx,
     FrapsContext * const s = avctx->priv_data;
     const uint8_t *buf     = avpkt->data;
     int buf_size           = avpkt->size;
-    ThreadFrame frame = { .f = data };
     AVFrame * const f = data;
     uint32_t header;
     unsigned int version,header_size;
@@ -227,7 +226,7 @@ static int decode_frame(AVCodecContext *avctx,
                                      : AVCOL_RANGE_JPEG;
     avctx->colorspace = version & 1 ? AVCOL_SPC_UNSPECIFIED : AVCOL_SPC_BT709;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, f, 0)) < 0)
         return ret;
 
     switch (version) {
diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c
index c7f5b64b99..2661ff4698 100644
--- a/libavcodec/h264_picture.c
+++ b/libavcodec/h264_picture.c
@@ -30,18 +30,19 @@
 #include "avcodec.h"
 #include "h264dec.h"
 #include "mpegutils.h"
+#include "thread.h"
 #include "threadframe.h"
 
 void ff_h264_unref_picture(H264Context *h, H264Picture *pic)
 {
-    int off = offsetof(H264Picture, tf_grain) + sizeof(pic->tf_grain);
+    int off = offsetof(H264Picture, f_grain) + sizeof(pic->f_grain);
     int i;
 
     if (!pic->f || !pic->f->buf[0])
         return;
 
     ff_thread_release_ext_buffer(h->avctx, &pic->tf);
-    ff_thread_release_buffer(h->avctx, &pic->tf_grain);
+    ff_thread_release_buffer(h->avctx, pic->f_grain);
     av_buffer_unref(&pic->hwaccel_priv_buf);
 
     av_buffer_unref(&pic->qscale_table_buf);
@@ -102,9 +103,7 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src)
         goto fail;
 
     if (src->needs_fg) {
-        av_assert0(src->tf_grain.f == src->f_grain);
-        dst->tf_grain.f = dst->f_grain;
-        ret = ff_thread_ref_frame(&dst->tf_grain, &src->tf_grain);
+        ret = av_frame_ref(dst->f_grain, src->f_grain);
         if (ret < 0)
             goto fail;
     }
@@ -161,10 +160,8 @@ int ff_h264_replace_picture(H264Context *h, H264Picture *dst, const H264Picture
         goto fail;
 
     if (src->needs_fg) {
-        av_assert0(src->tf_grain.f == src->f_grain);
-        dst->tf_grain.f = dst->f_grain;
-        ff_thread_release_buffer(h->avctx, &dst->tf_grain);
-        ret = ff_thread_ref_frame(&dst->tf_grain, &src->tf_grain);
+        ff_thread_release_buffer(h->avctx, dst->f_grain);
+        ret = av_frame_ref(dst->f_grain, src->f_grain);
         if (ret < 0)
             goto fail;
     }
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 32d2e090d5..110a41772a 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -45,6 +45,7 @@
 #include "mathops.h"
 #include "mpegutils.h"
 #include "rectangle.h"
+#include "thread.h"
 #include "threadframe.h"
 
 static const uint8_t field_scan[16+1] = {
@@ -197,11 +198,10 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
         goto fail;
 
     if (pic->needs_fg) {
-        pic->tf_grain.f = pic->f_grain;
         pic->f_grain->format = pic->f->format;
         pic->f_grain->width = pic->f->width;
         pic->f_grain->height = pic->f->height;
-        ret = ff_thread_get_buffer(h->avctx, &pic->tf_grain, 0);
+        ret = ff_thread_get_buffer(h->avctx, pic->f_grain, 0);
         if (ret < 0)
             goto fail;
     }
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 1d648f04b7..856fbca680 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -46,6 +46,7 @@
 #include "mpegutils.h"
 #include "profiles.h"
 #include "rectangle.h"
+#include "thread.h"
 #include "threadframe.h"
 
 const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 };
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
index 8168c8e97b..f18adda2d1 100644
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -109,7 +109,6 @@ typedef struct H264Picture {
     ThreadFrame tf;
 
     AVFrame *f_grain;
-    ThreadFrame tf_grain;
 
     AVBufferRef *qscale_table_buf;
     int8_t *qscale_table;
diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c
index 45c44ad78d..9f8dadc43d 100644
--- a/libavcodec/hapdec.c
+++ b/libavcodec/hapdec.c
@@ -305,7 +305,7 @@ static int hap_decode(AVCodecContext *avctx, void *data,
                       int *got_frame, AVPacket *avpkt)
 {
     HapContext *ctx = avctx->priv_data;
-    ThreadFrame tframe;
+    AVFrame *const frame = data;
     int ret, i, t;
     int section_size;
     enum HapSectionType section_type;
@@ -330,8 +330,7 @@ static int hap_decode(AVCodecContext *avctx, void *data,
     }
 
     /* Get the output frame ready to receive data */
-    tframe.f = data;
-    ret = ff_thread_get_buffer(avctx, &tframe, 0);
+    ret = ff_thread_get_buffer(avctx, frame, 0);
     if (ret < 0)
         return ret;
 
@@ -383,16 +382,15 @@ static int hap_decode(AVCodecContext *avctx, void *data,
 
         /* Use the decompress function on the texture, one block per thread */
         if (t == 0){
-            avctx->execute2(avctx, decompress_texture_thread, tframe.f, NULL, ctx->slice_count);
+            avctx->execute2(avctx, decompress_texture_thread, frame, NULL, ctx->slice_count);
         } else{
-            tframe.f = data;
-            avctx->execute2(avctx, decompress_texture2_thread, tframe.f, NULL, ctx->slice_count);
+            avctx->execute2(avctx, decompress_texture2_thread, frame, NULL, ctx->slice_count);
         }
     }
 
     /* Frame is ready to be output */
-    tframe.f->pict_type = AV_PICTURE_TYPE_I;
-    tframe.f->key_frame = 1;
+    frame->pict_type = AV_PICTURE_TYPE_I;
+    frame->key_frame = 1;
     *got_frame = 1;
 
     return avpkt->size;
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 0dd456bb92..1eb5daf157 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -39,7 +39,7 @@ void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
     frame->flags &= ~flags;
     if (!frame->flags) {
         ff_thread_release_ext_buffer(s->avctx, &frame->tf);
-        ff_thread_release_buffer(s->avctx, &frame->tf_grain);
+        ff_thread_release_buffer(s->avctx, frame->frame_grain);
         frame->needs_fg = 0;
 
         av_buffer_unref(&frame->tab_mvf_buf);
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 6d86a5bfdb..fdff450a5e 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -45,6 +45,7 @@
 #include "hevcdec.h"
 #include "hwconfig.h"
 #include "profiles.h"
+#include "thread.h"
 #include "threadframe.h"
 
 const uint8_t ff_hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2, [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] = 9 };
@@ -3026,7 +3027,7 @@ static int hevc_frame_start(HEVCContext *s)
         s->ref->frame_grain->format = s->ref->frame->format;
         s->ref->frame_grain->width = s->ref->frame->width;
         s->ref->frame_grain->height = s->ref->frame->height;
-        if ((ret = ff_thread_get_buffer(s->avctx, &s->ref->tf_grain, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(s->avctx, s->ref->frame_grain, 0)) < 0)
             goto fail;
     }
 
@@ -3533,7 +3534,7 @@ static int hevc_ref_frame(HEVCContext *s, HEVCFrame *dst, HEVCFrame *src)
         return ret;
 
     if (src->needs_fg) {
-        ret = ff_thread_ref_frame(&dst->tf_grain, &src->tf_grain);
+        ret = av_frame_ref(dst->frame_grain, src->frame_grain);
         if (ret < 0)
             return ret;
         dst->needs_fg = 1;
@@ -3652,7 +3653,6 @@ static av_cold int hevc_init_context(AVCodecContext *avctx)
         s->DPB[i].frame_grain = av_frame_alloc();
         if (!s->DPB[i].frame_grain)
             goto fail;
-        s->DPB[i].tf_grain.f = s->DPB[i].frame_grain;
     }
 
     s->max_ra = INT_MAX;
diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h
index 157bc6926f..bf390664d4 100644
--- a/libavcodec/hevcdec.h
+++ b/libavcodec/hevcdec.h
@@ -42,7 +42,7 @@
 #include "hevcdsp.h"
 #include "h274.h"
 #include "internal.h"
-#include "thread.h"
+#include "threadframe.h"
 #include "videodsp.h"
 
 #define SHIFT_CTB_WPP 2
@@ -396,7 +396,6 @@ typedef struct HEVCFrame {
     AVFrame *frame;
     AVFrame *frame_grain;
     ThreadFrame tf;
-    ThreadFrame tf_grain;
     int needs_fg; /* 1 if grain needs to be applied by the decoder */
     MvField *tab_mvf;
     RefPicList *refPicList;
diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index 3a4db1b6c3..09310b69e8 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -404,7 +404,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_picture_ptr, AVPacket *avpkt)
 {
     HQXContext *ctx = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
+    AVFrame *const frame = data;
     uint8_t *src = avpkt->data;
     uint32_t info_tag;
     int data_start;
@@ -499,7 +499,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    ret = ff_thread_get_buffer(avctx, &frame, 0);
+    ret = ff_thread_get_buffer(avctx, frame, 0);
     if (ret < 0)
         return ret;
 
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
index 0abf73b21b..a5e0ef5818 100644
--- a/libavcodec/huffyuvdec.c
+++ b/libavcodec/huffyuvdec.c
@@ -1185,7 +1185,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     HYuvContext *s = avctx->priv_data;
     const int width  = s->width;
     const int height = s->height;
-    ThreadFrame frame = { .f = data };
     AVFrame *const p = data;
     int slice, table_size = 0, ret, nb_slices;
     unsigned slices_info_offset;
@@ -1203,7 +1202,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     s->bdsp.bswap_buf((uint32_t *) s->bitstream_buffer,
                       (const uint32_t *) buf, buf_size / 4);
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     if (s->context) {
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index a7eb809f30..d96ec3a275 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -2476,7 +2476,6 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame, AVPacket *avpkt)
 {
     Jpeg2000DecoderContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     AVFrame *picture = data;
     int ret;
 
@@ -2517,7 +2516,7 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
         goto end;
 
     /* get picture buffer */
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, picture, 0)) < 0)
         goto end;
     picture->pict_type = AV_PICTURE_TYPE_I;
     picture->key_frame = 1;
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 7220648bc4..b8f330cf34 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -540,7 +540,6 @@ static int lag_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     unsigned int buf_size = avpkt->size;
     LagarithContext *l = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     AVFrame *const p  = data;
     uint8_t frametype;
     uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
@@ -569,7 +568,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
                 planes = 4;
             }
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
             return ret;
 
         if (frametype == FRAME_SOLID_RGBA) {
@@ -593,7 +592,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
             avctx->pix_fmt = AV_PIX_FMT_GBRAP;
         }
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame,0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, p,0)) < 0)
             return ret;
 
         for (i = 0; i < avctx->height; i++) {
@@ -614,7 +613,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
         if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
             avctx->pix_fmt = AV_PIX_FMT_GBRP;
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
             return ret;
 
         offs[0] = offset_bv;
@@ -650,7 +649,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YUY2:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
             return ret;
 
         if (offset_ry >= buf_size ||
@@ -678,7 +677,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
             return ret;
 
         if (offset_ry >= buf_size ||
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index a47e3bd780..f3b7a8ac1b 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -158,7 +158,6 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
     AVFrame *frame = data;
-    ThreadFrame tframe = { .f = data };
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LclDecContext * const c = avctx->priv_data;
@@ -175,7 +174,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     unsigned int len = buf_size;
     int linesize, offset;
 
-    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     outptr = frame->data[0]; // Output image pointer
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 8982d21be4..c9496d886e 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -324,7 +324,6 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
     uint8_t *buf            = avpkt->data;
     int buf_size            = avpkt->size;
     LibOpenJPEGContext *ctx = avctx->priv_data;
-    ThreadFrame frame       = { .f = data };
     AVFrame *picture        = data;
     const AVPixFmtDescriptor *desc;
     int width, height, ret;
@@ -417,7 +416,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         if (image->comps[i].prec > avctx->bits_per_raw_sample)
             avctx->bits_per_raw_sample = image->comps[i].prec;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, picture, 0)) < 0)
         goto done;
 
     ret = !opj_decode(dec, stream, image);
diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c
index 594196063b..46515780fc 100644
--- a/libavcodec/magicyuv.c
+++ b/libavcodec/magicyuv.c
@@ -431,7 +431,6 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
     MagicYUVContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     AVFrame *p = data;
     GetByteContext gb;
     uint32_t first_offset, offset, next_offset, header_size, slice_width;
@@ -641,7 +640,7 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data,
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     s->buf = avpkt->data;
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 007e7fada8..9f61256bc4 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -42,7 +42,6 @@ typedef struct MDECContext {
     BlockDSPContext bdsp;
     BswapDSPContext bbdsp;
     IDCTDSPContext idsp;
-    ThreadFrame frame;
     GetBitContext gb;
     ScanTable scantable;
     int version;
@@ -174,13 +173,13 @@ static int decode_frame(AVCodecContext *avctx,
     MDECContext * const a = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    ThreadFrame frame     = { .f = data };
+    AVFrame *const frame  = data;
     int ret;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
-    frame.f->pict_type = AV_PICTURE_TYPE_I;
-    frame.f->key_frame = 1;
+    frame->pict_type = AV_PICTURE_TYPE_I;
+    frame->key_frame = 1;
 
     av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size);
     if (!a->bitstream_buffer)
@@ -202,7 +201,7 @@ static int decode_frame(AVCodecContext *avctx,
             if ((ret = decode_mb(a, a->block)) < 0)
                 return ret;
 
-            idct_put(a, frame.f, a->mb_x, a->mb_y);
+            idct_put(a, frame, a->mb_x, a->mb_y);
         }
     }
 
diff --git a/libavcodec/mpegpicture.h b/libavcodec/mpegpicture.h
index e1e9f8d7e0..c79693caba 100644
--- a/libavcodec/mpegpicture.h
+++ b/libavcodec/mpegpicture.h
@@ -27,7 +27,7 @@
 
 #include "avcodec.h"
 #include "motion_est.h"
-#include "thread.h"
+#include "threadframe.h"
 
 #define MPEGVIDEO_MAX_PLANES 4
 #define MAX_PICTURE_COUNT 36
diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c
index be28161995..9dd3bf95a0 100644
--- a/libavcodec/notchlc.c
+++ b/libavcodec/notchlc.c
@@ -146,7 +146,7 @@ static int lz4_decompress(AVCodecContext *avctx,
     return bytestream2_tell_p(pb);
 }
 
-static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame,
+static int decode_blocks(AVCodecContext *avctx, AVFrame *p,
                          unsigned uncompressed_size)
 {
     NotchLCContext *s = avctx->priv_data;
@@ -221,7 +221,7 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame,
         return AVERROR_INVALIDDATA;
     s->uv_count_offset = s->y_data_offset - s->a_data_offset;
 
-    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     rgb = *gb;
@@ -464,7 +464,6 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     NotchLCContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     GetByteContext *gb = &s->gb;
     PutByteContext *pb = &s->pb;
     unsigned uncompressed_size;
@@ -513,7 +512,7 @@ static int decode_frame(AVCodecContext *avctx,
         bytestream2_init(gb, s->uncompressed_buffer, uncompressed_size);
     }
 
-    ret = decode_blocks(avctx, p, &frame, uncompressed_size);
+    ret = decode_blocks(avctx, p, uncompressed_size);
     if (ret < 0)
         return ret;
 
diff --git a/libavcodec/nvdec_av1.c b/libavcodec/nvdec_av1.c
index 1ce846a60d..3bbcd76123 100644
--- a/libavcodec/nvdec_av1.c
+++ b/libavcodec/nvdec_av1.c
@@ -49,7 +49,7 @@ static int nvdec_av1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
     CUVIDAV1PICPARAMS *ppc = &pp->CodecSpecific.av1;
     FrameDecodeData *fdd;
     NVDECFrame *cf;
-    AVFrame *cur_frame = s->cur_frame.tf.f;
+    AVFrame *cur_frame = s->cur_frame.f;
 
     unsigned char remap_lr_type[4] = { AV1_RESTORE_NONE, AV1_RESTORE_SWITCHABLE, AV1_RESTORE_WIENER, AV1_RESTORE_SGRPROJ };
 
@@ -233,7 +233,7 @@ static int nvdec_av1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
         ppc->loop_filter_ref_deltas[i] = frame_header->loop_filter_ref_deltas[i];
 
         /* Reference Frames */
-        ppc->ref_frame_map[i] = ff_nvdec_get_ref_idx(s->ref[i].tf.f);
+        ppc->ref_frame_map[i] = ff_nvdec_get_ref_idx(s->ref[i].f);
     }
 
     if (frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE) {
@@ -246,7 +246,7 @@ static int nvdec_av1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
     for (i = 0; i < AV1_REFS_PER_FRAME; ++i) {
         /* Ref Frame List */
         int8_t ref_idx = frame_header->ref_frame_idx[i];
-        AVFrame *ref_frame = s->ref[ref_idx].tf.f;
+        AVFrame *ref_frame = s->ref[ref_idx].f;
 
         ppc->ref_frame[i].index = ppc->ref_frame_map[ref_idx];
         ppc->ref_frame[i].width = ref_frame->width;
diff --git a/libavcodec/photocd.c b/libavcodec/photocd.c
index 50b465c1cd..23a8994ca3 100644
--- a/libavcodec/photocd.c
+++ b/libavcodec/photocd.c
@@ -293,7 +293,6 @@ static int photocd_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame, AVPacket *avpkt)
 {
     PhotoCDContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     const uint8_t *buf = avpkt->data;
     GetByteContext *gb = &s->gb;
     AVFrame *p = data;
@@ -326,7 +325,7 @@ static int photocd_decode_frame(AVCodecContext *avctx, void *data,
     if (ret < 0)
         return ret;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     p->pict_type = AV_PICTURE_TYPE_I;
diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c
index 5361bc42bf..a07690c6d0 100644
--- a/libavcodec/pixlet.c
+++ b/libavcodec/pixlet.c
@@ -606,7 +606,6 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data,
     PixletContext *ctx = avctx->priv_data;
     int i, w, h, width, height, ret, version;
     AVFrame *p = data;
-    ThreadFrame frame = { .f = data };
     uint32_t pktsize, depth;
 
     bytestream2_init(&ctx->gb, avpkt->data, avpkt->size);
@@ -673,20 +672,20 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data,
     p->key_frame = 1;
     p->color_range = AVCOL_RANGE_JPEG;
 
-    ret = ff_thread_get_buffer(avctx, &frame, 0);
+    ret = ff_thread_get_buffer(avctx, p, 0);
     if (ret < 0)
         return ret;
 
     for (i = 0; i < 3; i++) {
-        ret = decode_plane(avctx, i, avpkt, frame.f);
+        ret = decode_plane(avctx, i, avpkt, p);
         if (ret < 0)
             return ret;
         if (avctx->flags & AV_CODEC_FLAG_GRAY)
             break;
     }
 
-    postprocess_luma(avctx, frame.f, ctx->w, ctx->h, ctx->depth);
-    postprocess_chroma(frame.f, ctx->w >> 1, ctx->h >> 1, ctx->depth);
+    postprocess_luma(avctx, p, ctx->w, ctx->h, ctx->depth);
+    postprocess_chroma(p, ctx->w >> 1, ctx->h >> 1, ctx->depth);
 
     *got_frame = 1;
 
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index d2d881a3dd..3ab6666f74 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -779,7 +779,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     ProresContext *ctx = avctx->priv_data;
-    ThreadFrame tframe = { .f = data };
     AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -805,7 +804,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     buf += frame_hdr_size;
     buf_size -= frame_hdr_size;
 
-    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
     ff_thread_finish_setup(avctx);
 
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index f405622ca1..75b70a17ec 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -948,15 +948,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
     return 1;
 }
 
-static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
+static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int flags)
 {
     PerThreadContext *p;
     int err;
 
-    f->owner[0] = f->owner[1] = avctx;
-
     if (!(avctx->active_thread_type & FF_THREAD_FRAME))
-        return ff_get_buffer(avctx, f->f, flags);
+        return ff_get_buffer(avctx, f, flags);
 
     p = avctx->internal->thread_ctx;
 FF_DISABLE_DEPRECATION_WARNINGS
@@ -971,28 +969,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
         return -1;
     }
 
-    if (avctx->codec->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) {
-        atomic_int *progress;
-        f->progress = av_buffer_alloc(2 * sizeof(*progress));
-        if (!f->progress) {
-            return AVERROR(ENOMEM);
-        }
-        progress = (atomic_int*)f->progress->data;
-
-        atomic_init(&progress[0], -1);
-        atomic_init(&progress[1], -1);
-    }
-
     pthread_mutex_lock(&p->parent->buffer_mutex);
 #if !FF_API_THREAD_SAFE_CALLBACKS
     err = ff_get_buffer(avctx, f->f, flags);
 #else
 FF_DISABLE_DEPRECATION_WARNINGS
     if (THREAD_SAFE_CALLBACKS(avctx)) {
-        err = ff_get_buffer(avctx, f->f, flags);
+        err = ff_get_buffer(avctx, f, flags);
     } else {
         pthread_mutex_lock(&p->progress_mutex);
-        p->requested_frame = f->f;
+        p->requested_frame = f;
         p->requested_flags = flags;
         atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release);
         pthread_cond_broadcast(&p->progress_cond);
@@ -1009,8 +995,6 @@ FF_DISABLE_DEPRECATION_WARNINGS
         ff_thread_finish_setup(avctx);
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
-    if (err)
-        av_buffer_unref(&f->progress);
 
     pthread_mutex_unlock(&p->parent->buffer_mutex);
 
@@ -1049,7 +1033,7 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
-int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
+int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
 {
     int ret = thread_get_buffer_internal(avctx, f, flags);
     if (ret < 0)
@@ -1059,10 +1043,36 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
 
 int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
 {
-    return ff_thread_get_buffer(avctx, f, flags);
+    int ret;
+
+    f->owner[0] = f->owner[1] = avctx;
+    /* Hint: It is possible for this function to be called with codecs
+     * that don't support frame threading at all, namely in case
+     * a frame-threaded decoder shares code with codecs that are not.
+     * This currently affects non-MPEG-4 mpegvideo codecs and and VP7.
+     * The following check will always be true for them. */
+    if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+        return ff_get_buffer(avctx, f->f, flags);
+
+    if (avctx->codec->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) {
+        atomic_int *progress;
+        f->progress = av_buffer_alloc(2 * sizeof(*progress));
+        if (!f->progress) {
+            return AVERROR(ENOMEM);
+        }
+        progress = (atomic_int*)f->progress->data;
+
+        atomic_init(&progress[0], -1);
+        atomic_init(&progress[1], -1);
+    }
+
+    ret = ff_thread_get_buffer(avctx, f->f, flags);
+    if (ret)
+        av_buffer_unref(&f->progress);
+    return ret;
 }
 
-void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
+void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
 {
 #if FF_API_THREAD_SAFE_CALLBACKS
 FF_DISABLE_DEPRECATION_WARNINGS
@@ -1075,21 +1085,18 @@ FF_DISABLE_DEPRECATION_WARNINGS
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
-    if (!f->f)
+    if (!f)
         return;
 
     if (avctx->debug & FF_DEBUG_BUFFERS)
         av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
 
-    av_buffer_unref(&f->progress);
-    f->owner[0] = f->owner[1] = NULL;
-
 #if !FF_API_THREAD_SAFE_CALLBACKS
     av_frame_unref(f->f);
 #else
     // when the frame buffers are not allocated, just reset it to clean state
-    if (can_direct_free || !f->f->buf[0]) {
-        av_frame_unref(f->f);
+    if (can_direct_free || !f->buf[0]) {
+        av_frame_unref(f);
         return;
     }
 
@@ -1113,7 +1120,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
     }
 
     dst = p->released_buffers[p->num_released_buffers];
-    av_frame_move_ref(dst, f->f);
+    av_frame_move_ref(dst, f);
 
     p->num_released_buffers++;
 
@@ -1124,15 +1131,17 @@ fail:
     // this leaks, but it is better than crashing
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not queue a frame for freeing, this will leak\n");
-        memset(f->f->buf, 0, sizeof(f->f->buf));
-        if (f->f->extended_buf)
-            memset(f->f->extended_buf, 0, f->f->nb_extended_buf * sizeof(*f->f->extended_buf));
-        av_frame_unref(f->f);
+        memset(f->buf, 0, sizeof(f->buf));
+        if (f->extended_buf)
+            memset(f->extended_buf, 0, f->nb_extended_buf * sizeof(*f->extended_buf));
+        av_frame_unref(f);
     }
 #endif
 }
 
 void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
 {
-    ff_thread_release_buffer(avctx, f);
+    av_buffer_unref(&f->progress);
+    f->owner[0] = f->owner[1] = NULL;
+    ff_thread_release_buffer(avctx, f->f);
 }
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index febd41f577..1a0ca6b520 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -41,6 +41,7 @@
 #include "mpeg_er.h"
 #include "qpeldsp.h"
 #include "rectangle.h"
+#include "thread.h"
 #include "threadframe.h"
 
 #include "rv34vlc.h"
diff --git a/libavcodec/sheervideo.c b/libavcodec/sheervideo.c
index fb5a39303e..8505d124c4 100644
--- a/libavcodec/sheervideo.c
+++ b/libavcodec/sheervideo.c
@@ -1810,7 +1810,6 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     SheerVideoContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     const SheerTable *table;
     AVFrame *p = data;
     GetBitContext gb;
@@ -1982,7 +1981,7 @@ static int decode_frame(AVCodecContext *avctx,
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     if ((ret = init_get_bits8(&gb, avpkt->data + 20, avpkt->size - 20)) < 0)
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index 926dbf611e..19a3d75d2b 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -679,7 +679,6 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
 {
     TAKDecContext *s  = avctx->priv_data;
     AVFrame *frame    = data;
-    ThreadFrame tframe = { .f = data };
     GetBitContext *gb = &s->gb;
     int chan, i, ret, hsize;
 
@@ -742,7 +741,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
                                              : s->ti.frame_samples;
 
     frame->nb_samples = s->nb_samples;
-    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
     ff_thread_finish_setup(avctx);
 
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 091dc8a35e..716301b29f 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -31,14 +31,6 @@
 
 #include "avcodec.h"
 
-typedef struct ThreadFrame {
-    AVFrame *f;
-    AVCodecContext *owner[2];
-    // progress->data is an array of 2 ints holding progress for top/bottom
-    // fields
-    AVBufferRef *progress;
-} ThreadFrame;
-
 /**
  * Wait for decoding threads to finish and reset internal state.
  * Called by avcodec_flush_buffers().
@@ -92,7 +84,7 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe
  * @param avctx The current context.
  * @param f The frame to write into.
  */
-int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
+int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags);
 
 /**
  * Wrapper around release_buffer() frame-for multithreaded codecs.
@@ -105,9 +97,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
  * @param avctx The current context.
  * @param f The picture being released.
  */
-void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f);
-
-int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src);
+void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f);
 
 int ff_thread_init(AVCodecContext *s);
 int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx,
diff --git a/libavcodec/threadframe.h b/libavcodec/threadframe.h
index be63e62435..dea4dadc6d 100644
--- a/libavcodec/threadframe.h
+++ b/libavcodec/threadframe.h
@@ -21,8 +21,16 @@
 #ifndef AVCODEC_THREADFRAME_H
 #define AVCODEC_THREADFRAME_H
 
+#include "libavutil/frame.h"
 #include "avcodec.h"
-#include "thread.h"
+
+typedef struct ThreadFrame {
+    AVFrame *f;
+    AVCodecContext *owner[2];
+    // progress->data is an array of 2 ints holding progress for top/bottom
+    // fields
+    AVBufferRef *progress;
+} ThreadFrame;
 
 /**
  * Notify later decoding threads when part of their reference picture is ready.
@@ -74,4 +82,6 @@ int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
  */
 void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f);
 
+int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src);
+
 #endif
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index fd85d104dc..923f85d07f 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1016,7 +1016,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame,
     return avpkt->size;
 }
 
-static int init_image(TiffContext *s, ThreadFrame *frame)
+static int init_image(TiffContext *s, AVFrame *frame)
 {
     int ret;
     int create_gray_palette = 0;
@@ -1177,11 +1177,11 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
         return ret;
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         if (!create_gray_palette)
-            memcpy(frame->f->data[1], s->palette, sizeof(s->palette));
+            memcpy(frame->data[1], s->palette, sizeof(s->palette));
         else {
             /* make default grayscale pal */
             int i;
-            uint32_t *pal = (uint32_t *)frame->f->data[1];
+            uint32_t *pal = (uint32_t *)frame->data[1];
             for (i = 0; i < 1<<s->bpp; i++)
                 pal[i] = 0xFFU << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
         }
@@ -1743,7 +1743,6 @@ static int decode_frame(AVCodecContext *avctx,
 {
     TiffContext *const s = avctx->priv_data;
     AVFrame *const p = data;
-    ThreadFrame frame = { .f = data };
     unsigned off, last_off;
     int le, ret, plane, planes;
     int i, j, entries, stride;
@@ -1894,7 +1893,7 @@ again:
     }
 
     /* now we have the data and may start decoding */
-    if ((ret = init_image(s, &frame)) < 0)
+    if ((ret = init_image(s, p)) < 0)
         return ret;
 
     if (!s->is_tiled || has_strip_bits) {
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 17b4ca9032..7ffae3d0ba 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -222,7 +222,6 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
     AVFrame *frame     = data;
-    ThreadFrame tframe = { .f = data };
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     TTAContext *s = avctx->priv_data;
@@ -242,7 +241,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = framelen;
-    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     // decode directly to output buffer for 24-bit sample format
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index bc16424f91..2561854c47 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -893,10 +893,9 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe
     return ff_get_format(avctx, fmt);
 }
 
-int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
+int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
 {
-    f->owner[0] = f->owner[1] = avctx;
-    return ff_get_buffer(avctx, f->f, flags);
+    return ff_get_buffer(avctx, f, flags);
 }
 
 int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
@@ -905,10 +904,10 @@ int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
     return ff_get_buffer(avctx, f->f, flags);
 }
 
-void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
+void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
 {
-    if (f->f)
-        av_frame_unref(f->f);
+    if (f)
+        av_frame_unref(f);
 }
 
 void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index b39d8a7948..a824112415 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -563,14 +563,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     UtvideoContext *c = avctx->priv_data;
+    AVFrame *const frame = data;
     int i, j;
     const uint8_t *plane_start[5];
     int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
     int ret;
     GetByteContext gb;
-    ThreadFrame frame = { .f = data };
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     /* parse plane structure to get frame flags and validate slice offsets */
@@ -709,80 +709,80 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     case AV_PIX_FMT_GBRP:
     case AV_PIX_FMT_GBRAP:
         for (i = 0; i < c->planes; i++) {
-            ret = decode_plane(c, i, frame.f->data[i],
-                               frame.f->linesize[i], avctx->width,
+            ret = decode_plane(c, i, frame->data[i],
+                               frame->linesize[i], avctx->width,
                                avctx->height, plane_start[i],
                                c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median_planar(c, frame.f->data[i],
-                                          frame.f->linesize[i], avctx->width,
+                    restore_median_planar(c, frame->data[i],
+                                          frame->linesize[i], avctx->width,
                                           avctx->height, c->slices, 0);
                 } else {
-                    restore_median_planar_il(c, frame.f->data[i],
-                                             frame.f->linesize[i],
+                    restore_median_planar_il(c, frame->data[i],
+                                             frame->linesize[i],
                                              avctx->width, avctx->height, c->slices,
                                              0);
                 }
             } else if (c->frame_pred == PRED_GRADIENT) {
                 if (!c->interlaced) {
-                    restore_gradient_planar(c, frame.f->data[i],
-                                            frame.f->linesize[i], avctx->width,
+                    restore_gradient_planar(c, frame->data[i],
+                                            frame->linesize[i], avctx->width,
                                             avctx->height, c->slices, 0);
                 } else {
-                    restore_gradient_planar_il(c, frame.f->data[i],
-                                               frame.f->linesize[i],
+                    restore_gradient_planar_il(c, frame->data[i],
+                                               frame->linesize[i],
                                                avctx->width, avctx->height, c->slices,
                                                0);
                 }
             }
         }
-        c->utdsp.restore_rgb_planes(frame.f->data[2], frame.f->data[0], frame.f->data[1],
-                                    frame.f->linesize[2], frame.f->linesize[0], frame.f->linesize[1],
+        c->utdsp.restore_rgb_planes(frame->data[2], frame->data[0], frame->data[1],
+                                    frame->linesize[2], frame->linesize[0], frame->linesize[1],
                                     avctx->width, avctx->height);
         break;
     case AV_PIX_FMT_GBRAP10:
     case AV_PIX_FMT_GBRP10:
         for (i = 0; i < c->planes; i++) {
-            ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i],
-                                 frame.f->linesize[i] / 2, avctx->width,
+            ret = decode_plane10(c, i, (uint16_t *)frame->data[i],
+                                 frame->linesize[i] / 2, avctx->width,
                                  avctx->height, plane_start[i],
                                  plane_start[i + 1] - 1024,
                                  c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
         }
-        c->utdsp.restore_rgb_planes10((uint16_t *)frame.f->data[2], (uint16_t *)frame.f->data[0], (uint16_t *)frame.f->data[1],
-                                      frame.f->linesize[2] / 2, frame.f->linesize[0] / 2, frame.f->linesize[1] / 2,
+        c->utdsp.restore_rgb_planes10((uint16_t *)frame->data[2], (uint16_t *)frame->data[0], (uint16_t *)frame->data[1],
+                                      frame->linesize[2] / 2, frame->linesize[0] / 2, frame->linesize[1] / 2,
                                       avctx->width, avctx->height);
         break;
     case AV_PIX_FMT_YUV420P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, frame.f->data[i], frame.f->linesize[i],
+            ret = decode_plane(c, i, frame->data[i], frame->linesize[i],
                                avctx->width >> !!i, avctx->height >> !!i,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_median_planar(c, frame->data[i], frame->linesize[i],
                                           avctx->width >> !!i, avctx->height >> !!i,
                                           c->slices, !i);
                 } else {
-                    restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_median_planar_il(c, frame->data[i], frame->linesize[i],
                                              avctx->width  >> !!i,
                                              avctx->height >> !!i,
                                              c->slices, !i);
                 }
             } else if (c->frame_pred == PRED_GRADIENT) {
                 if (!c->interlaced) {
-                    restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_gradient_planar(c, frame->data[i], frame->linesize[i],
                                             avctx->width >> !!i, avctx->height >> !!i,
                                             c->slices, !i);
                 } else {
-                    restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_gradient_planar_il(c, frame->data[i], frame->linesize[i],
                                                avctx->width  >> !!i,
                                                avctx->height >> !!i,
                                                c->slices, !i);
@@ -792,28 +792,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     case AV_PIX_FMT_YUV422P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, frame.f->data[i], frame.f->linesize[i],
+            ret = decode_plane(c, i, frame->data[i], frame->linesize[i],
                                avctx->width >> !!i, avctx->height,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_median_planar(c, frame->data[i], frame->linesize[i],
                                           avctx->width >> !!i, avctx->height,
                                           c->slices, 0);
                 } else {
-                    restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_median_planar_il(c, frame->data[i], frame->linesize[i],
                                              avctx->width >> !!i, avctx->height,
                                              c->slices, 0);
                 }
             } else if (c->frame_pred == PRED_GRADIENT) {
                 if (!c->interlaced) {
-                    restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_gradient_planar(c, frame->data[i], frame->linesize[i],
                                             avctx->width >> !!i, avctx->height,
                                             c->slices, 0);
                 } else {
-                    restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_gradient_planar_il(c, frame->data[i], frame->linesize[i],
                                                avctx->width  >> !!i, avctx->height,
                                                c->slices, 0);
                 }
@@ -822,28 +822,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     case AV_PIX_FMT_YUV444P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, frame.f->data[i], frame.f->linesize[i],
+            ret = decode_plane(c, i, frame->data[i], frame->linesize[i],
                                avctx->width, avctx->height,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_median_planar(c, frame->data[i], frame->linesize[i],
                                           avctx->width, avctx->height,
                                           c->slices, 0);
                 } else {
-                    restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_median_planar_il(c, frame->data[i], frame->linesize[i],
                                              avctx->width, avctx->height,
                                              c->slices, 0);
                 }
             } else if (c->frame_pred == PRED_GRADIENT) {
                 if (!c->interlaced) {
-                    restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_gradient_planar(c, frame->data[i], frame->linesize[i],
                                             avctx->width, avctx->height,
                                             c->slices, 0);
                 } else {
-                    restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
+                    restore_gradient_planar_il(c, frame->data[i], frame->linesize[i],
                                                avctx->width, avctx->height,
                                                c->slices, 0);
                 }
@@ -852,7 +852,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     case AV_PIX_FMT_YUV420P10:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i], frame.f->linesize[i] / 2,
+            ret = decode_plane10(c, i, (uint16_t *)frame->data[i], frame->linesize[i] / 2,
                                  avctx->width >> !!i, avctx->height >> !!i,
                                  plane_start[i], plane_start[i + 1] - 1024, c->frame_pred == PRED_LEFT);
             if (ret)
@@ -861,7 +861,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     case AV_PIX_FMT_YUV422P10:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i], frame.f->linesize[i] / 2,
+            ret = decode_plane10(c, i, (uint16_t *)frame->data[i], frame->linesize[i] / 2,
                                  avctx->width >> !!i, avctx->height,
                                  plane_start[i], plane_start[i + 1] - 1024, c->frame_pred == PRED_LEFT);
             if (ret)
@@ -870,9 +870,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     }
 
-    frame.f->key_frame = 1;
-    frame.f->pict_type = AV_PICTURE_TYPE_I;
-    frame.f->interlaced_frame = !!c->interlaced;
+    frame->key_frame = 1;
+    frame->pict_type = AV_PICTURE_TYPE_I;
+    frame->interlaced_frame = !!c->interlaced;
 
     *got_frame = 1;
 
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index 0c95728781..19dd4eeeec 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -142,7 +142,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     V210DecContext *s = avctx->priv_data;
     ThreadData td;
     int ret, stride, aligned_input;
-    ThreadFrame frame = { .f = data };
     AVFrame *pic = data;
     const uint8_t *psrc = avpkt->data;
 
@@ -177,7 +176,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         ff_v210dec_init(s);
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     pic->pict_type = AV_PICTURE_TYPE_I;
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
index c23f84942d..ecf3ae2053 100644
--- a/libavcodec/v410dec.c
+++ b/libavcodec/v410dec.c
@@ -89,7 +89,6 @@ static int v410_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
     ThreadData td;
-    ThreadFrame frame = { .f = data };
     AVFrame *pic = data;
     uint8_t *src = avpkt->data;
     int ret;
@@ -101,7 +100,7 @@ static int v410_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR(EINVAL);
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     pic->key_frame = 1;
diff --git a/libavcodec/vaapi_av1.c b/libavcodec/vaapi_av1.c
index 5985493b8d..63374c31c9 100644
--- a/libavcodec/vaapi_av1.c
+++ b/libavcodec/vaapi_av1.c
@@ -18,14 +18,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/frame.h"
 #include "libavutil/pixdesc.h"
 #include "hwconfig.h"
 #include "vaapi_decode.h"
 #include "internal.h"
 #include "av1dec.h"
+#include "thread.h"
 
 typedef struct VAAPIAV1FrameRef {
-    ThreadFrame frame;
+    AVFrame *frame;
     int valid;
 } VAAPIAV1FrameRef;
 
@@ -40,13 +42,13 @@ typedef struct VAAPIAV1DecContext {
      * used to apply film grain and push to downstream.
     */
     VAAPIAV1FrameRef ref_tab[AV1_NUM_REF_FRAMES];
-    ThreadFrame tmp_frame;
+    AVFrame *tmp_frame;
 } VAAPIAV1DecContext;
 
 static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf)
 {
     if (vf)
-        return ff_vaapi_get_surface_id(vf->tf.f);
+        return ff_vaapi_get_surface_id(vf->f);
     else
         return VA_INVALID_SURFACE;
 }
@@ -73,16 +75,16 @@ static int vaapi_av1_decode_init(AVCodecContext *avctx)
 {
     VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data;
 
-    ctx->tmp_frame.f = av_frame_alloc();
-    if (!ctx->tmp_frame.f) {
+    ctx->tmp_frame = av_frame_alloc();
+    if (!ctx->tmp_frame) {
         av_log(avctx, AV_LOG_ERROR,
                "Failed to allocate frame.\n");
         return AVERROR(ENOMEM);
     }
 
     for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) {
-        ctx->ref_tab[i].frame.f = av_frame_alloc();
-        if (!ctx->ref_tab[i].frame.f) {
+        ctx->ref_tab[i].frame = av_frame_alloc();
+        if (!ctx->ref_tab[i].frame) {
             av_log(avctx, AV_LOG_ERROR,
                    "Failed to allocate reference table frame %d.\n", i);
             return AVERROR(ENOMEM);
@@ -97,14 +99,14 @@ static int vaapi_av1_decode_uninit(AVCodecContext *avctx)
 {
     VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data;
 
-    if (ctx->tmp_frame.f->buf[0])
-        ff_thread_release_buffer(avctx, &ctx->tmp_frame);
-    av_frame_free(&ctx->tmp_frame.f);
+    if (ctx->tmp_frame->buf[0])
+        ff_thread_release_buffer(avctx, ctx->tmp_frame);
+    av_frame_free(&ctx->tmp_frame);
 
     for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) {
-        if (ctx->ref_tab[i].frame.f->buf[0])
-            ff_thread_release_buffer(avctx, &ctx->ref_tab[i].frame);
-        av_frame_free(&ctx->ref_tab[i].frame.f);
+        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);
     }
 
     return ff_vaapi_decode_uninit(avctx);
@@ -135,12 +137,12 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx,
         goto fail;
 
     if (apply_grain) {
-        if (ctx->tmp_frame.f->buf[0])
-            ff_thread_release_buffer(avctx, &ctx->tmp_frame);
-        err = ff_thread_get_buffer(avctx, &ctx->tmp_frame, AV_GET_BUFFER_FLAG_REF);
+        if (ctx->tmp_frame->buf[0])
+            ff_thread_release_buffer(avctx, ctx->tmp_frame);
+        err = ff_thread_get_buffer(avctx, ctx->tmp_frame, AV_GET_BUFFER_FLAG_REF);
         if (err < 0)
             goto fail;
-        pic->output_surface = ff_vaapi_get_surface_id(ctx->tmp_frame.f);
+        pic->output_surface = ff_vaapi_get_surface_id(ctx->tmp_frame);
     } else {
         pic->output_surface = vaapi_av1_surface_id(&s->cur_frame);
     }
@@ -276,7 +278,7 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx,
             pic_param.ref_frame_map[i] = VA_INVALID_ID;
         else
             pic_param.ref_frame_map[i] = ctx->ref_tab[i].valid ?
-                                         ff_vaapi_get_surface_id(ctx->ref_tab[i].frame.f) :
+                                         ff_vaapi_get_surface_id(ctx->ref_tab[i].frame) :
                                          vaapi_av1_surface_id(&s->ref[i]);
     }
     for (int i = 0; i < AV1_REFS_PER_FRAME; i++) {
@@ -380,11 +382,11 @@ static int vaapi_av1_end_frame(AVCodecContext *avctx)
 
     for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
         if (header->refresh_frame_flags & (1 << i)) {
-            if (ctx->ref_tab[i].frame.f->buf[0])
-                ff_thread_release_buffer(avctx, &ctx->ref_tab[i].frame);
+            if (ctx->ref_tab[i].frame->buf[0])
+                ff_thread_release_buffer(avctx, ctx->ref_tab[i].frame);
 
             if (apply_grain) {
-                ret = ff_thread_ref_frame(&ctx->ref_tab[i].frame, &ctx->tmp_frame);
+                ret = av_frame_ref(ctx->ref_tab[i].frame, ctx->tmp_frame);
                 if (ret < 0)
                     return ret;
                 ctx->ref_tab[i].valid = 1;
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
index f1400959e0..bb542bef42 100644
--- a/libavcodec/vble.c
+++ b/libavcodec/vble.c
@@ -125,7 +125,6 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int offset = 0;
     int width_uv = avctx->width / 2, height_uv = avctx->height / 2;
     int ret;
-    ThreadFrame frame = { .f = data };
 
     if (avpkt->size < 4 || avpkt->size - 4 > INT_MAX/8) {
         av_log(avctx, AV_LOG_ERROR, "Invalid packet size\n");
@@ -133,7 +132,7 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     /* Allocate buffer */
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     /* Set flags */
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index e6091dfe04..fc2662bf0d 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -33,7 +33,7 @@
 #include "libavutil/thread.h"
 
 #include "h264pred.h"
-#include "thread.h"
+#include "threadframe.h"
 #include "vp56.h"
 #include "vp8dsp.h"
 
diff --git a/libavcodec/vp9shared.h b/libavcodec/vp9shared.h
index 54726df742..ebaa11d2c1 100644
--- a/libavcodec/vp9shared.h
+++ b/libavcodec/vp9shared.h
@@ -28,7 +28,7 @@
 #include <stdint.h>
 
 #include "vp9.h"
-#include "thread.h"
+#include "threadframe.h"
 #include "vp56.h"
 
 enum BlockPartition {
diff --git a/libavcodec/webp.c b/libavcodec/webp.c
index d5a81fd527..9e642e050a 100644
--- a/libavcodec/webp.c
+++ b/libavcodec/webp.c
@@ -568,8 +568,7 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
     img->frame->height = h;
 
     if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) {
-        ThreadFrame pt = { .f = img->frame };
-        ret = ff_thread_get_buffer(s->avctx, &pt, 0);
+        ret = ff_thread_get_buffer(s->avctx, img->frame, 0);
     } else
         ret = av_frame_get_buffer(img->frame, 1);
     if (ret < 0)
diff --git a/libavcodec/ylc.c b/libavcodec/ylc.c
index 1c2b5000fe..cbe33fe174 100644
--- a/libavcodec/ylc.c
+++ b/libavcodec/ylc.c
@@ -285,7 +285,6 @@ static int decode_frame(AVCodecContext *avctx,
     int TL[4] = { 128, 128, 128, 128 };
     int L[4]  = { 128, 128, 128, 128 };
     YLCContext *s = avctx->priv_data;
-    ThreadFrame frame = { .f = data };
     const uint8_t *buf = avpkt->data;
     int ret, x, y, toffset, boffset;
     AVFrame * const p = data;
@@ -307,7 +306,7 @@ static int decode_frame(AVCodecContext *avctx,
     if (toffset >= boffset || boffset >= avpkt->size)
         return AVERROR_INVALIDDATA;
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
         return ret;
 
     av_fast_malloc(&s->buffer, &s->buffer_size,
