diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index d8a0c39254..6bde984815 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -37,6 +37,7 @@
 #include "rangecoder.h"
 #include "mathops.h"
 #include "ffv1.h"
+#include "threadframe.h"
 
 av_cold int ff_ffv1_common_init(AVCodecContext *avctx)
 {
@@ -204,11 +205,11 @@ av_cold int ff_ffv1_close(AVCodecContext *avctx)
     int i, j;
 
     if (s->picture.f)
-        ff_thread_release_buffer(avctx, &s->picture);
+        ff_thread_release_ext_buffer(avctx, &s->picture);
     av_frame_free(&s->picture.f);
 
     if (s->last_picture.f)
-        ff_thread_release_buffer(avctx, &s->last_picture);
+        ff_thread_release_ext_buffer(avctx, &s->last_picture);
     av_frame_free(&s->last_picture.f);
 
     for (j = 0; j < s->max_slice_count; j++) {
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 3f90a8fb55..45ecf3152e 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -842,7 +842,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     AVFrame *p;
 
     if (f->last_picture.f)
-        ff_thread_release_buffer(avctx, &f->last_picture);
+        ff_thread_release_ext_buffer(avctx, &f->last_picture);
     FFSWAP(ThreadFrame, f->picture, f->last_picture);
 
     f->cur = p = f->picture.f;
@@ -874,7 +874,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         p->key_frame = 0;
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &f->picture, AV_GET_BUFFER_FLAG_REF)) < 0)
+    ret = ff_thread_get_ext_buffer(avctx, &f->picture, AV_GET_BUFFER_FLAG_REF);
+    if (ret < 0)
         return ret;
 
     if (avctx->debug & FF_DEBUG_PICT_INFO)
@@ -966,7 +967,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     ff_thread_report_progress(&f->picture, INT_MAX, 0);
 
     if (f->last_picture.f)
-        ff_thread_release_buffer(avctx, &f->last_picture);
+        ff_thread_release_ext_buffer(avctx, &f->last_picture);
     if ((ret = av_frame_ref(data, f->picture.f)) < 0)
         return ret;
 
@@ -1037,7 +1038,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
     av_assert1(fdst->max_slice_count == fsrc->max_slice_count);
 
 
-    ff_thread_release_buffer(dst, &fdst->picture);
+    ff_thread_release_ext_buffer(dst, &fdst->picture);
     if (fsrc->picture.f->data[0]) {
         if ((ret = ff_thread_ref_frame(&fdst->picture, &fsrc->picture)) < 0)
             return ret;
diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c
index 50a21c260f..c7f5b64b99 100644
--- a/libavcodec/h264_picture.c
+++ b/libavcodec/h264_picture.c
@@ -40,7 +40,7 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic)
     if (!pic->f || !pic->f->buf[0])
         return;
 
-    ff_thread_release_buffer(h->avctx, &pic->tf);
+    ff_thread_release_ext_buffer(h->avctx, &pic->tf);
     ff_thread_release_buffer(h->avctx, &pic->tf_grain);
     av_buffer_unref(&pic->hwaccel_priv_buf);
 
