From 6408dfb58ffd0f06f85ce0e3b2366675cf9e9539 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 23:35:01 +0100
Subject: [PATCH 30/77] avcodec/mpegvideo_enc: Use function ptr for
 encode_picture_header

This gets rid of a switch and (in case of FMT_H263) several
ifs.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/flvenc.c        |  5 +++-
 libavcodec/flvenc.h        |  5 ++--
 libavcodec/h261enc.c       |  8 ++++--
 libavcodec/h261enc.h       |  1 -
 libavcodec/h263enc.h       |  3 +-
 libavcodec/ituh263enc.c    | 13 +++++++--
 libavcodec/mjpegenc.c      | 12 +++++---
 libavcodec/mjpegenc.h      |  1 -
 libavcodec/mpeg12enc.c     |  6 +++-
 libavcodec/mpeg12enc.h     |  3 +-
 libavcodec/mpeg4videoenc.c |  7 +++--
 libavcodec/mpeg4videoenc.h |  4 +--
 libavcodec/mpegvideo_enc.c | 58 ++++++++------------------------------
 libavcodec/mpegvideoenc.h  |  2 ++
 libavcodec/msmpeg4enc.c    | 40 +++++++++++++++-----------
 libavcodec/msmpeg4enc.h    |  3 +-
 libavcodec/rv10enc.c       |  3 +-
 libavcodec/rv10enc.h       |  6 ++--
 libavcodec/rv20enc.c       |  6 +++-
 libavcodec/speedhqenc.c    | 12 ++++++--
 libavcodec/speedhqenc.h    |  1 -
 libavcodec/wmv2enc.c       |  6 ++--
 libavcodec/wmv2enc.h       |  1 -
 23 files changed, 107 insertions(+), 99 deletions(-)

diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index 0cd20f026d..b4a30fe558 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -23,8 +23,9 @@
 #include "mpegvideo.h"
 #include "mpegvideoenc.h"
 
-void ff_flv_encode_picture_header(MpegEncContext *s)
+int ff_flv_encode_picture_header(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int format;
 
     align_put_bits(&s->pb);
@@ -61,6 +62,8 @@ void ff_flv_encode_picture_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 1);   /* DeblockingFlag: on */
     put_bits(&s->pb, 5, s->qscale);   /* Quantizer */
     put_bits(&s->pb, 1, 0);   /* ExtraInformation */
+
+    return 0;
 }
 
 void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level,
diff --git a/libavcodec/flvenc.h b/libavcodec/flvenc.h
index 1ecbb46b17..3dc7480376 100644
--- a/libavcodec/flvenc.h
+++ b/libavcodec/flvenc.h
@@ -21,10 +21,11 @@
 #ifndef AVCODEC_FLVENC_H
 #define AVCODEC_FLVENC_H
 
-#include "mpegvideo.h"
 #include "put_bits.h"
 
-void ff_flv_encode_picture_header(MpegEncContext *s);
+typedef struct MPVMainEncContext MPVMainEncContext;
+
+int ff_flv_encode_picture_header(MPVMainEncContext *const m);
 void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run,
                            int last);
 
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 36c50db6df..bfe805bcdf 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -66,9 +66,10 @@ typedef struct H261EncContext {
     } format;
 } H261EncContext;
 
-void ff_h261_encode_picture_header(MpegEncContext *s)
+static int h261_encode_picture_header(MPVMainEncContext *const m)
 {
-    H261EncContext *const h = (H261EncContext *)s;
+    H261EncContext *const h = (H261EncContext *)m;
+    MpegEncContext *const s = &h->s.s;
     int temp_ref;
 
     align_put_bits(&s->pb);
@@ -94,6 +95,8 @@ void ff_h261_encode_picture_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 0); /* no PEI */
     h->gob_number = h->format - 1;
     s->mb_skip_run = 0;
