diff --git a/libavcodec/012v.c b/libavcodec/012v.c
index 4d57b57082..c03afd0bc7 100644
--- a/libavcodec/012v.c
+++ b/libavcodec/012v.c
@@ -150,7 +150,7 @@ const FFCodec ff_zero12v_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_012V,
     .init           = zero12v_decode_init,
-    .decode         = zero12v_decode_frame,
+    FF_CODEC_DECODE_CB(zero12v_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index 413b4f9330..3fb3568afd 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -1034,7 +1034,7 @@ const FFCodec ff_fourxm_decoder = {
     .priv_data_size = sizeof(FourXContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index d5146043ac..95a35159e3 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -180,7 +180,7 @@ const FFCodec ff_eightbps_decoder = {
     .p.id           = AV_CODEC_ID_8BPS,
     .priv_data_size = sizeof(EightBpsContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index 937800304c..6eb90834b9 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -194,7 +194,7 @@ const FFCodec ff_eightsvx_fib_decoder = {
   .p.id           = AV_CODEC_ID_8SVX_FIB,
   .priv_data_size = sizeof (EightSvxContext),
   .init           = eightsvx_decode_init,
-  .decode         = eightsvx_decode_frame,
+  FF_CODEC_DECODE_CB(eightsvx_decode_frame),
   .close          = eightsvx_decode_close,
   .p.capabilities = AV_CODEC_CAP_DR1,
   .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
@@ -210,7 +210,7 @@ const FFCodec ff_eightsvx_exp_decoder = {
   .p.id           = AV_CODEC_ID_8SVX_EXP,
   .priv_data_size = sizeof (EightSvxContext),
   .init           = eightsvx_decode_init,
-  .decode         = eightsvx_decode_frame,
+  FF_CODEC_DECODE_CB(eightsvx_decode_frame),
   .close          = eightsvx_decode_close,
   .p.capabilities = AV_CODEC_CAP_DR1,
   .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c
index b642a575f1..e80139ee51 100644
--- a/libavcodec/a64multienc.c
+++ b/libavcodec/a64multienc.c
@@ -401,7 +401,7 @@ const FFCodec ff_a64multi_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(A64Context),
     .init           = a64multi_encode_init,
-    .encode2        = a64multi_encode_frame,
+    FF_CODEC_ENCODE_CB(a64multi_encode_frame),
     .close          = a64multi_close_encoder,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
@@ -416,7 +416,7 @@ const FFCodec ff_a64multi5_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(A64Context),
     .init           = a64multi_encode_init,
-    .encode2        = a64multi_encode_frame,
+    FF_CODEC_ENCODE_CB(a64multi_encode_frame),
     .close          = a64multi_close_encoder,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 5fc6738b38..88c128f396 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -560,7 +560,7 @@ const FFCodec ff_aac_decoder = {
     .priv_data_size  = sizeof(AACContext),
     .init            = aac_decode_init,
     .close           = aac_decode_close,
-    .decode          = aac_decode_frame,
+    FF_CODEC_DECODE_CB(aac_decode_frame),
     .p.sample_fmts   = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
     },
@@ -588,7 +588,7 @@ const FFCodec ff_aac_latm_decoder = {
     .priv_data_size  = sizeof(struct LATMContext),
     .init            = latm_decode_init,
     .close           = aac_decode_close,
-    .decode          = latm_decode_frame,
+    FF_CODEC_DECODE_CB(latm_decode_frame),
     .p.sample_fmts   = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
     },
diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c
index bdce588b26..c7ac75024f 100644
--- a/libavcodec/aacdec_fixed.c
+++ b/libavcodec/aacdec_fixed.c
@@ -458,7 +458,7 @@ const FFCodec ff_aac_fixed_decoder = {
     .priv_data_size  = sizeof(AACContext),
     .init            = aac_decode_init,
     .close           = aac_decode_close,
-    .decode          = aac_decode_frame,
+    FF_CODEC_DECODE_CB(aac_decode_frame),
     .p.sample_fmts   = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
     },
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 820d9b60cb..eb091326b1 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -1144,7 +1144,7 @@ const FFCodec ff_aac_encoder = {
     .p.id           = AV_CODEC_ID_AAC,
     .priv_data_size = sizeof(AACEncContext),
     .init           = aac_encode_init,
-    .encode2        = aac_encode_frame,
+    FF_CODEC_ENCODE_CB(aac_encode_frame),
     .close          = aac_encode_end,
     .defaults       = aac_encode_defaults,
     .p.supported_samplerates = ff_mpeg4audio_sample_rates,
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index a462e2f05e..d297cfad76 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -157,7 +157,7 @@ const FFCodec ff_aasc_decoder = {
     .priv_data_size = sizeof(AascContext),
     .init           = aasc_decode_init,
     .close          = aasc_decode_end,
-    .decode         = aasc_decode_frame,
+    FF_CODEC_DECODE_CB(aasc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c
index de44bf80cf..4c0d4d6f5c 100644
--- a/libavcodec/ac3dec_fixed.c
+++ b/libavcodec/ac3dec_fixed.c
@@ -178,7 +178,7 @@ const FFCodec ff_ac3_fixed_decoder = {
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
-    .decode         = ac3_decode_frame,
+    FF_CODEC_DECODE_CB(ac3_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c
index 5aeb378bc6..2147b36afe 100644
--- a/libavcodec/ac3dec_float.c
+++ b/libavcodec/ac3dec_float.c
@@ -66,7 +66,7 @@ const FFCodec ff_ac3_decoder = {
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
-    .decode         = ac3_decode_frame,
+    FF_CODEC_DECODE_CB(ac3_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .p.long_name    = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
@@ -84,7 +84,7 @@ const FFCodec ff_eac3_decoder = {
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
-    .decode         = ac3_decode_frame,
+    FF_CODEC_DECODE_CB(ac3_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .p.long_name    = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index af6b2a20f9..92bf31b039 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -128,7 +128,7 @@ const FFCodec ff_ac3_fixed_encoder = {
     .p.capabilities  = AV_CODEC_CAP_DR1,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ac3_fixed_encode_init,
-    .encode2         = ff_ac3_fixed_encode_frame,
+    FF_CODEC_ENCODE_CB(ff_ac3_fixed_encode_frame),
     .close           = ff_ac3_encode_close,
     .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 1323df74a9..9f5341cf2d 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -132,7 +132,7 @@ const FFCodec ff_ac3_encoder = {
     .p.capabilities  = AV_CODEC_CAP_DR1,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ff_ac3_float_encode_init,
-    .encode2         = ff_ac3_float_encode_frame,
+    FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
     .close           = ff_ac3_encode_close,
     .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index ccb625ab54..b2ef7dfbec 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -2294,7 +2294,7 @@ const FFCodec ff_ ## name_ ## _decoder = {                  \
     .p.sample_fmts  = sample_fmts_,                         \
     .priv_data_size = sizeof(ADPCMDecodeContext),           \
     .init           = adpcm_decode_init,                    \
-    .decode         = adpcm_decode_frame,                   \
+    FF_CODEC_DECODE_CB(adpcm_decode_frame),                 \
     .flush          = adpcm_flush,                          \
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,         \
 };
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index 0a2e6bb3be..4ff77662b4 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -1007,7 +1007,7 @@ const FFCodec ff_ ## name_ ## _encoder = {                                 \
     .p.priv_class   = &adpcm_encoder_class,                                \
     .priv_data_size = sizeof(ADPCMEncodeContext),                          \
     .init           = adpcm_encode_init,                                   \
-    .encode2        = adpcm_encode_frame,                                  \
+    FF_CODEC_ENCODE_CB(adpcm_encode_frame),                                \
     .close          = adpcm_encode_close,                                  \
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, \
 };
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index 870f485726..1ebc250e47 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -197,7 +197,7 @@ const FFCodec ff_adpcm_adx_decoder = {
     .p.id           = AV_CODEC_ID_ADPCM_ADX,
     .priv_data_size = sizeof(ADXContext),
     .init           = adx_decode_init,
-    .decode         = adx_decode_frame,
+    FF_CODEC_DECODE_CB(adx_decode_frame),
     .flush          = adx_decode_flush,
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index af8d2861e7..9277cab7c9 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -197,7 +197,7 @@ const FFCodec ff_adpcm_adx_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(ADXContext),
     .init           = adx_encode_init,
-    .encode2        = adx_encode_frame,
+    FF_CODEC_ENCODE_CB(adx_encode_frame),
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
                                                       AV_SAMPLE_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/agm.c b/libavcodec/agm.c
index 795b34a415..27438dd1a4 100644
--- a/libavcodec/agm.c
+++ b/libavcodec/agm.c
@@ -1294,7 +1294,7 @@ const FFCodec ff_agm_decoder = {
     .priv_data_size   = sizeof(AGMContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush            = decode_flush,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP |
diff --git a/libavcodec/aic.c b/libavcodec/aic.c
index 7f124f5126..5f0eec6b80 100644
--- a/libavcodec/aic.c
+++ b/libavcodec/aic.c
@@ -503,7 +503,7 @@ const FFCodec ff_aic_decoder = {
     .priv_data_size = sizeof(AICContext),
     .init           = aic_decode_init,
     .close          = aic_decode_close,
-    .decode         = aic_decode_frame,
+    FF_CODEC_DECODE_CB(aic_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index b2d47e27c1..9aaf7066b2 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -618,7 +618,7 @@ const FFCodec ff_alac_decoder = {
     .priv_data_size = sizeof(ALACContext),
     .init           = alac_decode_init,
     .close          = alac_decode_close,
-    .decode         = alac_decode_frame,
+    FF_CODEC_DECODE_CB(alac_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.priv_class   = &alac_class
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 62ac32e345..72ce65e265 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -657,7 +657,7 @@ const FFCodec ff_alac_encoder = {
     .priv_data_size = sizeof(AlacEncodeContext),
     .p.priv_class   = &alacenc_class,
     .init           = alac_encode_init,
-    .encode2        = alac_encode_frame,
+    FF_CODEC_ENCODE_CB(alac_encode_frame),
     .close          = alac_encode_close,
     .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
 #if FF_API_OLD_CHANNEL_LAYOUT
diff --git a/libavcodec/aliaspixdec.c b/libavcodec/aliaspixdec.c
index 8dc579079f..73c83528f5 100644
--- a/libavcodec/aliaspixdec.c
+++ b/libavcodec/aliaspixdec.c
@@ -127,5 +127,5 @@ const FFCodec ff_alias_pix_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_ALIAS_PIX,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode       = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff --git a/libavcodec/aliaspixenc.c b/libavcodec/aliaspixenc.c
index 74b5450132..9c43cfa9e7 100644
--- a/libavcodec/aliaspixenc.c
+++ b/libavcodec/aliaspixenc.c
@@ -106,7 +106,7 @@ const FFCodec ff_alias_pix_encoder = {
     .p.long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
     .p.type    = AVMEDIA_TYPE_VIDEO,
     .p.id      = AV_CODEC_ID_ALIAS_PIX,
-    .encode2   = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     },
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 1a517916d5..bf961a03f5 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -2183,7 +2183,7 @@ const FFCodec ff_als_decoder = {
     .priv_data_size = sizeof(ALSDecContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 7df2e8eb1d..efb04589f6 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -384,7 +384,7 @@ const FFCodec ff_h264_amf_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_H264,
     .init           = amf_encode_init_h264,
-    .receive_packet = ff_amf_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(ff_amf_receive_packet),
     .close          = ff_amf_encode_close,
     .priv_data_size = sizeof(AmfContext),
     .p.priv_class   = &h264_amf_class,
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index ed7230ee21..8ab9330730 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -316,7 +316,7 @@ const FFCodec ff_hevc_amf_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_HEVC,
     .init           = amf_encode_init_hevc,
-    .receive_packet = ff_amf_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(ff_amf_receive_packet),
     .close          = ff_amf_encode_close,
     .priv_data_size = sizeof(AmfContext),
     .p.priv_class   = &hevc_amf_class,
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index 72482b25e4..f67ed1d02e 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -1103,7 +1103,7 @@ const FFCodec ff_amrnb_decoder = {
     .p.id           = AV_CODEC_ID_AMR_NB,
     .priv_data_size = sizeof(AMRChannelsContext),
     .init           = amrnb_decode_init,
-    .decode         = amrnb_decode_frame,
+    FF_CODEC_DECODE_CB(amrnb_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index e12078e028..7566f250d2 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -1299,7 +1299,7 @@ const FFCodec ff_amrwb_decoder = {
     .p.id           = AV_CODEC_ID_AMR_WB,
     .priv_data_size = sizeof(AMRWBChannelsContext),
     .init           = amrwb_decode_init,
-    .decode         = amrwb_decode_frame,
+    FF_CODEC_DECODE_CB(amrwb_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index 5e07247992..a9006be9c0 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -197,7 +197,7 @@ const FFCodec ff_anm_decoder = {
     .priv_data_size = sizeof(AnmContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index 80b3df0d92..909ebe7396 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -488,7 +488,7 @@ const FFCodec ff_ansi_decoder = {
     .priv_data_size = sizeof(AnsiContext),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .defaults       = ansi_defaults,
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 89b6bb04e5..f4000725f1 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -1666,7 +1666,7 @@ const FFCodec ff_ape_decoder = {
     .priv_data_size = sizeof(APEContext),
     .init           = ape_decode_init,
     .close          = ape_decode_close,
-    .decode         = ape_decode_frame,
+    FF_CODEC_DECODE_CB(ape_decode_frame),
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY |
                       AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/aptxdec.c b/libavcodec/aptxdec.c
index 03eb27cd5c..6ac070ba99 100644
--- a/libavcodec/aptxdec.c
+++ b/libavcodec/aptxdec.c
@@ -181,7 +181,7 @@ const FFCodec ff_aptx_decoder = {
     .p.id                  = AV_CODEC_ID_APTX,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .decode                = aptx_decode_frame,
+    FF_CODEC_DECODE_CB(aptx_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
 #if FF_API_OLD_CHANNEL_LAYOUT
@@ -201,7 +201,7 @@ const FFCodec ff_aptx_hd_decoder = {
     .p.id                  = AV_CODEC_ID_APTX_HD,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .decode                = aptx_decode_frame,
+    FF_CODEC_DECODE_CB(aptx_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
 #if FF_API_OLD_CHANNEL_LAYOUT
diff --git a/libavcodec/aptxenc.c b/libavcodec/aptxenc.c
index 206eb439e1..89ab3974c5 100644
--- a/libavcodec/aptxenc.c
+++ b/libavcodec/aptxenc.c
@@ -253,7 +253,7 @@ const FFCodec ff_aptx_encoder = {
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .encode2               = aptx_encode_frame,
+    FF_CODEC_ENCODE_CB(aptx_encode_frame),
     .close                 = aptx_close,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
 #if FF_API_OLD_CHANNEL_LAYOUT
@@ -275,7 +275,7 @@ const FFCodec ff_aptx_hd_encoder = {
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .encode2               = aptx_encode_frame,
+    FF_CODEC_ENCODE_CB(aptx_encode_frame),
     .close                 = aptx_close,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
 #if FF_API_OLD_CHANNEL_LAYOUT
diff --git a/libavcodec/arbc.c b/libavcodec/arbc.c
index d5171ee41e..78600963eb 100644
--- a/libavcodec/arbc.c
+++ b/libavcodec/arbc.c
@@ -218,7 +218,7 @@ const FFCodec ff_arbc_decoder = {
     .p.id           = AV_CODEC_ID_ARBC,
     .priv_data_size = sizeof(ARBCContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/argo.c b/libavcodec/argo.c
index 5c52b35b61..efd1056f16 100644
--- a/libavcodec/argo.c
+++ b/libavcodec/argo.c
@@ -740,7 +740,7 @@ const FFCodec ff_argo_decoder = {
     .p.id           = AV_CODEC_ID_ARGO,
     .priv_data_size = sizeof(ArgoContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index bf1260a947..b94629ea1d 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -68,7 +68,7 @@ const FFCodec ff_ssa_decoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_ASS,
     .init         = ass_decode_init,
-    .decode_sub   = ass_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(ass_decode_frame),
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
@@ -80,7 +80,7 @@ const FFCodec ff_ass_decoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_ASS,
     .init         = ass_decode_init,
-    .decode_sub   = ass_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(ass_decode_frame),
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index 948ccdf083..2ac40d5afe 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -75,7 +75,7 @@ const FFCodec ff_ssa_encoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_ASS,
     .init         = ass_encode_init,
-    .encode_sub   = ass_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(ass_encode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
@@ -87,7 +87,7 @@ const FFCodec ff_ass_encoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_ASS,
     .init         = ass_encode_init,
-    .encode_sub   = ass_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(ass_encode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index 0cce79d8b8..5b2c71be82 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -336,7 +336,7 @@ const FFCodec ff_asv1_decoder = {
     .priv_data_size = sizeof(ASV1Context),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -350,7 +350,7 @@ const FFCodec ff_asv2_decoder = {
     .p.id           = AV_CODEC_ID_ASV2,
     .priv_data_size = sizeof(ASV1Context),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index 8dd15f29bd..520173e6c9 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -350,7 +350,7 @@ const FFCodec ff_asv1_encoder = {
     .p.id           = AV_CODEC_ID_ASV1,
     .priv_data_size = sizeof(ASV1Context),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                      AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -365,7 +365,7 @@ const FFCodec ff_asv2_encoder = {
     .p.id           = AV_CODEC_ID_ASV2,
     .priv_data_size = sizeof(ASV1Context),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                      AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 9c953d8772..7265891ac1 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -392,7 +392,7 @@ const FFCodec ff_atrac1_decoder = {
     .priv_data_size = sizeof(AT1Ctx),
     .init           = atrac1_decode_init,
     .close          = atrac1_decode_end,
-    .decode         = atrac1_decode_frame,
+    FF_CODEC_DECODE_CB(atrac1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index 123acdc7e3..97f59438e1 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -1023,7 +1023,7 @@ const FFCodec ff_atrac3_decoder = {
     .priv_data_size   = sizeof(ATRAC3Context),
     .init             = atrac3_decode_init,
     .close            = atrac3_decode_close,
-    .decode           = atrac3_decode_frame,
+    FF_CODEC_DECODE_CB(atrac3_decode_frame),
     .p.capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
     .p.sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                         AV_SAMPLE_FMT_NONE },
@@ -1038,7 +1038,7 @@ const FFCodec ff_atrac3al_decoder = {
     .priv_data_size   = sizeof(ATRAC3Context),
     .init             = atrac3_decode_init,
     .close            = atrac3_decode_close,
-    .decode           = atrac3al_decode_frame,
+    FF_CODEC_DECODE_CB(atrac3al_decode_frame),
     .p.capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
     .p.sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                         AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/atrac3plusdec.c b/libavcodec/atrac3plusdec.c
index 3524ed22e3..f87ffb8938 100644
--- a/libavcodec/atrac3plusdec.c
+++ b/libavcodec/atrac3plusdec.c
@@ -400,7 +400,7 @@ const FFCodec ff_atrac3p_decoder = {
     .priv_data_size = sizeof(ATRAC3PContext),
     .init           = atrac3p_decode_init,
     .close          = atrac3p_decode_close,
-    .decode         = atrac3p_decode_frame,
+    FF_CODEC_DECODE_CB(atrac3p_decode_frame),
 };
 
 const FFCodec ff_atrac3pal_decoder = {
@@ -413,5 +413,5 @@ const FFCodec ff_atrac3pal_decoder = {
     .priv_data_size = sizeof(ATRAC3PContext),
     .init           = atrac3p_decode_init,
     .close          = atrac3p_decode_close,
-    .decode         = atrac3p_decode_frame,
+    FF_CODEC_DECODE_CB(atrac3p_decode_frame),
 };
diff --git a/libavcodec/atrac9dec.c b/libavcodec/atrac9dec.c
index 5d51c23f19..d9ad03140c 100644
--- a/libavcodec/atrac9dec.c
+++ b/libavcodec/atrac9dec.c
@@ -995,7 +995,7 @@ const FFCodec ff_atrac9_decoder = {
     .priv_data_size = sizeof(ATRAC9Context),
     .init           = atrac9_decode_init,
     .close          = atrac9_decode_close,
-    .decode         = atrac9_decode_frame,
+    FF_CODEC_DECODE_CB(atrac9_decode_frame),
     .flush          = atrac9_decode_flush,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c
index 3f6089f29a..b8d0e868f7 100644
--- a/libavcodec/audiotoolboxdec.c
+++ b/libavcodec/audiotoolboxdec.c
@@ -592,7 +592,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx)
         .priv_data_size = sizeof(ATDecodeContext), \
         .init           = ffat_init_decoder, \
         .close          = ffat_close_decoder, \
-        .decode         = ffat_decode, \
+        FF_CODEC_DECODE_CB(ffat_decode), \
         .flush          = ffat_decode_flush, \
         .p.priv_class   = &ffat_##NAME##_dec_class, \
         .bsfs           = bsf_name, \
diff --git a/libavcodec/audiotoolboxenc.c b/libavcodec/audiotoolboxenc.c
index 4e7073064f..f8305ab89b 100644
--- a/libavcodec/audiotoolboxenc.c
+++ b/libavcodec/audiotoolboxenc.c
@@ -621,7 +621,7 @@ static const AVOption options[] = {
         .priv_data_size = sizeof(ATDecodeContext), \
         .init           = ffat_init_encoder, \
         .close          = ffat_close_encoder, \
-        .encode2        = ffat_encode, \
+        FF_CODEC_ENCODE_CB(ffat_encode), \
         .flush          = ffat_encode_flush, \
         .p.priv_class   = &ffat_##NAME##_enc_class, \
         .p.capabilities = AV_CODEC_CAP_DELAY | \
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index 1896013cfb..b4167cacfd 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -102,7 +102,7 @@ const FFCodec ff_aura2_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_AURA2,
     .init           = aura_decode_init,
-    .decode         = aura_decode_frame,
+    FF_CODEC_DECODE_CB(aura_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 517fa701f4..1c09b1d6d6 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -1246,7 +1246,7 @@ const FFCodec ff_av1_decoder = {
     .priv_data_size        = sizeof(AV1DecContext),
     .init                  = av1_decode_init,
     .close                 = av1_decode_free,
-    .decode                = av1_decode_frame,
+    FF_CODEC_DECODE_CB(av1_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE |
                              FF_CODEC_CAP_INIT_CLEANUP |
diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c
index 8f716a129e..9bb0c1ffa2 100644
--- a/libavcodec/avrndec.c
+++ b/libavcodec/avrndec.c
@@ -96,7 +96,7 @@ const FFCodec ff_avrn_decoder = {
     .p.id           = AV_CODEC_ID_AVRN,
     .priv_data_size = sizeof(AVRnContext),
     .init           = init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index a26a3bbc00..6dda3393b5 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -182,7 +182,7 @@ const FFCodec ff_avs_decoder = {
     .p.id           = AV_CODEC_ID_AVS,
     .priv_data_size = sizeof(AvsContext),
     .init           = avs_decode_init,
-    .decode         = avs_decode_frame,
+    FF_CODEC_DECODE_CB(avs_decode_frame),
     .close          = avs_decode_end,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
index a86b0d5668..f545c41154 100644
--- a/libavcodec/avuidec.c
+++ b/libavcodec/avuidec.c
@@ -126,6 +126,6 @@ const FFCodec ff_avui_decoder = {
     .p.id           = AV_CODEC_ID_AVUI,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init         = avui_decode_init,
-    .decode       = avui_decode_frame,
+    FF_CODEC_DECODE_CB(avui_decode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/avuienc.c b/libavcodec/avuienc.c
index dccfd65c90..e2bd3181f5 100644
--- a/libavcodec/avuienc.c
+++ b/libavcodec/avuienc.c
@@ -99,6 +99,6 @@ const FFCodec ff_avui_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_UYVY422, AV_PIX_FMT_NONE },
     .init         = avui_encode_init,
-    .encode2      = avui_encode_frame,
+    FF_CODEC_ENCODE_CB(avui_encode_frame),
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index 44175805f1..9fc286fb00 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -166,7 +166,7 @@ const FFCodec ff_bethsoftvid_decoder = {
     .priv_data_size = sizeof(BethsoftvidContext),
     .init           = bethsoftvid_decode_init,
     .close          = bethsoftvid_decode_end,
-    .decode         = bethsoftvid_decode_frame,
+    FF_CODEC_DECODE_CB(bethsoftvid_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index fb22b0e1b1..6f9fbb0e96 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -183,7 +183,7 @@ const FFCodec ff_bfi_decoder = {
     .priv_data_size = sizeof(BFIContext),
     .init           = bfi_decode_init,
     .close          = bfi_decode_close,
-    .decode         = bfi_decode_frame,
+    FF_CODEC_DECODE_CB(bfi_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index 941c2244a7..ce740ad275 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -1427,7 +1427,7 @@ const FFCodec ff_bink_decoder = {
     .priv_data_size = sizeof(BinkContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index c4f3e743e2..fb5233f0ab 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -372,7 +372,7 @@ const FFCodec ff_binkaudio_rdft_decoder = {
     .init           = decode_init,
     .flush          = decode_flush,
     .close          = decode_end,
-    .receive_frame  = binkaudio_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(binkaudio_receive_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
@@ -386,7 +386,7 @@ const FFCodec ff_binkaudio_dct_decoder = {
     .init           = decode_init,
     .flush          = decode_flush,
     .close          = decode_end,
-    .receive_frame  = binkaudio_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(binkaudio_receive_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/bintext.c b/libavcodec/bintext.c
index 183fea5b84..e153198c32 100644
--- a/libavcodec/bintext.c
+++ b/libavcodec/bintext.c
@@ -224,7 +224,7 @@ const FFCodec ff_bintext_decoder = {
     .p.id           = AV_CODEC_ID_BINTEXT,
     .priv_data_size = sizeof(XbinContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -237,7 +237,7 @@ const FFCodec ff_xbin_decoder = {
     .p.id           = AV_CODEC_ID_XBIN,
     .priv_data_size = sizeof(XbinContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -250,7 +250,7 @@ const FFCodec ff_idf_decoder = {
     .p.id           = AV_CODEC_ID_IDF,
     .priv_data_size = sizeof(XbinContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/bitpacked_dec.c b/libavcodec/bitpacked_dec.c
index 3b8f2d8fd9..4723a3c7eb 100644
--- a/libavcodec/bitpacked_dec.c
+++ b/libavcodec/bitpacked_dec.c
@@ -149,7 +149,7 @@ const FFCodec ff_bitpacked_decoder = {
     .p.capabilities  = AV_CODEC_CAP_FRAME_THREADS,
     .priv_data_size        = sizeof(struct BitpackedContext),
     .init = bitpacked_init_decoder,
-    .decode = bitpacked_decode,
+    FF_CODEC_DECODE_CB(bitpacked_decode),
     .codec_tags     = (const uint32_t []){
         MKTAG('U', 'Y', 'V', 'Y'),
         FF_CODEC_TAGS_END,
diff --git a/libavcodec/bitpacked_enc.c b/libavcodec/bitpacked_enc.c
index c9c0501f39..127f1af59b 100644
--- a/libavcodec/bitpacked_enc.c
+++ b/libavcodec/bitpacked_enc.c
@@ -112,7 +112,7 @@ const FFCodec ff_bitpacked_encoder = {
     .priv_data_size = sizeof(struct BitpackedContext),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10,
                                                     AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index c971ff0f59..410065aba1 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -370,5 +370,5 @@ const FFCodec ff_bmp_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_BMP,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = bmp_decode_frame,
+    FF_CODEC_DECODE_CB(bmp_decode_frame),
 };
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index 1f2303c1e0..f28ce01f59 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -162,7 +162,7 @@ const FFCodec ff_bmp_encoder = {
     .p.id           = AV_CODEC_ID_BMP,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init           = bmp_encode_init,
-    .encode2        = bmp_encode_frame,
+    FF_CODEC_ENCODE_CB(bmp_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24,
         AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444,
diff --git a/libavcodec/bmvaudio.c b/libavcodec/bmvaudio.c
index d21370938f..f57ece0320 100644
--- a/libavcodec/bmvaudio.c
+++ b/libavcodec/bmvaudio.c
@@ -84,7 +84,7 @@ const FFCodec ff_bmv_audio_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_BMV_AUDIO,
     .init           = bmv_aud_decode_init,
-    .decode         = bmv_aud_decode_frame,
+    FF_CODEC_DECODE_CB(bmv_aud_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/bmvvideo.c b/libavcodec/bmvvideo.c
index baa8e37e46..c492d7fcfa 100644
--- a/libavcodec/bmvvideo.c
+++ b/libavcodec/bmvvideo.c
@@ -292,7 +292,7 @@ const FFCodec ff_bmv_video_decoder = {
     .p.id           = AV_CODEC_ID_BMV_VIDEO,
     .priv_data_size = sizeof(BMVDecContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/brenderpix.c b/libavcodec/brenderpix.c
index 98db6e6950..9807a11cf9 100644
--- a/libavcodec/brenderpix.c
+++ b/libavcodec/brenderpix.c
@@ -290,5 +290,5 @@ const FFCodec ff_brender_pix_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_BRENDER_PIX,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode       = pix_decode_frame,
+    FF_CODEC_DECODE_CB(pix_decode_frame),
 };
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index a5dee1d1a3..050bb42741 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -266,7 +266,7 @@ const FFCodec ff_c93_decoder = {
     .priv_data_size = sizeof(C93DecoderContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 6e424f4763..7aaf3f2bcf 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -1318,7 +1318,7 @@ const FFCodec ff_cavs_decoder = {
     .priv_data_size = sizeof(AVSContext),
     .init           = ff_cavs_init,
     .close          = ff_cavs_end,
-    .decode         = cavs_decode_frame,
+    FF_CODEC_DECODE_CB(cavs_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .flush          = cavs_flush,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c
index 32ee3a715d..e33fb36824 100644
--- a/libavcodec/ccaption_dec.c
+++ b/libavcodec/ccaption_dec.c
@@ -955,6 +955,6 @@ const FFCodec ff_ccaption_decoder = {
     .init           = init_decoder,
     .close          = close_decoder,
     .flush          = flush_decoder,
-    .decode_sub     = decode,
+    FF_CODEC_DECODE_SUB_CB(decode),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index 8d72e6d87c..b851ec430b 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -395,7 +395,7 @@ const FFCodec ff_cdgraphics_decoder = {
     .priv_data_size = sizeof(CDGraphicsContext),
     .init           = cdg_decode_init,
     .close          = cdg_decode_end,
-    .decode         = cdg_decode_frame,
+    FF_CODEC_DECODE_CB(cdg_decode_frame),
     .flush          = cdg_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/cdtoons.c b/libavcodec/cdtoons.c
index 1b1c1f827e..eb53a324db 100644
--- a/libavcodec/cdtoons.c
+++ b/libavcodec/cdtoons.c
@@ -451,7 +451,7 @@ const FFCodec ff_cdtoons_decoder = {
     .priv_data_size = sizeof(CDToonsContext),
     .init           = cdtoons_decode_init,
     .close          = cdtoons_decode_end,
-    .decode         = cdtoons_decode_frame,
+    FF_CODEC_DECODE_CB(cdtoons_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .flush          = cdtoons_flush,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index 34481fe2a3..1f25d8eb99 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -344,7 +344,7 @@ const FFCodec ff_cdxl_decoder = {
     .priv_data_size = sizeof(CDXLVideoContext),
     .init           = cdxl_decode_init,
     .close          = cdxl_decode_end,
-    .decode         = cdxl_decode_frame,
+    FF_CODEC_DECODE_CB(cdxl_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index ab074043c1..5adb0b2008 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -1463,7 +1463,7 @@ const FFCodec ff_cfhd_decoder = {
     .priv_data_size   = sizeof(CFHDContext),
     .init             = cfhd_init,
     .close            = cfhd_close,
-    .decode           = cfhd_decode,
+    FF_CODEC_DECODE_CB(cfhd_decode),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c
index f9b8ed2625..6b33b29da9 100644
--- a/libavcodec/cfhdenc.c
+++ b/libavcodec/cfhdenc.c
@@ -854,7 +854,7 @@ const FFCodec ff_cfhd_encoder = {
     .p.priv_class     = &cfhd_class,
     .init             = cfhd_encode_init,
     .close            = cfhd_encode_close,
-    .encode2          = cfhd_encode_frame,
+    FF_CODEC_ENCODE_CB(cfhd_encode_frame),
     .p.capabilities   = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts       = (const enum AVPixelFormat[]) {
                           AV_PIX_FMT_YUV422P10,
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index 9bc7a681e5..e69232efb1 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -514,7 +514,7 @@ const FFCodec ff_cinepak_decoder = {
     .priv_data_size = sizeof(CinepakContext),
     .init           = cinepak_decode_init,
     .close          = cinepak_decode_end,
-    .decode         = cinepak_decode_frame,
+    FF_CODEC_DECODE_CB(cinepak_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/cinepakenc.c b/libavcodec/cinepakenc.c
index 66baae3a1a..8b32c02780 100644
--- a/libavcodec/cinepakenc.c
+++ b/libavcodec/cinepakenc.c
@@ -1201,7 +1201,7 @@ const FFCodec ff_cinepak_encoder = {
     .p.id           = AV_CODEC_ID_CINEPAK,
     .priv_data_size = sizeof(CinepakEncContext),
     .init           = cinepak_encode_init,
-    .encode2        = cinepak_encode_frame,
+    FF_CODEC_ENCODE_CB(cinepak_encode_frame),
     .close          = cinepak_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE },
     .p.priv_class   = &cinepak_class,
diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c
index 4e54ccb680..37283d4ddd 100644
--- a/libavcodec/clearvideo.c
+++ b/libavcodec/clearvideo.c
@@ -775,7 +775,7 @@ const FFCodec ff_clearvideo_decoder = {
     .priv_data_size = sizeof(CLVContext),
     .init           = clv_decode_init,
     .close          = clv_decode_end,
-    .decode         = clv_decode_frame,
+    FF_CODEC_DECODE_CB(clv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/cljrdec.c b/libavcodec/cljrdec.c
index e3a278f16f..bb7c9bfb65 100644
--- a/libavcodec/cljrdec.c
+++ b/libavcodec/cljrdec.c
@@ -87,7 +87,7 @@ const FFCodec ff_cljr_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_CLJR,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/cljrenc.c b/libavcodec/cljrenc.c
index 6bd8537316..2d171a9376 100644
--- a/libavcodec/cljrenc.c
+++ b/libavcodec/cljrenc.c
@@ -115,7 +115,7 @@ const FFCodec ff_cljr_encoder = {
     .p.id           = AV_CODEC_ID_CLJR,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(CLJRContext),
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
                                                    AV_PIX_FMT_NONE },
     .p.priv_class   = &cljr_class,
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index f01498310a..f7283ca4f8 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -498,7 +498,7 @@ const FFCodec ff_cllc_decoder = {
     .p.id           = AV_CODEC_ID_CLLC,
     .priv_data_size = sizeof(CLLCContext),
     .init           = cllc_decode_init,
-    .decode         = cllc_decode_frame,
+    FF_CODEC_DECODE_CB(cllc_decode_frame),
     .close          = cllc_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c
index f396d5a5d0..d549ff4c05 100644
--- a/libavcodec/cngdec.c
+++ b/libavcodec/cngdec.c
@@ -169,7 +169,7 @@ const FFCodec ff_comfortnoise_decoder = {
     .p.id           = AV_CODEC_ID_COMFORT_NOISE,
     .priv_data_size = sizeof(CNGContext),
     .init           = cng_decode_init,
-    .decode         = cng_decode_frame,
+    FF_CODEC_DECODE_CB(cng_decode_frame),
     .flush          = cng_decode_flush,
     .close          = cng_decode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
diff --git a/libavcodec/cngenc.c b/libavcodec/cngenc.c
index 650bfa1938..1f5d25e5b3 100644
--- a/libavcodec/cngenc.c
+++ b/libavcodec/cngenc.c
@@ -104,7 +104,7 @@ const FFCodec ff_comfortnoise_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(CNGContext),
     .init           = cng_encode_init,
-    .encode2        = cng_encode_frame,
+    FF_CODEC_ENCODE_CB(cng_encode_frame),
     .close          = cng_encode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index 4e8c06a49e..a14f6592fe 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -88,6 +88,27 @@ struct AVCodecContext;
 struct AVSubtitle;
 struct AVPacket;
 
+enum FFCodecType {
+    /* The codec is a decoder using the decode callback;
+     * audio and video codecs only. */
+    FF_CODEC_CB_TYPE_DECODE,
+    /* The codec is a decoder using the decode_sub callback;
+     * subtitle codecs only. */
+    FF_CODEC_CB_TYPE_DECODE_SUB,
+    /* The codec is a decoder using the receive_frame callback;
+     * audio and video codecs only. */
+    FF_CODEC_CB_TYPE_RECEIVE_FRAME,
+    /* The codec is an encoder using the encode callback;
+     * audio and video codecs only. */
+    FF_CODEC_CB_TYPE_ENCODE,
+    /* The codec is an encoder using the encode_sub callback;
+     * subtitle codecs only. */
+    FF_CODEC_CB_TYPE_ENCODE_SUB,
+    /* The codec is an encoder using the receive_packet callback;
+     * audio and video codecs only. */
+    FF_CODEC_CB_TYPE_RECEIVE_PACKET,
+};
+
 typedef struct FFCodec {
     /**
      * The public AVCodec. See codec.h for it.
@@ -97,7 +118,14 @@ typedef struct FFCodec {
     /**
      * Internal codec capabilities FF_CODEC_CAP_*.
      */
-    int caps_internal;
+    unsigned caps_internal:29;
+
+    /**
+     * This field determines the type of the codec (decoder/encoder)
+     * and also the exact callback cb implemented by the codec.
+     * cb_type uses enum FFCodecType values.
+     */
+    unsigned cb_type:3;
 
     int priv_data_size;
     /**
@@ -133,53 +161,69 @@ typedef struct FFCodec {
     void (*init_static_data)(struct FFCodec *codec);
 
     int (*init)(struct AVCodecContext *);
-    int (*encode_sub)(struct AVCodecContext *, uint8_t *buf, int buf_size,
-                      const struct AVSubtitle *sub);
-    /**
-     * Encode data to an AVPacket.
-     *
-     * @param      avctx          codec context
-     * @param      avpkt          output AVPacket
-     * @param[in]  frame          AVFrame containing the raw data to be encoded
-     * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
-     *                            non-empty packet was returned in avpkt.
-     * @return 0 on success, negative error code on failure
-     */
-    int (*encode2)(struct AVCodecContext *avctx, struct AVPacket *avpkt,
-                   const struct AVFrame *frame, int *got_packet_ptr);
-    /**
-     * Decode to an AVFrame.
-     *
-     * @param      avctx          codec context
-     * @param      frame          AVFrame for output
-     * @param[out] got_frame_ptr  decoder sets to 0 or 1 to indicate that a
-     *                            non-empty frame was returned in outdata.
-     * @param[in]  avpkt          AVPacket containing the data to be decoded
-     * @return amount of bytes read from the packet on success, negative error
-     *         code on failure
-     */
-    int (*decode)(struct AVCodecContext *avctx, struct AVFrame *frame,
-                  int *got_frame_ptr, struct AVPacket *avpkt);
-    /**
-     * Decode subtitle data. Same as decode except that it uses
-     * a struct AVSubtitle structure for output.
-     */
-    int (*decode_sub)(struct AVCodecContext *avctx, struct AVSubtitle *sub,
+
+    union {
+        /**
+         * Decode to an AVFrame.
+         * cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE.
+         *
+         * @param      avctx          codec context
+         * @param[out] frame          AVFrame for output
+         * @param[out] got_frame_ptr  decoder sets to 0 or 1 to indicate that
+         *                            a non-empty frame was returned in frame.
+         * @param[in]  avpkt          AVPacket containing the data to be decoded
+         * @return amount of bytes read from the packet on success,
+         *         negative error code on failure
+         */
+        int (*decode)(struct AVCodecContext *avctx, struct AVFrame *frame,
                       int *got_frame_ptr, struct AVPacket *avpkt);
+        /**
+         * Decode subtitle data to an AVSubtitle.
+         * cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE_SUB.
+         *
+         * Apart from that this is like the decode callback.
+         */
+        int (*decode_sub)(struct AVCodecContext *avctx, struct AVSubtitle *sub,
+                          int *got_frame_ptr, struct AVPacket *avpkt);
+        /**
+         * Decode API with decoupled packet/frame dataflow.
+         * cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_FRAME.
+         *
+         * This function is called to get one output frame. It should call
+         * ff_decode_get_packet() to obtain input data.
+         */
+        int (*receive_frame)(struct AVCodecContext *avctx, struct AVFrame *frame);
+        /**
+         * Encode data to an AVPacket.
+         * cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE
+         *
+         * @param      avctx          codec context
+         * @param[out] avpkt          output AVPacket
+         * @param[in]  frame          AVFrame containing the input to be encoded
+         * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
+         *                            non-empty packet was returned in avpkt.
+         * @return 0 on success, negative error code on failure
+         */
+        int (*encode)(struct AVCodecContext *avctx, struct AVPacket *avpkt,
+                      const struct AVFrame *frame, int *got_packet_ptr);
+        /**
+         * Encode subtitles to a raw buffer.
+         * cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE_SUB.
+         */
+        int (*encode_sub)(struct AVCodecContext *avctx, uint8_t *buf,
+                          int buf_size, const struct AVSubtitle *sub);
+        /**
+         * Encode API with decoupled frame/packet dataflow.
+         * cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_PACKET.
+         *
+         * This function is called to get one output packet.
+         * It should call ff_encode_get_frame() to obtain input data.
+         */
+        int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt);
+    } cb;
+
     int (*close)(struct AVCodecContext *);
-    /**
-     * Encode API with decoupled frame/packet dataflow. This function is called
-     * to get one output packet. It should call ff_encode_get_frame() to obtain
-     * input data.
-     */
-    int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt);
 
-    /**
-     * Decode API with decoupled packet/frame dataflow. This function is called
-     * to get one output frame. It should call ff_decode_get_packet() to obtain
-     * input data.
-     */
-    int (*receive_frame)(struct AVCodecContext *avctx, struct AVFrame *frame);
     /**
      * Flush buffers.
      * Will be called when seeking
@@ -207,6 +251,25 @@ typedef struct FFCodec {
     const uint32_t *codec_tags;
 } FFCodec;
 
+#define FF_CODEC_DECODE_CB(func)                          \
+    .cb_type           = FF_CODEC_CB_TYPE_DECODE,         \
+    .cb.decode         = (func)
+#define FF_CODEC_DECODE_SUB_CB(func)                      \
+    .cb_type           = FF_CODEC_CB_TYPE_DECODE_SUB,     \
+    .cb.decode_sub     = (func)
+#define FF_CODEC_RECEIVE_FRAME_CB(func)                   \
+    .cb_type           = FF_CODEC_CB_TYPE_RECEIVE_FRAME,  \
+    .cb.receive_frame  = (func)
+#define FF_CODEC_ENCODE_CB(func)                          \
+    .cb_type           = FF_CODEC_CB_TYPE_ENCODE,         \
+    .cb.encode         = (func)
+#define FF_CODEC_ENCODE_SUB_CB(func)                      \
+    .cb_type           = FF_CODEC_CB_TYPE_ENCODE_SUB,     \
+    .cb.encode_sub     = (func)
+#define FF_CODEC_RECEIVE_PACKET_CB(func)                  \
+    .cb_type           = FF_CODEC_CB_TYPE_RECEIVE_PACKET, \
+    .cb.receive_packet = (func)
+
 static av_always_inline const FFCodec *ffcodec(const AVCodec *codec)
 {
     return (const FFCodec*)codec;
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 783623d7db..7161209db3 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -1304,7 +1304,7 @@ const FFCodec ff_cook_decoder = {
     .priv_data_size = sizeof(COOKContext),
     .init           = cook_decode_init,
     .close          = cook_decode_close,
-    .decode         = cook_decode_frame,
+    FF_CODEC_DECODE_CB(cook_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c
index 1b50aa9d30..2f4ad1fb5b 100644
--- a/libavcodec/cpia.c
+++ b/libavcodec/cpia.c
@@ -230,7 +230,7 @@ const FFCodec ff_cpia_decoder = {
     .priv_data_size = sizeof(CpiaContext),
     .init           = cpia_decode_init,
     .close          = cpia_decode_end,
-    .decode         = cpia_decode_frame,
+    FF_CODEC_DECODE_CB(cpia_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/cri.c b/libavcodec/cri.c
index b1922d5e9b..728983797a 100644
--- a/libavcodec/cri.c
+++ b/libavcodec/cri.c
@@ -429,7 +429,7 @@ const FFCodec ff_cri_decoder = {
     .p.id           = AV_CODEC_ID_CRI,
     .priv_data_size = sizeof(CRIContext),
     .init           = cri_decode_init,
-    .decode         = cri_decode_frame,
+    FF_CODEC_DECODE_CB(cri_decode_frame),
     .close          = cri_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index d4cf385cbd..cf74f22e7d 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -783,7 +783,7 @@ static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
         .p.priv_class   = &x##_crystalhd_class, \
         .init           = init, \
         .close          = uninit, \
-        .receive_frame  = crystalhd_receive_frame, \
+        FF_CODEC_RECEIVE_FRAME_CB(crystalhd_receive_frame), \
         .flush          = flush, \
         .bsfs           = bsf_name, \
         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 9b87c1b91d..ea84711299 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -175,7 +175,7 @@ const FFCodec ff_cscd_decoder = {
     .priv_data_size = sizeof(CamStudioContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index 0060e51c91..81d4c89215 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -1112,7 +1112,7 @@ static const AVCodecHWConfigInternal *const cuvid_hw_configs[] = {
         .p.priv_class   = &x##_cuvid_class, \
         .init           = cuvid_decode_init, \
         .close          = cuvid_decode_end, \
-        .receive_frame  = cuvid_output_frame, \
+        FF_CODEC_RECEIVE_FRAME_CB(cuvid_output_frame), \
         .flush          = cuvid_flush, \
         .bsfs           = bsf_name, \
         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index ba20cd02da..8fa4d1f3a7 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -184,7 +184,7 @@ const FFCodec ff_aura_decoder = {
     .p.id           = AV_CODEC_ID_AURA,
     .priv_data_size = sizeof(CyuvDecodeContext),
     .init           = cyuv_decode_init,
-    .decode         = cyuv_decode_frame,
+    FF_CODEC_DECODE_CB(cyuv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -198,7 +198,7 @@ const FFCodec ff_cyuv_decoder = {
     .p.id           = AV_CODEC_ID_CYUV,
     .priv_data_size = sizeof(CyuvDecodeContext),
     .init           = cyuv_decode_init,
-    .decode         = cyuv_decode_frame,
+    FF_CODEC_DECODE_CB(cyuv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 62684b8042..38ea8733e4 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -417,7 +417,7 @@ const FFCodec ff_dca_decoder = {
     .p.id           = AV_CODEC_ID_DTS,
     .priv_data_size = sizeof(DCAContext),
     .init           = dcadec_init,
-    .decode         = dcadec_decode_frame,
+    FF_CODEC_DECODE_CB(dcadec_decode_frame),
     .close          = dcadec_close,
     .flush          = dcadec_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index 7b92b861e3..aad06adb7e 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -1249,7 +1249,7 @@ const FFCodec ff_dca_encoder = {
     .priv_data_size        = sizeof(DCAEncContext),
     .init                  = encode_init,
     .close                 = encode_close,
-    .encode2               = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.sample_fmts         = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
                                                             AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/dds.c b/libavcodec/dds.c
index c5691a4afd..d4f6800ec9 100644
--- a/libavcodec/dds.c
+++ b/libavcodec/dds.c
@@ -753,7 +753,7 @@ const FFCodec ff_dds_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("DirectDraw Surface image decoder"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DDS,
-    .decode         = dds_decode,
+    FF_CODEC_DECODE_CB(dds_decode),
     .priv_data_size = sizeof(DDSContext),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index b5b78b9ca2..e51a39e70a 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -322,7 +322,7 @@ static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame,
     if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) {
         ret = ff_thread_decode_frame(avctx, frame, &got_frame, pkt);
     } else {
-        ret = codec->decode(avctx, frame, &got_frame, pkt);
+        ret = codec->cb.decode(avctx, frame, &got_frame, pkt);
 
         if (!(codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS))
             frame->pkt_dts = pkt->dts;
@@ -546,8 +546,8 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
 
     av_assert0(!frame->buf[0]);
 
-    if (codec->receive_frame) {
-        ret = codec->receive_frame(avctx, frame);
+    if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) {
+        ret = codec->cb.receive_frame(avctx, frame);
         if (ret != AVERROR(EAGAIN))
             av_packet_unref(avci->last_pkt_props);
     } else
@@ -862,7 +862,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
         if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
             sub->pts = av_rescale_q(avpkt->pts,
                                     avctx->pkt_timebase, AV_TIME_BASE_Q);
-        ret = ffcodec(avctx->codec)->decode_sub(avctx, sub, got_sub_ptr, pkt);
+        ret = ffcodec(avctx->codec)->cb.decode_sub(avctx, sub, got_sub_ptr, pkt);
         if (pkt == avci->buffer_pkt) // did we recode?
             av_packet_unref(avci->buffer_pkt);
         if (ret < 0) {
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 4625f62ec6..e74fd071d3 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -429,7 +429,7 @@ const FFCodec ff_dfa_decoder = {
     .priv_data_size = sizeof(DfaContext),
     .init           = dfa_decode_init,
     .close          = dfa_decode_end,
-    .decode         = dfa_decode_frame,
+    FF_CODEC_DECODE_CB(dfa_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/dfpwmdec.c b/libavcodec/dfpwmdec.c
index 4237200c6b..77c6d2cb18 100644
--- a/libavcodec/dfpwmdec.c
+++ b/libavcodec/dfpwmdec.c
@@ -131,7 +131,7 @@ const FFCodec ff_dfpwm_decoder = {
     .p.id           = AV_CODEC_ID_DFPWM,
     .priv_data_size = sizeof(DFPWMState),
     .init           = dfpwm_dec_init,
-    .decode         = dfpwm_dec_frame,
+    FF_CODEC_DECODE_CB(dfpwm_dec_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/dfpwmenc.c b/libavcodec/dfpwmenc.c
index e3a001aea7..85ee1a980a 100644
--- a/libavcodec/dfpwmenc.c
+++ b/libavcodec/dfpwmenc.c
@@ -114,7 +114,7 @@ const FFCodec ff_dfpwm_encoder = {
     .p.id            = AV_CODEC_ID_DFPWM,
     .priv_data_size  = sizeof(DFPWMState),
     .init            = dfpwm_enc_init,
-    .encode2         = dfpwm_enc_frame,
+    FF_CODEC_ENCODE_CB(dfpwm_enc_frame),
     .p.sample_fmts   = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE},
     .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index 319067bc79..d6d8168bd6 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -2364,7 +2364,7 @@ const FFCodec ff_dirac_decoder = {
     .priv_data_size = sizeof(DiracContext),
     .init           = dirac_decode_init,
     .close          = dirac_decode_end,
-    .decode         = dirac_decode_frame,
+    FF_CODEC_DECODE_CB(dirac_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .flush          = dirac_decode_flush,
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 4b22a4134e..65cd6d9398 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -732,7 +732,7 @@ const FFCodec ff_dnxhd_decoder = {
     .priv_data_size = sizeof(DNXHDContext),
     .init           = dnxhd_decode_init,
     .close          = dnxhd_decode_close,
-    .decode         = dnxhd_decode_frame,
+    FF_CODEC_DECODE_CB(dnxhd_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
                       AV_CODEC_CAP_SLICE_THREADS,
     .p.profiles     = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles),
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 1795993efe..c6378f8ecb 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -1361,7 +1361,7 @@ const FFCodec ff_dnxhd_encoder = {
                       AV_CODEC_CAP_SLICE_THREADS,
     .priv_data_size = sizeof(DNXHDEncContext),
     .init           = dnxhd_encode_init,
-    .encode2        = dnxhd_encode_picture,
+    FF_CODEC_ENCODE_CB(dnxhd_encode_picture),
     .close          = dnxhd_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUV422P,
diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c
index 6c86f74c94..a734af8d45 100644
--- a/libavcodec/dolby_e.c
+++ b/libavcodec/dolby_e.c
@@ -1305,7 +1305,7 @@ const FFCodec ff_dolby_e_decoder = {
     .priv_data_size = sizeof(DBEDecodeContext),
     .p.priv_class   = &dolby_e_decoder_class,
     .init           = dolby_e_init,
-    .decode         = dolby_e_decode_frame,
+    FF_CODEC_DECODE_CB(dolby_e_decode_frame),
     .close          = dolby_e_close,
     .flush          = dolby_e_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index db09ef274b..ad020b52f6 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -418,7 +418,7 @@ const FFCodec ff_ ## name_ ## _decoder = {                  \
     .p.capabilities = AV_CODEC_CAP_DR1,                     \
     .priv_data_size = sizeof(DPCMContext),                  \
     .init           = dpcm_decode_init,                     \
-    .decode         = dpcm_decode_frame,                    \
+    FF_CODEC_DECODE_CB(dpcm_decode_frame),                  \
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,         \
 }
 
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 7a3054b140..bb2c5e588e 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -765,6 +765,6 @@ const FFCodec ff_dpx_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DPX,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
 };
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index 15023d615e..1f2b1b8f5d 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -282,7 +282,7 @@ const FFCodec ff_dpx_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(DPXContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_GRAY8,
         AV_PIX_FMT_RGB24,    AV_PIX_FMT_RGBA, AV_PIX_FMT_ABGR,
diff --git a/libavcodec/dsddec.c b/libavcodec/dsddec.c
index e0578bc9cc..f0e54db100 100644
--- a/libavcodec/dsddec.c
+++ b/libavcodec/dsddec.c
@@ -121,7 +121,7 @@ const FFCodec ff_ ## name_ ## _decoder = { \
     .p.type       = AVMEDIA_TYPE_AUDIO, \
     .p.id         = AV_CODEC_ID_##id_, \
     .init         = decode_init, \
-    .decode       = decode_frame, \
+    FF_CODEC_DECODE_CB(decode_frame), \
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS, \
     .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, \
                                                    AV_SAMPLE_FMT_NONE }, \
diff --git a/libavcodec/dsicinaudio.c b/libavcodec/dsicinaudio.c
index 231afb2a69..2cfaebca40 100644
--- a/libavcodec/dsicinaudio.c
+++ b/libavcodec/dsicinaudio.c
@@ -128,7 +128,7 @@ const FFCodec ff_dsicinaudio_decoder = {
     .p.id           = AV_CODEC_ID_DSICINAUDIO,
     .priv_data_size = sizeof(CinAudioContext),
     .init           = cinaudio_decode_init,
-    .decode         = cinaudio_decode_frame,
+    FF_CODEC_DECODE_CB(cinaudio_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/dsicinvideo.c b/libavcodec/dsicinvideo.c
index b33959ef77..71f6071412 100644
--- a/libavcodec/dsicinvideo.c
+++ b/libavcodec/dsicinvideo.c
@@ -329,7 +329,7 @@ const FFCodec ff_dsicinvideo_decoder = {
     .priv_data_size = sizeof(CinVideoContext),
     .init           = cinvideo_decode_init,
     .close          = cinvideo_decode_end,
-    .decode         = cinvideo_decode_frame,
+    FF_CODEC_DECODE_CB(cinvideo_decode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.capabilities = AV_CODEC_CAP_DR1,
 };
diff --git a/libavcodec/dss_sp.c b/libavcodec/dss_sp.c
index 4d7a169f26..b465bfe932 100644
--- a/libavcodec/dss_sp.c
+++ b/libavcodec/dss_sp.c
@@ -779,7 +779,7 @@ const FFCodec ff_dss_sp_decoder = {
     .p.id           = AV_CODEC_ID_DSS_SP,
     .priv_data_size = sizeof(DssSpContext),
     .init           = dss_sp_decode_init,
-    .decode         = dss_sp_decode_frame,
+    FF_CODEC_DECODE_CB(dss_sp_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c
index e1d06a9c36..93642e34b9 100644
--- a/libavcodec/dstdec.c
+++ b/libavcodec/dstdec.c
@@ -386,7 +386,7 @@ const FFCodec ff_dst_decoder = {
     .p.id           = AV_CODEC_ID_DST,
     .priv_data_size = sizeof(DSTContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/dvaudiodec.c b/libavcodec/dvaudiodec.c
index 97851981c5..56d9c3573b 100644
--- a/libavcodec/dvaudiodec.c
+++ b/libavcodec/dvaudiodec.c
@@ -124,7 +124,7 @@ const FFCodec ff_dvaudio_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_DVAUDIO,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(DVAudioContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index c5391ea5ad..58e18cfece 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -1746,7 +1746,7 @@ const FFCodec ff_dvbsub_decoder = {
     .priv_data_size = sizeof(DVBSubContext),
     .init           = dvbsub_init_decoder,
     .close          = dvbsub_close_decoder,
-    .decode_sub     = dvbsub_decode,
+    FF_CODEC_DECODE_SUB_CB(dvbsub_decode),
     .p.priv_class   = &dvbsubdec_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c
index 5444dbfa99..06087b058d 100644
--- a/libavcodec/dvbsubenc.c
+++ b/libavcodec/dvbsubenc.c
@@ -512,5 +512,5 @@ const FFCodec ff_dvbsub_encoder = {
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_DVB_SUBTITLE,
     .priv_data_size = sizeof(DVBSubtitleContext),
-    .encode_sub     = dvbsub_encode,
+    FF_CODEC_ENCODE_SUB_CB(dvbsub_encode),
 };
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index 5a1de7a409..a0bae6f57e 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -688,7 +688,7 @@ const FFCodec ff_dvvideo_decoder = {
     .p.id           = AV_CODEC_ID_DVVIDEO,
     .priv_data_size = sizeof(DVVideoContext),
     .init           = dvvideo_decode_init,
-    .decode         = dvvideo_decode_frame,
+    FF_CODEC_DECODE_CB(dvvideo_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
     .p.max_lowres   = 3,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 713170cdc2..2951e74736 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -760,7 +760,7 @@ const FFCodec ff_dvdsub_decoder = {
     .p.id           = AV_CODEC_ID_DVD_SUBTITLE,
     .priv_data_size = sizeof(DVDSubContext),
     .init           = dvdsub_init,
-    .decode_sub     = dvdsub_decode,
+    FF_CODEC_DECODE_SUB_CB(dvdsub_decode),
     .flush          = dvdsub_flush,
     .p.priv_class   = &dvdsub_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index d6960e5f70..fc3b7d1816 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -500,7 +500,7 @@ const FFCodec ff_dvdsub_encoder = {
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_DVD_SUBTITLE,
     .init           = dvdsub_init,
-    .encode_sub     = dvdsub_encode,
+    FF_CODEC_ENCODE_SUB_CB(dvdsub_encode),
     .p.priv_class   = &dvdsubenc_class,
     .priv_data_size = sizeof(DVDSubtitleContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
index 2a760465e5..2922829dc5 100644
--- a/libavcodec/dvenc.c
+++ b/libavcodec/dvenc.c
@@ -1215,7 +1215,7 @@ const FFCodec ff_dvvideo_encoder = {
                       AV_CODEC_CAP_SLICE_THREADS,
     .priv_data_size = sizeof(DVVideoContext),
     .init           = dvvideo_encode_init,
-    .encode2        = dvvideo_encode_frame,
+    FF_CODEC_ENCODE_CB(dvvideo_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P,
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 1a383f182e..93a1724743 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -369,7 +369,7 @@ const FFCodec ff_dxa_decoder = {
     .priv_data_size = sizeof(DxaDecContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index e7aaee7cb6..b7dfff4755 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -875,6 +875,6 @@ const FFCodec ff_dxtory_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("Dxtory"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DXTORY,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
 };
diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c
index 63fec7a14e..d75f8b0402 100644
--- a/libavcodec/dxv.c
+++ b/libavcodec/dxv.c
@@ -1266,7 +1266,7 @@ const FFCodec ff_dxv_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DXV,
     .init           = dxv_init,
-    .decode         = dxv_decode,
+    FF_CODEC_DECODE_CB(dxv_decode),
     .close          = dxv_close,
     .priv_data_size = sizeof(DXVContext),
     .p.capabilities = AV_CODEC_CAP_DR1 |
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index 5c19d70266..79611cee0c 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -258,7 +258,7 @@ const FFCodec ff_eac3_encoder = {
     .p.capabilities  = AV_CODEC_CAP_DR1,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ff_ac3_float_encode_init,
-    .encode2         = ff_ac3_float_encode_frame,
+    FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
     .close           = ff_ac3_encode_close,
     .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index bd332a9106..0a13a74bb8 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -237,7 +237,7 @@ const FFCodec ff_eacmv_decoder = {
     .priv_data_size = sizeof(CmvContext),
     .init           = cmv_decode_init,
     .close          = cmv_decode_end,
-    .decode         = cmv_decode_frame,
+    FF_CODEC_DECODE_CB(cmv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index e6e90d6bd7..337a9c144a 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -348,7 +348,7 @@ const FFCodec ff_eamad_decoder = {
     .priv_data_size = sizeof(MadContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index ea5f4386bc..2e9d2fe13c 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -253,7 +253,7 @@ const FFCodec ff_eatgq_decoder = {
     .p.id           = AV_CODEC_ID_TGQ,
     .priv_data_size = sizeof(TgqContext),
     .init           = tgq_decode_init,
-    .decode         = tgq_decode_frame,
+    FF_CODEC_DECODE_CB(tgq_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index 525c80a570..23cf7300c6 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -366,7 +366,7 @@ const FFCodec ff_eatgv_decoder = {
     .priv_data_size = sizeof(TgvContext),
     .init           = tgv_decode_init,
     .close          = tgv_decode_end,
-    .decode         = tgv_decode_frame,
+    FF_CODEC_DECODE_CB(tgv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index dad742996c..305ea4ba2c 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -189,7 +189,7 @@ const FFCodec ff_eatqi_decoder = {
     .priv_data_size = sizeof(TqiContext),
     .init           = tqi_decode_init,
     .close          = tqi_decode_end,
-    .decode         = tqi_decode_frame,
+    FF_CODEC_DECODE_CB(tqi_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 70bd8da81f..3891ebcc91 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -152,7 +152,7 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
         return -1;
     }
 
-    ret = ffcodec(avctx->codec)->encode_sub(avctx, buf, buf_size, sub);
+    ret = ffcodec(avctx->codec)->cb.encode_sub(avctx, buf, buf_size, sub);
     avctx->frame_number++;
     return ret;
 }
@@ -202,7 +202,7 @@ static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt)
 
     got_packet = 0;
 
-    av_assert0(codec->encode2);
+    av_assert0(codec->cb_type == FF_CODEC_CB_TYPE_ENCODE);
 
     if (CONFIG_FRAME_THREAD_ENCODER &&
         avci->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME))
@@ -212,7 +212,7 @@ static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt)
          *  no sense to use the properties of the current frame anyway). */
         ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet);
     else {
-        ret = codec->encode2(avctx, avpkt, frame, &got_packet);
+        ret = codec->cb.encode(avctx, avpkt, frame, &got_packet);
         if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && !ret && got_packet &&
             !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
             avpkt->pts = avpkt->dts = frame->pts;
@@ -292,8 +292,8 @@ static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt
             return AVERROR(EINVAL);
     }
 
-    if (ffcodec(avctx->codec)->receive_packet) {
-        ret = ffcodec(avctx->codec)->receive_packet(avctx, avpkt);
+    if (ffcodec(avctx->codec)->cb_type == FF_CODEC_CB_TYPE_RECEIVE_PACKET) {
+        ret = ffcodec(avctx->codec)->cb.receive_packet(avctx, avpkt);
         if (ret < 0)
             av_packet_unref(avpkt);
         else
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index f52573107c..2fdffff13a 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -383,7 +383,7 @@ const FFCodec ff_escape124_decoder = {
     .priv_data_size = sizeof(Escape124Context),
     .init           = escape124_decode_init,
     .close          = escape124_decode_close,
-    .decode         = escape124_decode_frame,
+    FF_CODEC_DECODE_CB(escape124_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
index ffa2274ea9..cd6dd7690b 100644
--- a/libavcodec/escape130.c
+++ b/libavcodec/escape130.c
@@ -353,7 +353,7 @@ const FFCodec ff_escape130_decoder = {
     .priv_data_size = sizeof(Escape130Context),
     .init           = escape130_decode_init,
     .close          = escape130_decode_close,
-    .decode         = escape130_decode_frame,
+    FF_CODEC_DECODE_CB(escape130_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/evrcdec.c b/libavcodec/evrcdec.c
index d3703977ba..a6475199cd 100644
--- a/libavcodec/evrcdec.c
+++ b/libavcodec/evrcdec.c
@@ -935,7 +935,7 @@ const FFCodec ff_evrc_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_EVRC,
     .init           = evrc_decode_init,
-    .decode         = evrc_decode_frame,
+    FF_CODEC_DECODE_CB(evrc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .priv_data_size = sizeof(EVRCContext),
     .p.priv_class   = &evrcdec_class,
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 88e7c01488..4af0f4f771 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -2348,7 +2348,7 @@ const FFCodec ff_exr_decoder = {
     .priv_data_size   = sizeof(EXRContext),
     .init             = decode_init,
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
                         AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/exrenc.c b/libavcodec/exrenc.c
index baf29f5912..459afebb82 100644
--- a/libavcodec/exrenc.c
+++ b/libavcodec/exrenc.c
@@ -543,7 +543,7 @@ const FFCodec ff_exr_encoder = {
     .p.id           = AV_CODEC_ID_EXR,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_close,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
                                                  AV_PIX_FMT_GBRPF32,
diff --git a/libavcodec/fastaudio.c b/libavcodec/fastaudio.c
index fc525e58d1..46fffaf8b8 100644
--- a/libavcodec/fastaudio.c
+++ b/libavcodec/fastaudio.c
@@ -194,7 +194,7 @@ const FFCodec ff_fastaudio_decoder = {
     .p.id           = AV_CODEC_ID_FASTAUDIO,
     .priv_data_size = sizeof(FastAudioContext),
     .init           = fastaudio_init,
-    .decode         = fastaudio_decode,
+    FF_CODEC_DECODE_CB(fastaudio_decode),
     .close          = fastaudio_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 81fa249885..365f8b77a7 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -1060,7 +1060,7 @@ const FFCodec ff_ffv1_decoder = {
     .priv_data_size = sizeof(FFV1Context),
     .init           = decode_init,
     .close          = ff_ffv1_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/ |
                       AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 13af2547a0..cee2627eed 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -1284,7 +1284,7 @@ const FFCodec ff_ffv1_encoder = {
     .p.id           = AV_CODEC_ID_FFV1,
     .priv_data_size = sizeof(FFV1Context),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_close,
     .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DELAY,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c
index 0426386058..67e867b444 100644
--- a/libavcodec/ffwavesynth.c
+++ b/libavcodec/ffwavesynth.c
@@ -467,7 +467,7 @@ const FFCodec ff_ffwavesynth_decoder = {
     .priv_data_size = sizeof(struct wavesynth_context),
     .init           = wavesynth_init,
     .close          = wavesynth_close,
-    .decode         = wavesynth_decode,
+    FF_CODEC_DECODE_CB(wavesynth_decode),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/fic.c b/libavcodec/fic.c
index 86a5012587..e56a1a323c 100644
--- a/libavcodec/fic.c
+++ b/libavcodec/fic.c
@@ -491,7 +491,7 @@ const FFCodec ff_fic_decoder = {
     .p.id           = AV_CODEC_ID_FIC,
     .priv_data_size = sizeof(FICContext),
     .init           = fic_decode_init,
-    .decode         = fic_decode_frame,
+    FF_CODEC_DECODE_CB(fic_decode_frame),
     .close          = fic_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
     .p.priv_class   = &fic_decoder_class,
diff --git a/libavcodec/fitsdec.c b/libavcodec/fitsdec.c
index 25857a1799..b60c2bd441 100644
--- a/libavcodec/fitsdec.c
+++ b/libavcodec/fitsdec.c
@@ -329,5 +329,5 @@ const FFCodec ff_fits_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"),
     .p.priv_class   = &fits_decoder_class,
     .priv_data_size = sizeof(FITSContext),
-    .decode         = fits_decode_frame,
+    FF_CODEC_DECODE_CB(fits_decode_frame),
 };
diff --git a/libavcodec/fitsenc.c b/libavcodec/fitsenc.c
index eebabfb621..5e9100be85 100644
--- a/libavcodec/fitsenc.c
+++ b/libavcodec/fitsenc.c
@@ -116,7 +116,7 @@ const FFCodec ff_fits_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_FITS,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = fits_encode_frame,
+    FF_CODEC_ENCODE_CB(fits_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRAP16BE,
                                                      AV_PIX_FMT_GBRP16BE,
                                                      AV_PIX_FMT_GBRP,
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 11a62daab5..a23d7e2cf1 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -665,7 +665,7 @@ const FFCodec ff_flac_decoder = {
     .priv_data_size = sizeof(FLACContext),
     .init           = flac_decode_init,
     .close          = flac_decode_close,
-    .decode         = flac_decode_frame,
+    FF_CODEC_DECODE_CB(flac_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1 |
                       AV_CODEC_CAP_FRAME_THREADS,
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index 6b46664dd9..e9edd8476d 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -1467,7 +1467,7 @@ const FFCodec ff_flac_encoder = {
                       AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(FlacEncodeContext),
     .init           = flac_encode_init,
-    .encode2        = flac_encode_frame,
+    FF_CODEC_ENCODE_CB(flac_encode_frame),
     .close          = flac_encode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_S32,
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 3cf01336c8..0982161d49 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -502,7 +502,7 @@ const FFCodec ff_flashsv_decoder = {
     .priv_data_size = sizeof(FlashSVContext),
     .init           = flashsv_decode_init,
     .close          = flashsv_decode_end,
-    .decode         = flashsv_decode_frame,
+    FF_CODEC_DECODE_CB(flashsv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
@@ -569,7 +569,7 @@ const FFCodec ff_flashsv2_decoder = {
     .priv_data_size = sizeof(FlashSVContext),
     .init           = flashsv2_decode_init,
     .close          = flashsv2_decode_end,
-    .decode         = flashsv_decode_frame,
+    FF_CODEC_DECODE_CB(flashsv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c
index 42ae77810c..07fa9945ff 100644
--- a/libavcodec/flashsv2enc.c
+++ b/libavcodec/flashsv2enc.c
@@ -917,7 +917,7 @@ const FFCodec ff_flashsv2_encoder = {
     .p.id           = AV_CODEC_ID_FLASHSV2,
     .priv_data_size = sizeof(FlashSV2Context),
     .init           = flashsv2_encode_init,
-    .encode2        = flashsv2_encode_frame,
+    FF_CODEC_ENCODE_CB(flashsv2_encode_frame),
     .close          = flashsv2_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index 0059ea5a46..592bb061cb 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -264,7 +264,7 @@ const FFCodec ff_flashsv_encoder = {
     .p.id           = AV_CODEC_ID_FLASHSV,
     .priv_data_size = sizeof(FlashSVContext),
     .init           = flashsv_encode_init,
-    .encode2        = flashsv_encode_frame,
+    FF_CODEC_ENCODE_CB(flashsv_encode_frame),
     .close          = flashsv_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 79e50aa71d..b841050a81 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -1112,7 +1112,7 @@ const FFCodec ff_flic_decoder = {
     .priv_data_size = sizeof(FlicDecodeContext),
     .init           = flic_decode_init,
     .close          = flic_decode_end,
-    .decode         = flic_decode_frame,
+    FF_CODEC_DECODE_CB(flic_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index 096f82fa88..cc016d129d 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -121,7 +121,7 @@ const FFCodec ff_flv_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_h263_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index 1796c8a698..74ed321e27 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -100,7 +100,7 @@ const FFCodec ff_flv_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
diff --git a/libavcodec/fmvc.c b/libavcodec/fmvc.c
index 0dc918bc8c..4abf6d7048 100644
--- a/libavcodec/fmvc.c
+++ b/libavcodec/fmvc.c
@@ -634,7 +634,7 @@ const FFCodec ff_fmvc_decoder = {
     .priv_data_size   = sizeof(FMVCContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index c6528dd804..07d310a986 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -104,7 +104,7 @@ static void * attribute_align_arg worker(void *v){
         frame = task->indata;
         pkt   = task->outdata;
 
-        ret = ffcodec(avctx->codec)->encode2(avctx, pkt, frame, &got_packet);
+        ret = ffcodec(avctx->codec)->cb.encode(avctx, pkt, frame, &got_packet);
         if(got_packet) {
             int ret2 = av_packet_make_refcounted(pkt);
             if (ret >= 0 && ret2 < 0)
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 82851e74de..7f695305f1 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -347,7 +347,7 @@ const FFCodec ff_fraps_decoder = {
     .priv_data_size = sizeof(FrapsContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index 6ec88808df..766fda7455 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -122,7 +122,7 @@ const FFCodec ff_frwu_decoder = {
     .p.id           = AV_CODEC_ID_FRWU,
     .priv_data_size = sizeof(FRWUContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.priv_class   = &frwu_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
index 72368d9f4f..00964369c5 100644
--- a/libavcodec/g2meet.c
+++ b/libavcodec/g2meet.c
@@ -1630,7 +1630,7 @@ const FFCodec ff_g2m_decoder = {
     .priv_data_size = sizeof(G2MContext),
     .init           = g2m_decode_init,
     .close          = g2m_decode_end,
-    .decode         = g2m_decode_frame,
+    FF_CODEC_DECODE_CB(g2m_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
index e7e846b264..8a02ec5230 100644
--- a/libavcodec/g722dec.c
+++ b/libavcodec/g722dec.c
@@ -146,7 +146,7 @@ const FFCodec ff_adpcm_g722_decoder = {
     .p.id           = AV_CODEC_ID_ADPCM_G722,
     .priv_data_size = sizeof(G722Context),
     .init           = g722_decode_init,
-    .decode         = g722_decode_frame,
+    FF_CODEC_DECODE_CB(g722_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.priv_class   = &g722_decoder_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
index ca6bd46532..325c3927d1 100644
--- a/libavcodec/g722enc.c
+++ b/libavcodec/g722enc.c
@@ -380,7 +380,7 @@ const FFCodec ff_adpcm_g722_encoder = {
     .priv_data_size  = sizeof(G722Context),
     .init            = g722_encode_init,
     .close           = g722_encode_close,
-    .encode2         = g722_encode_frame,
+    FF_CODEC_ENCODE_CB(g722_encode_frame),
     .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
 #if FF_API_OLD_CHANNEL_LAYOUT
     .p.channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, 0 },
diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c
index b025cb2b8e..d095f09fe5 100644
--- a/libavcodec/g723_1dec.c
+++ b/libavcodec/g723_1dec.c
@@ -1118,7 +1118,7 @@ const FFCodec ff_g723_1_decoder = {
     .p.id           = AV_CODEC_ID_G723_1,
     .priv_data_size = sizeof(G723_1_Context),
     .init           = g723_1_decode_init,
-    .decode         = g723_1_decode_frame,
+    FF_CODEC_DECODE_CB(g723_1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
     .p.priv_class   = &g723_1dec_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/g723_1enc.c b/libavcodec/g723_1enc.c
index 60066ec305..e8fb8429c1 100644
--- a/libavcodec/g723_1enc.c
+++ b/libavcodec/g723_1enc.c
@@ -1246,7 +1246,7 @@ const FFCodec ff_g723_1_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(G723_1_Context),
     .init           = g723_1_encode_init,
-    .encode2        = g723_1_encode_frame,
+    FF_CODEC_ENCODE_CB(g723_1_encode_frame),
     .defaults       = defaults,
     .p.sample_fmts  = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 0e19a2a8fc..3bf0da3949 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -408,7 +408,7 @@ const FFCodec ff_adpcm_g726_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_encode_init,
-    .encode2        = g726_encode_frame,
+    FF_CODEC_ENCODE_CB(g726_encode_frame),
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .p.priv_class   = &g726_class,
@@ -426,7 +426,7 @@ const FFCodec ff_adpcm_g726le_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_encode_init,
-    .encode2        = g726_encode_frame,
+    FF_CODEC_ENCODE_CB(g726_encode_frame),
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .p.priv_class   = &g726_class,
@@ -509,7 +509,7 @@ const FFCodec ff_adpcm_g726_decoder = {
     .p.id           = AV_CODEC_ID_ADPCM_G726,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_decode_init,
-    .decode         = g726_decode_frame,
+    FF_CODEC_DECODE_CB(g726_decode_frame),
     .flush          = g726_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -523,7 +523,7 @@ const FFCodec ff_adpcm_g726le_decoder = {
     .p.id           = AV_CODEC_ID_ADPCM_G726LE,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_decode_init,
-    .decode         = g726_decode_frame,
+    FF_CODEC_DECODE_CB(g726_decode_frame),
     .flush          = g726_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.long_name    = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"),
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index 0d54f555bd..a306456f0a 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -759,7 +759,7 @@ const FFCodec ff_g729_decoder = {
     .p.id           = AV_CODEC_ID_G729,
     .priv_data_size = sizeof(G729Context),
     .init           = decoder_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -772,7 +772,7 @@ const FFCodec ff_acelp_kelvin_decoder = {
     .p.id           = AV_CODEC_ID_ACELP_KELVIN,
     .priv_data_size = sizeof(G729Context),
     .init           = decoder_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/gdv.c b/libavcodec/gdv.c
index d4c763cffb..70c2ad4bd1 100644
--- a/libavcodec/gdv.c
+++ b/libavcodec/gdv.c
@@ -568,7 +568,7 @@ const FFCodec ff_gdv_decoder = {
     .priv_data_size = sizeof(GDVContext),
     .init           = gdv_decode_init,
     .close          = gdv_decode_close,
-    .decode         = gdv_decode_frame,
+    FF_CODEC_DECODE_CB(gdv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/gemdec.c b/libavcodec/gemdec.c
index 0844f8cfb3..0d6acd5303 100644
--- a/libavcodec/gemdec.c
+++ b/libavcodec/gemdec.c
@@ -356,6 +356,6 @@ const FFCodec ff_gem_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_GEM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = gem_decode_frame,
+    FF_CODEC_DECODE_CB(gem_decode_frame),
     .close          = gem_close,
 };
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index a22cae1f0b..8c52c865a4 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -559,7 +559,7 @@ const FFCodec ff_gif_encoder = {
     .p.id           = AV_CODEC_ID_GIF,
     .priv_data_size = sizeof(GIFContext),
     .init           = gif_encode_init,
-    .encode2        = gif_encode_frame,
+    FF_CODEC_ENCODE_CB(gif_encode_frame),
     .close          = gif_encode_close,
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB8, AV_PIX_FMT_BGR8, AV_PIX_FMT_RGB4_BYTE, AV_PIX_FMT_BGR4_BYTE,
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index adb8d0cec3..3936de1cd2 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -564,7 +564,7 @@ const FFCodec ff_gif_decoder = {
     .priv_data_size = sizeof(GifState),
     .init           = gif_decode_init,
     .close          = gif_decode_close,
-    .decode         = gif_decode_frame,
+    FF_CODEC_DECODE_CB(gif_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index 84852c8b11..e5b8d6f41f 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -120,7 +120,7 @@ const FFCodec ff_gsm_decoder = {
     .p.id           = AV_CODEC_ID_GSM,
     .priv_data_size = sizeof(GSMContext),
     .init           = gsm_init,
-    .decode         = gsm_decode_frame,
+    FF_CODEC_DECODE_CB(gsm_decode_frame),
     .flush          = gsm_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -134,7 +134,7 @@ const FFCodec ff_gsm_ms_decoder = {
     .p.id           = AV_CODEC_ID_GSM_MS,
     .priv_data_size = sizeof(GSMContext),
     .init           = gsm_init,
-    .decode         = gsm_decode_frame,
+    FF_CODEC_DECODE_CB(gsm_decode_frame),
     .flush          = gsm_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index a826c1ca1c..1699172767 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -688,7 +688,7 @@ const FFCodec ff_h261_decoder = {
     .priv_data_size = sizeof(H261DecContext),
     .init           = h261_decode_init,
     .close          = h261_decode_end,
-    .decode         = h261_decode_frame,
+    FF_CODEC_DECODE_CB(h261_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .p.max_lowres   = 3,
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index f18f58b107..007bb4aa30 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -408,7 +408,7 @@ const FFCodec ff_h261_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .priv_data_size = sizeof(H261EncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 731f442b01..1f9f3e5e95 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -762,7 +762,7 @@ const FFCodec ff_h263_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_h263_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
 #if FF_API_FLAG_TRUNCATED
                       AV_CODEC_CAP_TRUNCATED |
@@ -784,7 +784,7 @@ const FFCodec ff_h263p_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_h263_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
 #if FF_API_FLAG_TRUNCATED
                       AV_CODEC_CAP_TRUNCATED |
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 1dbf136934..d80bc6b17f 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -1070,7 +1070,7 @@ const FFCodec ff_h264_decoder = {
     .priv_data_size        = sizeof(H264Context),
     .init                  = h264_decode_init,
     .close                 = h264_decode_end,
-    .decode                = h264_decode_frame,
+    FF_CODEC_DECODE_CB(h264_decode_frame),
     .p.capabilities        = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
                              AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
                              AV_CODEC_CAP_FRAME_THREADS,
diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c
index 1a0472d432..7db3f5fd76 100644
--- a/libavcodec/hapdec.c
+++ b/libavcodec/hapdec.c
@@ -478,7 +478,7 @@ const FFCodec ff_hap_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_HAP,
     .init           = hap_init,
-    .decode         = hap_decode,
+    FF_CODEC_DECODE_CB(hap_decode),
     .close          = hap_close,
     .priv_data_size = sizeof(HapContext),
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS |
diff --git a/libavcodec/hapenc.c b/libavcodec/hapenc.c
index ee03fef449..f3964896d5 100644
--- a/libavcodec/hapenc.c
+++ b/libavcodec/hapenc.c
@@ -357,7 +357,7 @@ const FFCodec ff_hap_encoder = {
     .priv_data_size = sizeof(HapContext),
     .p.priv_class   = &hapenc_class,
     .init           = hap_init,
-    .encode2        = hap_encode,
+    FF_CODEC_ENCODE_CB(hap_encode),
     .close          = hap_close,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGBA, AV_PIX_FMT_NONE,
diff --git a/libavcodec/hcadec.c b/libavcodec/hcadec.c
index 8539c772d8..4e84942bb9 100644
--- a/libavcodec/hcadec.c
+++ b/libavcodec/hcadec.c
@@ -452,7 +452,7 @@ const FFCodec ff_hca_decoder = {
     .p.id           = AV_CODEC_ID_HCA,
     .priv_data_size = sizeof(HCAContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/hcom.c b/libavcodec/hcom.c
index 4d55360294..74a13e0044 100644
--- a/libavcodec/hcom.c
+++ b/libavcodec/hcom.c
@@ -142,7 +142,7 @@ const FFCodec ff_hcom_decoder = {
     .priv_data_size = sizeof(HCOMContext),
     .init           = hcom_init,
     .close          = hcom_close,
-    .decode         = hcom_decode,
+    FF_CODEC_DECODE_CB(hcom_decode),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 9c2958b643..f782ea6394 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3884,7 +3884,7 @@ const FFCodec ff_hevc_decoder = {
     .p.priv_class          = &hevc_decoder_class,
     .init                  = hevc_decode_init,
     .close                 = hevc_decode_free,
-    .decode                = hevc_decode_frame,
+    FF_CODEC_DECODE_CB(hevc_decode_frame),
     .flush                 = hevc_decode_flush,
     .update_thread_context = ONLY_IF_THREADS_ENABLED(hevc_update_thread_context),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c
index deba534766..9eb9f3a694 100644
--- a/libavcodec/hnm4video.c
+++ b/libavcodec/hnm4video.c
@@ -505,7 +505,7 @@ const FFCodec ff_hnm4_video_decoder = {
     .priv_data_size = sizeof(Hnm4VideoContext),
     .init           = hnm_decode_init,
     .close          = hnm_decode_end,
-    .decode         = hnm_decode_frame,
+    FF_CODEC_DECODE_CB(hnm_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/hq_hqa.c b/libavcodec/hq_hqa.c
index a53b4641a0..cea2475bb8 100644
--- a/libavcodec/hq_hqa.c
+++ b/libavcodec/hq_hqa.c
@@ -388,7 +388,7 @@ const FFCodec ff_hq_hqa_decoder = {
     .p.id           = AV_CODEC_ID_HQ_HQA,
     .priv_data_size = sizeof(HQContext),
     .init           = hq_hqa_decode_init,
-    .decode         = hq_hqa_decode_frame,
+    FF_CODEC_DECODE_CB(hq_hqa_decode_frame),
     .close          = hq_hqa_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index 8c7fc9b1ec..c41fe61387 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -541,7 +541,7 @@ const FFCodec ff_hqx_decoder = {
     .p.id           = AV_CODEC_ID_HQX,
     .priv_data_size = sizeof(HQXContext),
     .init           = hqx_decode_init,
-    .decode         = hqx_decode_frame,
+    FF_CODEC_DECODE_CB(hqx_decode_frame),
     .close          = hqx_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
                       AV_CODEC_CAP_FRAME_THREADS,
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
index d98156e26d..07fa11e37a 100644
--- a/libavcodec/huffyuvdec.c
+++ b/libavcodec/huffyuvdec.c
@@ -1270,7 +1270,7 @@ const FFCodec ff_huffyuv_decoder = {
     .priv_data_size   = sizeof(HYuvContext),
     .init             = decode_init,
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                         AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
@@ -1285,7 +1285,7 @@ const FFCodec ff_ffvhuff_decoder = {
     .priv_data_size   = sizeof(HYuvContext),
     .init             = decode_init,
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                         AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
@@ -1301,7 +1301,7 @@ const FFCodec ff_hymt_decoder = {
     .priv_data_size   = sizeof(HYuvContext),
     .init             = decode_init,
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                         AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
index a19cf7efdc..195d45c911 100644
--- a/libavcodec/huffyuvenc.c
+++ b/libavcodec/huffyuvenc.c
@@ -1056,7 +1056,7 @@ const FFCodec ff_huffyuv_encoder = {
     .p.id           = AV_CODEC_ID_HUFFYUV,
     .priv_data_size = sizeof(HYuvContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.priv_class   = &normal_class,
@@ -1076,7 +1076,7 @@ const FFCodec ff_ffvhuff_encoder = {
     .p.id           = AV_CODEC_ID_FFVHUFF,
     .priv_data_size = sizeof(HYuvContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.priv_class   = &ff_class,
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index 1a3792be0e..ecd4ab2fee 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -248,7 +248,7 @@ const FFCodec ff_idcin_decoder = {
     .p.id           = AV_CODEC_ID_IDCIN,
     .priv_data_size = sizeof(IdcinContext),
     .init           = idcin_decode_init,
-    .decode         = idcin_decode_frame,
+    FF_CODEC_DECODE_CB(idcin_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .defaults       = idcin_defaults,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 184e3b865e..36c9535d54 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -1917,7 +1917,7 @@ const FFCodec ff_iff_ilbm_decoder = {
     .priv_data_size = sizeof(IffContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/ilbcdec.c b/libavcodec/ilbcdec.c
index 182a014d11..62a9ad19bf 100644
--- a/libavcodec/ilbcdec.c
+++ b/libavcodec/ilbcdec.c
@@ -1484,7 +1484,7 @@ const FFCodec ff_ilbc_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_ILBC,
     .init           = ilbc_decode_init,
-    .decode         = ilbc_decode_frame,
+    FF_CODEC_DECODE_CB(ilbc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .priv_data_size = sizeof(ILBCContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 7b0e9d3b55..ee12cd913f 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -1092,7 +1092,7 @@ const FFCodec ff_imc_decoder = {
     .priv_data_size = sizeof(IMCContext),
     .init           = imc_decode_init,
     .close          = imc_decode_close,
-    .decode         = imc_decode_frame,
+    FF_CODEC_DECODE_CB(imc_decode_frame),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
@@ -1109,7 +1109,7 @@ const FFCodec ff_iac_decoder = {
     .priv_data_size = sizeof(IMCContext),
     .init           = imc_decode_init,
     .close          = imc_decode_close,
-    .decode         = imc_decode_frame,
+    FF_CODEC_DECODE_CB(imc_decode_frame),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/imm4.c b/libavcodec/imm4.c
index d531bbdc3d..d826818864 100644
--- a/libavcodec/imm4.c
+++ b/libavcodec/imm4.c
@@ -540,7 +540,7 @@ const FFCodec ff_imm4_decoder = {
     .priv_data_size   = sizeof(IMM4Context),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush            = decode_flush,
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/imm5.c b/libavcodec/imm5.c
index eb30cc5509..9b7ac17aa5 100644
--- a/libavcodec/imm5.c
+++ b/libavcodec/imm5.c
@@ -183,7 +183,7 @@ const FFCodec ff_imm5_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_IMM5,
     .init           = imm5_init,
-    .decode         = imm5_decode_frame,
+    FF_CODEC_DECODE_CB(imm5_decode_frame),
     .close          = imm5_close,
     .flush          = imm5_flush,
     .priv_data_size = sizeof(IMM5Context),
diff --git a/libavcodec/imx.c b/libavcodec/imx.c
index 0d8924bf45..4ee6006860 100644
--- a/libavcodec/imx.c
+++ b/libavcodec/imx.c
@@ -187,7 +187,7 @@ const FFCodec ff_simbiosis_imx_decoder = {
     .p.id           = AV_CODEC_ID_SIMBIOSIS_IMX,
     .priv_data_size = sizeof(SimbiosisIMXContext),
     .init           = imx_decode_init,
-    .decode         = imx_decode_frame,
+    FF_CODEC_DECODE_CB(imx_decode_frame),
     .close          = imx_decode_close,
     .flush          = imx_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index 8b47b59f79..79028975e5 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -267,7 +267,7 @@ const FFCodec ff_indeo2_decoder = {
     .priv_data_size = sizeof(Ir2Context),
     .init           = ir2_decode_init,
     .close          = ir2_decode_end,
-    .decode         = ir2_decode_frame,
+    FF_CODEC_DECODE_CB(ir2_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 753f1b2560..43669f46b5 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -1141,7 +1141,7 @@ const FFCodec ff_indeo3_decoder = {
     .priv_data_size = sizeof(Indeo3DecodeContext),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index 833be98514..f0cdff0e2f 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -711,7 +711,7 @@ const FFCodec ff_indeo4_decoder = {
     .priv_data_size = sizeof(IVI45DecContext),
     .init           = decode_init,
     .close          = ff_ivi_decode_close,
-    .decode         = ff_ivi_decode_frame,
+    FF_CODEC_DECODE_CB(ff_ivi_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index 9a77cb9fba..aff1102211 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -691,7 +691,7 @@ const FFCodec ff_indeo5_decoder = {
     .priv_data_size = sizeof(IVI45DecContext),
     .init           = decode_init,
     .close          = ff_ivi_decode_close,
-    .decode         = ff_ivi_decode_frame,
+    FF_CODEC_DECODE_CB(ff_ivi_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index ddac619b8f..e7e821d3b3 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -137,7 +137,7 @@ const FFCodec ff_h263i_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_h263_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
diff --git a/libavcodec/interplayacm.c b/libavcodec/interplayacm.c
index f669d6cd31..3c482e4c88 100644
--- a/libavcodec/interplayacm.c
+++ b/libavcodec/interplayacm.c
@@ -639,7 +639,7 @@ const FFCodec ff_interplay_acm_decoder = {
     .p.id           = AV_CODEC_ID_INTERPLAY_ACM,
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(InterplayACMContext),
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index ff0efc127c..fe2a9e1e6b 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -1364,7 +1364,7 @@ const FFCodec ff_interplay_video_decoder = {
     .priv_data_size = sizeof(IpvideoContext),
     .init           = ipvideo_decode_init,
     .close          = ipvideo_decode_end,
-    .decode         = ipvideo_decode_frame,
+    FF_CODEC_DECODE_CB(ipvideo_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index db7cdf1fcb..e99ebfe076 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -911,7 +911,7 @@ const FFCodec ff_h263_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
 
@@ -947,6 +947,6 @@ const FFCodec ff_h263p_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index 0658b056cb..0b761d0b00 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -1839,7 +1839,7 @@ const FFCodec ff_jpeg2000_encoder = {
     .p.id           = AV_CODEC_ID_JPEG2000,
     .priv_data_size = sizeof(Jpeg2000EncoderContext),
     .init           = j2kenc_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = j2kenc_destroy,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV444P, AV_PIX_FMT_GRAY8,
diff --git a/libavcodec/jacosubdec.c b/libavcodec/jacosubdec.c
index 0d8e601b28..245ae22221 100644
--- a/libavcodec/jacosubdec.c
+++ b/libavcodec/jacosubdec.c
@@ -199,7 +199,7 @@ const FFCodec ff_jacosub_decoder = {
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_JACOSUB,
     .init           = ff_ass_subtitle_header_default,
-    .decode_sub     = jacosub_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(jacosub_decode_frame),
     .flush          = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 23f4cb768b..92966b11f5 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -2578,7 +2578,7 @@ const FFCodec ff_jpeg2000_decoder = {
     .p.capabilities   = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_DR1,
     .priv_data_size   = sizeof(Jpeg2000DecoderContext),
     .init             = jpeg2000_decode_init,
-    .decode           = jpeg2000_decode_frame,
+    FF_CODEC_DECODE_CB(jpeg2000_decode_frame),
     .p.priv_class     = &jpeg2000_class,
     .p.max_lowres     = 5,
     .p.profiles       = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles),
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 4c747b3919..399837cf2f 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -558,7 +558,7 @@ const FFCodec ff_jpegls_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .receive_frame  = ff_mjpeg_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
                       FF_CODEC_CAP_SETS_PKT_DTS,
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index dbd7941df2..577e8a19db 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -482,7 +482,7 @@ const FFCodec ff_jpegls_encoder = {
     .priv_data_size = sizeof(JPEGLSContext),
     .p.priv_class   = &jpegls_class,
     .init           = encode_jpegls_init,
-    .encode2        = encode_picture_ls,
+    FF_CODEC_ENCODE_CB(encode_picture_ls),
     .close          = encode_jpegls_close,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 805ff9dda5..06015ba59d 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -242,7 +242,7 @@ const FFCodec ff_jv_decoder = {
     .priv_data_size = sizeof(JvContext),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 83dbc8291f..08e92c7107 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -184,7 +184,7 @@ const FFCodec ff_kgv1_decoder = {
     .priv_data_size = sizeof(KgvContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index f031d37b7f..a009ba0ce2 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -411,7 +411,7 @@ const FFCodec ff_kmvc_decoder = {
     .p.id           = AV_CODEC_ID_KMVC,
     .priv_data_size = sizeof(KmvcContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 2276616bb8..3aeb1c8a99 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -732,7 +732,7 @@ const FFCodec ff_lagarith_decoder = {
     .p.id           = AV_CODEC_ID_LAGARITH,
     .priv_data_size = sizeof(LagarithContext),
     .init           = lag_decode_init,
-    .decode         = lag_decode_frame,
+    FF_CODEC_DECODE_CB(lag_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 6285e71d6e..ffa2fe5a6d 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -639,7 +639,7 @@ const FFCodec ff_mszh_decoder = {
     .priv_data_size = sizeof(LclDecContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
 #endif
@@ -654,7 +654,7 @@ const FFCodec ff_zlib_decoder = {
     .priv_data_size = sizeof(LclDecContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
 #endif
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 4389dcebf3..bd42c155aa 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -158,7 +158,7 @@ const FFCodec ff_zlib_encoder = {
     .p.id           = AV_CODEC_ID_ZLIB,
     .priv_data_size = sizeof(LclEncContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c
index a083487c33..52a8bf19e2 100644
--- a/libavcodec/libaomdec.c
+++ b/libavcodec/libaomdec.c
@@ -256,7 +256,7 @@ const FFCodec ff_libaom_av1_decoder = {
     .priv_data_size = sizeof(AV1DecodeContext),
     .init           = av1_init,
     .close          = aom_free,
-    .decode         = aom_decode,
+    FF_CODEC_DECODE_CB(aom_decode),
     .p.capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .p.profiles     = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 7dbb6f6f39..054903e6e2 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1353,7 +1353,7 @@ FFCodec ff_libaom_av1_encoder = {
     .p.wrapper_name = "libaom",
     .priv_data_size = sizeof(AOMContext),
     .init           = av1_init,
-    .encode2        = aom_encode,
+    FF_CODEC_ENCODE_CB(aom_encode),
     .close          = aom_free,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .defaults       = defaults,
diff --git a/libavcodec/libaribb24.c b/libavcodec/libaribb24.c
index ab7e0e02d5..e1a26e5659 100644
--- a/libavcodec/libaribb24.c
+++ b/libavcodec/libaribb24.c
@@ -391,6 +391,6 @@ const FFCodec ff_libaribb24_decoder = {
     .priv_data_size = sizeof(Libaribb24Context),
     .init      = libaribb24_init,
     .close     = libaribb24_close,
-    .decode_sub = libaribb24_decode,
+    FF_CODEC_DECODE_SUB_CB(libaribb24_decode),
     .flush     = libaribb24_flush,
 };
diff --git a/libavcodec/libcelt_dec.c b/libavcodec/libcelt_dec.c
index b5fc391731..d659d80ed2 100644
--- a/libavcodec/libcelt_dec.c
+++ b/libavcodec/libcelt_dec.c
@@ -137,5 +137,5 @@ const FFCodec ff_libcelt_decoder = {
     .priv_data_size = sizeof(struct libcelt_context),
     .init           = libcelt_dec_init,
     .close          = libcelt_dec_close,
-    .decode         = libcelt_dec_decode,
+    FF_CODEC_DECODE_CB(libcelt_dec_decode),
 };
diff --git a/libavcodec/libcodec2.c b/libavcodec/libcodec2.c
index 2cfa1542e4..9064b823ee 100644
--- a/libavcodec/libcodec2.c
+++ b/libavcodec/libcodec2.c
@@ -188,7 +188,7 @@ const FFCodec ff_libcodec2_decoder = {
     .priv_data_size         = sizeof(LibCodec2Context),
     .init                   = libcodec2_init_decoder,
     .close                  = libcodec2_close,
-    .decode                 = libcodec2_decode,
+    FF_CODEC_DECODE_CB(libcodec2_decode),
 #if FF_API_OLD_CHANNEL_LAYOUT
     .p.channel_layouts      = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
 #endif
@@ -207,7 +207,7 @@ const FFCodec ff_libcodec2_encoder = {
     .priv_data_size         = sizeof(LibCodec2Context),
     .init                   = libcodec2_init_encoder,
     .close                  = libcodec2_close,
-    .encode2                = libcodec2_encode,
+    FF_CODEC_ENCODE_CB(libcodec2_encode),
 #if FF_API_OLD_CHANNEL_LAYOUT
     .p.channel_layouts      = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
 #endif
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index fb3ccf169e..64014123ce 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -582,7 +582,7 @@ const FFCodec ff_libdav1d_decoder = {
     .init           = libdav1d_init,
     .close          = libdav1d_close,
     .flush          = libdav1d_flush,
-    .receive_frame  = libdav1d_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(libdav1d_receive_frame),
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SETS_PKT_DTS |
                       FF_CODEC_CAP_AUTO_THREADS,
diff --git a/libavcodec/libdavs2.c b/libavcodec/libdavs2.c
index 564f9fb7c5..a47027d300 100644
--- a/libavcodec/libdavs2.c
+++ b/libavcodec/libdavs2.c
@@ -220,7 +220,7 @@ const FFCodec ff_libdavs2_decoder = {
     .priv_data_size = sizeof(DAVS2Context),
     .init           = davs2_init,
     .close          = davs2_end,
-    .decode         = davs2_decode_frame,
+    FF_CODEC_DECODE_CB(davs2_decode_frame),
     .flush          = davs2_flush,
     .p.capabilities =  AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index c90324a3c8..11eee51a98 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -483,7 +483,7 @@ const FFCodec ff_libfdk_aac_decoder = {
     .p.id           = AV_CODEC_ID_AAC,
     .priv_data_size = sizeof(FDKAACDecContext),
     .init           = fdk_aac_decode_init,
-    .decode         = fdk_aac_decode_frame,
+    FF_CODEC_DECODE_CB(fdk_aac_decode_frame),
     .close          = fdk_aac_decode_close,
     .flush          = fdk_aac_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index d004ae00c3..a5697bde51 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -482,7 +482,7 @@ const FFCodec ff_libfdk_aac_encoder = {
     .p.id                  = AV_CODEC_ID_AAC,
     .priv_data_size        = sizeof(AACContext),
     .init                  = aac_encode_init,
-    .encode2               = aac_encode_frame,
+    FF_CODEC_ENCODE_CB(aac_encode_frame),
     .close                 = aac_encode_close,
     .p.capabilities        = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
     .p.sample_fmts         = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
diff --git a/libavcodec/libgsmdec.c b/libavcodec/libgsmdec.c
index 88f0a0b3d6..9c2304f7a2 100644
--- a/libavcodec/libgsmdec.c
+++ b/libavcodec/libgsmdec.c
@@ -135,7 +135,7 @@ const FFCodec ff_libgsm_decoder = {
     .priv_data_size = sizeof(LibGSMDecodeContext),
     .init           = libgsm_decode_init,
     .close          = libgsm_decode_close,
-    .decode         = libgsm_decode_frame,
+    FF_CODEC_DECODE_CB(libgsm_decode_frame),
     .flush          = libgsm_flush,
 };
 #endif
@@ -150,7 +150,7 @@ const FFCodec ff_libgsm_ms_decoder = {
     .priv_data_size = sizeof(LibGSMDecodeContext),
     .init           = libgsm_decode_init,
     .close          = libgsm_decode_close,
-    .decode         = libgsm_decode_frame,
+    FF_CODEC_DECODE_CB(libgsm_decode_frame),
     .flush          = libgsm_flush,
 };
 #endif
diff --git a/libavcodec/libgsmenc.c b/libavcodec/libgsmenc.c
index 7d24501b2f..a45b77be95 100644
--- a/libavcodec/libgsmenc.c
+++ b/libavcodec/libgsmenc.c
@@ -124,7 +124,7 @@ const FFCodec ff_libgsm_encoder = {
     .p.id           = AV_CODEC_ID_GSM,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init           = libgsm_encode_init,
-    .encode2        = libgsm_encode_frame,
+    FF_CODEC_ENCODE_CB(libgsm_encode_frame),
     .close          = libgsm_encode_close,
     .defaults       = libgsm_defaults,
 #if FF_API_OLD_CHANNEL_LAYOUT
@@ -144,7 +144,7 @@ const FFCodec ff_libgsm_ms_encoder = {
     .p.id           = AV_CODEC_ID_GSM_MS,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init           = libgsm_encode_init,
-    .encode2        = libgsm_encode_frame,
+    FF_CODEC_ENCODE_CB(libgsm_encode_frame),
     .close          = libgsm_encode_close,
     .defaults       = libgsm_defaults,
 #if FF_API_OLD_CHANNEL_LAYOUT
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index 0fecbd4bba..a7b1eaf28c 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -124,7 +124,7 @@ const FFCodec ff_libilbc_decoder = {
     .p.id           = AV_CODEC_ID_ILBC,
     .priv_data_size = sizeof(ILBCDecContext),
     .init           = ilbc_decode_init,
-    .decode         = ilbc_decode_frame,
+    FF_CODEC_DECODE_CB(ilbc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.priv_class   = &ilbc_dec_class,
 };
@@ -206,7 +206,7 @@ const FFCodec ff_libilbc_encoder = {
     .p.id           = AV_CODEC_ID_ILBC,
     .priv_data_size = sizeof(ILBCEncContext),
     .init           = ilbc_encode_init,
-    .encode2        = ilbc_encode_frame,
+    FF_CODEC_ENCODE_CB(ilbc_encode_frame),
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .defaults       = ilbc_encode_defaults,
diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c
index d6de24845d..7fd0e95233 100644
--- a/libavcodec/libkvazaar.c
+++ b/libavcodec/libkvazaar.c
@@ -332,7 +332,7 @@ const FFCodec ff_libkvazaar_encoder = {
     .defaults         = defaults,
 
     .init             = libkvazaar_init,
-    .encode2          = libkvazaar_encode,
+    FF_CODEC_ENCODE_CB(libkvazaar_encode),
     .close            = libkvazaar_close,
 
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 14f9872dd6..02a256c766 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -337,7 +337,7 @@ const FFCodec ff_libmp3lame_encoder = {
                              AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size        = sizeof(LAMEContext),
     .init                  = mp3lame_encode_init,
-    .encode2               = mp3lame_encode_frame,
+    FF_CODEC_ENCODE_CB(mp3lame_encode_frame),
     .close                 = mp3lame_encode_close,
     .p.sample_fmts         = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
                                                              AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index 8650296113..539f0ded3c 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -141,7 +141,7 @@ const FFCodec ff_libopencore_amrnb_decoder = {
     .priv_data_size = sizeof(AMRContext),
     .init           = amr_nb_decode_init,
     .close          = amr_nb_decode_close,
-    .decode         = amr_nb_decode_frame,
+    FF_CODEC_DECODE_CB(amr_nb_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
 };
 #endif /* CONFIG_LIBOPENCORE_AMRNB_DECODER */
@@ -295,7 +295,7 @@ const FFCodec ff_libopencore_amrnb_encoder = {
     .p.id           = AV_CODEC_ID_AMR_NB,
     .priv_data_size = sizeof(AMRContext),
     .init           = amr_nb_encode_init,
-    .encode2        = amr_nb_encode_frame,
+    FF_CODEC_ENCODE_CB(amr_nb_encode_frame),
     .close          = amr_nb_encode_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
@@ -382,7 +382,7 @@ const FFCodec ff_libopencore_amrwb_decoder = {
     .priv_data_size = sizeof(AMRWBContext),
     .init           = amr_wb_decode_init,
     .close          = amr_wb_decode_close,
-    .decode         = amr_wb_decode_frame,
+    FF_CODEC_DECODE_CB(amr_wb_decode_frame),
 };
 
 #endif /* CONFIG_LIBOPENCORE_AMRWB_DECODER */
diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c
index a88974cc62..b3e522c31f 100644
--- a/libavcodec/libopenh264dec.c
+++ b/libavcodec/libopenh264dec.c
@@ -163,7 +163,7 @@ const FFCodec ff_libopenh264_decoder = {
     .p.id           = AV_CODEC_ID_H264,
     .priv_data_size = sizeof(SVCContext),
     .init           = svc_decode_init,
-    .decode         = svc_decode_frame,
+    FF_CODEC_DECODE_CB(svc_decode_frame),
     .close          = svc_decode_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
index 7b25eba5d2..f31ed2d4ca 100644
--- a/libavcodec/libopenh264enc.c
+++ b/libavcodec/libopenh264enc.c
@@ -459,7 +459,7 @@ const FFCodec ff_libopenh264_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
     .priv_data_size = sizeof(SVCContext),
     .init           = svc_encode_init,
-    .encode2        = svc_encode_frame,
+    FF_CODEC_ENCODE_CB(svc_encode_frame),
     .close          = svc_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
                       FF_CODEC_CAP_AUTO_THREADS,
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 1458ea3fdf..58715b43ee 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -511,5 +511,5 @@ const FFCodec ff_libopenjpeg_decoder = {
     .p.wrapper_name = "libopenjpeg",
     .priv_data_size = sizeof(LibOpenJPEGContext),
     .init           = libopenjpeg_decode_init,
-    .decode         = libopenjpeg_decode_frame,
+    FF_CODEC_DECODE_CB(libopenjpeg_decode_frame),
 };
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index a07fde9a09..06338e882c 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -761,7 +761,7 @@ const FFCodec ff_libopenjpeg_encoder = {
     .p.id           = AV_CODEC_ID_JPEG2000,
     .priv_data_size = sizeof(LibOpenJPEGContext),
     .init           = libopenjpeg_encode_init,
-    .encode2        = libopenjpeg_encode_frame,
+    FF_CODEC_ENCODE_CB(libopenjpeg_encode_frame),
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c
index dcc1599d63..316ab0f2a7 100644
--- a/libavcodec/libopusdec.c
+++ b/libavcodec/libopusdec.c
@@ -238,7 +238,7 @@ const FFCodec ff_libopus_decoder = {
     .priv_data_size = sizeof(struct libopus_context),
     .init           = libopus_decode_init,
     .close          = libopus_decode_close,
-    .decode         = libopus_decode,
+    FF_CODEC_DECODE_CB(libopus_decode),
     .flush          = libopus_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index 0573d59736..c884075ffe 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -590,7 +590,7 @@ const FFCodec ff_libopus_encoder = {
     .p.id            = AV_CODEC_ID_OPUS,
     .priv_data_size  = sizeof(LibopusEncContext),
     .init            = libopus_encode_init,
-    .encode2         = libopus_encode,
+    FF_CODEC_ENCODE_CB(libopus_encode),
     .close           = libopus_encode_close,
     .p.capabilities  = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
diff --git a/libavcodec/librav1e.c b/libavcodec/librav1e.c
index aa8c0c8860..9d811ba81c 100644
--- a/libavcodec/librav1e.c
+++ b/libavcodec/librav1e.c
@@ -620,7 +620,7 @@ const FFCodec ff_librav1e_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_AV1,
     .init           = librav1e_encode_init,
-    .receive_packet = librav1e_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(librav1e_receive_packet),
     .close          = librav1e_encode_close,
     .priv_data_size = sizeof(librav1eContext),
     .p.priv_class   = &class,
diff --git a/libavcodec/librsvgdec.c b/libavcodec/librsvgdec.c
index c37fbbb0c9..6e949fe3d5 100644
--- a/libavcodec/librsvgdec.c
+++ b/libavcodec/librsvgdec.c
@@ -126,6 +126,6 @@ const FFCodec ff_librsvg_decoder = {
     .p.id           = AV_CODEC_ID_SVG,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.wrapper_name = "librsvg",
-    .decode         = librsvg_decode_frame,
+    FF_CODEC_DECODE_CB(librsvg_decode_frame),
     .priv_data_size = sizeof(LibRSVGContext),
 };
diff --git a/libavcodec/libshine.c b/libavcodec/libshine.c
index 2274c1aa32..9bc545689a 100644
--- a/libavcodec/libshine.c
+++ b/libavcodec/libshine.c
@@ -139,7 +139,7 @@ const FFCodec ff_libshine_encoder = {
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size        = sizeof(SHINEContext),
     .init                  = libshine_encode_init,
-    .encode2               = libshine_encode_frame,
+    FF_CODEC_ENCODE_CB(libshine_encode_frame),
     .close                 = libshine_encode_close,
     .p.sample_fmts         = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
                                                             AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index da47b271e0..8c9e05e51d 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -200,6 +200,6 @@ const FFCodec ff_libspeex_decoder = {
     .priv_data_size = sizeof(LibSpeexContext),
     .init           = libspeex_decode_init,
     .close          = libspeex_decode_close,
-    .decode         = libspeex_decode_frame,
+    FF_CODEC_DECODE_CB(libspeex_decode_frame),
     .flush          = libspeex_decode_flush,
 };
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index 2c4f4caac9..ec4b3c6a8f 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -355,7 +355,7 @@ const FFCodec ff_libspeex_encoder = {
     .p.id           = AV_CODEC_ID_SPEEX,
     .priv_data_size = sizeof(LibSpeexEncContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_close,
     .p.capabilities = AV_CODEC_CAP_DELAY,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 6cf280377e..7db789be5e 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -614,7 +614,7 @@ const FFCodec ff_libsvtav1_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_AV1,
     .init           = eb_enc_init,
-    .receive_packet = eb_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(eb_receive_packet),
     .close          = eb_enc_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index af07575482..162d170b0f 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -377,7 +377,7 @@ const FFCodec ff_libtheora_encoder = {
     .priv_data_size = sizeof(TheoraContext),
     .init           = encode_init,
     .close          = encode_close,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE
     },
diff --git a/libavcodec/libtwolame.c b/libavcodec/libtwolame.c
index 4320aa1b8c..1e53cf2257 100644
--- a/libavcodec/libtwolame.c
+++ b/libavcodec/libtwolame.c
@@ -216,7 +216,7 @@ const FFCodec ff_libtwolame_encoder = {
     .p.id           = AV_CODEC_ID_MP2,
     .priv_data_size = sizeof(TWOLAMEContext),
     .init           = twolame_encode_init,
-    .encode2        = twolame_encode_frame,
+    FF_CODEC_ENCODE_CB(twolame_encode_frame),
     .close          = twolame_encode_close,
     .p.capabilities = AV_CODEC_CAP_DELAY,
     .defaults       = twolame_defaults,
diff --git a/libavcodec/libuavs3d.c b/libavcodec/libuavs3d.c
index b5e861bd1f..48333f17d1 100644
--- a/libavcodec/libuavs3d.c
+++ b/libavcodec/libuavs3d.c
@@ -255,7 +255,7 @@ const FFCodec ff_libuavs3d_decoder = {
     .priv_data_size = sizeof(uavs3d_context),
     .init           = libuavs3d_init,
     .close          = libuavs3d_end,
-    .decode         = libuavs3d_decode_frame,
+    FF_CODEC_DECODE_CB(libuavs3d_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .flush          = libuavs3d_flush,
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index a52edbfaac..12ef6d7fe6 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -150,7 +150,7 @@ const FFCodec ff_libvo_amrwbenc_encoder = {
     .p.wrapper_name = "libvo_amrwbenc",
     .priv_data_size = sizeof(AMRWBContext),
     .init           = amr_wb_encode_init,
-    .encode2        = amr_wb_encode_frame,
+    FF_CODEC_ENCODE_CB(amr_wb_encode_frame),
     .close          = amr_wb_encode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c
index 26bd0c994e..81c4ac1c02 100644
--- a/libavcodec/libvorbisdec.c
+++ b/libavcodec/libvorbisdec.c
@@ -218,6 +218,6 @@ const FFCodec ff_libvorbis_decoder = {
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF,
     .priv_data_size = sizeof(OggVorbisDecContext),
     .init           = oggvorbis_decode_init,
-    .decode         = oggvorbis_decode_frame,
+    FF_CODEC_DECODE_CB(oggvorbis_decode_frame),
     .close          = oggvorbis_decode_close,
 };
diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c
index 5266da8dc0..9460d3267c 100644
--- a/libavcodec/libvorbisenc.c
+++ b/libavcodec/libvorbisenc.c
@@ -384,7 +384,7 @@ const FFCodec ff_libvorbis_encoder = {
                       AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(LibvorbisEncContext),
     .init           = libvorbis_encode_init,
-    .encode2        = libvorbis_encode_frame,
+    FF_CODEC_ENCODE_CB(libvorbis_encode_frame),
     .close          = libvorbis_encode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 51bdd13832..ef690a7093 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -365,7 +365,7 @@ const FFCodec ff_libvpx_vp8_decoder = {
     .priv_data_size = sizeof(VPxContext),
     .init           = vp8_init,
     .close          = vpx_free,
-    .decode         = vpx_decode,
+    FF_CODEC_DECODE_CB(vpx_decode),
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
 };
 #endif /* CONFIG_LIBVPX_VP8_DECODER */
@@ -388,7 +388,7 @@ FFCodec ff_libvpx_vp9_decoder = {
     .priv_data_size = sizeof(VPxContext),
     .init           = vp9_init,
     .close          = vpx_free,
-    .decode         = vpx_decode,
+    FF_CODEC_DECODE_CB(vpx_decode),
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .init_static_data = ff_vp9_init_static,
 };
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index dff1d06b0e..21a02d0b99 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1934,7 +1934,7 @@ const FFCodec ff_libvpx_vp8_encoder = {
                       AV_CODEC_CAP_OTHER_THREADS,
     .priv_data_size = sizeof(VPxContext),
     .init           = vp8_init,
-    .encode2        = vpx_encode,
+    FF_CODEC_ENCODE_CB(vpx_encode),
     .close          = vpx_free,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },
@@ -1969,7 +1969,7 @@ FFCodec ff_libvpx_vp9_encoder = {
     .p.wrapper_name = "libvpx",
     .priv_data_size = sizeof(VPxContext),
     .init           = vp9_init,
-    .encode2        = vpx_encode,
+    FF_CODEC_ENCODE_CB(vpx_encode),
     .close          = vpx_free,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .defaults       = defaults,
diff --git a/libavcodec/libwebpenc.c b/libavcodec/libwebpenc.c
index 12f15bbf65..c5dc1b160a 100644
--- a/libavcodec/libwebpenc.c
+++ b/libavcodec/libwebpenc.c
@@ -99,6 +99,6 @@ const FFCodec ff_libwebp_encoder = {
     .priv_data_size = sizeof(LibWebPContext),
     .defaults       = ff_libwebp_defaults,
     .init           = libwebp_encode_init,
-    .encode2        = libwebp_encode_frame,
+    FF_CODEC_ENCODE_CB(libwebp_encode_frame),
     .close          = libwebp_encode_close,
 };
diff --git a/libavcodec/libwebpenc_animencoder.c b/libavcodec/libwebpenc_animencoder.c
index 0f5b524335..c50c2a6a96 100644
--- a/libavcodec/libwebpenc_animencoder.c
+++ b/libavcodec/libwebpenc_animencoder.c
@@ -137,6 +137,6 @@ const FFCodec ff_libwebp_anim_encoder = {
     .priv_data_size = sizeof(LibWebPAnimContext),
     .defaults       = ff_libwebp_defaults,
     .init           = libwebp_anim_encode_init,
-    .encode2        = libwebp_anim_encode_frame,
+    FF_CODEC_ENCODE_CB(libwebp_anim_encode_frame),
     .close          = libwebp_anim_encode_close,
 };
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 989370ef70..4ce3791ae8 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -1228,7 +1228,7 @@ FFCodec ff_libx264_encoder = {
     .p.wrapper_name   = "libx264",
     .priv_data_size   = sizeof(X264Context),
     .init             = X264_init,
-    .encode2          = X264_frame,
+    FF_CODEC_ENCODE_CB(X264_frame),
     .close            = X264_close,
     .defaults         = x264_defaults,
 #if X264_BUILD < 153
@@ -1265,7 +1265,7 @@ const FFCodec ff_libx264rgb_encoder = {
     .p.wrapper_name = "libx264",
     .priv_data_size = sizeof(X264Context),
     .init           = X264_init,
-    .encode2        = X264_frame,
+    FF_CODEC_ENCODE_CB(X264_frame),
     .close          = X264_close,
     .defaults       = x264_defaults,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS
@@ -1297,7 +1297,7 @@ const FFCodec ff_libx262_encoder = {
     .p.wrapper_name   = "libx264",
     .priv_data_size   = sizeof(X264Context),
     .init             = X264_init,
-    .encode2          = X264_frame,
+    FF_CODEC_ENCODE_CB(X264_frame),
     .close            = X264_close,
     .defaults         = x264_defaults,
     .caps_internal    = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index abe64d69ef..4dcdcd7a77 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -752,7 +752,7 @@ FFCodec ff_libx265_encoder = {
     .p.wrapper_name   = "libx265",
     .init             = libx265_encode_init,
     .init_static_data = libx265_encode_init_csp,
-    .encode2          = libx265_encode_frame,
+    FF_CODEC_ENCODE_CB(libx265_encode_frame),
     .close            = libx265_encode_close,
     .priv_data_size   = sizeof(libx265Context),
     .defaults         = x265_defaults,
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index 609487202d..a3efbcb4a1 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -430,7 +430,7 @@ const FFCodec ff_libxavs_encoder = {
                       AV_CODEC_CAP_OTHER_THREADS,
     .priv_data_size = sizeof(XavsContext),
     .init           = XAVS_init,
-    .encode2        = XAVS_frame,
+    FF_CODEC_ENCODE_CB(XAVS_frame),
     .close          = XAVS_close,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
diff --git a/libavcodec/libxavs2.c b/libavcodec/libxavs2.c
index f189aaeed2..f77078e3fb 100644
--- a/libavcodec/libxavs2.c
+++ b/libavcodec/libxavs2.c
@@ -295,7 +295,7 @@ const FFCodec ff_libxavs2_encoder = {
                       AV_CODEC_CAP_OTHER_THREADS,
     .priv_data_size = sizeof(XAVS2EContext),
     .init           = xavs2_init,
-    .encode2        = xavs2_encode_frame,
+    FF_CODEC_ENCODE_CB(xavs2_encode_frame),
     .close          = xavs2_close,
     .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index ece7aaaebd..4b3dd71bc5 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -904,7 +904,7 @@ const FFCodec ff_libxvid_encoder = {
     .p.id           = AV_CODEC_ID_MPEG4,
     .priv_data_size = sizeof(struct xvid_context),
     .init           = xvid_encode_init,
-    .encode2        = xvid_encode_frame,
+    FF_CODEC_ENCODE_CB(xvid_encode_frame),
     .close          = xvid_encode_close,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .p.priv_class   = &xvid_class,
diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 4920c61e0f..79a1237431 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -822,6 +822,6 @@ const FFCodec ff_libzvbi_teletext_decoder = {
     .priv_data_size = sizeof(TeletextContext),
     .init      = teletext_init_decoder,
     .close     = teletext_close_decoder,
-    .decode_sub = teletext_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(teletext_decode_frame),
     .flush     = teletext_flush,
 };
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index fad19cbb76..e0fc417d1f 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -329,7 +329,7 @@ const FFCodec ff_ljpeg_encoder = {
     .priv_data_size = sizeof(LJpegEncContext),
     .p.priv_class   = &ljpeg_class,
     .init           = ljpeg_encode_init,
-    .encode2        = ljpeg_encode_frame,
+    FF_CODEC_ENCODE_CB(ljpeg_encode_frame),
     .close          = ljpeg_encode_close,
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]){
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index c21214a626..9cadc9d006 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -343,7 +343,7 @@ const FFCodec ff_loco_decoder = {
     .p.id           = AV_CODEC_ID_LOCO,
     .priv_data_size = sizeof(LOCOContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/lscrdec.c b/libavcodec/lscrdec.c
index dc2c7a51c2..9e7010c288 100644
--- a/libavcodec/lscrdec.c
+++ b/libavcodec/lscrdec.c
@@ -253,7 +253,7 @@ const FFCodec ff_lscr_decoder = {
     .priv_data_size = sizeof(LSCRContext),
     .init           = lscr_decode_init,
     .close          = lscr_decode_close,
-    .decode         = decode_frame_lscr,
+    FF_CODEC_DECODE_CB(decode_frame_lscr),
     .flush          = lscr_decode_flush,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/m101.c b/libavcodec/m101.c
index a635b153f7..fce31956c7 100644
--- a/libavcodec/m101.c
+++ b/libavcodec/m101.c
@@ -111,7 +111,7 @@ const FFCodec ff_m101_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_M101,
     .init           = m101_decode_init,
-    .decode         = m101_decode_frame,
+    FF_CODEC_DECODE_CB(m101_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index b32890c578..35af4a6aae 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -292,7 +292,7 @@ const FFCodec ff_mace3_decoder = {
     .p.id           = AV_CODEC_ID_MACE3,
     .priv_data_size = sizeof(MACEContext),
     .init           = mace_decode_init,
-    .decode         = mace_decode_frame,
+    FF_CODEC_DECODE_CB(mace_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
@@ -306,7 +306,7 @@ const FFCodec ff_mace6_decoder = {
     .p.id           = AV_CODEC_ID_MACE6,
     .priv_data_size = sizeof(MACEContext),
     .init           = mace_decode_init,
-    .decode         = mace_decode_frame,
+    FF_CODEC_DECODE_CB(mace_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c
index b99905f4ad..634d45ca48 100644
--- a/libavcodec/magicyuv.c
+++ b/libavcodec/magicyuv.c
@@ -701,7 +701,7 @@ const FFCodec ff_magicyuv_decoder = {
     .priv_data_size   = sizeof(MagicYUVContext),
     .init             = magy_decode_init,
     .close            = magy_decode_end,
-    .decode           = magy_decode_frame,
+    FF_CODEC_DECODE_CB(magy_decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 |
                         AV_CODEC_CAP_FRAME_THREADS |
                         AV_CODEC_CAP_SLICE_THREADS,
diff --git a/libavcodec/magicyuvenc.c b/libavcodec/magicyuvenc.c
index b365739443..ce492368ef 100644
--- a/libavcodec/magicyuvenc.c
+++ b/libavcodec/magicyuvenc.c
@@ -572,7 +572,7 @@ const FFCodec ff_magicyuv_encoder = {
     .p.priv_class     = &magicyuv_class,
     .init             = magy_encode_init,
     .close            = magy_encode_close,
-    .encode2          = magy_encode_frame,
+    FF_CODEC_ENCODE_CB(magy_encode_frame),
     .p.capabilities   = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts       = (const enum AVPixelFormat[]) {
                           AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_YUV422P,
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 24c0fc1adc..deabebda62 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -257,7 +257,7 @@ const FFCodec ff_mdec_decoder = {
     .priv_data_size   = sizeof(MDECContext),
     .init             = decode_init,
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index c8c9f1df08..6b4c39b4e0 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -540,7 +540,7 @@ const FFCodec ff_ ## short_name ## _mediacodec_decoder = {
     .p.priv_class   = &ff_##short_name##_mediacodec_dec_class,                                 \
     .priv_data_size = sizeof(MediaCodecH264DecContext),                                        \
     .init           = mediacodec_decode_init,                                                  \
-    .receive_frame  = mediacodec_receive_frame,                                                \
+    FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame),                                       \
     .flush          = mediacodec_decode_flush,                                                 \
     .close          = mediacodec_decode_close,                                                 \
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c
index 3897d42911..9c5d0369c4 100644
--- a/libavcodec/metasound.c
+++ b/libavcodec/metasound.c
@@ -381,7 +381,7 @@ const FFCodec ff_metasound_decoder = {
     .priv_data_size = sizeof(TwinVQContext),
     .init           = metasound_decode_init,
     .close          = ff_twinvq_decode_close,
-    .decode         = ff_twinvq_decode_frame,
+    FF_CODEC_DECODE_CB(ff_twinvq_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c
index f30068985e..280941cf2e 100644
--- a/libavcodec/mfenc.c
+++ b/libavcodec/mfenc.c
@@ -1160,7 +1160,7 @@ static int mf_close(AVCodecContext *avctx)
         .priv_data_size = sizeof(MFContext),                                   \
         .init           = mf_init,                                             \
         .close          = mf_close,                                            \
-        .receive_packet = mf_receive_packet,                                   \
+        FF_CODEC_RECEIVE_PACKET_CB(mf_receive_packet),                         \
         EXTRA                                                                  \
         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID |           \
                           AV_CODEC_CAP_DR1,                                    \
diff --git a/libavcodec/microdvddec.c b/libavcodec/microdvddec.c
index 1cd5d1d5f5..154fd3271b 100644
--- a/libavcodec/microdvddec.c
+++ b/libavcodec/microdvddec.c
@@ -374,7 +374,7 @@ const FFCodec ff_microdvd_decoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_MICRODVD,
     .init         = microdvd_init,
-    .decode_sub   = microdvd_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(microdvd_decode_frame),
     .flush        = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/midivid.c b/libavcodec/midivid.c
index 55fca27085..a21303ab60 100644
--- a/libavcodec/midivid.c
+++ b/libavcodec/midivid.c
@@ -285,7 +285,7 @@ const FFCodec ff_mvdv_decoder = {
     .p.id           = AV_CODEC_ID_MVDV,
     .priv_data_size = sizeof(MidiVidContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 05c193989b..74dd947f88 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -445,7 +445,7 @@ const FFCodec ff_mimic_decoder = {
     .priv_data_size        = sizeof(MimicContext),
     .init                  = mimic_decode_init,
     .close                 = mimic_decode_end,
-    .decode                = mimic_decode_frame,
+    FF_CODEC_DECODE_CB(mimic_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
     .caps_internal         = FF_CODEC_CAP_ALLOCATE_PROGRESS |
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index b04d61c0e0..8c1809e5fb 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -164,7 +164,7 @@ const FFCodec ff_mjpegb_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .decode         = mjpegb_decode_frame,
+    FF_CODEC_DECODE_CB(mjpegb_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.max_lowres   = 3,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 13b56e0b2f..32874a5a19 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -3020,7 +3020,7 @@ const FFCodec ff_mjpeg_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .receive_frame  = ff_mjpeg_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
     .flush          = decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.max_lowres   = 3,
@@ -3048,7 +3048,7 @@ const FFCodec ff_thp_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .receive_frame  = ff_mjpeg_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
     .flush          = decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.max_lowres   = 3,
@@ -3066,7 +3066,7 @@ const FFCodec ff_smvjpeg_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .receive_frame  = ff_mjpeg_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
     .flush          = decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index a39b990eea..31d794965f 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -658,7 +658,7 @@ const FFCodec ff_mjpeg_encoder = {
     .p.id           = AV_CODEC_ID_MJPEG,
     .priv_data_size = sizeof(MJPEGEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = mjpeg_encode_close,
     .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
@@ -687,7 +687,7 @@ const FFCodec ff_amv_encoder = {
     .p.id           = AV_CODEC_ID_AMV,
     .priv_data_size = sizeof(MJPEGEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = amv_encode_picture,
+    FF_CODEC_ENCODE_CB(amv_encode_picture),
     .close          = mjpeg_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index a3c1850d33..c5d8f5bde8 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -1424,7 +1424,7 @@ const FFCodec ff_mlp_decoder = {
     .priv_data_size = sizeof(MLPDecodeContext),
     .p.priv_class   = &mlp_decoder_class,
     .init           = mlp_decode_init,
-    .decode         = read_access_unit,
+    FF_CODEC_DECODE_CB(read_access_unit),
     .flush          = mlp_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -1439,7 +1439,7 @@ const FFCodec ff_truehd_decoder = {
     .priv_data_size = sizeof(MLPDecodeContext),
     .p.priv_class   = &truehd_decoder_class,
     .init           = mlp_decode_init,
-    .decode         = read_access_unit,
+    FF_CODEC_DECODE_CB(read_access_unit),
     .flush          = mlp_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index bcb479f2a6..da36818169 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -2213,7 +2213,7 @@ const FFCodec ff_mlp_encoder = {
     .p.id                   = AV_CODEC_ID_MLP,
     .priv_data_size         = sizeof(MLPEncodeContext),
     .init                   = mlp_encode_init,
-    .encode2                = mlp_encode_frame,
+    FF_CODEC_ENCODE_CB(mlp_encode_frame),
     .close                  = mlp_encode_close,
     .p.capabilities         = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
     .p.sample_fmts          = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE},
@@ -2233,7 +2233,7 @@ const FFCodec ff_truehd_encoder = {
     .p.id                   = AV_CODEC_ID_TRUEHD,
     .priv_data_size         = sizeof(MLPEncodeContext),
     .init                   = mlp_encode_init,
-    .encode2                = mlp_encode_frame,
+    FF_CODEC_ENCODE_CB(mlp_encode_frame),
     .close                  = mlp_encode_close,
     .p.capabilities         = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
     .p.sample_fmts          = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE},
diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
index 2a56bcae01..7fd24ad3b7 100644
--- a/libavcodec/mmaldec.c
+++ b/libavcodec/mmaldec.c
@@ -837,7 +837,7 @@ static const AVClass ffmmal_dec_class = {
         .priv_data_size = sizeof(MMALDecodeContext), \
         .init           = ffmmal_init_decoder, \
         .close          = ffmmal_close_decoder, \
-        .receive_frame  = ffmmal_receive_frame, \
+        FF_CODEC_RECEIVE_FRAME_CB(ffmmal_receive_frame), \
         .flush          = ffmmal_flush, \
         .p.priv_class   = &ffmmal_dec_class, \
         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index 54ed5fad14..fc80ec4764 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -246,7 +246,7 @@ const FFCodec ff_mmvideo_decoder = {
     .priv_data_size = sizeof(MmContext),
     .init           = mm_decode_init,
     .close          = mm_decode_end,
-    .decode         = mm_decode_frame,
+    FF_CODEC_DECODE_CB(mm_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mobiclip.c b/libavcodec/mobiclip.c
index 0b7230f326..2d09bc1f72 100644
--- a/libavcodec/mobiclip.c
+++ b/libavcodec/mobiclip.c
@@ -1347,7 +1347,7 @@ const FFCodec ff_mobiclip_decoder = {
     .p.id           = AV_CODEC_ID_MOBICLIP,
     .priv_data_size = sizeof(MobiClipContext),
     .init           = mobiclip_init,
-    .decode         = mobiclip_decode,
+    FF_CODEC_DECODE_CB(mobiclip_decode),
     .flush          = mobiclip_flush,
     .close          = mobiclip_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index aeea4e6865..29454fd242 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -353,7 +353,7 @@ const FFCodec ff_motionpixels_decoder = {
     .priv_data_size = sizeof(MotionPixelsContext),
     .init           = mp_decode_init,
     .close          = mp_decode_end,
-    .decode         = mp_decode_frame,
+    FF_CODEC_DECODE_CB(mp_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
index c3e0a75e57..6a71537291 100644
--- a/libavcodec/movtextdec.c
+++ b/libavcodec/movtextdec.c
@@ -599,7 +599,7 @@ const FFCodec ff_movtext_decoder = {
     .priv_data_size = sizeof(MovTextContext),
     .p.priv_class = &mov_text_decoder_class,
     .init         = mov_text_init,
-    .decode_sub   = mov_text_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(mov_text_decode_frame),
     .close        = mov_text_decode_close,
     .flush        = mov_text_flush,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
index 333a23be82..728338f2cc 100644
--- a/libavcodec/movtextenc.c
+++ b/libavcodec/movtextenc.c
@@ -707,7 +707,7 @@ const FFCodec ff_movtext_encoder = {
     .priv_data_size = sizeof(MovTextContext),
     .p.priv_class   = &mov_text_encoder_class,
     .init           = mov_text_encode_init,
-    .encode_sub     = mov_text_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(mov_text_encode_frame),
     .close          = mov_text_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index 5d8280ee2e..1b722714f0 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -317,7 +317,7 @@ const FFCodec ff_mpc7_decoder = {
     .priv_data_size = sizeof(MPCContext),
     .init           = mpc7_decode_init,
     .close          = mpc7_decode_close,
-    .decode         = mpc7_decode_frame,
+    FF_CODEC_DECODE_CB(mpc7_decode_frame),
     .flush          = mpc7_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index e876de4813..7903e5df8a 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -390,7 +390,7 @@ const FFCodec ff_mpc8_decoder = {
     .p.id           = AV_CODEC_ID_MUSEPACK8,
     .priv_data_size = sizeof(MPCContext),
     .init           = mpc8_decode_init,
-    .decode         = mpc8_decode_frame,
+    FF_CODEC_DECODE_CB(mpc8_decode_frame),
     .flush          = mpc8_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 599ee8dcb1..e9bde48f7a 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -2870,7 +2870,7 @@ const FFCodec ff_mpeg1video_decoder = {
     .priv_data_size        = sizeof(Mpeg1Context),
     .init                  = mpeg_decode_init,
     .close                 = mpeg_decode_end,
-    .decode                = mpeg_decode_frame,
+    FF_CODEC_DECODE_CB(mpeg_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
 #if FF_API_FLAG_TRUNCATED
                              AV_CODEC_CAP_TRUNCATED |
@@ -2903,7 +2903,7 @@ const FFCodec ff_mpeg2video_decoder = {
     .priv_data_size = sizeof(Mpeg1Context),
     .init           = mpeg_decode_init,
     .close          = mpeg_decode_end,
-    .decode         = mpeg_decode_frame,
+    FF_CODEC_DECODE_CB(mpeg_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
 #if FF_API_FLAG_TRUNCATED
                       AV_CODEC_CAP_TRUNCATED |
@@ -2949,7 +2949,7 @@ const FFCodec ff_mpegvideo_decoder = {
     .priv_data_size = sizeof(Mpeg1Context),
     .init           = mpeg_decode_init,
     .close          = mpeg_decode_end,
-    .decode         = mpeg_decode_frame,
+    FF_CODEC_DECODE_CB(mpeg_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
 #if FF_API_FLAG_TRUNCATED
                       AV_CODEC_CAP_TRUNCATED |
@@ -3113,7 +3113,7 @@ const FFCodec ff_ipu_decoder = {
     .p.id           = AV_CODEC_ID_IPU,
     .priv_data_size = sizeof(IPUContext),
     .init           = ipu_decode_init,
-    .decode         = ipu_decode_frame,
+    FF_CODEC_DECODE_CB(ipu_decode_frame),
     .close          = ipu_decode_end,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 77cbb60ea1..5ba2828e2f 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1232,7 +1232,7 @@ const FFCodec ff_mpeg1video_encoder = {
     .p.id                 = AV_CODEC_ID_MPEG1VIDEO,
     .priv_data_size       = sizeof(MPEG12EncContext),
     .init                 = encode_init,
-    .encode2              = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close                = ff_mpv_encode_end,
     .p.supported_framerates = ff_mpeg12_frame_rate_tab + 1,
     .p.pix_fmts           = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
@@ -1249,7 +1249,7 @@ const FFCodec ff_mpeg2video_encoder = {
     .p.id                 = AV_CODEC_ID_MPEG2VIDEO,
     .priv_data_size       = sizeof(MPEG12EncContext),
     .init                 = encode_init,
-    .encode2              = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close                = ff_mpv_encode_end,
     .p.supported_framerates = ff_mpeg2_frame_rate_tab,
     .p.pix_fmts           = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 5c55de3eb8..e2bde73639 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3670,7 +3670,7 @@ const FFCodec ff_mpeg4_decoder = {
     .priv_data_size        = sizeof(Mpeg4DecContext),
     .init                  = decode_init,
     .close                 = ff_h263_decode_end,
-    .decode                = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
 #if FF_API_FLAG_TRUNCATED
                              AV_CODEC_CAP_TRUNCATED |
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 1140c33a70..89e7ce1260 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1401,7 +1401,7 @@ const FFCodec ff_mpeg4_encoder = {
     .p.id           = AV_CODEC_ID_MPEG4,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
diff --git a/libavcodec/mpegaudiodec_fixed.c b/libavcodec/mpegaudiodec_fixed.c
index 8809fac976..8a5721d383 100644
--- a/libavcodec/mpegaudiodec_fixed.c
+++ b/libavcodec/mpegaudiodec_fixed.c
@@ -68,7 +68,7 @@ const FFCodec ff_mp1_decoder = {
     .p.id           = AV_CODEC_ID_MP1,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -86,7 +86,7 @@ const FFCodec ff_mp2_decoder = {
     .p.id           = AV_CODEC_ID_MP2,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -104,7 +104,7 @@ const FFCodec ff_mp3_decoder = {
     .p.id           = AV_CODEC_ID_MP3,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -122,7 +122,7 @@ const FFCodec ff_mp3adu_decoder = {
     .p.id           = AV_CODEC_ID_MP3ADU,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame_adu,
+    FF_CODEC_DECODE_CB(decode_frame_adu),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -141,7 +141,7 @@ const FFCodec ff_mp3on4_decoder = {
     .priv_data_size = sizeof(MP3On4DecodeContext),
     .init           = decode_init_mp3on4,
     .close          = decode_close_mp3on4,
-    .decode         = decode_frame_mp3on4,
+    FF_CODEC_DECODE_CB(decode_frame_mp3on4),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush_mp3on4,
diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c
index c4fd64a85f..bcd55069a0 100644
--- a/libavcodec/mpegaudiodec_float.c
+++ b/libavcodec/mpegaudiodec_float.c
@@ -81,7 +81,7 @@ const FFCodec ff_mp1float_decoder = {
     .p.id           = AV_CODEC_ID_MP1,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -99,7 +99,7 @@ const FFCodec ff_mp2float_decoder = {
     .p.id           = AV_CODEC_ID_MP2,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -117,7 +117,7 @@ const FFCodec ff_mp3float_decoder = {
     .p.id           = AV_CODEC_ID_MP3,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -135,7 +135,7 @@ const FFCodec ff_mp3adufloat_decoder = {
     .p.id           = AV_CODEC_ID_MP3ADU,
     .priv_data_size = sizeof(MPADecodeContext),
     .init           = decode_init,
-    .decode         = decode_frame_adu,
+    FF_CODEC_DECODE_CB(decode_frame_adu),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush,
@@ -154,7 +154,7 @@ const FFCodec ff_mp3on4float_decoder = {
     .priv_data_size = sizeof(MP3On4DecodeContext),
     .init           = decode_init_mp3on4,
     .close          = decode_close_mp3on4,
-    .decode         = decode_frame_mp3on4,
+    FF_CODEC_DECODE_CB(decode_frame_mp3on4),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .flush          = flush_mp3on4,
diff --git a/libavcodec/mpegaudioenc_fixed.c b/libavcodec/mpegaudioenc_fixed.c
index 2eaa933195..74cb4b8d57 100644
--- a/libavcodec/mpegaudioenc_fixed.c
+++ b/libavcodec/mpegaudioenc_fixed.c
@@ -30,7 +30,7 @@ const FFCodec ff_mp2fixed_encoder = {
     .p.id                  = AV_CODEC_ID_MP2,
     .priv_data_size        = sizeof(MpegAudioContext),
     .init                  = MPA_encode_init,
-    .encode2               = MPA_encode_frame,
+    FF_CODEC_ENCODE_CB(MPA_encode_frame),
     .p.sample_fmts         = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                             AV_SAMPLE_FMT_NONE },
     .p.supported_samplerates = (const int[]){
diff --git a/libavcodec/mpegaudioenc_float.c b/libavcodec/mpegaudioenc_float.c
index 9b9c7a442a..0a597b7e07 100644
--- a/libavcodec/mpegaudioenc_float.c
+++ b/libavcodec/mpegaudioenc_float.c
@@ -31,7 +31,7 @@ const FFCodec ff_mp2_encoder = {
     .p.id                  = AV_CODEC_ID_MP2,
     .priv_data_size        = sizeof(MpegAudioContext),
     .init                  = MPA_encode_init,
-    .encode2               = MPA_encode_frame,
+    FF_CODEC_ENCODE_CB(MPA_encode_frame),
     .p.sample_fmts         = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                             AV_SAMPLE_FMT_NONE },
     .p.supported_samplerates = (const int[]){
diff --git a/libavcodec/mpl2dec.c b/libavcodec/mpl2dec.c
index 490a3e6d45..7104670f4d 100644
--- a/libavcodec/mpl2dec.c
+++ b/libavcodec/mpl2dec.c
@@ -86,7 +86,7 @@ const FFCodec ff_mpl2_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("MPL2 subtitle"),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_MPL2,
-    .decode_sub     = mpl2_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(mpl2_decode_frame),
     .init           = ff_ass_subtitle_header_default,
     .flush          = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
diff --git a/libavcodec/mscc.c b/libavcodec/mscc.c
index e7f6015554..ac67ec9c47 100644
--- a/libavcodec/mscc.c
+++ b/libavcodec/mscc.c
@@ -252,7 +252,7 @@ const FFCodec ff_mscc_decoder = {
     .priv_data_size   = sizeof(MSCCContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
@@ -265,7 +265,7 @@ const FFCodec ff_srgc_decoder = {
     .priv_data_size   = sizeof(MSCCContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
index f0cb11eceb..a03e43f88c 100644
--- a/libavcodec/msmpeg4dec.c
+++ b/libavcodec/msmpeg4dec.c
@@ -872,7 +872,7 @@ const FFCodec ff_msmpeg4v1_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_msmpeg4_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
@@ -891,7 +891,7 @@ const FFCodec ff_msmpeg4v2_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_msmpeg4_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
@@ -910,7 +910,7 @@ const FFCodec ff_msmpeg4v3_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_msmpeg4_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
@@ -929,7 +929,7 @@ const FFCodec ff_wmv1_decoder = {
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_msmpeg4_decode_init,
     .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index dd75cd5746..e597dbbb4e 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -686,7 +686,7 @@ const FFCodec ff_msmpeg4v2_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MSMPEG4EncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
 
@@ -700,7 +700,7 @@ const FFCodec ff_msmpeg4v3_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MSMPEG4EncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
 
@@ -714,6 +714,6 @@ const FFCodec ff_wmv1_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MSMPEG4EncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
 };
diff --git a/libavcodec/msp2dec.c b/libavcodec/msp2dec.c
index 99dcf7e9f9..5374c4be81 100644
--- a/libavcodec/msp2dec.c
+++ b/libavcodec/msp2dec.c
@@ -98,5 +98,5 @@ const FFCodec ff_msp2_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MSP2,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = msp2_decode_frame,
+    FF_CODEC_DECODE_CB(msp2_decode_frame),
 };
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index 49fd3c86e2..041d0c9493 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -167,7 +167,7 @@ const FFCodec ff_msrle_decoder = {
     .priv_data_size = sizeof(MsrleContext),
     .init           = msrle_decode_init,
     .close          = msrle_decode_end,
-    .decode         = msrle_decode_frame,
+    FF_CODEC_DECODE_CB(msrle_decode_frame),
     .flush          = msrle_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
index 844a6bde9c..bc00a11abb 100644
--- a/libavcodec/mss1.c
+++ b/libavcodec/mss1.c
@@ -227,7 +227,7 @@ const FFCodec ff_mss1_decoder = {
     .priv_data_size = sizeof(MSS1Context),
     .init           = mss1_decode_init,
     .close          = mss1_decode_end,
-    .decode         = mss1_decode_frame,
+    FF_CODEC_DECODE_CB(mss1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index 235149b906..ab42d12217 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -854,7 +854,7 @@ const FFCodec ff_mss2_decoder = {
     .priv_data_size = sizeof(MSS2Context),
     .init           = mss2_decode_init,
     .close          = mss2_decode_end,
-    .decode         = mss2_decode_frame,
+    FF_CODEC_DECODE_CB(mss2_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index 3e12ea0399..55d2d10bd6 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -868,7 +868,7 @@ const FFCodec ff_msa1_decoder = {
     .priv_data_size = sizeof(MSS3Context),
     .init           = mss3_decode_init,
     .close          = mss3_decode_end,
-    .decode         = mss3_decode_frame,
+    FF_CODEC_DECODE_CB(mss3_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c
index c29d885077..be73e52a91 100644
--- a/libavcodec/mss4.c
+++ b/libavcodec/mss4.c
@@ -613,7 +613,7 @@ const FFCodec ff_mts2_decoder = {
     .priv_data_size = sizeof(MSS4Context),
     .init           = mss4_decode_init,
     .close          = mss4_decode_end,
-    .decode         = mss4_decode_frame,
+    FF_CODEC_DECODE_CB(mss4_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index fa08e2cdfd..a39f684b52 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -349,7 +349,7 @@ const FFCodec ff_msvideo1_decoder = {
     .priv_data_size = sizeof(Msvideo1Context),
     .init           = msvideo1_decode_init,
     .close          = msvideo1_decode_end,
-    .decode         = msvideo1_decode_frame,
+    FF_CODEC_DECODE_CB(msvideo1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c
index 917b7ea907..53f4a4b365 100644
--- a/libavcodec/msvideo1enc.c
+++ b/libavcodec/msvideo1enc.c
@@ -309,7 +309,7 @@ const FFCodec ff_msvideo1_encoder = {
     .p.id           = AV_CODEC_ID_MSVIDEO1,
     .priv_data_size = sizeof(Msvideo1EncContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_RGB555, AV_PIX_FMT_NONE},
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/mv30.c b/libavcodec/mv30.c
index 75ed23d493..a32fab2b92 100644
--- a/libavcodec/mv30.c
+++ b/libavcodec/mv30.c
@@ -710,7 +710,7 @@ const FFCodec ff_mv30_decoder = {
     .priv_data_size   = sizeof(MV30Context),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush            = decode_flush,
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/mvcdec.c b/libavcodec/mvcdec.c
index 2bef903bfa..4ee8d10ca9 100644
--- a/libavcodec/mvcdec.c
+++ b/libavcodec/mvcdec.c
@@ -262,7 +262,7 @@ const FFCodec ff_mvc1_decoder = {
     .p.id           = AV_CODEC_ID_MVC1,
     .priv_data_size = sizeof(MvcContext),
     .init           = mvc_decode_init,
-    .decode         = mvc_decode_frame,
+    FF_CODEC_DECODE_CB(mvc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -276,7 +276,7 @@ const FFCodec ff_mvc2_decoder = {
     .p.id           = AV_CODEC_ID_MVC2,
     .priv_data_size = sizeof(MvcContext),
     .init           = mvc_decode_init,
-    .decode         = mvc_decode_frame,
+    FF_CODEC_DECODE_CB(mvc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mvha.c b/libavcodec/mvha.c
index 7c312d8562..8a65c42583 100644
--- a/libavcodec/mvha.c
+++ b/libavcodec/mvha.c
@@ -306,7 +306,7 @@ const FFCodec ff_mvha_decoder = {
     .priv_data_size   = sizeof(MVHAContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/mwsc.c b/libavcodec/mwsc.c
index 82d149a295..d89fbde4e2 100644
--- a/libavcodec/mwsc.c
+++ b/libavcodec/mwsc.c
@@ -176,7 +176,7 @@ const FFCodec ff_mwsc_decoder = {
     .priv_data_size   = sizeof(MWSCContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 19a4bfcd8b..e5cdd44fd2 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -350,7 +350,7 @@ const FFCodec ff_mxpeg_decoder = {
     .priv_data_size = sizeof(MXpegDecodeContext),
     .init           = mxpeg_decode_init,
     .close          = mxpeg_decode_end,
-    .decode         = mxpeg_decode_frame,
+    FF_CODEC_DECODE_CB(mxpeg_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.max_lowres   = 3,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index 1d51b989a5..63b60f202c 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -194,7 +194,7 @@ const FFCodec ff_nellymoser_decoder = {
     .priv_data_size = sizeof(NellyMoserDecodeContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_tag,
+    FF_CODEC_DECODE_CB(decode_tag),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c
index 35a30b9942..c11dfe504c 100644
--- a/libavcodec/nellymoserenc.c
+++ b/libavcodec/nellymoserenc.c
@@ -422,7 +422,7 @@ const FFCodec ff_nellymoser_encoder = {
                       AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(NellyMoserEncodeContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c
index 36967a6f63..f6d62b8a4b 100644
--- a/libavcodec/notchlc.c
+++ b/libavcodec/notchlc.c
@@ -543,7 +543,7 @@ const FFCodec ff_notchlc_decoder = {
     .priv_data_size   = sizeof(NotchLCContext),
     .init             = decode_init,
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index 2fdb023751..71420a62f6 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -370,7 +370,7 @@ const FFCodec ff_nuv_decoder = {
     .priv_data_size = sizeof(NuvContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index 101f8ddb4c..1860c60a29 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -225,7 +225,7 @@ const FFCodec ff_h264_nvenc_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_H264,
     .init           = ff_nvenc_encode_init,
-    .receive_packet = ff_nvenc_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(ff_nvenc_receive_packet),
     .close          = ff_nvenc_encode_close,
     .flush          = ff_nvenc_encode_flush,
     .priv_data_size = sizeof(NvencContext),
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index 6443e3e145..2c64cce598 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -206,7 +206,7 @@ const FFCodec ff_hevc_nvenc_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_HEVC,
     .init           = ff_nvenc_encode_init,
-    .receive_packet = ff_nvenc_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(ff_nvenc_receive_packet),
     .close          = ff_nvenc_encode_close,
     .flush          = ff_nvenc_encode_flush,
     .priv_data_size = sizeof(NvencContext),
diff --git a/libavcodec/omx.c b/libavcodec/omx.c
index 4bf3b4ffdd..d481c0678b 100644
--- a/libavcodec/omx.c
+++ b/libavcodec/omx.c
@@ -943,7 +943,7 @@ const FFCodec ff_mpeg4_omx_encoder = {
     .p.id             = AV_CODEC_ID_MPEG4,
     .priv_data_size   = sizeof(OMXCodecContext),
     .init             = omx_encode_init,
-    .encode2          = omx_encode_frame,
+    FF_CODEC_ENCODE_CB(omx_encode_frame),
     .close            = omx_encode_end,
     .p.pix_fmts       = omx_encoder_pix_fmts,
     .p.capabilities   = AV_CODEC_CAP_DELAY,
@@ -964,7 +964,7 @@ const FFCodec ff_h264_omx_encoder = {
     .p.id             = AV_CODEC_ID_H264,
     .priv_data_size   = sizeof(OMXCodecContext),
     .init             = omx_encode_init,
-    .encode2          = omx_encode_frame,
+    FF_CODEC_ENCODE_CB(omx_encode_frame),
     .close            = omx_encode_end,
     .p.pix_fmts       = omx_encoder_pix_fmts,
     .p.capabilities   = AV_CODEC_CAP_DELAY,
diff --git a/libavcodec/on2avc.c b/libavcodec/on2avc.c
index 9ba4d764a0..5477f6f87b 100644
--- a/libavcodec/on2avc.c
+++ b/libavcodec/on2avc.c
@@ -1011,7 +1011,7 @@ const FFCodec ff_on2avc_decoder = {
     .p.id           = AV_CODEC_ID_ON2AVC,
     .priv_data_size = sizeof(On2AVCContext),
     .init           = on2avc_decode_init,
-    .decode         = on2avc_decode_frame,
+    FF_CODEC_DECODE_CB(on2avc_decode_frame),
     .close          = on2avc_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c
index ff7dd6c631..8ca99369c6 100644
--- a/libavcodec/opusdec.c
+++ b/libavcodec/opusdec.c
@@ -713,7 +713,7 @@ const FFCodec ff_opus_decoder = {
     .priv_data_size  = sizeof(OpusContext),
     .init            = opus_decode_init,
     .close           = opus_decode_close,
-    .decode          = opus_decode_packet,
+    FF_CODEC_DECODE_CB(opus_decode_packet),
     .flush           = opus_decode_flush,
     .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c
index 44aa9cbd44..b4b7c472a0 100644
--- a/libavcodec/opusenc.c
+++ b/libavcodec/opusenc.c
@@ -734,7 +734,7 @@ const FFCodec ff_opus_encoder = {
     .p.priv_class   = &opusenc_class,
     .priv_data_size = sizeof(OpusEncContext),
     .init           = opus_encode_init,
-    .encode2        = opus_encode_frame,
+    FF_CODEC_ENCODE_CB(opus_encode_frame),
     .close          = opus_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.capabilities = AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
diff --git a/libavcodec/pafaudio.c b/libavcodec/pafaudio.c
index 6e8da3d3c4..9f694d2dc8 100644
--- a/libavcodec/pafaudio.c
+++ b/libavcodec/pafaudio.c
@@ -79,7 +79,7 @@ const FFCodec ff_paf_audio_decoder = {
     .p.type       = AVMEDIA_TYPE_AUDIO,
     .p.id         = AV_CODEC_ID_PAF_AUDIO,
     .init         = paf_audio_init,
-    .decode       = paf_audio_decode,
+    FF_CODEC_DECODE_CB(paf_audio_decode),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/pafvideo.c b/libavcodec/pafvideo.c
index 3199e7f44c..a0bd22e8fd 100644
--- a/libavcodec/pafvideo.c
+++ b/libavcodec/pafvideo.c
@@ -416,7 +416,7 @@ const FFCodec ff_paf_video_decoder = {
     .priv_data_size = sizeof(PAFVideoDecContext),
     .init           = paf_video_init,
     .close          = paf_video_close,
-    .decode         = paf_video_decode,
+    FF_CODEC_DECODE_CB(paf_video_decode),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index 8ded835d25..8a94f8a537 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -133,7 +133,7 @@ const FFCodec ff_pam_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PAM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = pam_encode_frame,
+    FF_CODEC_ENCODE_CB(pam_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
         AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE,
diff --git a/libavcodec/pcm-bluray.c b/libavcodec/pcm-bluray.c
index fb9d06a36f..54338e679f 100644
--- a/libavcodec/pcm-bluray.c
+++ b/libavcodec/pcm-bluray.c
@@ -304,7 +304,7 @@ const FFCodec ff_pcm_bluray_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_PCM_BLURAY,
-    .decode         = pcm_bluray_decode_frame,
+    FF_CODEC_DECODE_CB(pcm_bluray_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]){
         AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE
diff --git a/libavcodec/pcm-blurayenc.c b/libavcodec/pcm-blurayenc.c
index 37b4709df8..99886e8c37 100644
--- a/libavcodec/pcm-blurayenc.c
+++ b/libavcodec/pcm-blurayenc.c
@@ -277,7 +277,7 @@ const FFCodec ff_pcm_bluray_encoder = {
     .p.id                  = AV_CODEC_ID_PCM_BLURAY,
     .priv_data_size        = sizeof(BlurayPCMEncContext),
     .init                  = pcm_bluray_encode_init,
-    .encode2               = pcm_bluray_encode_frame,
+    FF_CODEC_ENCODE_CB(pcm_bluray_encode_frame),
     .p.supported_samplerates = (const int[]) { 48000, 96000, 192000, 0 },
 #if FF_API_OLD_CHANNEL_LAYOUT
     .p.channel_layouts = (const uint64_t[]) {
diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c
index f7a5ba6600..57d0ff81d0 100644
--- a/libavcodec/pcm-dvd.c
+++ b/libavcodec/pcm-dvd.c
@@ -302,7 +302,7 @@ const FFCodec ff_pcm_dvd_decoder = {
     .p.id           = AV_CODEC_ID_PCM_DVD,
     .priv_data_size = sizeof(PCMDVDContext),
     .init           = pcm_dvd_decode_init,
-    .decode         = pcm_dvd_decode_frame,
+    FF_CODEC_DECODE_CB(pcm_dvd_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
     .p.sample_fmts  = (const enum AVSampleFormat[]) {
diff --git a/libavcodec/pcm-dvdenc.c b/libavcodec/pcm-dvdenc.c
index d0c328beb0..f18855cfa7 100644
--- a/libavcodec/pcm-dvdenc.c
+++ b/libavcodec/pcm-dvdenc.c
@@ -180,7 +180,7 @@ const FFCodec ff_pcm_dvd_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(PCMDVDContext),
     .init           = pcm_dvd_encode_init,
-    .encode2        = pcm_dvd_encode_frame,
+    FF_CODEC_ENCODE_CB(pcm_dvd_encode_frame),
     .p.supported_samplerates = (const int[]) { 48000, 96000, 0},
 #if FF_API_OLD_CHANNEL_LAYOUT
     .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index dfb10095c2..471075ad71 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -561,7 +561,7 @@ const FFCodec ff_ ## name_ ## _encoder = {                                  \
     .p.id         = AV_CODEC_ID_ ## id_,                                    \
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,    \
     .init         = pcm_encode_init,                                        \
-    .encode2      = pcm_encode_frame,                                       \
+    FF_CODEC_ENCODE_CB(pcm_encode_frame),                                   \
     .p.sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_,             \
                                                    AV_SAMPLE_FMT_NONE },    \
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,                          \
@@ -583,7 +583,7 @@ const FFCodec ff_ ## name_ ## _decoder = {                                  \
     .p.id           = AV_CODEC_ID_ ## id_,                                  \
     .priv_data_size = sizeof(PCMDecode),                                    \
     .init           = pcm_decode_init,                                      \
-    .decode         = pcm_decode_frame,                                     \
+    FF_CODEC_DECODE_CB(pcm_decode_frame),                                    \
     .p.capabilities = AV_CODEC_CAP_DR1,                                     \
     .p.sample_fmts  = (const enum AVSampleFormat[]){ sample_fmt_,           \
                                                      AV_SAMPLE_FMT_NONE },  \
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 2831f1bc3b..b21bdce5ce 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -254,6 +254,6 @@ const FFCodec ff_pcx_decoder = {
     .p.long_name  = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_PCX,
-    .decode       = pcx_decode_frame,
+    FF_CODEC_DECODE_CB(pcx_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
 };
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index 1ccd7db92f..e6eb387f0d 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -197,7 +197,7 @@ const FFCodec ff_pcx_encoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PCX,
-    .encode2        = pcx_encode_frame,
+    FF_CODEC_ENCODE_CB(pcx_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24,
         AV_PIX_FMT_RGB8, AV_PIX_FMT_BGR8, AV_PIX_FMT_RGB4_BYTE, AV_PIX_FMT_BGR4_BYTE,
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 8b5eb5f816..8441b88d27 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -698,7 +698,7 @@ const FFCodec ff_pgssub_decoder = {
     .priv_data_size = sizeof(PGSSubContext),
     .init           = init_decoder,
     .close          = close_decoder,
-    .decode_sub     = decode,
+    FF_CODEC_DECODE_SUB_CB(decode),
     .p.priv_class   = &pgsdec_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/pgxdec.c b/libavcodec/pgxdec.c
index 01cd484da2..899e7a9994 100644
--- a/libavcodec/pgxdec.c
+++ b/libavcodec/pgxdec.c
@@ -164,5 +164,5 @@ const FFCodec ff_pgx_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PGX,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = pgx_decode_frame,
+    FF_CODEC_DECODE_CB(pgx_decode_frame),
 };
diff --git a/libavcodec/photocd.c b/libavcodec/photocd.c
index 48dc1b88c4..0f3001f2e1 100644
--- a/libavcodec/photocd.c
+++ b/libavcodec/photocd.c
@@ -464,7 +464,7 @@ const FFCodec ff_photocd_decoder = {
     .p.priv_class   = &photocd_class,
     .init           = photocd_decode_init,
     .close          = photocd_decode_close,
-    .decode         = photocd_decode_frame,
+    FF_CODEC_DECODE_CB(photocd_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .p.long_name    = NULL_IF_CONFIG_SMALL("Kodak Photo CD"),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index 3c32cbc4e6..ed0292c797 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -286,5 +286,5 @@ const FFCodec ff_pictor_decoder = {
     .p.id           = AV_CODEC_ID_PICTOR,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PicContext),
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c
index 12857919fe..18a6587257 100644
--- a/libavcodec/pixlet.c
+++ b/libavcodec/pixlet.c
@@ -699,7 +699,7 @@ const FFCodec ff_pixlet_decoder = {
     .p.id             = AV_CODEC_ID_PIXLET,
     .init             = pixlet_init,
     .close            = pixlet_close,
-    .decode           = pixlet_decode_frame,
+    FF_CODEC_DECODE_CB(pixlet_decode_frame),
     .priv_data_size   = sizeof(PixletContext),
     .p.capabilities   = AV_CODEC_CAP_DR1 |
                         AV_CODEC_CAP_FRAME_THREADS,
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 59302c898a..6b44af59f2 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -1723,7 +1723,7 @@ const FFCodec ff_apng_decoder = {
     .priv_data_size = sizeof(PNGDecContext),
     .init           = png_dec_init,
     .close          = png_dec_end,
-    .decode         = decode_frame_apng,
+    FF_CODEC_DECODE_CB(decode_frame_apng),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
@@ -1740,7 +1740,7 @@ const FFCodec ff_png_decoder = {
     .priv_data_size = sizeof(PNGDecContext),
     .init           = png_dec_init,
     .close          = png_dec_end,
-    .decode         = decode_frame_png,
+    FF_CODEC_DECODE_CB(decode_frame_png),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
     .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index f67f90cd14..aaa6453218 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -1119,7 +1119,7 @@ const FFCodec ff_png_encoder = {
     .priv_data_size = sizeof(PNGEncContext),
     .init           = png_enc_init,
     .close          = png_enc_close,
-    .encode2        = encode_png,
+    FF_CODEC_ENCODE_CB(encode_png),
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
@@ -1142,7 +1142,7 @@ const FFCodec ff_apng_encoder = {
     .priv_data_size = sizeof(PNGEncContext),
     .init           = png_enc_init,
     .close          = png_enc_close,
-    .encode2        = encode_apng,
+    FF_CODEC_ENCODE_CB(encode_apng),
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
         AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE,
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index a6f5d7c55d..f2d9b7e4b6 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -338,7 +338,7 @@ const FFCodec ff_pgm_decoder = {
     .p.id           = AV_CODEC_ID_PGM,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PNMContext),
-    .decode         = pnm_decode_frame,
+    FF_CODEC_DECODE_CB(pnm_decode_frame),
 };
 #endif
 
@@ -350,7 +350,7 @@ const FFCodec ff_pgmyuv_decoder = {
     .p.id           = AV_CODEC_ID_PGMYUV,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PNMContext),
-    .decode         = pnm_decode_frame,
+    FF_CODEC_DECODE_CB(pnm_decode_frame),
 };
 #endif
 
@@ -362,7 +362,7 @@ const FFCodec ff_ppm_decoder = {
     .p.id           = AV_CODEC_ID_PPM,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PNMContext),
-    .decode         = pnm_decode_frame,
+    FF_CODEC_DECODE_CB(pnm_decode_frame),
 };
 #endif
 
@@ -374,7 +374,7 @@ const FFCodec ff_pbm_decoder = {
     .p.id           = AV_CODEC_ID_PBM,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PNMContext),
-    .decode         = pnm_decode_frame,
+    FF_CODEC_DECODE_CB(pnm_decode_frame),
 };
 #endif
 
@@ -386,7 +386,7 @@ const FFCodec ff_pam_decoder = {
     .p.id           = AV_CODEC_ID_PAM,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PNMContext),
-    .decode         = pnm_decode_frame,
+    FF_CODEC_DECODE_CB(pnm_decode_frame),
 };
 #endif
 
@@ -398,6 +398,6 @@ const FFCodec ff_pfm_decoder = {
     .p.id           = AV_CODEC_ID_PFM,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(PNMContext),
-    .decode         = pnm_decode_frame,
+    FF_CODEC_DECODE_CB(pnm_decode_frame),
 };
 #endif
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index 020dbd218c..feb26b8bfa 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -157,7 +157,7 @@ const FFCodec ff_pgm_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PGM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = pnm_encode_frame,
+    FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE
     },
@@ -172,7 +172,7 @@ const FFCodec ff_pgmyuv_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PGMYUV,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = pnm_encode_frame,
+    FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE
     },
@@ -187,7 +187,7 @@ const FFCodec ff_ppm_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PPM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = pnm_encode_frame,
+    FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE
     },
@@ -202,7 +202,7 @@ const FFCodec ff_pbm_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PBM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = pnm_encode_frame,
+    FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE,
                                                   AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -216,7 +216,7 @@ const FFCodec ff_pfm_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PFM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2        = pnm_encode_frame,
+    FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_GBRPF32,
                                                     AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index 46ca26150b..dba64a2489 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -878,7 +878,7 @@ const FFCodec ff_prores_decoder = {
     .priv_data_size = sizeof(ProresContext),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
     .p.profiles     = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
index 2f6bd89efd..914c3fb2c2 100644
--- a/libavcodec/proresenc_anatoliy.c
+++ b/libavcodec/proresenc_anatoliy.c
@@ -949,7 +949,7 @@ const FFCodec ff_prores_aw_encoder = {
     .priv_data_size = sizeof(ProresContext),
     .init           = prores_encode_init,
     .close          = prores_encode_close,
-    .encode2        = prores_encode_frame,
+    FF_CODEC_ENCODE_CB(prores_encode_frame),
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.priv_class   = &prores_enc_class,
     .p.profiles     = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
@@ -965,7 +965,7 @@ const FFCodec ff_prores_encoder = {
     .priv_data_size = sizeof(ProresContext),
     .init           = prores_encode_init,
     .close          = prores_encode_close,
-    .encode2        = prores_encode_frame,
+    FF_CODEC_ENCODE_CB(prores_encode_frame),
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.priv_class   = &prores_enc_class,
     .p.profiles     = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 429b623678..1062ca1443 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -1401,7 +1401,7 @@ const FFCodec ff_prores_ks_encoder = {
     .priv_data_size = sizeof(ProresContext),
     .init           = encode_init,
     .close          = encode_close,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
                           AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
diff --git a/libavcodec/prosumer.c b/libavcodec/prosumer.c
index db17cd5083..8a91d5e110 100644
--- a/libavcodec/prosumer.c
+++ b/libavcodec/prosumer.c
@@ -372,7 +372,7 @@ const FFCodec ff_prosumer_decoder = {
     .p.id           = AV_CODEC_ID_PROSUMER,
     .priv_data_size = sizeof(ProSumerContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .close          = decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/psd.c b/libavcodec/psd.c
index da802a5585..1d92163408 100644
--- a/libavcodec/psd.c
+++ b/libavcodec/psd.c
@@ -551,5 +551,5 @@ const FFCodec ff_psd_decoder = {
     .p.id             = AV_CODEC_ID_PSD,
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .priv_data_size   = sizeof(PSDContext),
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index aa971bd74d..10b84e57b0 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -218,7 +218,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
         av_frame_unref(p->frame);
         p->got_frame = 0;
-        p->result = codec->decode(avctx, p->frame, &p->got_frame, p->avpkt);
+        p->result = codec->cb.decode(avctx, p->frame, &p->got_frame, p->avpkt);
 
         if ((p->result < 0 || !p->got_frame) && p->frame->buf[0])
             ff_thread_release_buffer(avctx, p->frame);
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index b782bf1db3..1102049347 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -92,5 +92,5 @@ const FFCodec ff_ptx_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PTX,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = ptx_decode_frame,
+    FF_CODEC_DECODE_CB(ptx_decode_frame),
 };
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index 16ece70e63..1a4d308ac1 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -796,7 +796,7 @@ const FFCodec ff_qcelp_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_QCELP,
     .init           = qcelp_decode_init,
-    .decode         = qcelp_decode_frame,
+    FF_CODEC_DECODE_CB(qcelp_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .priv_data_size = sizeof(QCELPContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 9d0b541964..427e8e8449 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1877,7 +1877,7 @@ const FFCodec ff_qdm2_decoder = {
     .priv_data_size   = sizeof(QDM2Context),
     .init             = qdm2_decode_init,
     .close            = qdm2_decode_close,
-    .decode           = qdm2_decode_frame,
+    FF_CODEC_DECODE_CB(qdm2_decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/qdmc.c b/libavcodec/qdmc.c
index 4ef4be19f5..7c069a8012 100644
--- a/libavcodec/qdmc.c
+++ b/libavcodec/qdmc.c
@@ -736,7 +736,7 @@ const FFCodec ff_qdmc_decoder = {
     .priv_data_size   = sizeof(QDMCContext),
     .init             = qdmc_decode_init,
     .close            = qdmc_decode_close,
-    .decode           = qdmc_decode_frame,
+    FF_CODEC_DECODE_CB(qdmc_decode_frame),
     .flush            = qdmc_flush,
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c
index bf67f8523d..849d4a5cad 100644
--- a/libavcodec/qdrw.c
+++ b/libavcodec/qdrw.c
@@ -519,5 +519,5 @@ const FFCodec ff_qdraw_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_QDRAW,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 0f33e87de1..9e787cb434 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -359,7 +359,7 @@ const FFCodec ff_qpeg_decoder = {
     .priv_data_size = sizeof(QpegContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 08eda5bc26..de4af1754d 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -984,7 +984,7 @@ const FFCodec ff_##x##_qsv_decoder = { \
     .p.type         = AVMEDIA_TYPE_VIDEO, \
     .p.id           = AV_CODEC_ID_##X, \
     .init           = qsv_decode_init, \
-    .decode         = qsv_decode_frame, \
+    FF_CODEC_DECODE_CB(qsv_decode_frame), \
     .flush          = qsv_decode_flush, \
     .close          = qsv_decode_close, \
     .bsfs           = bsf_name, \
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 3778fe66c2..b4cf9ea456 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -184,7 +184,7 @@ const FFCodec ff_h264_qsv_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_H264,
     .init           = qsv_enc_init,
-    .encode2        = qsv_enc_frame,
+    FF_CODEC_ENCODE_CB(qsv_enc_frame),
     .close          = qsv_enc_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 5c1571f62f..36c2d484ad 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -298,7 +298,7 @@ const FFCodec ff_hevc_qsv_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_HEVC,
     .init           = qsv_enc_init,
-    .encode2        = qsv_enc_frame,
+    FF_CODEC_ENCODE_CB(qsv_enc_frame),
     .close          = qsv_enc_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
diff --git a/libavcodec/qsvenc_jpeg.c b/libavcodec/qsvenc_jpeg.c
index 6bae0a0be9..825eb8dc06 100644
--- a/libavcodec/qsvenc_jpeg.c
+++ b/libavcodec/qsvenc_jpeg.c
@@ -86,7 +86,7 @@ const FFCodec ff_mjpeg_qsv_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MJPEG,
     .init           = qsv_enc_init,
-    .encode2        = qsv_enc_frame,
+    FF_CODEC_ENCODE_CB(qsv_enc_frame),
     .close          = qsv_enc_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
diff --git a/libavcodec/qsvenc_mpeg2.c b/libavcodec/qsvenc_mpeg2.c
index 0ab1412abb..3f79b48cb8 100644
--- a/libavcodec/qsvenc_mpeg2.c
+++ b/libavcodec/qsvenc_mpeg2.c
@@ -99,7 +99,7 @@ const FFCodec ff_mpeg2_qsv_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MPEG2VIDEO,
     .init           = qsv_enc_init,
-    .encode2        = qsv_enc_frame,
+    FF_CODEC_ENCODE_CB(qsv_enc_frame),
     .close          = qsv_enc_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
diff --git a/libavcodec/qsvenc_vp9.c b/libavcodec/qsvenc_vp9.c
index 6afbef195d..4b2a6ce77f 100644
--- a/libavcodec/qsvenc_vp9.c
+++ b/libavcodec/qsvenc_vp9.c
@@ -109,7 +109,7 @@ const FFCodec ff_vp9_qsv_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_VP9,
     .init           = qsv_enc_init,
-    .encode2        = qsv_enc_frame,
+    FF_CODEC_ENCODE_CB(qsv_enc_frame),
     .close          = qsv_enc_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index b7f114bdec..5e2139cce9 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -589,7 +589,7 @@ const FFCodec ff_qtrle_decoder = {
     .priv_data_size = sizeof(QtrleContext),
     .init           = qtrle_decode_init,
     .close          = qtrle_decode_end,
-    .decode         = qtrle_decode_frame,
+    FF_CODEC_DECODE_CB(qtrle_decode_frame),
     .flush          = qtrle_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index 04e98185e5..21c19eda23 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -406,7 +406,7 @@ const FFCodec ff_qtrle_encoder = {
     .p.id           = AV_CODEC_ID_QTRLE,
     .priv_data_size = sizeof(QtrleEncContext),
     .init           = qtrle_encode_init,
-    .encode2        = qtrle_encode_frame,
+    FF_CODEC_ENCODE_CB(qtrle_encode_frame),
     .close          = qtrle_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_ARGB, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c
index da20ffe067..b95f663aa5 100644
--- a/libavcodec/r210dec.c
+++ b/libavcodec/r210dec.c
@@ -109,7 +109,7 @@ const FFCodec ff_r210_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_R210,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -121,7 +121,7 @@ const FFCodec ff_r10k_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_R10K,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -133,7 +133,7 @@ const FFCodec ff_avrp_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_AVRP,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c
index 88bbd4677d..cfff21cb23 100644
--- a/libavcodec/r210enc.c
+++ b/libavcodec/r210enc.c
@@ -98,7 +98,7 @@ const FFCodec ff_r210_encoder = {
     .p.id           = AV_CODEC_ID_R210,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = pix_fmt,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -111,7 +111,7 @@ const FFCodec ff_r10k_encoder = {
     .p.id           = AV_CODEC_ID_R10K,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = pix_fmt,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -124,7 +124,7 @@ const FFCodec ff_avrp_encoder = {
     .p.id           = AV_CODEC_ID_AVRP,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = pix_fmt,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index b795e327a2..bef6389bcf 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -133,7 +133,7 @@ const FFCodec ff_ra_144_decoder = {
     .p.id           = AV_CODEC_ID_RA_144,
     .priv_data_size = sizeof(RA144Context),
     .init           = ra144_decode_init,
-    .decode         = ra144_decode_frame,
+    FF_CODEC_DECODE_CB(ra144_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c
index ec65621060..66ac381e60 100644
--- a/libavcodec/ra144enc.c
+++ b/libavcodec/ra144enc.c
@@ -544,7 +544,7 @@ const FFCodec ff_ra_144_encoder = {
                       AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size = sizeof(RA144Context),
     .init           = ra144_encode_init,
-    .encode2        = ra144_encode_frame,
+    FF_CODEC_ENCODE_CB(ra144_encode_frame),
     .close          = ra144_encode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index f904d471a3..24d976fd92 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -244,7 +244,7 @@ const FFCodec ff_ra_288_decoder = {
     .p.id           = AV_CODEC_ID_RA_288,
     .priv_data_size = sizeof(RA288Context),
     .init           = ra288_decode_init,
-    .decode         = ra288_decode_frame,
+    FF_CODEC_DECODE_CB(ra288_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c
index 3887c29ee9..16cb524a4e 100644
--- a/libavcodec/ralf.c
+++ b/libavcodec/ralf.c
@@ -521,7 +521,7 @@ const FFCodec ff_ralf_decoder = {
     .priv_data_size = sizeof(RALFContext),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c
index 6966ada2d0..bcb619f11c 100644
--- a/libavcodec/rasc.c
+++ b/libavcodec/rasc.c
@@ -805,7 +805,7 @@ const FFCodec ff_rasc_decoder = {
     .priv_data_size   = sizeof(RASCContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush            = decode_flush,
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 7ed7492337..c10b20d4f9 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -488,7 +488,7 @@ const FFCodec ff_rawvideo_decoder = {
     .priv_data_size = sizeof(RawVideoContext),
     .init           = raw_init_decoder,
     .close          = raw_close_decoder,
-    .decode         = raw_decode,
+    FF_CODEC_DECODE_CB(raw_decode),
     .p.priv_class   = &rawdec_class,
     .p.capabilities = AV_CODEC_CAP_PARAM_CHANGE,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index 1aa88d9db0..34d7a1bef4 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -88,6 +88,6 @@ const FFCodec ff_rawvideo_encoder = {
     .p.id           = AV_CODEC_ID_RAWVIDEO,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .init           = raw_encode_init,
-    .encode2        = raw_encode,
+    FF_CODEC_ENCODE_CB(raw_encode),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/realtextdec.c b/libavcodec/realtextdec.c
index 1612554461..e058b7494d 100644
--- a/libavcodec/realtextdec.c
+++ b/libavcodec/realtextdec.c
@@ -79,7 +79,7 @@ const FFCodec ff_realtext_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("RealText subtitle"),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_REALTEXT,
-    .decode_sub     = realtext_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(realtext_decode_frame),
     .init           = ff_ass_subtitle_header_default,
     .flush          = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index d5eab14c09..d4f09f456d 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -569,7 +569,7 @@ static const AVCodecHWConfigInternal *const rkmpp_hw_configs[] = {
         .priv_data_size = sizeof(RKMPPDecodeContext), \
         .init           = rkmpp_init_decoder, \
         .close          = rkmpp_close_decoder, \
-        .receive_frame  = rkmpp_receive_frame, \
+        FF_CODEC_RECEIVE_FRAME_CB(rkmpp_receive_frame), \
         .flush          = rkmpp_flush, \
         .p.priv_class   = &rkmpp_##NAME##_dec_class, \
         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index 37c9bf5d82..e76b068970 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -225,7 +225,7 @@ const FFCodec ff_rl2_decoder = {
     .priv_data_size = sizeof(Rl2Context),
     .init           = rl2_decode_init,
     .close          = rl2_decode_end,
-    .decode         = rl2_decode_frame,
+    FF_CODEC_DECODE_CB(rl2_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c
index c444c2e635..18a5f23df0 100644
--- a/libavcodec/roqaudioenc.c
+++ b/libavcodec/roqaudioenc.c
@@ -195,7 +195,7 @@ const FFCodec ff_roq_dpcm_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(ROQDPCMContext),
     .init           = roq_dpcm_encode_init,
-    .encode2        = roq_dpcm_encode_frame,
+    FF_CODEC_ENCODE_CB(roq_dpcm_encode_frame),
     .close          = roq_dpcm_encode_close,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c
index 99aa1ce24c..3e796b18bc 100644
--- a/libavcodec/roqvideodec.c
+++ b/libavcodec/roqvideodec.c
@@ -241,7 +241,7 @@ const FFCodec ff_roq_decoder = {
     .priv_data_size = sizeof(RoqContext),
     .init           = roq_decode_init,
     .close          = roq_decode_end,
-    .decode         = roq_decode_frame,
+    FF_CODEC_DECODE_CB(roq_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index ef7861088d..8cdc9f389c 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -1125,7 +1125,7 @@ const FFCodec ff_roq_encoder = {
     .p.id                 = AV_CODEC_ID_ROQ,
     .priv_data_size       = sizeof(RoqEncContext),
     .init                 = roq_encode_init,
-    .encode2              = roq_encode_frame,
+    FF_CODEC_ENCODE_CB(roq_encode_frame),
     .close                = roq_encode_end,
     .p.pix_fmts           = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ444P,
                                                         AV_PIX_FMT_NONE },
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 4482dfc8c8..703f05e7b8 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -294,7 +294,7 @@ const FFCodec ff_rpza_decoder = {
     .priv_data_size = sizeof(RpzaContext),
     .init           = rpza_decode_init,
     .close          = rpza_decode_end,
-    .decode         = rpza_decode_frame,
+    FF_CODEC_DECODE_CB(rpza_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/rpzaenc.c b/libavcodec/rpzaenc.c
index c4c3843f1c..50b68bb8b3 100644
--- a/libavcodec/rpzaenc.c
+++ b/libavcodec/rpzaenc.c
@@ -851,7 +851,7 @@ const FFCodec ff_rpza_encoder = {
     .priv_data_size = sizeof(RpzaContext),
     .p.priv_class   = &rpza_class,
     .init           = rpza_encode_init,
-    .encode2        = rpza_encode_frame,
+    FF_CODEC_ENCODE_CB(rpza_encode_frame),
     .close          = rpza_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB555,
diff --git a/libavcodec/rscc.c b/libavcodec/rscc.c
index 3891cf24e4..f4fa786718 100644
--- a/libavcodec/rscc.c
+++ b/libavcodec/rscc.c
@@ -368,7 +368,7 @@ const FFCodec ff_rscc_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RSCC,
     .init           = rscc_init,
-    .decode         = rscc_decode_frame,
+    FF_CODEC_DECODE_CB(rscc_decode_frame),
     .close          = rscc_close,
     .priv_data_size = sizeof(RsccContext),
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 8c2188bc05..8f8a755ac3 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -689,7 +689,7 @@ const FFCodec ff_rv10_decoder = {
     .priv_data_size = sizeof(RVDecContext),
     .init           = rv10_decode_init,
     .close          = rv10_decode_end,
-    .decode         = rv10_decode_frame,
+    FF_CODEC_DECODE_CB(rv10_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .p.max_lowres   = 3,
@@ -707,7 +707,7 @@ const FFCodec ff_rv20_decoder = {
     .priv_data_size = sizeof(RVDecContext),
     .init           = rv10_decode_init,
     .close          = rv10_decode_end,
-    .decode         = rv10_decode_frame,
+    FF_CODEC_DECODE_CB(rv10_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .flush          = ff_mpeg_flush,
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index 8df8f0a060..7560e6026a 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -73,7 +73,7 @@ const FFCodec ff_rv10_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index 916f505ecc..422188e21a 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -70,7 +70,7 @@ const FFCodec ff_rv20_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index 7d5e1acc97..8fd8498d9a 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -299,7 +299,7 @@ const FFCodec ff_rv30_decoder = {
     .priv_data_size        = sizeof(RV34DecContext),
     .init                  = rv30_decode_init,
     .close                 = ff_rv34_decode_end,
-    .decode                = ff_rv34_decode_frame,
+    FF_CODEC_DECODE_CB(ff_rv34_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
                              AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = ff_mpeg_flush,
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index b95f0d7919..b15f3cddfc 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -582,7 +582,7 @@ const FFCodec ff_rv40_decoder = {
     .priv_data_size        = sizeof(RV34DecContext),
     .init                  = rv40_decode_init,
     .close                 = ff_rv34_decode_end,
-    .decode                = ff_rv34_decode_frame,
+    FF_CODEC_DECODE_CB(ff_rv34_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
                              AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = ff_mpeg_flush,
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index 68533be6c6..fb7b6e240b 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -234,7 +234,7 @@ const FFCodec ff_s302m_decoder = {
     .p.id           = AV_CODEC_ID_S302M,
     .p.priv_class   = &s302m_class,
     .priv_data_size = sizeof(S302Context),
-    .decode         = s302m_decode_frame,
+    FF_CODEC_DECODE_CB(s302m_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
 };
diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c
index 737fc94697..b6f9501bf2 100644
--- a/libavcodec/s302menc.c
+++ b/libavcodec/s302menc.c
@@ -179,7 +179,7 @@ const FFCodec ff_s302m_encoder = {
                              AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
     .priv_data_size        = sizeof(S302MEncContext),
     .init                  = s302m_encode_init,
-    .encode2               = s302m_encode2_frame,
+    FF_CODEC_ENCODE_CB(s302m_encode2_frame),
     .p.sample_fmts         = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
                                                             AV_SAMPLE_FMT_S16,
                                                             AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/samidec.c b/libavcodec/samidec.c
index f2cf5783af..b9f6128a3e 100644
--- a/libavcodec/samidec.c
+++ b/libavcodec/samidec.c
@@ -188,7 +188,7 @@ const FFCodec ff_sami_decoder = {
     .priv_data_size = sizeof(SAMIContext),
     .init           = sami_init,
     .close          = sami_close,
-    .decode_sub     = sami_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(sami_decode_frame),
     .flush          = sami_flush,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index b5e12fccc1..7f094c8bbf 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -1524,7 +1524,7 @@ const FFCodec ff_sanm_decoder = {
     .priv_data_size = sizeof(SANMVideoContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/sbcdec.c b/libavcodec/sbcdec.c
index 6b79136fac..99af7e1652 100644
--- a/libavcodec/sbcdec.c
+++ b/libavcodec/sbcdec.c
@@ -372,7 +372,7 @@ const FFCodec ff_sbc_decoder = {
     .p.id                  = AV_CODEC_ID_SBC,
     .priv_data_size        = sizeof(SBCDecContext),
     .init                  = sbc_decode_init,
-    .decode                = sbc_decode_frame,
+    FF_CODEC_DECODE_CB(sbc_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
 #if FF_API_OLD_CHANNEL_LAYOUT
diff --git a/libavcodec/sbcenc.c b/libavcodec/sbcenc.c
index db1370f1c7..18ac4fb9bd 100644
--- a/libavcodec/sbcenc.c
+++ b/libavcodec/sbcenc.c
@@ -351,7 +351,7 @@ const FFCodec ff_sbc_encoder = {
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size        = sizeof(SBCEncContext),
     .init                  = sbc_encode_init,
-    .encode2               = sbc_encode_frame,
+    FF_CODEC_ENCODE_CB(sbc_encode_frame),
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
 #if FF_API_OLD_CHANNEL_LAYOUT
     .p.channel_layouts     = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c
index c744db2539..0623b73c84 100644
--- a/libavcodec/scpr.c
+++ b/libavcodec/scpr.c
@@ -675,7 +675,7 @@ const FFCodec ff_scpr_decoder = {
     .priv_data_size   = sizeof(SCPRContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/screenpresso.c b/libavcodec/screenpresso.c
index b2b71a00b3..8a4a8cde9e 100644
--- a/libavcodec/screenpresso.c
+++ b/libavcodec/screenpresso.c
@@ -189,7 +189,7 @@ const FFCodec ff_screenpresso_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SCREENPRESSO,
     .init           = screenpresso_init,
-    .decode         = screenpresso_decode_frame,
+    FF_CODEC_DECODE_CB(screenpresso_decode_frame),
     .close          = screenpresso_close,
     .priv_data_size = sizeof(ScreenpressoContext),
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/sga.c b/libavcodec/sga.c
index cb6d8db3f4..cdd37feb70 100644
--- a/libavcodec/sga.c
+++ b/libavcodec/sga.c
@@ -526,7 +526,7 @@ const FFCodec ff_sga_decoder = {
     .p.id           = AV_CODEC_ID_SGA_VIDEO,
     .priv_data_size = sizeof(SGAVideoContext),
     .init           = sga_decode_init,
-    .decode         = sga_decode_frame,
+    FF_CODEC_DECODE_CB(sga_decode_frame),
     .close          = sga_decode_end,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index a0669590ed..b23e205c3b 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -292,7 +292,7 @@ const FFCodec ff_sgi_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SGI,
     .priv_data_size = sizeof(SgiState),
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .init           = sgi_decode_init,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 8a3c1ddde1..93cb95f07f 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -278,7 +278,7 @@ const FFCodec ff_sgi_encoder = {
     .priv_data_size = sizeof(SgiContext),
     .p.priv_class = &sgi_class,
     .init      = encode_init,
-    .encode2   = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
         AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE,
diff --git a/libavcodec/sgirledec.c b/libavcodec/sgirledec.c
index 8e00fdf183..e04b9b1cad 100644
--- a/libavcodec/sgirledec.c
+++ b/libavcodec/sgirledec.c
@@ -137,7 +137,7 @@ const FFCodec ff_sgirle_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SGIRLE,
     .init           = sgirle_decode_init,
-    .decode         = sgirle_decode_frame,
+    FF_CODEC_DECODE_CB(sgirle_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/sheervideo.c b/libavcodec/sheervideo.c
index ecde9e1637..327bf85eda 100644
--- a/libavcodec/sheervideo.c
+++ b/libavcodec/sheervideo.c
@@ -2006,5 +2006,5 @@ const FFCodec ff_sheervideo_decoder = {
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .priv_data_size   = sizeof(SheerVideoContext),
     .close            = decode_end,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index 96dec88191..27074e930d 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -811,7 +811,7 @@ const FFCodec ff_shorten_decoder = {
     .priv_data_size = sizeof(ShortenContext),
     .init           = shorten_decode_init,
     .close          = shorten_decode_close,
-    .decode         = shorten_decode_frame,
+    FF_CODEC_DECODE_CB(shorten_decode_frame),
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DELAY |
                       AV_CODEC_CAP_DR1 |
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index dde39f154a..9d11f2c5c6 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -569,7 +569,7 @@ const FFCodec ff_sipr_decoder = {
     .p.id           = AV_CODEC_ID_SIPR,
     .priv_data_size = sizeof(SiprContext),
     .init           = sipr_decoder_init,
-    .decode         = sipr_decode_frame,
+    FF_CODEC_DECODE_CB(sipr_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/siren.c b/libavcodec/siren.c
index 70e8267dad..b613ee113d 100644
--- a/libavcodec/siren.c
+++ b/libavcodec/siren.c
@@ -849,7 +849,7 @@ const FFCodec ff_siren_decoder = {
     .p.id           = AV_CODEC_ID_SIREN,
     .init           = siren_init,
     .close          = siren_close,
-    .decode         = siren_decode,
+    FF_CODEC_DECODE_CB(siren_decode),
     .flush          = siren_flush,
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
@@ -865,7 +865,7 @@ const FFCodec ff_msnsiren_decoder = {
     .p.id           = AV_CODEC_ID_MSNSIREN,
     .init           = siren_init,
     .close          = siren_close,
-    .decode         = siren_decode,
+    FF_CODEC_DECODE_CB(siren_decode),
     .flush          = siren_flush,
     .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 1ef2161dbb..179c70f1ee 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -730,7 +730,7 @@ const FFCodec ff_smacker_decoder = {
     .priv_data_size = sizeof(SmackVContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -741,7 +741,7 @@ const FFCodec ff_smackaud_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_SMACKAUDIO,
     .init           = smka_decode_init,
-    .decode         = smka_decode_frame,
+    FF_CODEC_DECODE_CB(smka_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index 2f87937c49..313d8edba6 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -476,7 +476,7 @@ const FFCodec ff_smc_decoder = {
     .priv_data_size = sizeof(SmcContext),
     .init           = smc_decode_init,
     .close          = smc_decode_end,
-    .decode         = smc_decode_frame,
+    FF_CODEC_DECODE_CB(smc_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/smcenc.c b/libavcodec/smcenc.c
index a9f6c483a7..e1137098d0 100644
--- a/libavcodec/smcenc.c
+++ b/libavcodec/smcenc.c
@@ -555,7 +555,7 @@ const FFCodec ff_smc_encoder = {
     .p.id           = AV_CODEC_ID_SMC,
     .priv_data_size = sizeof(SMCContext),
     .init           = smc_encode_init,
-    .encode2        = smc_encode_frame,
+    FF_CODEC_ENCODE_CB(smc_encode_frame),
     .close          = smc_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_PAL8,
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index 4208707da0..92ff87731c 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -661,7 +661,7 @@ const FFCodec ff_snow_decoder = {
     .priv_data_size = sizeof(SnowContext),
     .init           = ff_snow_common_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index b5a5e57a91..410aa0f0e5 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1919,7 +1919,7 @@ const FFCodec ff_snow_encoder = {
     .p.id           = AV_CODEC_ID_SNOW,
     .priv_data_size = sizeof(SnowContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV444P,
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
index f20365485d..dfb055d80e 100644
--- a/libavcodec/sonic.c
+++ b/libavcodec/sonic.c
@@ -1084,7 +1084,7 @@ const FFCodec ff_sonic_decoder = {
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_decode_init,
     .close          = sonic_decode_close,
-    .decode         = sonic_decode_frame,
+    FF_CODEC_DECODE_CB(sonic_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
@@ -1098,7 +1098,7 @@ const FFCodec ff_sonic_encoder = {
     .p.id           = AV_CODEC_ID_SONIC,
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
-    .encode2        = sonic_encode_frame,
+    FF_CODEC_ENCODE_CB(sonic_encode_frame),
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
     .p.capabilities = AV_CODEC_CAP_EXPERIMENTAL,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
@@ -1114,7 +1114,7 @@ const FFCodec ff_sonic_ls_encoder = {
     .p.id           = AV_CODEC_ID_SONIC_LS,
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
-    .encode2        = sonic_encode_frame,
+    FF_CODEC_ENCODE_CB(sonic_encode_frame),
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
     .p.capabilities = AV_CODEC_CAP_EXPERIMENTAL,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c
index 99647efa52..aa4d3d771b 100644
--- a/libavcodec/sp5xdec.c
+++ b/libavcodec/sp5xdec.c
@@ -100,7 +100,7 @@ const FFCodec ff_sp5x_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .receive_frame  = ff_mjpeg_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.max_lowres   = 3,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
@@ -116,7 +116,7 @@ const FFCodec ff_amv_decoder = {
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
-    .receive_frame  = ff_mjpeg_receive_frame,
+    FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
     .p.max_lowres   = 3,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
diff --git a/libavcodec/speedhq.c b/libavcodec/speedhq.c
index fbe2d584d0..4cfd4ce73d 100644
--- a/libavcodec/speedhq.c
+++ b/libavcodec/speedhq.c
@@ -731,7 +731,7 @@ const FFCodec ff_speedhq_decoder = {
     .p.id           = AV_CODEC_ID_SPEEDHQ,
     .priv_data_size = sizeof(SHQContext),
     .init           = speedhq_decode_init,
-    .decode         = speedhq_decode_frame,
+    FF_CODEC_DECODE_CB(speedhq_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 22213b823d..55b378abce 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -278,7 +278,7 @@ const FFCodec ff_speedhq_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
diff --git a/libavcodec/speexdec.c b/libavcodec/speexdec.c
index 28a6b67a66..3251eda820 100644
--- a/libavcodec/speexdec.c
+++ b/libavcodec/speexdec.c
@@ -1582,7 +1582,7 @@ const FFCodec ff_speex_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_SPEEX,
     .init           = speex_decode_init,
-    .decode         = speex_decode_frame,
+    FF_CODEC_DECODE_CB(speex_decode_frame),
     .close          = speex_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .priv_data_size = sizeof(SpeexContext),
diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c
index aa975d16c7..705df007d6 100644
--- a/libavcodec/srtdec.c
+++ b/libavcodec/srtdec.c
@@ -96,7 +96,7 @@ const FFCodec ff_srt_decoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_SUBRIP,
     .init         = ff_ass_subtitle_header_default,
-    .decode_sub   = srt_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(srt_decode_frame),
     .flush        = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -110,7 +110,7 @@ const FFCodec ff_subrip_decoder = {
     .p.type       = AVMEDIA_TYPE_SUBTITLE,
     .p.id         = AV_CODEC_ID_SUBRIP,
     .init         = ff_ass_subtitle_header_default,
-    .decode_sub   = srt_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(srt_decode_frame),
     .flush        = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
index 8ff799b684..51456c8b9d 100644
--- a/libavcodec/srtenc.c
+++ b/libavcodec/srtenc.c
@@ -300,7 +300,7 @@ const FFCodec ff_srt_encoder = {
     .p.id           = AV_CODEC_ID_SUBRIP,
     .priv_data_size = sizeof(SRTContext),
     .init           = srt_encode_init,
-    .encode_sub     = srt_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(srt_encode_frame),
     .close          = srt_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -314,7 +314,7 @@ const FFCodec ff_subrip_encoder = {
     .p.id           = AV_CODEC_ID_SUBRIP,
     .priv_data_size = sizeof(SRTContext),
     .init           = srt_encode_init,
-    .encode_sub     = srt_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(srt_encode_frame),
     .close          = srt_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -328,7 +328,7 @@ const FFCodec ff_text_encoder = {
     .p.id           = AV_CODEC_ID_TEXT,
     .priv_data_size = sizeof(SRTContext),
     .init           = srt_encode_init,
-    .encode_sub     = text_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(text_encode_frame),
     .close          = srt_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c
index 9001dd3d45..b6acea93f5 100644
--- a/libavcodec/subviewerdec.c
+++ b/libavcodec/subviewerdec.c
@@ -70,7 +70,7 @@ const FFCodec ff_subviewer_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("SubViewer subtitle"),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_SUBVIEWER,
-    .decode_sub     = subviewer_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(subviewer_decode_frame),
     .init           = ff_ass_subtitle_header_default,
     .flush          = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index 65b4f359b2..e543757a39 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -211,5 +211,5 @@ const FFCodec ff_sunrast_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SUNRAST,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = sunrast_decode_frame,
+    FF_CODEC_DECODE_CB(sunrast_decode_frame),
 };
diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c
index acc609c3b6..6245e592c7 100644
--- a/libavcodec/sunrastenc.c
+++ b/libavcodec/sunrastenc.c
@@ -215,7 +215,7 @@ const FFCodec ff_sunrast_encoder = {
     .p.id           = AV_CODEC_ID_SUNRAST,
     .priv_data_size = sizeof(SUNRASTContext),
     .init           = sunrast_encode_init,
-    .encode2        = sunrast_encode_frame,
+    FF_CODEC_ENCODE_CB(sunrast_encode_frame),
     .p.priv_class   = &sunrast_class,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24,
                                                   AV_PIX_FMT_PAL8,
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index e0a599bb36..7cd623ff18 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -851,7 +851,7 @@ const FFCodec ff_svq1_decoder = {
     .priv_data_size = sizeof(SVQ1Context),
     .init           = svq1_decode_init,
     .close          = svq1_decode_end,
-    .decode         = svq1_decode_frame,
+    FF_CODEC_DECODE_CB(svq1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .flush          = svq1_flush,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 706bc2e42e..a0205e8bb7 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -684,7 +684,7 @@ const FFCodec ff_svq1_encoder = {
     .priv_data_size = sizeof(SVQ1EncContext),
     .p.priv_class   = &svq1enc_class,
     .init           = svq1_encode_init,
-    .encode2        = svq1_encode_frame,
+    FF_CODEC_ENCODE_CB(svq1_encode_frame),
     .close          = svq1_encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
                                                      AV_PIX_FMT_NONE },
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index 69949b7e63..f038466922 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -1596,7 +1596,7 @@ const FFCodec ff_svq3_decoder = {
     .priv_data_size = sizeof(SVQ3Context),
     .init           = svq3_decode_init,
     .close          = svq3_decode_end,
-    .decode         = svq3_decode_frame,
+    FF_CODEC_DECODE_CB(svq3_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND |
                       AV_CODEC_CAP_DR1             |
                       AV_CODEC_CAP_DELAY,
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index 0ef42adc81..47978fcd4b 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -949,7 +949,7 @@ const FFCodec ff_tak_decoder = {
     .priv_data_size   = sizeof(TAKDecContext),
     .init             = tak_decode_init,
     .close            = tak_decode_close,
-    .decode           = tak_decode_frame,
+    FF_CODEC_DECODE_CB(tak_decode_frame),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index d6c46f8dce..833576c6b3 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -312,5 +312,5 @@ const FFCodec ff_targa_decoder = {
     .p.id           = AV_CODEC_ID_TARGA,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(TargaContext),
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff --git a/libavcodec/targa_y216dec.c b/libavcodec/targa_y216dec.c
index c6339ab92a..bf33dc8a68 100644
--- a/libavcodec/targa_y216dec.c
+++ b/libavcodec/targa_y216dec.c
@@ -79,7 +79,7 @@ const FFCodec ff_targa_y216_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_TARGA_Y216,
     .init         = y216_decode_init,
-    .decode       = y216_decode_frame,
+    FF_CODEC_DECODE_CB(y216_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c
index 9170eff956..84e2086869 100644
--- a/libavcodec/targaenc.c
+++ b/libavcodec/targaenc.c
@@ -210,7 +210,7 @@ const FFCodec ff_targa_encoder = {
     .priv_data_size = sizeof(TargaContext),
     .p.priv_class   = &targa_class,
     .init           = targa_encode_init,
-    .encode2        = targa_encode_frame,
+    FF_CODEC_ENCODE_CB(targa_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8,
         AV_PIX_FMT_NONE
diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c
index 701cd8b9ad..0cf17d75dd 100644
--- a/libavcodec/tdsc.c
+++ b/libavcodec/tdsc.c
@@ -627,7 +627,7 @@ const FFCodec ff_tdsc_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_TDSC,
     .init           = tdsc_init,
-    .decode         = tdsc_decode_frame,
+    FF_CODEC_DECODE_CB(tdsc_decode_frame),
     .close          = tdsc_close,
     .priv_data_size = sizeof(TDSCContext),
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/tests/avcodec.c b/libavcodec/tests/avcodec.c
index f77d7aebe9..08b5fbede1 100644
--- a/libavcodec/tests/avcodec.c
+++ b/libavcodec/tests/avcodec.c
@@ -64,7 +64,7 @@ int main(void){
     while (codec = av_codec_iterate(&iter)) {
         const FFCodec *const codec2 = ffcodec(codec);
         const AVCodecDescriptor *desc;
-        int is_decoder, is_encoder;
+        int is_decoder = 0, is_encoder = 0;
 
         if (!codec->name) {
             AV_LOG("Codec for format %s has no name\n",
@@ -102,17 +102,38 @@ int main(void){
                                      AV_CODEC_CAP_OTHER_THREADS)))
             ERR("Codec %s has private-only threading support\n");
 
-        is_decoder = av_codec_is_decoder(codec);
-        is_encoder = av_codec_is_encoder(codec);
-        if (!!is_decoder + !!is_encoder != 1) {
-            ERR("Codec %s is decoder and encoder or neither.\n");
+        switch (codec2->cb_type) {
+        case FF_CODEC_CB_TYPE_DECODE:
+        case FF_CODEC_CB_TYPE_DECODE_SUB:
+        case FF_CODEC_CB_TYPE_RECEIVE_FRAME:
+            is_decoder = 1;
+            break;
+        case FF_CODEC_CB_TYPE_ENCODE:
+        case FF_CODEC_CB_TYPE_ENCODE_SUB:
+        case FF_CODEC_CB_TYPE_RECEIVE_PACKET:
+            is_encoder = 1;
+            break;
+        default:
+            ERR("Codec %s has unknown cb_type\n");
             continue;
         }
+        if (is_decoder != av_codec_is_decoder(codec) ||
+            is_encoder != av_codec_is_encoder(codec)) {
+            ERR("Codec %s cb_type and av_codec_is_(de|en)coder inconsistent.\n");
+            continue;
+        }
+#define CHECK(TYPE, type) (codec2->cb_type == FF_CODEC_CB_TYPE_ ## TYPE && !codec2->cb.type)
+        if (CHECK(DECODE, decode) || CHECK(DECODE_SUB, decode_sub) ||
+            CHECK(RECEIVE_PACKET, receive_packet) ||
+            CHECK(ENCODE, encode) || CHECK(ENCODE_SUB, encode_sub) ||
+            CHECK(RECEIVE_FRAME, receive_frame)) {
+            ERR_EXT("Codec %s does not implement its %s callback.\n",
+                    is_decoder ? "decoding" : "encoding");
+        }
+#undef CHECK
         if (is_encoder) {
-            if (codec->type == AVMEDIA_TYPE_SUBTITLE ^ !!codec2->encode_sub)
+            if ((codec->type == AVMEDIA_TYPE_SUBTITLE) != (codec2->cb_type == FF_CODEC_CB_TYPE_ENCODE_SUB))
                 ERR("Encoder %s is both subtitle encoder and not subtitle encoder.");
-            if (!!codec2->encode_sub + !!codec2->encode2 + !!codec2->receive_packet != 1)
-                ERR("Encoder %s does not implement exactly one encode API.\n");
             if (codec2->update_thread_context || codec2->update_thread_context_for_user || codec2->bsfs)
                 ERR("Encoder %s has decoder-only thread functions or bsf.\n");
             if (codec->type == AVMEDIA_TYPE_AUDIO) {
@@ -135,14 +156,11 @@ int main(void){
                 codec->capabilities & AV_CODEC_CAP_ENCODER_FLUSH)
                 ERR("Frame-threaded encoder %s claims to support flushing\n");
         } else {
-            if (codec->type == AVMEDIA_TYPE_SUBTITLE && !codec2->decode_sub)
+            if ((codec->type == AVMEDIA_TYPE_SUBTITLE) != (codec2->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB))
                 ERR("Subtitle decoder %s does not implement decode_sub callback\n");
             if (codec->type == AVMEDIA_TYPE_SUBTITLE && codec2->bsfs)
                 ERR("Automatic bitstream filtering unsupported for subtitles; "
                     "yet decoder %s has it set\n");
-            if (codec->type != AVMEDIA_TYPE_SUBTITLE !=
-                !!codec2->decode + !!codec2->receive_frame)
-                ERR("Decoder %s does not implement exactly one decode API.\n");
             if (codec->capabilities & (AV_CODEC_CAP_SMALL_LAST_FRAME    |
                                        AV_CODEC_CAP_VARIABLE_FRAME_SIZE |
                                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
diff --git a/libavcodec/textdec.c b/libavcodec/textdec.c
index 48e7e14602..09de0ad8fd 100644
--- a/libavcodec/textdec.c
+++ b/libavcodec/textdec.c
@@ -86,7 +86,7 @@ const FFCodec ff_text_decoder = {
     .priv_data_size = sizeof(TextContext),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_TEXT,
-    .decode_sub     = text_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(text_decode_frame),
     .init           = ff_ass_subtitle_header_default,
     .p.priv_class   = &textsub_decoder_class,
     .flush          = text_flush,
@@ -110,7 +110,7 @@ const FFCodec ff_vplayer_decoder = {
     .priv_data_size = sizeof(TextContext),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_VPLAYER,
-    .decode_sub     = text_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(text_decode_frame),
     .init           = linebreak_init,
     .p.priv_class   = &textsub_decoder_class,
     .flush          = text_flush,
@@ -125,7 +125,7 @@ const FFCodec ff_stl_decoder = {
     .priv_data_size = sizeof(TextContext),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_STL,
-    .decode_sub     = text_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(text_decode_frame),
     .init           = linebreak_init,
     .p.priv_class   = &textsub_decoder_class,
     .flush          = text_flush,
@@ -140,7 +140,7 @@ const FFCodec ff_pjs_decoder = {
     .priv_data_size = sizeof(TextContext),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_PJS,
-    .decode_sub     = text_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(text_decode_frame),
     .init           = linebreak_init,
     .p.priv_class   = &textsub_decoder_class,
     .flush          = text_flush,
@@ -155,7 +155,7 @@ const FFCodec ff_subviewer1_decoder = {
     .priv_data_size = sizeof(TextContext),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_SUBVIEWER1,
-    .decode_sub     = text_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(text_decode_frame),
     .init           = linebreak_init,
     .p.priv_class   = &textsub_decoder_class,
     .flush          = text_flush,
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index 06d9c39880..618275a57c 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -269,7 +269,7 @@ const FFCodec ff_tiertexseqvideo_decoder = {
     .priv_data_size = sizeof(SeqVideoContext),
     .init           = seqvideo_decode_init,
     .close          = seqvideo_decode_end,
-    .decode         = seqvideo_decode_frame,
+    FF_CODEC_DECODE_CB(seqvideo_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 3d5b3c28ac..e4a5d3c537 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -2185,7 +2185,7 @@ const FFCodec ff_tiff_decoder = {
     .priv_data_size = sizeof(TiffContext),
     .init           = tiff_init,
     .close          = tiff_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.priv_class   = &tiff_decoder_class,
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index 17ff542354..2f2742e566 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -578,7 +578,7 @@ const FFCodec ff_tiff_encoder = {
     .init           = encode_init,
     .close          = encode_close,
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_PAL8,
         AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE,
diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c
index 263a63aa55..d1685a0ae7 100644
--- a/libavcodec/tmv.c
+++ b/libavcodec/tmv.c
@@ -92,7 +92,7 @@ const FFCodec ff_tmv_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_TMV,
     .init           = tmv_decode_init,
-    .decode         = tmv_decode_frame,
+    FF_CODEC_DECODE_CB(tmv_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index 7ef025b43e..64d9b8fed1 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -918,7 +918,7 @@ const FFCodec ff_truemotion1_decoder = {
     .priv_data_size = sizeof(TrueMotion1Context),
     .init           = truemotion1_decode_init,
     .close          = truemotion1_decode_end,
-    .decode         = truemotion1_decode_frame,
+    FF_CODEC_DECODE_CB(truemotion1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index a89f999ce5..3fd956ee1e 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -1016,7 +1016,7 @@ const FFCodec ff_truemotion2_decoder = {
     .priv_data_size = sizeof(TM2Context),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/truemotion2rt.c b/libavcodec/truemotion2rt.c
index 0383cb090f..a3686fc1ac 100644
--- a/libavcodec/truemotion2rt.c
+++ b/libavcodec/truemotion2rt.c
@@ -226,7 +226,7 @@ const FFCodec ff_truemotion2rt_decoder = {
     .p.id           = AV_CODEC_ID_TRUEMOTION2RT,
     .priv_data_size = sizeof(TrueMotion2RTContext),
     .init           = truemotion2rt_decode_init,
-    .decode         = truemotion2rt_decode_frame,
+    FF_CODEC_DECODE_CB(truemotion2rt_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c
index a8bf43d2a4..e472cb8241 100644
--- a/libavcodec/truespeech.c
+++ b/libavcodec/truespeech.c
@@ -363,7 +363,7 @@ const FFCodec ff_truespeech_decoder = {
     .p.id           = AV_CODEC_ID_TRUESPEECH,
     .priv_data_size = sizeof(TSContext),
     .init           = truespeech_decode_init,
-    .decode         = truespeech_decode_frame,
+    FF_CODEC_DECODE_CB(truespeech_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c
index a841fd2c9d..7343d7aace 100644
--- a/libavcodec/tscc.c
+++ b/libavcodec/tscc.c
@@ -178,7 +178,7 @@ const FFCodec ff_tscc_decoder = {
     .priv_data_size = sizeof(CamtasiaContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c
index 6879f42cd9..136f1f76d9 100644
--- a/libavcodec/tscc2.c
+++ b/libavcodec/tscc2.c
@@ -364,7 +364,7 @@ const FFCodec ff_tscc2_decoder = {
     .priv_data_size = sizeof(TSCC2Context),
     .init           = tscc2_decode_init,
     .close          = tscc2_decode_end,
-    .decode         = tscc2_decode_frame,
+    FF_CODEC_DECODE_CB(tscc2_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 506a61b881..74be140d51 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -428,7 +428,7 @@ const FFCodec ff_tta_decoder = {
     .priv_data_size = sizeof(TTAContext),
     .init           = tta_decode_init,
     .close          = tta_decode_close,
-    .decode         = tta_decode_frame,
+    FF_CODEC_DECODE_CB(tta_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
     .p.priv_class   = &tta_decoder_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/ttaenc.c b/libavcodec/ttaenc.c
index b52cb21d2c..b7d4aafdc3 100644
--- a/libavcodec/ttaenc.c
+++ b/libavcodec/ttaenc.c
@@ -210,7 +210,7 @@ const FFCodec ff_tta_encoder = {
     .priv_data_size = sizeof(TTAEncContext),
     .init           = tta_encode_init,
     .close          = tta_encode_close,
-    .encode2        = tta_encode_frame,
+    FF_CODEC_ENCODE_CB(tta_encode_frame),
     .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8,
                                                      AV_SAMPLE_FMT_S16,
diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c
index 98a36caf5c..be1d8fb2e8 100644
--- a/libavcodec/ttmlenc.c
+++ b/libavcodec/ttmlenc.c
@@ -390,7 +390,7 @@ const FFCodec ff_ttml_encoder = {
     .p.id           = AV_CODEC_ID_TTML,
     .priv_data_size = sizeof(TTMLContext),
     .init           = ttml_encode_init,
-    .encode_sub     = ttml_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(ttml_encode_frame),
     .close          = ttml_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c
index 7f0eeb0bfb..6dfa57f007 100644
--- a/libavcodec/twinvqdec.c
+++ b/libavcodec/twinvqdec.c
@@ -422,7 +422,7 @@ const FFCodec ff_twinvq_decoder = {
     .priv_data_size = sizeof(TwinVQContext),
     .init           = twinvq_decode_init,
     .close          = ff_twinvq_decode_close,
-    .decode         = ff_twinvq_decode_frame,
+    FF_CODEC_DECODE_CB(ff_twinvq_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index 854ef1522d..8b1da773a3 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -170,5 +170,5 @@ const FFCodec ff_txd_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_TXD,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = txd_decode_frame,
+    FF_CODEC_DECODE_CB(txd_decode_frame),
 };
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index c5be1dffda..a8bec9cce2 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -426,7 +426,7 @@ const FFCodec ff_ulti_decoder = {
     .priv_data_size = sizeof(UltimotionDecodeContext),
     .init           = ulti_decode_init,
     .close          = ulti_decode_end,
-    .decode         = ulti_decode_frame,
+    FF_CODEC_DECODE_CB(ulti_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 34d97022b7..eb7e505a62 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -74,13 +74,17 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size)
 int av_codec_is_encoder(const AVCodec *avcodec)
 {
     const FFCodec *const codec = ffcodec(avcodec);
-    return codec && (codec->encode_sub || codec->encode2 || codec->receive_packet);
+    return codec && (codec->cb_type == FF_CODEC_CB_TYPE_ENCODE     ||
+                     codec->cb_type == FF_CODEC_CB_TYPE_ENCODE_SUB ||
+                     codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_PACKET);
 }
 
 int av_codec_is_decoder(const AVCodec *avcodec)
 {
     const FFCodec *const codec = ffcodec(avcodec);
-    return codec && (codec->decode || codec->decode_sub || codec->receive_frame);
+    return codec && (codec->cb_type == FF_CODEC_CB_TYPE_DECODE     ||
+                     codec->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB ||
+                     codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME);
 }
 
 int ff_set_dimensions(AVCodecContext *s, int width, int height)
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 051f90c9db..03ee8f0b10 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -1058,7 +1058,7 @@ const FFCodec ff_utvideo_decoder = {
     .priv_data_size = sizeof(UtvideoContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index e1f7086152..15a53a6094 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -651,7 +651,7 @@ const FFCodec ff_utvideo_encoder = {
     .priv_data_size = sizeof(UtvideoContext),
     .p.priv_class   = &utvideo_class,
     .init           = utvideo_encode_init,
-    .encode2        = utvideo_encode_frame,
+    FF_CODEC_ENCODE_CB(utvideo_encode_frame),
     .close          = utvideo_encode_close,
     .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index f208a0786f..b5e1d728a7 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -218,7 +218,7 @@ const FFCodec ff_v210_decoder = {
     .p.id           = AV_CODEC_ID_V210,
     .priv_data_size = sizeof(V210DecContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 |
                       AV_CODEC_CAP_SLICE_THREADS |
                       AV_CODEC_CAP_FRAME_THREADS,
diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
index 2582571823..9ac923571c 100644
--- a/libavcodec/v210enc.c
+++ b/libavcodec/v210enc.c
@@ -160,7 +160,7 @@ const FFCodec ff_v210_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .priv_data_size = sizeof(V210EncContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c
index 34eb54e447..18d3e637be 100644
--- a/libavcodec/v210x.c
+++ b/libavcodec/v210x.c
@@ -125,7 +125,7 @@ const FFCodec ff_v210x_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_V210X,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v308dec.c b/libavcodec/v308dec.c
index 6c85bc585d..5f8cbc634b 100644
--- a/libavcodec/v308dec.c
+++ b/libavcodec/v308dec.c
@@ -78,7 +78,7 @@ const FFCodec ff_v308_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_V308,
     .init         = v308_decode_init,
-    .decode       = v308_decode_frame,
+    FF_CODEC_DECODE_CB(v308_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c
index 08e6ddaecb..c4f07a123d 100644
--- a/libavcodec/v308enc.c
+++ b/libavcodec/v308enc.c
@@ -77,7 +77,7 @@ const FFCodec ff_v308_encoder = {
     .p.id         = AV_CODEC_ID_V308,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init         = v308_encode_init,
-    .encode2      = v308_encode_frame,
+    FF_CODEC_ENCODE_CB(v308_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE },
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v408dec.c b/libavcodec/v408dec.c
index 32ea98b724..02024959c7 100644
--- a/libavcodec/v408dec.c
+++ b/libavcodec/v408dec.c
@@ -88,7 +88,7 @@ const FFCodec ff_ayuv_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_AYUV,
     .init         = v408_decode_init,
-    .decode       = v408_decode_frame,
+    FF_CODEC_DECODE_CB(v408_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -100,7 +100,7 @@ const FFCodec ff_v408_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_V408,
     .init         = v408_decode_init,
-    .decode       = v408_decode_frame,
+    FF_CODEC_DECODE_CB(v408_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c
index 52d5e19802..157ed85104 100644
--- a/libavcodec/v408enc.c
+++ b/libavcodec/v408enc.c
@@ -87,7 +87,7 @@ const FFCodec ff_ayuv_encoder = {
     .p.id         = AV_CODEC_ID_AYUV,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init         = v408_encode_init,
-    .encode2      = v408_encode_frame,
+    FF_CODEC_ENCODE_CB(v408_encode_frame),
     .p.pix_fmts   = pix_fmt,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
@@ -100,7 +100,7 @@ const FFCodec ff_v408_encoder = {
     .p.id         = AV_CODEC_ID_V408,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init         = v408_encode_init,
-    .encode2      = v408_encode_frame,
+    FF_CODEC_ENCODE_CB(v408_encode_frame),
     .p.pix_fmts   = pix_fmt,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
index bb1dd5d0c6..f6d675c508 100644
--- a/libavcodec/v410dec.c
+++ b/libavcodec/v410dec.c
@@ -120,7 +120,7 @@ const FFCodec ff_v410_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_V410,
     .init         = v410_decode_init,
-    .decode       = v410_decode_frame,
+    FF_CODEC_DECODE_CB(v410_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
                     AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
index 32966d9176..88a2ce346b 100644
--- a/libavcodec/v410enc.c
+++ b/libavcodec/v410enc.c
@@ -81,7 +81,7 @@ const FFCodec ff_v410_encoder = {
     .p.id         = AV_CODEC_ID_V410,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init         = v410_encode_init,
-    .encode2      = v410_encode_frame,
+    FF_CODEC_ENCODE_CB(v410_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE },
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
index 4c521eba34..8a51dec3fa 100644
--- a/libavcodec/v4l2_m2m_dec.c
+++ b/libavcodec/v4l2_m2m_dec.c
@@ -248,7 +248,7 @@ static const AVOption options[] = {
         .priv_data_size = sizeof(V4L2m2mPriv), \
         .p.priv_class   = &v4l2_m2m_ ## NAME ## _dec_class, \
         .init           = v4l2_decode_init, \
-        .receive_frame  = v4l2_receive_frame, \
+        FF_CODEC_RECEIVE_FRAME_CB(v4l2_receive_frame), \
         .close          = v4l2_decode_close, \
         .bsfs           = bsf_name, \
         .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
index 1d90de2b9d..20f81df750 100644
--- a/libavcodec/v4l2_m2m_enc.c
+++ b/libavcodec/v4l2_m2m_enc.c
@@ -429,7 +429,7 @@ static const FFCodecDefault v4l2_m2m_defaults[] = {
         .priv_data_size = sizeof(V4L2m2mPriv), \
         .p.priv_class   = &v4l2_m2m_ ## NAME ##_enc_class, \
         .init           = v4l2_encode_init, \
-        .receive_packet = v4l2_receive_packet, \
+        FF_CODEC_RECEIVE_PACKET_CB(v4l2_receive_packet), \
         .close          = v4l2_encode_close, \
         .defaults       = v4l2_m2m_defaults, \
         .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 69d5abfe55..7a6b54ab6f 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -1332,7 +1332,7 @@ const FFCodec ff_h264_vaapi_encoder = {
     .p.id           = AV_CODEC_ID_H264,
     .priv_data_size = sizeof(VAAPIEncodeH264Context),
     .init           = &vaapi_encode_h264_init,
-    .receive_packet = &ff_vaapi_encode_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &vaapi_encode_h264_close,
     .p.priv_class   = &vaapi_encode_h264_class,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index a77cb21c82..0be32588c0 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -1309,7 +1309,7 @@ const FFCodec ff_hevc_vaapi_encoder = {
     .p.id           = AV_CODEC_ID_HEVC,
     .priv_data_size = sizeof(VAAPIEncodeH265Context),
     .init           = &vaapi_encode_h265_init,
-    .receive_packet = &ff_vaapi_encode_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &vaapi_encode_h265_close,
     .p.priv_class   = &vaapi_encode_h265_class,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
index d42c1d7b1e..ddc1d0fc8d 100644
--- a/libavcodec/vaapi_encode_mjpeg.c
+++ b/libavcodec/vaapi_encode_mjpeg.c
@@ -559,7 +559,7 @@ const FFCodec ff_mjpeg_vaapi_encoder = {
     .p.id           = AV_CODEC_ID_MJPEG,
     .priv_data_size = sizeof(VAAPIEncodeMJPEGContext),
     .init           = &vaapi_encode_mjpeg_init,
-    .receive_packet = &ff_vaapi_encode_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &vaapi_encode_mjpeg_close,
     .p.priv_class   = &vaapi_encode_mjpeg_class,
     .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1,
diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c
index ef24dcbbb9..0e30efe119 100644
--- a/libavcodec/vaapi_encode_mpeg2.c
+++ b/libavcodec/vaapi_encode_mpeg2.c
@@ -697,7 +697,7 @@ const FFCodec ff_mpeg2_vaapi_encoder = {
     .p.id           = AV_CODEC_ID_MPEG2VIDEO,
     .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),
     .init           = &vaapi_encode_mpeg2_init,
-    .receive_packet = &ff_vaapi_encode_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &vaapi_encode_mpeg2_close,
     .p.priv_class   = &vaapi_encode_mpeg2_class,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c
index 9824fff052..0e384d5a58 100644
--- a/libavcodec/vaapi_encode_vp8.c
+++ b/libavcodec/vaapi_encode_vp8.c
@@ -252,7 +252,7 @@ const FFCodec ff_vp8_vaapi_encoder = {
     .p.id           = AV_CODEC_ID_VP8,
     .priv_data_size = sizeof(VAAPIEncodeVP8Context),
     .init           = &vaapi_encode_vp8_init,
-    .receive_packet = &ff_vaapi_encode_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &ff_vaapi_encode_close,
     .p.priv_class   = &vaapi_encode_vp8_class,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c
index dd87825c28..9ca4e451a3 100644
--- a/libavcodec/vaapi_encode_vp9.c
+++ b/libavcodec/vaapi_encode_vp9.c
@@ -294,7 +294,7 @@ const FFCodec ff_vp9_vaapi_encoder = {
     .p.id           = AV_CODEC_ID_VP9,
     .priv_data_size = sizeof(VAAPIEncodeVP9Context),
     .init           = &vaapi_encode_vp9_init,
-    .receive_packet = &ff_vaapi_encode_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &ff_vaapi_encode_close,
     .p.priv_class   = &vaapi_encode_vp9_class,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
diff --git a/libavcodec/vb.c b/libavcodec/vb.c
index 1a05bd949f..82b4ea85ca 100644
--- a/libavcodec/vb.c
+++ b/libavcodec/vb.c
@@ -286,7 +286,7 @@ const FFCodec ff_vb_decoder = {
     .priv_data_size = sizeof(VBDecContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
index 85b1fec855..f7ab17d621 100644
--- a/libavcodec/vble.c
+++ b/libavcodec/vble.c
@@ -209,7 +209,7 @@ const FFCodec ff_vble_decoder = {
     .priv_data_size = sizeof(VBLEContext),
     .init           = vble_decode_init,
     .close          = vble_decode_close,
-    .decode         = vble_decode_frame,
+    FF_CODEC_DECODE_CB(vble_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 0f5a07ff33..3e746e64cb 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -1209,7 +1209,7 @@ const FFCodec ff_vc1_decoder = {
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
     .close          = ff_vc1_decode_end,
-    .decode         = vc1_decode_frame,
+    FF_CODEC_DECODE_CB(vc1_decode_frame),
     .flush          = ff_mpeg_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -1247,7 +1247,7 @@ const FFCodec ff_wmv3_decoder = {
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
     .close          = ff_vc1_decode_end,
-    .decode         = vc1_decode_frame,
+    FF_CODEC_DECODE_CB(vc1_decode_frame),
     .flush          = ff_mpeg_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
@@ -1286,7 +1286,7 @@ const FFCodec ff_wmv3image_decoder = {
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
     .close          = ff_vc1_decode_end,
-    .decode         = vc1_decode_frame,
+    FF_CODEC_DECODE_CB(vc1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .flush          = vc1_sprite_flush,
@@ -1306,7 +1306,7 @@ const FFCodec ff_vc1image_decoder = {
     .priv_data_size = sizeof(VC1Context),
     .init           = vc1_decode_init,
     .close          = ff_vc1_decode_end,
-    .decode         = vc1_decode_frame,
+    FF_CODEC_DECODE_CB(vc1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .flush          = vc1_sprite_flush,
diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c
index e1b8b7ffae..1e3127f080 100644
--- a/libavcodec/vc2enc.c
+++ b/libavcodec/vc2enc.c
@@ -1234,7 +1234,7 @@ const FFCodec ff_vc2_encoder = {
     .priv_data_size = sizeof(VC2EncContext),
     .init           = vc2_encode_init,
     .close          = vc2_encode_end,
-    .encode2        = vc2_encode_frame,
+    FF_CODEC_ENCODE_CB(vc2_encode_frame),
     .p.priv_class   = &vc2enc_class,
     .defaults       = vc2enc_defaults,
     .p.pix_fmts     = allowed_pix_fmts
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index d062700259..4aed1eeafb 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -128,7 +128,7 @@ const FFCodec ff_vcr1_decoder = {
     .p.id           = AV_CODEC_ID_VCR1,
     .priv_data_size = sizeof(VCR1Context),
     .init           = vcr1_decode_init,
-    .decode         = vcr1_decode_frame,
+    FF_CODEC_DECODE_CB(vcr1_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index 61c24f9110..270496b7a7 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -2732,7 +2732,7 @@ const FFCodec ff_h264_videotoolbox_encoder = {
     .priv_data_size   = sizeof(VTEncContext),
     .p.pix_fmts       = avc_pix_fmts,
     .init             = vtenc_init,
-    .encode2          = vtenc_frame,
+    FF_CODEC_ENCODE_CB(vtenc_frame),
     .close            = vtenc_close,
     .p.priv_class     = &h264_videotoolbox_class,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
@@ -2767,7 +2767,7 @@ const FFCodec ff_hevc_videotoolbox_encoder = {
     .priv_data_size   = sizeof(VTEncContext),
     .p.pix_fmts       = hevc_pix_fmts,
     .init             = vtenc_init,
-    .encode2          = vtenc_frame,
+    FF_CODEC_ENCODE_CB(vtenc_frame),
     .close            = vtenc_close,
     .p.priv_class     = &hevc_videotoolbox_class,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
@@ -2806,7 +2806,7 @@ const FFCodec ff_prores_videotoolbox_encoder = {
     .priv_data_size   = sizeof(VTEncContext),
     .p.pix_fmts       = prores_pix_fmts,
     .init             = vtenc_init,
-    .encode2          = vtenc_frame,
+    FF_CODEC_ENCODE_CB(vtenc_frame),
     .close            = vtenc_close,
     .p.priv_class     = &prores_videotoolbox_class,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/vima.c b/libavcodec/vima.c
index e429855245..73276056c2 100644
--- a/libavcodec/vima.c
+++ b/libavcodec/vima.c
@@ -213,7 +213,7 @@ const FFCodec ff_adpcm_vima_decoder = {
     .p.type       = AVMEDIA_TYPE_AUDIO,
     .p.id         = AV_CODEC_ID_ADPCM_VIMA,
     .init         = decode_init,
-    .decode       = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/vmdaudio.c b/libavcodec/vmdaudio.c
index b81e5b0ced..2e6e358b64 100644
--- a/libavcodec/vmdaudio.c
+++ b/libavcodec/vmdaudio.c
@@ -235,7 +235,7 @@ const FFCodec ff_vmdaudio_decoder = {
     .p.id           = AV_CODEC_ID_VMDAUDIO,
     .priv_data_size = sizeof(VmdAudioContext),
     .init           = vmdaudio_decode_init,
-    .decode         = vmdaudio_decode_frame,
+    FF_CODEC_DECODE_CB(vmdaudio_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/vmdvideo.c b/libavcodec/vmdvideo.c
index fd48dc3255..947f09b73b 100644
--- a/libavcodec/vmdvideo.c
+++ b/libavcodec/vmdvideo.c
@@ -472,7 +472,7 @@ const FFCodec ff_vmdvideo_decoder = {
     .priv_data_size = sizeof(VmdVideoContext),
     .init           = vmdvideo_decode_init,
     .close          = vmdvideo_decode_end,
-    .decode         = vmdvideo_decode_frame,
+    FF_CODEC_DECODE_CB(vmdvideo_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index e7db38e85c..cc790984ad 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -581,7 +581,7 @@ const FFCodec ff_vmnc_decoder = {
     .priv_data_size = sizeof(VmncContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 433fbfc6f9..6ba0e1d811 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1892,7 +1892,7 @@ const FFCodec ff_vorbis_decoder = {
     .priv_data_size  = sizeof(vorbis_context),
     .init            = vorbis_decode_init,
     .close           = vorbis_decode_close,
-    .decode          = vorbis_decode_frame,
+    FF_CODEC_DECODE_CB(vorbis_decode_frame),
     .flush           = vorbis_decode_flush,
     .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index a6c5cfa8c7..0db8aeb2b5 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -1302,7 +1302,7 @@ const FFCodec ff_vorbis_encoder = {
     .p.id           = AV_CODEC_ID_VORBIS,
     .priv_data_size = sizeof(vorbis_enc_context),
     .init           = vorbis_encode_init,
-    .encode2        = vorbis_encode_frame,
+    FF_CODEC_ENCODE_CB(vorbis_encode_frame),
     .close          = vorbis_encode_close,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 528029203d..1a745331f4 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -3176,7 +3176,7 @@ const FFCodec ff_theora_decoder = {
     .priv_data_size        = sizeof(Vp3DecodeContext),
     .init                  = theora_decode_init,
     .close                 = vp3_decode_end,
-    .decode                = vp3_decode_frame,
+    FF_CODEC_DECODE_CB(vp3_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                              AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
@@ -3194,7 +3194,7 @@ const FFCodec ff_vp3_decoder = {
     .priv_data_size        = sizeof(Vp3DecodeContext),
     .init                  = vp3_decode_init,
     .close                 = vp3_decode_end,
-    .decode                = vp3_decode_frame,
+    FF_CODEC_DECODE_CB(vp3_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                              AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
@@ -3212,7 +3212,7 @@ const FFCodec ff_vp4_decoder = {
     .priv_data_size        = sizeof(Vp3DecodeContext),
     .init                  = vp3_decode_init,
     .close                 = vp3_decode_end,
-    .decode                = vp3_decode_frame,
+    FF_CODEC_DECODE_CB(vp3_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                              AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 167fda4bfc..7ec381b5e5 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -311,7 +311,7 @@ const FFCodec ff_vp5_decoder = {
     .priv_data_size = sizeof(VP56Context),
     .init           = vp5_decode_init,
     .close          = vp56_free,
-    .decode         = ff_vp56_decode_frame,
+    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index 313b499623..19dc754fee 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -720,7 +720,7 @@ const FFCodec ff_vp6_decoder = {
     .priv_data_size = sizeof(VP56Context),
     .init           = vp6_decode_init,
     .close          = vp6_decode_free,
-    .decode         = ff_vp56_decode_frame,
+    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
@@ -734,7 +734,7 @@ const FFCodec ff_vp6f_decoder = {
     .priv_data_size = sizeof(VP56Context),
     .init           = vp6_decode_init,
     .close          = vp6_decode_free,
-    .decode         = ff_vp56_decode_frame,
+    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
@@ -748,7 +748,7 @@ const FFCodec ff_vp6a_decoder = {
     .priv_data_size = 2 /* Main context + alpha context */ * sizeof(VP56Context),
     .init           = vp6_decode_init,
     .close          = vp6_decode_free,
-    .decode         = ff_vp56_decode_frame,
+    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index acb61ceede..f521f2c9de 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -2947,7 +2947,7 @@ const FFCodec ff_vp7_decoder = {
     .priv_data_size        = sizeof(VP8Context),
     .init                  = vp7_decode_init,
     .close                 = ff_vp8_decode_free,
-    .decode                = vp7_decode_frame,
+    FF_CODEC_DECODE_CB(vp7_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
     .flush                 = vp8_decode_flush,
@@ -2963,7 +2963,7 @@ const FFCodec ff_vp8_decoder = {
     .priv_data_size        = sizeof(VP8Context),
     .init                  = ff_vp8_decode_init,
     .close                 = ff_vp8_decode_free,
-    .decode                = ff_vp8_decode_frame,
+    FF_CODEC_DECODE_CB(ff_vp8_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
                              AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE |
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 8f2c52da87..fee79fb45b 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -1874,7 +1874,7 @@ const FFCodec ff_vp9_decoder = {
     .priv_data_size        = sizeof(VP9Context),
     .init                  = vp9_decode_init,
     .close                 = vp9_decode_free,
-    .decode                = vp9_decode_frame,
+    FF_CODEC_DECODE_CB(vp9_decode_frame),
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
                              FF_CODEC_CAP_SLICE_THREAD_HAS_MF |
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index e8555e2570..62f930ed94 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -854,7 +854,7 @@ const FFCodec ff_vqa_decoder = {
     .priv_data_size = sizeof(VqaContext),
     .init           = vqa_decode_init,
     .close          = vqa_decode_end,
-    .decode         = vqa_decode_frame,
+    FF_CODEC_DECODE_CB(vqa_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .defaults       = vqa_defaults,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 8bb03e5b4f..efd9e0fdd0 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1710,7 +1710,7 @@ const FFCodec ff_wavpack_decoder = {
     .priv_data_size = sizeof(WavpackContext),
     .init           = wavpack_decode_init,
     .close          = wavpack_decode_end,
-    .decode         = wavpack_decode_frame,
+    FF_CODEC_DECODE_CB(wavpack_decode_frame),
     .flush          = wavpack_decode_flush,
     .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c
index ac14d0c4f3..1f95768c09 100644
--- a/libavcodec/wavpackenc.c
+++ b/libavcodec/wavpackenc.c
@@ -2969,7 +2969,7 @@ const FFCodec ff_wavpack_encoder = {
     .priv_data_size = sizeof(WavPackEncodeContext),
     .p.priv_class   = &wavpack_encoder_class,
     .init           = wavpack_encode_init,
-    .encode2        = wavpack_encode_frame,
+    FF_CODEC_ENCODE_CB(wavpack_encode_frame),
     .close          = wavpack_encode_close,
     .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
     .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8P,
diff --git a/libavcodec/wcmv.c b/libavcodec/wcmv.c
index 8dfc1363a5..ac135f6859 100644
--- a/libavcodec/wcmv.c
+++ b/libavcodec/wcmv.c
@@ -248,7 +248,7 @@ const FFCodec ff_wcmv_decoder = {
     .priv_data_size   = sizeof(WCMVContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities   = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/webp.c b/libavcodec/webp.c
index a0b51ac1e7..1b5e943a6e 100644
--- a/libavcodec/webp.c
+++ b/libavcodec/webp.c
@@ -1562,7 +1562,7 @@ const FFCodec ff_webp_decoder = {
     .p.id           = AV_CODEC_ID_WEBP,
     .priv_data_size = sizeof(WebPContext),
     .init           = webp_decode_init,
-    .decode         = webp_decode_frame,
+    FF_CODEC_DECODE_CB(webp_decode_frame),
     .close          = webp_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/webvttdec.c b/libavcodec/webvttdec.c
index 8cb7fea070..0179fc26d2 100644
--- a/libavcodec/webvttdec.c
+++ b/libavcodec/webvttdec.c
@@ -103,7 +103,7 @@ const FFCodec ff_webvtt_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
     .p.type         = AVMEDIA_TYPE_SUBTITLE,
     .p.id           = AV_CODEC_ID_WEBVTT,
-    .decode_sub     = webvtt_decode_frame,
+    FF_CODEC_DECODE_SUB_CB(webvtt_decode_frame),
     .init           = ff_ass_subtitle_header_default,
     .flush          = ff_ass_decoder_flush,
     .priv_data_size = sizeof(FFASSDecoderContext),
diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c
index 7f514ed940..e433bb4579 100644
--- a/libavcodec/webvttenc.c
+++ b/libavcodec/webvttenc.c
@@ -218,7 +218,7 @@ const FFCodec ff_webvtt_encoder = {
     .p.id           = AV_CODEC_ID_WEBVTT,
     .priv_data_size = sizeof(WebVTTContext),
     .init           = webvtt_encode_init,
-    .encode_sub     = webvtt_encode_frame,
+    FF_CODEC_ENCODE_SUB_CB(webvtt_encode_frame),
     .close          = webvtt_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 945fd8c843..825bd6cdbb 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -1007,7 +1007,7 @@ const FFCodec ff_wmav1_decoder = {
     .priv_data_size = sizeof(WMACodecContext),
     .init           = wma_decode_init,
     .close          = ff_wma_end,
-    .decode         = wma_decode_superframe,
+    FF_CODEC_DECODE_CB(wma_decode_superframe),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
@@ -1024,7 +1024,7 @@ const FFCodec ff_wmav2_decoder = {
     .priv_data_size = sizeof(WMACodecContext),
     .init           = wma_decode_init,
     .close          = ff_wma_end,
-    .decode         = wma_decode_superframe,
+    FF_CODEC_DECODE_CB(wma_decode_superframe),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index fd1fb8ad97..28a7546eb5 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -440,7 +440,7 @@ const FFCodec ff_wmav1_encoder = {
     .p.id           = AV_CODEC_ID_WMAV1,
     .priv_data_size = sizeof(WMACodecContext),
     .init           = encode_init,
-    .encode2        = encode_superframe,
+    FF_CODEC_ENCODE_CB(encode_superframe),
     .close          = ff_wma_end,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
@@ -455,7 +455,7 @@ const FFCodec ff_wmav2_encoder = {
     .p.id           = AV_CODEC_ID_WMAV2,
     .priv_data_size = sizeof(WMACodecContext),
     .init           = encode_init,
-    .encode2        = encode_superframe,
+    FF_CODEC_ENCODE_CB(encode_superframe),
     .close          = ff_wma_end,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index daa775314d..9a8d6cc276 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -1336,7 +1336,7 @@ const FFCodec ff_wmalossless_decoder = {
     .priv_data_size = sizeof(WmallDecodeCtx),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_packet,
+    FF_CODEC_DECODE_CB(decode_packet),
     .flush          = flush,
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 245241aa50..9cf763acd4 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -2088,7 +2088,7 @@ const FFCodec ff_wmapro_decoder = {
     .priv_data_size = sizeof(WMAProDecodeCtx),
     .init           = wmapro_decode_init,
     .close          = wmapro_decode_end,
-    .decode         = wmapro_decode_packet,
+    FF_CODEC_DECODE_CB(wmapro_decode_packet),
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
     .flush          = wmapro_flush,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
@@ -2104,7 +2104,7 @@ const FFCodec ff_xma1_decoder = {
     .priv_data_size = sizeof(XMADecodeCtx),
     .init           = xma_decode_init,
     .close          = xma_decode_end,
-    .decode         = xma_decode_packet,
+    FF_CODEC_DECODE_CB(xma_decode_packet),
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
@@ -2119,7 +2119,7 @@ const FFCodec ff_xma2_decoder = {
     .priv_data_size = sizeof(XMADecodeCtx),
     .init           = xma_decode_init,
     .close          = xma_decode_end,
-    .decode         = xma_decode_packet,
+    FF_CODEC_DECODE_CB(xma_decode_packet),
     .flush          = xma_flush,
     .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index 571dd5803b..c52ab876b2 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -2006,7 +2006,7 @@ const FFCodec ff_wmavoice_decoder = {
     .priv_data_size   = sizeof(WMAVoiceContext),
     .init             = wmavoice_decode_init,
     .close            = wmavoice_decode_end,
-    .decode           = wmavoice_decode_packet,
+    FF_CODEC_DECODE_CB(wmavoice_decode_packet),
     .p.capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .flush            = wmavoice_flush,
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 249200bf23..bf0e609c0b 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -599,7 +599,7 @@ const FFCodec ff_wmv2_decoder = {
     .priv_data_size = sizeof(WMV2DecContext),
     .init           = wmv2_decode_init,
     .close          = wmv2_decode_end,
-    .decode         = ff_h263_decode_frame,
+    FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index a4d15e1d55..88211ac179 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -241,7 +241,7 @@ const FFCodec ff_wmv2_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .priv_data_size = sizeof(WMV2EncContext),
     .init           = wmv2_encode_init,
-    .encode2        = ff_mpv_encode_picture,
+    FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index 913b42a78f..0cf2181a48 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -138,7 +138,7 @@ const FFCodec ff_wnv1_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WNV1,
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c
index 6794dd2045..3af007d478 100644
--- a/libavcodec/wrapped_avframe.c
+++ b/libavcodec/wrapped_avframe.c
@@ -113,7 +113,7 @@ const FFCodec ff_wrapped_avframe_encoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket passthrough"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WRAPPED_AVFRAME,
-    .encode2        = wrapped_avframe_encode,
+    FF_CODEC_ENCODE_CB(wrapped_avframe_encode),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
 
@@ -122,6 +122,6 @@ const FFCodec ff_wrapped_avframe_decoder = {
     .p.long_name    = NULL_IF_CONFIG_SMALL("AVPacket to AVFrame passthrough"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WRAPPED_AVFRAME,
-    .decode         = wrapped_avframe_decode,
+    FF_CODEC_DECODE_CB(wrapped_avframe_decode),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c
index 00e4d91d4f..8d072297ee 100644
--- a/libavcodec/ws-snd1.c
+++ b/libavcodec/ws-snd1.c
@@ -176,7 +176,7 @@ const FFCodec ff_ws_snd1_decoder = {
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_WESTWOOD_SND1,
     .init           = ws_snd_decode_init,
-    .decode         = ws_snd_decode_frame,
+    FF_CODEC_DECODE_CB(ws_snd_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index e9f6c334a1..3386a702b1 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -642,7 +642,7 @@ const FFCodec ff_xan_wc3_decoder = {
     .priv_data_size = sizeof(XanContext),
     .init           = xan_decode_init,
     .close          = xan_decode_end,
-    .decode         = xan_decode_frame,
+    FF_CODEC_DECODE_CB(xan_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c
index bf9446195f..62ce46f3a7 100644
--- a/libavcodec/xbmdec.c
+++ b/libavcodec/xbmdec.c
@@ -143,5 +143,5 @@ const FFCodec ff_xbm_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_XBM,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode       = xbm_decode_frame,
+    FF_CODEC_DECODE_CB(xbm_decode_frame),
 };
diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c
index 95db87dba6..60fb169457 100644
--- a/libavcodec/xbmenc.c
+++ b/libavcodec/xbmenc.c
@@ -81,7 +81,7 @@ const FFCodec ff_xbm_encoder = {
     .p.long_name  = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_XBM,
-    .encode2      = xbm_encode_frame,
+    FF_CODEC_ENCODE_CB(xbm_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE,
                                                    AV_PIX_FMT_NONE },
 };
diff --git a/libavcodec/xfacedec.c b/libavcodec/xfacedec.c
index 0542a36a5d..b103b5beda 100644
--- a/libavcodec/xfacedec.c
+++ b/libavcodec/xfacedec.c
@@ -182,7 +182,7 @@ const FFCodec ff_xface_decoder = {
     .p.id           = AV_CODEC_ID_XFACE,
     .priv_data_size = sizeof(XFaceContext),
     .init           = xface_decode_init,
-    .decode         = xface_decode_frame,
+    FF_CODEC_DECODE_CB(xface_decode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/xfaceenc.c b/libavcodec/xfaceenc.c
index c1beb002cf..a46b7133e7 100644
--- a/libavcodec/xfaceenc.c
+++ b/libavcodec/xfaceenc.c
@@ -219,5 +219,5 @@ const FFCodec ff_xface_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE },
     .priv_data_size = sizeof(XFaceContext),
-    .encode2        = xface_encode_frame,
+    FF_CODEC_ENCODE_CB(xface_encode_frame),
 };
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index d414bcf95d..d2037b9f09 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -132,7 +132,7 @@ const FFCodec ff_xl_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_VIXL,
     .init         = decode_init,
-    .decode       = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c
index 468175fc4b..26d076d2e8 100644
--- a/libavcodec/xpmdec.c
+++ b/libavcodec/xpmdec.c
@@ -444,5 +444,5 @@ const FFCodec ff_xpm_decoder = {
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(XPMDecContext),
     .close          = xpm_decode_close,
-    .decode         = xpm_decode_frame,
+    FF_CODEC_DECODE_CB(xpm_decode_frame),
 };
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index c2c1b920cc..f22c5cf3b3 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -160,6 +160,6 @@ const FFCodec ff_xsub_decoder = {
     .p.type    = AVMEDIA_TYPE_SUBTITLE,
     .p.id      = AV_CODEC_ID_XSUB,
     .init      = decode_init,
-    .decode_sub = decode_frame,
+    FF_CODEC_DECODE_SUB_CB(decode_frame),
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index 9069a96437..8ca411e5af 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -217,6 +217,6 @@ const FFCodec ff_xsub_encoder = {
     .p.type     = AVMEDIA_TYPE_SUBTITLE,
     .p.id       = AV_CODEC_ID_XSUB,
     .init       = xsub_encoder_init,
-    .encode_sub = xsub_encode,
+    FF_CODEC_ENCODE_SUB_CB(xsub_encode),
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c
index 650a0bf774..f8afab598d 100644
--- a/libavcodec/xwddec.c
+++ b/libavcodec/xwddec.c
@@ -253,5 +253,5 @@ const FFCodec ff_xwd_decoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_XWD,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .decode         = xwd_decode_frame,
+    FF_CODEC_DECODE_CB(xwd_decode_frame),
 };
diff --git a/libavcodec/xwdenc.c b/libavcodec/xwdenc.c
index 0bfe5a2970..0c6dfc6569 100644
--- a/libavcodec/xwdenc.c
+++ b/libavcodec/xwdenc.c
@@ -220,7 +220,7 @@ const FFCodec ff_xwd_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_XWD,
     .p.capabilities = AV_CODEC_CAP_DR1,
-    .encode2      = xwd_encode_frame,
+    FF_CODEC_ENCODE_CB(xwd_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA,
                                                  AV_PIX_FMT_RGBA,
                                                  AV_PIX_FMT_ARGB,
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 9a79e58d8a..d73bd46284 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -441,7 +441,7 @@ const FFCodec ff_xan_wc4_decoder = {
     .priv_data_size = sizeof(XanContext),
     .init           = xan_decode_init,
     .close          = xan_decode_end,
-    .decode         = xan_decode_frame,
+    FF_CODEC_DECODE_CB(xan_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/y41pdec.c b/libavcodec/y41pdec.c
index 663a1cc910..ca81dda0e8 100644
--- a/libavcodec/y41pdec.c
+++ b/libavcodec/y41pdec.c
@@ -87,7 +87,7 @@ const FFCodec ff_y41p_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_Y41P,
     .init         = y41p_decode_init,
-    .decode       = y41p_decode_frame,
+    FF_CODEC_DECODE_CB(y41p_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c
index 0522de6613..390bd10ba1 100644
--- a/libavcodec/y41penc.c
+++ b/libavcodec/y41penc.c
@@ -84,7 +84,7 @@ const FFCodec ff_y41p_encoder = {
     .p.id         = AV_CODEC_ID_Y41P,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .init         = y41p_encode_init,
-    .encode2      = y41p_encode_frame,
+    FF_CODEC_ENCODE_CB(y41p_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
                                                  AV_PIX_FMT_NONE },
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
diff --git a/libavcodec/ylc.c b/libavcodec/ylc.c
index 9b19405b24..94d0388f31 100644
--- a/libavcodec/ylc.c
+++ b/libavcodec/ylc.c
@@ -457,7 +457,7 @@ const FFCodec ff_ylc_decoder = {
     .priv_data_size = sizeof(YLCContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index 3079af061f..5befbb072e 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -274,6 +274,6 @@ const FFCodec ff_yop_decoder = {
     .priv_data_size = sizeof(YopDecContext),
     .init           = yop_decode_init,
     .close          = yop_decode_close,
-    .decode         = yop_decode_frame,
+    FF_CODEC_DECODE_CB(yop_decode_frame),
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/yuv4dec.c b/libavcodec/yuv4dec.c
index 3c6d6eda6e..bbd213e698 100644
--- a/libavcodec/yuv4dec.c
+++ b/libavcodec/yuv4dec.c
@@ -79,7 +79,7 @@ const FFCodec ff_yuv4_decoder = {
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_YUV4,
     .init         = yuv4_decode_init,
-    .decode       = yuv4_decode_frame,
+    FF_CODEC_DECODE_CB(yuv4_decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/yuv4enc.c b/libavcodec/yuv4enc.c
index 3a4d36f40c..8d72382197 100644
--- a/libavcodec/yuv4enc.c
+++ b/libavcodec/yuv4enc.c
@@ -66,5 +66,5 @@ const FFCodec ff_yuv4_encoder = {
     .p.id           = AV_CODEC_ID_YUV4,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .encode2      = yuv4_encode_frame,
+    FF_CODEC_ENCODE_CB(yuv4_encode_frame),
 };
diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c
index b4d189cd7a..08511ca152 100644
--- a/libavcodec/zerocodec.c
+++ b/libavcodec/zerocodec.c
@@ -140,7 +140,7 @@ const FFCodec ff_zerocodec_decoder = {
     .p.id           = AV_CODEC_ID_ZEROCODEC,
     .priv_data_size = sizeof(ZeroCodecContext),
     .init           = zerocodec_decode_init,
-    .decode         = zerocodec_decode_frame,
+    FF_CODEC_DECODE_CB(zerocodec_decode_frame),
     .flush          = zerocodec_decode_flush,
     .close          = zerocodec_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index 4a845a333d..37c18e3a14 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -653,7 +653,7 @@ const FFCodec ff_zmbv_decoder = {
     .priv_data_size = sizeof(ZmbvContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index 89814de800..ef21a189a6 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -418,7 +418,7 @@ const FFCodec ff_zmbv_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(ZmbvEncContext),
     .init           = encode_init,
-    .encode2        = encode_frame,
+    FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_end,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_PAL8,
                                                      AV_PIX_FMT_RGB555LE,