@@ -155,7 +155,7 @@ int ff_h264_replace_picture(H264Context *h, H264Picture *dst, const H264Picture
     av_assert0(src->tf.f == src->f);
 
     dst->tf.f = dst->f;
-    ff_thread_release_buffer(h->avctx, &dst->tf);
+    ff_thread_release_ext_buffer(h->avctx, &dst->tf);
     ret = ff_thread_ref_frame(&dst->tf, &src->tf);
     if (ret < 0)
         goto fail;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 600a109889..32d2e090d5 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -191,8 +191,8 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
     av_assert0(!pic->f->data[0]);
 
     pic->tf.f = pic->f;
-    ret = ff_thread_get_buffer(h->avctx, &pic->tf, pic->reference ?
-                                                   AV_GET_BUFFER_FLAG_REF : 0);
+    ret = ff_thread_get_ext_buffer(h->avctx, &pic->tf,
+                                   pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
     if (ret < 0)
         goto fail;
 
@@ -1699,7 +1699,7 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl,
                 ff_thread_await_progress(&prev->tf, INT_MAX, 0);
                 if (prev->field_picture)
                     ff_thread_await_progress(&prev->tf, INT_MAX, 1);
-                ff_thread_release_buffer(h->avctx, &h->short_ref[0]->tf);
+                ff_thread_release_ext_buffer(h->avctx, &h->short_ref[0]->tf);
                 h->short_ref[0]->tf.f = h->short_ref[0]->f;
                 ret = ff_thread_ref_frame(&h->short_ref[0]->tf, &prev->tf);
                 if (ret < 0)
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index d0a7888e21..0dd456bb92 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -38,7 +38,7 @@ void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
 
     frame->flags &= ~flags;
     if (!frame->flags) {
-        ff_thread_release_buffer(s->avctx, &frame->tf);
+        ff_thread_release_ext_buffer(s->avctx, &frame->tf);
         ff_thread_release_buffer(s->avctx, &frame->tf_grain);
         frame->needs_fg = 0;
 
@@ -90,8 +90,8 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
         if (frame->frame->buf[0])
             continue;
 
-        ret = ff_thread_get_buffer(s->avctx, &frame->tf,
-                                   AV_GET_BUFFER_FLAG_REF);
+        ret = ff_thread_get_ext_buffer(s->avctx, &frame->tf,
+                                       AV_GET_BUFFER_FLAG_REF);
         if (ret < 0)
             return NULL;
 
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 6a51da5748..d3343b5da7 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -112,7 +112,7 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
 
     for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
         if (ctx->frames[i].f)
-            ff_thread_release_buffer(avctx, &ctx->frames[i]);
+            ff_thread_release_ext_buffer(avctx, &ctx->frames[i]);
         av_frame_free(&ctx->frames[i].f);
     }
 
@@ -164,7 +164,7 @@ static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCod
     dst->prev_index = src->next_prev_index;
 
     for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
-        ff_thread_release_buffer(avctx, &dst->frames[i]);
+        ff_thread_release_ext_buffer(avctx, &dst->frames[i]);
         if (i != src->next_cur_index && src->frames[i].f->data[0]) {
             ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
             if (ret < 0)
@@ -395,11 +395,11 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+    ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]);
     ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
                                                            AV_PICTURE_TYPE_I;
-    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
-                                    AV_GET_BUFFER_FLAG_REF)) < 0)
+    if ((res = ff_thread_get_ext_buffer(avctx, &ctx->frames[ctx->cur_index],
+                                        AV_GET_BUFFER_FLAG_REF)) < 0)
         return res;
 
     ctx->next_prev_index = ctx->cur_index;
@@ -420,7 +420,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
     ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
     if (res < 0) {
         if (!(avctx->active_thread_type & FF_THREAD_FRAME))
-            ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+            ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]);
         return res;
     }
 
diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c
index 27e497c404..be6e6967e0 100644
--- a/libavcodec/mpegpicture.c
+++ b/libavcodec/mpegpicture.c
@@ -29,6 +29,7 @@
 #include "motion_est.h"
 #include "mpegpicture.h"
 #include "mpegutils.h"