+
+    return 0;
 }
 
 /**
@@ -370,6 +373,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
     s->private_ctx = &h->common;
+    h->s.encode_picture_header = h261_encode_picture_header;
 
     s->min_qcoeff       = -127;
     s->max_qcoeff       = 127;
diff --git a/libavcodec/h261enc.h b/libavcodec/h261enc.h
index 7877d8aa9d..092363b6f3 100644
--- a/libavcodec/h261enc.h
+++ b/libavcodec/h261enc.h
@@ -33,6 +33,5 @@
 void ff_h261_reorder_mb_index(MpegEncContext *s);
 void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
                        int motion_x, int motion_y);
-void ff_h261_encode_picture_header(MpegEncContext *s);
 
 #endif
diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index 71e30931aa..29a785dfeb 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -26,8 +26,7 @@
 
 const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1];
 
-void ff_h263_encode_init(MpegEncContext *s);
-void ff_h263_encode_picture_header(MpegEncContext *s);
+void ff_h263_encode_init(MPVMainEncContext *m);
 void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
 void ff_h263_encode_mb(MpegEncContext *s,
                        int16_t block[6][64],
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 825b398455..c82e0ceffd 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -221,8 +221,9 @@ av_const int ff_h263_aspect_to_info(AVRational aspect){
     return FF_ASPECT_EXTENDED;
 }
 
-void ff_h263_encode_picture_header(MpegEncContext * s)
+static int h263_encode_picture_header(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref;
     int best_clock_code=1;
     int best_divisor=60;
@@ -354,6 +355,8 @@ void ff_h263_encode_picture_header(MpegEncContext * s)
 
         put_bits(&s->pb, 1, 1);
     }
+
+    return 0;
 }
 
 /**
@@ -819,8 +822,10 @@ void ff_h263_update_mb(MpegEncContext *s)
     ff_h263_update_motion_val(s);
 }
 
-av_cold void ff_h263_encode_init(MpegEncContext *s)
+av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
+
     s->me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
 
     s->intra_ac_vlc_length     =s->inter_ac_vlc_length     = uni_h263_inter_rl_len;
@@ -854,6 +859,7 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         break;
         // Note for MPEG-4 & H.263 the dc-scale table will be set per frame as needed later
     case AV_CODEC_ID_FLV1:
+        m->encode_picture_header = ff_flv_encode_picture_header;
         if (s->h263_flv > 1) {
             s->min_qcoeff= -1023;
             s->max_qcoeff=  1023;
@@ -866,6 +872,9 @@ av_cold void ff_h263_encode_init(MpegEncContext *s)
         s->min_qcoeff= -127;
         s->max_qcoeff=  127;
     }
+    // H.263, H.263+; will be overwritten for MSMPEG-4 later
+    if (!m->encode_picture_header)
+        m->encode_picture_header = h263_encode_picture_header;
 
     ff_h263dsp_init(&s->h263dsp);
 }
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index a77a703f53..7706f52148 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -104,13 +104,16 @@ static void mjpeg_encode_picture_header(MpegEncContext *s)
         s->thread_context[i]->esc_pos = 0;
 }
 
-void ff_mjpeg_amv_encode_picture_header(MpegEncContext *s)
+static int mjpeg_amv_encode_picture_header(MPVMainEncContext *const m)
 {
-    MJPEGEncContext *const m = (MJPEGEncContext*)s;
-    av_assert2(s->mjpeg_ctx == &m->mjpeg);
+    MJPEGEncContext *const m2 = (MJPEGEncContext*)m;
+    MpegEncContext *const s = &m->s;
+    av_assert2(s->mjpeg_ctx == &m2->mjpeg);
     /* s->huffman == HUFFMAN_TABLE_OPTIMAL can only be true for MJPEG. */
-    if (!CONFIG_MJPEG_ENCODER || m->mjpeg.huffman != HUFFMAN_TABLE_OPTIMAL)
+    if (!CONFIG_MJPEG_ENCODER || m2->mjpeg.huffman != HUFFMAN_TABLE_OPTIMAL)
         mjpeg_encode_picture_header(s);
+
+    return 0;
 }
 
 #if CONFIG_MJPEG_ENCODER
@@ -309,6 +312,7 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
     int ret;
 
     s->mjpeg_ctx = m;
+    m2->mpeg.encode_picture_header = mjpeg_amv_encode_picture_header;
 
     if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
         // Used to produce garbage with MJPEG.
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index 2c98de057a..9610656aaa 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -94,7 +94,6 @@ static inline void put_marker(PutBitContext *p, enum JpegMarker code)
 
 typedef struct MpegEncContext MpegEncContext;
 