+#include "threadframe.h"
 
 static void av_noinline free_picture_tables(Picture *pic)
 {
@@ -130,8 +131,8 @@ static int alloc_frame_buffer(AVCodecContext *avctx,  Picture *pic,
             pic->f->height = avctx->height + 2 * EDGE_WIDTH;
         }
 
-        r = ff_thread_get_buffer(avctx, &pic->tf,
-                                 pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
+        r = ff_thread_get_ext_buffer(avctx, &pic->tf,
+                                     pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
     } else {
         pic->f->width  = avctx->width;
         pic->f->height = avctx->height;
@@ -321,7 +322,7 @@ void ff_mpeg_unref_picture(AVCodecContext *avctx, Picture *pic)
     if (avctx->codec_id != AV_CODEC_ID_WMV3IMAGE &&
         avctx->codec_id != AV_CODEC_ID_VC1IMAGE  &&
         avctx->codec_id != AV_CODEC_ID_MSS2)
-        ff_thread_release_buffer(avctx, &pic->tf);
+        ff_thread_release_ext_buffer(avctx, &pic->tf);
     else if (pic->f)
         av_frame_unref(pic->f);
 
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 3b12f4057a..7571def907 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -721,8 +721,9 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
             s->bpp += byte_depth;
         }
 
-        ff_thread_release_buffer(avctx, &s->picture);
-        if ((ret = ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF)) < 0)
+        ff_thread_release_ext_buffer(avctx, &s->picture);
+        if ((ret = ff_thread_get_ext_buffer(avctx, &s->picture,
+                                            AV_GET_BUFFER_FLAG_REF)) < 0)
             return ret;
 
         p->pict_type        = AV_PICTURE_TYPE_I;
@@ -1560,7 +1561,7 @@ static int decode_frame_png(AVCodecContext *avctx,
         goto the_end;
 
     if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
-        ff_thread_release_buffer(avctx, &s->last_picture);
+        ff_thread_release_ext_buffer(avctx, &s->last_picture);
         FFSWAP(ThreadFrame, s->picture, s->last_picture);
     }
 
@@ -1624,9 +1625,9 @@ static int decode_frame_apng(AVCodecContext *avctx,
 
     if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
         if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
-            ff_thread_release_buffer(avctx, &s->picture);
+            ff_thread_release_ext_buffer(avctx, &s->picture);
         } else {
-            ff_thread_release_buffer(avctx, &s->last_picture);
+            ff_thread_release_ext_buffer(avctx, &s->last_picture);
             FFSWAP(ThreadFrame, s->picture, s->last_picture);
         }
     }
@@ -1677,7 +1678,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
     src_frame = psrc->dispose_op == APNG_DISPOSE_OP_PREVIOUS ?
                 &psrc->last_picture : &psrc->picture;
 
-    ff_thread_release_buffer(dst, &pdst->last_picture);
+    ff_thread_release_ext_buffer(dst, &pdst->last_picture);
     if (src_frame && src_frame->f->data[0]) {
         ret = ff_thread_ref_frame(&pdst->last_picture, src_frame);
         if (ret < 0)
@@ -1712,9 +1713,9 @@ static av_cold int png_dec_end(AVCodecContext *avctx)
 {
     PNGDecContext *s = avctx->priv_data;
 
-    ff_thread_release_buffer(avctx, &s->last_picture);
+    ff_thread_release_ext_buffer(avctx, &s->last_picture);
     av_frame_free(&s->last_picture.f);
-    ff_thread_release_buffer(avctx, &s->picture);
+    ff_thread_release_ext_buffer(avctx, &s->picture);
     av_frame_free(&s->picture.f);
     av_freep(&s->buffer);
     s->buffer_size = 0;
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 73dc4d3669..f405622ca1 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -1057,6 +1057,11 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
     return ret;
 }
 
+int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
+{
+    return ff_thread_get_buffer(avctx, f, flags);
+}
+
 void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
 {
 #if FF_API_THREAD_SAFE_CALLBACKS
@@ -1126,3 +1131,8 @@ fail:
     }
 #endif
 }
+
+void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
+{
+    ff_thread_release_buffer(avctx, f);
+}
diff --git a/libavcodec/threadframe.h b/libavcodec/threadframe.h
index c2caf511b9..be63e62435 100644
--- a/libavcodec/threadframe.h
+++ b/libavcodec/threadframe.h
@@ -50,4 +50,28 @@ void ff_thread_report_progress(ThreadFrame *f, int progress, int field);
  */
 void ff_thread_await_progress(ThreadFrame *f, int progress, int field);
 
+/**
+ * Wrapper around ff_get_buffer() for frame-multithreaded codecs.
+ * Call this function instead of ff_get_buffer() if you might need
+ * to wait for progress on this frame.
+ * Cannot be called after the codec has called ff_thread_finish_setup().
+ *
+ * @param avctx The current context.
+ * @param f The frame to write into.
+ * @note: It is fine to call this with codecs that do not support
+ *        frame threading.
+ */
+int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
+
+/**
+ * Unref a ThreadFrame.
+ *
+ * This is basically a wrapper around av_frame_unref() and should
+ * be called instead of it.
+ *
+ * @param avctx The current context.
+ * @param f The picture being released.
+ */
+void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f);
+
 #endif
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 0fd4469a74..bc16424f91 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -879,7 +879,7 @@ int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src)
 
     if (src->progress &&
         !(dst->progress = av_buffer_ref(src->progress))) {
-        ff_thread_release_buffer(dst->owner[0], dst);
+        ff_thread_release_ext_buffer(dst->owner[0], dst);
         return AVERROR(ENOMEM);
     }
 