-void ff_mjpeg_amv_encode_picture_header(MpegEncContext *s);
 void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 int  ff_mjpeg_encode_stuffing(MpegEncContext *s);
 
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index ed2c63086f..f28a41f5ff 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -333,7 +333,7 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 0);
 }
 
-void ff_mpeg1_encode_picture_header(MPVMainEncContext *const m)
+static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
 {
     MPEG12EncContext *const mpeg12 = (MPEG12EncContext*)m;
     MpegEncContext *const s = &m->s;
@@ -485,6 +485,8 @@ void ff_mpeg1_encode_picture_header(MPVMainEncContext *const m)
 
     s->mb_y = 0;
     ff_mpeg1_encode_slice_header(s);
+
+    return 0;
 }
 
 static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
@@ -1108,6 +1110,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    m->encode_picture_header = mpeg1_encode_picture_header;
+
     s->me.mv_penalty = mv_penalty;
     s->fcode_tab     = fcode_tab + MAX_MV;
     if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
diff --git a/libavcodec/mpeg12enc.h b/libavcodec/mpeg12enc.h
index fa1504177a..6c3709bbff 100644
--- a/libavcodec/mpeg12enc.h
+++ b/libavcodec/mpeg12enc.h
@@ -24,10 +24,9 @@
 
 #include <stdint.h>
 
-#include "mpegvideoenc.h"
+#include "mpegvideo.h"
 #include "mpegvideodata.h"
 
-void ff_mpeg1_encode_picture_header(MPVMainEncContext *m);
 void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64],
                         int motion_x, int motion_y);
 void ff_mpeg1_encode_slice_header(MpegEncContext *s);
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index c265316ed6..f34ea1fcb4 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1062,7 +1062,7 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
 }
 
 /* write MPEG-4 VOP header */
-int ff_mpeg4_encode_picture_header(MPVMainEncContext *const m)
+static int mpeg4_encode_picture_header(MPVMainEncContext *const m)
 {
     Mpeg4EncContext *const m4 = mainctx_to_mpeg4(m);
     MpegEncContext *const s = &m->s;
@@ -1291,7 +1291,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
     Mpeg4EncContext *const m4 = avctx->priv_data;
-    MpegEncContext  *const  s = &m4->m.s;
+    MPVMainEncContext *const m = &m4->m;
+    MpegEncContext  *const  s = &m->s;
     int ret;
 
     if (avctx->width >= (1<<13) || avctx->height >= (1<<13)) {
@@ -1299,6 +1300,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
+    m->encode_picture_header = mpeg4_encode_picture_header;
+
     ff_qpeldsp_init(&s->qdsp);
     if ((ret = ff_mpv_encode_init(avctx)) < 0)
         return ret;
diff --git a/libavcodec/mpeg4videoenc.h b/libavcodec/mpeg4videoenc.h
index 1c53ce4ede..4565a518b2 100644
--- a/libavcodec/mpeg4videoenc.h
+++ b/libavcodec/mpeg4videoenc.h
@@ -25,14 +25,14 @@
 
 #include <stdint.h>
 
-#include "mpegvideoenc.h"
 #include "put_bits.h"
 
+typedef struct MpegEncContext MpegEncContext;
+
 void ff_mpeg4_encode_mb(MpegEncContext *s,
                         int16_t block[6][64],
                         int motion_x, int motion_y);
 void ff_set_mpeg4_time(MpegEncContext *s);
-int ff_mpeg4_encode_picture_header(MPVMainEncContext *m);
 
 void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
 void ff_mpeg4_stuffing(PutBitContext *pbc);
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index d4f4f825ff..03a8ae2687 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -66,7 +66,6 @@
 #include "qpeldsp.h"
 #include "faandct.h"
 #include "aandcttab.h"
-#include "flvenc.h"
 #include "mpeg4video.h"
 #include "mpeg4videodata.h"
 #include "mpeg4videoenc.h"
@@ -809,12 +808,17 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         avctx->delay = 0;
         s->low_delay = 1;
         break;
+#if CONFIG_RV10_ENCODER
     case AV_CODEC_ID_RV10:
+        m->encode_picture_header = ff_rv10_encode_picture_header;
         s->out_format = FMT_H263;
         avctx->delay  = 0;
         s->low_delay  = 1;
         break;
+#endif
+#if CONFIG_RV20_ENCODER
     case AV_CODEC_ID_RV20:
+        m->encode_picture_header = ff_rv20_encode_picture_header;
         s->out_format      = FMT_H263;
         avctx->delay       = 0;
         s->low_delay       = 1;
@@ -824,6 +828,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->loop_filter     = 1;
         s->unrestricted_mv = 0;
         break;
+#endif
     case AV_CODEC_ID_MPEG4:
         s->out_format      = FMT_H263;
         s->h263_pred       = 1;
@@ -996,10 +1001,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     }
 
     if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) {
-        ff_h263_encode_init(s);
+        ff_h263_encode_init(m);
 #if CONFIG_MSMPEG4ENC
         if (s->msmpeg4_version != MSMP4_UNUSED)
-            ff_msmpeg4_encode_init(s);
+            ff_msmpeg4_encode_init(m);
 #endif
     }
 