@@ -899,12 +899,25 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
     return ff_get_buffer(avctx, f->f, flags);
 }
 
+int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
+{
+    f->owner[0] = f->owner[1] = avctx;
+    return ff_get_buffer(avctx, f->f, flags);
+}
+
 void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
 {
     if (f->f)
         av_frame_unref(f->f);
 }
 
+void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
+{
+    f->owner[0] = f->owner[1] = NULL;
+    if (f->f)
+        av_frame_unref(f->f);
+}
+
 void ff_thread_finish_setup(AVCodecContext *avctx)
 {
 }
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 06b0e873b6..e9ab54d736 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -333,11 +333,11 @@ static void vp3_decode_flush(AVCodecContext *avctx)
     Vp3DecodeContext *s = avctx->priv_data;
 
     if (s->golden_frame.f)
-        ff_thread_release_buffer(avctx, &s->golden_frame);
+        ff_thread_release_ext_buffer(avctx, &s->golden_frame);
     if (s->last_frame.f)
-        ff_thread_release_buffer(avctx, &s->last_frame);
+        ff_thread_release_ext_buffer(avctx, &s->last_frame);
     if (s->current_frame.f)
-        ff_thread_release_buffer(avctx, &s->current_frame);
+        ff_thread_release_ext_buffer(avctx, &s->current_frame);
 }
 
 static av_cold int vp3_decode_end(AVCodecContext *avctx)
@@ -2507,25 +2507,25 @@ static int update_frames(AVCodecContext *avctx)
     int ret = 0;
 
     /* shuffle frames (last = current) */
-    ff_thread_release_buffer(avctx, &s->last_frame);
+    ff_thread_release_ext_buffer(avctx, &s->last_frame);
     ret = ff_thread_ref_frame(&s->last_frame, &s->current_frame);
     if (ret < 0)
         goto fail;
 
     if (s->keyframe) {
-        ff_thread_release_buffer(avctx, &s->golden_frame);
+        ff_thread_release_ext_buffer(avctx, &s->golden_frame);
         ret = ff_thread_ref_frame(&s->golden_frame, &s->current_frame);
     }
 
 fail:
-    ff_thread_release_buffer(avctx, &s->current_frame);
+    ff_thread_release_ext_buffer(avctx, &s->current_frame);
     return ret;
 }
 
 #if HAVE_THREADS
 static int ref_frame(Vp3DecodeContext *s, ThreadFrame *dst, ThreadFrame *src)
 {
-    ff_thread_release_buffer(s->avctx, dst);
+    ff_thread_release_ext_buffer(s->avctx, dst);
     if (src->f->data[0])
         return ff_thread_ref_frame(dst, src);
     return 0;
@@ -2675,7 +2675,8 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
                                                 : AV_PICTURE_TYPE_P;
     s->current_frame.f->key_frame = s->keyframe;
-    if ((ret = ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF)) < 0)
+    if ((ret = ff_thread_get_ext_buffer(avctx, &s->current_frame,
+                                        AV_GET_BUFFER_FLAG_REF)) < 0)
         goto error;
 
     if (!s->edge_emu_buffer)
@@ -2734,10 +2735,10 @@ static int vp3_decode_frame(AVCodecContext *avctx,
                    "vp3: first frame not a keyframe\n");
 
             s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
-            if ((ret = ff_thread_get_buffer(avctx, &s->golden_frame,
-                                     AV_GET_BUFFER_FLAG_REF)) < 0)
+            if ((ret = ff_thread_get_ext_buffer(avctx, &s->golden_frame,
+                                                AV_GET_BUFFER_FLAG_REF)) < 0)
                 goto error;