@@ -3888,50 +3893,9 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 
     s->mb_x = s->mb_y = 0;
     s->last_bits= put_bits_count(&s->pb);
-    switch(s->out_format) {
-#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
-    case FMT_MJPEG:
-        ff_mjpeg_amv_encode_picture_header(s);
-        break;
-#endif
-    case FMT_SPEEDHQ:
-        if (CONFIG_SPEEDHQ_ENCODER)
-            ff_speedhq_encode_picture_header(s);
-        break;
-    case FMT_H261:
-        if (CONFIG_H261_ENCODER)
-            ff_h261_encode_picture_header(s);
-        break;
-    case FMT_H263:
-        if (CONFIG_WMV2_ENCODER && s->codec_id == AV_CODEC_ID_WMV2)
-            ff_wmv2_encode_picture_header(s);
-#if CONFIG_MSMPEG4ENC
-        else if (s->msmpeg4_version != MSMP4_UNUSED)
-            ff_msmpeg4_encode_picture_header(s);
-#endif
-        else if (CONFIG_MPEG4_ENCODER && s->h263_pred) {
-            ret = ff_mpeg4_encode_picture_header(m);
-            if (ret < 0)
-                return ret;
-        } else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) {
-            ret = ff_rv10_encode_picture_header(s);
-            if (ret < 0)
-                return ret;
-        }
-        else if (CONFIG_RV20_ENCODER && s->codec_id == AV_CODEC_ID_RV20)
-            ff_rv20_encode_picture_header(s);
-        else if (CONFIG_FLV_ENCODER && s->codec_id == AV_CODEC_ID_FLV1)
-            ff_flv_encode_picture_header(s);
-        else if (CONFIG_H263_ENCODER)
-            ff_h263_encode_picture_header(s);
-        break;
-    case FMT_MPEG1:
-        if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
-            ff_mpeg1_encode_picture_header(m);
-        break;
-    default:
-        av_assert0(0);
-    }
+    ret = m->encode_picture_header(m);
+    if (ret < 0)
+        return ret;
     bits= put_bits_count(&s->pb);
     m->header_bits = bits - s->last_bits;
 
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 9c70fe6d71..cd82b16590 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -74,6 +74,8 @@ typedef struct MPVMainEncContext {
     int frame_skip_cmp;
     me_cmp_func frame_skip_cmp_fn;
 
+    int (*encode_picture_header)(struct MPVMainEncContext *m);
+
     /* bit rate control */
     int64_t total_bits;
     int frame_bits;                ///< bits used for the current frame
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 98b72e4d58..01d5707370 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -135,20 +135,6 @@ static av_cold void msmpeg4_encode_init_static(void)
     }
 }
 