-            ff_thread_release_buffer(avctx, &s->last_frame);
+            ff_thread_release_ext_buffer(avctx, &s->last_frame);
             if ((ret = ff_thread_ref_frame(&s->last_frame,
                                            &s->golden_frame)) < 0)
                 goto error;
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 6aba0c5feb..40a7e13683 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -72,8 +72,8 @@ static void free_buffers(VP8Context *s)
 static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
 {
     int ret;
-    if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
-                                    ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+    if ((ret = ff_thread_get_ext_buffer(s->avctx, &f->tf,
+                                        ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
         return ret;
     if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height)))
         goto fail;
@@ -90,7 +90,7 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
 
 fail:
     av_buffer_unref(&f->seg_map);
-    ff_thread_release_buffer(s->avctx, &f->tf);
+    ff_thread_release_ext_buffer(s->avctx, &f->tf);
     return AVERROR(ENOMEM);
 }
 
@@ -99,7 +99,7 @@ static void vp8_release_frame(VP8Context *s, VP8Frame *f)
     av_buffer_unref(&f->seg_map);
     av_buffer_unref(&f->hwaccel_priv_buf);
     f->hwaccel_picture_private = NULL;
-    ff_thread_release_buffer(s->avctx, &f->tf);
+    ff_thread_release_ext_buffer(s->avctx, &f->tf);
 }
 
 #if CONFIG_VP8_DECODER
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 1250425dce..7ef10f7a80 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -93,7 +93,7 @@ static void vp9_tile_data_free(VP9TileData *td)
 
 static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f)
 {
-    ff_thread_release_buffer(avctx, &f->tf);
+    ff_thread_release_ext_buffer(avctx, &f->tf);
     av_buffer_unref(&f->extradata);
     av_buffer_unref(&f->hwaccel_priv_buf);
     f->segmentation_map = NULL;
@@ -105,7 +105,7 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f)
     VP9Context *s = avctx->priv_data;
     int ret, sz;
 
-    ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF);
+    ret = ff_thread_get_ext_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF);
     if (ret < 0)
         return ret;
 
@@ -1237,9 +1237,9 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx)
     }
     av_buffer_pool_uninit(&s->frame_extradata_pool);
     for (i = 0; i < 8; i++) {
-        ff_thread_release_buffer(avctx, &s->s.refs[i]);
+        ff_thread_release_ext_buffer(avctx, &s->s.refs[i]);
         av_frame_free(&s->s.refs[i].f);
-        ff_thread_release_buffer(avctx, &s->next_refs[i]);
+        ff_thread_release_ext_buffer(avctx, &s->next_refs[i]);
         av_frame_free(&s->next_refs[i].f);
     }
 
@@ -1571,7 +1571,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, void *frame,
         ((AVFrame *)frame)->pkt_dts = pkt->dts;
         for (i = 0; i < 8; i++) {
             if (s->next_refs[i].f->buf[0])
-                ff_thread_release_buffer(avctx, &s->next_refs[i]);
+                ff_thread_release_ext_buffer(avctx, &s->next_refs[i]);
             if (s->s.refs[i].f->buf[0] &&
                 (ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0)
                 return ret;
@@ -1611,7 +1611,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, void *frame,
     // ref frame setup
     for (i = 0; i < 8; i++) {
         if (s->next_refs[i].f->buf[0])
-            ff_thread_release_buffer(avctx, &s->next_refs[i]);
+            ff_thread_release_ext_buffer(avctx, &s->next_refs[i]);
         if (s->s.h.refreshrefmask & (1 << i)) {
             ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf);
         } else if (s->s.refs[i].f->buf[0]) {
@@ -1760,7 +1760,7 @@ finish:
     // ref frame setup
     for (i = 0; i < 8; i++) {
         if (s->s.refs[i].f->buf[0])
-            ff_thread_release_buffer(avctx, &s->s.refs[i]);
+            ff_thread_release_ext_buffer(avctx, &s->s.refs[i]);
         if (s->next_refs[i].f->buf[0] &&
             (ret = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0)
             return ret;
@@ -1783,7 +1783,7 @@ static void vp9_decode_flush(AVCodecContext *avctx)
     for (i = 0; i < 3; i++)
         vp9_frame_unref(avctx, &s->s.frames[i]);
     for (i = 0; i < 8; i++)
-        ff_thread_release_buffer(avctx, &s->s.refs[i]);
+        ff_thread_release_ext_buffer(avctx, &s->s.refs[i]);
 }
 
 static av_cold int vp9_decode_init(AVCodecContext *avctx)
@@ -1832,7 +1832,7 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
     }
     for (i = 0; i < 8; i++) {
         if (s->s.refs[i].f->buf[0])
-            ff_thread_release_buffer(dst, &s->s.refs[i]);
+            ff_thread_release_ext_buffer(dst, &s->s.refs[i]);
         if (ssrc->next_refs[i].f->buf[0]) {
             if ((ret = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0)
                 return ret;
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 5a338d7658..30790ef16e 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1019,7 +1019,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
     if (dst == src)
         return 0;
 
-    ff_thread_release_buffer(dst, &fdst->curr_frame);
+    ff_thread_release_ext_buffer(dst, &fdst->curr_frame);
     if (fsrc->curr_frame.f->data[0]) {
         if ((ret = ff_thread_ref_frame(&fdst->curr_frame, &fsrc->curr_frame)) < 0)
             return ret;
@@ -1066,10 +1066,10 @@ static av_cold int wavpack_decode_end(AVCodecContext *avctx)
         av_freep(&s->fdec[i]);
     s->fdec_num = 0;
 
-    ff_thread_release_buffer(avctx, &s->curr_frame);
+    ff_thread_release_ext_buffer(avctx, &s->curr_frame);
     av_frame_free(&s->curr_frame.f);
 
-    ff_thread_release_buffer(avctx, &s->prev_frame);
+    ff_thread_release_ext_buffer(avctx, &s->prev_frame);
     av_frame_free(&s->prev_frame.f);
 
     av_buffer_unref(&s->dsd_ref);
@@ -1539,7 +1539,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 av_log(avctx, AV_LOG_ERROR, "Error reinitializing the DSD context\n");
                 return ret;
             }
-            ff_thread_release_buffer(avctx, &wc->curr_frame);
+            ff_thread_release_ext_buffer(avctx, &wc->curr_frame);
         }
         avctx->channels            = new_channels;
         avctx->channel_layout      = new_chmask;
@@ -1547,12 +1547,14 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
         avctx->sample_fmt          = sample_fmt;
         avctx->bits_per_raw_sample = orig_bpp;
 
-        ff_thread_release_buffer(avctx, &wc->prev_frame);
+        ff_thread_release_ext_buffer(avctx, &wc->prev_frame);
         FFSWAP(ThreadFrame, wc->curr_frame, wc->prev_frame);
 
         /* get output buffer */
         wc->curr_frame.f->nb_samples = s->samples;
-        if ((ret = ff_thread_get_buffer(avctx, &wc->curr_frame, AV_GET_BUFFER_FLAG_REF)) < 0)
+        ret = ff_thread_get_ext_buffer(avctx, &wc->curr_frame,
+                                       AV_GET_BUFFER_FLAG_REF);
+        if (ret < 0)
             return ret;
 
         wc->frame = wc->curr_frame.f;
@@ -1676,7 +1678,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     ff_thread_await_progress(&s->prev_frame, INT_MAX, 0);
-    ff_thread_release_buffer(avctx, &s->prev_frame);
+    ff_thread_release_ext_buffer(avctx, &s->prev_frame);
 
     if (s->modulation == MODULATION_DSD)
         avctx->execute2(avctx, dsd_channel, s->frame, NULL, avctx->channels);
@@ -1693,7 +1695,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
 error:
     if (s->frame) {
         ff_thread_await_progress(&s->prev_frame, INT_MAX, 0);
-        ff_thread_release_buffer(avctx, &s->prev_frame);
+        ff_thread_release_ext_buffer(avctx, &s->prev_frame);
         ff_thread_report_progress(&s->curr_frame, INT_MAX, 0);
     }
 