-av_cold void ff_msmpeg4_encode_init(MpegEncContext *s)
-{
-    static AVOnce init_static_once = AV_ONCE_INIT;
-
-    ff_msmpeg4_common_init(s);
-    if (s->msmpeg4_version >= MSMP4_WMV1) {
-        s->min_qcoeff = -255;
-        s->max_qcoeff =  255;
-    }
-
-    /* init various encoding tables */
-    ff_thread_once(&init_static_once, msmpeg4_encode_init_static);
-}
-
 static void find_best_tables(MSMPEG4EncContext *ms)
 {
     MpegEncContext *const s = &ms->m.s;
@@ -215,9 +201,10 @@ static void find_best_tables(MSMPEG4EncContext *ms)
 }
 
 /* write MSMPEG4 compatible frame header */
-void ff_msmpeg4_encode_picture_header(MpegEncContext * s)
+static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
 {
-    MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)s;
+    MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)m;
+    MpegEncContext *const s = &m->s;
 
     find_best_tables(ms);
 
@@ -275,6 +262,8 @@ void ff_msmpeg4_encode_picture_header(MpegEncContext * s)
 
     s->esc3_level_length= 0;
     s->esc3_run_length= 0;
+
+    return 0;
 }
 
 void ff_msmpeg4_encode_ext_header(MpegEncContext * s)
@@ -674,6 +663,25 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
     }
 }
 
+av_cold void ff_msmpeg4_encode_init(MPVMainEncContext *const m)
+{
+    MpegEncContext *const s = &m->s;
+    static AVOnce init_static_once = AV_ONCE_INIT;
+
+    ff_msmpeg4_common_init(s);
+
+    if (s->msmpeg4_version <= MSMP4_WMV1)
+        m->encode_picture_header = msmpeg4_encode_picture_header;
+
+    if (s->msmpeg4_version >= MSMP4_WMV1) {
+        s->min_qcoeff = -255;
+        s->max_qcoeff =  255;
+    }
+
+    /* init various encoding tables */
+    ff_thread_once(&init_static_once, msmpeg4_encode_init_static);
+}
+
 const FFCodec ff_msmpeg4v2_encoder = {
     .p.name         = "msmpeg4v2",
     CODEC_LONG_NAME("MPEG-4 part 2 Microsoft variant version 2"),
diff --git a/libavcodec/msmpeg4enc.h b/libavcodec/msmpeg4enc.h
index 72992176de..5511e01283 100644
--- a/libavcodec/msmpeg4enc.h
+++ b/libavcodec/msmpeg4enc.h
@@ -33,8 +33,7 @@ typedef struct MSMPEG4EncContext {
     unsigned ac_stats[2][2][MAX_LEVEL + 1][MAX_RUN + 1][2];
 } MSMPEG4EncContext;
 
-void ff_msmpeg4_encode_init(MpegEncContext *s);
-void ff_msmpeg4_encode_picture_header(MpegEncContext *s);
+void ff_msmpeg4_encode_init(MPVMainEncContext *m);
 void ff_msmpeg4_encode_ext_header(MpegEncContext *s);
 void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
                           int motion_x, int motion_y);
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index d55fa7c2b0..0b5065212d 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -31,8 +31,9 @@
 #include "put_bits.h"
 #include "rv10enc.h"
 
-int ff_rv10_encode_picture_header(MpegEncContext *s)
+int ff_rv10_encode_picture_header(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int full_frame= 0;
 
     align_put_bits(&s->pb);
diff --git a/libavcodec/rv10enc.h b/libavcodec/rv10enc.h
index fc3665e839..5aa7250e87 100644
--- a/libavcodec/rv10enc.h
+++ b/libavcodec/rv10enc.h
@@ -21,9 +21,9 @@
 #ifndef AVCODEC_RV10ENC_H
 #define AVCODEC_RV10ENC_H
 
-#include "mpegvideo.h"
+typedef struct MPVMainEncContext MPVMainEncContext;
 
-int ff_rv10_encode_picture_header(MpegEncContext *s);
-void ff_rv20_encode_picture_header(MpegEncContext *s);
+int ff_rv10_encode_picture_header(MPVMainEncContext *m);
+int ff_rv20_encode_picture_header(MPVMainEncContext *m);
 
 #endif /* AVCODEC_RV10ENC_H */
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index cacda6fdda..1a59fd4c70 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -34,7 +34,10 @@
 #include "put_bits.h"
 #include "rv10enc.h"
 
-void ff_rv20_encode_picture_header(MpegEncContext *s) {
+int ff_rv20_encode_picture_header(MPVMainEncContext *const m)
+{
+    MpegEncContext *const s = &m->s;
+
     put_bits(&s->pb, 2, s->pict_type); //I 0 vs. 1 ?
     put_bits(&s->pb, 1, 0);     /* unknown bit */
     put_bits(&s->pb, 5, s->qscale);
@@ -60,6 +63,7 @@ void ff_rv20_encode_picture_header(MpegEncContext *s) {
         s->y_dc_scale_table=
         s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
     }
+    return 0;
 }
 
 const FFCodec ff_rv20_encoder = {
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index daccd0c3bf..1ba5dcc68f 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -95,9 +95,10 @@ static av_cold void speedhq_init_static_data(void)
                              ff_speedhq_vlc_table, uni_speedhq_ac_vlc_len);
 }
 
-void ff_speedhq_encode_picture_header(MpegEncContext *s)
+static int speedhq_encode_picture_header(MPVMainEncContext *const m)
 {
-    SpeedHQEncContext *ctx = (SpeedHQEncContext*)s;
+    SpeedHQEncContext *const ctx = (SpeedHQEncContext*)m;
+    MpegEncContext *const s = &m->s;
 
     put_bits_le(&s->pb, 8, 100 - s->qscale * 2);  /* FIXME why doubled */
     put_bits_le(&s->pb, 24, 4);  /* no second field */
@@ -105,6 +106,8 @@ void ff_speedhq_encode_picture_header(MpegEncContext *s)
     ctx->slice_start = 4;
     /* length of first slice, will be filled out later */
     put_bits_le(&s->pb, 24, 0);
+
+    return 0;
 }
 
 void ff_speedhq_end_slice(MpegEncContext *s)
@@ -230,7 +233,8 @@ void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64])
 static av_cold int speedhq_encode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
-    MpegEncContext *const s = avctx->priv_data;
+    MPVMainEncContext *const m = avctx->priv_data;
+    MpegEncContext *const s = &m->s;
     int ret;
 
     if (avctx->width > 65500 || avctx->height > 65500) {
@@ -258,6 +262,8 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
         av_assert0(0);
     }
 
+    m->encode_picture_header = speedhq_encode_picture_header;
+
     s->min_qcoeff = -2048;
     s->max_qcoeff = 2047;
 
diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index 66ef7ee023..b0e6662279 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -36,7 +36,6 @@
 void ff_speedhq_encode_close(MpegEncContext *s);
 void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 
-void ff_speedhq_encode_picture_header(MpegEncContext *s);
 void ff_speedhq_end_slice(MpegEncContext *s);
 
 static inline int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 55fcc91484..d70a680fb3 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -73,9 +73,10 @@ static int encode_ext_header(WMV2EncContext *w)
     return 0;
 }
 
-int ff_wmv2_encode_picture_header(MpegEncContext *s)
+static int wmv2_encode_picture_header(MPVMainEncContext *const m)
 {
-    WMV2EncContext *const w = (WMV2EncContext *) s;
+    WMV2EncContext *const w = (WMV2EncContext *) m;
+    MpegEncContext *const s = &m->s;
 
     put_bits(&s->pb, 1, s->pict_type - 1);
     if (s->pict_type == AV_PICTURE_TYPE_I)
@@ -222,6 +223,7 @@ static av_cold int wmv2_encode_init(AVCodecContext *avctx)
     MpegEncContext *const s = &w->msmpeg4.m.s;
     int ret;
 
+    w->msmpeg4.m.encode_picture_header = wmv2_encode_picture_header;
     s->private_ctx = &w->common;
     ret = ff_mpv_encode_init(avctx);
     if (ret < 0)
diff --git a/libavcodec/wmv2enc.h b/libavcodec/wmv2enc.h
index 263265acf3..59046c6a07 100644
--- a/libavcodec/wmv2enc.h
+++ b/libavcodec/wmv2enc.h
@@ -23,7 +23,6 @@
 
 #include "mpegvideo.h"
 
-int ff_wmv2_encode_picture_header(MpegEncContext * s);
 void ff_wmv2_encode_mb(MpegEncContext * s, int16_t block[6][64],
                        int motion_x, int motion_y);
 
-- 
2.45.2