Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 01/77] avcodec/mpegvideo(_enc)?: Mark init, close functions as, av_cold
@ 2025-03-19 21:18 Andreas Rheinhardt
  2025-03-19 21:20 ` Andreas Rheinhardt
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-19 21:18 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 277 bytes --]

First part of a patchset; the second part will be sent separately
because the complete set crosses the ML thresholds ("Message body is too
big: 1731572 bytes with a limit of 1000 KB"). A complete branch can be
found here: https://github.com/mkver/FFmpeg/tree/mpvenc

- Andreas

[-- Attachment #2: 0001-avcodec-mpegvideo-_enc-Mark-init-close-functions-as-.patch --]
[-- Type: text/x-patch, Size: 3909 bytes --]

From b232c37e21e7a8759546f821e198ef83cf548a2f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 04:58:27 +0100
Subject: [PATCH 01/77] avcodec/mpegvideo(_enc)?: Mark init, close functions as
 av_cold

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.c     | 16 ++++++++--------
 libavcodec/mpegvideo_enc.c |  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index f114dd8c0c..4b69b5b65c 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -349,7 +349,7 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
 #endif
 }
 
-static int init_duplicate_context(MpegEncContext *s)
+static av_cold int init_duplicate_context(MpegEncContext *s)
 {
     if (s->encoding) {
         s->me.map = av_mallocz(2 * ME_MAP_SIZE * sizeof(*s->me.map));
@@ -383,7 +383,7 @@ static int init_duplicate_context(MpegEncContext *s)
     return 0;
 }
 
-int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
+av_cold int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
 {
     int nb_slices = s->slice_context_count, ret;
 
@@ -407,7 +407,7 @@ int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
     return init_duplicate_context(s);
 }
 
-static void free_duplicate_context(MpegEncContext *s)
+static av_cold void free_duplicate_context(MpegEncContext *s)
 {
     if (!s)
         return;
@@ -426,7 +426,7 @@ static void free_duplicate_context(MpegEncContext *s)
     s->block = NULL;
 }
 
-static void free_duplicate_contexts(MpegEncContext *s)
+static av_cold void free_duplicate_contexts(MpegEncContext *s)
 {
     for (int i = 1; i < s->slice_context_count; i++) {
         free_duplicate_context(s->thread_context[i]);
@@ -497,7 +497,7 @@ av_cold void ff_mpv_common_defaults(MpegEncContext *s)
     s->slice_context_count   = 1;
 }
 
-static void free_buffer_pools(BufferPoolContext *pools)
+static av_cold void free_buffer_pools(BufferPoolContext *pools)
 {
     av_refstruct_pool_uninit(&pools->mbskip_table_pool);
     av_refstruct_pool_uninit(&pools->qscale_table_pool);
@@ -507,7 +507,7 @@ static void free_buffer_pools(BufferPoolContext *pools)
     pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0;
 }
 
-int ff_mpv_init_context_frame(MpegEncContext *s)
+av_cold int ff_mpv_init_context_frame(MpegEncContext *s)
 {
     BufferPoolContext *const pools = &s->buffer_pools;
     int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
@@ -744,7 +744,7 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
     return ret;
 }
 
-void ff_mpv_free_context_frame(MpegEncContext *s)
+av_cold void ff_mpv_free_context_frame(MpegEncContext *s)
 {
     free_duplicate_contexts(s);
 
@@ -769,7 +769,7 @@ void ff_mpv_free_context_frame(MpegEncContext *s)
     s->linesize = s->uvlinesize = 0;
 }
 
-void ff_mpv_common_end(MpegEncContext *s)
+av_cold void ff_mpv_common_end(MpegEncContext *s)
 {
     ff_mpv_free_context_frame(s);
     if (s->slice_context_count > 1)
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 493a3edde6..720ded49c2 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -268,7 +268,7 @@ static void update_duplicate_context_after_me(MpegEncContext *dst,
 #undef COPY
 }
 
-static void mpv_encode_init_static(void)
+static av_cold void mpv_encode_init_static(void)
 {
    for (int i = -16; i < 16; i++)
         default_fcode_tab[i + MAX_MV] = 1;
@@ -278,7 +278,7 @@ static void mpv_encode_init_static(void)
  * Set the given MpegEncContext to defaults for encoding.
  * the changed fields will not depend upon the prior state of the MpegEncContext.
  */
-static void mpv_encode_defaults(MpegEncContext *s)
+static av_cold void mpv_encode_defaults(MpegEncContext *s)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
 
-- 
2.45.2


[-- Attachment #3: 0002-avcodec-mpegvideoenc-Add-MPVMainEncContext.patch --]
[-- Type: text/x-patch, Size: 8939 bytes --]

From 05f52331882ac51b589bde5bb710d51219453a5f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Feb 2025 18:56:15 +0100
Subject: [PATCH 02/77] avcodec/mpegvideoenc: Add MPVMainEncContext

This is in preparation for moving all the elements from
MpegEncContext that are only used by the main encoder thread
to MPVMainEncContext.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/flvenc.c        | 2 +-
 libavcodec/h261enc.c       | 4 ++--
 libavcodec/ituh263enc.c    | 4 ++--
 libavcodec/mjpegenc.c      | 2 +-
 libavcodec/mpeg12enc.c     | 4 ++--
 libavcodec/mpeg4videoenc.c | 2 +-
 libavcodec/mpegvideoenc.h  | 4 ++++
 libavcodec/msmpeg4enc.c    | 2 +-
 libavcodec/msmpeg4enc.h    | 4 ++--
 libavcodec/rv10enc.c       | 2 +-
 libavcodec/rv20enc.c       | 2 +-
 libavcodec/speedhqenc.c    | 2 +-
 libavcodec/wmv2enc.c       | 4 ++--
 13 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index b6f9d1c6db..0cd20f026d 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -89,7 +89,7 @@ const FFCodec ff_flv_encoder = {
     .p.id           = AV_CODEC_ID_FLV1,
     .p.priv_class   = &ff_mpv_enc_class,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MPVMainEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 36436ee60f..264efb0aa3 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -55,7 +55,7 @@ static uint8_t uni_h261_rl_len_last[64 * 128];
 static uint8_t h261_mv_codes[64][2];
 
 typedef struct H261EncContext {
-    MpegEncContext s;
+    MPVMainEncContext s;
 
     H261Context common;
 
@@ -167,7 +167,7 @@ static inline int get_cbp(MpegEncContext *s, int16_t block[6][64])
  */
 static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
 {
-    MpegEncContext *const s = &h->s;
+    MpegEncContext *const s = &h->s.s;
     int level, run, i, j, last_index, last_non_zero;
 
     if (s->mb_intra) {
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index a81bfb7c79..825b398455 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -908,7 +908,7 @@ const FFCodec ff_h263_encoder = {
     .p.priv_class   = &h263_class,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MPVMainEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
@@ -941,7 +941,7 @@ const FFCodec ff_h263p_encoder = {
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
                       AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MPVMainEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 30f2c9900d..0a2d6eebd3 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -64,7 +64,7 @@ typedef struct MJpegHuffmanCode {
  * MpegEncContext is followed by a MjpegContext; the other threads
  * can access this shared context via MpegEncContext.mjpeg. */
 typedef struct MJPEGEncContext {
-    MpegEncContext mpeg;
+    MPVMainEncContext mpeg;
     MJpegContext   mjpeg;
 } MJPEGEncContext;
 
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 1563cefd23..bb61b4f4fe 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -72,7 +72,7 @@ static uint32_t mpeg1_lum_dc_uni[512];
 static uint32_t mpeg1_chr_dc_uni[512];
 
 typedef struct MPEG12EncContext {
-    MpegEncContext mpeg;
+    MPVMainEncContext mpeg;
     AVRational frame_rate_ext;
     unsigned frame_rate_index;
 
@@ -201,7 +201,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
-    if (mpeg12->mpeg.q_scale_type == 1) {
+    if (mpeg12->mpeg.s.q_scale_type == 1) {
         if (avctx->qmax > 28) {
             av_log(avctx, AV_LOG_ERROR,
                    "non linear quant only supports qmax <= 28 currently\n");
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 3b312915b4..11872f29eb 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1395,7 +1395,7 @@ const FFCodec ff_mpeg4_encoder = {
     CODEC_LONG_NAME("MPEG-4 part 2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MPEG4,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MPVMainEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 6dd382a3c6..f7aad17650 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -33,6 +33,10 @@
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
 
+typedef struct MPVMainEncContext {
+    MpegEncContext s;  ///< The main slicecontext
+} MPVMainEncContext;
+
 #define MAX_FCODE        7
 #define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
 #define INPLACE_OFFSET 16
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 8310e0a578..98b72e4d58 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -151,7 +151,7 @@ av_cold void ff_msmpeg4_encode_init(MpegEncContext *s)
 
 static void find_best_tables(MSMPEG4EncContext *ms)
 {
-    MpegEncContext *const s = &ms->s;
+    MpegEncContext *const s = &ms->m.s;
     int i;
     int best        = 0, best_size        = INT_MAX;
     int chroma_best = 0, best_chroma_size = INT_MAX;
diff --git a/libavcodec/msmpeg4enc.h b/libavcodec/msmpeg4enc.h
index da9a45b589..72992176de 100644
--- a/libavcodec/msmpeg4enc.h
+++ b/libavcodec/msmpeg4enc.h
@@ -22,12 +22,12 @@
 #ifndef AVCODEC_MSMPEG4ENC_H
 #define AVCODEC_MSMPEG4ENC_H
 
-#include "mpegvideo.h"
+#include "mpegvideoenc.h"
 #include "put_bits.h"
 #include "rl.h"
 
 typedef struct MSMPEG4EncContext {
-    MpegEncContext s;
+    MPVMainEncContext m;
 
     /** [mb_intra][isChroma][level][run][last] */
     unsigned ac_stats[2][2][MAX_LEVEL + 1][MAX_RUN + 1][2];
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index 53463dd068..d55fa7c2b0 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -72,7 +72,7 @@ const FFCodec ff_rv10_encoder = {
     .p.id           = AV_CODEC_ID_RV10,
     .p.priv_class   = &ff_mpv_enc_class,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MPVMainEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index cf27ff04ea..cacda6fdda 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -69,7 +69,7 @@ const FFCodec ff_rv20_encoder = {
     .p.id           = AV_CODEC_ID_RV20,
     .p.priv_class   = &ff_mpv_enc_class,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MPVMainEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 536ddc0bf1..a0baa869cc 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -59,7 +59,7 @@ static uint32_t speedhq_chr_dc_uni[512];
 static uint8_t uni_speedhq_ac_vlc_len[64 * 64 * 2];
 
 typedef struct SpeedHQEncContext {
-    MpegEncContext m;
+    MPVMainEncContext m;
 
     int slice_start;
 } SpeedHQEncContext;
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 825ab91a05..33569a6d39 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -49,7 +49,7 @@ typedef struct WMV2EncContext {
 
 static int encode_ext_header(WMV2EncContext *w)
 {
-    MpegEncContext *const s = &w->msmpeg4.s;
+    MpegEncContext *const s = &w->msmpeg4.m.s;
     PutBitContext pb;
     int code;
 
@@ -76,7 +76,7 @@ static int encode_ext_header(WMV2EncContext *w)
 static av_cold int wmv2_encode_init(AVCodecContext *avctx)
 {
     WMV2EncContext *const w = avctx->priv_data;
-    MpegEncContext *const s = &w->msmpeg4.s;
+    MpegEncContext *const s = &w->msmpeg4.m.s;
 
     s->private_ctx = &w->common;
     if (ff_mpv_encode_init(avctx) < 0)
-- 
2.45.2


[-- Attachment #4: 0003-avcodec-mpegvideoenc-Move-tmp-bframes-to-MPVMainEncC.patch --]
[-- Type: text/x-patch, Size: 16445 bytes --]

From 92dd0825800227c364fb2e5b0d7f9d23ddde6662 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Jan 2022 20:24:18 +0100
Subject: [PATCH 03/77] avcodec/mpegvideoenc: Move tmp bframes to
 MPVMainEncContext

Also move b_frame_strategy and b_sensitivity and brd_scale;
they are all only used by an encoder's main thread when
b_frame_strategy == 2.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |   8 ---
 libavcodec/mpegvideo_enc.c | 114 ++++++++++++++++++++-----------------
 libavcodec/mpegvideoenc.h  |  15 ++++-
 3 files changed, 73 insertions(+), 64 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index afd18591c4..1091c93d95 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -48,8 +48,6 @@
 
 #define MAX_THREADS 32
 
-#define MAX_B_FRAMES 16
-
 /**
  * Scantable.
  */
@@ -446,7 +444,6 @@ typedef struct MpegEncContext {
     int top_field_first;
     int concealment_motion_vectors;
     int q_scale_type;
-    int brd_scale;
     int intra_vlc_format;
     int alternate_scan;
     int repeat_first_field;
@@ -518,11 +515,6 @@ typedef struct MpegEncContext {
 
     int error_rate;
 
-    /* temporary frames used by b_frame_strategy = 2 */
-    AVFrame *tmp_frames[MAX_B_FRAMES + 2];
-    int b_frame_strategy;
-    int b_sensitivity;
-
     /* frame skip options for encoding */
     int frame_skip_threshold;
     int frame_skip_factor;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 720ded49c2..ffa9484669 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -419,7 +419,8 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
 /* init video encoder */
 av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 {
-    MpegEncContext *s = avctx->priv_data;
+    MPVMainEncContext *const m = avctx->priv_data;
+    MpegEncContext    *const s = &m->s;
     AVCPBProperties *cpb_props;
     int i, ret;
     int mb_array_size, mv_table_size;
@@ -456,10 +457,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     }
     s->gop_size     = avctx->gop_size;
     s->avctx        = avctx;
-    if (avctx->max_b_frames > MAX_B_FRAMES) {
+    if (avctx->max_b_frames > MPVENC_MAX_B_FRAMES) {
         av_log(avctx, AV_LOG_ERROR, "Too many B-frames requested, maximum "
-               "is %d.\n", MAX_B_FRAMES);
-        avctx->max_b_frames = MAX_B_FRAMES;
+               "is " AV_STRINGIFY(MPVENC_MAX_B_FRAMES) ".\n");
+        avctx->max_b_frames = MPVENC_MAX_B_FRAMES;
     } else if (avctx->max_b_frames < 0) {
         av_log(avctx, AV_LOG_ERROR,
                "max b frames must be 0 or positive for mpegvideo based encoders\n");
@@ -700,10 +701,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    if (s->b_frame_strategy && (avctx->flags & AV_CODEC_FLAG_PASS2)) {
+    if (m->b_frame_strategy && (avctx->flags & AV_CODEC_FLAG_PASS2)) {
         av_log(avctx, AV_LOG_INFO,
                "notice: b_frame_strategy only affects the first pass\n");
-        s->b_frame_strategy = 0;
+        m->b_frame_strategy = 0;
     }
 
     i = av_gcd(avctx->time_base.den, avctx->time_base.num);
@@ -914,8 +915,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return ret;
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MAX_B_FRAMES + 1) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) ||
+        !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MPVENC_MAX_B_FRAMES + 1) ||
+        !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MPVENC_MAX_B_FRAMES + 1) ||
         !(s->new_pic = av_frame_alloc()) ||
         !(s->picture_pool = ff_mpv_alloc_pic_pool(0)))
         return AVERROR(ENOMEM);
@@ -1010,17 +1011,17 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     if ((ret = ff_rate_control_init(s)) < 0)
         return ret;
 
-    if (s->b_frame_strategy == 2) {
+    if (m->b_frame_strategy == 2) {
         for (i = 0; i < s->max_b_frames + 2; i++) {
-            s->tmp_frames[i] = av_frame_alloc();
-            if (!s->tmp_frames[i])
+            m->tmp_frames[i] = av_frame_alloc();
+            if (!m->tmp_frames[i])
                 return AVERROR(ENOMEM);
 
-            s->tmp_frames[i]->format = AV_PIX_FMT_YUV420P;
-            s->tmp_frames[i]->width  = s->width  >> s->brd_scale;
-            s->tmp_frames[i]->height = s->height >> s->brd_scale;
+            m->tmp_frames[i]->format = AV_PIX_FMT_YUV420P;
+            m->tmp_frames[i]->width  = s->width  >> m->brd_scale;
+            m->tmp_frames[i]->height = s->height >> m->brd_scale;
 
-            ret = av_frame_get_buffer(s->tmp_frames[i], 0);
+            ret = av_frame_get_buffer(m->tmp_frames[i], 0);
             if (ret < 0)
                 return ret;
         }
@@ -1039,8 +1040,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
 av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
 {
-    MpegEncContext *s = avctx->priv_data;
-    int i;
+    MPVMainEncContext *const m = avctx->priv_data;
+    MpegEncContext    *const s = &m->s;
 
     ff_rate_control_uninit(&s->rc_context);
 
@@ -1048,13 +1049,13 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_refstruct_pool_uninit(&s->picture_pool);
 
     if (s->input_picture && s->reordered_input_picture) {
-        for (int i = 0; i < MAX_B_FRAMES + 1; i++) {
+        for (int i = 0; i < MPVENC_MAX_B_FRAMES + 1; i++) {
             av_refstruct_unref(&s->input_picture[i]);
             av_refstruct_unref(&s->reordered_input_picture[i]);
         }
     }
-    for (i = 0; i < FF_ARRAY_ELEMS(s->tmp_frames); i++)
-        av_frame_free(&s->tmp_frames[i]);
+    for (int i = 0; i < FF_ARRAY_ELEMS(m->tmp_frames); i++)
+        av_frame_free(&m->tmp_frames[i]);
 
     av_frame_free(&s->new_pic);
 
@@ -1249,8 +1250,9 @@ static int prepare_picture(MpegEncContext *s, AVFrame *f, const AVFrame *props_f
     return 0;
 }
 
-static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
+static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg)
 {
+    MpegEncContext *const s = &m->s;
     MPVPicture *pic = NULL;
     int64_t pts;
     int display_picture_number = 0, ret;
@@ -1376,9 +1378,9 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
     }
 
     /* shift buffer entries */
-    for (int i = flush_offset; i <= MAX_B_FRAMES; i++)
+    for (int i = flush_offset; i <= MPVENC_MAX_B_FRAMES; i++)
         s->input_picture[i - flush_offset] = s->input_picture[i];
-    for (int i = MAX_B_FRAMES + 1 - flush_offset; i <= MAX_B_FRAMES; i++)
+    for (int i = MPVENC_MAX_B_FRAMES + 1 - flush_offset; i <= MPVENC_MAX_B_FRAMES; i++)
         s->input_picture[i] = NULL;
 
     s->input_picture[encoding_delay] = pic;
@@ -1451,10 +1453,11 @@ static int encode_frame(AVCodecContext *c, const AVFrame *frame, AVPacket *pkt)
     return size;
 }
 
-static int estimate_best_b_count(MpegEncContext *s)
+static int estimate_best_b_count(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     AVPacket *pkt;
-    const int scale = s->brd_scale;
+    const int scale = m->brd_scale;
     int width  = s->width  >> scale;
     int height = s->height >> scale;
     int i, j, out_size, p_lambda, b_lambda, lambda2;
@@ -1491,18 +1494,18 @@ static int estimate_best_b_count(MpegEncContext *s)
                 data[2] += INPLACE_OFFSET;
             }
 
-            s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[0],
-                                       s->tmp_frames[i]->linesize[0],
+            s->mpvencdsp.shrink[scale](m->tmp_frames[i]->data[0],
+                                       m->tmp_frames[i]->linesize[0],
                                        data[0],
                                        pre_input_ptr->f->linesize[0],
                                        width, height);
-            s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[1],
-                                       s->tmp_frames[i]->linesize[1],
+            s->mpvencdsp.shrink[scale](m->tmp_frames[i]->data[1],
+                                       m->tmp_frames[i]->linesize[1],
                                        data[1],
                                        pre_input_ptr->f->linesize[1],
                                        width >> 1, height >> 1);
-            s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[2],
-                                       s->tmp_frames[i]->linesize[2],
+            s->mpvencdsp.shrink[scale](m->tmp_frames[i]->data[2],
+                                       m->tmp_frames[i]->linesize[2],
                                        data[2],
                                        pre_input_ptr->f->linesize[2],
                                        width >> 1, height >> 1);
@@ -1539,10 +1542,10 @@ static int estimate_best_b_count(MpegEncContext *s)
             goto fail;
 
 
-        s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I;
-        s->tmp_frames[0]->quality   = 1 * FF_QP2LAMBDA;
+        m->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I;
+        m->tmp_frames[0]->quality   = 1 * FF_QP2LAMBDA;
 
-        out_size = encode_frame(c, s->tmp_frames[0], pkt);
+        out_size = encode_frame(c, m->tmp_frames[0], pkt);
         if (out_size < 0) {
             ret = out_size;
             goto fail;
@@ -1553,11 +1556,11 @@ static int estimate_best_b_count(MpegEncContext *s)
         for (i = 0; i < s->max_b_frames + 1; i++) {
             int is_p = i % (j + 1) == j || i == s->max_b_frames;
 
-            s->tmp_frames[i + 1]->pict_type = is_p ?
+            m->tmp_frames[i + 1]->pict_type = is_p ?
                                      AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
-            s->tmp_frames[i + 1]->quality   = is_p ? p_lambda : b_lambda;
+            m->tmp_frames[i + 1]->quality   = is_p ? p_lambda : b_lambda;
 
-            out_size = encode_frame(c, s->tmp_frames[i + 1], pkt);
+            out_size = encode_frame(c, m->tmp_frames[i + 1], pkt);
             if (out_size < 0) {
                 ret = out_size;
                 goto fail;
@@ -1603,8 +1606,10 @@ fail:
  * input_picture[0] is always NULL when exiting this function, even on error;
  * reordered_input_picture[0] is always NULL when exiting this function on error.
  */
-static int set_bframe_chain_length(MpegEncContext *s)
+static int set_bframe_chain_length(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
+
     /* Either nothing to do or can't do anything */
     if (s->reordered_input_picture[0] || !s->input_picture[0])
         return 0;
@@ -1649,11 +1654,11 @@ static int set_bframe_chain_length(MpegEncContext *s)
             }
         }
 
-        if (s->b_frame_strategy == 0) {
+        if (m->b_frame_strategy == 0) {
             b_frames = s->max_b_frames;
             while (b_frames && !s->input_picture[b_frames])
                 b_frames--;
-        } else if (s->b_frame_strategy == 1) {
+        } else if (m->b_frame_strategy == 1) {
             int i;
             for (i = 1; i < s->max_b_frames + 1; i++) {
                 if (s->input_picture[i] &&
@@ -1668,7 +1673,7 @@ static int set_bframe_chain_length(MpegEncContext *s)
             for (i = 0; i < s->max_b_frames + 1; i++) {
                 if (!s->input_picture[i] ||
                     s->input_picture[i]->b_frame_score - 1 >
-                        s->mb_num / s->b_sensitivity)
+                        s->mb_num / m->b_sensitivity)
                     break;
             }
 
@@ -1678,8 +1683,8 @@ static int set_bframe_chain_length(MpegEncContext *s)
             for (i = 0; i < b_frames + 1; i++) {
                 s->input_picture[i]->b_frame_score = 0;
             }
-        } else if (s->b_frame_strategy == 2) {
-            b_frames = estimate_best_b_count(s);
+        } else if (m->b_frame_strategy == 2) {
+            b_frames = estimate_best_b_count(m);
             if (b_frames < 0) {
                 av_refstruct_unref(&s->input_picture[0]);
                 return b_frames;
@@ -1733,17 +1738,18 @@ static int set_bframe_chain_length(MpegEncContext *s)
     return 0;
 }
 
-static int select_input_picture(MpegEncContext *s)
+static int select_input_picture(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int ret;
 
     av_assert1(!s->reordered_input_picture[0]);
 
-    for (int i = 1; i <= MAX_B_FRAMES; i++)
+    for (int i = 1; i <= MPVENC_MAX_B_FRAMES; i++)
         s->reordered_input_picture[i - 1] = s->reordered_input_picture[i];
-    s->reordered_input_picture[MAX_B_FRAMES] = NULL;
+    s->reordered_input_picture[MPVENC_MAX_B_FRAMES] = NULL;
 
-    ret = set_bframe_chain_length(s);
+    ret = set_bframe_chain_length(m);
     av_assert1(!s->input_picture[0]);
     if (ret < 0)
         return ret;
@@ -1867,7 +1873,8 @@ static void frame_start(MpegEncContext *s)
 int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
                           const AVFrame *pic_arg, int *got_packet)
 {
-    MpegEncContext *s = avctx->priv_data;
+    MPVMainEncContext *const m = avctx->priv_data;
+    MpegEncContext    *const s = &m->s;
     int stuffing_count, ret;
     int context_count = s->slice_context_count;
 
@@ -1877,12 +1884,13 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
     s->picture_in_gop_number++;
 
-    if (load_input_picture(s, pic_arg) < 0)
-        return -1;
+    ret = load_input_picture(m, pic_arg);
+    if (ret < 0)
+        return ret;
 
-    if (select_input_picture(s) < 0) {
-        return -1;
-    }
+    ret = select_input_picture(m);
+    if (ret < 0)
+        return ret;
 
     /* output? */
     if (s->new_pic->data[0]) {
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index f7aad17650..7b5635e50e 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -33,8 +33,16 @@
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
 
+#define MPVENC_MAX_B_FRAMES 16
+
 typedef struct MPVMainEncContext {
     MpegEncContext s;  ///< The main slicecontext
+
+    /// temporary frames used by b_frame_strategy = 2
+    AVFrame *tmp_frames[MPVENC_MAX_B_FRAMES + 2];
+    int b_frame_strategy;
+    int b_sensitivity;
+    int brd_scale;
 } MPVMainEncContext;
 
 #define MAX_FCODE        7
@@ -85,6 +93,7 @@ typedef struct MPVMainEncContext {
 { "msad",   "Sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }
 
 #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
+#define FF_MPV_MAIN_OFFSET(x) offsetof(MPVMainEncContext, x)
 #define FF_RC_OFFSET(x)  offsetof(MpegEncContext, rc_context.x)
 #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
 #define FF_MPV_COMMON_OPTS \
@@ -126,9 +135,9 @@ FF_MPV_OPT_CMP_FUNC, \
 {"ps", "RTP payload size in bytes",                             FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 
 #define FF_MPV_COMMON_BFRAME_OPTS \
-{"b_strategy", "Strategy to choose between I/P/B-frames",      FF_MPV_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS }, \
-{"b_sensitivity", "Adjust sensitivity of b_frame_strategy 1",  FF_MPV_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS }, \
-{"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS },
+{"b_strategy", "Strategy to choose between I/P/B-frames",      FF_MPV_MAIN_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS }, \
+{"b_sensitivity", "Adjust sensitivity of b_frame_strategy 1",  FF_MPV_MAIN_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_MAIN_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS },
 
 #define FF_MPV_COMMON_MOTION_EST_OPTS \
 {"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
-- 
2.45.2


[-- Attachment #5: 0004-avcodec-mpegvideoenc-Move-ratecontrol-to-MPVMainEncC.patch --]
[-- Type: text/x-patch, Size: 34411 bytes --]

From 0bbf4604f747b894efcd7adfd2149edbfb58d97f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 28 Jan 2022 20:43:54 +0100
Subject: [PATCH 04/77] avcodec/mpegvideoenc: Move ratecontrol to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  8 ----
 libavcodec/mpegvideo_enc.c | 73 ++++++++++++++++++---------------
 libavcodec/mpegvideoenc.h  | 10 ++++-
 libavcodec/ratecontrol.c   | 75 +++++++++++++++++++---------------
 libavcodec/ratecontrol.h   | 12 +++---
 libavcodec/snowenc.c       | 82 ++++++++++++++++++++------------------
 6 files changed, 140 insertions(+), 120 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 1091c93d95..75b1fff245 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -42,7 +42,6 @@
 #include "mpegvideoencdsp.h"
 #include "pixblockdsp.h"
 #include "put_bits.h"
-#include "ratecontrol.h"
 #include "qpeldsp.h"
 #include "videodsp.h"
 
@@ -327,13 +326,6 @@ typedef struct MpegEncContext {
     int dct_count[2];
     uint16_t (*dct_offset)[64];
 
-    /* bit rate control */
-    int64_t total_bits;
-    int frame_bits;                ///< bits used for the current frame
-    int stuffing_bits;             ///< bits used for stuffing
-    int next_lambda;               ///< next lambda used for retrying to encode a frame
-    RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
-
     /* statistics, used for 2-pass encoding */
     int mv_bits;
     int header_bits;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index ffa9484669..7f24c1baa6 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -84,7 +84,7 @@
 #define QMAT_SHIFT_MMX 16
 #define QMAT_SHIFT 21
 
-static int encode_picture(MpegEncContext *s, const AVPacket *pkt);
+static int encode_picture(MPVMainEncContext *const s, const AVPacket *pkt);
 static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale);
 static int sse_mb(MpegEncContext *s);
 static void denoise_dct_c(MpegEncContext *s, int16_t *block);
@@ -1008,7 +1008,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 #endif
     }
 
-    if ((ret = ff_rate_control_init(s)) < 0)
+    ret = ff_rate_control_init(m);
+    if (ret < 0)
         return ret;
 
     if (m->b_frame_strategy == 2) {
@@ -1043,7 +1044,7 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     MPVMainEncContext *const m = avctx->priv_data;
     MpegEncContext    *const s = &m->s;
 
-    ff_rate_control_uninit(&s->rc_context);
+    ff_rate_control_uninit(&m->rc_context);
 
     ff_mpv_common_end(s);
     av_refstruct_pool_uninit(&s->picture_pool);
@@ -1622,7 +1623,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
             // FIXME check that the gop check above is +-1 correct
             av_refstruct_unref(&s->input_picture[0]);
 
-            ff_vbv_update(s, 0);
+            ff_vbv_update(m, 0);
 
             return 0;
         }
@@ -1642,15 +1643,15 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
             for (int i = 0; i < s->max_b_frames + 1; i++) {
                 int pict_num = s->input_picture[0]->display_picture_number + i;
 
-                if (pict_num >= s->rc_context.num_entries)
+                if (pict_num >= m->rc_context.num_entries)
                     break;
                 if (!s->input_picture[i]) {
-                    s->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P;
+                    m->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P;
                     break;
                 }
 
                 s->input_picture[i]->f->pict_type =
-                    s->rc_context.entry[pict_num].new_pict_type;
+                    m->rc_context.entry[pict_num].new_pict_type;
             }
         }
 
@@ -1918,7 +1919,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
         //emms_c();
         frame_start(s);
 vbv_retry:
-        ret = encode_picture(s, pkt);
+        ret = encode_picture(m, pkt);
         if (growing_buffer) {
             av_assert0(s->pb.buf == avctx->internal->byte_buffer);
             pkt->data = s->pb.buf;
@@ -1933,14 +1934,14 @@ vbv_retry:
             ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
 
         if (avctx->rc_buffer_size) {
-            RateControlContext *rcc = &s->rc_context;
+            RateControlContext *rcc = &m->rc_context;
             int max_size = FFMAX(rcc->buffer_index * avctx->rc_max_available_vbv_use, rcc->buffer_index - 500);
             int hq = (avctx->mb_decision == FF_MB_DECISION_RD || avctx->trellis);
             int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139;
 
             if (put_bits_count(&s->pb) > max_size &&
                 s->lambda < s->lmax) {
-                s->next_lambda = FFMAX(s->lambda + min_step, s->lambda *
+                m->next_lambda = FFMAX(s->lambda + min_step, s->lambda *
                                        (s->qscale + 1) / s->qscale);
                 if (s->adaptive_quant) {
                     int i;
@@ -1968,7 +1969,7 @@ vbv_retry:
         }
 
         if (avctx->flags & AV_CODEC_FLAG_PASS1)
-            ff_write_pass1_stats(s);
+            ff_write_pass1_stats(m);
 
         for (int i = 0; i < MPV_MAX_PLANES; i++)
             avctx->error[i] += s->encoding_error[i];
@@ -1982,10 +1983,10 @@ vbv_retry:
                                              s->misc_bits + s->i_tex_bits +
                                              s->p_tex_bits);
         flush_put_bits(&s->pb);
-        s->frame_bits  = put_bits_count(&s->pb);
+        m->frame_bits  = put_bits_count(&s->pb);
 
-        stuffing_count = ff_vbv_update(s, s->frame_bits);
-        s->stuffing_bits = 8*stuffing_count;
+        stuffing_count = ff_vbv_update(m, m->frame_bits);
+        m->stuffing_bits = 8*stuffing_count;
         if (stuffing_count) {
             if (put_bytes_left(&s->pb, 0) < stuffing_count + 50) {
                 av_log(avctx, AV_LOG_ERROR, "stuffing too large\n");
@@ -2009,10 +2010,10 @@ vbv_retry:
             break;
             default:
                 av_log(avctx, AV_LOG_ERROR, "vbv buffer overflow\n");
-                s->stuffing_bits = 0;
+                m->stuffing_bits = 0;
             }
             flush_put_bits(&s->pb);
-            s->frame_bits  = put_bits_count(&s->pb);
+            m->frame_bits  = put_bits_count(&s->pb);
         }
 
         /* update MPEG-1/2 vbv_delay for CBR */
@@ -2027,9 +2028,9 @@ vbv_retry:
             int vbv_delay, min_delay;
             double inbits  = avctx->rc_max_rate *
                              av_q2d(avctx->time_base);
-            int    minbits = s->frame_bits - 8 *
+            int    minbits = m->frame_bits - 8 *
                              (s->vbv_delay_pos - 1);
-            double bits    = s->rc_context.buffer_index + minbits - inbits;
+            double bits    = m->rc_context.buffer_index + minbits - inbits;
             uint8_t *const vbv_delay_ptr = s->pb.buf + s->vbv_delay_pos;
 
             if (bits < 0)
@@ -2064,7 +2065,7 @@ vbv_retry:
                 return ret;
             }
         }
-        s->total_bits     += s->frame_bits;
+        m->total_bits += m->frame_bits;
 
         pkt->pts = s->cur_pic.ptr->f->pts;
         pkt->duration = s->cur_pic.ptr->f->duration;
@@ -2089,14 +2090,14 @@ vbv_retry:
         if (s->mb_info)
             av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);
     } else {
-        s->frame_bits = 0;
+        m->frame_bits = 0;
     }
 
     ff_mpv_unref_picture(&s->cur_pic);
 
-    av_assert1((s->frame_bits & 7) == 0);
+    av_assert1((m->frame_bits & 7) == 0);
 
-    pkt->size = s->frame_bits / 8;
+    pkt->size = m->frame_bits / 8;
     *got_packet = !!pkt->size;
     return 0;
 }
@@ -3611,12 +3612,15 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
     flush_put_bits(&dst->pb);
 }
 
-static int estimate_qp(MpegEncContext *s, int dry_run){
-    if (s->next_lambda){
-        s->cur_pic.ptr->f->quality = s->next_lambda;
-        if(!dry_run) s->next_lambda= 0;
+static int estimate_qp(MPVMainEncContext *const m, int dry_run)
+{
+    MpegEncContext *const s = &m->s;
+
+    if (m->next_lambda){
+        s->cur_pic.ptr->f->quality = m->next_lambda;
+        if(!dry_run) m->next_lambda= 0;
     } else if (!s->fixed_qscale) {
-        int quality = ff_rate_estimate_qscale(s, dry_run);
+        int quality = ff_rate_estimate_qscale(m, dry_run);
         s->cur_pic.ptr->f->quality = quality;
         if (s->cur_pic.ptr->f->quality < 0)
             return -1;
@@ -3661,8 +3665,9 @@ static void set_frame_distances(MpegEncContext * s){
     }
 }
 
-static int encode_picture(MpegEncContext *s, const AVPacket *pkt)
+static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 {
+    MpegEncContext *const s = &m->s;
     int i, ret;
     int bits;
     int context_count = s->slice_context_count;
@@ -3689,9 +3694,10 @@ static int encode_picture(MpegEncContext *s, const AVPacket *pkt)
     }
 
     if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
-        if (estimate_qp(s,1) < 0)
-            return -1;
-        ff_get_2pass_fcode(s);
+        ret = estimate_qp(m, 1);
+        if (ret < 0)
+            return ret;
+        ff_get_2pass_fcode(m);
     } else if (!(s->avctx->flags & AV_CODEC_FLAG_QSCALE)) {
         if(s->pict_type==AV_PICTURE_TYPE_B)
             s->lambda= s->last_lambda_for[s->pict_type];
@@ -3814,8 +3820,9 @@ static int encode_picture(MpegEncContext *s, const AVPacket *pkt)
         }
     }
 
-    if (estimate_qp(s, 0) < 0)
-        return -1;
+    ret = estimate_qp(m, 0);
+    if (ret < 0)
+        return ret;
 
     if (s->qscale < 3 && s->max_qcoeff <= 128 &&
         s->pict_type == AV_PICTURE_TYPE_I &&
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 7b5635e50e..c1d2821038 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -32,6 +32,7 @@
 
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
+#include "ratecontrol.h"
 
 #define MPVENC_MAX_B_FRAMES 16
 
@@ -43,6 +44,13 @@ typedef struct MPVMainEncContext {
     int b_frame_strategy;
     int b_sensitivity;
     int brd_scale;
+
+    /* bit rate control */
+    int64_t total_bits;
+    int frame_bits;                ///< bits used for the current frame
+    int stuffing_bits;             ///< bits used for stuffing
+    int next_lambda;               ///< next lambda used for retrying to encode a frame
+    RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
 } MPVMainEncContext;
 
 #define MAX_FCODE        7
@@ -94,7 +102,7 @@ typedef struct MPVMainEncContext {
 
 #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
 #define FF_MPV_MAIN_OFFSET(x) offsetof(MPVMainEncContext, x)
-#define FF_RC_OFFSET(x)  offsetof(MpegEncContext, rc_context.x)
+#define FF_RC_OFFSET(x)  offsetof(MPVMainEncContext, rc_context.x)
 #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
 #define FF_MPV_COMMON_OPTS \
 FF_MPV_OPT_CMP_FUNC, \
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index f5e0b70a9a..ebc3a30fc1 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -35,8 +35,9 @@
 #include "mpegvideoenc.h"
 #include "libavutil/eval.h"
 
-void ff_write_pass1_stats(MpegEncContext *s)
+void ff_write_pass1_stats(MPVMainEncContext *const m)
 {
+    const MpegEncContext *const s = &m->s;
     snprintf(s->avctx->stats_out, 256,
              "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d "
              "fcode:%d bcode:%d mc-var:%"PRId64" var:%"PRId64" icount:%d hbits:%d;\n",
@@ -101,9 +102,10 @@ static double bits2qp_cb(void *rce, double qp)
     return bits2qp(rce, qp);
 }
 
-static double get_diff_limited_q(MpegEncContext *s, const RateControlEntry *rce, double q)
+static double get_diff_limited_q(MPVMainEncContext *m, const RateControlEntry *rce, double q)
 {
-    RateControlContext *rcc   = &s->rc_context;
+    MpegEncContext     *const   s = &m->s;
+    RateControlContext *const rcc = &m->rc_context;
     AVCodecContext *a         = s->avctx;
     const int pict_type       = rce->new_pict_type;
     const double last_p_q     = rcc->last_qscale_for[AV_PICTURE_TYPE_P];
@@ -168,10 +170,11 @@ static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pic
     *qmax_ret = qmax;
 }
 
-static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
+static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *rce,
                             double q, int frame_num)
 {
-    RateControlContext *rcc  = &s->rc_context;
+    MpegEncContext     *const   s = &m->s;
+    RateControlContext *const rcc = &m->rc_context;
     const double buffer_size = s->avctx->rc_buffer_size;
     const double fps         = get_fps(s->avctx);
     const double min_rate    = s->avctx->rc_min_rate / fps;
@@ -259,10 +262,11 @@ static double modify_qscale(MpegEncContext *s, const RateControlEntry *rce,
 /**
  * Modify the bitrate curve from pass1 for one frame.
  */
-static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
+static double get_qscale(MPVMainEncContext *const m, RateControlEntry *rce,
                          double rate_factor, int frame_num)
 {
-    RateControlContext *rcc = &s->rc_context;
+    MpegEncContext *const s = &m->s;
+    RateControlContext *rcc = &m->rc_context;
     AVCodecContext *a       = s->avctx;
     const int pict_type     = rce->new_pict_type;
     const double mb_num     = s->mb_num;
@@ -332,9 +336,10 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
     return q;
 }
 
-static int init_pass2(MpegEncContext *s)
+static int init_pass2(MPVMainEncContext *const m)
 {
-    RateControlContext *rcc = &s->rc_context;
+    RateControlContext *const rcc = &m->rc_context;
+    MpegEncContext     *const   s = &m->s;
     AVCodecContext *a       = s->avctx;
     int i, toobig;
     AVRational fps         = get_fpsQ(s->avctx);
@@ -393,7 +398,7 @@ static int init_pass2(MpegEncContext *s)
         for (i = 0; i < rcc->num_entries; i++) {
             const RateControlEntry *rce = &rcc->entry[i];
 
-            qscale[i] = get_qscale(s, &rcc->entry[i], rate_factor, i);
+            qscale[i] = get_qscale(m, &rcc->entry[i], rate_factor, i);
             rcc->last_qscale_for[rce->pict_type] = qscale[i];
         }
         av_assert0(filter_size % 2 == 1);
@@ -402,13 +407,13 @@ static int init_pass2(MpegEncContext *s)
         for (i = FFMAX(0, rcc->num_entries - 300); i < rcc->num_entries; i++) {
             const RateControlEntry *rce = &rcc->entry[i];
 
-            qscale[i] = get_diff_limited_q(s, rce, qscale[i]);
+            qscale[i] = get_diff_limited_q(m, rce, qscale[i]);
         }
 
         for (i = rcc->num_entries - 1; i >= 0; i--) {
             const RateControlEntry *rce = &rcc->entry[i];
 
-            qscale[i] = get_diff_limited_q(s, rce, qscale[i]);
+            qscale[i] = get_diff_limited_q(m, rce, qscale[i]);
         }
 
         /* smooth curve */
@@ -438,10 +443,10 @@ static int init_pass2(MpegEncContext *s)
             RateControlEntry *rce = &rcc->entry[i];
             double bits;
 
-            rce->new_qscale = modify_qscale(s, rce, blurred_qscale[i], i);
+            rce->new_qscale = modify_qscale(m, rce, blurred_qscale[i], i);
 
             bits  = qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
-            bits += 8 * ff_vbv_update(s, bits);
+            bits += 8 * ff_vbv_update(m, bits);
 
             rce->expected_bits = expected_bits;
             expected_bits     += bits;
@@ -494,9 +499,10 @@ static int init_pass2(MpegEncContext *s)
     return 0;
 }
 
-av_cold int ff_rate_control_init(MpegEncContext *s)
+av_cold int ff_rate_control_init(MPVMainEncContext *const m)
 {
-    RateControlContext *rcc = &s->rc_context;
+    MpegEncContext *const s = &m->s;
+    RateControlContext *rcc = &m->rc_context;
     int i, res;
     static const char * const const_names[] = {
         "PI",
@@ -632,7 +638,7 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
             p = next;
         }
 
-        res = init_pass2(s);
+        res = init_pass2(m);
         if (res < 0)
             return res;
     }
@@ -686,7 +692,7 @@ av_cold int ff_rate_control_init(MpegEncContext *s)
                 rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;
                 rcc->frame_count[rce.pict_type]++;
 
-                get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);
+                get_qscale(m, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);
 
                 // FIXME misbehaves a little for variable fps
                 rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx);
@@ -717,9 +723,10 @@ av_cold void ff_rate_control_uninit(RateControlContext *rcc)
     av_freep(&rcc->cplx_tab);
 }
 
-int ff_vbv_update(MpegEncContext *s, int frame_size)
+int ff_vbv_update(MPVMainEncContext *m, int frame_size)
 {
-    RateControlContext *rcc = &s->rc_context;
+    MpegEncContext     *const   s = &m->s;
+    RateControlContext *const rcc = &m->rc_context;
     const double fps        = get_fps(s->avctx);
     const int buffer_size   = s->avctx->rc_buffer_size;
     const double min_rate   = s->avctx->rc_min_rate / fps;
@@ -893,9 +900,10 @@ static void adaptive_quantization(RateControlContext *const rcc,
     }
 }
 
-void ff_get_2pass_fcode(MpegEncContext *s)
+void ff_get_2pass_fcode(MPVMainEncContext *const m)
 {
-    const RateControlContext *rcc = &s->rc_context;
+    MpegEncContext *const s = &m->s;
+    const RateControlContext *rcc = &m->rc_context;
     const RateControlEntry   *rce = &rcc->entry[s->picture_number];
 
     s->f_code = rce->f_code;
@@ -904,8 +912,10 @@ void ff_get_2pass_fcode(MpegEncContext *s)
 
 // FIXME rd or at least approx for dquant
 
-float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
+float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
 {
+    MpegEncContext *const s = &m->s;
+    RateControlContext *rcc = &m->rc_context;
     float q;
     int qmin, qmax;
     float br_compensation;
@@ -914,7 +924,6 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
     double fps;
     int picture_number = s->picture_number;
     int64_t wanted_bits;
-    RateControlContext *rcc = &s->rc_context;
     AVCodecContext *a       = s->avctx;
     RateControlEntry local_rce, *rce;
     double bits;
@@ -931,11 +940,11 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
         const int64_t last_var =
             s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum
                                                    : rcc->last_mc_mb_var_sum;
-        av_assert1(s->frame_bits >= s->stuffing_bits);
+        av_assert1(m->frame_bits >= m->stuffing_bits);
         update_predictor(&rcc->pred[s->last_pict_type],
                          rcc->last_qscale,
                          sqrt(last_var),
-                         s->frame_bits - s->stuffing_bits);
+                         m->frame_bits - m->stuffing_bits);
     }
 
     if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
@@ -970,7 +979,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
             wanted_bits = (int64_t)wanted_bits_double;
     }
 
-    diff = s->total_bits - wanted_bits;
+    diff = m->total_bits - wanted_bits;
     br_compensation = (a->bit_rate_tolerance - diff) / a->bit_rate_tolerance;
     if (br_compensation <= 0.0)
         br_compensation = 0.001;
@@ -984,7 +993,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
 
         q = rce->new_qscale / br_compensation;
         ff_dlog(s->avctx, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale,
-                br_compensation, s->frame_bits, var, pict_type);
+                br_compensation, m->frame_bits, var, pict_type);
     } else {
         rce->pict_type     =
         rce->new_pict_type = pict_type;
@@ -1015,12 +1024,12 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
         rate_factor = rcc->pass1_wanted_bits /
                       rcc->pass1_rc_eq_output_sum * br_compensation;
 
-        q = get_qscale(s, rce, rate_factor, picture_number);
+        q = get_qscale(m, rce, rate_factor, picture_number);
         if (q < 0)
             return -1;
 
         av_assert0(q > 0.0);
-        q = get_diff_limited_q(s, rce, q);
+        q = get_diff_limited_q(m, rce, q);
         av_assert0(q > 0.0);
 
         // FIXME type dependent blur like in 2-pass
@@ -1034,7 +1043,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
         }
         av_assert0(q > 0.0);
 
-        q = modify_qscale(s, rce, q, picture_number);
+        q = modify_qscale(m, rce, q, picture_number);
 
         rcc->pass1_wanted_bits += s->bit_rate / fps;
 
@@ -1047,8 +1056,8 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
                "size:%d var:%"PRId64"/%"PRId64" br:%"PRId64" fps:%d\n",
                av_get_picture_type_char(pict_type),
                qmin, q, qmax, picture_number,
-               wanted_bits / 1000, s->total_bits / 1000,
-               br_compensation, short_term_q, s->frame_bits,
+               wanted_bits / 1000, m->total_bits / 1000,
+               br_compensation, short_term_q, m->frame_bits,
                s->mb_var_sum, s->mc_mb_var_sum,
                s->bit_rate / 1000, (int)fps);
     }
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index b889491335..3bcfa5658a 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -93,14 +93,14 @@ typedef struct RateControlContext{
     float *cplx_tab, *bits_tab;
 }RateControlContext;
 
-struct MpegEncContext;
+typedef struct MPVMainEncContext MPVMainEncContext;
 
 /* rate control */
-int ff_rate_control_init(struct MpegEncContext *s);
-float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run);
-void ff_write_pass1_stats(struct MpegEncContext *s);
-int ff_vbv_update(struct MpegEncContext *s, int frame_size);
-void ff_get_2pass_fcode(struct MpegEncContext *s);
+int ff_rate_control_init(MPVMainEncContext *m);
+float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run);
+void ff_write_pass1_stats(MPVMainEncContext *m);
+int ff_vbv_update(MPVMainEncContext *m, int frame_size);
+void ff_get_2pass_fcode(MPVMainEncContext *m);
 void ff_rate_control_uninit(RateControlContext *rcc);
 
 #endif /* AVCODEC_RATECONTROL_H */
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 4d69c3053d..830f6f5096 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -61,7 +61,7 @@ typedef struct SnowEncContext {
     int scenechange_threshold;
 
     MECmpContext mecc;
-    MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
+    MPVMainEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
     MPVPicture cur_pic, last_pic;
 #define ME_CACHE_SIZE 1024
     unsigned me_cache[ME_CACHE_SIZE];
@@ -160,7 +160,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 {
     SnowEncContext *const enc = avctx->priv_data;
     SnowContext *const s = &enc->com;
-    MpegEncContext *const mpv = &enc->m;
+    MpegEncContext *const mpv = &enc->m.s;
     int plane_index, ret;
     int i;
 
@@ -217,7 +217,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     mcf(12,12)
 
     ff_me_cmp_init(&enc->mecc, avctx);
-    ret = ff_me_init(&enc->m.me, avctx, &enc->mecc, 0);
+    ret = ff_me_init(&mpv->me, avctx, &enc->mecc, 0);
     if (ret < 0)
         return ret;
     ff_mpegvideoencdsp_init(&enc->mpvencdsp, avctx);
@@ -252,7 +252,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
             return AVERROR(ENOMEM);
     }
     if((avctx->flags&AV_CODEC_FLAG_PASS2) || !(avctx->flags&AV_CODEC_FLAG_QSCALE)){
-        ret = ff_rate_control_init(mpv);
+        ret = ff_rate_control_init(&enc->m);
         if(ret < 0)
             return ret;
     }
@@ -369,7 +369,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
 static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
 {
     SnowContext      *const s = &enc->com;
-    MotionEstContext *const c = &enc->m.me;
+    MotionEstContext *const c = &enc->m.s.me;
     uint8_t p_buffer[1024];
     uint8_t i_buffer[1024];
     uint8_t p_state[sizeof(s->block_state)];
@@ -435,9 +435,9 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
     last_mv[2][0]= bottom->mx;
     last_mv[2][1]= bottom->my;
 
-    enc->m.mb_stride = 2;
-    enc->m.mb_x =
-    enc->m.mb_y = 0;
+    enc->m.s.mb_stride = 2;
+    enc->m.s.mb_x =
+    enc->m.s.mb_y = 0;
     c->skip= 0;
 
     av_assert1(c->  stride ==   stride);
@@ -446,7 +446,7 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
     c->penalty_factor    = get_penalty_factor(enc->lambda, enc->lambda2, c->avctx->me_cmp);
     c->sub_penalty_factor= get_penalty_factor(enc->lambda, enc->lambda2, c->avctx->me_sub_cmp);
     c->mb_penalty_factor = get_penalty_factor(enc->lambda, enc->lambda2, c->avctx->mb_cmp);
-    c->current_mv_penalty = c->mv_penalty[enc->m.f_code=1] + MAX_DMV;
+    c->current_mv_penalty = c->mv_penalty[enc->m.s.f_code=1] + MAX_DMV;
 
     c->xmin = - x*block_w - 16+3;
     c->ymin = - y*block_w - 16+3;
@@ -482,7 +482,7 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
     for(ref=0; ref<s->ref_frames; ref++){
         init_ref(c, current_data, s->last_picture[ref]->data, NULL, block_w*x, block_w*y, 0);
 
-        ref_score= ff_epzs_motion_search(&enc->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
+        ref_score = ff_epzs_motion_search(&enc->m.s, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
                                          (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w);
 
         av_assert2(ref_mx >= c->xmin);
@@ -490,8 +490,10 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
         av_assert2(ref_my >= c->ymin);
         av_assert2(ref_my <= c->ymax);
 
-        ref_score= c->sub_motion_search(&enc->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w);
-        ref_score= ff_get_mb_score(&enc->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0);
+        ref_score = c->sub_motion_search(&enc->m.s, &ref_mx, &ref_my, ref_score,
+                                         0, 0, level-LOG2_MB_SIZE+4, block_w);
+        ref_score = ff_get_mb_score(&enc->m.s, ref_mx, ref_my, 0, 0,
+                                    level-LOG2_MB_SIZE+4, block_w, 0);
         ref_score+= 2*av_log2(2*ref)*c->penalty_factor;
         if(s->ref_mvs[ref]){
             s->ref_mvs[ref][index][0]= ref_mx;
@@ -567,7 +569,7 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
         if (vard <= 64 || vard < varc)
             c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
         else
-            c->scene_change_score += enc->m.qscale;
+            c->scene_change_score += enc->m.s.qscale;
     }
 
     if(level!=s->block_max_depth){
@@ -670,7 +672,7 @@ static int get_dc(SnowEncContext *enc, int mb_x, int mb_y, int plane_index)
     const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     const int ref_stride= s->current_picture->linesize[plane_index];
     const uint8_t *src = s->input_picture->data[plane_index];
-    IDWTELEM *dst= (IDWTELEM*)enc->m.sc.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
+    IDWTELEM *dst= (IDWTELEM*)enc->m.s.sc.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
     const int b_stride = s->b_width << s->block_max_depth;
     const int w= p->width;
     const int h= p->height;
@@ -768,7 +770,7 @@ static int get_block_rd(SnowEncContext *enc, int mb_x, int mb_y,
     const int ref_stride= s->current_picture->linesize[plane_index];
     uint8_t *dst= s->current_picture->data[plane_index];
     const uint8_t *src = s->input_picture->data[plane_index];
-    IDWTELEM *pred= (IDWTELEM*)enc->m.sc.obmc_scratchpad + plane_index*block_size*block_size*4;
+    IDWTELEM *pred= (IDWTELEM*)enc->m.s.sc.obmc_scratchpad + plane_index*block_size*block_size*4;
     uint8_t *cur = s->scratchbuf;
     uint8_t *tmp = s->emu_edge_buffer;
     const int b_stride = s->b_width << s->block_max_depth;
@@ -831,19 +833,19 @@ static int get_block_rd(SnowEncContext *enc, int mb_x, int mb_y,
          * to improve the score of the whole frame, thus iterative motion
          * estimation does not always converge. */
         if(s->avctx->me_cmp == FF_CMP_W97)
-            distortion = ff_w97_32_c(&enc->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
+            distortion = ff_w97_32_c(&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
         else if(s->avctx->me_cmp == FF_CMP_W53)
-            distortion = ff_w53_32_c(&enc->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
+            distortion = ff_w53_32_c(&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
         else{
             distortion = 0;
             for(i=0; i<4; i++){
                 int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
-                distortion += enc->m.me.me_cmp[0](&enc->m, src + off, dst + off, ref_stride, 16);
+                distortion += enc->m.s.me.me_cmp[0](&enc->m.s, src + off, dst + off, ref_stride, 16);
             }
         }
     }else{
         av_assert2(block_w==8);
-        distortion = enc->m.me.me_cmp[0](&enc->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
+        distortion = enc->m.s.me.me_cmp[0](&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
     }
 
     if(plane_index==0){
@@ -909,7 +911,7 @@ static int get_4block_rd(SnowEncContext *enc, int mb_x, int mb_y, int plane_inde
         }
 
         av_assert1(block_w== 8 || block_w==16);
-        distortion += enc->m.me.me_cmp[block_w==8](&enc->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
+        distortion += enc->m.s.me.me_cmp[block_w==8](&enc->m.s, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
     }
 
     if(plane_index==0){
@@ -1706,11 +1708,11 @@ static int ratecontrol_1pass(SnowEncContext *enc, AVFrame *pict)
     coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
 
     if(pict->pict_type == AV_PICTURE_TYPE_I){
-        enc->m.mb_var_sum    = coef_sum;
-        enc->m.mc_mb_var_sum = 0;
+        enc->m.s.mb_var_sum    = coef_sum;
+        enc->m.s.mc_mb_var_sum = 0;
     }else{
-        enc->m.mc_mb_var_sum = coef_sum;
-        enc->m.mb_var_sum    = 0;
+        enc->m.s.mc_mb_var_sum = coef_sum;
+        enc->m.s.mb_var_sum    = 0;
     }
 
     pict->quality= ff_rate_estimate_qscale(&enc->m, 1);
@@ -1757,7 +1759,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 {
     SnowEncContext *const enc = avctx->priv_data;
     SnowContext *const s = &enc->com;
-    MpegEncContext *const mpv = &enc->m;
+    MpegEncContext *const mpv = &enc->m.s;
     RangeCoder * const c= &s->c;
     AVCodecInternal *avci = avctx->internal;
     AVFrame *pic;
@@ -1793,10 +1795,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
     mpv->picture_number = avctx->frame_num;
     if(avctx->flags&AV_CODEC_FLAG_PASS2){
-        mpv->pict_type = pic->pict_type = mpv->rc_context.entry[avctx->frame_num].new_pict_type;
+        mpv->pict_type = pic->pict_type = enc->m.rc_context.entry[avctx->frame_num].new_pict_type;
         s->keyframe = pic->pict_type == AV_PICTURE_TYPE_I;
         if(!(avctx->flags&AV_CODEC_FLAG_QSCALE)) {
-            pic->quality = ff_rate_estimate_qscale(mpv, 0);
+            pic->quality = ff_rate_estimate_qscale(&enc->m, 0);
             if (pic->quality < 0)
                 return -1;
         }
@@ -1877,7 +1879,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
         mpv->qdsp = enc->qdsp; //move
         mpv->hdsp = s->hdsp;
-        ff_me_init_pic(&enc->m);
+        ff_me_init_pic(mpv);
         s->hdsp = mpv->hdsp;
     }
 
@@ -2043,17 +2045,19 @@ redo_frame:
 
     s->current_picture->pict_type = pic->pict_type;
     s->current_picture->quality = pic->quality;
-    mpv->frame_bits = 8 * (s->c.bytestream - s->c.bytestream_start);
-    mpv->p_tex_bits = mpv->frame_bits - mpv->misc_bits - mpv->mv_bits;
-    mpv->total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
+    enc->m.frame_bits = 8 * (s->c.bytestream - s->c.bytestream_start);
+    mpv->p_tex_bits = enc->m.frame_bits - mpv->misc_bits - mpv->mv_bits;
+    enc->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
     enc->cur_pic.display_picture_number =
     enc->cur_pic.coded_picture_number   = avctx->frame_num;
     enc->cur_pic.f->quality             = pic->quality;
-    if (enc->pass1_rc)
-        if (ff_rate_estimate_qscale(mpv, 0) < 0)
-            return -1;
+    if (enc->pass1_rc) {
+        ret = ff_rate_estimate_qscale(&enc->m, 0);
+        if (ret < 0)
+            return ret;
+    }
     if(avctx->flags&AV_CODEC_FLAG_PASS1)
-        ff_write_pass1_stats(mpv);
+        ff_write_pass1_stats(&enc->m);
     mpv->last_pict_type = mpv->pict_type;
 
     emms_c();
@@ -2088,10 +2092,10 @@ static av_cold int encode_end(AVCodecContext *avctx)
         av_freep(&s->ref_scores[i]);
     }
 
-    enc->m.me.temp = NULL;
-    av_freep(&enc->m.me.scratchpad);
-    av_freep(&enc->m.me.map);
-    av_freep(&enc->m.sc.obmc_scratchpad);
+    enc->m.s.me.temp = NULL;
+    av_freep(&enc->m.s.me.scratchpad);
+    av_freep(&enc->m.s.me.map);
+    av_freep(&enc->m.s.sc.obmc_scratchpad);
 
     av_freep(&avctx->stats_out);
 
-- 
2.45.2


[-- Attachment #6: 0005-avcodec-mpegvideo_enc-Precalculate-which-frames-to-r.patch --]
[-- Type: text/x-patch, Size: 2700 bytes --]

From bc39e9e03975c50cce5b73629ae2ba1266021b98 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 01:48:08 +0100
Subject: [PATCH 05/77] avcodec/mpegvideo_enc: Precalculate which frames to
 reconstruct

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  3 +++
 libavcodec/mpegvideo_enc.c | 16 +++++++++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 75b1fff245..0bb12a343e 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -499,6 +499,9 @@ typedef struct MpegEncContext {
     int lmin, lmax;
     int vbv_ignore_qmax;
 
+    /// Bitfield containing information which frames to reconstruct.
+    int frame_reconstruction_bitfield;
+
     /* flag to indicate a reinitialization is required, e.g. after
      * a frame size change */
     int context_reinit;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 7f24c1baa6..d2bd6f4a18 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -897,6 +897,18 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                                                 AV_CODEC_FLAG_INTERLACED_ME) ||
                                 s->alternate_scan);
 
+    if (avctx->flags & AV_CODEC_FLAG_PSNR || avctx->mb_decision == FF_MB_DECISION_RD ||
+        s->frame_skip_threshold || s->frame_skip_factor) {
+        s->frame_reconstruction_bitfield = (1 << AV_PICTURE_TYPE_I) |
+                                           (1 << AV_PICTURE_TYPE_P) |
+                                           (1 << AV_PICTURE_TYPE_B);
+    } else if (!s->intra_only) {
+        s->frame_reconstruction_bitfield = (1 << AV_PICTURE_TYPE_I) |
+                                           (1 << AV_PICTURE_TYPE_P);
+    } else {
+        s->frame_reconstruction_bitfield = 0;
+    }
+
     if (s->lmin > s->lmax) {
         av_log(avctx, AV_LOG_WARNING, "Clipping lmin value to %d\n", s->lmax);
         s->lmin = s->lmax;
@@ -1122,9 +1134,7 @@ static void mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64])
        }
     }
 
-    if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->frame_skip_threshold || s->frame_skip_factor ||
-        !((s->intra_only || s->pict_type == AV_PICTURE_TYPE_B) &&
-          s->avctx->mb_decision != FF_MB_DECISION_RD)) { // FIXME precalc
+    if ((1 << s->pict_type) & s->frame_reconstruction_bitfield) {
         uint8_t *dest_y = s->dest[0], *dest_cb = s->dest[1], *dest_cr = s->dest[2];
         int dct_linesize, dct_offset;
         const int linesize   = s->cur_pic.linesize[0];
-- 
2.45.2


[-- Attachment #7: 0006-avcodec-mpegvideo-Move-frame_skip_-fields-to-MPVMain.patch --]
[-- Type: text/x-patch, Size: 8602 bytes --]

From 0cc58c515276ccb0c6c6fbf1d5828dc4f72b510a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 02:04:41 +0100
Subject: [PATCH 06/77] avcodec/mpegvideo: Move frame_skip_* fields to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  7 -------
 libavcodec/mpegvideo_enc.c | 31 +++++++++++++++++--------------
 libavcodec/mpegvideoenc.h  | 15 +++++++++++----
 3 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 0bb12a343e..2cc6dbf534 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -510,13 +510,6 @@ typedef struct MpegEncContext {
 
     int error_rate;
 
-    /* frame skip options for encoding */
-    int frame_skip_threshold;
-    int frame_skip_factor;
-    int frame_skip_exp;
-    int frame_skip_cmp;
-    me_cmp_func frame_skip_cmp_fn;
-
     int scenechange_threshold;
     int noise_reduction;
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index d2bd6f4a18..1b7a4c1236 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -307,8 +307,9 @@ av_cold void ff_dct_encode_init(MpegEncContext *s)
         s->dct_quantize  = dct_quantize_trellis_c;
 }
 
-static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
+static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx)
 {
+    MpegEncContext *const s = &m->s;
     MECmpContext mecc;
     me_cmp_func me_cmp[6];
     int ret;
@@ -317,10 +318,10 @@ static av_cold int me_cmp_init(MpegEncContext *s, AVCodecContext *avctx)
     ret = ff_me_init(&s->me, avctx, &mecc, 1);
     if (ret < 0)
         return ret;
-    ret = ff_set_cmp(&mecc, me_cmp, s->frame_skip_cmp, 1);
+    ret = ff_set_cmp(&mecc, me_cmp, m->frame_skip_cmp, 1);
     if (ret < 0)
         return ret;
-    s->frame_skip_cmp_fn = me_cmp[1];
+    m->frame_skip_cmp_fn = me_cmp[1];
     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
         ret = ff_set_cmp(&mecc, me_cmp, avctx->ildct_cmp, 1);
         if (ret < 0)
@@ -898,7 +899,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                                 s->alternate_scan);
 
     if (avctx->flags & AV_CODEC_FLAG_PSNR || avctx->mb_decision == FF_MB_DECISION_RD ||
-        s->frame_skip_threshold || s->frame_skip_factor) {
+        m->frame_skip_threshold || m->frame_skip_factor) {
         s->frame_reconstruction_bitfield = (1 << AV_PICTURE_TYPE_I) |
                                            (1 << AV_PICTURE_TYPE_P) |
                                            (1 << AV_PICTURE_TYPE_B);
@@ -922,7 +923,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     ff_fdctdsp_init(&s->fdsp, avctx);
     ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
     ff_pixblockdsp_init(&s->pdsp, avctx);
-    ret = me_cmp_init(s, avctx);
+    ret = me_cmp_init(m, avctx);
     if (ret < 0)
         return ret;
 
@@ -1402,8 +1403,10 @@ fail:
     return ret;
 }
 
-static int skip_check(MpegEncContext *s, const MPVPicture *p, const MPVPicture *ref)
+static int skip_check(MPVMainEncContext *const m,
+                      const MPVPicture *p, const MPVPicture *ref)
 {
+    MpegEncContext *const s = &m->s;
     int x, y, plane;
     int score = 0;
     int64_t score64 = 0;
@@ -1416,9 +1419,9 @@ static int skip_check(MpegEncContext *s, const MPVPicture *p, const MPVPicture *
                 int off = p->shared ? 0 : 16;
                 const uint8_t *dptr = p->f->data[plane] + 8 * (x + y * stride) + off;
                 const uint8_t *rptr = ref->f->data[plane] + 8 * (x + y * stride);
-                int v = s->frame_skip_cmp_fn(s, dptr, rptr, stride, 8);
+                int v = m->frame_skip_cmp_fn(s, dptr, rptr, stride, 8);
 
-                switch (FFABS(s->frame_skip_exp)) {
+                switch (FFABS(m->frame_skip_exp)) {
                 case 0: score    =  FFMAX(score, v);          break;
                 case 1: score   += FFABS(v);                  break;
                 case 2: score64 += v * (int64_t)v;                       break;
@@ -1432,13 +1435,13 @@ static int skip_check(MpegEncContext *s, const MPVPicture *p, const MPVPicture *
 
     if (score)
         score64 = score;
-    if (s->frame_skip_exp < 0)
+    if (m->frame_skip_exp < 0)
         score64 = pow(score64 / (double)(s->mb_width * s->mb_height),
-                      -1.0/s->frame_skip_exp);
+                      -1.0/m->frame_skip_exp);
 
-    if (score64 < s->frame_skip_threshold)
+    if (score64 < m->frame_skip_threshold)
         return 1;
-    if (score64 < ((s->frame_skip_factor * (int64_t) s->lambda) >> 8))
+    if (score64 < ((m->frame_skip_factor * (int64_t) s->lambda) >> 8))
         return 1;
     return 0;
 }
@@ -1626,10 +1629,10 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         return 0;
 
     /* set next picture type & ordering */
-    if (s->frame_skip_threshold || s->frame_skip_factor) {
+    if (m->frame_skip_threshold || m->frame_skip_factor) {
         if (s->picture_in_gop_number < s->gop_size &&
             s->next_pic.ptr &&
-            skip_check(s, s->input_picture[0], s->next_pic.ptr)) {
+            skip_check(m, s->input_picture[0], s->next_pic.ptr)) {
             // FIXME check that the gop check above is +-1 correct
             av_refstruct_unref(&s->input_picture[0]);
 
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index c1d2821038..9f0d63c31e 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -45,6 +45,13 @@ typedef struct MPVMainEncContext {
     int b_sensitivity;
     int brd_scale;
 
+    /* frame skip options */
+    int frame_skip_threshold;
+    int frame_skip_factor;
+    int frame_skip_exp;
+    int frame_skip_cmp;
+    me_cmp_func frame_skip_cmp_fn;
+
     /* bit rate control */
     int64_t total_bits;
     int frame_bits;                ///< bits used for the current frame
@@ -134,10 +141,10 @@ FF_MPV_OPT_CMP_FUNC, \
 {"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},    \
 {"lmin", "minimum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
 {"lmax", "maximum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
-{"skip_threshold", "Frame skip threshold",                          FF_MPV_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
-{"skip_factor", "Frame skip factor",                                FF_MPV_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
-{"skip_exp", "Frame skip exponent",                                 FF_MPV_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
-{"skip_cmp", "Frame skip compare function",                         FF_MPV_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
+{"skip_threshold", "Frame skip threshold",                          FF_MPV_MAIN_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"skip_factor", "Frame skip factor",                                FF_MPV_MAIN_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"skip_exp", "Frame skip exponent",                                 FF_MPV_MAIN_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"skip_cmp", "Frame skip compare function",                         FF_MPV_MAIN_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
 {"sc_threshold", "Scene change threshold",                          FF_MPV_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"noise_reduction", "Noise reduction",                              FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"ps", "RTP payload size in bytes",                             FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
-- 
2.45.2


[-- Attachment #8: 0007-avcodec-h261enc-Make-h261_encode_init-call-ff_mpv_en.patch --]
[-- Type: text/x-patch, Size: 3696 bytes --]

From 8f5523200a086f092218e87ca2f2b3aeebd040b8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 23:37:50 +0100
Subject: [PATCH 07/77] avcodec/h261enc: Make h261_encode_init() call
 ff_mpv_encode_init()

Right now, ff_mpv_encode_init() is set as FFCodec.init and
calls ff_h261_encode_init(). The opposite is more natural
and avoids a non-static function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261enc.c       | 17 +++++++++--------
 libavcodec/h261enc.h       |  1 -
 libavcodec/mpegvideo_enc.c |  5 -----
 3 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 264efb0aa3..36c50db6df 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -352,20 +352,21 @@ static av_cold void h261_encode_init_static(void)
     mv_codes[0][1] = 1;
 }
 
-av_cold int ff_h261_encode_init(MpegEncContext *s)
+static av_cold int h261_encode_init(AVCodecContext *avctx)
 {
-    H261EncContext *const h = (H261EncContext*)s;
     static AVOnce init_static_once = AV_ONCE_INIT;
+    H261EncContext *const h = avctx->priv_data;
+    MpegEncContext *const s = &h->s.s;
 
-    if (s->width == 176 && s->height == 144) {
+    if (avctx->width == 176 && avctx->height == 144) {
         h->format = H261_QCIF;
-    } else if (s->width == 352 && s->height == 288) {
+    } else if (avctx->width == 352 && avctx->height == 288) {
         h->format = H261_CIF;
     } else {
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                 "The specified picture size of %dx%d is not valid for the "
                 "H.261 codec.\nValid sizes are 176x144, 352x288\n",
-                s->width, s->height);
+               avctx->width, avctx->height);
         return AVERROR(EINVAL);
     }
     s->private_ctx = &h->common;
@@ -380,7 +381,7 @@ av_cold int ff_h261_encode_init(MpegEncContext *s)
     s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len_last;
     ff_thread_once(&init_static_once, h261_encode_init_static);
 
-    return 0;
+    return ff_mpv_encode_init(avctx);
 }
 
 const FFCodec ff_h261_encoder = {
@@ -391,7 +392,7 @@ const FFCodec ff_h261_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(H261EncContext),
-    .init           = ff_mpv_encode_init,
+    .init           = h261_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/h261enc.h b/libavcodec/h261enc.h
index d8fdcad7aa..7877d8aa9d 100644
--- a/libavcodec/h261enc.h
+++ b/libavcodec/h261enc.h
@@ -34,6 +34,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);
-int ff_h261_encode_init(MpegEncContext *s);
 
 #endif
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 1b7a4c1236..5c2f73b2d1 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -778,11 +778,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->low_delay = 1;
         break;
     case AV_CODEC_ID_H261:
-        if (!CONFIG_H261_ENCODER)
-            return AVERROR_ENCODER_NOT_FOUND;
-        ret = ff_h261_encode_init(s);
-        if (ret < 0)
-            return ret;
         s->out_format = FMT_H261;
         avctx->delay  = 0;
         s->low_delay  = 1;
-- 
2.45.2


[-- Attachment #9: 0008-avcodec-mpegvideo-Don-t-initialize-yc-_dc_scale_tabl.patch --]
[-- Type: text/x-patch, Size: 2838 bytes --]

From b77de4fb3b253c8ab9459853d092825dddd9af1b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 17:26:00 +0100
Subject: [PATCH 08/77] avcodec/mpegvideo: Don't initialize [yc]_dc_scale_table
 by default

Only the H.263-based decoders as well as the encoders need it;
so move it to ff_h263_decode_init() as well as ff_mpv_encode_init().
Also for the latter make it only set these tables if none are
already set.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h263dec.c       | 5 ++++-
 libavcodec/mpegvideo.c     | 2 --
 libavcodec/mpegvideo_enc.c | 6 +++++-
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 2d806fc703..8434f6e7cf 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -41,8 +41,8 @@
 #include "mpeg_er.h"
 #include "mpeg4video.h"
 #include "mpeg4videodec.h"
-#include "mpeg4videodefs.h"
 #include "mpegvideo.h"
+#include "mpegvideodata.h"
 #include "mpegvideodec.h"
 #include "msmpeg4dec.h"
 #include "thread.h"
@@ -102,6 +102,9 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
     s->decode_mb       = ff_h263_decode_mb;
     s->low_delay       = 1;
 
+    s->y_dc_scale_table =
+    s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
+
     // dct_unquantize defaults for H.263;
     // they might change on a per-frame basis for MPEG-4.
     s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 4b69b5b65c..9cd67151aa 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -482,8 +482,6 @@ int ff_update_duplicate_context(MpegEncContext *dst, const MpegEncContext *src)
  */
 av_cold void ff_mpv_common_defaults(MpegEncContext *s)
 {
-    s->y_dc_scale_table      =
-    s->c_dc_scale_table      = ff_mpeg1_dc_scale_table;
     s->chroma_qscale_table   = ff_default_chroma_qscale_table;
     s->progressive_frame     = 1;
     s->progressive_sequence  = 1;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 5c2f73b2d1..7eb381af36 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -276,7 +276,6 @@ static av_cold void mpv_encode_init_static(void)
 
 /**
  * Set the given MpegEncContext to defaults for encoding.
- * the changed fields will not depend upon the prior state of the MpegEncContext.
  */
 static av_cold void mpv_encode_defaults(MpegEncContext *s)
 {
@@ -288,6 +287,11 @@ static av_cold void mpv_encode_defaults(MpegEncContext *s)
 
     s->fcode_tab     = default_fcode_tab + MAX_MV;
 
+    if (!s->y_dc_scale_table) {
+        s->y_dc_scale_table =
+        s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
+    }
+
     s->input_picture_number  = 0;
     s->picture_in_gop_number = 0;
 }
-- 
2.45.2


[-- Attachment #10: 0009-avcodec-speedhqenc-Make-speedhq_encode_init-call-ff_.patch --]
[-- Type: text/x-patch, Size: 4016 bytes --]

From c3e33d9885a3e4a31f657ef9b1fb52311ac5d921 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 1 Mar 2025 23:37:50 +0100
Subject: [PATCH 09/77] avcodec/speedhqenc: Make speedhq_encode_init() call
 ff_mpv_encode_init()

Right now, ff_mpv_encode_init() is set as FFCodec.init and
calls ff_speedhq_encode_init(). The opposite is more natural
and avoids a non-static function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c |  4 ----
 libavcodec/speedhqenc.c    | 22 ++++++++++++++--------
 libavcodec/speedhqenc.h    |  1 -
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 7eb381af36..1f55512674 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -774,10 +774,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     case AV_CODEC_ID_SPEEDHQ:
         s->out_format = FMT_SPEEDHQ;
         s->intra_only = 1; /* force intra only for SHQ */
-        if (!CONFIG_SPEEDHQ_ENCODER)
-            return AVERROR_ENCODER_NOT_FOUND;
-        if ((ret = ff_speedhq_encode_init(s)) < 0)
-            return ret;
         avctx->delay = 0;
         s->low_delay = 1;
         break;
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index a0baa869cc..de1bc0cfca 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -95,26 +95,26 @@ static av_cold void speedhq_init_static_data(void)
                              ff_speedhq_vlc_table, uni_speedhq_ac_vlc_len);
 }
 
-av_cold int ff_speedhq_encode_init(MpegEncContext *s)
+static av_cold int speedhq_encode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
+    MpegEncContext *const s = avctx->priv_data;
+    int ret;
 
-    if (s->width > 65500 || s->height > 65500) {
-        av_log(s->avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
+    if (avctx->width > 65500 || avctx->height > 65500) {
+        av_log(avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
     }
 
     // border is not implemented correctly at the moment, see ticket #10078
-    if (s->width % 16) {
-        av_log(s->avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
+    if (avctx->width % 16) {
+        av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
         return AVERROR_PATCHWELCOME;
     }
 
     s->min_qcoeff = -2048;
     s->max_qcoeff = 2047;
 
-    ff_thread_once(&init_static_once, speedhq_init_static_data);
-
     s->intra_ac_vlc_length      =
     s->intra_ac_vlc_last_length =
     s->intra_chroma_ac_vlc_length      =
@@ -123,6 +123,12 @@ av_cold int ff_speedhq_encode_init(MpegEncContext *s)
     s->y_dc_scale_table =
     s->c_dc_scale_table = ff_mpeg12_dc_scale_table[3];
 
+    ret = ff_mpv_encode_init(avctx);
+    if (ret < 0)
+        return ret;
+
+    ff_thread_once(&init_static_once, speedhq_init_static_data);
+
     switch (s->avctx->pix_fmt) {
     case AV_PIX_FMT_YUV420P:
         s->avctx->codec_tag = MKTAG('S','H','Q','0');
@@ -280,7 +286,7 @@ const FFCodec ff_speedhq_encoder = {
     .p.priv_class   = &ff_mpv_enc_class,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SpeedHQEncContext),
-    .init           = ff_mpv_encode_init,
+    .init           = speedhq_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index 15be9764d7..66ef7ee023 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -33,7 +33,6 @@
 
 #include "mpegvideo.h"
 
-int  ff_speedhq_encode_init(MpegEncContext *s);
 void ff_speedhq_encode_close(MpegEncContext *s);
 void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 
-- 
2.45.2


[-- Attachment #11: 0010-avcodec-speedhqenc-Avoid-indirection.patch --]
[-- Type: text/x-patch, Size: 1821 bytes --]

From 67be5b312ac5b2f5ca28131c6d72ba2254c955a8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 00:34:19 +0100
Subject: [PATCH 10/77] avcodec/speedhqenc: Avoid indirection

Namely use avctx directly instead of s->avctx. While just at it,
also move the switch to the other checks involving avctx.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index de1bc0cfca..2e09016935 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -112,6 +112,20 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
         return AVERROR_PATCHWELCOME;
     }
 
+    switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+        avctx->codec_tag = MKTAG('S','H','Q','0');
+        break;
+    case AV_PIX_FMT_YUV422P:
+        avctx->codec_tag = MKTAG('S','H','Q','2');
+        break;
+    case AV_PIX_FMT_YUV444P:
+        avctx->codec_tag = MKTAG('S','H','Q','4');
+        break;
+    default:
+        av_assert0(0);
+    }
+
     s->min_qcoeff = -2048;
     s->max_qcoeff = 2047;
 
@@ -129,20 +143,6 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, speedhq_init_static_data);
 
-    switch (s->avctx->pix_fmt) {
-    case AV_PIX_FMT_YUV420P:
-        s->avctx->codec_tag = MKTAG('S','H','Q','0');
-        break;
-    case AV_PIX_FMT_YUV422P:
-        s->avctx->codec_tag = MKTAG('S','H','Q','2');
-        break;
-    case AV_PIX_FMT_YUV444P:
-        s->avctx->codec_tag = MKTAG('S','H','Q','4');
-        break;
-    default:
-        av_assert0(0);
-    }
-
     return 0;
 }
 
-- 
2.45.2


[-- Attachment #12: 0011-avcodec-mjpegenc-Make-mjpeg_encode_init-call-ff_mpv_.patch --]
[-- Type: text/x-patch, Size: 5340 bytes --]

From ee2d713903d78262c0b1c7700318bf0ec5ff1aa7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 02:13:31 +0100
Subject: [PATCH 11/77] avcodec/mjpegenc: Make mjpeg_encode_init() call
 ff_mpv_encode_init()

Right now, ff_mpv_encode_init() is set as FFCodec.init and
calls ff_speedhq_encode_init(). The opposite is more natural,
avoids a non-static function and allows to reuse e.g.
slice_context_count instead of duplicating the logic from
ff_mpv_common_init().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c      | 37 ++++++++++++++++++-------------------
 libavcodec/mjpegenc.h      |  1 -
 libavcodec/mpegvideo_enc.c |  2 --
 3 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 0a2d6eebd3..f34e89235d 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -283,10 +283,6 @@ static int alloc_huffman(MpegEncContext *s)
     size_t num_mbs, num_blocks, num_codes;
     int blocks_per_mb;
 
-    // We need to init this here as the mjpeg init is called before the common init,
-    s->mb_width  = (s->width  + 15) / 16;
-    s->mb_height = (s->height + 15) / 16;
-
     switch (s->chroma_format) {
     case CHROMA_420: blocks_per_mb =  6; break;
     case CHROMA_422: blocks_per_mb =  8; break;
@@ -305,34 +301,30 @@ static int alloc_huffman(MpegEncContext *s)
     return 0;
 }
 
-av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
+static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
 {
-    MJpegContext *const m = &((MJPEGEncContext*)s)->mjpeg;
-    int ret, use_slices;
+    MJPEGEncContext *const m2 = avctx->priv_data;
+    MJpegContext    *const m  = &m2->mjpeg;
+    MpegEncContext  *const s  = &m2->mpeg.s;
+    int ret;
 
     s->mjpeg_ctx = m;
-    use_slices = s->avctx->slices > 0 ? s->avctx->slices > 1 :
-                 (s->avctx->active_thread_type & FF_THREAD_SLICE) &&
-                 s->avctx->thread_count > 1;
-
-    if (use_slices)
-        m->huffman = HUFFMAN_TABLE_DEFAULT;
 
     if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
         // Used to produce garbage with MJPEG.
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "QP RD is no longer compatible with MJPEG or AMV\n");
         return AVERROR(EINVAL);
     }
 
     /* The following check is automatically true for AMV,
      * but it doesn't hurt either. */
-    ret = ff_mjpeg_encode_check_pix_fmt(s->avctx);
+    ret = ff_mjpeg_encode_check_pix_fmt(avctx);
     if (ret < 0)
         return ret;
 
-    if (s->width > 65500 || s->height > 65500) {
-        av_log(s->avctx, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
+    if (avctx->width > 65500 || avctx->height > 65500) {
+        av_log(avctx, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
         return AVERROR(EINVAL);
     }
 
@@ -366,9 +358,16 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
     s->intra_chroma_ac_vlc_length      =
     s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len;
 
+    ret = ff_mpv_encode_init(avctx);
+    if (ret < 0)
+        return ret;
+
     // Buffers start out empty.
     m->huff_ncode = 0;
 
+    if (s->slice_context_count > 1)
+        m->huffman = HUFFMAN_TABLE_DEFAULT;
+
     if (m->huffman == HUFFMAN_TABLE_OPTIMAL)
         return alloc_huffman(s);
 
@@ -681,7 +680,7 @@ const FFCodec ff_mjpeg_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MJPEG,
     .priv_data_size = sizeof(MJPEGEncContext),
-    .init           = ff_mpv_encode_init,
+    .init           = mjpeg_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = mjpeg_encode_close,
     .p.capabilities = AV_CODEC_CAP_DR1 |
@@ -711,7 +710,7 @@ const FFCodec ff_amv_encoder = {
     .p.id           = AV_CODEC_ID_AMV,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(MJPEGEncContext),
-    .init           = ff_mpv_encode_init,
+    .init           = mjpeg_encode_init,
     FF_CODEC_ENCODE_CB(amv_encode_picture),
     .close          = mjpeg_encode_close,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index 1ac0d6de7e..2c98de057a 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;
 
-int  ff_mjpeg_encode_init(MpegEncContext *s);
 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/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 1f55512674..d2e3ed1d8c 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -765,8 +765,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     case AV_CODEC_ID_AMV:
         s->out_format = FMT_MJPEG;
         s->intra_only = 1; /* force intra only for jpeg */
-        if ((ret = ff_mjpeg_encode_init(s)) < 0)
-            return ret;
         avctx->delay = 0;
         s->low_delay = 1;
         break;
-- 
2.45.2


[-- Attachment #13: 0012-avcodec-mjpegenc-Simplify-allocating-huffman-table.patch --]
[-- Type: text/x-patch, Size: 2220 bytes --]

From d1c52483aeeab5584a685146ab86f746cc941834 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 02:36:55 +0100
Subject: [PATCH 12/77] avcodec/mjpegenc: Simplify allocating huffman table

Reuse the already computed value of macroblocks; use an array
instead of a switch, evaluate 64 * sizeof(MJpegHuffmanCode)
at compile-time.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index f34e89235d..6f9818baf2 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -277,25 +277,21 @@ fail:
     return ret;
 }
 
-static int alloc_huffman(MpegEncContext *s)
+static int alloc_huffman(MJPEGEncContext *const m2)
 {
-    MJpegContext *m = s->mjpeg_ctx;
-    size_t num_mbs, num_blocks, num_codes;
-    int blocks_per_mb;
-
-    switch (s->chroma_format) {
-    case CHROMA_420: blocks_per_mb =  6; break;
-    case CHROMA_422: blocks_per_mb =  8; break;
-    case CHROMA_444: blocks_per_mb = 12; break;
-    default: av_assert0(0);
+    MJpegContext   *const m = &m2->mjpeg;
+    MpegEncContext *const s = &m2->mpeg.s;
+    static const char blocks_per_mb[] = {
+        [CHROMA_420] = 6, [CHROMA_422] = 8, [CHROMA_444] = 12
     };
+    size_t num_blocks, num_codes;
 
     // Make sure we have enough space to hold this frame.
-    num_mbs = s->mb_width * s->mb_height;
-    num_blocks = num_mbs * blocks_per_mb;
+    num_blocks = s->mb_num * blocks_per_mb[s->chroma_format];
     num_codes = num_blocks * 64;
 
-    m->huff_buffer = av_malloc_array(num_codes, sizeof(MJpegHuffmanCode));
+    m->huff_buffer = av_malloc_array(num_codes,
+                                     64 /* codes per MB */ * sizeof(MJpegHuffmanCode));
     if (!m->huff_buffer)
         return AVERROR(ENOMEM);
     return 0;
@@ -369,7 +365,7 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
         m->huffman = HUFFMAN_TABLE_DEFAULT;
 
     if (m->huffman == HUFFMAN_TABLE_OPTIMAL)
-        return alloc_huffman(s);
+        return alloc_huffman(m2);
 
     return 0;
 }
-- 
2.45.2


[-- Attachment #14: 0013-avcodec-mpegvideo_enc-Only-set-fcode_tab-if-unset.patch --]
[-- Type: text/x-patch, Size: 1198 bytes --]

From fbd7724d012c9ff833c78d1e6944d7a6da4809b8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 18:07:02 +0100
Subject: [PATCH 13/77] avcodec/mpegvideo_enc: Only set fcode_tab if unset

This is in preparation for merging ff_mpeg1_encode_init()
into the MPEG-1/2 encoder's init function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index d2e3ed1d8c..398b06d929 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -283,10 +283,10 @@ static av_cold void mpv_encode_defaults(MpegEncContext *s)
 
     ff_mpv_common_defaults(s);
 
-    ff_thread_once(&init_static_once, mpv_encode_init_static);
-
-    s->fcode_tab     = default_fcode_tab + MAX_MV;
-
+    if (!s->fcode_tab) {
+        s->fcode_tab = default_fcode_tab + MAX_MV;
+        ff_thread_once(&init_static_once, mpv_encode_init_static);
+    }
     if (!s->y_dc_scale_table) {
         s->y_dc_scale_table =
         s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
-- 
2.45.2


[-- Attachment #15: 0014-avcodec-mpeg12enc-Move-encode_init-to-the-end-of-the.patch --]
[-- Type: text/x-patch, Size: 13119 bytes --]

From 67b4194006c40618d20adfe53863bda2364faa59 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 18:11:10 +0100
Subject: [PATCH 14/77] avcodec/mpeg12enc: Move encode_init() to the end of the
 file

Will avoid forward declarations later.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c | 298 ++++++++++++++++++++---------------------
 1 file changed, 149 insertions(+), 149 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index bb61b4f4fe..730e0411c7 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -137,155 +137,6 @@ av_cold void ff_mpeg1_init_uni_ac_vlc(const int8_t max_level[],
 }
 
 #if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
-static int find_frame_rate_index(AVCodecContext *avctx, MPEG12EncContext *mpeg12)
-{
-    int i;
-    AVRational bestq = (AVRational) {0, 0};
-    AVRational ext;
-    AVRational target = av_inv_q(avctx->time_base);
-
-    for (i = 1; i < 14; i++) {
-        if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
-            i >= 9)
-            break;
-
-        for (ext.num=1; ext.num <= 4; ext.num++) {
-            for (ext.den=1; ext.den <= 32; ext.den++) {
-                AVRational q = av_mul_q(ext, ff_mpeg12_frame_rate_tab[i]);
-
-                if (avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO && (ext.den!=1 || ext.num!=1))
-                    continue;
-                if (av_gcd(ext.den, ext.num) != 1)
-                    continue;
-
-                if (    bestq.num==0
-                    || av_nearer_q(target, bestq, q) < 0
-                    || ext.num==1 && ext.den==1 && av_nearer_q(target, bestq, q) == 0) {
-                    bestq               = q;
-                    mpeg12->frame_rate_index   = i;
-                    mpeg12->frame_rate_ext.num = ext.num;
-                    mpeg12->frame_rate_ext.den = ext.den;
-                }
-            }
-        }
-    }
-
-    if (av_cmp_q(target, bestq))
-        return -1;
-    else
-        return 0;
-}
-
-static av_cold int encode_init(AVCodecContext *avctx)
-{
-    MPEG12EncContext *const mpeg12 = avctx->priv_data;
-    int ret;
-    int max_size = avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 16383 : 4095;
-
-    if (avctx->width > max_size || avctx->height > max_size) {
-        av_log(avctx, AV_LOG_ERROR, "%s does not support resolutions above %dx%d\n",
-               CONFIG_SMALL ? avctx->codec->name : avctx->codec->long_name,
-               max_size, max_size);
-        return AVERROR(EINVAL);
-    }
-    if ((avctx->width & 0xFFF) == 0 && (avctx->height & 0xFFF) == 1) {
-        av_log(avctx, AV_LOG_ERROR, "Width / Height is invalid for MPEG2\n");
-        return AVERROR(EINVAL);
-    }
-
-    if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
-        if ((avctx->width & 0xFFF) == 0 || (avctx->height & 0xFFF) == 0) {
-            av_log(avctx, AV_LOG_ERROR, "Width or Height are not allowed to be multiples of 4096\n"
-                                        "add '-strict %d' if you want to use them anyway.\n", FF_COMPLIANCE_UNOFFICIAL);
-            return AVERROR(EINVAL);
-        }
-    }
-
-    if (mpeg12->mpeg.s.q_scale_type == 1) {
-        if (avctx->qmax > 28) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "non linear quant only supports qmax <= 28 currently\n");
-            return AVERROR_PATCHWELCOME;
-        }
-    }
-
-    if (avctx->profile == AV_PROFILE_UNKNOWN) {
-        if (avctx->level != AV_LEVEL_UNKNOWN) {
-            av_log(avctx, AV_LOG_ERROR, "Set profile and level\n");
-            return AVERROR(EINVAL);
-        }
-        /* Main or 4:2:2 */
-        avctx->profile = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? AV_PROFILE_MPEG2_MAIN
-                                                              : AV_PROFILE_MPEG2_422;
-    }
-    if (avctx->level == AV_LEVEL_UNKNOWN) {
-        if (avctx->profile == AV_PROFILE_MPEG2_422) {   /* 4:2:2 */
-            if (avctx->width <= 720 && avctx->height <= 608)
-                avctx->level = 5;                   /* Main */
-            else
-                avctx->level = 2;                   /* High */
-        } else {
-            if (avctx->profile != AV_PROFILE_MPEG2_HIGH &&
-                avctx->pix_fmt != AV_PIX_FMT_YUV420P) {
-                av_log(avctx, AV_LOG_ERROR,
-                       "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n");
-                return AVERROR(EINVAL);
-            }
-            if (avctx->width <= 720 && avctx->height <= 576)
-                avctx->level = 8;                   /* Main */
-            else if (avctx->width <= 1440)
-                avctx->level = 6;                   /* High 1440 */
-            else
-                avctx->level = 4;                   /* High */
-        }
-    }
-
-    if ((ret = ff_mpv_encode_init(avctx)) < 0)
-        return ret;
-
-    if (find_frame_rate_index(avctx, mpeg12) < 0) {
-        if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
-            av_log(avctx, AV_LOG_ERROR, "MPEG-1/2 does not support %d/%d fps\n",
-                   avctx->time_base.den, avctx->time_base.num);
-            return AVERROR(EINVAL);
-        } else {
-            av_log(avctx, AV_LOG_INFO,
-                   "MPEG-1/2 does not support %d/%d fps, there may be AV sync issues\n",
-                   avctx->time_base.den, avctx->time_base.num);
-        }
-    }
-
-    if (avctx->rc_max_rate &&
-        avctx->rc_min_rate == avctx->rc_max_rate &&
-        90000LL * (avctx->rc_buffer_size - 1) >
-            avctx->rc_max_rate * 0xFFFFLL) {
-        av_log(avctx, AV_LOG_INFO,
-               "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
-               "specified vbv buffer is too large for the given bitrate!\n");
-    }
-
-    if (mpeg12->drop_frame_timecode)
-        mpeg12->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME;
-    if (mpeg12->drop_frame_timecode && mpeg12->frame_rate_index != 4) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Drop frame time code only allowed with 1001/30000 fps\n");
-        return AVERROR(EINVAL);
-    }
-
-    if (mpeg12->tc_opt_str) {
-        AVRational rate = ff_mpeg12_frame_rate_tab[mpeg12->frame_rate_index];
-        int ret = av_timecode_init_from_string(&mpeg12->tc, rate, mpeg12->tc_opt_str, avctx);
-        if (ret < 0)
-            return ret;
-        mpeg12->drop_frame_timecode  = !!(mpeg12->tc.flags & AV_TIMECODE_FLAG_DROPFRAME);
-        mpeg12->timecode_frame_start = mpeg12->tc.start;
-    } else {
-        mpeg12->timecode_frame_start = 0; // default is -1
-    }
-
-    return 0;
-}
-
 static void put_header(MpegEncContext *s, uint32_t header)
 {
     align_put_bits(&s->pb);
@@ -1179,6 +1030,155 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s)
     ff_thread_once(&init_static_once, mpeg12_encode_init_static);
 }
 
+static av_cold int find_frame_rate_index(AVCodecContext *avctx, MPEG12EncContext *mpeg12)
+{
+    AVRational bestq = (AVRational) {0, 0};
+    AVRational ext;
+    AVRational target = av_inv_q(avctx->time_base);
+
+    for (int i = 1; i < 14; i++) {
+        if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
+            i >= 9)
+            break;
+
+        for (ext.num = 1; ext.num <= 4; ext.num++) {
+            for (ext.den = 1; ext.den <= 32; ext.den++) {
+                AVRational q = av_mul_q(ext, ff_mpeg12_frame_rate_tab[i]);
+
+                if (avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO && (ext.den!=1 || ext.num!=1))
+                    continue;
+                if (av_gcd(ext.den, ext.num) != 1)
+                    continue;
+
+                if (    bestq.num==0
+                    || av_nearer_q(target, bestq, q) < 0
+                    || ext.num==1 && ext.den==1 && av_nearer_q(target, bestq, q) == 0) {
+                    bestq               = q;
+                    mpeg12->frame_rate_index   = i;
+                    mpeg12->frame_rate_ext.num = ext.num;
+                    mpeg12->frame_rate_ext.den = ext.den;
+                }
+            }
+        }
+    }
+
+    if (av_cmp_q(target, bestq))
+        return -1;
+    else
+        return 0;
+}
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    MPEG12EncContext *const mpeg12 = avctx->priv_data;
+    int ret;
+    int max_size = avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 16383 : 4095;
+
+    if (avctx->width > max_size || avctx->height > max_size) {
+        av_log(avctx, AV_LOG_ERROR, "%s does not support resolutions above %dx%d\n",
+               CONFIG_SMALL ? avctx->codec->name : avctx->codec->long_name,
+               max_size, max_size);
+        return AVERROR(EINVAL);
+    }
+    if ((avctx->width & 0xFFF) == 0 && (avctx->height & 0xFFF) == 1) {
+        av_log(avctx, AV_LOG_ERROR, "Width / Height is invalid for MPEG2\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+        if ((avctx->width & 0xFFF) == 0 || (avctx->height & 0xFFF) == 0) {
+            av_log(avctx, AV_LOG_ERROR, "Width or Height are not allowed to be multiples of 4096\n"
+                                        "add '-strict %d' if you want to use them anyway.\n", FF_COMPLIANCE_UNOFFICIAL);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    if (mpeg12->mpeg.s.q_scale_type == 1) {
+        if (avctx->qmax > 28) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "non linear quant only supports qmax <= 28 currently\n");
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+
+    if (avctx->profile == AV_PROFILE_UNKNOWN) {
+        if (avctx->level != AV_LEVEL_UNKNOWN) {
+            av_log(avctx, AV_LOG_ERROR, "Set profile and level\n");
+            return AVERROR(EINVAL);
+        }
+        /* Main or 4:2:2 */
+        avctx->profile = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? AV_PROFILE_MPEG2_MAIN
+                                                              : AV_PROFILE_MPEG2_422;
+    }
+    if (avctx->level == AV_LEVEL_UNKNOWN) {
+        if (avctx->profile == AV_PROFILE_MPEG2_422) {   /* 4:2:2 */
+            if (avctx->width <= 720 && avctx->height <= 608)
+                avctx->level = 5;                   /* Main */
+            else
+                avctx->level = 2;                   /* High */
+        } else {
+            if (avctx->profile != AV_PROFILE_MPEG2_HIGH &&
+                avctx->pix_fmt != AV_PIX_FMT_YUV420P) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n");
+                return AVERROR(EINVAL);
+            }
+            if (avctx->width <= 720 && avctx->height <= 576)
+                avctx->level = 8;                   /* Main */
+            else if (avctx->width <= 1440)
+                avctx->level = 6;                   /* High 1440 */
+            else
+                avctx->level = 4;                   /* High */
+        }
+    }
+
+    ret = ff_mpv_encode_init(avctx);
+    if (ret < 0)
+        return ret;
+
+    if (find_frame_rate_index(avctx, mpeg12) < 0) {
+        if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+            av_log(avctx, AV_LOG_ERROR, "MPEG-1/2 does not support %d/%d fps\n",
+                   avctx->time_base.den, avctx->time_base.num);
+            return AVERROR(EINVAL);
+        } else {
+            av_log(avctx, AV_LOG_INFO,
+                   "MPEG-1/2 does not support %d/%d fps, there may be AV sync issues\n",
+                   avctx->time_base.den, avctx->time_base.num);
+        }
+    }
+
+    if (avctx->rc_max_rate &&
+        avctx->rc_min_rate == avctx->rc_max_rate &&
+        90000LL * (avctx->rc_buffer_size - 1) >
+            avctx->rc_max_rate * 0xFFFFLL) {
+        av_log(avctx, AV_LOG_INFO,
+               "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
+               "specified vbv buffer is too large for the given bitrate!\n");
+    }
+
+    if (mpeg12->drop_frame_timecode)
+        mpeg12->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME;
+    if (mpeg12->drop_frame_timecode && mpeg12->frame_rate_index != 4) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Drop frame time code only allowed with 1001/30000 fps\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (mpeg12->tc_opt_str) {
+        AVRational rate = ff_mpeg12_frame_rate_tab[mpeg12->frame_rate_index];
+        int ret = av_timecode_init_from_string(&mpeg12->tc, rate, mpeg12->tc_opt_str, avctx);
+        if (ret < 0)
+            return ret;
+        mpeg12->drop_frame_timecode  = !!(mpeg12->tc.flags & AV_TIMECODE_FLAG_DROPFRAME);
+        mpeg12->timecode_frame_start = mpeg12->tc.start;
+    } else {
+        mpeg12->timecode_frame_start = 0; // default is -1
+    }
+
+    return 0;
+}
+
 #define OFFSET(x) offsetof(MPEG12EncContext, x)
 #define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
 #define COMMON_OPTS                                                           \
-- 
2.45.2


[-- Attachment #16: 0015-avcodec-mpeg12enc-Merge-ff_mpeg1_encode_init-into-or.patch --]
[-- Type: text/x-patch, Size: 5004 bytes --]

From 24b7f2a2d10d2e62b54bd2cea97fe29492cced75 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 18:28:13 +0100
Subject: [PATCH 15/77] avcodec/mpeg12enc: Merge ff_mpeg1_encode_init() into
 ordinary init

Everything except setting the dc_scale_tables can be done
before calling ff_mpv_encode_init(); setting the dc_scale_tables
unfortunately still has to be performed via a (now inlined)
callback performed by ff_mpv_encode_init() as it relies
on intra_dc_precision having been sanitized.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c | 58 +++++++++++++++++++-----------------------
 libavcodec/mpeg12enc.h |  9 ++++++-
 2 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 730e0411c7..c1e6cc84db 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -46,7 +46,6 @@
 #include "mpeg12vlc.h"
 #include "mpegutils.h"
 #include "mpegvideo.h"
-#include "mpegvideodata.h"
 #include "mpegvideoenc.h"
 #include "profiles.h"
 #include "rl.h"
@@ -1000,36 +999,6 @@ static av_cold void mpeg12_encode_init_static(void)
             fcode_tab[mv + MAX_MV] = f_code;
 }
 
-av_cold void ff_mpeg1_encode_init(MpegEncContext *s)
-{
-    static AVOnce init_static_once = AV_ONCE_INIT;
-
-    s->y_dc_scale_table =
-    s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
-
-    s->me.mv_penalty = mv_penalty;
-    s->fcode_tab     = fcode_tab + MAX_MV;
-    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
-        s->min_qcoeff = -255;
-        s->max_qcoeff = 255;
-    } else {
-        s->min_qcoeff = -2047;
-        s->max_qcoeff = 2047;
-        s->mpeg_quant = 1;
-    }
-    if (s->intra_vlc_format) {
-        s->intra_ac_vlc_length      =
-        s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len;
-    } else {
-        s->intra_ac_vlc_length      =
-        s->intra_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;
-    }
-    s->inter_ac_vlc_length      =
-    s->inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;
-
-    ff_thread_once(&init_static_once, mpeg12_encode_init_static);
-}
-
 static av_cold int find_frame_rate_index(AVCodecContext *avctx, MPEG12EncContext *mpeg12)
 {
     AVRational bestq = (AVRational) {0, 0};
@@ -1070,7 +1039,10 @@ static av_cold int find_frame_rate_index(AVCodecContext *avctx, MPEG12EncContext
 
 static av_cold int encode_init(AVCodecContext *avctx)
 {
+    static AVOnce init_static_once = AV_ONCE_INIT;
     MPEG12EncContext *const mpeg12 = avctx->priv_data;
+    MPVMainEncContext *const m = &mpeg12->mpeg;
+    MpegEncContext    *const s = &m->s;
     int ret;
     int max_size = avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 16383 : 4095;
 
@@ -1093,7 +1065,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
-    if (mpeg12->mpeg.s.q_scale_type == 1) {
+    if (s->q_scale_type == 1) {
         if (avctx->qmax > 28) {
             av_log(avctx, AV_LOG_ERROR,
                    "non linear quant only supports qmax <= 28 currently\n");
@@ -1132,6 +1104,26 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
+    s->me.mv_penalty = mv_penalty;
+    s->fcode_tab     = fcode_tab + MAX_MV;
+    if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+        s->min_qcoeff = -255;
+        s->max_qcoeff = 255;
+    } else {
+        s->min_qcoeff = -2047;
+        s->max_qcoeff = 2047;
+        s->mpeg_quant = 1;
+    }
+    if (s->intra_vlc_format) {
+        s->intra_ac_vlc_length      =
+        s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len;
+    } else {
+        s->intra_ac_vlc_length      =
+        s->intra_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;
+    }
+    s->inter_ac_vlc_length      =
+    s->inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;
+
     ret = ff_mpv_encode_init(avctx);
     if (ret < 0)
         return ret;
@@ -1176,6 +1168,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
         mpeg12->timecode_frame_start = 0; // default is -1
     }
 
+    ff_thread_once(&init_static_once, mpeg12_encode_init_static);
+
     return 0;
 }
 
diff --git a/libavcodec/mpeg12enc.h b/libavcodec/mpeg12enc.h
index 0b35af8a30..908971905d 100644
--- a/libavcodec/mpeg12enc.h
+++ b/libavcodec/mpeg12enc.h
@@ -25,11 +25,18 @@
 #include <stdint.h>
 
 #include "mpegvideo.h"
+#include "mpegvideodata.h"
 
 void ff_mpeg1_encode_picture_header(MpegEncContext *s);
 void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64],
                         int motion_x, int motion_y);
-void ff_mpeg1_encode_init(MpegEncContext *s);
 void ff_mpeg1_encode_slice_header(MpegEncContext *s);
 
+// Must not be called before intra_dc_precision has been sanitized in ff_mpv_encode_init()
+static inline void ff_mpeg1_encode_init(MpegEncContext *s)
+{
+    s->y_dc_scale_table =
+    s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
+}
+
 #endif /* AVCODEC_MPEG12ENC_H */
-- 
2.45.2


[-- Attachment #17: 0016-avcodec-mpeg12enc-Don-t-write-invalid-MPEG-1-slice-h.patch --]
[-- Type: text/x-patch, Size: 3926 bytes --]

From 06ce4b8647097489ac4d56f7f80693430132feb2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 04:30:11 +0100
Subject: [PATCH 16/77] avcodec/mpeg12enc: Don't write invalid MPEG-1 slice
 headers

The valid values for slice_start_code are 0x1..0xAF, which implies
that one can't start a slice with row nb > 174 (zero-based).
This problem can be encountered with files of sufficient height
(more than 2800 pixels) either by using the slice option or by
imposing an RTP payload limit.

Fix this by making the last slice start on the maximum allowed
slice row if necessary and divide the first 174 rows to the remaining
slices. This will impede parallelism both in the decoder and encoder,
but that is unavoidable.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     | 26 ++++++++++++++++++++++++++
 libavcodec/mpegvideo_enc.c |  4 +++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index c1e6cc84db..d84d628563 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -25,6 +25,7 @@
  * MPEG-1/2 encoder
  */
 
+#include <assert.h>
 #include <stdint.h>
 
 #include "config.h"
@@ -324,6 +325,7 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s)
         /* slice_vertical_position_extension */
         put_bits(&s->pb, 3, s->mb_y >> 7);
     } else {
+        av_assert1(s->mb_y <= SLICE_MAX_START_CODE - SLICE_MIN_START_CODE);
         put_header(s, SLICE_MIN_START_CODE + s->mb_y);
     }
     put_qscale(s);
@@ -1128,6 +1130,30 @@ static av_cold int encode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
+    if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
+        s->thread_context[s->slice_context_count - 1]->start_mb_y >
+            SLICE_MAX_START_CODE - SLICE_MIN_START_CODE) {
+        // MPEG-1 slices must not start at a MB row number that would make
+        // their start code > SLICE_MAX_START_CODE. So make the last slice
+        // bigger if needed and evenly distribute the first 174 rows.
+        static_assert(MAX_THREADS <= 1 + SLICE_MAX_START_CODE - SLICE_MIN_START_CODE,
+                      "With more than 175 slice contexts, we have to handle "
+                      "the case in which there is no work to do for some "
+                      "slice contexts.");
+        const int mb_height = SLICE_MAX_START_CODE - SLICE_MIN_START_CODE;
+        const int nb_slices = s->slice_context_count - 1;
+
+        s->thread_context[nb_slices]->start_mb_y = mb_height;
+
+        av_assert1(nb_slices >= 1);
+        for (int i = 0; i < nb_slices; i++) {
+            s->thread_context[i]->start_mb_y =
+                (mb_height * (i    ) + nb_slices / 2) / nb_slices;
+            s->thread_context[i]->end_mb_y   =
+                (mb_height * (i + 1) + nb_slices / 2) / nb_slices;
+        }
+    }
+
     if (find_frame_rate_index(avctx, mpeg12) < 0) {
         if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
             av_log(avctx, AV_LOG_ERROR, "MPEG-1/2 does not support %d/%d fps\n",
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 398b06d929..2cba4deca3 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3077,7 +3077,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
                 case AV_CODEC_ID_MPEG2VIDEO:
                     if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
                 case AV_CODEC_ID_MPEG1VIDEO:
-                    if(s->mb_skip_run) is_gob_start=0;
+                    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->mb_y >= 175 ||
+                        s->mb_skip_run)
+                        is_gob_start=0;
                     break;
                 case AV_CODEC_ID_MJPEG:
                     if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
-- 
2.45.2


[-- Attachment #18: 0017-avcodec-pthread_slice-Remove-MPEG-1-height-hack.patch --]
[-- Type: text/x-patch, Size: 1238 bytes --]

From d045df9d51b5162fa29ecd2ccb92588ee5976b5c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 04:59:55 +0100
Subject: [PATCH 17/77] avcodec/pthread_slice: Remove MPEG-1 height hack

This is no longer necessary given that the MPEG-1 encoder
now adapts the size of the last slice to ensure that
no slice header has an invalid slice_start_code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/pthread_slice.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
index 8fd3fdafd3..4714fef106 100644
--- a/libavcodec/pthread_slice.c
+++ b/libavcodec/pthread_slice.c
@@ -115,12 +115,6 @@ av_cold int ff_slice_thread_init(AVCodecContext *avctx)
     int thread_count = avctx->thread_count;
     void (*mainfunc)(void *);
 
-    // We cannot do this in the encoder init as the threads are created before
-    if (ff_codec_is_encoder(avctx->codec) &&
-        avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
-        avctx->height > 2800)
-        thread_count = avctx->thread_count = 1;
-
     if (!thread_count) {
         int nb_cpus = av_cpu_count();
         if  (avctx->height)
-- 
2.45.2


[-- Attachment #19: 0018-avcodec-pthread_slice-Return-error-on-error.patch --]
[-- Type: text/x-patch, Size: 1545 bytes --]

From d80f255e10e7a5ef14df6479114a92dbd1c1c37f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 05:24:51 +0100
Subject: [PATCH 18/77] avcodec/pthread_slice: Return error on error

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/pthread_slice.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
index 4714fef106..f9da670735 100644
--- a/libavcodec/pthread_slice.c
+++ b/libavcodec/pthread_slice.c
@@ -132,14 +132,16 @@ av_cold int ff_slice_thread_init(AVCodecContext *avctx)
     }
 
     avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c));
+    if (!c)
+        return AVERROR(ENOMEM);
     mainfunc = ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SLICE_THREAD_HAS_MF ? &main_function : NULL;
-    if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, mainfunc, thread_count)) <= 1) {
-        if (c)
-            avpriv_slicethread_free(&c->thread);
-        av_freep(&avctx->internal->thread_ctx);
+    thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func,
+                                             mainfunc, thread_count);
+    if (thread_count <= 1) {
+        ff_slice_thread_free(avctx);
         avctx->thread_count = 1;
         avctx->active_thread_type = 0;
-        return 0;
+        return thread_count < 0 ? thread_count : 0;
     }
     avctx->thread_count = thread_count;
 
-- 
2.45.2


[-- Attachment #20: 0019-avutil-slicethread-Remove-NULL-pointer-check-when-fr.patch --]
[-- Type: text/x-patch, Size: 1248 bytes --]

From 351c46b4dc3a1d63c148aaf611bf9bde3de34598 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 05:30:15 +0100
Subject: [PATCH 19/77] avutil/slicethread: Remove NULL pointer check when
 freeing

avpriv_slicethread_free() is one of our functions that takes
a pointer to a pointer and resets the pointer when done.
It is legal for such functions to be passed a pointer to a NULL
pointer, yet passing a NULL pointer would be insane and should
not be tolerated.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/slicethread.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavutil/slicethread.c b/libavutil/slicethread.c
index e6b82e31b6..6593d58abc 100644
--- a/libavutil/slicethread.c
+++ b/libavutil/slicethread.c
@@ -224,13 +224,12 @@ void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_mai
 
 void avpriv_slicethread_free(AVSliceThread **pctx)
 {
-    AVSliceThread *ctx;
+    AVSliceThread *ctx = *pctx;
     int nb_workers, i;
 
-    if (!pctx || !*pctx)
+    if (!ctx)
         return;
 
-    ctx = *pctx;
     nb_workers = ctx->nb_threads;
     if (!ctx->main_func)
         nb_workers--;
-- 
2.45.2


[-- Attachment #21: 0020-avutil-slicethread-Mark-avpriv_slicethread_-create-f.patch --]
[-- Type: text/x-patch, Size: 1210 bytes --]

From 803680237e97a86d1d7f2c9afcf8823d66dec819 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 05:34:29 +0100
Subject: [PATCH 20/77] avutil/slicethread: Mark
 avpriv_slicethread_{create,free} as av_cold

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/slicethread.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavutil/slicethread.c b/libavutil/slicethread.c
index 6593d58abc..7650fc66ad 100644
--- a/libavutil/slicethread.c
+++ b/libavutil/slicethread.c
@@ -95,6 +95,7 @@ static void *attribute_align_arg thread_worker(void *v)
     }
 }
 
+av_cold
 int avpriv_slicethread_create(AVSliceThread **pctx, void *priv,
                               void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads),
                               void (*main_func)(void *priv),
@@ -222,7 +223,7 @@ void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_mai
     }
 }
 
-void avpriv_slicethread_free(AVSliceThread **pctx)
+av_cold void avpriv_slicethread_free(AVSliceThread **pctx)
 {
     AVSliceThread *ctx = *pctx;
     int nb_workers, i;
-- 
2.45.2


[-- Attachment #22: 0021-avcodec-mpeg4videoenc-Add-Mpeg4EncContext-and-move-t.patch --]
[-- Type: text/x-patch, Size: 7626 bytes --]

From ee671d14898fc311152f37fbd1d81719a9172848 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 01:03:10 +0100
Subject: [PATCH 21/77] avcodec/mpeg4videoenc: Add Mpeg4EncContext and move
 time_increment_bits

It is only ever used by the main encoder thread.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4videoenc.c | 36 +++++++++++++++++++++++++++---------
 libavcodec/mpeg4videoenc.h |  4 ++--
 libavcodec/mpegvideo.h     |  2 --
 libavcodec/mpegvideo_enc.c |  3 +--
 4 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 11872f29eb..18f97bb81d 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -71,6 +71,17 @@ static uint8_t  uni_mpeg4_inter_rl_len[64 * 64 * 2 * 2];
  * max run: 29/41
  */
 
+typedef struct Mpeg4EncContext {
+    MPVMainEncContext m;
+    /// number of bits to represent the fractional part of time
+    int time_increment_bits;
+} Mpeg4EncContext;
+
+static inline Mpeg4EncContext *mainctx_to_mpeg4(MPVMainEncContext *m)
+{
+    return (Mpeg4EncContext*)m;
+}
+
 /**
  * Return the number of bits that encoding the 8x8 block in block would need.
  * @param[in]  block_last_index last index in scantable order that refers to a non zero element in block.
@@ -960,10 +971,11 @@ static void mpeg4_encode_visual_object_header(MpegEncContext *s)
     ff_mpeg4_stuffing(&s->pb);
 }
 
-static void mpeg4_encode_vol_header(MpegEncContext *s,
+static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
                                     int vo_number,
                                     int vol_number)
 {
+    MpegEncContext *const s = &m4->m.s;
     int vo_ver_id, vo_type, aspect_ratio_info;
 
     if (s->max_b_frames || s->quarter_sample) {
@@ -1002,8 +1014,8 @@ static void mpeg4_encode_vol_header(MpegEncContext *s,
     put_bits(&s->pb, 1, 1);             /* marker bit */
 
     put_bits(&s->pb, 16, s->avctx->time_base.den);
-    if (s->time_increment_bits < 1)
-        s->time_increment_bits = 1;
+    if (m4->time_increment_bits < 1)
+        m4->time_increment_bits = 1;
     put_bits(&s->pb, 1, 1);             /* marker bit */
     put_bits(&s->pb, 1, 0);             /* fixed vop rate=no */
     put_bits(&s->pb, 1, 1);             /* marker bit */
@@ -1050,8 +1062,10 @@ static void mpeg4_encode_vol_header(MpegEncContext *s,
 }
 
 /* write MPEG-4 VOP header */
-int ff_mpeg4_encode_picture_header(MpegEncContext *s)
+int ff_mpeg4_encode_picture_header(MPVMainEncContext *const m)
 {
+    Mpeg4EncContext *const m4 = mainctx_to_mpeg4(m);
+    MpegEncContext *const s = &m->s;
     uint64_t time_incr;
     int64_t time_div, time_mod;
 
@@ -1060,7 +1074,7 @@ int ff_mpeg4_encode_picture_header(MpegEncContext *s)
             if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT)  // HACK, the reference sw is buggy
                 mpeg4_encode_visual_object_header(s);
             if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->picture_number == 0)  // HACK, the reference sw is buggy
-                mpeg4_encode_vol_header(s, 0, 0);
+                mpeg4_encode_vol_header(m4, 0, 0);
         }
         mpeg4_encode_gop_header(s);
     }
@@ -1085,7 +1099,7 @@ int ff_mpeg4_encode_picture_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 0);
 
     put_bits(&s->pb, 1, 1);                             /* marker */
-    put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */
+    put_bits(&s->pb, m4->time_increment_bits, time_mod); /* time increment */
     put_bits(&s->pb, 1, 1);                             /* marker */
     put_bits(&s->pb, 1, 1);                             /* vop coded */
     if (s->pict_type == AV_PICTURE_TYPE_P) {
@@ -1276,7 +1290,8 @@ static av_cold void mpeg4_encode_init_static(void)
 static av_cold int encode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
-    MpegEncContext *s = avctx->priv_data;
+    Mpeg4EncContext *const m4 = avctx->priv_data;
+    MpegEncContext  *const  s = &m4->m.s;
     int ret;
 
     if (avctx->width >= (1<<13) || avctx->height >= (1<<13)) {
@@ -1290,7 +1305,10 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, mpeg4_encode_init_static);
 
+    m4->time_increment_bits     = av_log2(avctx->time_base.den - 1) + 1;
+
     s->fcode_tab                = fcode_tab + MAX_MV;
+
     s->min_qcoeff               = -2048;
     s->max_qcoeff               = 2047;
     s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
@@ -1309,7 +1327,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         init_put_bits(&s->pb, s->avctx->extradata, 1024);
 
         mpeg4_encode_visual_object_header(s);
-        mpeg4_encode_vol_header(s, 0, 0);
+        mpeg4_encode_vol_header(m4, 0, 0);
 
 //            ff_mpeg4_stuffing(&s->pb); ?
         flush_put_bits(&s->pb);
@@ -1395,7 +1413,7 @@ const FFCodec ff_mpeg4_encoder = {
     CODEC_LONG_NAME("MPEG-4 part 2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MPEG4,
-    .priv_data_size = sizeof(MPVMainEncContext),
+    .priv_data_size = sizeof(Mpeg4EncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = ff_mpv_encode_end,
diff --git a/libavcodec/mpeg4videoenc.h b/libavcodec/mpeg4videoenc.h
index f0d5c3d077..1c53ce4ede 100644
--- a/libavcodec/mpeg4videoenc.h
+++ b/libavcodec/mpeg4videoenc.h
@@ -25,14 +25,14 @@
 
 #include <stdint.h>
 
-#include "mpegvideo.h"
+#include "mpegvideoenc.h"
 #include "put_bits.h"
 
 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(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.h b/libavcodec/mpegvideo.h
index 2cc6dbf534..b532088730 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -362,8 +362,6 @@ typedef struct MpegEncContext {
     /* MPEG-4 specific */
     int studio_profile;
     int dct_precision;
-    /// number of bits to represent the fractional part of time (encoder only)
-    int time_increment_bits;
     int last_time_base;
     int time_base;                  ///< time in seconds of last I,P,S Frame
     int64_t time;                   ///< time of current frame
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 2cba4deca3..ab67f5444d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -746,7 +746,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                (1 << 16) - 1);
         return AVERROR(EINVAL);
     }
-    s->time_increment_bits = av_log2(avctx->time_base.den - 1) + 1;
 
     switch (avctx->codec->id) {
 #if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
@@ -3919,7 +3918,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
             ff_msmpeg4_encode_picture_header(s);
 #endif
         else if (CONFIG_MPEG4_ENCODER && s->h263_pred) {
-            ret = ff_mpeg4_encode_picture_header(s);
+            ret = ff_mpeg4_encode_picture_header(m);
             if (ret < 0)
                 return ret;
         } else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) {
-- 
2.45.2


[-- Attachment #23: 0022-avcodec-mpegvideo_enc-Move-MPEG-4-specific-check-to-.patch --]
[-- Type: text/x-patch, Size: 2228 bytes --]

From 653ef25c0d328cc705144f0601da81238915e173 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 02:20:03 +0100
Subject: [PATCH 22/77] avcodec/mpegvideo_enc: Move MPEG-4 specific check to
 mpeg4videoenc.c

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4videoenc.c |  9 +++++++++
 libavcodec/mpegvideo_enc.c | 10 ----------
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 18f97bb81d..c265316ed6 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1305,6 +1305,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     ff_thread_once(&init_static_once, mpeg4_encode_init_static);
 
+    if (avctx->time_base.den > (1 << 16) - 1) {
+        av_log(avctx, AV_LOG_ERROR,
+               "timebase %d/%d not supported by MPEG 4 standard, "
+               "the maximum admitted value for the timebase denominator "
+               "is %d\n", avctx->time_base.num, avctx->time_base.den,
+               (1 << 16) - 1);
+        return AVERROR(EINVAL);
+    }
+
     m4->time_increment_bits     = av_log2(avctx->time_base.den - 1) + 1;
 
     s->fcode_tab                = fcode_tab + MAX_MV;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index ab67f5444d..0a9c18ff79 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -737,16 +737,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias);
 
-    if (avctx->codec_id == AV_CODEC_ID_MPEG4 &&
-        avctx->time_base.den > (1 << 16) - 1) {
-        av_log(avctx, AV_LOG_ERROR,
-               "timebase %d/%d not supported by MPEG 4 standard, "
-               "the maximum admitted value for the timebase denominator "
-               "is %d\n", avctx->time_base.num, avctx->time_base.den,
-               (1 << 16) - 1);
-        return AVERROR(EINVAL);
-    }
-
     switch (avctx->codec->id) {
 #if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
     case AV_CODEC_ID_MPEG2VIDEO:
-- 
2.45.2


[-- Attachment #24: 0023-avcodec-mpegvideo-Move-sequence-level-properties-to-.patch --]
[-- Type: text/x-patch, Size: 17822 bytes --]

From 77ab1578003a88587c83ef9d8cc52ca837e6337c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 02:55:04 +0100
Subject: [PATCH 23/77] avcodec/mpegvideo: Move sequence-level properties to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     | 14 ++++---
 libavcodec/mpeg12enc.h     |  4 +-
 libavcodec/mpegvideo.h     | 15 -------
 libavcodec/mpegvideo_enc.c | 86 +++++++++++++++++++-------------------
 libavcodec/mpegvideoenc.h  | 16 +++++++
 libavcodec/ratecontrol.c   |  4 +-
 6 files changed, 71 insertions(+), 68 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index d84d628563..ed2c63086f 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -144,9 +144,9 @@ static void put_header(MpegEncContext *s, uint32_t header)
 }
 
 /* put sequence header if needed */
-static void mpeg1_encode_sequence_header(MpegEncContext *s)
+static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
 {
-    MPEG12EncContext *const mpeg12 = (MPEG12EncContext*)s;
+    MpegEncContext *const s = &mpeg12->mpeg.s;
     unsigned int vbv_buffer_size, fps, v;
     int constraint_parameter_flag;
     AVRational framerate = ff_mpeg12_frame_rate_tab[mpeg12->frame_rate_index];
@@ -299,7 +299,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
     put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
     put_bits(&s->pb, 6, (uint32_t)((time_code % fps)));
     put_bits(&s->pb, 1, !!(s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) ||
-                        s->intra_only || !mpeg12->gop_picture_number);
+                        mpeg12->mpeg.intra_only || !mpeg12->gop_picture_number);
     put_bits(&s->pb, 1, 0);                     // broken link
 }
 
@@ -333,11 +333,13 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s)
     put_bits(&s->pb, 1, 0);
 }
 
-void ff_mpeg1_encode_picture_header(MpegEncContext *s)
+void ff_mpeg1_encode_picture_header(MPVMainEncContext *const m)
 {
-    MPEG12EncContext *const mpeg12 = (MPEG12EncContext*)s;
+    MPEG12EncContext *const mpeg12 = (MPEG12EncContext*)m;
+    MpegEncContext *const s = &m->s;
     const AVFrameSideData *side_data;
-    mpeg1_encode_sequence_header(s);
+
+    mpeg1_encode_sequence_header(mpeg12);
 
     /* MPEG-1 picture header */
     put_header(s, PICTURE_START_CODE);
diff --git a/libavcodec/mpeg12enc.h b/libavcodec/mpeg12enc.h
index 908971905d..fa1504177a 100644
--- a/libavcodec/mpeg12enc.h
+++ b/libavcodec/mpeg12enc.h
@@ -24,10 +24,10 @@
 
 #include <stdint.h>
 
-#include "mpegvideo.h"
+#include "mpegvideoenc.h"
 #include "mpegvideodata.h"
 
-void ff_mpeg1_encode_picture_header(MpegEncContext *s);
+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/mpegvideo.h b/libavcodec/mpegvideo.h
index b532088730..3259c1117c 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -91,8 +91,6 @@ typedef struct MpegEncContext {
     void *private_ctx;
     /* the following parameters must be initialized before encoding */
     int width, height;///< picture size. must be a multiple of 16
-    int gop_size;
-    int intra_only;   ///< if true, only intra pictures are generated
     int64_t bit_rate; ///< wanted bit rate
     enum OutputFormat out_format; ///< output format
     int h263_pred;    ///< use MPEG-4/H.263 ac/dc predictions
@@ -114,10 +112,7 @@ typedef struct MpegEncContext {
 
     /* sequence parameters */
     int context_initialized;
-    int input_picture_number;  ///< used to set pic->display_picture_number, should not be used for/by anything else
-    int coded_picture_number;  ///< used to set pic->coded_picture_number, should not be used for/by anything else
     int picture_number;       //FIXME remove, unclear definition
-    int picture_in_gop_number; ///< 0-> first pic in gop, ...
     int mb_width, mb_height;   ///< number of MBs horizontally & vertically
     int mb_stride;             ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11
     int b8_stride;             ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing
@@ -131,16 +126,6 @@ typedef struct MpegEncContext {
 
     BufferPoolContext buffer_pools;
 
-    int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_send_frame()
-    /**
-     * pts difference between the first and second input frame, used for
-     * calculating dts of the first frame when there's a delay */
-    int64_t dts_delta;
-    /**
-     * reordered pts to be used as dts for the next output frame when there's
-     * a delay */
-    int64_t reordered_pts;
-
     /** bit output */
     PutBitContext pb;
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 0a9c18ff79..cc3c7a745f 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -291,9 +291,6 @@ static av_cold void mpv_encode_defaults(MpegEncContext *s)
         s->y_dc_scale_table =
         s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
     }
-
-    s->input_picture_number  = 0;
-    s->picture_in_gop_number = 0;
 }
 
 av_cold void ff_dct_encode_init(MpegEncContext *s)
@@ -354,9 +351,10 @@ static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx
 }
 
 #define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
-static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
+static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avctx)
 {
-    const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !s->intra_only;
+    MpegEncContext *const s = &m->s;
+    const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !m->intra_only;
     const uint16_t *intra_matrix, *inter_matrix;
     int ret;
 
@@ -368,14 +366,14 @@ static av_cold int init_matrices(MpegEncContext *s, AVCodecContext *avctx)
         s->q_chroma_intra_matrix   = s->q_intra_matrix   + 32;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16 + 32;
         // No need to set q_inter_matrix
-        av_assert1(s->intra_only);
+        av_assert1(m->intra_only);
         // intra_matrix, chroma_intra_matrix will be set later for MJPEG.
         return 0;
     } else {
         s->q_chroma_intra_matrix   = s->q_intra_matrix;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
     }
-    if (!s->intra_only) {
+    if (!m->intra_only) {
         s->q_inter_matrix   = s->q_intra_matrix   + 32;
         s->q_inter_matrix16 = s->q_intra_matrix16 + 32;
     }
@@ -460,7 +458,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                avctx->gop_size, 600);
         avctx->gop_size = 600;
     }
-    s->gop_size     = avctx->gop_size;
+    m->gop_size     = avctx->gop_size;
     s->avctx        = avctx;
     if (avctx->max_b_frames > MPVENC_MAX_B_FRAMES) {
         av_log(avctx, AV_LOG_ERROR, "Too many B-frames requested, maximum "
@@ -499,13 +497,13 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "intra dc precision too large\n");
         return AVERROR(EINVAL);
     }
-    s->user_specified_pts = AV_NOPTS_VALUE;
+    m->user_specified_pts = AV_NOPTS_VALUE;
 
-    if (s->gop_size <= 1) {
-        s->intra_only = 1;
-        s->gop_size   = 12;
+    if (m->gop_size <= 1) {
+        m->intra_only = 1;
+        m->gop_size   = 12;
     } else {
-        s->intra_only = 0;
+        m->intra_only = 0;
     }
 
     /* Fixed QSCALE */
@@ -753,14 +751,14 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     case AV_CODEC_ID_MJPEG:
     case AV_CODEC_ID_AMV:
         s->out_format = FMT_MJPEG;
-        s->intra_only = 1; /* force intra only for jpeg */
+        m->intra_only = 1; /* force intra only for jpeg */
         avctx->delay = 0;
         s->low_delay = 1;
         break;
 #endif
     case AV_CODEC_ID_SPEEDHQ:
         s->out_format = FMT_SPEEDHQ;
-        s->intra_only = 1; /* force intra only for SHQ */
+        m->intra_only = 1; /* force intra only for SHQ */
         avctx->delay = 0;
         s->low_delay = 1;
         break;
@@ -885,7 +883,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->frame_reconstruction_bitfield = (1 << AV_PICTURE_TYPE_I) |
                                            (1 << AV_PICTURE_TYPE_P) |
                                            (1 << AV_PICTURE_TYPE_B);
-    } else if (!s->intra_only) {
+    } else if (!m->intra_only) {
         s->frame_reconstruction_bitfield = (1 << AV_PICTURE_TYPE_I) |
                                            (1 << AV_PICTURE_TYPE_P);
     } else {
@@ -916,7 +914,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         !(s->picture_pool = ff_mpv_alloc_pic_pool(0)))
         return AVERROR(ENOMEM);
 
-    ret = init_matrices(s, avctx);
+    ret = init_matrices(m, avctx);
     if (ret < 0)
         return ret;
 
@@ -1259,11 +1257,11 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
 
     if (pic_arg) {
         pts = pic_arg->pts;
-        display_picture_number = s->input_picture_number++;
+        display_picture_number = m->input_picture_number++;
 
         if (pts != AV_NOPTS_VALUE) {
-            if (s->user_specified_pts != AV_NOPTS_VALUE) {
-                int64_t last = s->user_specified_pts;
+            if (m->user_specified_pts != AV_NOPTS_VALUE) {
+                int64_t last = m->user_specified_pts;
 
                 if (pts <= last) {
                     av_log(s->avctx, AV_LOG_ERROR,
@@ -1273,13 +1271,13 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
                 }
 
                 if (!s->low_delay && display_picture_number == 1)
-                    s->dts_delta = pts - last;
+                    m->dts_delta = pts - last;
             }
-            s->user_specified_pts = pts;
+            m->user_specified_pts = pts;
         } else {
-            if (s->user_specified_pts != AV_NOPTS_VALUE) {
-                s->user_specified_pts =
-                pts = s->user_specified_pts + 1;
+            if (m->user_specified_pts != AV_NOPTS_VALUE) {
+                m->user_specified_pts =
+                pts = m->user_specified_pts + 1;
                 av_log(s->avctx, AV_LOG_INFO,
                        "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n",
                        pts);
@@ -1612,7 +1610,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
 
     /* set next picture type & ordering */
     if (m->frame_skip_threshold || m->frame_skip_factor) {
-        if (s->picture_in_gop_number < s->gop_size &&
+        if (m->picture_in_gop_number < m->gop_size &&
             s->next_pic.ptr &&
             skip_check(m, s->input_picture[0], s->next_pic.ptr)) {
             // FIXME check that the gop check above is +-1 correct
@@ -1624,13 +1622,13 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         }
     }
 
-    if (/*s->picture_in_gop_number >= s->gop_size ||*/
-        !s->next_pic.ptr || s->intra_only) {
+    if (/* m->picture_in_gop_number >= m->gop_size || */
+        !s->next_pic.ptr || m->intra_only) {
         s->reordered_input_picture[0] = s->input_picture[0];
         s->input_picture[0] = NULL;
         s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I;
         s->reordered_input_picture[0]->coded_picture_number =
-            s->coded_picture_number++;
+            m->coded_picture_number++;
     } else {
         int b_frames = 0;
 
@@ -1700,10 +1698,10 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
                     "warning, too many B-frames in a row\n");
         }
 
-        if (s->picture_in_gop_number + b_frames >= s->gop_size) {
+        if (m->picture_in_gop_number + b_frames >= m->gop_size) {
             if ((s->mpv_flags & FF_MPV_FLAG_STRICT_GOP) &&
-                s->gop_size > s->picture_in_gop_number) {
-                b_frames = s->gop_size - s->picture_in_gop_number - 1;
+                m->gop_size > m->picture_in_gop_number) {
+                b_frames = m->gop_size - m->picture_in_gop_number - 1;
             } else {
                 if (s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)
                     b_frames = 0;
@@ -1720,14 +1718,14 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         if (s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_I)
             s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_P;
         s->reordered_input_picture[0]->coded_picture_number =
-            s->coded_picture_number++;
+            m->coded_picture_number++;
         for (int i = 0; i < b_frames; i++) {
             s->reordered_input_picture[i + 1] = s->input_picture[i];
             s->input_picture[i]               = NULL;
             s->reordered_input_picture[i + 1]->f->pict_type =
                 AV_PICTURE_TYPE_B;
             s->reordered_input_picture[i + 1]->coded_picture_number =
-                s->coded_picture_number++;
+                m->coded_picture_number++;
         }
     }
 
@@ -1794,11 +1792,13 @@ fail:
     return ret;
 }
 
-static void frame_end(MpegEncContext *s)
+static void frame_end(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
+
     if (s->unrestricted_mv &&
         s->cur_pic.reference &&
-        !s->intra_only) {
+        !m->intra_only) {
         int hshift = s->chroma_x_shift;
         int vshift = s->chroma_y_shift;
         s->mpvencdsp.draw_edges(s->cur_pic.data[0],
@@ -1878,7 +1878,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
     s->vbv_ignore_qmax = 0;
 
-    s->picture_in_gop_number++;
+    m->picture_in_gop_number++;
 
     ret = load_input_picture(m, pic_arg);
     if (ret < 0)
@@ -1923,7 +1923,7 @@ vbv_retry:
         if (ret < 0)
             return -1;
 
-        frame_end(s);
+        frame_end(m);
 
        if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) && s->out_format == FMT_MJPEG)
             ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
@@ -2066,10 +2066,10 @@ vbv_retry:
         pkt->duration = s->cur_pic.ptr->f->duration;
         if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {
             if (!s->cur_pic.ptr->coded_picture_number)
-                pkt->dts = pkt->pts - s->dts_delta;
+                pkt->dts = pkt->pts - m->dts_delta;
             else
-                pkt->dts = s->reordered_pts;
-            s->reordered_pts = pkt->pts;
+                pkt->dts = m->reordered_pts;
+            m->reordered_pts = pkt->pts;
         } else
             pkt->dts = pkt->pts;
 
@@ -3882,7 +3882,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     s->cur_pic.ptr->f->pict_type = s->pict_type;
 
     if (s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
-        s->picture_in_gop_number=0;
+        m->picture_in_gop_number = 0;
 
     s->mb_x = s->mb_y = 0;
     s->last_bits= put_bits_count(&s->pb);
@@ -3925,7 +3925,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         break;
     case FMT_MPEG1:
         if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
-            ff_mpeg1_encode_picture_header(s);
+            ff_mpeg1_encode_picture_header(m);
         break;
     default:
         av_assert0(0);
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 9f0d63c31e..a76d17f63e 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -39,6 +39,22 @@
 typedef struct MPVMainEncContext {
     MpegEncContext s;  ///< The main slicecontext
 
+    int intra_only;                ///< if true, only intra pictures are generated
+    int gop_size;
+    int picture_in_gop_number;     ///< 0-> first pic in gop, ...
+    int input_picture_number;      ///< used to set pic->display_picture_number
+    int coded_picture_number;      ///< used to set pic->coded_picture_number
+
+    int64_t user_specified_pts;    ///< last non-zero pts from user-supplied AVFrame
+    /**
+     * pts difference between the first and second input frame, used for
+     * calculating dts of the first frame when there's a delay */
+    int64_t dts_delta;
+    /**
+     * reordered pts to be used as dts for the next output frame when there's
+     * a delay */
+    int64_t reordered_pts;
+
     /// temporary frames used by b_frame_strategy = 2
     AVFrame *tmp_frames[MPVENC_MAX_B_FRAMES + 2];
     int b_frame_strategy;
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index ebc3a30fc1..4aa358a4e5 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -660,7 +660,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
                 double bits = rcc->initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
                 RateControlEntry rce;
 
-                if (i % ((s->gop_size + 3) / 4) == 0)
+                if (i % ((m->gop_size + 3) / 4) == 0)
                     rce.pict_type = AV_PICTURE_TYPE_I;
                 else if (i % (s->max_b_frames + 1))
                     rce.pict_type = AV_PICTURE_TYPE_B;
@@ -1033,7 +1033,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
         av_assert0(q > 0.0);
 
         // FIXME type dependent blur like in 2-pass
-        if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) {
+        if (pict_type == AV_PICTURE_TYPE_P || m->intra_only) {
             rcc->short_term_qsum   *= a->qblur;
             rcc->short_term_qcount *= a->qblur;
 
-- 
2.45.2


[-- Attachment #25: 0024-avcodec-mpegvideo-Move-ratecontrol-adjacent-fields-t.patch --]
[-- Type: text/x-patch, Size: 15567 bytes --]

From f1ee64b9e2b800ff6e4f58efd161b9d3a6bcdefe Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 04:01:24 +0100
Subject: [PATCH 24/77] avcodec/mpegvideo: Move ratecontrol-adjacent fields to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  6 ------
 libavcodec/mpegvideo_enc.c | 40 ++++++++++++++++++++------------------
 libavcodec/mpegvideoenc.h  | 15 ++++++++++----
 libavcodec/ratecontrol.c   | 18 +++++++++--------
 libavcodec/snowenc.c       |  4 ++--
 5 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 3259c1117c..6c71d9bc01 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -101,7 +101,6 @@ typedef struct MpegEncContext {
     int h263_flv;     ///< use flv H.263 header
 
     enum AVCodecID codec_id;     /* see AV_CODEC_ID_xxx */
-    int fixed_qscale; ///< fixed qscale if non zero
     int encoding;     ///< true if we are encoding (vs decoding)
     int max_b_frames; ///< max number of B-frames for encoding
     int luma_elim_threshold;
@@ -478,10 +477,6 @@ typedef struct MpegEncContext {
     me_cmp_func sse_cmp[2];
     int (*sum_abs_dctelem)(const int16_t *block);
 
-    float border_masking;
-    int lmin, lmax;
-    int vbv_ignore_qmax;
-
     /// Bitfield containing information which frames to reconstruct.
     int frame_reconstruction_bitfield;
 
@@ -493,7 +488,6 @@ typedef struct MpegEncContext {
 
     int error_rate;
 
-    int scenechange_threshold;
     int noise_reduction;
 
     int intra_penalty;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index cc3c7a745f..06314dc602 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -195,8 +195,10 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
     }
 }
 
-static inline void update_qscale(MpegEncContext *s)
+static inline void update_qscale(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
+
     if (s->q_scale_type == 1 && 0) {
         int i;
         int bestdiff=INT_MAX;
@@ -205,7 +207,7 @@ static inline void update_qscale(MpegEncContext *s)
         for (i = 0 ; i<FF_ARRAY_ELEMS(ff_mpeg2_non_linear_qscale); i++) {
             int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->lambda * 139);
             if (ff_mpeg2_non_linear_qscale[i] < s->avctx->qmin ||
-                (ff_mpeg2_non_linear_qscale[i] > s->avctx->qmax && !s->vbv_ignore_qmax))
+                (ff_mpeg2_non_linear_qscale[i] > s->avctx->qmax && !m->vbv_ignore_qmax))
                 continue;
             if (diff < bestdiff) {
                 bestdiff = diff;
@@ -216,7 +218,7 @@ static inline void update_qscale(MpegEncContext *s)
     } else {
         s->qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >>
                     (FF_LAMBDA_SHIFT + 7);
-        s->qscale = av_clip(s->qscale, s->avctx->qmin, s->vbv_ignore_qmax ? 31 : s->avctx->qmax);
+        s->qscale = av_clip(s->qscale, s->avctx->qmin, m->vbv_ignore_qmax ? 31 : s->avctx->qmax);
     }
 
     s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
@@ -507,16 +509,16 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     }
 
     /* Fixed QSCALE */
-    s->fixed_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
+    m->fixed_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
 
     s->adaptive_quant = (avctx->lumi_masking ||
                          avctx->dark_masking ||
                          avctx->temporal_cplx_masking ||
                          avctx->spatial_cplx_masking  ||
                          avctx->p_masking      ||
-                         s->border_masking ||
+                         m->border_masking ||
                          (s->mpv_flags & FF_MPV_FLAG_QP_RD)) &&
-                        !s->fixed_qscale;
+                        !m->fixed_qscale;
 
     s->loop_filter = !!(avctx->flags & AV_CODEC_FLAG_LOOP_FILTER);
 
@@ -580,7 +582,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    if (!s->fixed_qscale &&
+    if (!m->fixed_qscale &&
         avctx->bit_rate * av_q2d(avctx->time_base) >
             avctx->bit_rate_tolerance) {
         double nbt = avctx->bit_rate * av_q2d(avctx->time_base) * 5;
@@ -675,7 +677,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    if (s->scenechange_threshold < 1000000000 &&
+    if (m->scenechange_threshold < 1000000000 &&
         (avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)) {
         av_log(avctx, AV_LOG_ERROR,
                "closed gop with scene change detection are not supported yet, "
@@ -890,9 +892,9 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->frame_reconstruction_bitfield = 0;
     }
 
-    if (s->lmin > s->lmax) {
-        av_log(avctx, AV_LOG_WARNING, "Clipping lmin value to %d\n", s->lmax);
-        s->lmin = s->lmax;
+    if (m->lmin > m->lmax) {
+        av_log(avctx, AV_LOG_WARNING, "Clipping lmin value to %d\n", m->lmax);
+        m->lmin = m->lmax;
     }
 
     /* init */
@@ -1876,7 +1878,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
     ff_mpv_unref_picture(&s->cur_pic);
 
-    s->vbv_ignore_qmax = 0;
+    m->vbv_ignore_qmax = 0;
 
     m->picture_in_gop_number++;
 
@@ -1935,7 +1937,7 @@ vbv_retry:
             int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139;
 
             if (put_bits_count(&s->pb) > max_size &&
-                s->lambda < s->lmax) {
+                s->lambda < m->lmax) {
                 m->next_lambda = FFMAX(s->lambda + min_step, s->lambda *
                                        (s->qscale + 1) / s->qscale);
                 if (s->adaptive_quant) {
@@ -1955,7 +1957,7 @@ vbv_retry:
                     s->time_base       = s->last_time_base;
                     s->last_non_b_time = s->time - s->pp_time;
                 }
-                s->vbv_ignore_qmax = 1;
+                m->vbv_ignore_qmax = 1;
                 av_log(avctx, AV_LOG_VERBOSE, "reencoding frame due to VBV\n");
                 goto vbv_retry;
             }
@@ -3616,7 +3618,7 @@ static int estimate_qp(MPVMainEncContext *const m, int dry_run)
     if (m->next_lambda){
         s->cur_pic.ptr->f->quality = m->next_lambda;
         if(!dry_run) m->next_lambda= 0;
-    } else if (!s->fixed_qscale) {
+    } else if (!m->fixed_qscale) {
         int quality = ff_rate_estimate_qscale(m, dry_run);
         s->cur_pic.ptr->f->quality = quality;
         if (s->cur_pic.ptr->f->quality < 0)
@@ -3643,7 +3645,7 @@ static int estimate_qp(MPVMainEncContext *const m, int dry_run)
         //FIXME broken
     }else
         s->lambda = s->cur_pic.ptr->f->quality;
-    update_qscale(s);
+    update_qscale(m);
     return 0;
 }
 
@@ -3700,7 +3702,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
             s->lambda= s->last_lambda_for[s->pict_type];
         else
             s->lambda= s->last_lambda_for[s->last_non_b_pict_type];
-        update_qscale(s);
+        update_qscale(m);
     }
 
     ff_me_init_pic(s);
@@ -3742,7 +3744,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         for(i=0; i<s->mb_stride*s->mb_height; i++)
             s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
 
-        if(!s->fixed_qscale){
+        if (!m->fixed_qscale) {
             /* finding spatial complexity for I-frame rate control */
             s->avctx->execute(s->avctx, mb_var_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
         }
@@ -3754,7 +3756,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     s->mb_var_sum    = s->me.   mb_var_sum_temp;
     emms_c();
 
-    if (s->me.scene_change_score > s->scenechange_threshold &&
+    if (s->me.scene_change_score > m->scenechange_threshold &&
         s->pict_type == AV_PICTURE_TYPE_P) {
         s->pict_type= AV_PICTURE_TYPE_I;
         for(i=0; i<s->mb_stride*s->mb_height; i++)
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index a76d17f63e..1fbe5590df 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -39,6 +39,8 @@
 typedef struct MPVMainEncContext {
     MpegEncContext s;  ///< The main slicecontext
 
+    int scenechange_threshold;
+
     int intra_only;                ///< if true, only intra pictures are generated
     int gop_size;
     int picture_in_gop_number;     ///< 0-> first pic in gop, ...
@@ -61,6 +63,10 @@ typedef struct MPVMainEncContext {
     int b_sensitivity;
     int brd_scale;
 
+    float border_masking;
+    int lmin, lmax;
+    int vbv_ignore_qmax;
+
     /* frame skip options */
     int frame_skip_threshold;
     int frame_skip_factor;
@@ -73,6 +79,7 @@ typedef struct MPVMainEncContext {
     int frame_bits;                ///< bits used for the current frame
     int stuffing_bits;             ///< bits used for stuffing
     int next_lambda;               ///< next lambda used for retrying to encode a frame
+    int fixed_qscale;              ///< fixed qscale if non zero
     RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
 } MPVMainEncContext;
 
@@ -154,14 +161,14 @@ FF_MPV_OPT_CMP_FUNC, \
                                                                     FF_RC_OFFSET(rc_eq), AV_OPT_TYPE_STRING,                           .flags = FF_MPV_OPT_FLAGS },            \
 {"rc_init_cplx", "initial complexity for 1-pass encoding",          FF_RC_OFFSET(initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},       \
 {"rc_buf_aggressivity", "currently useless",                        FF_RC_OFFSET(buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
-{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},    \
-{"lmin", "minimum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
-{"lmax", "maximum Lagrange factor (VBR)",                           FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
+{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_MAIN_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS},    \
+{"lmin", "minimum Lagrange factor (VBR)",                           FF_MPV_MAIN_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
+{"lmax", "maximum Lagrange factor (VBR)",                           FF_MPV_MAIN_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS },            \
 {"skip_threshold", "Frame skip threshold",                          FF_MPV_MAIN_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_factor", "Frame skip factor",                                FF_MPV_MAIN_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_exp", "Frame skip exponent",                                 FF_MPV_MAIN_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_cmp", "Frame skip compare function",                         FF_MPV_MAIN_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
-{"sc_threshold", "Scene change threshold",                          FF_MPV_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"sc_threshold", "Scene change threshold",                          FF_MPV_MAIN_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"noise_reduction", "Noise reduction",                              FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"ps", "RTP payload size in bytes",                             FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 4aa358a4e5..f4df67aab0 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -142,10 +142,11 @@ static double get_diff_limited_q(MPVMainEncContext *m, const RateControlEntry *r
 /**
  * Get the qmin & qmax for pict_type.
  */
-static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type)
+static void get_qminmax(int *qmin_ret, int *qmax_ret, MPVMainEncContext *const m, int pict_type)
 {
-    int qmin = s->lmin;
-    int qmax = s->lmax;
+    MpegEncContext *const s = &m->s;
+    int qmin = m->lmin;
+    int qmax = m->lmax;
 
     av_assert0(qmin <= qmax);
 
@@ -182,7 +183,7 @@ static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *
     const int pict_type      = rce->new_pict_type;
     int qmin, qmax;
 
-    get_qminmax(&qmin, &qmax, s, pict_type);
+    get_qminmax(&qmin, &qmax, m, pict_type);
 
     /* modulation */
     if (rcc->qmod_freq &&
@@ -784,15 +785,16 @@ static void update_predictor(Predictor *p, double q, double var, double size)
 }
 
 static void adaptive_quantization(RateControlContext *const rcc,
-                                  MpegEncContext *const s, double q)
+                                  MPVMainEncContext *const m, double q)
 {
+    MpegEncContext *const s = &m->s;
     int i;
     const float lumi_masking         = s->avctx->lumi_masking / (128.0 * 128.0);
     const float dark_masking         = s->avctx->dark_masking / (128.0 * 128.0);
     const float temp_cplx_masking    = s->avctx->temporal_cplx_masking;
     const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
     const float p_masking            = s->avctx->p_masking;
-    const float border_masking       = s->border_masking;
+    const float border_masking       = m->border_masking;
     float bits_sum                   = 0.0;
     float cplx_sum                   = 0.0;
     float *cplx_tab                  = rcc->cplx_tab;
@@ -932,7 +934,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
     const int pict_type = s->pict_type;
     emms_c();
 
-    get_qminmax(&qmin, &qmax, s, pict_type);
+    get_qminmax(&qmin, &qmax, m, pict_type);
 
     fps = get_fps(s->avctx);
     /* update predictors */
@@ -1068,7 +1070,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
         q = qmax;
 
     if (s->adaptive_quant)
-        adaptive_quantization(rcc, s, q);
+        adaptive_quantization(rcc, m, q);
     else
         q = (int)(q + 0.5);
 
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 830f6f5096..d974a12f6b 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -228,8 +228,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     mpv->avctx   = avctx;
     mpv->bit_rate= avctx->bit_rate;
-    mpv->lmin    = avctx->mb_lmin;
-    mpv->lmax    = avctx->mb_lmax;
+    enc->m.lmin  = avctx->mb_lmin;
+    enc->m.lmax  = avctx->mb_lmax;
     mpv->mb_num  = (avctx->width * avctx->height + 255) / 256; // For ratecontrol
 
     mpv->me.temp      =
-- 
2.45.2


[-- Attachment #26: 0025-avcodec-mpegvideoenc-Disable-scenechange-threshold-o.patch --]
[-- Type: text/x-patch, Size: 4563 bytes --]

From bbea7caa24368f0543f8bff9395741d34201e83b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 06:29:35 +0100
Subject: [PATCH 25/77] avcodec/mpegvideoenc: Disable scenechange threshold opt
 for MJPEG, AMV

It makes no sense for them. Also do the same for the mv0 flag.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideoenc.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 1fbe5590df..17bf50443d 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -142,7 +142,6 @@ FF_MPV_OPT_CMP_FUNC, \
 { "qp_rd",          "Use rate distortion optimization for qp selection", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_QP_RD },  0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
 { "cbp_rd",         "use rate distortion optimization for CBP",          0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_CBP_RD }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
 { "naq",            "normalize adaptive quantization",                   0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_NAQ },    0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
-{ "mv0",            "always try a mb with mv=<0,0>",                     0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 },    0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
 { "luma_elim_threshold",   "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)",\
                                                                       FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
 { "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\
@@ -168,7 +167,6 @@ FF_MPV_OPT_CMP_FUNC, \
 {"skip_factor", "Frame skip factor",                                FF_MPV_MAIN_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_exp", "Frame skip exponent",                                 FF_MPV_MAIN_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_cmp", "Frame skip compare function",                         FF_MPV_MAIN_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
-{"sc_threshold", "Scene change threshold",                          FF_MPV_MAIN_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"noise_reduction", "Noise reduction",                              FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"ps", "RTP payload size in bytes",                             FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 
@@ -178,6 +176,7 @@ FF_MPV_OPT_CMP_FUNC, \
 {"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_MAIN_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS },
 
 #define FF_MPV_COMMON_MOTION_EST_OPTS \
+{ "mv0",            "always try a mb with mv=<0,0>",                     0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 },    0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
 {"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
 { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
@@ -185,6 +184,7 @@ FF_MPV_OPT_CMP_FUNC, \
 {"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"intra_penalty", "Penalty for intra blocks in block decision", FF_MPV_OFFSET(intra_penalty), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX/2, FF_MPV_OPT_FLAGS }, \
+{"sc_threshold", "Scene change threshold",                          FF_MPV_MAIN_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 
 extern const AVClass ff_mpv_enc_class;
 
-- 
2.45.2


[-- Attachment #27: 0026-avcodec-mpegvideo-Move-macroblock-variance-stats-to-.patch --]
[-- Type: text/x-patch, Size: 5948 bytes --]

From 922e53781b442add21a381da7ef713e72ca8adb8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Thu, 13 Oct 2022 02:15:46 +0200
Subject: [PATCH 26/77] avcodec/mpegvideo: Move macroblock-variance stats to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  2 --
 libavcodec/mpegvideo_enc.c |  6 +++---
 libavcodec/mpegvideoenc.h  |  3 +++
 libavcodec/ratecontrol.c   | 16 ++++++++--------
 libavcodec/snowenc.c       |  8 ++++----
 5 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 6c71d9bc01..bdd3196060 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -230,8 +230,6 @@ typedef struct MpegEncContext {
     uint16_t *mb_var;           ///< Table for MB variances
     uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
     uint8_t *mb_mean;           ///< Table for MB luminance
-    int64_t mb_var_sum;         ///< sum of MB variance for current frame
-    int64_t mc_mb_var_sum;      ///< motion compensated MB variance for current frame
     uint64_t encoding_error[MPV_MAX_PLANES];
 
     int motion_est;                      ///< ME algorithm
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 06314dc602..44bad9eb52 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3752,8 +3752,8 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     for(i=1; i<context_count; i++){
         merge_context_after_me(s, s->thread_context[i]);
     }
-    s->mc_mb_var_sum = s->me.mc_mb_var_sum_temp;
-    s->mb_var_sum    = s->me.   mb_var_sum_temp;
+    m->mc_mb_var_sum = s->me.mc_mb_var_sum_temp;
+    m->mb_var_sum    = s->me.   mb_var_sum_temp;
     emms_c();
 
     if (s->me.scene_change_score > m->scenechange_threshold &&
@@ -3764,7 +3764,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         if (s->msmpeg4_version >= MSMP4_V3)
             s->no_rounding=1;
         ff_dlog(s->avctx, "Scene change detected, encoding as I Frame %"PRId64" %"PRId64"\n",
-                s->mb_var_sum, s->mc_mb_var_sum);
+                m->mb_var_sum, m->mc_mb_var_sum);
     }
 
     if(!s->umvplus){
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 17bf50443d..283fa8f705 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -81,6 +81,9 @@ typedef struct MPVMainEncContext {
     int next_lambda;               ///< next lambda used for retrying to encode a frame
     int fixed_qscale;              ///< fixed qscale if non zero
     RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
+
+    int64_t mb_var_sum;            ///< sum of MB variance for current frame
+    int64_t mc_mb_var_sum;         ///< motion compensated MB variance for current frame
 } MPVMainEncContext;
 
 #define MAX_FCODE        7
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index f4df67aab0..9c5d34dfde 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -51,8 +51,8 @@ void ff_write_pass1_stats(MPVMainEncContext *const m)
              s->misc_bits,
              s->f_code,
              s->b_code,
-             s->mc_mb_var_sum,
-             s->mb_var_sum,
+             m->mc_mb_var_sum,
+             m->mb_var_sum,
              s->i_count,
              s->header_bits);
 }
@@ -986,7 +986,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
     if (br_compensation <= 0.0)
         br_compensation = 0.001;
 
-    var = pict_type == AV_PICTURE_TYPE_I ? s->mb_var_sum : s->mc_mb_var_sum;
+    var = pict_type == AV_PICTURE_TYPE_I ? m->mb_var_sum : m->mc_mb_var_sum;
 
     short_term_q = 0; /* avoid warning */
     if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
@@ -999,8 +999,8 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
     } else {
         rce->pict_type     =
         rce->new_pict_type = pict_type;
-        rce->mc_mb_var_sum = s->mc_mb_var_sum;
-        rce->mb_var_sum    = s->mb_var_sum;
+        rce->mc_mb_var_sum = m->mc_mb_var_sum;
+        rce->mb_var_sum    = m->mb_var_sum;
         rce->qscale        = FF_QP2LAMBDA * 2;
         rce->f_code        = s->f_code;
         rce->b_code        = s->b_code;
@@ -1060,7 +1060,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
                qmin, q, qmax, picture_number,
                wanted_bits / 1000, m->total_bits / 1000,
                br_compensation, short_term_q, m->frame_bits,
-               s->mb_var_sum, s->mc_mb_var_sum,
+               m->mb_var_sum, m->mc_mb_var_sum,
                s->bit_rate / 1000, (int)fps);
     }
 
@@ -1076,8 +1076,8 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
 
     if (!dry_run) {
         rcc->last_qscale        = q;
-        rcc->last_mc_mb_var_sum = s->mc_mb_var_sum;
-        rcc->last_mb_var_sum    = s->mb_var_sum;
+        rcc->last_mc_mb_var_sum = m->mc_mb_var_sum;
+        rcc->last_mb_var_sum    = m->mb_var_sum;
     }
     return q;
 }
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index d974a12f6b..e074e878d6 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1708,11 +1708,11 @@ static int ratecontrol_1pass(SnowEncContext *enc, AVFrame *pict)
     coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
 
     if(pict->pict_type == AV_PICTURE_TYPE_I){
-        enc->m.s.mb_var_sum    = coef_sum;
-        enc->m.s.mc_mb_var_sum = 0;
+        enc->m.mb_var_sum    = coef_sum;
+        enc->m.mc_mb_var_sum = 0;
     }else{
-        enc->m.s.mc_mb_var_sum = coef_sum;
-        enc->m.s.mb_var_sum    = 0;
+        enc->m.mc_mb_var_sum = coef_sum;
+        enc->m.mb_var_sum    = 0;
     }
 
     pict->quality= ff_rate_estimate_qscale(&enc->m, 1);
-- 
2.45.2


[-- Attachment #28: 0027-avcodec-mpegvideo-Move-header_bits-to-MPVMainEncCont.patch --]
[-- Type: text/x-patch, Size: 5051 bytes --]

From 626b8ecf0e9767a11ca419ab0e56a2926c744dd4 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 29 Jan 2022 05:34:14 +0100
Subject: [PATCH 27/77] avcodec/mpegvideo: Move header_bits to
 MPVMainEncContext

The header is always written by the main thread, so it is
not surprising that header_bits can be moved to MPVMainEncContext
as well.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c      | 10 +++++++---
 libavcodec/mpegvideo.h     |  1 -
 libavcodec/mpegvideo_enc.c |  6 +++---
 libavcodec/mpegvideoenc.h  |  1 +
 libavcodec/ratecontrol.c   |  2 +-
 5 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 6f9818baf2..a77a703f53 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -119,8 +119,9 @@ void ff_mjpeg_amv_encode_picture_header(MpegEncContext *s)
  *
  * @param s The MpegEncContext.
  */
-static void mjpeg_encode_picture_frame(MpegEncContext *s)
+static void mjpeg_encode_picture_frame(MPVMainEncContext *const main)
 {
+    MpegEncContext *const s = &main->s;
     int nbits, code, table_id;
     MJpegContext *m = s->mjpeg_ctx;
     uint8_t  *huff_size[4] = { m->huff_size_dc_luminance,
@@ -134,7 +135,7 @@ static void mjpeg_encode_picture_frame(MpegEncContext *s)
     size_t total_bits = 0;
     size_t bytes_needed;
 
-    s->header_bits = get_bits_diff(s);
+    main->header_bits = get_bits_diff(s);
     // Estimate the total size first
     for (int i = 0; i < m->huff_ncode; i++) {
         table_id = m->huff_buffer[i].table_id;
@@ -240,6 +241,9 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s)
 
 #if CONFIG_MJPEG_ENCODER
     if (m->huffman == HUFFMAN_TABLE_OPTIMAL) {
+        /* HUFFMAN_TABLE_OPTIMAL is incompatible with slice threading,
+         * therefore the following cast is allowed. */
+        MPVMainEncContext *const main = (MPVMainEncContext*)s;
 
         mjpeg_build_optimal_huffman(m);
 
@@ -253,7 +257,7 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s)
         s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len;
 
         mjpeg_encode_picture_header(s);
-        mjpeg_encode_picture_frame(s);
+        mjpeg_encode_picture_frame(main);
     }
 #endif
 
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index bdd3196060..fcc51af41a 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -310,7 +310,6 @@ typedef struct MpegEncContext {
 
     /* statistics, used for 2-pass encoding */
     int mv_bits;
-    int header_bits;
     int i_tex_bits;
     int p_tex_bits;
     int i_count;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 44bad9eb52..d4f4f825ff 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1928,7 +1928,7 @@ vbv_retry:
         frame_end(m);
 
        if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) && s->out_format == FMT_MJPEG)
-            ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
+            ff_mjpeg_encode_picture_trailer(&s->pb, m->header_bits);
 
         if (avctx->rc_buffer_size) {
             RateControlContext *rcc = &m->rc_context;
@@ -1976,7 +1976,7 @@ vbv_retry:
                                        s->pict_type);
 
         if (avctx->flags & AV_CODEC_FLAG_PASS1)
-            assert(put_bits_count(&s->pb) == s->header_bits + s->mv_bits +
+            assert(put_bits_count(&s->pb) == m->header_bits + s->mv_bits +
                                              s->misc_bits + s->i_tex_bits +
                                              s->p_tex_bits);
         flush_put_bits(&s->pb);
@@ -3933,7 +3933,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         av_assert0(0);
     }
     bits= put_bits_count(&s->pb);
-    s->header_bits= bits - s->last_bits;
+    m->header_bits = bits - s->last_bits;
 
     for(i=1; i<context_count; i++){
         update_duplicate_context_after_me(s->thread_context[i], s);
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 283fa8f705..9c70fe6d71 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -77,6 +77,7 @@ typedef struct MPVMainEncContext {
     /* bit rate control */
     int64_t total_bits;
     int frame_bits;                ///< bits used for the current frame
+    int header_bits;
     int stuffing_bits;             ///< bits used for stuffing
     int next_lambda;               ///< next lambda used for retrying to encode a frame
     int fixed_qscale;              ///< fixed qscale if non zero
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 9c5d34dfde..895e557877 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -54,7 +54,7 @@ void ff_write_pass1_stats(MPVMainEncContext *const m)
              m->mc_mb_var_sum,
              m->mb_var_sum,
              s->i_count,
-             s->header_bits);
+             m->header_bits);
 }
 
 static AVRational get_fpsQ(AVCodecContext *avctx)
-- 
2.45.2


[-- Attachment #29: 0028-avcodec-speedhqenc-Move-speedhq_encode_init-down.patch --]
[-- Type: text/x-patch, Size: 4100 bytes --]

From 7522f0eb03977271057f67252b0f70393fb7d00c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 19:24:25 +0100
Subject: [PATCH 28/77] avcodec/speedhqenc: Move speedhq_encode_init() down

Will avoid forward declarations later.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.c | 102 ++++++++++++++++++++--------------------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 2e09016935..daccd0c3bf 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -95,57 +95,6 @@ static av_cold void speedhq_init_static_data(void)
                              ff_speedhq_vlc_table, uni_speedhq_ac_vlc_len);
 }
 
-static av_cold int speedhq_encode_init(AVCodecContext *avctx)
-{
-    static AVOnce init_static_once = AV_ONCE_INIT;
-    MpegEncContext *const s = avctx->priv_data;
-    int ret;
-
-    if (avctx->width > 65500 || avctx->height > 65500) {
-        av_log(avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
-        return AVERROR(EINVAL);
-    }
-
-    // border is not implemented correctly at the moment, see ticket #10078
-    if (avctx->width % 16) {
-        av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
-        return AVERROR_PATCHWELCOME;
-    }
-
-    switch (avctx->pix_fmt) {
-    case AV_PIX_FMT_YUV420P:
-        avctx->codec_tag = MKTAG('S','H','Q','0');
-        break;
-    case AV_PIX_FMT_YUV422P:
-        avctx->codec_tag = MKTAG('S','H','Q','2');
-        break;
-    case AV_PIX_FMT_YUV444P:
-        avctx->codec_tag = MKTAG('S','H','Q','4');
-        break;
-    default:
-        av_assert0(0);
-    }
-
-    s->min_qcoeff = -2048;
-    s->max_qcoeff = 2047;
-
-    s->intra_ac_vlc_length      =
-    s->intra_ac_vlc_last_length =
-    s->intra_chroma_ac_vlc_length      =
-    s->intra_chroma_ac_vlc_last_length = uni_speedhq_ac_vlc_len;
-
-    s->y_dc_scale_table =
-    s->c_dc_scale_table = ff_mpeg12_dc_scale_table[3];
-
-    ret = ff_mpv_encode_init(avctx);
-    if (ret < 0)
-        return ret;
-
-    ff_thread_once(&init_static_once, speedhq_init_static_data);
-
-    return 0;
-}
-
 void ff_speedhq_encode_picture_header(MpegEncContext *s)
 {
     SpeedHQEncContext *ctx = (SpeedHQEncContext*)s;
@@ -278,6 +227,57 @@ void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64])
     s->i_tex_bits += get_bits_diff(s);
 }
 
+static av_cold int speedhq_encode_init(AVCodecContext *avctx)
+{
+    static AVOnce init_static_once = AV_ONCE_INIT;
+    MpegEncContext *const s = avctx->priv_data;
+    int ret;
+
+    if (avctx->width > 65500 || avctx->height > 65500) {
+        av_log(avctx, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n");
+        return AVERROR(EINVAL);
+    }
+
+    // border is not implemented correctly at the moment, see ticket #10078
+    if (avctx->width % 16) {
+        av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 16\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+        avctx->codec_tag = MKTAG('S','H','Q','0');
+        break;
+    case AV_PIX_FMT_YUV422P:
+        avctx->codec_tag = MKTAG('S','H','Q','2');
+        break;
+    case AV_PIX_FMT_YUV444P:
+        avctx->codec_tag = MKTAG('S','H','Q','4');
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    s->min_qcoeff = -2048;
+    s->max_qcoeff = 2047;
+
+    s->intra_ac_vlc_length      =
+    s->intra_ac_vlc_last_length =
+    s->intra_chroma_ac_vlc_length      =
+    s->intra_chroma_ac_vlc_last_length = uni_speedhq_ac_vlc_len;
+
+    s->y_dc_scale_table =
+    s->c_dc_scale_table = ff_mpeg12_dc_scale_table[3];
+
+    ret = ff_mpv_encode_init(avctx);
+    if (ret < 0)
+        return ret;
+
+    ff_thread_once(&init_static_once, speedhq_init_static_data);
+
+    return 0;
+}
+
 const FFCodec ff_speedhq_encoder = {
     .p.name         = "speedhq",
     CODEC_LONG_NAME("NewTek SpeedHQ"),
-- 
2.45.2


[-- Attachment #30: 0029-avcodec-wmv2enc-Move-wmv2_encode_init-down.patch --]
[-- Type: text/x-patch, Size: 2252 bytes --]

From c32a691d3a2215fa6b714aa0d73b1c494aa99aed Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 3 Mar 2025 19:28:41 +0100
Subject: [PATCH 29/77] avcodec/wmv2enc: Move wmv2_encode_init() down

Will avoid forward declarations later.
While just at it, forward ff_mpv_encode_init() errors.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/wmv2enc.c | 44 +++++++++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 33569a6d39..55fcc91484 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -73,27 +73,6 @@ static int encode_ext_header(WMV2EncContext *w)
     return 0;
 }
 
-static av_cold int wmv2_encode_init(AVCodecContext *avctx)
-{
-    WMV2EncContext *const w = avctx->priv_data;
-    MpegEncContext *const s = &w->msmpeg4.m.s;
-
-    s->private_ctx = &w->common;
-    if (ff_mpv_encode_init(avctx) < 0)
-        return -1;
-
-    ff_wmv2_common_init(s);
-
-    avctx->extradata_size = WMV2_EXTRADATA_SIZE;
-    avctx->extradata      = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
-    if (!avctx->extradata)
-        return AVERROR(ENOMEM);
-
-    encode_ext_header(w);
-
-    return 0;
-}
-
 int ff_wmv2_encode_picture_header(MpegEncContext *s)
 {
     WMV2EncContext *const w = (WMV2EncContext *) s;
@@ -237,6 +216,29 @@ void ff_wmv2_encode_mb(MpegEncContext *s, int16_t block[6][64],
         s->p_tex_bits += get_bits_diff(s);
 }
 
+static av_cold int wmv2_encode_init(AVCodecContext *avctx)
+{
+    WMV2EncContext *const w = avctx->priv_data;
+    MpegEncContext *const s = &w->msmpeg4.m.s;
+    int ret;
+
+    s->private_ctx = &w->common;
+    ret = ff_mpv_encode_init(avctx);
+    if (ret < 0)
+        return ret;
+
+    ff_wmv2_common_init(s);
+
+    avctx->extradata_size = WMV2_EXTRADATA_SIZE;
+    avctx->extradata      = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
+
+    encode_ext_header(w);
+
+    return 0;
+}
+
 const FFCodec ff_wmv2_encoder = {
     .p.name         = "wmv2",
     CODEC_LONG_NAME("Windows Media Video 8"),
-- 
2.45.2


[-- Attachment #31: 0030-avcodec-mpegvideo_enc-Use-function-ptr-for-encode_pi.patch --]
[-- Type: text/x-patch, Size: 23570 bytes --]

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


[-- Attachment #32: 0031-avcodec-mpegvideo-Move-fcode_tab-to-MPVMainEncContex.patch --]
[-- Type: text/x-patch, Size: 8118 bytes --]

From 4712c5a9d583c529eeedf21b6f06edd0425f5d0c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 7 Feb 2022 10:24:38 +0100
Subject: [PATCH 31/77] avcodec/mpegvideo: Move fcode_tab to MPVMainEncContext

Only used by the main encoding thread.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    |  2 +-
 libavcodec/motion_est.c    |  6 ++++--
 libavcodec/motion_est.h    |  3 ++-
 libavcodec/mpeg12enc.c     |  2 +-
 libavcodec/mpeg4videoenc.c |  2 +-
 libavcodec/mpegvideo.h     |  1 -
 libavcodec/mpegvideo_enc.c | 23 ++++++++++++-----------
 libavcodec/mpegvideoenc.h  |  2 ++
 8 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index c82e0ceffd..739f959e40 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -848,7 +848,7 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
         break;
     case AV_CODEC_ID_H263P:
         if(s->umvplus)
-            s->fcode_tab = umv_fcode_tab + MAX_MV;
+            m->fcode_tab = umv_fcode_tab + MAX_MV;
         if(s->modified_quant){
             s->min_qcoeff= -2047;
             s->max_qcoeff=  2047;
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index f7c8305847..7c08fe53eb 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -1596,12 +1596,14 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
 }
 
 /* find best f_code for ME which do unlimited searches */
-int ff_get_best_fcode(MpegEncContext * s, const int16_t (*mv_table)[2], int type)
+int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2], int type)
 {
+    MpegEncContext *const s = &m->s;
+
     if (s->motion_est != FF_ME_ZERO) {
         int score[8];
         int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2);
-        const uint8_t * fcode_tab = s->fcode_tab;
+        const uint8_t * fcode_tab = m->fcode_tab;
         int best_fcode=-1;
         int best_score=-10000000;
 
diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h
index 12f7cd43ab..d8a2cab3a0 100644
--- a/libavcodec/motion_est.h
+++ b/libavcodec/motion_est.h
@@ -29,6 +29,7 @@
 #include "qpeldsp.h"
 
 struct MpegEncContext;
+typedef struct MPVMainEncContext MPVMainEncContext;
 
 #if ARCH_IA64 // Limit static arrays to avoid gcc failing "short data segment overflowed"
 #define MAX_MV 1024
@@ -136,7 +137,7 @@ int ff_epzs_motion_search(struct MpegEncContext *s, int *mx_ptr, int *my_ptr,
 int ff_get_mb_score(struct MpegEncContext *s, int mx, int my, int src_index,
                     int ref_index, int size, int h, int add_rate);
 
-int ff_get_best_fcode(struct MpegEncContext *s,
+int ff_get_best_fcode(MPVMainEncContext *m,
                       const int16_t (*mv_table)[2], int type);
 
 void ff_fix_long_p_mvs(struct MpegEncContext *s, int type);
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index f28a41f5ff..b67f70c5cd 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1113,7 +1113,7 @@ 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;
+    m->fcode_tab     = fcode_tab + MAX_MV;
     if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
         s->min_qcoeff = -255;
         s->max_qcoeff = 255;
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index f34ea1fcb4..cc3c676e18 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1319,7 +1319,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     m4->time_increment_bits     = av_log2(avctx->time_base.den - 1) + 1;
 
-    s->fcode_tab                = fcode_tab + MAX_MV;
+    m->fcode_tab                = fcode_tab + MAX_MV;
 
     s->min_qcoeff               = -2048;
     s->max_qcoeff               = 2047;
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index fcc51af41a..49e8159769 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -253,7 +253,6 @@ typedef struct MpegEncContext {
     int mv[2][4][2];
     int field_select[2][2];
     int last_mv[2][2][2];             ///< last MV, used for MV prediction in MPEG-1 & B-frame MPEG-4
-    const uint8_t *fcode_tab;         ///< smallest fcode needed for each MV
     int16_t direct_scale_mv[2][64];   ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv
 
     MotionEstContext me;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 03a8ae2687..08fc72edb4 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -278,14 +278,15 @@ static av_cold void mpv_encode_init_static(void)
 /**
  * Set the given MpegEncContext to defaults for encoding.
  */
-static av_cold void mpv_encode_defaults(MpegEncContext *s)
+static av_cold void mpv_encode_defaults(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     static AVOnce init_static_once = AV_ONCE_INIT;
 
     ff_mpv_common_defaults(s);
 
-    if (!s->fcode_tab) {
-        s->fcode_tab = default_fcode_tab + MAX_MV;
+    if (!m->fcode_tab) {
+        m->fcode_tab = default_fcode_tab + MAX_MV;
         ff_thread_once(&init_static_once, mpv_encode_init_static);
     }
     if (!s->y_dc_scale_table) {
@@ -429,7 +430,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     int i, ret;
     int mb_array_size, mv_table_size;
 
-    mpv_encode_defaults(s);
+    mpv_encode_defaults(m);
 
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_YUVJ444P:
@@ -3774,12 +3775,12 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 
     if(!s->umvplus){
         if(s->pict_type==AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
-            s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);
+            s->f_code = ff_get_best_fcode(m, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);
 
             if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
                 int a,b;
-                a= ff_get_best_fcode(s, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select
-                b= ff_get_best_fcode(s, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I);
+                a = ff_get_best_fcode(m, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select
+                b = ff_get_best_fcode(m, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I);
                 s->f_code= FFMAX3(s->f_code, a, b);
             }
 
@@ -3796,12 +3797,12 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         } else if (s->pict_type == AV_PICTURE_TYPE_B) {
             int a, b;
 
-            a = ff_get_best_fcode(s, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD);
-            b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR);
+            a = ff_get_best_fcode(m, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD);
+            b = ff_get_best_fcode(m, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR);
             s->f_code = FFMAX(a, b);
 
-            a = ff_get_best_fcode(s, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD);
-            b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR);
+            a = ff_get_best_fcode(m, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD);
+            b = ff_get_best_fcode(m, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR);
             s->b_code = FFMAX(a, b);
 
             ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1);
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index cd82b16590..4b74f8eb46 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -67,6 +67,8 @@ typedef struct MPVMainEncContext {
     int lmin, lmax;
     int vbv_ignore_qmax;
 
+    const uint8_t *fcode_tab;      ///< smallest fcode needed for each MV
+
     /* frame skip options */
     int frame_skip_threshold;
     int frame_skip_factor;
-- 
2.45.2


[-- Attachment #33: 0032-avcodec-speedhqenc-Remove-declaration-of-non-existen.patch --]
[-- Type: text/x-patch, Size: 775 bytes --]

From 8d086d13a3cda9ec275bddebeff16ed331b1129e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 18:40:11 +0100
Subject: [PATCH 32/77] avcodec/speedhqenc: Remove declaration of non-existent
 function

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/speedhqenc.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index b0e6662279..f02fa1f51a 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -33,7 +33,6 @@
 
 #include "mpegvideo.h"
 
-void ff_speedhq_encode_close(MpegEncContext *s);
 void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 
 void ff_speedhq_end_slice(MpegEncContext *s);
-- 
2.45.2


[-- Attachment #34: 0033-avcodec-mjpegenc-Move-mjpeg_encode_init-down.patch --]
[-- Type: text/x-patch, Size: 6714 bytes --]

From 126096175de96dfd1d9b75dffd4b31fd6bfe1a63 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 18:42:44 +0100
Subject: [PATCH 33/77] avcodec/mjpegenc: Move mjpeg_encode_init() down

Will avoid a forward declaration later.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 149 +++++++++++++++++++++---------------------
 1 file changed, 75 insertions(+), 74 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 7706f52148..4c7a25832b 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -304,80 +304,6 @@ static int alloc_huffman(MJPEGEncContext *const m2)
     return 0;
 }
 
-static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
-{
-    MJPEGEncContext *const m2 = avctx->priv_data;
-    MJpegContext    *const m  = &m2->mjpeg;
-    MpegEncContext  *const s  = &m2->mpeg.s;
-    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.
-        av_log(avctx, AV_LOG_ERROR,
-               "QP RD is no longer compatible with MJPEG or AMV\n");
-        return AVERROR(EINVAL);
-    }
-
-    /* The following check is automatically true for AMV,
-     * but it doesn't hurt either. */
-    ret = ff_mjpeg_encode_check_pix_fmt(avctx);
-    if (ret < 0)
-        return ret;
-
-    if (avctx->width > 65500 || avctx->height > 65500) {
-        av_log(avctx, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
-        return AVERROR(EINVAL);
-    }
-
-    s->min_qcoeff=-1023;
-    s->max_qcoeff= 1023;
-
-    // Build default Huffman tables.
-    // These may be overwritten later with more optimal Huffman tables, but
-    // they are needed at least right now for some processes like trellis.
-    ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance,
-                                 m->huff_code_dc_luminance,
-                                 ff_mjpeg_bits_dc_luminance,
-                                 ff_mjpeg_val_dc);
-    ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance,
-                                 m->huff_code_dc_chrominance,
-                                 ff_mjpeg_bits_dc_chrominance,
-                                 ff_mjpeg_val_dc);
-    ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance,
-                                 m->huff_code_ac_luminance,
-                                 ff_mjpeg_bits_ac_luminance,
-                                 ff_mjpeg_val_ac_luminance);
-    ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance,
-                                 m->huff_code_ac_chrominance,
-                                 ff_mjpeg_bits_ac_chrominance,
-                                 ff_mjpeg_val_ac_chrominance);
-
-    init_uni_ac_vlc(m->huff_size_ac_luminance,   m->uni_ac_vlc_len);
-    init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len);
-    s->intra_ac_vlc_length      =
-    s->intra_ac_vlc_last_length = m->uni_ac_vlc_len;
-    s->intra_chroma_ac_vlc_length      =
-    s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len;
-
-    ret = ff_mpv_encode_init(avctx);
-    if (ret < 0)
-        return ret;
-
-    // Buffers start out empty.
-    m->huff_ncode = 0;
-
-    if (s->slice_context_count > 1)
-        m->huffman = HUFFMAN_TABLE_DEFAULT;
-
-    if (m->huffman == HUFFMAN_TABLE_OPTIMAL)
-        return alloc_huffman(m2);
-
-    return 0;
-}
-
 static av_cold int mjpeg_encode_close(AVCodecContext *avctx)
 {
     MJPEGEncContext *const mjpeg = avctx->priv_data;
@@ -603,6 +529,81 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
     }
 }
 
+static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
+{
+    MJPEGEncContext *const m2 = avctx->priv_data;
+    MJpegContext    *const m  = &m2->mjpeg;
+    MpegEncContext  *const s  = &m2->mpeg.s;
+    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.
+        av_log(avctx, AV_LOG_ERROR,
+               "QP RD is no longer compatible with MJPEG or AMV\n");
+        return AVERROR(EINVAL);
+    }
+
+    /* The following check is automatically true for AMV,
+     * but it doesn't hurt either. */
+    ret = ff_mjpeg_encode_check_pix_fmt(avctx);
+    if (ret < 0)
+        return ret;
+
+    if (avctx->width > 65500 || avctx->height > 65500) {
+        av_log(avctx, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
+        return AVERROR(EINVAL);
+    }
+
+    // Build default Huffman tables.
+    // These may be overwritten later with more optimal Huffman tables, but
+    // they are needed at least right now for some processes like trellis.
+    ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance,
+                                 m->huff_code_dc_luminance,
+                                 ff_mjpeg_bits_dc_luminance,
+                                 ff_mjpeg_val_dc);
+    ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance,
+                                 m->huff_code_dc_chrominance,
+                                 ff_mjpeg_bits_dc_chrominance,
+                                 ff_mjpeg_val_dc);
+    ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance,
+                                 m->huff_code_ac_luminance,
+                                 ff_mjpeg_bits_ac_luminance,
+                                 ff_mjpeg_val_ac_luminance);
+    ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance,
+                                 m->huff_code_ac_chrominance,
+                                 ff_mjpeg_bits_ac_chrominance,
+                                 ff_mjpeg_val_ac_chrominance);
+
+    init_uni_ac_vlc(m->huff_size_ac_luminance,   m->uni_ac_vlc_len);
+    init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len);
+
+    s->min_qcoeff = -1023;
+    s->max_qcoeff =  1023;
+
+    s->intra_ac_vlc_length      =
+    s->intra_ac_vlc_last_length = m->uni_ac_vlc_len;
+    s->intra_chroma_ac_vlc_length      =
+    s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len;
+
+    ret = ff_mpv_encode_init(avctx);
+    if (ret < 0)
+        return ret;
+
+    // Buffers start out empty.
+    m->huff_ncode = 0;
+
+    if (s->slice_context_count > 1)
+        m->huffman = HUFFMAN_TABLE_DEFAULT;
+
+    if (m->huffman == HUFFMAN_TABLE_OPTIMAL)
+        return alloc_huffman(m2);
+
+    return 0;
+}
+
 #if CONFIG_AMV_ENCODER
 // maximum over s->mjpeg_vsample[i]
 #define V_MAX 2
-- 
2.45.2


[-- Attachment #35: 0034-avcodec-mpegvideo_enc-Use-func-ptr-for-encoding-macr.patch --]
[-- Type: text/x-patch, Size: 18160 bytes --]

From ff0dfff3fa4af98ae908edc18249293aacbc50a2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 19:09:24 +0100
Subject: [PATCH 34/77] avcodec/mpegvideo_enc: Use func ptr for encoding
 macroblocks

It gets rid of a switch (with accompanying CONFIG_*_ENCODER checks);
for MJPEG, it even lets one perform the check for whether one is
really encoding or only recording the macroblock once during init.

Furthermore, the switch actually contained lots of dead code --
it is compiled three times (for different pixel formats: 420, 422, 444),
yet most encoders only support 420. The approach used here automatically
fixes this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261enc.c       |  5 ++--
 libavcodec/h261enc.h       |  2 --
 libavcodec/h263enc.h       |  3 ---
 libavcodec/ituh263enc.c    |  8 ++++---
 libavcodec/mjpegenc.c      | 19 +++++++++++----
 libavcodec/mjpegenc.h      |  1 -
 libavcodec/mpeg12enc.c     |  5 ++--
 libavcodec/mpeg12enc.h     |  2 --
 libavcodec/mpeg4videoenc.c |  5 ++--
 libavcodec/mpeg4videoenc.h |  3 ---
 libavcodec/mpegvideo.h     |  4 ++++
 libavcodec/mpegvideo_enc.c | 48 +-------------------------------------
 libavcodec/msmpeg4enc.c    | 10 ++++----
 libavcodec/msmpeg4enc.h    |  2 --
 libavcodec/speedhqenc.c    |  4 +++-
 libavcodec/speedhqenc.h    |  2 --
 libavcodec/wmv2enc.c       |  6 ++---
 libavcodec/wmv2enc.h       | 30 ------------------------
 18 files changed, 45 insertions(+), 114 deletions(-)
 delete mode 100644 libavcodec/wmv2enc.h

diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index bfe805bcdf..81711b3a16 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -228,8 +228,8 @@ static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
         put_bits(&s->pb, 2, 0x2); // EOB
 }
 
-void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
-                       int motion_x, int motion_y)
+static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
+                           int motion_x, int motion_y)
 {
     /* The following is only allowed because this encoder
      * does not use slice threading. */
@@ -374,6 +374,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
     }
     s->private_ctx = &h->common;
     h->s.encode_picture_header = h261_encode_picture_header;
+    s->encode_mb               = h261_encode_mb;
 
     s->min_qcoeff       = -127;
     s->max_qcoeff       = 127;
diff --git a/libavcodec/h261enc.h b/libavcodec/h261enc.h
index 092363b6f3..79cdd31c2f 100644
--- a/libavcodec/h261enc.h
+++ b/libavcodec/h261enc.h
@@ -31,7 +31,5 @@
 #include "mpegvideo.h"
 
 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);
 
 #endif
diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index 29a785dfeb..dd9caa7969 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -28,9 +28,6 @@ const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1];
 
 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],
-                       int motion_x, int motion_y);
 void ff_h263_encode_mba(MpegEncContext *s);
 
 void ff_clean_h263_qscales(MpegEncContext *s);
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 739f959e40..deaf7dc5c6 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -608,9 +608,9 @@ static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
     return pred_dc;
 }
 
-void ff_h263_encode_mb(MpegEncContext * s,
-                       int16_t block[6][64],
-                       int motion_x, int motion_y)
+static void h263_encode_mb(MpegEncContext *const s,
+                           int16_t block[][64],
+                           int motion_x, int motion_y)
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y;
     int16_t pred_dc;
@@ -875,6 +875,8 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
     // H.263, H.263+; will be overwritten for MSMPEG-4 later
     if (!m->encode_picture_header)
         m->encode_picture_header = h263_encode_picture_header;
+    if (!s->encode_mb)
+        s->encode_mb = h263_encode_mb;
 
     ff_h263dsp_init(&s->h263dsp);
 }
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 4c7a25832b..6c58c04892 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -463,10 +463,10 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
         put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
 }
 
-void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
+static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
+                            int unused_x, int unused_y)
 {
     int i;
-    if (s->mjpeg_ctx->huffman == HUFFMAN_TABLE_OPTIMAL) {
         if (s->chroma_format == CHROMA_444) {
             record_block(s, block[0], 0);
             record_block(s, block[2], 2);
@@ -495,7 +495,12 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
                 record_block(s, block[7], 7);
             }
         }
-    } else {
+}
+
+static void mjpeg_encode_mb(MpegEncContext *const s, int16_t block[][64],
+                            int unused_x, int unused_y)
+{
+    int i;
         if (s->chroma_format == CHROMA_444) {
             encode_block(s, block[0], 0);
             encode_block(s, block[2], 2);
@@ -526,7 +531,6 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
         }
 
         s->i_tex_bits += get_bits_diff(s);
-    }
 }
 
 static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
@@ -538,6 +542,8 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
 
     s->mjpeg_ctx = m;
     m2->mpeg.encode_picture_header = mjpeg_amv_encode_picture_header;
+    // May be overridden below
+    s->encode_mb                   = mjpeg_encode_mb;
 
     if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
         // Used to produce garbage with MJPEG.
@@ -598,8 +604,11 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
     if (s->slice_context_count > 1)
         m->huffman = HUFFMAN_TABLE_DEFAULT;
 
-    if (m->huffman == HUFFMAN_TABLE_OPTIMAL)
+    if (m->huffman == HUFFMAN_TABLE_OPTIMAL) {
+        // If we are here, we have only one slice_context. So no loop necessary.
+        s->encode_mb = mjpeg_record_mb;
         return alloc_huffman(m2);
+    }
 
     return 0;
 }
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index 9610656aaa..ceacba9893 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_encode_mb(MpegEncContext *s, int16_t block[12][64]);
 int  ff_mjpeg_encode_stuffing(MpegEncContext *s);
 
 #endif /* AVCODEC_MJPEGENC_H */
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index b67f70c5cd..1ef88d23b8 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -929,8 +929,8 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
     }
 }
 
-void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64],
-                        int motion_x, int motion_y)
+static void mpeg12_encode_mb(MpegEncContext *s, int16_t block[][64],
+                             int motion_x, int motion_y)
 {
     if (!s->mb_intra)
         s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 128 << s->intra_dc_precision;
@@ -1111,6 +1111,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     }
 
     m->encode_picture_header = mpeg1_encode_picture_header;
+    s->encode_mb             = mpeg12_encode_mb;
 
     s->me.mv_penalty = mv_penalty;
     m->fcode_tab     = fcode_tab + MAX_MV;
diff --git a/libavcodec/mpeg12enc.h b/libavcodec/mpeg12enc.h
index 6c3709bbff..8ffa471a63 100644
--- a/libavcodec/mpeg12enc.h
+++ b/libavcodec/mpeg12enc.h
@@ -27,8 +27,6 @@
 #include "mpegvideo.h"
 #include "mpegvideodata.h"
 
-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);
 
 // Must not be called before intra_dc_precision has been sanitized in ff_mpv_encode_init()
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index cc3c676e18..4f97199eba 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -499,8 +499,8 @@ static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
 // FIXME this is duplicated to h263.c
 static const int dquant_code[5] = { 1, 0, 9, 2, 3 };
 
-void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
-                        int motion_x, int motion_y)
+static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
+                            int motion_x, int motion_y)
 {
     int cbpc, cbpy, pred_x, pred_y;
     PutBitContext *const pb2    = s->data_partitioning ? &s->pb2 : &s->pb;
@@ -1301,6 +1301,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     }
 
     m->encode_picture_header = mpeg4_encode_picture_header;
+    s->encode_mb             = mpeg4_encode_mb;
 
     ff_qpeldsp_init(&s->qdsp);
     if ((ret = ff_mpv_encode_init(avctx)) < 0)
diff --git a/libavcodec/mpeg4videoenc.h b/libavcodec/mpeg4videoenc.h
index 4565a518b2..0727be6750 100644
--- a/libavcodec/mpeg4videoenc.h
+++ b/libavcodec/mpeg4videoenc.h
@@ -29,9 +29,6 @@
 
 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);
 
 void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 49e8159769..bdab782b29 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -438,7 +438,11 @@ typedef struct MpegEncContext {
 
     int16_t (*block)[64]; ///< points to one of the following blocks
     int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
+    union {
     int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch()
+        void (*encode_mb)(struct MpegEncContext *s, int16_t block[][64],
+                          int motion_x, int motion_y);
+    };
 
 #define SLICE_OK         0
 #define SLICE_ERROR     -1
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 08fc72edb4..6650e5b35d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -71,7 +71,6 @@
 #include "mpeg4videoenc.h"
 #include "internal.h"
 #include "bytestream.h"
-#include "wmv2enc.h"
 #include "rv10enc.h"
 #include "packet_internal.h"
 #include "libavutil/refstruct.h"
@@ -2562,52 +2561,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         }
     }
 
-    /* huffman encode */
-    switch(s->codec_id){ //FIXME funct ptr could be slightly faster
-    case AV_CODEC_ID_MPEG1VIDEO:
-    case AV_CODEC_ID_MPEG2VIDEO:
-        if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
-            ff_mpeg1_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case AV_CODEC_ID_MPEG4:
-        if (CONFIG_MPEG4_ENCODER)
-            ff_mpeg4_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case AV_CODEC_ID_MSMPEG4V2:
-    case AV_CODEC_ID_MSMPEG4V3:
-    case AV_CODEC_ID_WMV1:
-        if (CONFIG_MSMPEG4ENC)
-            ff_msmpeg4_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case AV_CODEC_ID_WMV2:
-        if (CONFIG_WMV2_ENCODER)
-            ff_wmv2_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case AV_CODEC_ID_H261:
-        if (CONFIG_H261_ENCODER)
-            ff_h261_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case AV_CODEC_ID_H263:
-    case AV_CODEC_ID_H263P:
-    case AV_CODEC_ID_FLV1:
-    case AV_CODEC_ID_RV10:
-    case AV_CODEC_ID_RV20:
-        if (CONFIG_H263_ENCODER)
-            ff_h263_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
-    case AV_CODEC_ID_MJPEG:
-    case AV_CODEC_ID_AMV:
-        ff_mjpeg_encode_mb(s, s->block);
-        break;
-#endif
-    case AV_CODEC_ID_SPEEDHQ:
-        if (CONFIG_SPEEDHQ_ENCODER)
-            ff_speedhq_encode_mb(s, s->block);
-        break;
-    default:
-        av_assert1(0);
-    }
+    s->encode_mb(s, s->block, motion_x, motion_y);
 }
 
 static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 01d5707370..9e58a91a80 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -370,9 +370,9 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val)
     }
 }
 
-void ff_msmpeg4_encode_mb(MpegEncContext * s,
-                          int16_t block[6][64],
-                          int motion_x, int motion_y)
+static void msmpeg4_encode_mb(MpegEncContext *const s,
+                              int16_t block[][64],
+                              int motion_x, int motion_y)
 {
     int cbp, coded_cbp, i;
     int pred_x, pred_y;
@@ -670,8 +670,10 @@ av_cold void ff_msmpeg4_encode_init(MPVMainEncContext *const m)
 
     ff_msmpeg4_common_init(s);
 
-    if (s->msmpeg4_version <= MSMP4_WMV1)
+    if (s->msmpeg4_version <= MSMP4_WMV1) {
         m->encode_picture_header = msmpeg4_encode_picture_header;
+        s->encode_mb             = msmpeg4_encode_mb;
+    }
 
     if (s->msmpeg4_version >= MSMP4_WMV1) {
         s->min_qcoeff = -255;
diff --git a/libavcodec/msmpeg4enc.h b/libavcodec/msmpeg4enc.h
index 5511e01283..dde1fb6b93 100644
--- a/libavcodec/msmpeg4enc.h
+++ b/libavcodec/msmpeg4enc.h
@@ -35,8 +35,6 @@ typedef struct MSMPEG4EncContext {
 
 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);
 void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n);
 void ff_msmpeg4_handle_slices(MpegEncContext *s);
 void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 1ba5dcc68f..1e28702f18 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -207,7 +207,8 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
     put_bits_le(&s->pb, 4, 6);
 }
 
-void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64])
+static void speedhq_encode_mb(MpegEncContext *const s, int16_t block[12][64],
+                              int unused_x, int unused_y)
 {
     int i;
     for(i=0;i<6;i++) {
@@ -263,6 +264,7 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
     }
 
     m->encode_picture_header = speedhq_encode_picture_header;
+    s->encode_mb             = speedhq_encode_mb;
 
     s->min_qcoeff = -2048;
     s->max_qcoeff = 2047;
diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index f02fa1f51a..e804ce714a 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -33,8 +33,6 @@
 
 #include "mpegvideo.h"
 
-void ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]);
-
 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 d70a680fb3..3ab3e75722 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -29,7 +29,6 @@
 #include "msmpeg4data.h"
 #include "msmpeg4_vc1_data.h"
 #include "wmv2.h"
-#include "wmv2enc.h"
 
 #define WMV2_EXTRADATA_SIZE 4
 
@@ -147,8 +146,8 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
 /* Nearly identical to wmv1 but that is just because we do not use the
  * useless M$ crap features. It is duplicated here in case someone wants
  * to add support for these crap features. */
-void ff_wmv2_encode_mb(MpegEncContext *s, int16_t block[6][64],
-                       int motion_x, int motion_y)
+static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
+                           int motion_x, int motion_y)
 {
     WMV2EncContext *const w = (WMV2EncContext *) s;
     int cbp, coded_cbp, i;
@@ -224,6 +223,7 @@ static av_cold int wmv2_encode_init(AVCodecContext *avctx)
     int ret;
 
     w->msmpeg4.m.encode_picture_header = wmv2_encode_picture_header;
+    s->encode_mb                       = wmv2_encode_mb;
     s->private_ctx = &w->common;
     ret = ff_mpv_encode_init(avctx);
     if (ret < 0)
diff --git a/libavcodec/wmv2enc.h b/libavcodec/wmv2enc.h
deleted file mode 100644
index 59046c6a07..0000000000
--- a/libavcodec/wmv2enc.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2002 The FFmpeg Project
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_WMV2ENC_H
-#define AVCODEC_WMV2ENC_H
-
-#include "mpegvideo.h"
-
-void ff_wmv2_encode_mb(MpegEncContext * s, int16_t block[6][64],
-                       int motion_x, int motion_y);
-
-
-#endif
-- 
2.45.2


[-- Attachment #36: 0035-avcodec-mjpegenc-Reindent-after-the-previous-commit.patch --]
[-- Type: text/x-patch, Size: 4993 bytes --]

From 85a48c91d7df84aedcb7de0a3ef86c3234f51d68 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 4 Mar 2025 19:26:50 +0100
Subject: [PATCH 35/77] avcodec/mjpegenc: Reindent after the previous commit

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mjpegenc.c | 102 ++++++++++++++++++++----------------------
 1 file changed, 49 insertions(+), 53 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 6c58c04892..a6f202da0a 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -466,71 +466,67 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
 static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
                             int unused_x, int unused_y)
 {
-    int i;
-        if (s->chroma_format == CHROMA_444) {
-            record_block(s, block[0], 0);
-            record_block(s, block[2], 2);
-            record_block(s, block[4], 4);
-            record_block(s, block[8], 8);
+    if (s->chroma_format == CHROMA_444) {
+        record_block(s, block[0], 0);
+        record_block(s, block[2], 2);
+        record_block(s, block[4], 4);
+        record_block(s, block[8], 8);
+        record_block(s, block[5], 5);
+        record_block(s, block[9], 9);
+
+        if (16*s->mb_x+8 < s->width) {
+            record_block(s, block[1],   1);
+            record_block(s, block[3],   3);
+            record_block(s, block[6],   6);
+            record_block(s, block[10], 10);
+            record_block(s, block[7],   7);
+            record_block(s, block[11], 11);
+        }
+    } else {
+        for (int i = 0; i < 5; i++)
+            record_block(s, block[i], i);
+        if (s->chroma_format == CHROMA_420) {
             record_block(s, block[5], 5);
-            record_block(s, block[9], 9);
-
-            if (16*s->mb_x+8 < s->width) {
-                record_block(s, block[1], 1);
-                record_block(s, block[3], 3);
-                record_block(s, block[6], 6);
-                record_block(s, block[10], 10);
-                record_block(s, block[7], 7);
-                record_block(s, block[11], 11);
-            }
         } else {
-            for(i=0;i<5;i++) {
-                record_block(s, block[i], i);
-            }
-            if (s->chroma_format == CHROMA_420) {
-                record_block(s, block[5], 5);
-            } else {
-                record_block(s, block[6], 6);
-                record_block(s, block[5], 5);
-                record_block(s, block[7], 7);
-            }
+            record_block(s, block[6], 6);
+            record_block(s, block[5], 5);
+            record_block(s, block[7], 7);
         }
+    }
 }
 
 static void mjpeg_encode_mb(MpegEncContext *const s, int16_t block[][64],
                             int unused_x, int unused_y)
 {
-    int i;
-        if (s->chroma_format == CHROMA_444) {
-            encode_block(s, block[0], 0);
-            encode_block(s, block[2], 2);
-            encode_block(s, block[4], 4);
-            encode_block(s, block[8], 8);
+    if (s->chroma_format == CHROMA_444) {
+        encode_block(s, block[0], 0);
+        encode_block(s, block[2], 2);
+        encode_block(s, block[4], 4);
+        encode_block(s, block[8], 8);
+        encode_block(s, block[5], 5);
+        encode_block(s, block[9], 9);
+
+        if (16 * s->mb_x + 8 < s->width) {
+            encode_block(s, block[1], 1);
+            encode_block(s, block[3], 3);
+            encode_block(s, block[6], 6);
+            encode_block(s, block[10], 10);
+            encode_block(s, block[7], 7);
+            encode_block(s, block[11], 11);
+        }
+    } else {
+        for (int i = 0; i < 5; i++)
+            encode_block(s, block[i], i);
+        if (s->chroma_format == CHROMA_420) {
             encode_block(s, block[5], 5);
-            encode_block(s, block[9], 9);
-
-            if (16*s->mb_x+8 < s->width) {
-                encode_block(s, block[1], 1);
-                encode_block(s, block[3], 3);
-                encode_block(s, block[6], 6);
-                encode_block(s, block[10], 10);
-                encode_block(s, block[7], 7);
-                encode_block(s, block[11], 11);
-            }
         } else {
-            for(i=0;i<5;i++) {
-                encode_block(s, block[i], i);
-            }
-            if (s->chroma_format == CHROMA_420) {
-                encode_block(s, block[5], 5);
-            } else {
-                encode_block(s, block[6], 6);
-                encode_block(s, block[5], 5);
-                encode_block(s, block[7], 7);
-            }
+            encode_block(s, block[6], 6);
+            encode_block(s, block[5], 5);
+            encode_block(s, block[7], 7);
         }
+    }
 
-        s->i_tex_bits += get_bits_diff(s);
+    s->i_tex_bits += get_bits_diff(s);
 }
 
 static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
-- 
2.45.2


[-- Attachment #37: 0036-avcodec-mpegvideo-Add-pointer-to-main-context-to-sli.patch --]
[-- Type: text/x-patch, Size: 2686 bytes --]

From f0abfd94263082284c6e434d98dc9a093c9e170d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 07:16:33 +0100
Subject: [PATCH 36/77] avcodec/mpegvideo: Add pointer to main context to slice
 contexts

It is a pointer to const to allow the slice threads to inspect
values without modifying them; also make it a simple cast
for codecs that don't support slice threading.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.c    |  2 ++
 libavcodec/mpegvideo.h    |  4 ++++
 libavcodec/mpegvideoenc.h | 12 ++++++++++++
 3 files changed, 18 insertions(+)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 9cd67151aa..bc367fba07 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -387,6 +387,8 @@ av_cold int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
 {
     int nb_slices = s->slice_context_count, ret;
 
+    s->parent = s;
+
     /* We initialize the copies before the original so that
      * fields allocated in init_duplicate_context are NULL after
      * copying. This prevents double-frees upon allocation error. */
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index bdab782b29..04eade13aa 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -86,6 +86,10 @@ typedef struct MpegEncContext {
     uint8_t permutated_intra_v_scantable[64];
 
     struct AVCodecContext *avctx;
+    union {
+        const struct MpegEncContext *parent;
+        const struct MPVMainEncContext *encparent;
+    };
     /* The following pointer is intended for codecs sharing code
      * between decoder and encoder and in need of a common context to do so. */
     void *private_ctx;
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 4b74f8eb46..65bb3447b3 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -30,6 +30,7 @@
 
 #include <float.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
 #include "ratecontrol.h"
@@ -91,6 +92,17 @@ typedef struct MPVMainEncContext {
     int64_t mc_mb_var_sum;         ///< motion compensated MB variance for current frame
 } MPVMainEncContext;
 
+static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)
+{
+#ifdef NO_SLICE_THREADING_HERE
+    av_assert2(s->slice_context_count <= 1 &&
+               !(s->avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS));
+    return (const MPVMainEncContext*)s;
+#else
+    return s->encparent;
+#endif
+}
+
 #define MAX_FCODE        7
 #define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
 #define INPLACE_OFFSET 16
-- 
2.45.2


[-- Attachment #38: 0037-avcodec-mpegvideo-Move-max_b_frames-to-MPVMainEncCon.patch --]
[-- Type: text/x-patch, Size: 14009 bytes --]

From 45f19ed03d4c17dfbc0b8ab5e04fa9c1d11a6fe8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 11:20:25 +0100
Subject: [PATCH 37/77] avcodec/mpegvideo: Move max_b_frames to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4videoenc.c | 17 +++++++-------
 libavcodec/mpegvideo.h     |  1 -
 libavcodec/mpegvideo_enc.c | 48 ++++++++++++++++++--------------------
 libavcodec/mpegvideoenc.h  |  1 +
 libavcodec/ratecontrol.c   |  6 ++---
 5 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 4f97199eba..d54064cd89 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -650,11 +650,11 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
 
             if ((cbp | motion_x | motion_y | s->dquant) == 0 &&
                 s->mv_type == MV_TYPE_16X16) {
+                const MPVMainEncContext *const m = slice_to_mainenc(s);
                 /* Check if the B-frames can skip it too, as we must skip it
                  * if we skip here why didn't they just compress
                  * the skip-mb bits instead of reusing them ?! */
-                if (s->max_b_frames > 0) {
-                    int i;
+                if (m->max_b_frames > 0) {
                     int x, y, offset;
                     const uint8_t *p_pic;
 
@@ -665,7 +665,7 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                     p_pic  = s->new_pic->data[0] + offset;
 
                     s->mb_skipped = 1;
-                    for (i = 0; i < s->max_b_frames; i++) {
+                    for (int i = 0; i < m->max_b_frames; i++) {
                         const uint8_t *b_pic;
                         int diff;
                         const MPVPicture *pic = s->reordered_input_picture[i + 1];
@@ -929,14 +929,15 @@ static void mpeg4_encode_gop_header(MpegEncContext *s)
     ff_mpeg4_stuffing(&s->pb);
 }
 
-static void mpeg4_encode_visual_object_header(MpegEncContext *s)
+static void mpeg4_encode_visual_object_header(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int profile_and_level_indication;
     int vo_ver_id;
 
     if (s->avctx->profile != AV_PROFILE_UNKNOWN) {
         profile_and_level_indication = s->avctx->profile << 4;
-    } else if (s->max_b_frames || s->quarter_sample) {
+    } else if (m->max_b_frames || s->quarter_sample) {
         profile_and_level_indication = 0xF0;  // adv simple
     } else {
         profile_and_level_indication = 0x00;  // simple
@@ -978,7 +979,7 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
     MpegEncContext *const s = &m4->m.s;
     int vo_ver_id, vo_type, aspect_ratio_info;
 
-    if (s->max_b_frames || s->quarter_sample) {
+    if (m4->m.max_b_frames || s->quarter_sample) {
         vo_ver_id  = 5;
         vo_type = ADV_SIMPLE_VO_TYPE;
     } else {
@@ -1072,7 +1073,7 @@ static int mpeg4_encode_picture_header(MPVMainEncContext *const m)
     if (s->pict_type == AV_PICTURE_TYPE_I) {
         if (!(s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
             if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT)  // HACK, the reference sw is buggy
-                mpeg4_encode_visual_object_header(s);
+                mpeg4_encode_visual_object_header(m);
             if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->picture_number == 0)  // HACK, the reference sw is buggy
                 mpeg4_encode_vol_header(m4, 0, 0);
         }
@@ -1339,7 +1340,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
             return AVERROR(ENOMEM);
         init_put_bits(&s->pb, s->avctx->extradata, 1024);
 
-        mpeg4_encode_visual_object_header(s);
+        mpeg4_encode_visual_object_header(m);
         mpeg4_encode_vol_header(m4, 0, 0);
 
 //            ff_mpeg4_stuffing(&s->pb); ?
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 04eade13aa..d25b5cdf3a 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -106,7 +106,6 @@ typedef struct MpegEncContext {
 
     enum AVCodecID codec_id;     /* see AV_CODEC_ID_xxx */
     int encoding;     ///< true if we are encoding (vs decoding)
-    int max_b_frames; ///< max number of B-frames for encoding
     int luma_elim_threshold;
     int chroma_elim_threshold;
     int workaround_bugs;       ///< workaround bugs in encoders which cannot be detected automatically
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 6650e5b35d..ffa652d02d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -470,9 +470,9 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                "max b frames must be 0 or positive for mpegvideo based encoders\n");
         return AVERROR(EINVAL);
     }
-    s->max_b_frames = avctx->max_b_frames;
+    m->max_b_frames = avctx->max_b_frames;
     s->codec_id     = avctx->codec->id;
-    if (s->max_b_frames && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
+    if (m->max_b_frames && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
         av_log(avctx, AV_LOG_ERROR, "B-frames not supported by codec\n");
         return AVERROR(EINVAL);
     }
@@ -692,7 +692,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                    "set strict_std_compliance to 'unofficial' or lower in order to allow it\n");
             return AVERROR(EINVAL);
         }
-        if (s->max_b_frames != 0) {
+        if (m->max_b_frames != 0) {
             av_log(avctx, AV_LOG_ERROR,
                    "B-frames cannot be used with low delay\n");
             return AVERROR(EINVAL);
@@ -744,7 +744,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     case AV_CODEC_ID_MPEG1VIDEO:
         s->out_format = FMT_MPEG1;
         s->low_delay  = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY);
-        avctx->delay  = s->low_delay ? 0 : (s->max_b_frames + 1);
+        avctx->delay  = s->low_delay ? 0 : (m->max_b_frames + 1);
         ff_mpeg1_encode_init(s);
         break;
 #endif
@@ -834,8 +834,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->h263_pred       = 1;
         s->unrestricted_mv = 1;
         s->flipflop_rounding = 1;
-        s->low_delay       = s->max_b_frames ? 0 : 1;
-        avctx->delay       = s->low_delay ? 0 : (s->max_b_frames + 1);
+        s->low_delay       = m->max_b_frames ? 0 : 1;
+        avctx->delay       = s->low_delay ? 0 : (m->max_b_frames + 1);
         break;
     case AV_CODEC_ID_MSMPEG4V2:
         s->out_format      = FMT_H263;
@@ -1013,7 +1013,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return ret;
 
     if (m->b_frame_strategy == 2) {
-        for (i = 0; i < s->max_b_frames + 2; i++) {
+        for (int i = 0; i < m->max_b_frames + 2; i++) {
             m->tmp_frames[i] = av_frame_alloc();
             if (!m->tmp_frames[i])
                 return AVERROR(ENOMEM);
@@ -1255,7 +1255,7 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
     MPVPicture *pic = NULL;
     int64_t pts;
     int display_picture_number = 0, ret;
-    int encoding_delay = s->max_b_frames ? s->max_b_frames
+    int encoding_delay = m->max_b_frames ? m->max_b_frames
                                          : (s->low_delay ? 0 : 1);
     int flush_offset = 1;
     int direct = 1;
@@ -1461,7 +1461,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
     const int scale = m->brd_scale;
     int width  = s->width  >> scale;
     int height = s->height >> scale;
-    int i, j, out_size, p_lambda, b_lambda, lambda2;
+    int out_size, p_lambda, b_lambda, lambda2;
     int64_t best_rd  = INT64_MAX;
     int best_b_count = -1;
     int ret = 0;
@@ -1481,7 +1481,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
     lambda2  = (b_lambda * b_lambda + (1 << FF_LAMBDA_SHIFT) / 2) >>
                FF_LAMBDA_SHIFT;
 
-    for (i = 0; i < s->max_b_frames + 2; i++) {
+    for (int i = 0; i < m->max_b_frames + 2; i++) {
         const MPVPicture *pre_input_ptr = i ? s->input_picture[i - 1] :
                                            s->next_pic.ptr;
 
@@ -1513,7 +1513,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
         }
     }
 
-    for (j = 0; j < s->max_b_frames + 1; j++) {
+    for (int j = 0; j < m->max_b_frames + 1; j++) {
         AVCodecContext *c;
         int64_t rd = 0;
 
@@ -1536,7 +1536,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
         c->me_sub_cmp   = s->avctx->me_sub_cmp;
         c->pix_fmt      = AV_PIX_FMT_YUV420P;
         c->time_base    = s->avctx->time_base;
-        c->max_b_frames = s->max_b_frames;
+        c->max_b_frames = m->max_b_frames;
 
         ret = avcodec_open2(c, s->avctx->codec, NULL);
         if (ret < 0)
@@ -1554,8 +1554,8 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
 
         //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;
 
-        for (i = 0; i < s->max_b_frames + 1; i++) {
-            int is_p = i % (j + 1) == j || i == s->max_b_frames;
+        for (int i = 0; i < m->max_b_frames + 1; i++) {
+            int is_p = i % (j + 1) == j || i == m->max_b_frames;
 
             m->tmp_frames[i + 1]->pict_type = is_p ?
                                      AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
@@ -1640,7 +1640,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         int b_frames = 0;
 
         if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
-            for (int i = 0; i < s->max_b_frames + 1; i++) {
+            for (int i = 0; i < m->max_b_frames + 1; i++) {
                 int pict_num = s->input_picture[0]->display_picture_number + i;
 
                 if (pict_num >= m->rc_context.num_entries)
@@ -1656,12 +1656,11 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         }
 
         if (m->b_frame_strategy == 0) {
-            b_frames = s->max_b_frames;
+            b_frames = m->max_b_frames;
             while (b_frames && !s->input_picture[b_frames])
                 b_frames--;
         } else if (m->b_frame_strategy == 1) {
-            int i;
-            for (i = 1; i < s->max_b_frames + 1; i++) {
+            for (int i = 1; i < m->max_b_frames + 1; i++) {
                 if (s->input_picture[i] &&
                     s->input_picture[i]->b_frame_score == 0) {
                     s->input_picture[i]->b_frame_score =
@@ -1671,19 +1670,18 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
                                         s->linesize) + 1;
                 }
             }
-            for (i = 0; i < s->max_b_frames + 1; i++) {
+            for (int i = 0; i < m->max_b_frames + 1; i++) {
                 if (!s->input_picture[i] ||
                     s->input_picture[i]->b_frame_score - 1 >
-                        s->mb_num / m->b_sensitivity)
+                        s->mb_num / m->b_sensitivity) {
+                    b_frames = FFMAX(0, i - 1);
                     break;
+                }
             }
 
-            b_frames = FFMAX(0, i - 1);
-
             /* reset scores */
-            for (i = 0; i < b_frames + 1; i++) {
+            for (int i = 0; i < b_frames + 1; i++)
                 s->input_picture[i]->b_frame_score = 0;
-            }
         } else if (m->b_frame_strategy == 2) {
             b_frames = estimate_best_b_count(m);
             if (b_frames < 0) {
@@ -1700,7 +1698,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
                 b_frames = i;
         }
         if (s->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_B &&
-            b_frames == s->max_b_frames) {
+            b_frames == m->max_b_frames) {
             av_log(s->avctx, AV_LOG_ERROR,
                     "warning, too many B-frames in a row\n");
         }
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 65bb3447b3..27bd099aad 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -44,6 +44,7 @@ typedef struct MPVMainEncContext {
 
     int intra_only;                ///< if true, only intra pictures are generated
     int gop_size;
+    int max_b_frames;              ///< max number of B-frames
     int picture_in_gop_number;     ///< 0-> first pic in gop, ...
     int input_picture_number;      ///< used to set pic->display_picture_number
     int coded_picture_number;      ///< used to set pic->coded_picture_number
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 895e557877..20e3ccabf8 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -581,7 +581,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
         p = s->avctx->stats_in;
         for (i = -1; p; i++)
             p = strchr(p + 1, ';');
-        i += s->max_b_frames;
+        i += m->max_b_frames;
         if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry))
             return -1;
         rcc->entry       = av_mallocz(i * sizeof(RateControlEntry));
@@ -602,7 +602,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
 
         /* read stats */
         p = s->avctx->stats_in;
-        for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) {
+        for (i = 0; i < rcc->num_entries - m->max_b_frames; i++) {
             RateControlEntry *rce;
             int picture_number;
             int e;
@@ -663,7 +663,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
 
                 if (i % ((m->gop_size + 3) / 4) == 0)
                     rce.pict_type = AV_PICTURE_TYPE_I;
-                else if (i % (s->max_b_frames + 1))
+                else if (i % (m->max_b_frames + 1))
                     rce.pict_type = AV_PICTURE_TYPE_B;
                 else
                     rce.pict_type = AV_PICTURE_TYPE_P;
-- 
2.45.2


[-- Attachment #39: 0038-avcodec-mpegvideo-Move-MPVPicture-arrays-to-MPVMainE.patch --]
[-- Type: text/x-patch, Size: 18360 bytes --]

From 9a126503f549cd5f8f39f1c9bf515633489adfc1 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 11:47:58 +0100
Subject: [PATCH 38/77] avcodec/mpegvideo: Move MPVPicture arrays to
 MPVMainEncContext

Also avoid allocations while at it.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg4videoenc.c |  11 ++--
 libavcodec/mpegvideo.h     |   2 -
 libavcodec/mpegvideo_enc.c | 124 ++++++++++++++++++-------------------
 libavcodec/mpegvideoenc.h  |   3 +
 4 files changed, 68 insertions(+), 72 deletions(-)

diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index d54064cd89..4c31e7e9c8 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -668,7 +668,7 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                     for (int i = 0; i < m->max_b_frames; i++) {
                         const uint8_t *b_pic;
                         int diff;
-                        const MPVPicture *pic = s->reordered_input_picture[i + 1];
+                        const MPVPicture *pic = m->reordered_input_picture[i + 1];
 
                         if (!pic || pic->f->pict_type != AV_PICTURE_TYPE_B)
                             break;
@@ -900,16 +900,17 @@ void ff_set_mpeg4_time(MpegEncContext *s)
     }
 }
 
-static void mpeg4_encode_gop_header(MpegEncContext *s)
+static void mpeg4_encode_gop_header(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int64_t hours, minutes, seconds;
     int64_t time;
 
     put_bits32(&s->pb, GOP_STARTCODE);
 
     time = s->cur_pic.ptr->f->pts;
-    if (s->reordered_input_picture[1])
-        time = FFMIN(time, s->reordered_input_picture[1]->f->pts);
+    if (m->reordered_input_picture[1])
+        time = FFMIN(time, m->reordered_input_picture[1]->f->pts);
     time = time * s->avctx->time_base.num;
     s->last_time_base = FFUDIV(time, s->avctx->time_base.den);
 
@@ -1077,7 +1078,7 @@ static int mpeg4_encode_picture_header(MPVMainEncContext *const m)
             if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->picture_number == 0)  // HACK, the reference sw is buggy
                 mpeg4_encode_vol_header(m4, 0, 0);
         }
-        mpeg4_encode_gop_header(s);
+        mpeg4_encode_gop_header(m);
     }
 
     s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index d25b5cdf3a..12cb8fc3d5 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -123,8 +123,6 @@ typedef struct MpegEncContext {
     ptrdiff_t linesize;        ///< line size, in bytes, may be different from width
     ptrdiff_t uvlinesize;      ///< line size, for chroma in bytes, may be different from width
     struct AVRefStructPool *picture_pool; ///< Pool for MPVPictures
-    MPVPicture **input_picture;///< next pictures on display order for encoding
-    MPVPicture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding
 
     BufferPoolContext buffer_pools;
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index ffa652d02d..8af572a69e 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -915,8 +915,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return ret;
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->input_picture,           MPVENC_MAX_B_FRAMES + 1) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MPVENC_MAX_B_FRAMES + 1) ||
         !(s->new_pic = av_frame_alloc()) ||
         !(s->picture_pool = ff_mpv_alloc_pic_pool(0)))
         return AVERROR(ENOMEM);
@@ -1049,11 +1047,9 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     ff_mpv_common_end(s);
     av_refstruct_pool_uninit(&s->picture_pool);
 
-    if (s->input_picture && s->reordered_input_picture) {
-        for (int i = 0; i < MPVENC_MAX_B_FRAMES + 1; i++) {
-            av_refstruct_unref(&s->input_picture[i]);
-            av_refstruct_unref(&s->reordered_input_picture[i]);
-        }
+    for (int i = 0; i < MPVENC_MAX_B_FRAMES + 1; i++) {
+        av_refstruct_unref(&m->input_picture[i]);
+        av_refstruct_unref(&m->reordered_input_picture[i]);
     }
     for (int i = 0; i < FF_ARRAY_ELEMS(m->tmp_frames); i++)
         av_frame_free(&m->tmp_frames[i]);
@@ -1077,8 +1073,6 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
 
     av_freep(&s->q_intra_matrix);
     av_freep(&s->q_intra_matrix16);
-    av_freep(&s->input_picture);
-    av_freep(&s->reordered_input_picture);
     av_freep(&s->dct_offset);
     av_freep(&s->mb_var);
     av_freep(&s->mc_mb_var);
@@ -1260,7 +1254,7 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
     int flush_offset = 1;
     int direct = 1;
 
-    av_assert1(!s->input_picture[0]);
+    av_assert1(!m->input_picture[0]);
 
     if (pic_arg) {
         pts = pic_arg->pts;
@@ -1363,14 +1357,14 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
 
         pic->display_picture_number = display_picture_number;
         pic->f->pts = pts; // we set this here to avoid modifying pic_arg
-    } else if (!s->reordered_input_picture[1]) {
+    } else if (!m->reordered_input_picture[1]) {
         /* Flushing: When the above check is true, the encoder is about to run
          * out of frames to encode. Check if there are input_pictures left;
-         * if so, ensure s->input_picture[0] contains the first picture.
+         * if so, ensure m->input_picture[0] contains the first picture.
          * A flush_offset != 1 will only happen if we did not receive enough
          * input frames. */
         for (flush_offset = 0; flush_offset < encoding_delay + 1; flush_offset++)
-            if (s->input_picture[flush_offset])
+            if (m->input_picture[flush_offset])
                 break;
 
         encoding_delay -= flush_offset - 1;
@@ -1378,11 +1372,11 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
 
     /* shift buffer entries */
     for (int i = flush_offset; i <= MPVENC_MAX_B_FRAMES; i++)
-        s->input_picture[i - flush_offset] = s->input_picture[i];
+        m->input_picture[i - flush_offset] = m->input_picture[i];
     for (int i = MPVENC_MAX_B_FRAMES + 1 - flush_offset; i <= MPVENC_MAX_B_FRAMES; i++)
-        s->input_picture[i] = NULL;
+        m->input_picture[i] = NULL;
 
-    s->input_picture[encoding_delay] = pic;
+    m->input_picture[encoding_delay] = pic;
 
     return 0;
 fail:
@@ -1482,7 +1476,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
                FF_LAMBDA_SHIFT;
 
     for (int i = 0; i < m->max_b_frames + 2; i++) {
-        const MPVPicture *pre_input_ptr = i ? s->input_picture[i - 1] :
+        const MPVPicture *pre_input_ptr = i ? m->input_picture[i - 1] :
                                            s->next_pic.ptr;
 
         if (pre_input_ptr) {
@@ -1517,7 +1511,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
         AVCodecContext *c;
         int64_t rd = 0;
 
-        if (!s->input_picture[j])
+        if (!m->input_picture[j])
             break;
 
         c = avcodec_alloc_context3(NULL);
@@ -1612,16 +1606,16 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
     MpegEncContext *const s = &m->s;
 
     /* Either nothing to do or can't do anything */
-    if (s->reordered_input_picture[0] || !s->input_picture[0])
+    if (m->reordered_input_picture[0] || !m->input_picture[0])
         return 0;
 
     /* set next picture type & ordering */
     if (m->frame_skip_threshold || m->frame_skip_factor) {
         if (m->picture_in_gop_number < m->gop_size &&
             s->next_pic.ptr &&
-            skip_check(m, s->input_picture[0], s->next_pic.ptr)) {
+            skip_check(m, m->input_picture[0], s->next_pic.ptr)) {
             // FIXME check that the gop check above is +-1 correct
-            av_refstruct_unref(&s->input_picture[0]);
+            av_refstruct_unref(&m->input_picture[0]);
 
             ff_vbv_update(m, 0);
 
@@ -1631,48 +1625,48 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
 
     if (/* m->picture_in_gop_number >= m->gop_size || */
         !s->next_pic.ptr || m->intra_only) {
-        s->reordered_input_picture[0] = s->input_picture[0];
-        s->input_picture[0] = NULL;
-        s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I;
-        s->reordered_input_picture[0]->coded_picture_number =
+        m->reordered_input_picture[0] = m->input_picture[0];
+        m->input_picture[0] = NULL;
+        m->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I;
+        m->reordered_input_picture[0]->coded_picture_number =
             m->coded_picture_number++;
     } else {
         int b_frames = 0;
 
         if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
             for (int i = 0; i < m->max_b_frames + 1; i++) {
-                int pict_num = s->input_picture[0]->display_picture_number + i;
+                int pict_num = m->input_picture[0]->display_picture_number + i;
 
                 if (pict_num >= m->rc_context.num_entries)
                     break;
-                if (!s->input_picture[i]) {
+                if (!m->input_picture[i]) {
                     m->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P;
                     break;
                 }
 
-                s->input_picture[i]->f->pict_type =
+                m->input_picture[i]->f->pict_type =
                     m->rc_context.entry[pict_num].new_pict_type;
             }
         }
 
         if (m->b_frame_strategy == 0) {
             b_frames = m->max_b_frames;
-            while (b_frames && !s->input_picture[b_frames])
+            while (b_frames && !m->input_picture[b_frames])
                 b_frames--;
         } else if (m->b_frame_strategy == 1) {
             for (int i = 1; i < m->max_b_frames + 1; i++) {
-                if (s->input_picture[i] &&
-                    s->input_picture[i]->b_frame_score == 0) {
-                    s->input_picture[i]->b_frame_score =
+                if (m->input_picture[i] &&
+                    m->input_picture[i]->b_frame_score == 0) {
+                    m->input_picture[i]->b_frame_score =
                         get_intra_count(s,
-                                        s->input_picture[i    ]->f->data[0],
-                                        s->input_picture[i - 1]->f->data[0],
+                                        m->input_picture[i    ]->f->data[0],
+                                        m->input_picture[i - 1]->f->data[0],
                                         s->linesize) + 1;
                 }
             }
             for (int i = 0; i < m->max_b_frames + 1; i++) {
-                if (!s->input_picture[i] ||
-                    s->input_picture[i]->b_frame_score - 1 >
+                if (!m->input_picture[i] ||
+                    m->input_picture[i]->b_frame_score - 1 >
                         s->mb_num / m->b_sensitivity) {
                     b_frames = FFMAX(0, i - 1);
                     break;
@@ -1681,11 +1675,11 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
 
             /* reset scores */
             for (int i = 0; i < b_frames + 1; i++)
-                s->input_picture[i]->b_frame_score = 0;
+                m->input_picture[i]->b_frame_score = 0;
         } else if (m->b_frame_strategy == 2) {
             b_frames = estimate_best_b_count(m);
             if (b_frames < 0) {
-                av_refstruct_unref(&s->input_picture[0]);
+                av_refstruct_unref(&m->input_picture[0]);
                 return b_frames;
             }
         }
@@ -1693,11 +1687,11 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         emms_c();
 
         for (int i = b_frames - 1; i >= 0; i--) {
-            int type = s->input_picture[i]->f->pict_type;
+            int type = m->input_picture[i]->f->pict_type;
             if (type && type != AV_PICTURE_TYPE_B)
                 b_frames = i;
         }
-        if (s->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_B &&
+        if (m->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_B &&
             b_frames == m->max_b_frames) {
             av_log(s->avctx, AV_LOG_ERROR,
                     "warning, too many B-frames in a row\n");
@@ -1710,26 +1704,26 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
             } else {
                 if (s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)
                     b_frames = 0;
-                s->input_picture[b_frames]->f->pict_type = AV_PICTURE_TYPE_I;
+                m->input_picture[b_frames]->f->pict_type = AV_PICTURE_TYPE_I;
             }
         }
 
         if ((s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) && b_frames &&
-            s->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_I)
+            m->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_I)
             b_frames--;
 
-        s->reordered_input_picture[0] = s->input_picture[b_frames];
-        s->input_picture[b_frames]    = NULL;
-        if (s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_I)
-            s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_P;
-        s->reordered_input_picture[0]->coded_picture_number =
+        m->reordered_input_picture[0] = m->input_picture[b_frames];
+        m->input_picture[b_frames]    = NULL;
+        if (m->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_I)
+            m->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_P;
+        m->reordered_input_picture[0]->coded_picture_number =
             m->coded_picture_number++;
         for (int i = 0; i < b_frames; i++) {
-            s->reordered_input_picture[i + 1] = s->input_picture[i];
-            s->input_picture[i]               = NULL;
-            s->reordered_input_picture[i + 1]->f->pict_type =
+            m->reordered_input_picture[i + 1] = m->input_picture[i];
+            m->input_picture[i]               = NULL;
+            m->reordered_input_picture[i + 1]->f->pict_type =
                 AV_PICTURE_TYPE_B;
-            s->reordered_input_picture[i + 1]->coded_picture_number =
+            m->reordered_input_picture[i + 1]->coded_picture_number =
                 m->coded_picture_number++;
         }
     }
@@ -1742,34 +1736,34 @@ static int select_input_picture(MPVMainEncContext *const m)
     MpegEncContext *const s = &m->s;
     int ret;
 
-    av_assert1(!s->reordered_input_picture[0]);
+    av_assert1(!m->reordered_input_picture[0]);
 
     for (int i = 1; i <= MPVENC_MAX_B_FRAMES; i++)
-        s->reordered_input_picture[i - 1] = s->reordered_input_picture[i];
-    s->reordered_input_picture[MPVENC_MAX_B_FRAMES] = NULL;
+        m->reordered_input_picture[i - 1] = m->reordered_input_picture[i];
+    m->reordered_input_picture[MPVENC_MAX_B_FRAMES] = NULL;
 
     ret = set_bframe_chain_length(m);
-    av_assert1(!s->input_picture[0]);
+    av_assert1(!m->input_picture[0]);
     if (ret < 0)
         return ret;
 
     av_frame_unref(s->new_pic);
 
-    if (s->reordered_input_picture[0]) {
-        s->reordered_input_picture[0]->reference =
-           s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_B;
+    if (m->reordered_input_picture[0]) {
+        m->reordered_input_picture[0]->reference =
+           m->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_B;
 
-        if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
+        if (m->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
             // input is a shared pix, so we can't modify it -> allocate a new
             // one & ensure that the shared one is reuseable
-            av_frame_move_ref(s->new_pic, s->reordered_input_picture[0]->f);
+            av_frame_move_ref(s->new_pic, m->reordered_input_picture[0]->f);
 
-            ret = prepare_picture(s, s->reordered_input_picture[0]->f, s->new_pic);
+            ret = prepare_picture(s, m->reordered_input_picture[0]->f, s->new_pic);
             if (ret < 0)
                 goto fail;
         } else {
             // input is not a shared pix -> reuse buffer for current_pix
-            ret = av_frame_ref(s->new_pic, s->reordered_input_picture[0]->f);
+            ret = av_frame_ref(s->new_pic, m->reordered_input_picture[0]->f);
             if (ret < 0)
                 goto fail;
             for (int i = 0; i < MPV_MAX_PLANES; i++) {
@@ -1777,8 +1771,8 @@ static int select_input_picture(MPVMainEncContext *const m)
                     s->new_pic->data[i] += INPLACE_OFFSET;
             }
         }
-        s->cur_pic.ptr = s->reordered_input_picture[0];
-        s->reordered_input_picture[0] = NULL;
+        s->cur_pic.ptr = m->reordered_input_picture[0];
+        m->reordered_input_picture[0] = NULL;
         av_assert1(s->mb_width  == s->buffer_pools.alloc_mb_width);
         av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height);
         av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride);
@@ -1793,7 +1787,7 @@ static int select_input_picture(MPVMainEncContext *const m)
     }
     return 0;
 fail:
-    av_refstruct_unref(&s->reordered_input_picture[0]);
+    av_refstruct_unref(&m->reordered_input_picture[0]);
     return ret;
 }
 
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 27bd099aad..f02708e7ec 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -49,6 +49,9 @@ typedef struct MPVMainEncContext {
     int input_picture_number;      ///< used to set pic->display_picture_number
     int coded_picture_number;      ///< used to set pic->coded_picture_number
 
+    MPVPicture *input_picture[MPVENC_MAX_B_FRAMES + 1]; ///< next pictures in display order
+    MPVPicture *reordered_input_picture[MPVENC_MAX_B_FRAMES + 1]; ///< next pictures in coded order
+
     int64_t user_specified_pts;    ///< last non-zero pts from user-supplied AVFrame
     /**
      * pts difference between the first and second input frame, used for
-- 
2.45.2


[-- Attachment #40: 0039-avcodec-mpegvideo-Move-vbv_delay_pos-to-MPVMainEncCo.patch --]
[-- Type: text/x-patch, Size: 2848 bytes --]

From 61883272a086fff9550f1df3f932a438b9ed6517 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 11:52:20 +0100
Subject: [PATCH 39/77] avcodec/mpegvideo: Move vbv_delay_pos to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     | 2 +-
 libavcodec/mpegvideo.h     | 1 -
 libavcodec/mpegvideo_enc.c | 4 ++--
 libavcodec/mpegvideoenc.h  | 3 +++
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 1ef88d23b8..43addcfda9 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -350,7 +350,7 @@ static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
              (s->picture_number - mpeg12->gop_picture_number) & 0x3ff);
     put_bits(&s->pb, 3, s->pict_type);
 
-    s->vbv_delay_pos = put_bytes_count(&s->pb, 0);
+    m->vbv_delay_pos = put_bytes_count(&s->pb, 0);
     put_bits(&s->pb, 16, 0xFFFF);               /* vbv_delay */
 
     // RAL: Forward f_code also needed for B-frames
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 12cb8fc3d5..ed9224d2fe 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -401,7 +401,6 @@ typedef struct MpegEncContext {
 
     /* MPEG-1 specific */
     int last_mv_dir;         ///< last mv_dir, used for B-frame encoding
-    int vbv_delay_pos;       ///< offset of vbv_delay in the bitstream
 
     /* MPEG-2-specific - I wished not to have to support this mess. */
     int progressive_sequence;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 8af572a69e..cb1cf972d8 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -2023,9 +2023,9 @@ vbv_retry:
             double inbits  = avctx->rc_max_rate *
                              av_q2d(avctx->time_base);
             int    minbits = m->frame_bits - 8 *
-                             (s->vbv_delay_pos - 1);
+                             (m->vbv_delay_pos - 1);
             double bits    = m->rc_context.buffer_index + minbits - inbits;
-            uint8_t *const vbv_delay_ptr = s->pb.buf + s->vbv_delay_pos;
+            uint8_t *const vbv_delay_ptr = s->pb.buf + m->vbv_delay_pos;
 
             if (bits < 0)
                 av_log(avctx, AV_LOG_ERROR,
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index f02708e7ec..18741e9c22 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -72,6 +72,9 @@ typedef struct MPVMainEncContext {
     int lmin, lmax;
     int vbv_ignore_qmax;
 
+    /* MPEG-1/2 specific */
+    int vbv_delay_pos;             ///< offset of vbv_delay in the bitstream
+
     const uint8_t *fcode_tab;      ///< smallest fcode needed for each MV
 
     /* frame skip options */
-- 
2.45.2


[-- Attachment #41: 0040-avcodec-mpegvideoenc-Add-bit_rate-to-MPVMainEncConte.patch --]
[-- Type: text/x-patch, Size: 9507 bytes --]

From a28b4480676c75333b84f95f450c6e2d1efe9e64 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 07:25:15 +0100
Subject: [PATCH 40/77] avcodec/mpegvideoenc: Add bit_rate to MPVMainEncContext

Use it instead of the MpegEncContext field which will
be removed soon.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c     |  2 +-
 libavcodec/mpegvideo_enc.c |  2 +-
 libavcodec/mpegvideoenc.h  |  1 +
 libavcodec/msmpeg4enc.c    | 15 ++++++++++-----
 libavcodec/ratecontrol.c   | 16 ++++++++--------
 libavcodec/snowenc.c       |  2 +-
 libavcodec/wmv2enc.c       |  4 ++--
 7 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 43addcfda9..ae87f28d66 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -198,7 +198,7 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
     else
         /* VBV calculation: Scaled so that a VCD has the proper
          * VBV size of 40 kilobytes */
-        vbv_buffer_size = av_rescale_rnd(s->bit_rate, 20, 1151929 / 2, AV_ROUND_ZERO) * 8 * 1024;
+        vbv_buffer_size = av_rescale_rnd(mpeg12->mpeg.bit_rate, 20, 1151929 / 2, AV_ROUND_ZERO) * 8 * 1024;
     vbv_buffer_size = (vbv_buffer_size + 16383) / 16384;
 
     put_sbits(&s->pb, 18, v);
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index cb1cf972d8..116c974098 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -449,7 +449,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     avctx->bits_per_raw_sample = av_clip(avctx->bits_per_raw_sample, 0, 8);
 
-    s->bit_rate = avctx->bit_rate;
+    m->bit_rate = avctx->bit_rate;
     s->width    = avctx->width;
     s->height   = avctx->height;
     if (avctx->gop_size > 600 &&
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 18741e9c22..57b91d169a 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -87,6 +87,7 @@ typedef struct MPVMainEncContext {
     int (*encode_picture_header)(struct MPVMainEncContext *m);
 
     /* bit rate control */
+    int64_t bit_rate;
     int64_t total_bits;
     int frame_bits;                ///< bits used for the current frame
     int header_bits;
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 9e58a91a80..e5501e5e32 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -30,6 +30,8 @@
 #include <stdint.h>
 #include <string.h>
 
+#define NO_SLICE_THREADING_HERE
+
 #include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
 #include "libavutil/thread.h"
@@ -222,8 +224,10 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
     s->use_skip_mb_code = 1; /* only if P-frame */
     s->per_mb_rl_table = 0;
     if (s->msmpeg4_version == MSMP4_WMV1)
-        s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==AV_PICTURE_TYPE_P);
-    ff_dlog(s->avctx, "%d %"PRId64" %d %d %d\n", s->pict_type, s->bit_rate,
+        s->inter_intra_pred = s->width * s->height < 320*240 &&
+                              m->bit_rate  <= II_BITRATE     &&
+                              s->pict_type == AV_PICTURE_TYPE_P;
+    ff_dlog(s->avctx, "%d %"PRId64" %d %d %d\n", s->pict_type, m->bit_rate,
             s->inter_intra_pred, s->width, s->height);
 
     if (s->pict_type == AV_PICTURE_TYPE_I) {
@@ -232,7 +236,7 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
 
         if (s->msmpeg4_version == MSMP4_WMV1) {
             ff_msmpeg4_encode_ext_header(s);
-            if(s->bit_rate>MBAC_BITRATE)
+            if (m->bit_rate > MBAC_BITRATE)
                 put_bits(&s->pb, 1, s->per_mb_rl_table);
         }
 
@@ -247,7 +251,7 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
     } else {
         put_bits(&s->pb, 1, s->use_skip_mb_code);
 
-        if (s->msmpeg4_version == MSMP4_WMV1 && s->bit_rate > MBAC_BITRATE)
+        if (s->msmpeg4_version == MSMP4_WMV1 && m->bit_rate > MBAC_BITRATE)
             put_bits(&s->pb, 1, s->per_mb_rl_table);
 
         if (s->msmpeg4_version > MSMP4_V2) {
@@ -268,6 +272,7 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
 
 void ff_msmpeg4_encode_ext_header(MpegEncContext * s)
 {
+    const MPVMainEncContext *const m = slice_to_mainenc(s);
     unsigned fps;
 
     if (s->avctx->framerate.num > 0 && s->avctx->framerate.den > 0)
@@ -284,7 +289,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
     put_bits(&s->pb, 5, FFMIN(fps, 31)); //yes 29.97 -> 29
 
-    put_bits(&s->pb, 11, FFMIN(s->bit_rate / 1024, 2047));
+    put_bits(&s->pb, 11, FFMIN(m->bit_rate / 1024, 2047));
 
     if (s->msmpeg4_version >= MSMP4_V3)
         put_bits(&s->pb, 1, s->flipflop_rounding);
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 20e3ccabf8..0d2bf8fb30 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -347,7 +347,7 @@ static int init_pass2(MPVMainEncContext *const m)
     double complexity[5]   = { 0 }; // approximate bits at quant=1
     uint64_t const_bits[5] = { 0 }; // quantizer independent bits
     uint64_t all_const_bits;
-    uint64_t all_available_bits = av_rescale_q(s->bit_rate,
+    uint64_t all_available_bits = av_rescale_q(m->bit_rate,
                                                (AVRational){rcc->num_entries,1},
                                                fps);
     double rate_factor          = 0;
@@ -477,8 +477,8 @@ static int init_pass2(MPVMainEncContext *const m)
     av_assert0(toobig <= 40);
     av_log(s->avctx, AV_LOG_DEBUG,
            "[lavc rc] requested bitrate: %"PRId64" bps  expected bitrate: %"PRId64" bps\n",
-           s->bit_rate,
-           (int64_t)(expected_bits / ((double)all_available_bits / s->bit_rate)));
+           m->bit_rate,
+           (int64_t)(expected_bits / ((double)all_available_bits / m->bit_rate)));
     av_log(s->avctx, AV_LOG_DEBUG,
            "[lavc rc] estimated target average qp: %.3f\n",
            (float)qscale_sum / rcc->num_entries);
@@ -696,7 +696,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
                 get_qscale(m, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);
 
                 // FIXME misbehaves a little for variable fps
-                rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx);
+                rcc->pass1_wanted_bits += m->bit_rate / get_fps(s->avctx);
             }
         }
     }
@@ -971,9 +971,9 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
             dts_pic = s->last_pic.ptr;
 
         if (!dts_pic || dts_pic->f->pts == AV_NOPTS_VALUE)
-            wanted_bits_double = s->bit_rate * (double)picture_number / fps;
+            wanted_bits_double = m->bit_rate * (double)picture_number / fps;
         else
-            wanted_bits_double = s->bit_rate * (double)dts_pic->f->pts / fps;
+            wanted_bits_double = m->bit_rate * (double)dts_pic->f->pts / fps;
         if (wanted_bits_double > INT64_MAX) {
             av_log(s->avctx, AV_LOG_WARNING, "Bits exceed 64bit range\n");
             wanted_bits = INT64_MAX;
@@ -1047,7 +1047,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
 
         q = modify_qscale(m, rce, q, picture_number);
 
-        rcc->pass1_wanted_bits += s->bit_rate / fps;
+        rcc->pass1_wanted_bits += m->bit_rate / fps;
 
         av_assert0(q > 0.0);
     }
@@ -1061,7 +1061,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
                wanted_bits / 1000, m->total_bits / 1000,
                br_compensation, short_term_q, m->frame_bits,
                m->mb_var_sum, m->mc_mb_var_sum,
-               s->bit_rate / 1000, (int)fps);
+               m->bit_rate / 1000, (int)fps);
     }
 
     if (q < qmin)
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index e074e878d6..b4a329158f 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -227,7 +227,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     s->version=0;
 
     mpv->avctx   = avctx;
-    mpv->bit_rate= avctx->bit_rate;
+    enc->m.bit_rate = avctx->bit_rate;
     enc->m.lmin  = avctx->mb_lmin;
     enc->m.lmax  = avctx->mb_lmax;
     mpv->mb_num  = (avctx->width * avctx->height + 255) / 256; // For ratecontrol
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 3ab3e75722..6eda38d05f 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -55,7 +55,7 @@ static int encode_ext_header(WMV2EncContext *w)
     init_put_bits(&pb, s->avctx->extradata, WMV2_EXTRADATA_SIZE);
 
     put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); // yes 29.97 -> 29
-    put_bits(&pb, 11, FFMIN(s->bit_rate / 1024, 2047));
+    put_bits(&pb, 11, FFMIN(w->msmpeg4.m.bit_rate / 1024, 2047));
 
     put_bits(&pb, 1, w->mspel_bit        = 1);
     put_bits(&pb, 1, s->loop_filter);
@@ -135,7 +135,7 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
         put_bits(&s->pb, 1, s->dc_table_index);
         put_bits(&s->pb, 1, s->mv_table_index);
 
-        s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && s->bit_rate <= II_BITRATE);
+        s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && m->bit_rate <= II_BITRATE);
     }
     s->esc3_level_length = 0;
     s->esc3_run_length   = 0;
-- 
2.45.2


[-- Attachment #42: 0041-avcodec-mpeg12dec-Add-bit_rate-field-to-Mpeg1Context.patch --]
[-- Type: text/x-patch, Size: 3693 bytes --]

From d55f544cdde2b231d1f0f54f1cba706d383edd04 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 07:28:13 +0100
Subject: [PATCH 41/77] avcodec/mpeg12dec: Add bit_rate field to Mpeg1Context

Use it instead of MpegEncContext.bit_rate which will be removed soon.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12dec.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 81cc543424..ed739be538 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -91,6 +91,7 @@ typedef struct Mpeg1Context {
     int first_slice;
     int extradata_decoded;
     int vbv_delay;
+    int64_t bit_rate;
     int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non drop frame format */
 } Mpeg1Context;
 
@@ -950,12 +951,12 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
         if (ret < 0)
             return ret;
 
-        if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->bit_rate &&
-            (s->bit_rate != 0x3FFFF*400)) {
-            avctx->rc_max_rate = s->bit_rate;
-        } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&
-                   (s->bit_rate != 0x3FFFF*400 || s1->vbv_delay != 0xFFFF)) {
-            avctx->bit_rate = s->bit_rate;
+        if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s1->bit_rate &&
+            (s1->bit_rate != 0x3FFFF*400)) {
+            avctx->rc_max_rate = s1->bit_rate;
+        } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s1->bit_rate &&
+                   (s1->bit_rate != 0x3FFFF*400 || s1->vbv_delay != 0xFFFF)) {
+            avctx->bit_rate = s1->bit_rate;
         }
         s1->save_aspect          = s->avctx->sample_aspect_ratio;
         s1->save_width           = s->width;
@@ -1075,7 +1076,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
     s->width  |= (horiz_size_ext << 12);
     s->height |= (vert_size_ext  << 12);
     bit_rate_ext = get_bits(&s->gb, 12);  /* XXX: handle it */
-    s->bit_rate += (bit_rate_ext << 18) * 400LL;
+    s1->bit_rate += (bit_rate_ext << 18) * 400LL;
     check_marker(s->avctx, &s->gb, "after bit rate extension");
     s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
 
@@ -1093,7 +1094,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
         av_log(s->avctx, AV_LOG_DEBUG,
                "profile: %d, level: %d ps: %d cf:%d vbv buffer: %d, bitrate:%"PRId64"\n",
                s->avctx->profile, s->avctx->level, s->progressive_sequence, s->chroma_format,
-               s->avctx->rc_buffer_size, s->bit_rate);
+               s->avctx->rc_buffer_size, s1->bit_rate);
 }
 
 static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
@@ -1799,7 +1800,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
                "frame_rate_index %d is invalid\n", s1->frame_rate_index);
         s1->frame_rate_index = 1;
     }
-    s->bit_rate = get_bits(&s->gb, 18) * 400LL;
+    s1->bit_rate = get_bits(&s->gb, 18) * 400;
     if (check_marker(s->avctx, &s->gb, "in sequence header") == 0) {
         return AVERROR_INVALIDDATA;
     }
@@ -1851,7 +1852,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
 
     if (s->avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%"PRId64", aspect_ratio_info: %d \n",
-               s->avctx->rc_buffer_size, s->bit_rate, s1->aspect_ratio_info);
+               s->avctx->rc_buffer_size, s1->bit_rate, s1->aspect_ratio_info);
 
     return 0;
 }
-- 
2.45.2


[-- Attachment #43: 0042-avcodec-msmpeg4dec-Add-MSMPEG4DecContext.patch --]
[-- Type: text/x-patch, Size: 6547 bytes --]

From 34f4b06de97cd99806d9847e2532f81199d2de1c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 07:42:26 +0100
Subject: [PATCH 42/77] avcodec/msmpeg4dec: Add MSMPEG4DecContext

This is in preparation for further commits.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/msmpeg4dec.c |  8 ++++----
 libavcodec/msmpeg4dec.h | 10 ++++++++++
 libavcodec/wmv2dec.c    | 24 ++++++++++++------------
 3 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
index 0604dc8963..b7ff6126b1 100644
--- a/libavcodec/msmpeg4dec.c
+++ b/libavcodec/msmpeg4dec.c
@@ -845,7 +845,7 @@ const FFCodec ff_msmpeg4v1_decoder = {
     CODEC_LONG_NAME("MPEG-4 part 2 Microsoft variant version 1"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MSMPEG4V1,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MSMP4DecContext),
     .init           = ff_msmpeg4_decode_init,
     FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .close          = ff_mpv_decode_close,
@@ -860,7 +860,7 @@ const FFCodec ff_msmpeg4v2_decoder = {
     CODEC_LONG_NAME("MPEG-4 part 2 Microsoft variant version 2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MSMPEG4V2,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MSMP4DecContext),
     .init           = ff_msmpeg4_decode_init,
     FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .close          = ff_mpv_decode_close,
@@ -875,7 +875,7 @@ const FFCodec ff_msmpeg4v3_decoder = {
     CODEC_LONG_NAME("MPEG-4 part 2 Microsoft variant version 3"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MSMPEG4V3,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MSMP4DecContext),
     .init           = ff_msmpeg4_decode_init,
     FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .close          = ff_mpv_decode_close,
@@ -890,7 +890,7 @@ const FFCodec ff_wmv1_decoder = {
     CODEC_LONG_NAME("Windows Media Video 7"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WMV1,
-    .priv_data_size = sizeof(MpegEncContext),
+    .priv_data_size = sizeof(MSMP4DecContext),
     .init           = ff_msmpeg4_decode_init,
     FF_CODEC_DECODE_CB(ff_h263_decode_frame),
     .close          = ff_mpv_decode_close,
diff --git a/libavcodec/msmpeg4dec.h b/libavcodec/msmpeg4dec.h
index 5daa7c6bc3..d024674f0d 100644
--- a/libavcodec/msmpeg4dec.h
+++ b/libavcodec/msmpeg4dec.h
@@ -28,6 +28,16 @@
 #define INTER_INTRA_VLC_BITS 3
 #define MB_NON_INTRA_VLC_BITS 9
 
+typedef struct MSMP4DecContext {
+    MpegEncContext m;
+} MSMP4DecContext;
+
+static inline MSMP4DecContext *mpv_to_msmpeg4(MpegEncContext *s)
+{
+    // Only legal because no MSMPEG-4 decoder uses slice-threading.
+    return (MSMP4DecContext*)s;
+}
+
 extern const VLCElem *ff_mb_non_intra_vlc[4];
 extern VLCElem ff_inter_intra_vlc[8];
 
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 7f43a5c0ba..5ab619c2ca 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -37,7 +37,7 @@
 #include "wmv2dec.h"
 
 typedef struct WMV2DecContext {
-    MpegEncContext s;
+    MSMP4DecContext ms;
     WMV2Context common;
     IntraX8Context x8;
     int j_type_bit;
@@ -59,7 +59,7 @@ typedef struct WMV2DecContext {
 static void wmv2_add_block(WMV2DecContext *w, int16_t *block1,
                            uint8_t *dst, int stride, int n)
 {
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
 
     if (s->block_last_index[n] >= 0) {
         switch (w->abt_type_table[n]) {
@@ -103,7 +103,7 @@ static int parse_mb_skip(WMV2DecContext *w)
 {
     int mb_x, mb_y;
     int coded_mb_count = 0;
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
     uint32_t *const mb_type = s->cur_pic.mb_type;
 
     w->skip_type = get_bits(&s->gb, 2);
@@ -166,7 +166,7 @@ static int parse_mb_skip(WMV2DecContext *w)
 
 static int decode_ext_header(WMV2DecContext *w)
 {
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
     GetBitContext gb;
     int fps;
     int code;
@@ -336,8 +336,8 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
                                   2 * s->qscale, (s->qscale - 1) | 1,
                                   s->loop_filter, s->low_delay);
 
-        ff_er_add_slice(&w->s.er, 0, 0,
-                        (w->s.mb_x >> 1) - 1, (w->s.mb_y >> 1) - 1,
+        ff_er_add_slice(&s->er, 0, 0,
+                        (s->mb_x >> 1) - 1, (s->mb_y >> 1) - 1,
                         ER_MB_END);
         return 1;
     }
@@ -347,7 +347,7 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
 
 static inline void wmv2_decode_motion(WMV2DecContext *w, int *mx_ptr, int *my_ptr)
 {
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
 
     ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr);
 
@@ -359,7 +359,7 @@ static inline void wmv2_decode_motion(WMV2DecContext *w, int *mx_ptr, int *my_pt
 
 static int16_t *wmv2_pred_motion(WMV2DecContext *w, int *px, int *py)
 {
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
     int xy, wrap, diff, type;
     int16_t *A, *B, *C, *mot_val;
 
@@ -405,7 +405,7 @@ static int16_t *wmv2_pred_motion(WMV2DecContext *w, int *px, int *py)
 static inline int wmv2_decode_inter_block(WMV2DecContext *w, int16_t *block,
                                           int n, int cbp)
 {
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
     static const int sub_cbp_table[3] = { 2, 3, 1 };
     int sub_cbp, ret;
 
@@ -561,7 +561,7 @@ static int wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
 static av_cold int wmv2_decode_init(AVCodecContext *avctx)
 {
     WMV2DecContext *const w = avctx->priv_data;
-    MpegEncContext *const s = &w->s;
+    MpegEncContext *const s = &w->ms.m;
     int ret;
 
     s->private_ctx = &w->common;
@@ -575,8 +575,8 @@ static av_cold int wmv2_decode_init(AVCodecContext *avctx)
 
     decode_ext_header(w);
 
-    return ff_intrax8_common_init(avctx, &w->x8, w->s.block,
-                                  w->s.mb_width, w->s.mb_height);
+    return ff_intrax8_common_init(avctx, &w->x8, s->block,
+                                  s->mb_width, s->mb_height);
 }
 
 static av_cold int wmv2_decode_end(AVCodecContext *avctx)
-- 
2.45.2


[-- Attachment #44: 0043-avcodec-mpegvideo-Move-bit_rate-field-to-MSMP4DecCon.patch --]
[-- Type: text/x-patch, Size: 6355 bytes --]

From 08a06a9d6d1c3c2089a32c0b4645176266ca6630 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 07:59:47 +0100
Subject: [PATCH 43/77] avcodec/mpegvideo: Move bit_rate field to
 MSMP4DecContext

Also make it an int as that is all MSMP4 needs.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h  |  1 -
 libavcodec/msmpeg4dec.c | 21 ++++++++++++++-------
 libavcodec/msmpeg4dec.h |  1 +
 libavcodec/wmv2dec.c    |  8 ++++----
 4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index ed9224d2fe..136b9b18a7 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -95,7 +95,6 @@ typedef struct MpegEncContext {
     void *private_ctx;
     /* the following parameters must be initialized before encoding */
     int width, height;///< picture size. must be a multiple of 16
-    int64_t bit_rate; ///< wanted bit rate
     enum OutputFormat out_format; ///< output format
     int h263_pred;    ///< use MPEG-4/H.263 ac/dc predictions
     int pb_frame;     ///< PB-frame mode (0 = none, 1 = base, 2 = improved)
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
index b7ff6126b1..aac12882d7 100644
--- a/libavcodec/msmpeg4dec.c
+++ b/libavcodec/msmpeg4dec.c
@@ -389,6 +389,7 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
 
 int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
 {
+    MSMP4DecContext *const ms = mpv_to_msmpeg4(s);
     int code;
 
     // at minimum one bit per macroblock is required at least in a valid frame,
@@ -457,8 +458,10 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
         case MSMP4_WMV1:
             ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
 
-            if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
-            else                           s->per_mb_rl_table= 0;
+            if (ms->bit_rate > MBAC_BITRATE)
+                s->per_mb_rl_table = get_bits1(&s->gb);
+            else
+                s->per_mb_rl_table = 0;
 
             if(!s->per_mb_rl_table){
                 s->rl_chroma_table_index = decode012(&s->gb);
@@ -503,8 +506,10 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
         case MSMP4_WMV1:
             s->use_skip_mb_code = get_bits1(&s->gb);
 
-            if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
-            else                           s->per_mb_rl_table= 0;
+            if (ms->bit_rate > MBAC_BITRATE)
+                s->per_mb_rl_table = get_bits1(&s->gb);
+            else
+                s->per_mb_rl_table = 0;
 
             if(!s->per_mb_rl_table){
                 s->rl_table_index = decode012(&s->gb);
@@ -514,7 +519,8 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
             s->dc_table_index = get_bits1(&s->gb);
 
             s->mv_table_index = get_bits1(&s->gb);
-            s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
+            s->inter_intra_pred = s->width*s->height < 320*240 &&
+                                  ms->bit_rate <= II_BITRATE;
             break;
         }
 
@@ -534,7 +540,7 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
             s->no_rounding = 0;
         }
     }
-    ff_dlog(s->avctx, "%d %"PRId64" %d %d %d\n", s->pict_type, s->bit_rate,
+    ff_dlog(s->avctx, "%d %d %d %d %d\n", s->pict_type, ms->bit_rate,
             s->inter_intra_pred, s->width, s->height);
 
     s->esc3_level_length= 0;
@@ -545,13 +551,14 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
 
 int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
 {
+    MSMP4DecContext *const ms = mpv_to_msmpeg4(s);
     int left= buf_size*8 - get_bits_count(&s->gb);
     int length = s->msmpeg4_version >= MSMP4_V3 ? 17 : 16;
     /* the alt_bitstream reader could read over the end so we need to check it */
     if(left>=length && left<length+8)
     {
         skip_bits(&s->gb, 5); /* fps */
-        s->bit_rate= get_bits(&s->gb, 11)*1024;
+        ms->bit_rate = get_bits(&s->gb, 11) * 1024;
         if (s->msmpeg4_version >= MSMP4_V3)
             s->flipflop_rounding= get_bits1(&s->gb);
         else
diff --git a/libavcodec/msmpeg4dec.h b/libavcodec/msmpeg4dec.h
index d024674f0d..47c4495f1d 100644
--- a/libavcodec/msmpeg4dec.h
+++ b/libavcodec/msmpeg4dec.h
@@ -30,6 +30,7 @@
 
 typedef struct MSMP4DecContext {
     MpegEncContext m;
+    int bit_rate;
 } MSMP4DecContext;
 
 static inline MSMP4DecContext *mpv_to_msmpeg4(MpegEncContext *s)
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 5ab619c2ca..02c3dc2535 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -177,7 +177,7 @@ static int decode_ext_header(WMV2DecContext *w)
     init_get_bits(&gb, s->avctx->extradata, 32);
 
     fps                 = get_bits(&gb, 5);
-    s->bit_rate         = get_bits(&gb, 11) * 1024;
+    w->ms.bit_rate      = get_bits(&gb, 11) * 1024;
     w->mspel_bit        = get_bits1(&gb);
     s->loop_filter      = get_bits1(&gb);
     w->abt_flag         = get_bits1(&gb);
@@ -193,10 +193,10 @@ static int decode_ext_header(WMV2DecContext *w)
 
     if (s->avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(s->avctx, AV_LOG_DEBUG,
-               "fps:%d, br:%"PRId64", qpbit:%d, abt_flag:%d, j_type_bit:%d, "
+               "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, "
                "tl_mv_flag:%d, mbrl_bit:%d, code:%d, loop_filter:%d, "
                "slices:%d\n",
-               fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit,
+               fps, w->ms.bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit,
                w->top_left_mv_flag, w->per_mb_rl_bit, code, s->loop_filter,
                code);
     return 0;
@@ -313,7 +313,7 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
         s->dc_table_index   = get_bits1(&s->gb);
         s->mv_table_index   = get_bits1(&s->gb);
 
-        s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && s->bit_rate <= II_BITRATE);
+        s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && w->ms.bit_rate <= II_BITRATE);
         s->no_rounding     ^= 1;
 
         if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
-- 
2.45.2


[-- Attachment #45: 0044-avcodec-msmpeg4enc-Use-LUT-to-write-motion-vectors.patch --]
[-- Type: text/x-patch, Size: 4064 bytes --]

From d58b21e1c18050428505d6f4e84924b307121439 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 08:25:24 +0100
Subject: [PATCH 44/77] avcodec/msmpeg4enc: Use LUT to write motion vectors

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/msmpeg4data.h |  1 -
 libavcodec/msmpeg4enc.c  | 43 +++++++++++++++++++---------------------
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h
index aa4ca86a05..4921548d0c 100644
--- a/libavcodec/msmpeg4data.h
+++ b/libavcodec/msmpeg4data.h
@@ -43,7 +43,6 @@ typedef struct MVTable {
     const uint8_t *table_mv_bits;
     const uint8_t *table_mvx;
     const uint8_t *table_mvy;
-    uint16_t *table_mv_index; /* encoding: convert mv to index in table_mv */
     const VLCElem *vlc;       /* decoding: vlc */
 } MVTable;
 
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index e5501e5e32..b5da98f03b 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -50,21 +50,27 @@
 
 static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
 
+// The lowest 8 bits of each entry are length, the other bits are the code.
+// The index of the (mx, my) entry is (mx * 64) + my.
+static uint32_t mv_vector_tables[2][4096];
+
 /* build the table which associate a (x,y) motion vector to a vlc */
-static av_cold void init_mv_table(MVTable *tab, uint16_t table_mv_index[4096])
+static av_cold void init_mv_table(const MVTable *tab, uint32_t mv_vector_table[4096],
+                                  unsigned escape_code, int escape_length)
 {
     int i, x, y;
 
-    tab->table_mv_index = table_mv_index;
-
-    /* mark all entries as not used */
-    for(i=0;i<4096;i++)
-        tab->table_mv_index[i] = MSMPEG4_MV_TABLES_NB_ELEMS;
+    for (int i = 0; i < 4096; i++) {
+        // Initialize to the table to "escaped". This code is equivalent to
+        // the following double loop (with x and y ranging over 0..63):
+        // tab[x * 64 + y] = (esc_code << 20) | (x << 14) | (y << 8) | esc_length
+        mv_vector_table[i] = (escape_code << 20) | (i << 8) | escape_length;
+    }
 
     for (i = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS; i++) {
         x = tab->table_mvx[i];
         y = tab->table_mvy[i];
-        tab->table_mv_index[(x << 6) | y] = i;
+        mv_vector_table[(x << 6) | y] = (tab->table_mv_code[i] << 8) | tab->table_mv_bits[i];
     }
 }
 
@@ -122,9 +128,8 @@ static int get_size_of_code(const RLTable *rl, int last, int run,
 
 static av_cold void msmpeg4_encode_init_static(void)
 {
-    static uint16_t mv_index_tables[2][4096];
-    init_mv_table(&ff_mv_tables[0], mv_index_tables[0]);
-    init_mv_table(&ff_mv_tables[1], mv_index_tables[1]);
+    init_mv_table(&ff_mv_tables[0], mv_vector_tables[0], 0x0000, 8 + 12);
+    init_mv_table(&ff_mv_tables[1], mv_vector_tables[1], 0x000b, 4 + 12);
 
     for (int i = 0; i < NB_RL_TABLES; i++) {
         for (int level = 1; level <= MAX_LEVEL; level++) {
@@ -300,8 +305,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
 void ff_msmpeg4_encode_motion(MpegEncContext * s,
                                   int mx, int my)
 {
-    int code;
-    MVTable *mv;
+    const uint32_t *const mv_vector_table = mv_vector_tables[s->mv_table_index];
+    uint32_t code;
 
     /* modulo encoding */
     /* WARNING : you cannot reach all the MVs even with the modulo
@@ -317,17 +322,9 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s,
 
     mx += 32;
     my += 32;
-    mv = &ff_mv_tables[s->mv_table_index];
-
-    code = mv->table_mv_index[(mx << 6) | my];
-    put_bits(&s->pb,
-             mv->table_mv_bits[code],
-             mv->table_mv_code[code]);
-    if (code == MSMPEG4_MV_TABLES_NB_ELEMS) {
-        /* escape : code literally */
-        put_bits(&s->pb, 6, mx);
-        put_bits(&s->pb, 6, my);
-    }
+
+    code = mv_vector_table[(mx << 6) | my];
+    put_bits(&s->pb, code & 0xff, code >> 8);
 }
 
 void ff_msmpeg4_handle_slices(MpegEncContext *s){
-- 
2.45.2


[-- Attachment #46: 0045-avcodec-msmpeg4dec-Avoid-lookups-when-decoding-motio.patch --]
[-- Type: text/x-patch, Size: 42404 bytes --]

From 1307b017e5ece29921010a067504f3b0c207378c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 10:28:05 +0100
Subject: [PATCH 45/77] avcodec/msmpeg4dec: Avoid lookups when decoding motion
 vector

Up until now, the decoder uses VLCs to determine whether
this is an escape element or an index in two separate tables
giving the x and y components of the motion vector.
Given that both these components fit into an int16_t and therefore
into a VLCElem's symbol one can simply use a symbol table
to avoid the latter lookups.

This necessitated to combine the two tables for x and y components.
While just at it, also switch to ff_vlc_init_tables_from_lengths().
This will allow to get rid of the code tables (about 4KiB) once
the encoder has been ported, too.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/msmpeg4data.c | 510 ++++++++++++++++++++++++++++++++++++++-
 libavcodec/msmpeg4data.h |   7 +-
 libavcodec/msmpeg4dec.c  |  42 ++--
 libavcodec/msmpeg4enc.c  |   2 +-
 4 files changed, 536 insertions(+), 25 deletions(-)

diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c
index 65546da66e..aac75abd7c 100644
--- a/libavcodec/msmpeg4data.c
+++ b/libavcodec/msmpeg4data.c
@@ -481,6 +481,515 @@ RLTable ff_rl_table[NB_RL_TABLES] = {
 
 /* motion vector table 0 */
 
+#define E(mvx, mvy) ((mvx << 8) | mvy)
+#define ESCAPE 0
+
+const uint16_t ff_msmp4_mv_table0[MSMPEG4_MV_TABLES_NB_ELEMS] = {
+    ESCAPE,    E(31, 39), E(38, 31), E(24, 32), E(23, 30), E(34, 20),
+    E(33, 22), E(21, 29), E(28, 34), E(33, 24), E(49, 32), E(27, 41),
+    E(32,  2), E(40, 33), E(34, 39), E(37, 25), E(29, 26), E(38, 28),
+    E(43, 31), E(37, 33), E(31, 35), E(32, 35), E(25, 29), E(26, 28),
+    E(32, 42), E(33, 23), E(42, 31), E(35, 36), E(27, 31), E(36, 30),
+    E(21, 32), E(23, 32), E(43, 32), E(36, 32), E(39, 29), E(38, 30),
+    E(36, 34), E(34, 36), E(19, 30), E(20, 38), E(41, 41), E(26, 44),
+    E(41, 53), E(42, 11), E(42, 20), E(42, 25), E(26, 45), E(26, 46),
+    E(26, 47), E(26, 48), E( 1, 39), E(26, 52), E(37, 46), E(37, 49),
+    E(37, 63), E(23, 55), E(34, 44), E(42, 38), E(27, 13), E(43, 13),
+    E(34, 57), E(27, 22), E(31, 51), E(24, 16), E(33, 12), E(16, 28),
+    E( 3, 35), E(31, 57), E(24, 25), E(31, 33), E(33, 33), E(34, 32),
+    E(31, 34), E(34, 31), E(33, 20), E(24, 26), E( 4, 28), E(44, 28),
+    E(44, 29), E(11, 32), E(44, 31), E(31, 62), E(13, 34), E(13, 35),
+    E(44, 35), E(45, 19), E(13, 49), E(25, 48), E(22, 39), E(38, 40),
+    E(26, 18), E(38, 43), E(38, 46), E(39, 11), E(32,  6), E(30, 48),
+    E(39, 19), E(30, 49), E(22, 41), E(32, 10), E(26, 23), E(30, 58),
+    E(47, 17), E(47, 21), E(47, 23), E(19, 34), E(47, 30), E(30, 60),
+    E(31,  0), E(35, 44), E( 8, 34), E(23, 26), E(47, 37), E(47, 46),
+    E(27, 43), E(35, 49), E(47, 59), E(31,  4), E(48, 34), E(35, 59),
+    E(19, 37), E(36, 22), E(49, 25), E(49, 28), E(33, 46), E(31,  6),
+    E(39, 40), E(27, 59), E(39, 42), E(49, 36), E(49, 61), E(50, 28),
+    E(50, 30), E(50, 31), E(39, 43), E(31, 10), E(51, 22), E(51, 23),
+    E(39, 47), E(28, 20), E(33, 52), E(33, 55), E(21, 36), E(40, 25),
+    E(31, 16), E(52,  1), E(53, 11), E(40, 27), E(53, 29), E( 9,  5),
+    E(33, 63), E(31, 18), E(53, 41), E(54, 31), E(54, 34), E(54, 38),
+    E(55,  1), E(55,  5), E(34, 13), E(15, 28), E(56, 31), E(25, 17),
+    E(56, 38), E(21, 39), E(21, 41), E(40, 36), E(40, 37), E(25, 22),
+    E(40, 39), E(58, 33), E(36, 43), E( 5, 43), E(41, 15), E(41, 17),
+    E(12, 49), E(60, 30), E(41, 21), E(41, 22), E(37, 20), E(22, 10),
+    E(61, 17), E(18, 25), E(29, 54), E(29, 57), E(30,  3), E(61, 34),
+    E(30,  8), E(61, 36), E(62, 25), E(62, 31), E(30, 14), E(30, 15),
+    E(63, 19), E(18, 29), E(13, 25), E(30, 18), E(45, 30), E( 1, 63),
+    E(34, 16), E(31, 42), E(22, 28), E(35, 13), E(15, 33), E(46, 33),
+    E(46, 35), E(35, 19), E(31, 46), E(28, 43), E(29, 17), E(29, 19),
+    E(23, 36), E(41, 39), E(27, 24), E(14, 31), E(53, 32), E(53, 33),
+    E(27, 26), E(24, 28), E(32, 62), E(57, 33), E(32, 63), E(17, 33),
+    E(42, 39), E(37, 19), E(29, 49), E(33, 17), E( 1, 31), E(25, 43),
+    E(32, 13), E(32, 15), E(63, 29), E(26, 25), E(40, 35), E(23, 34),
+    E(27, 25), E(22, 33), E(24, 29), E(22, 31), E(39, 39), E(43, 35),
+    E(27, 36), E(37, 24), E( 6, 32), E(42, 30), E(24, 33), E(40, 31),
+    E(28, 39), E(32,  1), E(32, 41), E(41, 32), E(36, 31), E(28, 32),
+    E(35, 31), E(29, 31), E(38, 32), E(23, 31), E(27, 30), E(32, 59),
+    E(32, 22), E(32, 21), E(30, 39), E(35, 25), E(26, 34), E(34, 38),
+    E(30, 28), E(44, 33), E(36, 23), E(47, 33), E(26, 27), E(30, 44),
+    E(31, 60), E(41, 30), E(39, 36), E(33, 19), E(33, 29), E(32, 36),
+    E(22, 34), E(45, 31), E(36, 24), E(32, 16), E(45, 35), E(19, 32),
+    E(36, 27), E(32,  4), E(43, 33), E(60, 32), E(37, 31), E(35, 33),
+    E(35, 32), E(34, 29), E(33, 28), E(25, 33), E(25, 34), E(21, 33),
+    E(36, 35), E(37, 32), E(29, 39), E(31, 24), E(30, 41), E(31,  3),
+    E(41, 35), E(22, 32), E(32, 39), E(32, 30), E(33, 32), E(32, 29),
+    E(33, 35), E(31, 28), E(28, 30), E(26, 33), E(31, 49), E(39, 41),
+    E(20, 28), E(20, 29), E(44, 34), E(23, 38), E(33,  7), E(34, 61),
+    E(29, 29), E(31, 38), E(35, 11), E(33, 50), E(33, 13), E(28, 41),
+    E(41, 19), E(23, 47), E(41, 25), E(41, 26), E(29, 15), E(25, 42),
+    E(26, 41), E(49, 29), E(29, 45), E(24, 27), E(37, 17), E(49, 35),
+    E(34, 33), E(30, 35), E(50, 32), E(51, 29), E(51, 32), E(26, 24),
+    E(39, 13), E(25, 26), E(26, 26), E(15, 31), E(39, 24), E(18, 33),
+    E(42, 28), E(17, 30), E( 4, 31), E(31, 11), E(32, 45), E(32, 46),
+    E(60, 33), E( 1, 33), E(42, 35), E(32, 57), E( 0, 32), E(12, 32),
+    E(19, 35), E(35, 45), E(22, 38), E(30, 21), E( 5, 33), E( 5, 31),
+    E(17, 31), E(29, 21), E(22, 35), E(31,  5), E(31, 17), E(43, 29),
+    E(37, 38), E(27, 38), E(32, 18), E(32, 58), E(32, 19), E(33, 43),
+    E(29, 41), E(33, 41), E(31, 37), E(30, 37), E(41, 33), E( 7, 32),
+    E(28, 31), E(34, 27), E(30, 27), E(37, 28), E(26, 36), E(34, 30),
+    E(31, 29), E(33, 30), E(27, 32), E(38, 29), E(30, 25), E(36, 28),
+    E(37, 36), E(21, 34), E(23, 39), E(19, 53), E(34, 41), E(36, 33),
+    E(32, 28), E(25, 32), E(29, 32), E(29, 33), E(33, 27), E(29, 27),
+    E(43, 30), E(35, 41), E(29, 43), E(26, 39), E(22, 29), E(32,  7),
+    E(19, 29), E(32, 17), E(25, 28), E(31, 19), E(41, 28), E(49, 31),
+    E(28, 25), E(34, 19), E(28, 40), E(39, 26), E(34, 21), E(19, 33),
+    E(37, 39), E(38, 23), E(29, 40), E(21, 30), E(36, 39), E(42, 34),
+    E(27, 28), E(59, 33), E(38, 33), E(35, 28), E(33, 34), E(30, 32),
+    E(30, 36), E(23, 35), E(33, 21), E(35, 23), E(31, 21), E(30, 26),
+    E(41, 31), E(39, 32), E(32, 27), E(26, 30), E(31, 22), E(37, 37),
+    E(38, 27), E(39, 27), E(32, 43), E(23, 29), E(32, 60), E(27, 39),
+    E(25, 35), E(61, 32), E(30, 33), E(30, 34), E(34, 28), E(33, 36),
+    E(37, 27), E(20, 22), E(20, 27), E(41, 20), E(13, 29), E( 2, 33),
+    E( 5, 41), E( 5, 42), E( 1, 35), E(32, 24), E(34, 24), E( 5, 62),
+    E(32, 50), E( 6, 29), E(32, 53), E(35, 50), E(20, 35), E(35, 55),
+    E(27, 42), E(35, 61), E(35, 63), E(36,  4), E(36,  7), E(13, 42),
+    E(36, 21), E(41, 46), E(41, 47), E(33, 37), E(28, 33), E(41, 49),
+    E( 3, 27), E(30, 46), E(42, 17), E(27, 55), E(20, 41), E(30, 50),
+    E(27, 63), E(28,  4), E(30, 56), E(21, 18), E(33,  8), E(33, 10),
+    E(14, 18), E(24, 51), E(30, 63), E(42, 36), E(24, 55), E(33, 18),
+    E(25,  5), E(42, 55), E(43,  9), E(14, 29), E(43, 17), E(43, 21),
+    E(14, 30), E(43, 27), E( 7,  1), E(36, 59), E(37,  7), E(37, 11),
+    E(37, 12), E(37, 15), E( 7,  5), E(14, 42), E(25, 24), E(43, 41),
+    E(43, 43), E(44,  7), E(15, 27), E(37, 22), E( 7, 25), E( 7, 31),
+    E( 3, 30), E( 1, 37), E( 8, 22), E(15, 39), E(15, 53), E( 8, 29),
+    E(44, 36), E(44, 37), E(44, 48), E(45,  0), E(45,  5), E(45, 13),
+    E(45, 17), E( 8, 31), E( 8, 32), E(45, 26), E(21, 46), E(45, 28),
+    E(28, 44), E(28, 45), E(28, 46), E(21, 53), E(28, 49), E(28, 51),
+    E(22,  3), E(37, 41), E(46,  3), E(46, 22), E(37, 42), E( 8, 33),
+    E(29,  5), E(37, 45), E(29,  7), E(22, 22), E(46, 40), E(37, 53),
+    E(22, 24), E(29, 14), E(47, 25), E(47, 27), E(38, 10), E(38, 12),
+    E(16, 34), E(38, 16), E(38, 17), E(33, 53), E(38, 20), E(22, 26),
+    E(47, 39), E(47, 45), E(29, 18), E(25, 45), E(16, 35), E( 0, 33),
+    E(48, 31), E( 1, 49), E(34,  4), E(48, 39), E(48, 42), E(34, 11),
+    E(25, 51), E(26,  5), E(26, 13), E(49, 26), E(49, 27), E(26, 17),
+    E( 1, 52), E(49, 30), E( 4,  0), E(26, 22), E( 4, 12), E(49, 34),
+    E( 1, 62), E( 9, 36), E(49, 38), E(49, 41), E(49, 47), E(10, 30),
+    E(49, 63), E(17, 38), E(38, 41), E(17, 43), E(17, 59), E(50, 33),
+    E(38, 45), E(50, 37), E(50, 38), E(22, 40), E(38, 47), E(51, 24),
+    E(38, 48), E(38, 49), E(51, 30), E(39,  1), E(39, 10), E(18, 22),
+    E(22, 49), E(39, 15), E(51, 39), E(22, 59), E(52, 31), E(52, 32),
+    E(52, 33), E(39, 18), E(53, 13), E(53, 15), E(10, 31), E(23, 21),
+    E(18, 27), E(29, 44), E(10, 42), E(53, 39), E(29, 46), E(54, 17),
+    E(11, 26), E(54, 32), E(11, 30), E(11, 31), E(55,  0), E( 1, 30),
+    E(18, 34), E(55,  9), E(55, 12), E(55, 13), E(55, 25), E(55, 31),
+    E(55, 32), E(29, 55), E(34, 43), E(18, 35), E(29, 61), E(56, 33),
+    E(56, 35), E(34, 46), E(57, 25), E(34, 47), E(34, 48), E(29, 62),
+    E(29, 63), E(57, 38), E(57, 61), E(35,  1), E(35,  2), E(35,  5),
+    E(35,  7), E(35,  9), E(39, 46), E(35, 10), E(59, 34), E(59, 35),
+    E(18, 36), E(59, 55), E(39, 51), E(30,  7), E(18, 40), E(40, 23),
+    E(60, 34), E(60, 37), E(61,  5), E(30, 13), E(18, 42), E(61, 18),
+    E(61, 25), E(19, 27), E(19, 28), E(41, 11), E(17, 37), E(26, 42),
+    E(20, 39), E(45, 37), E(46, 31), E(32, 49), E(37, 21), E(22, 27),
+    E(47, 29), E(29, 47), E(31, 53), E(27, 40), E(29, 51), E(30, 16),
+    E(21, 26), E(33,  1), E(35, 40), E(18, 30), E(25, 41), E(33, 44),
+    E(50, 34), E(51, 25), E(42, 27), E( 2, 31), E(15, 35), E(51, 35),
+    E(53, 31), E(33, 15), E(25, 49), E(29,  1), E(55, 35), E(37, 40),
+    E(38,  5), E(33, 58), E(38, 21), E(59, 29), E(38, 22), E(33, 59),
+    E(39, 45), E(13, 31), E(32,  9), E(40, 26), E(61,  9), E(61, 29),
+    E(32, 11), E( 9, 32), E(44, 30), E( 3,  3), E(31, 13), E(29, 20),
+    E(25, 18), E(24, 35), E(48, 32), E(16, 32), E(28, 24), E(49, 33),
+    E(22, 30), E(34, 40), E(31, 47), E(38, 39), E(39, 37), E(44, 32),
+    E(11, 33), E(35, 24), E(30, 23), E(33, 45), E(33, 47), E(36, 25),
+    E(31, 59), E(40, 34), E(25, 27), E(27, 27), E(38, 26), E(31, 40),
+    E(36, 37), E(28, 27), E(32, 31), E(31, 31), E(34, 35), E(32, 37),
+    E(34, 34), E(24, 31), E(39, 34), E(34, 37), E(27, 33), E(28, 35),
+    E(31, 61), E(36, 26), E(25, 39), E(45, 33), E(25, 31), E(35, 34),
+    E( 3, 31), E(34, 22), E(38, 37), E(39, 25), E(40, 30), E(38, 25),
+    E( 1, 32), E(25, 30), E(39, 35), E(30, 38), E(37, 29), E(32, 40),
+    E(28, 28), E(29, 38), E(32,  5), E(37, 34), E(31, 27), E(35, 27),
+    E(27, 29), E(23, 27), E(28, 23), E(33, 42), E(46, 32), E(15, 32),
+    E(13, 33), E(24, 36), E(41, 37), E(24, 37), E(34, 17), E(34, 18),
+    E(30, 22), E(26, 40), E(24, 38), E(14, 32), E(60, 31), E(21, 35),
+    E(29, 24), E(39, 17), E(23, 25), E(35, 17), E(37, 23), E(30, 24),
+    E(32, 61), E(19, 31), E(24, 34), E(25, 25), E(26, 38), E(45, 32),
+    E(38, 35), E(36, 29), E( 3, 32), E(26, 29), E(36, 36), E(30, 31),
+    E(59, 32), E(28, 36), E(63, 32), E(26, 32), E(38, 34), E(63, 33),
+    E(31, 20), E(27, 11), E(20, 32), E(24, 30), E(33,  3), E(37, 35),
+    E(28, 38), E(39, 30), E(32,  3), E(31, 26), E(39, 31), E(35, 29),
+    E(31, 30), E(32, 38), E(23, 33), E(23,  3), E( 9, 29), E(25, 40),
+    E( 9, 31), E(29, 53), E(20, 30), E(30, 17), E(30, 20), E(42, 37),
+    E(18, 31), E(28, 42), E(25, 47), E(28, 47), E(28, 54), E(21, 38),
+    E(29,  9), E(43, 34), E(29, 13), E(43, 37), E(26, 21), E(44, 25),
+    E(44, 27), E(21, 43), E(38, 42), E(35, 30), E(21, 45), E(24, 40),
+    E(45, 25), E(45, 27), E(35, 46), E(39, 22), E(22, 25), E(35, 53),
+    E(36, 20), E(34,  2), E(34, 14), E(45, 39), E(34, 15), E(29, 22),
+    E(31, 44), E(46, 34), E(25, 21), E(46, 38), E(16, 33), E(17, 27),
+    E(31, 48), E(20, 34), E(32, 52), E(47, 35), E(47, 47), E(47, 49),
+    E(32, 54), E(49,  2), E(49, 13), E(49, 23), E(31, 52), E( 1, 29),
+    E(27, 45), E(28, 22), E(39, 49), E(39, 54), E(21, 21), E(36, 40),
+    E(23, 42), E(51, 31), E( 2, 30), E(40, 29), E(51, 34), E(32,  0),
+    E(53, 25), E(24, 23), E(30, 51), E(24, 24), E(30, 59), E(21, 28),
+    E(40, 38), E(57, 29), E(57, 31), E(31,  2), E(41, 13), E(58, 31),
+    E(32,  8), E(12, 31), E( 4, 33), E(32, 12), E(34, 45), E(59, 41),
+    E(31,  7), E(32, 14), E(13, 30), E( 9, 25), E(35, 18), E(26, 43),
+    E(35, 20), E(37, 43), E(61, 35), E(37, 44), E(63,  1), E(26, 49),
+    E(29, 42), E(41, 42), E(45, 34), E(33, 51), E(34, 42), E(47, 31),
+    E(41, 36), E(22, 36), E(42, 29), E(35, 21), E(35, 22), E(23, 37),
+    E(32, 44), E(35, 43), E(43, 25), E(32, 47), E( 7, 33), E(31, 45),
+    E(41, 27), E(20, 31), E(31, 58), E(16, 31), E(13, 32), E(63, 31),
+    E(25, 38), E(30, 43), E(33, 61), E(31, 43), E(41, 29), E(34, 23),
+    E(39, 28), E(47, 32), E(40, 28), E(58, 32), E(59, 31), E(41, 34),
+    E(33,  5), E( 3, 33), E(17, 32), E(61, 33), E(42, 33), E(21, 31),
+    E(26, 35), E(35, 26), E(29, 36), E(26, 31), E(33, 38), E(30, 30),
+    E(31, 32), E(33, 31), E(37, 30), E(31, 23), E(30, 42), E(26, 37),
+    E(33, 26), E(27, 35), E(31, 36), E(27, 34), E(35, 37), E(29, 23),
+    E(36, 38), E(61, 31), E(33, 40), E(37, 26), E(62, 32), E(35, 38),
+    E(57, 32), E(31, 41), E(34, 26), E(34, 25), E(40, 32), E(35, 35),
+    E(29, 34), E(32, 25), E(29, 30), E(28, 26), E(38, 18), E(23, 41),
+    E(32, 20), E(29, 28), E(29, 25), E(28, 37), E(42, 32), E(33, 39),
+    E(32, 26), E(31, 25), E(30, 40), E(35, 47), E(30, 45), E(30, 54),
+    E(31,  1), E(32, 23), E(33, 25), E(42, 26), E(47, 34), E(39, 38),
+    E(38, 14), E(40, 22), E(40, 24), E(51, 33), E(55, 34), E(56, 32),
+    E(18, 32), E(21, 37), E(39, 21), E(39, 23), E(33, 49), E(17, 35),
+    E(41, 23), E(23, 28), E(24, 39), E(43, 39), E(25, 23), E(31, 55),
+    E(20, 33), E(25, 37), E(38, 38), E(25, 36), E(27, 37), E(29, 37),
+    E( 4, 32), E(39, 33), E( 5, 32), E(28, 29), E(38, 24), E(17, 29),
+    E(35, 39), E( 2, 32), E(38, 36), E(30, 29), E(29, 35), E(32, 34),
+    E(32, 33), E(32, 32),
+};
+
+const uint8_t ff_msmp4_mv_table0_lens[MSMPEG4_MV_TABLES_NB_ELEMS] = {
+     8, 12, 12, 13, 15, 15, 15, 15, 12, 15, 15, 15, 15, 14, 14, 14, 14, 14,
+    14, 11,  9,  8, 13, 14, 14, 14, 14, 13, 11, 12, 12, 12, 12, 10, 13, 13,
+    12, 12, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,  6,  6,  7,
+     8,  8, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 13, 12, 11, 10,
+     9,  9, 11, 13, 13, 14, 14, 13, 13, 13, 13, 13, 12, 16, 16, 15, 15, 15,
+    15, 15, 15, 15,  9, 10, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 11,  9,
+     8, 10, 11, 12, 14, 14, 13, 10, 13, 14, 14, 14, 14, 13, 11,  7,  5,  8,
+     9, 11, 12, 13, 16, 16, 16, 16, 16, 16, 16, 16, 11, 12, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  8, 10, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    14, 14, 11, 12, 13, 13, 11, 12, 13, 14, 14,  9,  9,  8, 10, 13, 13, 13,
+    14, 16, 17, 17, 15, 11, 10, 10,  8,  9, 11, 13, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    14, 14, 12, 12,  8,  7, 11, 14, 14, 14, 14, 13, 13, 10, 10, 13, 14, 14,
+    14, 14, 14, 14, 14, 14, 13, 12,  8,  9, 11, 11, 14, 17, 17, 17, 17, 17,
+    17, 17, 17, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 11, 11, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14,
+    14, 14,  4,  5, 10, 10,  9, 13, 13, 12, 11, 12, 14, 14, 14, 14, 11, 10,
+    14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 12, 13, 13, 13, 13, 12, 11, 12,
+    12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 12, 12, 13, 13,  8,
+    12, 13, 13, 11, 12, 15, 16, 16, 14, 14, 14, 12, 13, 13, 12, 12, 11, 10,
+     8, 11, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13,
+    13, 13, 12, 12, 12,  9,  4,  5, 12, 13, 14, 14, 12, 12, 10, 12, 12, 14,
+    14, 14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 10, 10, 10, 10, 14, 16, 16,
+    15, 13, 13, 13, 12, 12, 11, 11, 13, 15, 15, 15, 15, 12, 11, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 14, 14, 14, 13, 12, 12, 11, 12, 12, 14, 14, 13, 13, 13, 10, 10,  6,
+     4,  1,
+};
+
+/* motion vector table 1 */
+
+const uint16_t ff_msmp4_mv_table1[MSMPEG4_MV_TABLES_NB_ELEMS] = {
+    E(32, 32), E(42, 39), E(35, 53), E( 3, 28), E(51, 39), E(35, 57),
+    E(16, 46), E(35, 10), E(30, 52), E(63, 27), E(57, 35), E(39, 42),
+    E(39, 45), E(25, 59), E(35, 15), E(51, 34), E(31,  9), E(48, 34),
+    E( 2, 33), E( 6, 31), E(34, 49), E(30, 43), E(28, 42), E(33, 51),
+    E(39, 27), E(33, 42), E(37, 25), E(60, 34), E(38, 60), E( 9, 38),
+    E(38, 33), E(51, 32), E(30, 22), E(33, 23), E(32, 24), E(32, 26),
+    E(32, 29), E(40, 29), E(27, 23), E(46, 29), E(31, 14), E( 9, 30),
+    E(35, 45), E(29, 49), E(31, 11), E(47, 32), E(32, 48), E(39, 35),
+    E(37, 31), E(25, 34), E(30, 25), E(24, 30), E(35, 25), E(61, 32),
+    E(39, 24), E(16, 24), E(36, 23), E(50, 32), E(32, 45), E(19, 33),
+    E(59, 33), E(29, 25), E(30, 36), E(63, 33), E(45, 39), E(31, 12),
+    E(60, 29), E(14, 24), E(34,  0), E(42, 20), E(24, 16), E( 0, 28),
+    E(37, 43), E(18, 35), E(61, 28), E(57,  1), E(30, 30), E(31, 33),
+    E(31, 35), E(26, 32), E(37, 49), E(28,  4), E(53, 21), E(20, 42),
+    E(46, 39), E(14, 29), E(47,  3), E(38, 44), E(38, 21), E(38, 53),
+    E( 9, 55), E(34, 11), E(39,  5), E(43,  3), E(17, 39), E(39, 53),
+    E(59, 28), E( 5, 25), E(27, 19), E( 0, 34), E(55, 31), E(46, 28),
+    E(19, 35), E(37, 41), E(62, 30), E(34, 44), E(30, 18), E(16, 29),
+    E(19, 34), E(49, 35), E(30, 41), E(25, 27), E(43, 32), E( 4, 32),
+    E(34, 25), E(27, 25), E(33, 19), E(32, 41), E(25, 29), E(62, 31),
+    E(24, 35), E(32, 38), E(30, 32), E(34, 33), E(34, 29), E(41, 36),
+    E(12, 28), E(27, 21), E(41, 25), E(39, 26), E(30, 24), E(37, 21),
+    E(14, 31), E( 5, 30), E(13, 34), E(35, 19), E(55, 34), E(30, 44),
+    E(40, 36), E(40, 38), E(42, 25), E(31, 19), E(27, 36), E(30, 42),
+    E(37, 27), E(31, 17), E(21, 33), E(45, 31), E(32, 44), E(39, 28),
+    E(20, 33), E(46, 33), E(47, 31), E(35, 23), E(19, 31), E(33, 30),
+    E(28, 32), E(36, 32), E(33, 32), E(34, 40), E( 8, 31), E(20, 28),
+    E(35, 39), E(43, 33), E(25, 23), E(45, 37), E(35,  3), E(33, 55),
+    E(35, 29), E(36, 41), E(54, 30), E(38, 22), E(27, 41), E(37, 24),
+    E(62, 33), E(40, 26), E(15, 35), E(59, 35), E(49, 30), E( 1, 33),
+    E(40, 33), E(32,  0), E(29, 37), E(32,  2), E( 3, 32), E(42, 32),
+    E(49, 31), E(21, 34), E(21, 30), E(14, 32), E( 5, 31), E(28, 36),
+    E(31, 21), E(51, 33), E(31, 55), E(29, 51), E(31, 38), E(62, 32),
+    E(34, 47), E(34, 48), E(39, 38), E(24, 24), E(32, 30), E(29, 32),
+    E(30, 34), E(35, 34), E(29, 15), E(25, 21), E(26, 36), E(33, 61),
+    E(31, 26), E(32, 34), E(30, 33), E(27, 31), E(23, 35), E(29, 50),
+    E(21, 25), E(31, 47), E(36, 37), E(35, 41), E(58, 31), E(29, 23),
+    E(29, 41), E(21, 29), E(20, 30), E(33, 24), E(32, 22), E(42, 35),
+    E(29, 46), E(10, 30), E(61, 29), E(33, 10), E(49, 34), E(35, 42),
+    E(34, 45), E( 3, 29), E(38, 42), E(39, 22), E(29,  3), E( 7, 33),
+    E(41, 27), E( 1, 34), E(30, 31), E(13, 32), E(28, 25), E(12, 32),
+    E(40, 28), E(25, 35), E(31, 61), E(28, 31), E(29, 34), E(34, 35),
+    E(28, 33), E(26, 33), E(35,  1), E( 4, 34), E(31, 58), E(33,  2),
+    E(39, 37), E(21, 31), E(60, 33), E(23, 28), E(15, 34), E(38, 30),
+    E(37, 33), E(34, 34), E(31, 28), E(23, 36), E(11, 35), E(37, 23),
+    E(28, 23), E(35, 13), E(30, 58), E(30,  3), E(24, 26), E( 1, 63),
+    E(43, 25), E(56, 31), E( 8, 34), E(32, 14), E(44, 33), E(32, 35),
+    E(26, 31), E(31,  5), E(33, 49), E(31, 20), E(36, 33), E(32,  1),
+    E(27, 33), E(31, 34), E(31, 30), E(28, 39), E(37, 36), E(43, 31),
+    E(31, 59), E(34, 39), E(31, 27), E(34, 61), E(42, 38), E(24, 39),
+    E(45, 25), E(30, 61), E(20, 29), E(23, 37), E( 8, 30), E(38, 41),
+    E(22, 26), E(33, 48), E(17, 28), E(52, 33), E(34, 50), E(29, 21),
+    E(32,  9), E(30, 23), E(49, 33), E(43, 35), E(28, 24), E(39, 39),
+    E(33, 21), E(33, 34), E(32, 28), E(30, 29), E(25, 37), E(32, 11),
+    E(48, 33), E( 2, 30), E(15, 31), E(20, 31), E(22, 35), E(53, 30),
+    E(43, 37), E(44, 29), E(29, 30), E( 1, 29), E(27, 40), E(31,  6),
+    E(41, 39), E(43, 28), E(41, 28), E(30, 19), E(31,  8), E(36, 22),
+    E(30, 45), E(25, 28), E(31, 51), E(28, 40), E(32, 25), E(21, 35),
+    E(24, 29), E(25, 25), E(15, 33), E(20, 32), E(40, 30), E(39, 34),
+    E(31, 46), E(17, 35), E(22, 32), E(39, 31), E(33, 28), E(29, 29),
+    E(21, 32), E(37, 37), E(43, 30), E(18, 30), E(32,  8), E(37, 32),
+    E(31, 32), E(31, 22), E(31, 40), E(57, 32), E(38, 29), E(33, 37),
+    E(35, 35), E(33, 63), E( 5, 34), E(55, 35), E(31, 10), E(33, 58),
+    E(30, 17), E(40, 37), E(23, 39), E(15, 30), E(29, 18), E(34, 54),
+    E(34, 14), E(59, 29), E(34, 16), E(30, 59), E(11, 30), E(13, 35),
+    E(38, 23), E( 5, 35), E(24, 28), E(33, 15), E(37, 30), E(25, 31),
+    E(36, 40), E(13, 33), E(33, 45), E(31, 49), E(32, 16), E(42, 31),
+    E(25, 33), E(32, 36), E(39, 25), E(11, 32), E(33,  5), E(61, 31),
+    E(63, 32), E(31,  4), E( 0, 30), E(30, 47), E(32, 62), E(37, 29),
+    E(31,  2), E(42, 36), E( 5, 29), E(30, 55), E(29, 20), E(29, 35),
+    E(34, 12), E(10, 31), E(44, 35), E(30, 14), E(63, 29), E(35, 18),
+    E(12, 34), E( 3, 34), E(33, 47), E(32, 51), E(39, 36), E(37, 39),
+    E(32, 53), E(32, 10), E(29, 24), E(17, 29), E(32, 20), E(29, 39),
+    E(33, 27), E(31, 36), E(32, 27), E(31,  3), E(30, 39), E(44, 32),
+    E(31, 37), E( 5, 33), E(44, 30), E(46, 31), E(32, 40), E(36, 25),
+    E(35, 40), E(26, 38), E(37, 38), E(33, 38), E(25, 32), E( 2, 32),
+    E(58, 33), E(26, 24), E(15, 29), E(31,  1), E(31, 25), E(17, 26),
+    E(25, 22), E(34,  2), E(43, 27), E(39, 23), E(34,  8), E(56, 30),
+    E(29, 55), E(23, 38), E(30, 60), E(12, 31), E(30,  4), E(10, 34),
+    E(35, 49), E( 9, 34), E(24, 27), E(58, 34), E(10, 33), E(12, 30),
+    E(54, 31), E(32, 56), E(34, 23), E(38, 27), E( 8, 32), E(22, 31),
+    E(34, 24), E(36, 36), E(17, 32), E(38, 36), E(33, 25), E(32, 33),
+    E(32, 31), E(58, 32), E(38, 28), E(38, 37), E(38, 26), E(22, 29),
+    E(29, 43), E(32, 61), E(25, 36), E(16, 33), E(35, 24), E(32, 55),
+    E(35, 43), E(33,  9), E(43, 29), E(18, 34), E(46, 34), E(38, 24),
+    E(35, 26), E(32,  6), E(60, 31), E( 1, 32), E(23, 33), E(30, 35),
+    E(27, 32), E(33, 26), E(41, 31), E(35, 38), E(33, 54), E(37, 42),
+    E(20, 35), E(41, 38), E(35, 46), E(29, 44), E(18, 26), E(61, 27),
+    E(30,  9), E(40, 39), E(24, 25), E(39, 21), E(39, 32), E(53, 29),
+    E(62, 28), E(26, 42), E(29, 13), E(33,  0), E(34,  5), E(53, 34),
+    E(49, 37), E(21, 28), E(27, 24), E(11, 29), E(63, 63), E(50, 33),
+    E(33, 18), E(18, 33), E(53, 33), E(60, 30), E(13, 31), E(32, 50),
+    E(36, 24), E(24, 34), E(27, 34), E(32, 58), E(38, 35), E(35, 28),
+    E(16, 32), E(33, 60), E(51, 30), E(32,  4), E(36, 39), E(43, 34),
+    E(45, 30), E(27, 39), E(45, 33), E(42, 33), E(30, 38), E(32, 17),
+    E(31, 43), E(20, 26), E(26, 22), E(23, 27), E( 7, 29), E(13, 25),
+    E( 6, 33), E(47, 25), E(29, 61), E(30,  0), E( 9, 35), E(51, 25),
+    E(22, 36), E(34, 15), E(21, 27), E(25, 40), E(33, 53), E(32, 37),
+    E(56, 33), E(57,  3), E(30, 10), E(38, 16), E(51, 37), E(51, 38),
+    E(38, 18), E(63, 30), E(28, 46), E(40, 27), E(35,  9), E(33,  6),
+    E(42, 28), E(29, 22), E(24, 38), E(30,  2), E(25, 26), E(31, 63),
+    E(52, 32), E(31, 57), E(29, 26), E(35, 31), E(32,  5), E(41, 32),
+    E(35, 21), E(38, 39), E( 4, 31), E(30, 40), E(17, 31), E( 9, 33),
+    E(22, 28), E(34, 18), E( 4, 30), E(17, 34), E(28, 22), E(55, 33),
+    E(42, 29), E(40, 34), E(46, 32), E(38, 34), E(48, 32), E(63, 31),
+    E(23, 31), E(39, 33), E(33,  3), E( 3, 31), E(18, 29), E(33, 62),
+    E(33,  8), E(24, 42), E(58, 28), E(58, 29), E(34,  3), E(49, 25),
+    E(29, 16), E(43, 26), E( 4, 29), E( 1, 35), E( 4, 28), E(42, 27),
+    E(35, 51), E(35, 61), E(30, 48), E(17, 37), E( 5,  9), E(56, 34),
+    E(25, 41), E(17, 30), E(20, 34), E(47, 35), E(34, 21), E(33, 13),
+    E(16, 34), E(40, 35), E(32, 19), E(28, 35), E(33, 36), E(36, 30),
+    E(25, 39), E(16, 30), E(42, 30), E(19, 32), E(30, 46), E(53, 32),
+    E(32, 23), E(29, 42), E(10, 32), E(11, 31), E(14, 33), E(34, 38),
+    E(32, 39), E(41, 29), E(26, 26), E(61,  7), E(25, 49), E(22, 33),
+    E(28, 38), E(36, 38), E(45, 32), E(34, 27), E(28, 30), E(34, 28),
+    E(33, 59), E(37, 45), E(36, 20), E(55, 29), E(28, 21), E(35,  5),
+    E(29,  5), E(50, 29), E(48, 28), E(52, 34), E( 2, 29), E(42, 24),
+    E(34, 10), E(40, 24), E(46, 35), E(46, 36), E(43, 38), E(33, 11),
+    E( 4, 33), E(33, 40), E(32, 18), E(36, 34), E(27, 35), E(35, 22),
+    E(35, 55), E(29, 11), E(29, 38), E(41, 33), E(29, 28), E( 7, 32),
+    E(44, 31), E(26, 25), E(39, 29), E(32,  3), E(16, 31), E(31, 53),
+    E(26, 27), E(34, 43), E(38, 25), E(29, 40), E(41, 35), E(35, 27),
+    E(36, 29), E(38, 31), E(29, 27), E(32, 43), E(27, 29), E(30, 37),
+    E(24, 32), ESCAPE,    E(32, 63), E(24, 31), E(42, 34), E(48, 36),
+    E(20, 38), E(29, 53), E(31, 54), E(61, 33), E(41, 26), E( 7, 30),
+    E(30, 49), E(35, 20), E(19, 27), E(14, 30), E(21, 39), E( 8, 33),
+    E(39, 41), E(39, 49), E(40, 22), E(46, 38), E(55, 38), E(34,  4),
+    E( 6, 30), E(30,  8), E(34,  9), E(37,  3), E(25, 24), E(37, 22),
+    E(33, 50), E(22, 37), E(44, 36), E(52, 31), E(17, 27), E(35,  2),
+    E(31, 50), E(30, 21), E(24, 36), E(35, 33), E(22, 38), E(61, 30),
+    E(32, 12), E( 9, 31), E(45, 34), E(34, 20), E(31, 15), E(19, 29),
+    E( 9, 32), E(31, 62), E(18, 32), E(33, 17), E(33,  1), E(37, 34),
+    E(32, 15), E(22, 30), E(26, 30), E(59, 31), E(29,  9), E(36, 42),
+    E(46, 30), E(31, 13), E(35, 17), E(54, 32), E(29, 19), E(57, 31),
+    E(30, 20), E(50, 31), E( 3, 30), E(31,  7), E(63,  1), E(34, 17),
+    E(47, 34), E(41, 37), E(35, 63), E(40, 25), E(25, 30), E(37, 28),
+    E( 1, 31), E(26, 28), E(22, 34), E(35, 37), E(34, 32), E(60, 32),
+    E(27, 30), E(37, 19), E(28, 44), E(30,  1), E(50, 28), E(14, 28),
+    E(28, 48), E(55, 30), E( 6, 34), E(23, 41), E(19, 41), E(14, 38),
+    E(30, 12), E( 3, 27), E(30, 15), E(28,  0), E(28, 16), E(61, 34),
+    E(61, 35), E(47, 38), E(45, 28), E(48, 29), E(40, 40), E(40, 42),
+    E(34, 51), E(34, 52), E(25, 45), E(30, 54), E(29, 59), E(35, 59),
+    E( 4, 42), E(51, 31), E(18, 31), E(31, 44), E(14, 34), E(37, 26),
+    E(36, 35), E(37, 35), E(30, 26), E(31, 41), E(31, 39), E(23, 32),
+    E(23, 29), E(38, 40), E(31, 16), E(24, 37), E(32, 52), E(31, 48),
+    E(50, 30), E(28, 34), E(32, 21), E(33, 20), E(31, 18), E(49, 32),
+    E(34, 37), E(33, 29), E(31, 29), E(40, 31), E( 3, 33), E(28, 27),
+    E(26, 35), E(28, 28), E(33, 39), E(34, 26), E(26, 44), E(53, 37),
+    E(50, 26), E(26, 46), E(41, 24), E(27, 15), E(59, 39), E(27, 22),
+    E(29, 31), E(38, 46), E(39, 19), E( 3, 35), E(50, 38), E(43, 17),
+    E(47, 37), E(23, 23), E(33, 52), E(55, 55), E(35, 50), E(21, 37),
+    E(23, 26), E(35, 11), E(61, 37), E(33, 12), E(46, 24), E(52, 30),
+    E(35, 16), E(34, 13), E(24, 22), E(30, 13), E(43, 36), E(16, 35),
+    E(37, 40), E(21, 41), E( 2, 34), E(54, 33), E(27, 38), E( 9, 29),
+    E(33,  7), E(23, 25), E(19, 30), E(32, 54), E(29, 45), E(29, 47),
+    E(33, 46), E(28, 41), E(27, 27), E(32, 49), E(39, 30), E(33, 31),
+    E(59, 32), E(32, 42), E(33, 22), E(47, 29), E(49, 29), E(32, 59),
+    E(40, 32), E(31, 24), E(27, 37), E(23, 34), E(28, 37), E(36, 26),
+    E(32,  7), E(38, 32), E(29, 33), E(15, 32), E(30, 16), E(47, 30),
+    E(33, 14), E(27, 26), E(25, 38), E(54, 34), E(44, 34), E(45, 29),
+    E(50, 34), E(58, 30), E(51, 29), E(48, 30), E(33, 57), E(59, 30),
+    E( 6, 32), E(34, 22), E(27, 28), E(31, 45), E(30, 27), E(24, 33),
+    E(26, 29), E(33,  4), E(24, 41), E(45, 26), E(23, 30), E( 2, 31),
+    E(28, 29), E(35, 36), E(30, 28), E(34, 53), E(30, 51), E(55,  5),
+    E(55, 21), E( 1, 30), E(29,  2), E(29, 63), E(26, 41), E(28, 20),
+    E(25,  1), E(31, 56), E(36, 21), E(22, 24), E(17, 25), E(30,  5),
+    E(52, 28), E( 2, 35), E(44, 26), E(44, 28), E(57, 30), E(26, 18),
+    E(62, 29), E(41, 23), E(39, 40), E(57, 34), E(26, 20), E(46, 42),
+    E(49, 39), E(11, 34), E(16, 28), E(19, 61), E( 5, 38), E(34, 46),
+    E(57, 33), E(13, 29), E(26, 39), E(33, 44), E(13, 30), E(48, 31),
+    E(30, 50), E(11, 33), E( 7, 31), E(56, 32), E(34, 19), E(33, 43),
+    E(32, 46), E(34, 41), E(41, 30), E(36, 28), E(34, 31), E(33, 33),
+    E(33, 35), E(26, 34), E(28, 26), E(32, 13), E(41, 34), E( 0, 32),
+    E(32, 57), E(35, 30), E(35, 32), E(55, 32), E(26, 40), E( 0, 31),
+    E(26, 37), E(35, 47), E( 1,  1), E(51, 35), E(33, 16), E(53, 31),
+    E(31,  0), E(45, 35), E(12, 33), E(29,  1), E(29, 17), E(36, 27),
+    E( 5, 32), E(38, 38), E(59, 27), E(38, 62), E(39,  9), E(58, 36),
+    E(34, 42), E(31, 42), E(36, 31), E(47, 33), E(32, 47), E(17, 33),
+    E(31, 60), E(31, 23), E(33, 41), E(34, 30), E(34, 36), E(32, 60),
+    E(29, 36), E(38, 17), E(25,  9), E(49, 49), E(50, 24), E(22, 25),
+    E(28, 54), E(59, 34), E( 9, 39), E(59, 37), E( 7,  3), E(28,  1),
+    E(55, 25), E(17, 38), E( 4, 38), E(35, 44), E(50, 35), E(21, 36),
+    E(29, 12), E(44, 60), E(47, 36), E(18, 38), E(24, 40), E(19, 25),
+    E(25, 43), E(31, 31),
+};
+
+const uint8_t ff_msmp4_mv_table1_lens[MSMPEG4_MV_TABLES_NB_ELEMS] = {
+     2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 13, 13, 13, 14, 15, 15, 11, 13, 13, 12, 11, 10,
+     8, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 10, 12, 12, 12, 12, 10,
+    14, 15, 15, 13, 13, 13, 12, 12, 11, 13, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15,  9,  6,  9, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 13, 13, 11, 11, 12, 13, 13, 11, 12, 13, 13, 10,  7,  8, 10, 14,
+    15, 15, 14, 14, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13,
+    13, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13,  8,  9,  9,  5, 13, 14, 14,
+    12, 12, 14, 14, 14, 14, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13,
+    12, 12, 12, 11, 10, 11, 13, 13, 13, 13, 12, 12, 12, 13, 14, 14, 11, 12,
+    14, 14, 14, 14,  7,  8,  9, 10, 14, 14, 13, 12, 11,  7,  8, 10, 13, 14,
+    14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 11, 13, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14,  8, 13, 13, 13, 13, 12, 12, 10, 10, 10,
+    10, 11, 14, 14, 13, 13, 13, 12, 13, 14, 14, 11, 10,  9, 10, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13,  8, 11, 12, 13, 13, 10, 10,
+    10,  8,  8, 13, 13, 12, 12, 12, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12,  8,  9, 10, 13, 13,
+    13, 13, 13, 13, 14, 14, 14, 14, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 13, 13, 13,  9, 13, 13, 13, 13, 12, 12, 12, 13, 13, 11, 10, 10, 10,
+    11, 13, 13, 13, 13,  9,  4, 12, 12, 12, 12, 10, 10, 13, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 11, 10,
+    13, 13, 13, 13, 12, 12, 10,  9, 13, 13, 12, 11, 11, 13, 14, 14, 12, 11,
+    12, 14, 14, 14, 14, 10, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13,
+    13, 13, 13, 13, 12, 12, 10, 10,  9, 11, 12, 12, 10, 12, 13, 13, 11, 13,
+    13, 13, 13, 11,  9, 11, 13, 14, 14, 12, 10, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 12,
+    12, 12, 12, 12, 10,  5,  4, 12, 12, 13, 13, 13, 13, 10, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 12, 12, 12, 11, 11, 10,  9, 11, 11, 12, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  9, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 11, 12, 12, 11,
+    12, 13, 13, 10, 13, 13, 13, 13, 12, 12, 11, 12, 12, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  9, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12,  8, 10, 10,
+    13, 13, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 12, 12,
+    11, 10, 11, 11, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 11, 10, 10,
+    13, 13, 12, 12, 13, 13, 10, 13, 13, 13, 13, 11,  9, 12, 13, 14, 14, 12,
+    12, 12, 12, 11, 10, 10, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 13, 13, 12, 12, 10, 11, 13, 14, 14, 12, 11, 11, 12,
+    13, 13, 11,  9, 13, 13, 13, 13, 13, 13, 12, 11, 11, 10, 11, 11, 11, 11,
+    10,  4, 11, 11, 12, 14, 14, 14, 14, 11, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    13, 13, 13,  8, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 11,
+    12, 12, 11, 11, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 14, 14, 11, 12, 12, 12, 12, 11,  6, 10, 11, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 11, 11, 11, 11, 10, 10,
+    12, 13, 13, 13, 13, 13, 13, 10, 10, 13, 13, 12, 11,  8,  8, 11, 11, 12,
+    12, 11, 10, 11, 14, 14, 14, 14, 14, 14, 14, 14,  8, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11,  5,
+    10, 11, 12, 13, 13, 10, 10, 11, 12, 12, 12, 12, 11,  9,  8, 12, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11,
+    12, 13, 14, 14, 12, 12, 11, 11, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12,
+    12, 12, 12, 11,  7,  5,  8, 11, 12, 12, 12, 12, 11,  9,  7, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 10, 12, 14, 14, 14, 14,
+    12, 12,  9, 12, 12, 12, 12, 11, 11,  8, 10, 10, 11, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14,  4,
+};
+
 static const uint16_t table0_mv_code[1100] = {
     0x0001, 0x0003, 0x0005, 0x0007, 0x0003, 0x0008, 0x000c, 0x0001,
     0x0002, 0x001b, 0x0006, 0x000b, 0x0015, 0x0002, 0x000e, 0x000f,
@@ -1045,7 +1554,6 @@ static const uint8_t table0_mvy[1099] = {
     25, 27, 28,
 };
 
-/* motion vector table 1 */
 static const uint16_t table1_mv_code[1100] = {
     0x0000, 0x0007, 0x0009, 0x000f, 0x000a, 0x0011, 0x001a, 0x001c,
     0x0011, 0x0031, 0x0025, 0x002d, 0x002f, 0x006f, 0x0075, 0x0041,
diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h
index 4921548d0c..2217b5ea48 100644
--- a/libavcodec/msmpeg4data.h
+++ b/libavcodec/msmpeg4data.h
@@ -58,7 +58,12 @@ extern const uint8_t ff_wmv1_y_dc_scale_table[32];
 extern const uint8_t ff_wmv1_c_dc_scale_table[32];
 extern const uint8_t ff_old_ff_y_dc_scale_table[32];
 
-#define MSMPEG4_MV_TABLES_NB_ELEMS 1099
+#define MSMPEG4_MV_TABLES_NB_ELEMS 1100
+/// The entries are of the form (8 << mvx) | mvy. Escape value is zero.
+extern const uint16_t ff_msmp4_mv_table0[MSMPEG4_MV_TABLES_NB_ELEMS];
+extern const uint8_t  ff_msmp4_mv_table0_lens[MSMPEG4_MV_TABLES_NB_ELEMS];
+extern const uint16_t ff_msmp4_mv_table1[MSMPEG4_MV_TABLES_NB_ELEMS];
+extern const uint8_t  ff_msmp4_mv_table1_lens[MSMPEG4_MV_TABLES_NB_ELEMS];
 extern MVTable ff_mv_tables[2];
 
 extern const uint8_t ff_v2_mb_type[8][2];
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
index aac12882d7..b60e218f6a 100644
--- a/libavcodec/msmpeg4dec.c
+++ b/libavcodec/msmpeg4dec.c
@@ -46,6 +46,8 @@
 
 #define DEFAULT_INTER_INDEX 3
 
+static const VLCElem *mv_tables[2];
+
 static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
                                     int32_t **dc_val_ptr)
 {
@@ -300,7 +302,6 @@ static av_cold void msmpeg4_decode_init_static(void)
 {
     static VLCElem vlc_buf[3714 + 2694 + 1636 + 2648 + 1532 + 2488];
     VLCInitState state = VLC_INIT_STATE(vlc_buf);
-    MVTable *mv;
 
     INIT_FIRST_VLC_RL(ff_rl_table[0], 642);
     INIT_FIRST_VLC_RL(ff_rl_table[1], 1104);
@@ -326,18 +327,16 @@ static av_cold void msmpeg4_decode_init_static(void)
                           &ff_v2_mb_type[0][1], 2, 1,
                           &ff_v2_mb_type[0][0], 2, 1, 0);
 
-    mv = &ff_mv_tables[0];
-    mv->vlc = ff_vlc_init_tables_sparse(&state, MV_VLC_BITS,
-                                        MSMPEG4_MV_TABLES_NB_ELEMS + 1,
-                                        mv->table_mv_bits, 1, 1,
-                                        mv->table_mv_code, 2, 2,
-                                        NULL, 0, 0, 0);
-    mv = &ff_mv_tables[1];
-    mv->vlc = ff_vlc_init_tables_sparse(&state, MV_VLC_BITS,
-                                        MSMPEG4_MV_TABLES_NB_ELEMS + 1,
-                                        mv->table_mv_bits, 1, 1,
-                                        mv->table_mv_code, 2, 2,
-                                        NULL, 0, 0, 0);
+    mv_tables[0] = ff_vlc_init_tables_from_lengths(&state, MV_VLC_BITS,
+                                                   MSMPEG4_MV_TABLES_NB_ELEMS,
+                                                   ff_msmp4_mv_table0_lens, 1,
+                                                   ff_msmp4_mv_table0, 2, 2,
+                                                   0, 0);
+    mv_tables[1] = ff_vlc_init_tables_from_lengths(&state, MV_VLC_BITS,
+                                                   MSMPEG4_MV_TABLES_NB_ELEMS,
+                                                   ff_msmp4_mv_table1_lens, 1,
+                                                   ff_msmp4_mv_table1, 2, 2,
+                                                   0, 0);
 
     for (unsigned i = 0; i < 4; i++) {
         ff_mb_non_intra_vlc[i] =
@@ -817,18 +816,17 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
 
 void ff_msmpeg4_decode_motion(MpegEncContext *s, int *mx_ptr, int *my_ptr)
 {
-    const MVTable *mv;
-    int code, mx, my;
-
-    mv = &ff_mv_tables[s->mv_table_index];
+    const VLCElem *const mv_vlc = mv_tables[s->mv_table_index];
+    int sym, mx, my;
 
-    code = get_vlc2(&s->gb, mv->vlc, MV_VLC_BITS, 2);
-    if (code == MSMPEG4_MV_TABLES_NB_ELEMS) {
+    sym = get_vlc2(&s->gb, mv_vlc, MV_VLC_BITS, 2);
+    if (sym) {
+        mx = sym >> 8;
+        my = sym & 0xFF;
+    } else {
+        /* Escape */
         mx = get_bits(&s->gb, 6);
         my = get_bits(&s->gb, 6);
-    } else {
-        mx = mv->table_mvx[code];
-        my = mv->table_mvy[code];
     }
 
     mx += *mx_ptr - 32;
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index b5da98f03b..5ce54a8d16 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -67,7 +67,7 @@ static av_cold void init_mv_table(const MVTable *tab, uint32_t mv_vector_table[4
         mv_vector_table[i] = (escape_code << 20) | (i << 8) | escape_length;
     }
 
-    for (i = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS; i++) {
+    for (i = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS - 1; i++) {
         x = tab->table_mvx[i];
         y = tab->table_mvy[i];
         mv_vector_table[(x << 6) | y] = (tab->table_mv_code[i] << 8) | tab->table_mv_bits[i];
-- 
2.45.2


[-- Attachment #47: 0046-avcodec-msmpeg4enc-Avoid-using-MVTable.patch --]
[-- Type: text/x-patch, Size: 54656 bytes --]

From 2b14bd1858de5e141a9d63b0601b69a0e89b12e4 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 15 Mar 2025 11:08:38 +0100
Subject: [PATCH 46/77] avcodec/msmpeg4enc: Avoid using MVTable

Switch to using the length+symbol table combination that is
also used by the decoder and remove MVTable as well as
the old tables altogether.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/msmpeg4data.c | 1139 --------------------------------------
 libavcodec/msmpeg4data.h |   11 -
 libavcodec/msmpeg4enc.c  |   24 +-
 3 files changed, 15 insertions(+), 1159 deletions(-)

diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c
index aac75abd7c..b3603f7db1 100644
--- a/libavcodec/msmpeg4data.c
+++ b/libavcodec/msmpeg4data.c
@@ -990,1145 +990,6 @@ const uint8_t ff_msmp4_mv_table1_lens[MSMPEG4_MV_TABLES_NB_ELEMS] = {
     14,  4,
 };
 
-static const uint16_t table0_mv_code[1100] = {
-    0x0001, 0x0003, 0x0005, 0x0007, 0x0003, 0x0008, 0x000c, 0x0001,
-    0x0002, 0x001b, 0x0006, 0x000b, 0x0015, 0x0002, 0x000e, 0x000f,
-    0x0014, 0x0020, 0x0022, 0x0025, 0x0027, 0x0029, 0x002d, 0x004b,
-    0x004d, 0x0003, 0x0022, 0x0023, 0x0025, 0x0027, 0x0042, 0x0048,
-    0x0049, 0x0050, 0x005c, 0x0091, 0x009f, 0x000e, 0x0043, 0x004c,
-    0x0054, 0x0056, 0x008c, 0x0098, 0x009a, 0x009b, 0x00b1, 0x00b2,
-    0x0120, 0x0121, 0x0126, 0x0133, 0x0139, 0x01a1, 0x01a4, 0x01a5,
-    0x01a6, 0x01a7, 0x01ae, 0x01af, 0x000b, 0x0019, 0x0085, 0x0090,
-    0x009b, 0x00aa, 0x00af, 0x010c, 0x010e, 0x011c, 0x011e, 0x0133,
-    0x0144, 0x0160, 0x0174, 0x0175, 0x0177, 0x0178, 0x0249, 0x024b,
-    0x0252, 0x0261, 0x0265, 0x0270, 0x0352, 0x0353, 0x0355, 0x0359,
-    0x0010, 0x0011, 0x0013, 0x0034, 0x0035, 0x0036, 0x0037, 0x003d,
-    0x003e, 0x0109, 0x0126, 0x0156, 0x021a, 0x021e, 0x023a, 0x023e,
-    0x028e, 0x028f, 0x02cf, 0x0491, 0x0494, 0x049f, 0x04a0, 0x04a3,
-    0x04a6, 0x04a7, 0x04ad, 0x04ae, 0x04c0, 0x04c4, 0x04c6, 0x04c8,
-    0x04c9, 0x04f5, 0x04f6, 0x04f7, 0x0680, 0x0682, 0x0683, 0x0688,
-    0x0689, 0x068d, 0x068e, 0x068f, 0x06a2, 0x06a3, 0x06a9, 0x06b0,
-    0x06b1, 0x06b4, 0x06b5, 0x0024, 0x0060, 0x0063, 0x0078, 0x0079,
-    0x0211, 0x0244, 0x0245, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b,
-    0x026b, 0x02af, 0x02b8, 0x02bb, 0x0436, 0x0476, 0x0477, 0x047e,
-    0x04c8, 0x04c9, 0x04ca, 0x0514, 0x0586, 0x0587, 0x0598, 0x059d,
-    0x05d9, 0x05da, 0x0920, 0x0921, 0x093b, 0x093c, 0x093d, 0x0942,
-    0x0943, 0x0944, 0x0945, 0x0959, 0x095e, 0x095f, 0x0982, 0x0983,
-    0x098e, 0x098f, 0x09c4, 0x09e7, 0x09e8, 0x09e9, 0x0d02, 0x0d17,
-    0x0d18, 0x0d19, 0x0d41, 0x0d42, 0x0d43, 0x0d50, 0x0d5f, 0x0d6d,
-    0x0d6e, 0x0d6f, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
-    0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x041e, 0x041f, 0x0420, 0x0421,
-    0x048c, 0x048d, 0x04d3, 0x04d4, 0x04d5, 0x055c, 0x055d, 0x0572,
-    0x0573, 0x0574, 0x0575, 0x08de, 0x08df, 0x08fe, 0x08ff, 0x0996,
-    0x0a36, 0x0a37, 0x0b08, 0x0b09, 0x0b0a, 0x0b0b, 0x0b32, 0x0b33,
-    0x0b34, 0x0b35, 0x0b36, 0x0b37, 0x0b38, 0x0b39, 0x0bb0, 0x0bf7,
-    0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, 0x0bfc, 0x0bfd, 0x0bfe, 0x0bff,
-    0x1254, 0x1255, 0x1256, 0x1257, 0x1270, 0x1271, 0x1272, 0x1273,
-    0x1274, 0x1275, 0x12ab, 0x12ac, 0x12ad, 0x12ae, 0x12af, 0x12b0,
-    0x12b1, 0x1315, 0x1316, 0x1317, 0x13bf, 0x13c0, 0x13c1, 0x13c2,
-    0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7, 0x13c8, 0x13c9, 0x13ca,
-    0x13cb, 0x13cc, 0x13cd, 0x1a06, 0x1a07, 0x1a28, 0x1a29, 0x1a2a,
-    0x1a2b, 0x1a2c, 0x1a2d, 0x1a80, 0x1abb, 0x1abc, 0x1abd, 0x1ad8,
-    0x1ad9, 0x0094, 0x0095, 0x0096, 0x0097, 0x00a0, 0x00a1, 0x00a2,
-    0x00a3, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837,
-    0x0838, 0x0839, 0x083a, 0x083b, 0x0939, 0x093a, 0x093b, 0x093c,
-    0x093d, 0x093e, 0x093f, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x09a4,
-    0x09a5, 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2,
-    0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba,
-    0x11bb, 0x132f, 0x1454, 0x1455, 0x1456, 0x1457, 0x1458, 0x1459,
-    0x145a, 0x145b, 0x145c, 0x145d, 0x145e, 0x145f, 0x1460, 0x1461,
-    0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467, 0x1468, 0x1469,
-    0x146a, 0x146b, 0x17de, 0x17df, 0x17e0, 0x17e1, 0x17e2, 0x17e3,
-    0x17e4, 0x17e5, 0x17e6, 0x17e7, 0x17e8, 0x17e9, 0x17ea, 0x17eb,
-    0x17ec, 0x17ed, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545,
-    0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d,
-    0x254e, 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555,
-    0x2628, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c,
-    0x276d, 0x276e, 0x276f, 0x2770, 0x2771, 0x2772, 0x2773, 0x2774,
-    0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c,
-    0x277d, 0x3503, 0x3544, 0x3545, 0x3546, 0x3547, 0x3560, 0x3561,
-    0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, 0x3569,
-    0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, 0x3571,
-    0x3572, 0x3573, 0x3574, 0x3575, 0x03f0, 0x103d, 0x103e, 0x103f,
-    0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
-    0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f,
-    0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
-    0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f,
-    0x1060, 0x1061, 0x1270, 0x1271, 0x21b8, 0x21b9, 0x21ba, 0x21bb,
-    0x21bc, 0x21bd, 0x21be, 0x21bf, 0x21f0, 0x21f1, 0x21f2, 0x21f3,
-    0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f8, 0x21f9, 0x21fa, 0x21fb,
-    0x21fc, 0x21fd, 0x21fe, 0x21ff, 0x2340, 0x2341, 0x2342, 0x2343,
-    0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b,
-    0x234c, 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353,
-    0x2354, 0x2355, 0x2356, 0x2357, 0x265c, 0x2f88, 0x2f89, 0x2f8a,
-    0x2f8b, 0x2f8c, 0x2f8d, 0x2f8e, 0x2f8f, 0x2f90, 0x2f91, 0x2f92,
-    0x2f93, 0x2f94, 0x2f95, 0x2f96, 0x2f97, 0x2f98, 0x2f99, 0x2f9a,
-    0x2f9b, 0x2f9c, 0x2f9d, 0x2f9e, 0x2f9f, 0x2fa0, 0x2fa1, 0x2fa2,
-    0x2fa3, 0x2fa4, 0x2fa5, 0x2fa6, 0x2fa7, 0x2fa8, 0x2fa9, 0x2faa,
-    0x2fab, 0x2fac, 0x2fad, 0x2fae, 0x2faf, 0x2fb0, 0x2fb1, 0x2fb2,
-    0x2fb3, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 0x2fb8, 0x2fb9, 0x2fba,
-    0x2fbb, 0x4c52, 0x4c53, 0x4e28, 0x4e29, 0x4e2a, 0x4e2b, 0x4e2c,
-    0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, 0x4e33, 0x4e34,
-    0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, 0x4e3b, 0x4e3c,
-    0x4e3d, 0x4e3e, 0x4e3f, 0x4e80, 0x4e81, 0x4e82, 0x4e83, 0x4e84,
-    0x4e85, 0x4e86, 0x4e87, 0x4e88, 0x4e89, 0x4e8a, 0x4e8b, 0x4e8c,
-    0x4e8d, 0x4e8e, 0x4e8f, 0x4e90, 0x4e91, 0x4e92, 0x4e93, 0x4e94,
-    0x4e95, 0x4e96, 0x4e97, 0x4e98, 0x4e99, 0x4e9a, 0x4e9b, 0x4e9c,
-    0x4e9d, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea1, 0x4ea2, 0x4ea3, 0x4ea4,
-    0x4ea5, 0x4ea6, 0x4ea7, 0x4ea8, 0x4ea9, 0x4eaa, 0x4eab, 0x4eac,
-    0x4ead, 0x4eae, 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb2, 0x4eb3, 0x4eb4,
-    0x4eb5, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, 0x4eba, 0x4ebb, 0x4ebc,
-    0x4ebd, 0x4ebe, 0x4ebf, 0x4ec0, 0x4ec1, 0x4ec2, 0x4ec3, 0x4ec4,
-    0x4ec5, 0x4ec6, 0x4ec7, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x6a04,
-    0x6a05, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8,
-    0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0,
-    0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8,
-    0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, 0x07ff, 0x2000,
-    0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008,
-    0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x200e, 0x200f, 0x2010,
-    0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018,
-    0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f, 0x2020,
-    0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028,
-    0x2029, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x202f, 0x2030,
-    0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038,
-    0x2039, 0x203a, 0x203b, 0x203c, 0x203d, 0x203e, 0x203f, 0x2040,
-    0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048,
-    0x2049, 0x204a, 0x204b, 0x204c, 0x204d, 0x204e, 0x204f, 0x2050,
-    0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058,
-    0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 0x205f, 0x2060,
-    0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068,
-    0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0x2070,
-    0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078,
-    0x2079, 0x4cba, 0x4cbb, 0x5d88, 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c,
-    0x5d8d, 0x5d8e, 0x5d8f, 0x5db0, 0x5db1, 0x5db2, 0x5db3, 0x5db4,
-    0x5db5, 0x5db6, 0x5db7, 0x5db8, 0x5db9, 0x5dba, 0x5dbb, 0x5dbc,
-    0x5dbd, 0x5dbe, 0x5dbf, 0x5e40, 0x5e41, 0x5e42, 0x5e43, 0x5e44,
-    0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4c,
-    0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5e54,
-    0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, 0x5e5b, 0x5e5c,
-    0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, 0x5e62, 0x5e63, 0x5e64,
-    0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c,
-    0x5e6d, 0x5e6e, 0x5e6f, 0x5e70, 0x5e71, 0x5e72, 0x5e73, 0x5e74,
-    0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, 0x5e7a, 0x5e7b, 0x5e7c,
-    0x5e7d, 0x5e7e, 0x5e7f, 0x5e80, 0x5e81, 0x5e82, 0x5e83, 0x5e84,
-    0x5e85, 0x5e86, 0x5e87, 0x5e88, 0x5e89, 0x5e8a, 0x5e8b, 0x5e8c,
-    0x5e8d, 0x5e8e, 0x5e8f, 0x5e90, 0x5e91, 0x5e92, 0x5e93, 0x5e94,
-    0x5e95, 0x5e96, 0x5e97, 0x5e98, 0x5e99, 0x5e9a, 0x5e9b, 0x5e9c,
-    0x5e9d, 0x5e9e, 0x5e9f, 0x5ea0, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4,
-    0x5ea5, 0x5ea6, 0x5ea7, 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac,
-    0x5ead, 0x5eae, 0x5eaf, 0x5eb0, 0x5eb1, 0x5eb2, 0x5eb3, 0x5eb4,
-    0x5eb5, 0x5eb6, 0x5eb7, 0x5eb8, 0x5eb9, 0x5eba, 0x5ebb, 0x5ebc,
-    0x5ebd, 0x5ebe, 0x5ebf, 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4,
-    0x5ec5, 0x5ec6, 0x5ec7, 0x5ec8, 0x5ec9, 0x5eca, 0x5ecb, 0x5ecc,
-    0x5ecd, 0x5ece, 0x5ecf, 0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4,
-    0x5ed5, 0x5ed6, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edb, 0x5edc,
-    0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4,
-    0x5ee5, 0x5ee6, 0x5ee7, 0x5ee8, 0x5ee9, 0x5eea, 0x5eeb, 0x5eec,
-    0x5eed, 0x5eee, 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef4,
-    0x5ef5, 0x5ef6, 0x5ef7, 0x5ef8, 0x5ef9, 0x5efa, 0x5efb, 0x5efc,
-    0x5efd, 0x5efe, 0x5eff, 0x5f00, 0x5f01, 0x5f02, 0x5f03, 0x5f04,
-    0x5f05, 0x5f06, 0x5f07, 0x5f08, 0x5f09, 0x5f0a, 0x5f0b, 0x5f0c,
-    0x5f0d, 0x5f0e, 0x5f0f, 0x0000,
-};
-
-static const uint8_t table0_mv_bits[1100] = {
-     1,  4,  4,  4,  5,  5,  5,  6,
-     6,  6,  7,  7,  7,  8,  8,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  9,  9,  9,  9,  9,  9,  9,
-     9,  9,  9,  9,  9, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16,
-    16, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17, 17, 17, 17, 17, 17,
-    17, 17, 17,  8,
-};
-
-static const uint8_t table0_mvx[1099] = {
-    32, 32, 31, 32, 33, 31, 33, 31,
-    33, 32, 34, 32, 30, 32, 31, 34,
-    35, 32, 34, 33, 29, 33, 30, 30,
-    31, 31, 35, 29, 33, 35, 33, 34,
-    31, 29, 30, 34, 30, 36, 28, 32,
-    34, 37, 30, 27, 32, 25, 39, 32,
-    34, 32, 35, 35, 35, 31, 35, 29,
-    32, 29, 30, 29, 37, 27, 36, 38,
-    37, 33, 32, 31, 29, 31, 28, 36,
-    33, 30, 34, 33, 33, 28, 27, 25,
-    31, 26, 39, 32, 32, 31, 33, 39,
-    31, 38, 28, 36, 21, 23, 43, 36,
-    34, 41, 30, 25, 28, 31, 30, 34,
-    38, 35, 61, 34, 28, 30, 37, 37,
-    35, 27, 36,  3, 59, 38, 37, 32,
-    31, 29, 26, 33, 37, 33, 27, 27,
-    35, 34, 34, 40, 42, 33, 32, 29,
-     4,  5, 28, 24, 25, 35, 39, 38,
-    32, 23, 27, 32, 30, 35, 26, 34,
-    60, 36, 29, 22, 26, 41,  7, 30,
-    38, 30, 36, 29, 30, 41, 26, 25,
-    32, 34, 24, 39,  1, 25, 39, 32,
-    28, 29, 32, 38, 26, 36, 28, 63,
-    28, 39, 23, 21, 26, 35, 31, 35,
-    57, 31, 29, 29, 28, 30, 27, 35,
-     2, 38, 40, 34, 37, 29, 38, 43,
-    26, 32, 33, 42, 24, 40, 28, 32,
-    32, 32, 36, 32, 43, 25, 21, 31,
-    30, 31, 41, 29, 33, 37, 26, 37,
-    27, 59, 23, 33, 35, 31, 31, 37,
-    38, 39, 32, 23, 32, 27, 37, 36,
-    31, 40, 25, 27, 38, 31, 36, 28,
-    31, 36, 25, 45,  3, 34, 38, 39,
-    40, 38, 30, 32, 19, 24, 25, 26,
-    45, 20, 24, 33, 33, 31, 41, 34,
-    39, 47, 40, 58, 59, 41, 33,  3,
-    17, 61, 42, 30, 26, 29, 36, 61,
-    33, 37, 62, 28, 25, 38, 25, 38,
-    17, 23, 34, 33, 21, 33, 49, 27,
-    32, 23, 27, 22, 24, 22, 39, 43,
-    27, 37,  6, 42, 47, 26, 30, 31,
-    41, 39, 33, 22, 45, 36, 32, 45,
-    19, 22, 30,  5,  5, 17, 29, 22,
-    31, 31, 43, 37, 27, 32, 32, 32,
-    33, 34, 43, 35, 29, 26, 22, 32,
-    19, 32, 25, 31, 41, 49, 28, 34,
-    28, 39, 34, 19, 37, 38, 29, 21,
-    36, 42, 24, 48, 16, 28, 49, 22,
-    34, 31, 38, 39, 44, 11, 35, 30,
-    33, 33, 23, 28, 33, 46, 15, 13,
-    24, 41, 24, 34, 34, 30, 26, 24,
-    14, 60, 21, 29, 39, 23, 35, 37,
-    63, 45, 33, 34, 47, 41, 22, 42,
-    35, 35, 23, 32, 35, 43, 32,  7,
-    31, 41, 20, 31, 16, 13, 63, 25,
-    30, 32, 35, 30, 30, 31, 42, 47,
-    39, 38, 40, 40, 51, 55, 56, 18,
-    21, 39, 39, 33, 17, 41, 23, 24,
-    43, 25, 31, 20, 19, 45,  1, 34,
-    31, 22, 35, 15, 46, 46, 35, 31,
-    28, 29, 29, 23, 41, 27, 14, 53,
-    53, 27, 24, 32, 57, 32, 17, 42,
-    37, 29, 33,  1, 25, 32, 32, 63,
-    26, 40, 44, 36, 31, 39, 20, 20,
-    44, 23, 33, 34, 35, 33, 33, 28,
-    41, 23, 41, 41, 29, 25, 26, 49,
-    29, 24, 37, 49, 50, 51, 51, 26,
-    39, 25, 26, 15, 39, 18, 42, 17,
-     4, 31, 32, 32, 60,  1, 42, 32,
-     0, 12, 19, 35, 21, 41, 17, 26,
-    20, 45, 46, 32, 37, 22, 47, 29,
-    31, 27, 29, 30, 21, 33, 35, 18,
-    25, 33, 50, 51, 42,  2, 15, 51,
-    53, 33, 25, 29, 55, 37, 38, 33,
-    38, 59, 38, 33, 39, 13, 32, 40,
-    61, 61, 32,  9, 44,  3, 31, 29,
-    25, 31, 27, 23,  9, 25,  9, 29,
-    20, 30, 30, 42, 18, 28, 25, 28,
-    28, 21, 29, 43, 29, 43, 26, 44,
-    44, 21, 38, 21, 24, 45, 45, 35,
-    39, 22, 35, 36, 34, 34, 45, 34,
-    29, 31, 46, 25, 46, 16, 17, 31,
-    20, 32, 47, 47, 47, 32, 49, 49,
-    49, 31,  1, 27, 28, 39, 39, 21,
-    36, 23, 51,  2, 40, 51, 32, 53,
-    24, 30, 24, 30, 21, 40, 57, 57,
-    31, 41, 58, 32, 12,  4, 32, 34,
-    59, 31, 32, 13,  9, 35, 26, 35,
-    37, 61, 37, 63, 26, 29, 41, 38,
-    23, 20, 41, 26, 41, 42, 42, 42,
-    26, 26, 26, 26,  1, 26, 37, 37,
-    37, 23, 34, 42, 27, 43, 34, 27,
-    31, 24, 33, 16,  3, 31, 24, 33,
-    24,  4, 44, 44, 11, 44, 31, 13,
-    13, 44, 45, 13, 25, 22, 38, 26,
-    38, 38, 39, 32, 30, 39, 30, 22,
-    32, 26, 30, 47, 47, 47, 19, 47,
-    30, 31, 35,  8, 23, 47, 47, 27,
-    35, 47, 31, 48, 35, 19, 36, 49,
-    49, 33, 31, 39, 27, 39, 49, 49,
-    50, 50, 50, 39, 31, 51, 51, 39,
-    28, 33, 33, 21, 40, 31, 52, 53,
-    40, 53,  9, 33, 31, 53, 54, 54,
-    54, 55, 55, 34, 15, 56, 25, 56,
-    21, 21, 40, 40, 25, 40, 58, 36,
-     5, 41, 41, 12, 60, 41, 41, 37,
-    22, 61, 18, 29, 29, 30, 61, 30,
-    61, 62, 62, 30, 30, 63, 18, 13,
-    30, 23, 19, 20, 20, 41, 13,  2,
-     5,  5,  1,  5, 32,  6, 32, 35,
-    20, 35, 27, 35, 35, 36, 36, 13,
-    36, 41, 41, 41,  3, 30, 42, 27,
-    20, 30, 27, 28, 30, 21, 33, 33,
-    14, 24, 30, 42, 24, 33, 25, 42,
-    43, 14, 43, 43, 14, 43,  7, 36,
-    37, 37, 37, 37,  7, 14, 25, 43,
-    43, 44, 15, 37,  7,  7,  3,  1,
-     8, 15, 15,  8, 44, 44, 44, 45,
-    45, 45, 45,  8,  8, 45, 21, 45,
-    28, 28, 28, 21, 28, 28, 22, 37,
-    46, 46, 37,  8, 29, 37, 29, 22,
-    46, 37, 22, 29, 47, 47, 38, 38,
-    16, 38, 38, 33, 38, 22, 47, 47,
-    29, 25, 16,  0, 48,  1, 34, 48,
-    48, 34, 25, 26, 26, 49, 49, 26,
-     1, 49,  4, 26,  4, 49,  1,  9,
-    49, 49, 49, 10, 49, 17, 38, 17,
-    17, 50, 38, 50, 50, 22, 38, 51,
-    38, 38, 51, 39, 39, 18, 22, 39,
-    51, 22, 52, 52, 52, 39, 53, 53,
-    10, 23, 18, 29, 10, 53, 29, 54,
-    11, 54, 11, 11, 55,  1, 18, 55,
-    55, 55, 55, 55, 55, 29, 34, 18,
-    29, 56, 56, 34, 57, 34, 34, 29,
-    29, 57, 57, 35, 35, 35, 35, 35,
-    39, 35, 59, 59, 18, 59, 39, 30,
-    18, 40, 60, 60, 61, 30, 18, 61,
-    61, 19, 19,
-};
-
-static const uint8_t table0_mvy[1099] = {
-    32, 31, 32, 33, 32, 31, 31, 33,
-    33, 34, 32, 30, 32, 35, 34, 31,
-    32, 29, 33, 30, 32, 34, 33, 31,
-    30, 35, 31, 31, 29, 33, 35, 30,
-    29, 33, 34, 34, 30, 32, 32, 36,
-    29, 32, 35, 32, 28, 32, 32, 27,
-    35, 37, 34, 29, 30, 36, 35, 34,
-    25, 30, 29, 35, 33, 31, 31, 32,
-    31, 28, 39, 28, 29, 37, 31, 33,
-    27, 36, 28, 36, 37, 33, 33, 31,
-    27, 32, 31, 38, 26, 25, 25, 33,
-    39, 31, 34, 30, 32, 32, 32, 34,
-    36, 32, 28, 33, 30, 38, 37, 27,
-    33, 28, 32, 37, 35, 38, 29, 34,
-    27, 29, 29, 32, 32, 34, 35,  3,
-    26, 36, 31, 38, 30, 26, 35, 34,
-    37, 26, 25, 32, 32, 39, 23, 37,
-    32, 32, 29, 32, 29, 36, 29, 30,
-    41, 31, 30, 21, 39, 25, 34, 38,
-    32, 35, 39, 32, 33, 33, 32, 27,
-    29, 25, 28, 27, 26, 31, 30, 35,
-    24, 24, 31, 34, 32, 30, 35, 40,
-    28, 38,  5, 35, 29, 36, 36, 32,
-    38, 30, 33, 31, 35, 26, 23, 38,
-    32, 41, 28, 25, 37, 40, 37, 39,
-    32, 36, 33, 39, 25, 26, 28, 31,
-    28, 42, 23, 31, 33, 31, 39,  1,
-    59, 22, 27,  4, 33, 34, 33, 24,
-    41,  3, 35, 41, 41, 28, 36, 36,
-    28, 33, 35, 21, 23, 21, 22, 37,
-    27, 27, 43, 29, 60, 39, 27, 25,
-    59, 34, 27, 27, 26, 40, 37, 27,
-    61, 26, 39, 33, 31, 22, 37, 25,
-    30, 25, 24, 61, 31, 34, 25, 38,
-    32, 32, 30,  3, 61, 43, 29, 23,
-    28, 32, 28, 32, 31, 34,  5, 33,
-    32, 33, 33, 42, 37, 23, 38, 31,
-    40, 26, 32, 26, 37, 38, 36, 24,
-    29, 30, 20, 22, 29, 24, 32, 41,
-     2, 34, 25, 33, 29, 31, 39, 35,
-    36, 24, 32, 30, 33, 27, 44, 60,
-    30, 36, 19, 34, 31, 24, 16, 35,
-    32, 38, 21, 33, 31, 31, 21, 35,
-     5, 17, 29, 38, 38, 18, 58, 19,
-    43, 41, 30, 41, 43, 39, 29,  7,
-    29, 17, 28, 19, 28, 31, 25, 19,
-    40, 26, 21, 33, 39, 23, 40, 30,
-    39, 34, 35, 32, 32, 24, 33, 30,
-    40, 47, 39, 37, 32, 33, 24, 23,
-    45, 47, 27, 23, 42, 32, 32, 33,
-    36, 37, 37, 17, 18, 22, 40, 38,
-    32, 31, 35, 24, 17, 25, 17, 23,
-    33, 34, 51, 42, 31, 36, 36, 29,
-    21, 22, 37, 44, 43, 25, 47, 33,
-    45, 27, 31, 58, 31, 32, 31, 38,
-    43, 20, 47, 45, 54,  1, 26, 34,
-    38, 14, 22, 24, 33, 34, 32, 32,
-    37, 21, 23, 49, 35, 23, 28, 39,
-    39, 23, 55, 33, 30, 30, 63, 16,
-    42, 28, 13, 33, 33, 35, 19, 46,
-    43, 17, 19, 36, 39, 24, 31, 32,
-    33, 26, 28, 62, 33, 63, 33, 39,
-    19, 49, 17, 31, 43, 13, 15, 29,
-    25, 35, 33, 23, 49, 41, 28, 29,
-    34, 38,  7, 61, 11, 50, 13, 41,
-    19, 47, 25, 26, 15, 42, 41, 29,
-    45, 27, 17, 35, 32, 29, 32, 24,
-    13, 26, 26, 31, 24, 33, 28, 30,
-    31, 11, 45, 46, 33, 33, 35, 57,
-    32, 32, 35, 45, 34, 11, 37, 42,
-    39, 37, 31, 49, 21, 27, 29, 47,
-    53, 40, 51, 16, 26,  1, 40, 30,
-    41, 44, 34, 25, 27, 31, 35, 35,
-    31, 15, 49,  1, 35, 40,  5, 58,
-    21, 29, 22, 59, 45, 31,  9, 26,
-     9, 29, 11, 32, 30,  3, 13, 20,
-    18, 20, 11,  3, 29, 40, 31, 53,
-    30, 17, 20, 37, 31, 42, 47, 47,
-    54, 38,  9, 34, 13, 37, 21, 25,
-    27, 43, 42, 45, 40, 25, 27, 46,
-    22, 25, 53, 20,  2, 14, 39, 15,
-    22, 44, 34, 21, 38, 33, 27, 48,
-    34, 52, 35, 47, 49, 54,  2, 13,
-    23, 52, 29, 45, 22, 49, 54, 21,
-    40, 42, 31, 30, 29, 34,  0, 25,
-    23, 51, 24, 59, 28, 38, 29, 31,
-     2, 13, 31,  8, 31, 33, 12, 45,
-    41,  7, 14, 30, 25, 18, 43, 20,
-    43, 35, 44,  1, 49, 42, 42, 18,
-    41, 38, 41, 44, 53, 11, 20, 25,
-    45, 46, 47, 48, 39, 52, 46, 49,
-    63, 55, 44, 38, 13, 13, 57, 22,
-    51, 16, 12, 28, 35, 57, 25, 20,
-    26, 28, 28, 29, 32, 31, 62, 34,
-    35, 35, 19, 49, 48, 39, 40, 18,
-    43, 46, 11,  6, 48, 19, 49, 41,
-    10, 23, 58, 17, 21, 23, 34, 30,
-    60,  0, 44, 34, 26, 37, 46, 43,
-    49, 59,  4, 34, 59, 37, 22, 25,
-    28, 46,  6, 40, 59, 42, 36, 61,
-    28, 30, 31, 43, 10, 22, 23, 47,
-    20, 52, 55, 36, 25, 16,  1, 11,
-    27, 29,  5, 63, 18, 41, 31, 34,
-    38,  1,  5, 13, 28, 31, 17, 38,
-    39, 41, 36, 37, 22, 39, 33, 43,
-    43, 15, 17, 49, 30, 21, 22, 20,
-    10, 17, 25, 54, 57,  3, 34,  8,
-    36, 25, 31, 14, 15, 19, 29, 25,
-    18, 39, 53, 22, 27, 20, 29, 33,
-    41, 42, 35, 62, 50, 29, 53, 50,
-    35, 55, 42, 61, 63,  4,  7, 42,
-    21, 46, 47, 49, 27, 46, 17, 55,
-    41, 50, 63,  4, 56, 18,  8, 10,
-    18, 51, 63, 36, 55, 18,  5, 55,
-     9, 29, 17, 21, 30, 27,  1, 59,
-     7, 11, 12, 15,  5, 42, 24, 41,
-    43,  7, 27, 22, 25, 31, 30, 37,
-    22, 39, 53, 29, 36, 37, 48,  0,
-     5, 13, 17, 31, 32, 26, 46, 28,
-    44, 45, 46, 53, 49, 51,  3, 41,
-     3, 22, 42, 33,  5, 45,  7, 22,
-    40, 53, 24, 14, 25, 27, 10, 12,
-    34, 16, 17, 53, 20, 26, 39, 45,
-    18, 45, 35, 33, 31, 49,  4, 39,
-    42, 11, 51,  5, 13, 26, 27, 17,
-    52, 30,  0, 22, 12, 34, 62, 36,
-    38, 41, 47, 30, 63, 38, 41, 43,
-    59, 33, 45, 37, 38, 40, 47, 24,
-    48, 49, 30,  1, 10, 22, 49, 15,
-    39, 59, 31, 32, 33, 18, 13, 15,
-    31, 21, 27, 44, 42, 39, 46, 17,
-    26, 32, 30, 31,  0, 30, 34,  9,
-    12, 13, 25, 31, 32, 55, 43, 35,
-    61, 33, 35, 46, 25, 47, 48, 62,
-    63, 38, 61,  1,  2,  5,  7,  9,
-    46, 10, 34, 35, 36, 55, 51,  7,
-    40, 23, 34, 37,  5, 13, 42, 18,
-    25, 27, 28,
-};
-
-static const uint16_t table1_mv_code[1100] = {
-    0x0000, 0x0007, 0x0009, 0x000f, 0x000a, 0x0011, 0x001a, 0x001c,
-    0x0011, 0x0031, 0x0025, 0x002d, 0x002f, 0x006f, 0x0075, 0x0041,
-    0x004c, 0x004e, 0x005c, 0x0060, 0x0062, 0x0066, 0x0068, 0x0069,
-    0x006b, 0x00a6, 0x00c1, 0x00cb, 0x00cc, 0x00ce, 0x00da, 0x00e8,
-    0x00ee, 0x0087, 0x0090, 0x009e, 0x009f, 0x00ba, 0x00ca, 0x00d8,
-    0x00db, 0x00df, 0x0104, 0x0109, 0x010c, 0x0143, 0x0145, 0x014a,
-    0x0156, 0x015c, 0x01b3, 0x01d3, 0x01da, 0x0103, 0x0109, 0x010b,
-    0x0122, 0x0127, 0x0134, 0x0161, 0x0164, 0x0176, 0x0184, 0x018d,
-    0x018e, 0x018f, 0x0190, 0x0193, 0x0196, 0x019d, 0x019e, 0x019f,
-    0x01a9, 0x01b2, 0x01b4, 0x01ba, 0x01bb, 0x01bc, 0x0201, 0x0202,
-    0x0205, 0x0207, 0x020d, 0x0210, 0x0211, 0x0215, 0x021b, 0x021f,
-    0x0281, 0x0285, 0x0290, 0x029c, 0x029d, 0x02a2, 0x02a7, 0x02a8,
-    0x02aa, 0x02b0, 0x02b1, 0x02b4, 0x02bc, 0x02bf, 0x0320, 0x0326,
-    0x0327, 0x0329, 0x032a, 0x0336, 0x0360, 0x0362, 0x0363, 0x0372,
-    0x03b2, 0x03bc, 0x03bd, 0x0203, 0x0205, 0x021a, 0x0249, 0x024a,
-    0x024c, 0x02c7, 0x02ca, 0x02ce, 0x02ef, 0x030d, 0x0322, 0x0325,
-    0x0338, 0x0373, 0x037a, 0x0409, 0x0415, 0x0416, 0x0418, 0x0428,
-    0x042d, 0x042f, 0x0434, 0x0508, 0x0509, 0x0510, 0x0511, 0x051c,
-    0x051e, 0x0524, 0x0541, 0x0543, 0x0546, 0x0547, 0x054d, 0x0557,
-    0x055f, 0x056a, 0x056c, 0x056d, 0x056f, 0x0576, 0x0577, 0x057a,
-    0x057b, 0x057c, 0x057d, 0x0600, 0x0601, 0x0603, 0x0614, 0x0616,
-    0x0617, 0x061c, 0x061f, 0x0642, 0x0648, 0x0649, 0x064a, 0x064b,
-    0x0657, 0x0668, 0x0669, 0x066b, 0x066e, 0x067f, 0x06c2, 0x06c8,
-    0x06cb, 0x06de, 0x06df, 0x06e2, 0x06e3, 0x06ef, 0x0748, 0x074b,
-    0x076e, 0x076f, 0x077c, 0x0409, 0x0423, 0x0428, 0x0429, 0x042a,
-    0x042b, 0x0432, 0x0433, 0x0496, 0x049a, 0x04d5, 0x04db, 0x0581,
-    0x0582, 0x058b, 0x058c, 0x058d, 0x0598, 0x0599, 0x059a, 0x059e,
-    0x05dd, 0x0619, 0x0632, 0x0633, 0x0648, 0x0672, 0x06a1, 0x06a2,
-    0x06a3, 0x06af, 0x06e2, 0x06e3, 0x06e4, 0x0800, 0x0801, 0x0802,
-    0x0803, 0x081a, 0x081b, 0x0829, 0x082f, 0x0832, 0x083e, 0x083f,
-    0x0852, 0x0853, 0x0858, 0x086b, 0x0877, 0x0878, 0x0879, 0x087a,
-    0x087b, 0x0a00, 0x0a01, 0x0a0d, 0x0a0e, 0x0a0f, 0x0a24, 0x0a37,
-    0x0a3a, 0x0a3b, 0x0a3e, 0x0a46, 0x0a47, 0x0a4a, 0x0a4b, 0x0a5f,
-    0x0a79, 0x0a7a, 0x0a7b, 0x0a80, 0x0a81, 0x0a84, 0x0a85, 0x0a99,
-    0x0aa5, 0x0aa6, 0x0ab8, 0x0aba, 0x0abb, 0x0abc, 0x0abd, 0x0ac8,
-    0x0ace, 0x0acf, 0x0ad7, 0x0adc, 0x0aeb, 0x0c04, 0x0c25, 0x0c26,
-    0x0c27, 0x0c2a, 0x0c2b, 0x0c3a, 0x0c3b, 0x0c3c, 0x0c3d, 0x0ca0,
-    0x0cad, 0x0cd4, 0x0cd5, 0x0cfc, 0x0cfd, 0x0d86, 0x0d92, 0x0d93,
-    0x0d94, 0x0d95, 0x0db0, 0x0db8, 0x0db9, 0x0dba, 0x0dbb, 0x0dc0,
-    0x0dc2, 0x0dc3, 0x0dda, 0x0ddb, 0x0ddc, 0x0ddd, 0x0e92, 0x0e93,
-    0x0e94, 0x0e95, 0x0ec7, 0x0ecc, 0x0ece, 0x0ecf, 0x0ed8, 0x0ed9,
-    0x0eda, 0x0edb, 0x0808, 0x0809, 0x080a, 0x0810, 0x0811, 0x0844,
-    0x0845, 0x0861, 0x0862, 0x0863, 0x086c, 0x0922, 0x0923, 0x092e,
-    0x092f, 0x0936, 0x0937, 0x09b1, 0x09b2, 0x09b3, 0x09b4, 0x09b5,
-    0x09b8, 0x09b9, 0x09ba, 0x09bb, 0x09bc, 0x09bd, 0x09be, 0x09bf,
-    0x0b00, 0x0b15, 0x0b2c, 0x0b2d, 0x0b2e, 0x0b2f, 0x0b36, 0x0bb9,
-    0x0c28, 0x0c2a, 0x0c2b, 0x0c2c, 0x0c2d, 0x0c2e, 0x0c2f, 0x0c30,
-    0x0c31, 0x0c38, 0x0c60, 0x0c61, 0x0c62, 0x0c63, 0x0c8d, 0x0c8e,
-    0x0c8f, 0x0c92, 0x0cbe, 0x0cbf, 0x0ce6, 0x0ce7, 0x0d40, 0x0d41,
-    0x0d57, 0x0d58, 0x0d59, 0x0d5a, 0x0d5b, 0x0d5c, 0x0d5d, 0x0d98,
-    0x0d99, 0x0d9a, 0x0d9b, 0x0d9c, 0x0d9d, 0x0dad, 0x0dae, 0x0daf,
-    0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, 0x0dca, 0x0dcb, 0x0dec, 0x0ded,
-    0x0dee, 0x0def, 0x1018, 0x1022, 0x1023, 0x1030, 0x1031, 0x1032,
-    0x1033, 0x1050, 0x1051, 0x105c, 0x1074, 0x1075, 0x1076, 0x1077,
-    0x1078, 0x1079, 0x107a, 0x107b, 0x10b2, 0x10b3, 0x10b8, 0x10b9,
-    0x10ba, 0x10bb, 0x10d4, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x1404,
-    0x1405, 0x1406, 0x1407, 0x1410, 0x1411, 0x1412, 0x1413, 0x1414,
-    0x1415, 0x1416, 0x1417, 0x1418, 0x1419, 0x1466, 0x1467, 0x1468,
-    0x1469, 0x146a, 0x146b, 0x146c, 0x146d, 0x147e, 0x147f, 0x1488,
-    0x1489, 0x148a, 0x148b, 0x14b6, 0x14b7, 0x14b8, 0x14b9, 0x14ba,
-    0x14bb, 0x14bc, 0x14bd, 0x14f0, 0x14f1, 0x14f8, 0x14f9, 0x14fa,
-    0x14fb, 0x14fc, 0x14fd, 0x14fe, 0x14ff, 0x152a, 0x152b, 0x152c,
-    0x152d, 0x152e, 0x152f, 0x1530, 0x1531, 0x1548, 0x1549, 0x154e,
-    0x154f, 0x1558, 0x1559, 0x155a, 0x155b, 0x1572, 0x159a, 0x159b,
-    0x15ac, 0x15ba, 0x15bb, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4,
-    0x15d5, 0x181d, 0x181e, 0x181f, 0x1840, 0x1841, 0x1842, 0x1843,
-    0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x1861, 0x1862,
-    0x1863, 0x1864, 0x1865, 0x1866, 0x1867, 0x1868, 0x1869, 0x186a,
-    0x186b, 0x186c, 0x186d, 0x186e, 0x191b, 0x191c, 0x191d, 0x191e,
-    0x191f, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947, 0x1958,
-    0x1959, 0x19ed, 0x19ee, 0x19ef, 0x19f0, 0x19f1, 0x19f2, 0x19f3,
-    0x19f4, 0x19f5, 0x19f6, 0x19f7, 0x1b0e, 0x1b0f, 0x1b62, 0x1b63,
-    0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b68, 0x1b69, 0x1b6a, 0x1b6b,
-    0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b82, 0x1ba8, 0x1ba9, 0x1baa,
-    0x1bab, 0x1bac, 0x1bad, 0x1bae, 0x1baf, 0x1bb0, 0x1bb1, 0x1bb2,
-    0x1bb3, 0x1d80, 0x1d81, 0x1d82, 0x1d83, 0x1d84, 0x1d85, 0x1d86,
-    0x1d87, 0x1d88, 0x1d89, 0x1d8a, 0x1d8b, 0x1d8c, 0x1d8d, 0x1007,
-    0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f,
-    0x1016, 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086,
-    0x1087, 0x10c0, 0x123a, 0x123b, 0x123c, 0x123d, 0x123e, 0x123f,
-    0x1240, 0x1241, 0x1242, 0x1243, 0x1350, 0x1352, 0x1353, 0x1358,
-    0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f, 0x1360,
-    0x1361, 0x1602, 0x1603, 0x160c, 0x160d, 0x160e, 0x160f, 0x1620,
-    0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627, 0x1628,
-    0x1629, 0x166e, 0x166f, 0x167c, 0x167d, 0x167e, 0x167f, 0x1770,
-    0x1771, 0x1852, 0x1853, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876,
-    0x1877, 0x1878, 0x1879, 0x187a, 0x187b, 0x187c, 0x187d, 0x187e,
-    0x187f, 0x1918, 0x1919, 0x1926, 0x1927, 0x1970, 0x1971, 0x1972,
-    0x1973, 0x1974, 0x1975, 0x1976, 0x1977, 0x1978, 0x1979, 0x197a,
-    0x197b, 0x1aa0, 0x1aa1, 0x1aa2, 0x1aa3, 0x1aa4, 0x1aa5, 0x1aa6,
-    0x1aa7, 0x1aa8, 0x1aa9, 0x1aaa, 0x1aab, 0x1aac, 0x1aad, 0x1b3c,
-    0x1b3d, 0x1b3e, 0x1b3f, 0x1b50, 0x1b51, 0x1b52, 0x1b53, 0x1b54,
-    0x1b55, 0x1b56, 0x1b57, 0x1b58, 0x1b59, 0x2032, 0x2033, 0x2034,
-    0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, 0x203c,
-    0x203d, 0x203e, 0x203f, 0x2040, 0x2041, 0x2042, 0x2043, 0x20ba,
-    0x20bb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20e0, 0x20e1, 0x20e2,
-    0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x21aa, 0x21ab, 0x21c0,
-    0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 0x21c8,
-    0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 0x21d0,
-    0x21d1, 0x21d2, 0x21d3, 0x2894, 0x2895, 0x2896, 0x2897, 0x2898,
-    0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f, 0x28c0,
-    0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7, 0x28c8,
-    0x28c9, 0x28ca, 0x28cb, 0x2930, 0x2931, 0x2932, 0x2933, 0x2934,
-    0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c,
-    0x293d, 0x293e, 0x293f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964,
-    0x2965, 0x2966, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x2a40,
-    0x2a41, 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48,
-    0x2a49, 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50,
-    0x2a51, 0x2a52, 0x2a53, 0x2ae6, 0x2ae7, 0x2b24, 0x2b25, 0x2b26,
-    0x2b27, 0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e,
-    0x2b2f, 0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b5a, 0x2b5b, 0x3014,
-    0x3015, 0x3016, 0x3017, 0x3020, 0x3021, 0x3022, 0x3023, 0x3024,
-    0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c,
-    0x302d, 0x302e, 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034,
-    0x3035, 0x3036, 0x3037, 0x3038, 0x3039, 0x30c0, 0x30c1, 0x30de,
-    0x30df, 0x3218, 0x3219, 0x321a, 0x321b, 0x321c, 0x321d, 0x321e,
-    0x321f, 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226,
-    0x3227, 0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e,
-    0x322f, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3378,
-    0x3379, 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x337f, 0x33c0,
-    0x33c1, 0x33c2, 0x33c3, 0x33c4, 0x33c5, 0x33c6, 0x33c7, 0x33c8,
-    0x33c9, 0x33ca, 0x33cb, 0x33cc, 0x33cd, 0x33ce, 0x33cf, 0x33d0,
-    0x33d1, 0x33d2, 0x33d3, 0x33d4, 0x33d5, 0x33d6, 0x33d7, 0x33d8,
-    0x33d9, 0x3706, 0x3707, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734,
-    0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c,
-    0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744,
-    0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c,
-    0x374d, 0x374e, 0x374f, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 0x3be8,
-    0x3be9, 0x3bea, 0x3beb, 0x3bec, 0x3bed, 0x3bee, 0x3bef, 0x3bf0,
-    0x3bf1, 0x3bf2, 0x3bf3, 0x3bf4, 0x3bf5, 0x3bf6, 0x3bf7, 0x3bf8,
-    0x3bf9, 0x3bfa, 0x3bfb, 0x3bfc, 0x3bfd, 0x3bfe, 0x3bff, 0x2000,
-    0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008,
-    0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x202e, 0x202f, 0x2182,
-    0x2183, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 0x21b8, 0x21b9, 0x21ba,
-    0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x2460, 0x2461, 0x2462,
-    0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a,
-    0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472,
-    0x2473, 0x26a2, 0x26a3, 0x000b,
-};
-
-static const uint8_t table1_mv_bits[1100] = {
-     2,  4,  4,  4,  5,  5,  5,  5,
-     6,  6,  7,  7,  7,  7,  7,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  9,  9,  9,  9,  9,  9,  9,
-     9,  9,  9,  9,  9,  9,  9,  9,
-     9,  9,  9,  9,  9, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 10, 10, 10, 10, 10,
-    10, 10, 10, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 11, 11, 11, 11, 11,
-    11, 11, 11, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 13,
-    13, 13, 13, 13, 13, 13, 13, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 14,
-    14, 14, 14, 14, 14, 14, 14, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15,  4,
-};
-
-static const uint8_t table1_mvx[1099] = {
-    32, 31, 32, 31, 33, 32, 33, 33,
-    31, 34, 30, 32, 32, 34, 35, 32,
-    34, 33, 29, 30, 30, 32, 31, 31,
-    33, 35, 35, 33, 31, 29, 29, 33,
-    34, 30, 31, 28, 36, 30, 34, 32,
-    32, 37, 32, 32, 25, 27, 39, 32,
-    32, 32, 38, 35, 36, 32, 37, 61,
-    26, 32, 34, 35,  3, 35, 27, 28,
-    29, 34, 28, 37, 31, 36, 32, 27,
-    31, 30, 29, 39, 33, 29, 33, 35,
-    25, 25, 29, 33, 31, 31, 31, 33,
-    32, 30, 32, 32, 41, 39, 33, 36,
-    32, 28, 34, 36, 38, 24, 60, 31,
-    23, 28, 32, 33, 59, 32, 40, 30,
-     5, 34, 32, 38, 32, 30, 43,  4,
-    32, 32, 42, 31, 31, 32, 26, 38,
-    26, 22, 21, 37, 61, 63, 37, 31,
-    32, 33,  2,  1, 23, 33, 41, 27,
-    35, 30, 38, 23, 33,  3, 28, 34,
-    34, 27, 41, 29, 39, 35, 36, 29,
-    32, 27, 30, 32, 24, 61, 37, 26,
-    59, 25, 35, 27, 36, 37, 30, 31,
-    34, 40,  3, 28, 34, 39, 32, 31,
-    32, 30, 24, 28, 35, 36, 26, 32,
-    31, 33, 29, 33, 39, 25, 30, 24,
-    35, 59, 29, 34, 25, 30, 21, 35,
-    43, 40, 32, 29,  5, 28, 31, 62,
-    33, 33, 25, 31, 21, 31, 43, 31,
-    34, 33, 20, 40, 39, 31, 31, 57,
-    38, 32, 42, 33, 32, 31, 32, 29,
-    30, 44,  5, 31, 22, 34, 36, 17,
-    38, 58, 38, 35, 32, 60, 35, 24,
-    32, 38, 16, 45, 42, 32, 31, 29,
-     4, 30, 17, 40, 46, 48, 63, 32,
-    42, 19, 41, 22, 28, 36, 45, 33,
-    33, 32, 29,  7, 41, 42, 18, 33,
-    33, 32, 22, 37,  1, 26, 22, 23,
-    49, 28, 26, 27, 32, 33, 27, 23,
-    28, 36, 15,  6, 34, 27, 31, 26,
-    23,  2, 33, 32, 34, 41, 28, 32,
-    41,  0, 36, 38, 34, 31, 47, 32,
-    17, 31, 39, 33, 37, 51, 30, 47,
-    32, 50, 32, 19, 63, 30, 25, 27,
-    33, 62, 24, 31, 27, 30, 37, 31,
-    45, 32, 39, 20, 46, 47, 35, 19,
-    34,  1, 49, 21, 21, 14, 51, 26,
-    23, 31, 36, 35, 58, 29, 29, 21,
-    20, 42, 13, 28, 12, 40, 31, 33,
-    39, 60, 32, 44, 33, 31, 28, 37,
-    29, 32, 30, 49, 43, 28, 39, 25,
-    32, 48,  2, 15, 20, 25, 31, 28,
-    21, 24, 25, 15, 31, 17, 37, 43,
-    18, 32, 33, 24, 33, 36, 13, 33,
-    31, 39, 11, 31, 33, 32, 39, 37,
-    32, 32, 29, 17, 44, 46, 36, 35,
-    26, 37, 58, 32, 34, 38,  8, 38,
-    38, 22, 29, 25, 16, 35, 32, 35,
-    33, 43, 18, 46, 38, 50, 33, 18,
-    53, 60, 13, 32, 36, 33, 51, 36,
-    43, 45, 27, 42, 29, 24, 30, 25,
-    31, 52, 31, 35, 38,  9, 22, 34,
-     4, 17, 28, 55, 42, 25, 17, 20,
-    47, 34, 33, 16, 40, 25, 16, 30,
-    53, 29, 10, 11, 14, 26, 33,  4,
-    35, 44, 26, 16, 31, 26, 34, 38,
-    29, 31, 30, 24, 22, 61, 32,  9,
-    45, 34, 31, 19,  9, 31, 46, 31,
-    35, 54, 29, 57, 30, 50,  3, 31,
-    63, 34, 47, 41, 51, 18, 31, 14,
-    37, 38, 31, 24, 32, 31, 50, 33,
-    31, 54, 27,  9, 33, 23, 19, 32,
-    29, 29, 33, 28, 47, 49, 30, 47,
-    33, 27, 25, 54, 44, 45, 50, 58,
-    51, 48, 33, 59, 33, 34, 57, 13,
-    26, 33, 13, 48, 30, 11,  7, 56,
-    34, 55, 26,  0, 26, 35,  1, 51,
-    33, 53, 31, 45, 12, 29, 29, 51,
-    31, 48,  2,  6, 34, 30, 28, 33,
-    60, 40, 27, 46, 31,  9, 35, 29,
-    31, 39, 55, 46, 19, 37, 62, 34,
-    30, 16, 19, 49, 41, 41, 39, 37,
-    14,  5, 13, 35, 55, 30, 40, 40,
-    42,  8, 20, 25, 45, 35, 33, 36,
-    54, 38, 27, 37, 62, 40, 15, 59,
-    49, 31, 29, 34, 34, 39, 24, 29,
-    25, 29, 21, 29, 10, 61, 33, 49,
-    35, 34,  3, 38, 39, 29,  7, 41,
-     1, 35,  4, 23, 15, 23, 11, 37,
-    28, 35, 30, 30, 24,  1, 43, 56,
-     8, 34, 42, 24, 45, 30, 20, 23,
-     8, 38, 22, 33, 17, 52, 34, 22,
-    53, 43, 44,  1, 27, 31, 41, 43,
-    41, 30, 31, 36, 30,  5, 55, 31,
-    33, 30, 40, 23, 15, 29, 34, 34,
-    59, 34, 30, 11, 13, 38,  5,  0,
-    30, 42,  5, 30, 29, 34, 10, 44,
-    30, 63, 35, 12,  3, 26, 15, 17,
-    25, 34, 43, 39, 34, 56, 29, 23,
-    30, 12, 30, 10, 35,  9, 24, 58,
-    10, 12, 54, 33, 37, 20, 41, 35,
-    29, 18, 61, 30, 40, 24, 39, 53,
-    62, 26, 29, 33, 34, 53, 49, 21,
-    27, 11, 63, 20, 26, 23,  7, 13,
-     6, 47, 29, 30,  9, 51, 22, 34,
-    21, 25, 33, 56, 57, 30, 38, 51,
-    51, 38, 63, 28, 40, 35, 33, 18,
-    33, 33, 24, 58, 58, 34, 49, 29,
-    43,  4,  1,  4, 42, 35, 35, 30,
-    17,  5, 56, 61, 25, 37, 36, 55,
-    28, 35, 29, 50, 48, 52,  2, 42,
-    34, 40, 46, 46, 43, 35, 29, 48,
-    20, 29, 31, 41,  7, 30, 35, 19,
-    14, 21,  8, 39, 39, 40, 46, 55,
-    34,  6, 30, 34, 37, 25, 37, 33,
-    22, 44, 52, 17, 35, 29, 36, 35,
-    40, 37, 28, 30, 50, 14, 28, 55,
-     6, 23, 19, 14, 30,  3, 30, 28,
-    28, 61, 61, 47, 45, 48, 40, 40,
-    34, 34, 25, 30, 29, 35,  4, 26,
-    53, 50, 26, 41, 27, 59, 27, 38,
-    39,  3, 50, 43, 47, 23, 33, 55,
-    35, 21, 23, 35, 61, 33, 46, 52,
-    35, 34, 24, 30, 43, 16, 37, 21,
-     2, 24, 45, 34, 30, 55, 55,  1,
-    29, 29, 26, 28, 25, 31, 36, 22,
-    17, 30, 52,  2, 44, 44, 57, 26,
-    62, 41, 39, 57, 26, 46, 49, 11,
-    16, 19,  5, 59, 38, 39, 58, 38,
-    25, 49, 50, 22, 28, 59,  9, 59,
-     7, 28, 55, 17,  4, 35, 50, 21,
-    29, 44, 47, 18, 24, 19, 25, 42,
-    35,  3, 51, 35, 16, 35, 30, 63,
-    57, 39, 39, 25, 35, 38,  9, 16,
-    36, 45, 31, 60, 14, 34, 42, 24,
-     0, 37, 18, 61, 57, 37, 28, 53,
-    20, 46, 14, 47, 38, 38, 38,  9,
-    34, 39, 43, 17, 39, 59,  5, 27,
-     0, 12, 27,
-};
-
-static const uint8_t table1_mvy[1099] = {
-    32, 32, 31, 31, 32, 33, 31, 33,
-    33, 32, 32, 30, 34, 31, 32, 29,
-    33, 30, 32, 33, 31, 35, 34, 30,
-    34, 31, 33, 29, 29, 31, 33, 35,
-    30, 30, 35, 32, 32, 34, 34, 28,
-    25, 32, 36, 27, 32, 32, 32, 37,
-    39,  3, 32, 30, 31, 26, 31, 32,
-    32, 38, 29, 29, 32, 34, 31, 31,
-    34, 35, 33, 33, 28, 33,  1, 33,
-    27, 29, 30, 31, 28, 29, 37, 35,
-    31, 33, 35, 27, 36, 37, 25, 25,
-    61, 35,  4,  5, 32, 33, 36, 30,
-    23, 30, 28, 34, 31, 32, 32, 39,
-    32, 34, 21, 39, 32, 59, 32, 28,
-    32, 36, 60, 33, 24, 36, 32, 32,
-    41,  2, 32, 38, 26, 22, 33, 30,
-    31, 32, 32, 30, 31, 32, 29,  3,
-    40, 38, 32, 32, 33, 26, 31, 34,
-    28, 38, 34, 31,  3, 31, 35, 38,
-    27, 35, 33, 28, 29, 27, 29, 27,
-    43, 29, 37, 63, 31, 33, 34, 30,
-    31, 30, 37, 30, 35, 35, 26, 41,
-    37, 31, 33, 28, 26, 30, 42, 24,
-     7, 27, 33, 29, 36, 28, 34, 57,
-    23, 41, 36, 23, 35, 34, 25, 30,
-    25, 33, 25, 25, 29, 24, 33, 39,
-    33, 33,  0, 37, 31, 36, 21, 32,
-    61, 24, 35, 61, 31,  5, 31, 59,
-    39, 21, 32, 30, 34, 22, 40, 32,
-    29, 16, 31,  5, 62,  2, 20, 39,
-    39, 32, 33,  1, 31, 24, 36, 32,
-    36, 32, 28, 26,  6, 31, 38, 34,
-    58, 35, 32, 33, 33, 17, 43, 26,
-    31, 40, 31, 34, 32, 32, 31, 19,
-    30, 32, 29, 33, 38, 38, 32, 59,
-    40, 18, 38, 32, 35, 34, 32, 17,
-     1, 15, 30, 28, 31, 28, 34, 29,
-    32, 27, 35, 27, 49, 22, 37, 34,
-    37, 26, 32, 32, 22, 28, 45, 29,
-    30, 31, 43, 46, 41, 30, 26, 13,
-    34, 32, 27, 38, 42, 42, 33, 47,
-    33, 60, 27, 42, 25, 32, 22, 32,
-    48, 32, 45, 33, 33, 41, 27, 25,
-    19, 31, 35, 19, 36, 42, 27, 17,
-    31, 44, 28, 33, 33, 31, 23, 31,
-    40, 33, 31, 34, 30, 32, 33, 36,
-    35, 47, 37, 41, 31, 23, 41, 29,
-    30, 35, 32, 25, 32, 28, 58,  2,
-    37, 33, 14, 33, 49, 20, 39, 36,
-    21,  9, 23, 33, 35, 24, 39, 37,
-    11, 33, 30, 31, 31, 28, 51, 40,
-    35, 29, 25, 33, 46, 35, 37, 30,
-    30,  8, 63, 28, 15, 40, 33, 45,
-    49, 25, 32,  4, 47, 51, 36, 39,
-    53, 10, 24, 29, 30, 31, 25, 40,
-    38, 38, 33, 56, 23, 27, 32, 37,
-    26, 29, 43, 36, 33, 24, 55, 43,
-     9, 29, 34, 34, 24, 33, 18, 33,
-    33, 30, 31, 50, 24, 60, 30, 39,
-    34, 30, 39, 28, 22, 38,  2, 26,
-    63, 32, 57, 21, 39, 33, 28, 18,
-    30, 34, 22, 33, 29, 41, 30, 34,
-    35, 21, 13, 34, 35, 39, 30, 46,
-    32, 42, 32, 31, 33, 26, 11, 33,
-    22, 31, 25, 31, 53, 27, 43, 25,
-    40, 50, 21, 36, 38, 30, 12, 31,
-    34, 20, 15, 29, 32, 62, 30, 13,
-    17, 32, 19, 31, 20, 31, 30,  7,
-     1, 17, 34, 37, 31, 31, 44, 34,
-    26, 40, 16, 37, 52, 48, 30, 20,
-    18, 33, 38, 29,  7, 25, 30, 54,
-    45, 47, 46, 41, 29, 29, 16, 30,
-    14, 26, 38, 34, 34, 29, 34, 30,
-    29, 30, 57, 30,  4, 46, 33, 29,
-    39, 44, 30, 31, 50, 33, 31, 32,
-    19, 32, 40, 31, 37, 47,  1, 35,
-    16, 31,  0, 35, 33,  1, 17, 34,
-     9, 34, 33, 31, 49, 43, 42, 51,
-    34, 29, 23, 29, 14, 30, 45, 49,
-    11, 24, 31, 28, 35, 41, 30, 44,
-    18, 29, 34, 35, 36, 25, 26, 21,
-    31, 30, 34, 19, 34, 44, 36, 38,
-    25, 31, 28, 23, 37,  3, 55, 41,
-    30, 22, 41, 24, 33, 26, 35, 35,
-    30, 55, 51, 47, 48, 38, 24, 15,
-    21, 50, 25, 46, 30, 29, 10, 34,
-    42, 45, 29, 42, 22,  3, 33, 27,
-    34,  1, 34, 28, 34, 36, 35, 23,
-    23, 13, 58,  3, 26, 63, 25, 31,
-    34, 61, 38, 39, 25, 61, 29, 37,
-    30, 41, 26, 48, 28, 33, 50, 35,
-    30, 37, 29, 29, 40,  6, 39, 28,
-    28, 19,  8, 22, 45, 34, 35, 10,
-    58, 17, 37, 39, 30, 18, 54, 14,
-    29, 16, 59, 30, 35, 23, 35, 30,
-    47, 36, 29, 55, 20, 12, 31, 35,
-    14, 29, 18, 34, 34, 24, 29, 26,
-    22,  2, 27, 23,  8, 30, 55, 38,
-    60, 31,  4, 34, 49, 34, 27, 34,
-    33, 30, 31, 54, 42, 35, 38, 46,
-    44, 26, 27,  9, 39, 25, 21, 29,
-    28, 42, 13,  0,  5, 34, 37, 28,
-    24, 29, 63, 26, 22, 27, 29, 25,
-    33, 25, 61,  0, 35, 25, 36, 15,
-    27, 40, 53, 33,  3, 10, 16, 37,
-    38, 18, 30, 46, 27,  9,  6, 29,
-    62,  8, 42, 28, 29,  3, 25, 16,
-    26, 29, 35, 28, 27, 51, 61, 48,
-    37,  9, 34,  7, 49, 45, 20, 29,
-    21,  5,  5, 29, 28, 34, 29, 24,
-    10, 24, 35, 36, 38, 55, 11, 36,
-    38, 53, 54, 26, 30, 49, 20, 27,
-    30, 39, 33, 41, 49, 22, 38, 38,
-     4, 30,  8,  9,  3, 24, 22, 50,
-    37, 36, 31, 27,  2,  9, 42, 63,
-    25, 19, 44,  1, 28, 28, 48, 30,
-    34, 41, 41, 38, 12, 27, 15,  0,
-    16, 34, 35, 38, 28, 29, 40, 42,
-    51, 52, 45, 54, 59, 59, 42, 44,
-    37, 26, 46, 24, 15, 39, 22, 46,
-    19, 35, 38, 17, 37, 23, 52, 55,
-    50, 37, 26, 11, 37, 12, 24, 30,
-    16, 13, 22, 13, 36, 35, 40, 41,
-    34, 41, 26, 53, 51,  5, 21, 30,
-     2, 63, 41, 20,  1, 56, 21, 24,
-    25,  5, 28, 35, 26, 28, 30, 18,
-    29, 23, 40, 34, 20, 42, 39, 34,
-    28, 61, 38, 27, 62,  9, 36, 17,
-     9, 49, 24, 25, 54, 34, 39, 37,
-     3,  1, 25, 38, 38, 44, 35, 36,
-    12, 60, 36, 38, 40, 25, 43, 39,
-    53, 28, 39, 57, 46, 10, 52, 27,
-    35, 42, 45, 59, 15, 60, 38, 24,
-    23, 39, 12, 29, 24,  0, 20, 16,
-    28, 43, 35, 28,  1, 49,  4, 21,
-    42, 39, 29,  3, 44, 21, 53, 55,
-    11,  5,  3, 39, 53, 28, 25, 19,
-    34, 28, 21,
-};
-
-MVTable ff_mv_tables[2] = {
-    { table0_mv_code,
-      table0_mv_bits,
-      table0_mvx,
-      table0_mvy, },
-    { table1_mv_code,
-      table1_mv_bits,
-      table1_mvx,
-      table1_mvy, }
-};
-
 const uint8_t ff_v2_mb_type[8][2] = {
     { 1, 1 }, {    0, 2 }, {    3, 3 }, {    9, 5 },
     { 5, 4 }, { 0x21, 7 }, { 0x20, 7 }, { 0x11, 6 },
diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h
index 2217b5ea48..13267d25c1 100644
--- a/libavcodec/msmpeg4data.h
+++ b/libavcodec/msmpeg4data.h
@@ -35,16 +35,6 @@
 #include "libavutil/attributes_internal.h"
 
 #include "rl.h"
-#include "vlc.h"
-
-/* motion vector table */
-typedef struct MVTable {
-    const uint16_t *table_mv_code;
-    const uint8_t *table_mv_bits;
-    const uint8_t *table_mvx;
-    const uint8_t *table_mvy;
-    const VLCElem *vlc;       /* decoding: vlc */
-} MVTable;
 
 FF_VISIBILITY_PUSH_HIDDEN
 #define NB_RL_TABLES  6
@@ -64,7 +54,6 @@ extern const uint16_t ff_msmp4_mv_table0[MSMPEG4_MV_TABLES_NB_ELEMS];
 extern const uint8_t  ff_msmp4_mv_table0_lens[MSMPEG4_MV_TABLES_NB_ELEMS];
 extern const uint16_t ff_msmp4_mv_table1[MSMPEG4_MV_TABLES_NB_ELEMS];
 extern const uint8_t  ff_msmp4_mv_table1_lens[MSMPEG4_MV_TABLES_NB_ELEMS];
-extern MVTable ff_mv_tables[2];
 
 extern const uint8_t ff_v2_mb_type[8][2];
 extern const uint8_t ff_v2_intra_cbpc[4][2];
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 5ce54a8d16..0ab2e473aa 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -55,11 +55,10 @@ static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
 static uint32_t mv_vector_tables[2][4096];
 
 /* build the table which associate a (x,y) motion vector to a vlc */
-static av_cold void init_mv_table(const MVTable *tab, uint32_t mv_vector_table[4096],
+static av_cold void init_mv_table(const uint16_t mv_table[], const uint8_t mv_table_lens[],
+                                  uint32_t mv_vector_table[4096],
                                   unsigned escape_code, int escape_length)
 {
-    int i, x, y;
-
     for (int i = 0; i < 4096; i++) {
         // Initialize to the table to "escaped". This code is equivalent to
         // the following double loop (with x and y ranging over 0..63):
@@ -67,11 +66,16 @@ static av_cold void init_mv_table(const MVTable *tab, uint32_t mv_vector_table[4
         mv_vector_table[i] = (escape_code << 20) | (i << 8) | escape_length;
     }
 
-    for (i = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS - 1; i++) {
-        x = tab->table_mvx[i];
-        y = tab->table_mvy[i];
-        mv_vector_table[(x << 6) | y] = (tab->table_mv_code[i] << 8) | tab->table_mv_bits[i];
+    for (uint32_t i = 0, code = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS; i++) {
+        int sym = mv_table[i];
+        int len = mv_table_lens[i];
+        int x = sym >> 8;
+        int y = sym & 0xFF;
+        // We ignore the escape value here and restore it after the loop.
+        mv_vector_table[(x << 6) | y] = (code >> (24 - len)) | len;
+        code += 1U << (32 - len);
     }
+    mv_vector_table[0] = (escape_code << 20) | escape_length;
 }
 
 void ff_msmpeg4_code012(PutBitContext *pb, int n)
@@ -128,8 +132,10 @@ static int get_size_of_code(const RLTable *rl, int last, int run,
 
 static av_cold void msmpeg4_encode_init_static(void)
 {
-    init_mv_table(&ff_mv_tables[0], mv_vector_tables[0], 0x0000, 8 + 12);
-    init_mv_table(&ff_mv_tables[1], mv_vector_tables[1], 0x000b, 4 + 12);
+    init_mv_table(ff_msmp4_mv_table0, ff_msmp4_mv_table0_lens,
+                  mv_vector_tables[0], 0x0000, 8 + 12);
+    init_mv_table(ff_msmp4_mv_table1, ff_msmp4_mv_table1_lens,
+                  mv_vector_tables[1], 0x000b, 4 + 12);
 
     for (int i = 0; i < NB_RL_TABLES; i++) {
         for (int level = 1; level <= MAX_LEVEL; level++) {
-- 
2.45.2


[-- Attachment #48: 0047-avcodec-mpegvideo-Move-MSMPEG4-fields-to-MSMPEG4-con.patch --]
[-- Type: text/x-patch, Size: 47297 bytes --]

From 2f66421c3470639904baed80a25094d73c2abc19 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 13:21:23 +0100
Subject: [PATCH 47/77] avcodec/mpegvideo: Move MSMPEG4 fields to MSMPEG4
 contexts

Several fields are not used by any generic code and can therefore
be moved to more specialized contexts.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h  |   7 --
 libavcodec/msmpeg4dec.c | 145 +++++++++++++++++++++-------------------
 libavcodec/msmpeg4dec.h |  12 +++-
 libavcodec/msmpeg4enc.c |  89 ++++++++++++------------
 libavcodec/msmpeg4enc.h |  16 ++++-
 libavcodec/vaapi_vc1.c  |   4 +-
 libavcodec/vc1.c        |  12 ++--
 libavcodec/vc1.h        |   4 ++
 libavcodec/vc1_block.c  |  26 +++----
 libavcodec/wmv2dec.c    |  72 +++++++++++---------
 libavcodec/wmv2enc.c    |  33 ++++-----
 11 files changed, 227 insertions(+), 193 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 136b9b18a7..39ca4b3d1a 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -372,11 +372,6 @@ typedef struct MpegEncContext {
     int esc_pos;
 
     /* MSMPEG4 specific */
-    int mv_table_index;
-    int rl_table_index;
-    int rl_chroma_table_index;
-    int dc_table_index;
-    int use_skip_mb_code;
     int slice_height;      ///< in macroblocks
     int first_slice_line;  ///< used in MPEG-4 too to handle resync markers
     int flipflop_rounding;
@@ -389,9 +384,7 @@ typedef struct MpegEncContext {
         MSMP4_WMV2,
         MSMP4_VC1,        ///< for VC1 (image), WMV3 (image) and MSS2.
     } msmpeg4_version;
-    int per_mb_rl_table;
     int esc3_level_length;
-    int esc3_run_length;
     int inter_intra_pred;
     int mspel;
 
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
index b60e218f6a..df67d43542 100644
--- a/libavcodec/msmpeg4dec.c
+++ b/libavcodec/msmpeg4dec.c
@@ -107,11 +107,12 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
 
 static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
+    MSMP4DecContext *const ms = mpv_to_msmpeg4(s);
     int cbp, code, i;
     uint32_t * const mb_type_ptr = &s->cur_pic.mb_type[s->mb_x + s->mb_y*s->mb_stride];
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        if (s->use_skip_mb_code) {
+        if (ms->use_skip_mb_code) {
             if (get_bits1(&s->gb)) {
                 /* skip mb */
                 s->mb_intra = 0;
@@ -198,7 +199,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
 
     s->bdsp.clear_blocks(s->block[0]);
     for (i = 0; i < 6; i++) {
-        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+        if (ff_msmpeg4_decode_block(ms, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
         {
              av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
              return -1;
@@ -209,6 +210,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
 
 static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
+    MSMP4DecContext *const ms = mpv_to_msmpeg4(s);
     int cbp, code, i;
     uint8_t *coded_val;
     uint32_t * const mb_type_ptr = &s->cur_pic.mb_type[s->mb_x + s->mb_y*s->mb_stride];
@@ -217,7 +219,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
         return AVERROR_INVALIDDATA;
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        if (s->use_skip_mb_code) {
+        if (ms->use_skip_mb_code) {
             if (get_bits1(&s->gb)) {
                 /* skip mb */
                 s->mb_intra = 0;
@@ -257,12 +259,12 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
 
     if (!s->mb_intra) {
         int mx, my;
-        if(s->per_mb_rl_table && cbp){
-            s->rl_table_index = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
+        if (ms->per_mb_rl_table && cbp) {
+            ms->rl_table_index = decode012(&s->gb);
+            ms->rl_chroma_table_index = ms->rl_table_index;
         }
         ff_h263_pred_motion(s, 0, 0, &mx, &my);
-        ff_msmpeg4_decode_motion(s, &mx, &my);
+        ff_msmpeg4_decode_motion(ms, &mx, &my);
         s->mv_dir = MV_DIR_FORWARD;
         s->mv_type = MV_TYPE_16X16;
         s->mv[0][0][0] = mx;
@@ -279,15 +281,15 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
             ff_dlog(s->avctx, "%d%d %d %d/",
                     s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
         }
-        if(s->per_mb_rl_table && cbp){
-            s->rl_table_index = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
+        if (ms->per_mb_rl_table && cbp) {
+            ms->rl_table_index = decode012(&s->gb);
+            ms->rl_chroma_table_index = ms->rl_table_index;
         }
     }
 
     s->bdsp.clear_blocks(s->block[0]);
     for (i = 0; i < 6; i++) {
-        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+        if (ff_msmpeg4_decode_block(ms, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
         {
             av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
             return -1;
@@ -443,31 +445,31 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
         switch(s->msmpeg4_version){
         case MSMP4_V1:
         case MSMP4_V2:
-            s->rl_chroma_table_index = 2;
-            s->rl_table_index = 2;
+            ms->rl_chroma_table_index = 2;
+            ms->rl_table_index = 2;
 
-            s->dc_table_index = 0; //not used
+            ms->dc_table_index = 0; //not used
             break;
         case MSMP4_V3:
-            s->rl_chroma_table_index = decode012(&s->gb);
-            s->rl_table_index = decode012(&s->gb);
+            ms->rl_chroma_table_index = decode012(&s->gb);
+            ms->rl_table_index = decode012(&s->gb);
 
-            s->dc_table_index = get_bits1(&s->gb);
+            ms->dc_table_index = get_bits1(&s->gb);
             break;
         case MSMP4_WMV1:
             ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
 
             if (ms->bit_rate > MBAC_BITRATE)
-                s->per_mb_rl_table = get_bits1(&s->gb);
+                ms->per_mb_rl_table = get_bits1(&s->gb);
             else
-                s->per_mb_rl_table = 0;
+                ms->per_mb_rl_table = 0;
 
-            if(!s->per_mb_rl_table){
-                s->rl_chroma_table_index = decode012(&s->gb);
-                s->rl_table_index = decode012(&s->gb);
+            if (!ms->per_mb_rl_table) {
+                ms->rl_chroma_table_index = decode012(&s->gb);
+                ms->rl_table_index        = decode012(&s->gb);
             }
 
-            s->dc_table_index = get_bits1(&s->gb);
+            ms->dc_table_index = get_bits1(&s->gb);
             s->inter_intra_pred= 0;
             break;
         }
@@ -475,49 +477,49 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
         if(s->avctx->debug&FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d   \n",
                 s->qscale,
-                s->rl_chroma_table_index,
-                s->rl_table_index,
-                s->dc_table_index,
-                s->per_mb_rl_table,
+                ms->rl_chroma_table_index,
+                ms->rl_table_index,
+                ms->dc_table_index,
+                ms->per_mb_rl_table,
                 s->slice_height);
     } else {
         switch(s->msmpeg4_version){
         case MSMP4_V1:
         case MSMP4_V2:
             if (s->msmpeg4_version == MSMP4_V1)
-                s->use_skip_mb_code = 1;
+                ms->use_skip_mb_code = 1;
             else
-                s->use_skip_mb_code = get_bits1(&s->gb);
-            s->rl_table_index = 2;
-            s->rl_chroma_table_index = s->rl_table_index;
-            s->dc_table_index = 0; //not used
-            s->mv_table_index = 0;
+                ms->use_skip_mb_code = get_bits1(&s->gb);
+            ms->rl_table_index = 2;
+            ms->rl_chroma_table_index = ms->rl_table_index;
+            ms->dc_table_index = 0; //not used
+            ms->mv_table_index = 0;
             break;
         case MSMP4_V3:
-            s->use_skip_mb_code = get_bits1(&s->gb);
-            s->rl_table_index = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
+            ms->use_skip_mb_code = get_bits1(&s->gb);
+            ms->rl_table_index = decode012(&s->gb);
+            ms->rl_chroma_table_index = ms->rl_table_index;
 
-            s->dc_table_index = get_bits1(&s->gb);
+            ms->dc_table_index = get_bits1(&s->gb);
 
-            s->mv_table_index = get_bits1(&s->gb);
+            ms->mv_table_index = get_bits1(&s->gb);
             break;
         case MSMP4_WMV1:
-            s->use_skip_mb_code = get_bits1(&s->gb);
+            ms->use_skip_mb_code = get_bits1(&s->gb);
 
             if (ms->bit_rate > MBAC_BITRATE)
-                s->per_mb_rl_table = get_bits1(&s->gb);
+                ms->per_mb_rl_table = get_bits1(&s->gb);
             else
-                s->per_mb_rl_table = 0;
+                ms->per_mb_rl_table = 0;
 
-            if(!s->per_mb_rl_table){
-                s->rl_table_index = decode012(&s->gb);
-                s->rl_chroma_table_index = s->rl_table_index;
+            if (!ms->per_mb_rl_table) {
+                ms->rl_table_index = decode012(&s->gb);
+                ms->rl_chroma_table_index = ms->rl_table_index;
             }
 
-            s->dc_table_index = get_bits1(&s->gb);
+            ms->dc_table_index = get_bits1(&s->gb);
 
-            s->mv_table_index = get_bits1(&s->gb);
+            ms->mv_table_index = get_bits1(&s->gb);
             s->inter_intra_pred = s->width*s->height < 320*240 &&
                                   ms->bit_rate <= II_BITRATE;
             break;
@@ -525,12 +527,12 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
 
         if(s->avctx->debug&FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d   \n",
-                s->use_skip_mb_code,
-                s->rl_table_index,
-                s->rl_chroma_table_index,
-                s->dc_table_index,
-                s->mv_table_index,
-                s->per_mb_rl_table,
+                ms->use_skip_mb_code,
+                ms->rl_table_index,
+                ms->rl_chroma_table_index,
+                ms->dc_table_index,
+                ms->mv_table_index,
+                ms->per_mb_rl_table,
                 s->qscale);
 
         if(s->flipflop_rounding){
@@ -542,8 +544,8 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
     ff_dlog(s->avctx, "%d %d %d %d %d\n", s->pict_type, ms->bit_rate,
             s->inter_intra_pred, s->width, s->height);
 
-    s->esc3_level_length= 0;
-    s->esc3_run_length= 0;
+    ms->esc3_level_length = 0;
+    ms->esc3_run_length   = 0;
 
     return 0;
 }
@@ -577,8 +579,9 @@ int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
     return 0;
 }
 
-static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+static int msmpeg4_decode_dc(MSMP4DecContext *const ms, int n, int *dir_ptr)
 {
+    MpegEncContext *const s = &ms->m;
     int level, pred;
 
     if (s->msmpeg4_version <= MSMP4_V2) {
@@ -594,7 +597,7 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
         }
         level-=256;
     } else {
-        level = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
+        level = get_vlc2(&s->gb, ff_msmp4_dc_vlc[ms->dc_table_index][n >= 4],
                          MSMP4_DC_VLC_BITS, 3);
 
         if (level == DC_MAX) {
@@ -630,9 +633,10 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
     return level;
 }
 
-int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
+int ff_msmpeg4_decode_block(MSMP4DecContext *const ms, int16_t * block,
                               int n, int coded, const uint8_t *scan_table)
 {
+    MpegEncContext *const s = &ms->m;
     int level, i, last, run, run_diff;
     int dc_pred_dir = -1; //unused but its passed around, so it needs to be initialized
     const RLTable *rl;
@@ -644,20 +648,20 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
         qadd=0;
 
         /* DC coef */
-        level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
+        level = msmpeg4_decode_dc(ms, n, &dc_pred_dir);
 
         if (level < 0){
             av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
             if(s->inter_intra_pred) level=0;
         }
         if (n < 4) {
-            rl = &ff_rl_table[s->rl_table_index];
+            rl = &ff_rl_table[ms->rl_table_index];
             if(level > 256*s->y_dc_scale){
                 av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale);
                 if(!s->inter_intra_pred) return -1;
             }
         } else {
-            rl = &ff_rl_table[3 + s->rl_chroma_table_index];
+            rl = &ff_rl_table[3 + ms->rl_chroma_table_index];
             if(level > 256*s->c_dc_scale){
                 av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale);
                 if(!s->inter_intra_pred) return -1;
@@ -683,7 +687,7 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
         qmul = s->qscale << 1;
         qadd = (s->qscale - 1) | 1;
         i = -1;
-        rl = &ff_rl_table[3 + s->rl_table_index];
+        rl = &ff_rl_table[3 + ms->rl_table_index];
 
         if (s->msmpeg4_version == MSMP4_V2)
             run_diff = 0;
@@ -721,7 +725,7 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
                     }else{
                         int sign;
                         last=  SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
-                        if(!s->esc3_level_length){
+                        if (!ms->esc3_level_length) {
                             int ll;
                             ff_dlog(s->avctx, "ESC-3 %X at %d %d\n",
                                     show_bits(&s->gb, 24), s->mb_x, s->mb_y);
@@ -739,18 +743,18 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
                                 if(ll<8) SKIP_BITS(re, &s->gb, 1);
                             }
 
-                            s->esc3_level_length= ll;
-                            s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
+                            ms->esc3_level_length = ll;
+                            ms->esc3_run_length   = SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
                             UPDATE_CACHE(re, &s->gb);
                         }
-                        run=   SHOW_UBITS(re, &s->gb, s->esc3_run_length);
-                        SKIP_BITS(re, &s->gb, s->esc3_run_length);
+                        run   = SHOW_UBITS(re, &s->gb, ms->esc3_run_length);
+                        SKIP_BITS(re, &s->gb, ms->esc3_run_length);
 
                         sign=  SHOW_UBITS(re, &s->gb, 1);
                         SKIP_BITS(re, &s->gb, 1);
 
-                        level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);
-                        SKIP_BITS(re, &s->gb, s->esc3_level_length);
+                        level = SHOW_UBITS(re, &s->gb, ms->esc3_level_length);
+                        SKIP_BITS(re, &s->gb, ms->esc3_level_length);
                         if(sign) level= -level;
                     }
 
@@ -814,9 +818,10 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
     return 0;
 }
 
-void ff_msmpeg4_decode_motion(MpegEncContext *s, int *mx_ptr, int *my_ptr)
+void ff_msmpeg4_decode_motion(MSMP4DecContext *const ms, int *mx_ptr, int *my_ptr)
 {
-    const VLCElem *const mv_vlc = mv_tables[s->mv_table_index];
+    const VLCElem *const mv_vlc = mv_tables[ms->mv_table_index];
+    MpegEncContext *const s = &ms->m;
     int sym, mx, my;
 
     sym = get_vlc2(&s->gb, mv_vlc, MV_VLC_BITS, 2);
diff --git a/libavcodec/msmpeg4dec.h b/libavcodec/msmpeg4dec.h
index 47c4495f1d..b04331fd47 100644
--- a/libavcodec/msmpeg4dec.h
+++ b/libavcodec/msmpeg4dec.h
@@ -31,6 +31,14 @@
 typedef struct MSMP4DecContext {
     MpegEncContext m;
     int bit_rate;
+    int mv_table_index;
+    int rl_table_index;
+    int rl_chroma_table_index;
+    int dc_table_index;
+    int use_skip_mb_code;
+    int per_mb_rl_table;
+    int esc3_level_length;
+    int esc3_run_length;
 } MSMP4DecContext;
 
 static inline MSMP4DecContext *mpv_to_msmpeg4(MpegEncContext *s)
@@ -45,8 +53,8 @@ extern VLCElem ff_inter_intra_vlc[8];
 int ff_msmpeg4_decode_init(AVCodecContext *avctx);
 int ff_msmpeg4_decode_picture_header(MpegEncContext *s);
 int ff_msmpeg4_decode_ext_header(MpegEncContext *s, int buf_size);
-void ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr);
-int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
+void ff_msmpeg4_decode_motion(MSMP4DecContext *ms, int *mx_ptr, int *my_ptr);
+int ff_msmpeg4_decode_block(MSMP4DecContext *ms, int16_t * block,
                             int n, int coded, const uint8_t *scan_table);
 
 #endif
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 0ab2e473aa..78197756ae 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -200,15 +200,15 @@ static void find_best_tables(MSMPEG4EncContext *ms)
 
     memset(ms->ac_stats, 0, sizeof(ms->ac_stats));
 
-    s->rl_table_index       =        best;
-    s->rl_chroma_table_index= chroma_best;
+    ms->rl_table_index        =        best;
+    ms->rl_chroma_table_index = chroma_best;
 
     if(s->pict_type != s->last_non_b_pict_type){
-        s->rl_table_index= 2;
+        ms->rl_table_index = 2;
         if(s->pict_type==AV_PICTURE_TYPE_I)
-            s->rl_chroma_table_index= 1;
+            ms->rl_chroma_table_index = 1;
         else
-            s->rl_chroma_table_index= 2;
+            ms->rl_chroma_table_index = 2;
     }
 
 }
@@ -226,14 +226,14 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
 
     put_bits(&s->pb, 5, s->qscale);
     if (s->msmpeg4_version <= MSMP4_V2) {
-        s->rl_table_index = 2;
-        s->rl_chroma_table_index = 2;
+        ms->rl_table_index = 2;
+        ms->rl_chroma_table_index = 2;
     }
 
-    s->dc_table_index = 1;
-    s->mv_table_index = 1; /* only if P-frame */
-    s->use_skip_mb_code = 1; /* only if P-frame */
-    s->per_mb_rl_table = 0;
+    ms->dc_table_index   = 1;
+    ms->mv_table_index   = 1; /* only if P-frame */
+    ms->use_skip_mb_code = 1; /* only if P-frame */
+    ms->per_mb_rl_table  = 0;
     if (s->msmpeg4_version == MSMP4_WMV1)
         s->inter_intra_pred = s->width * s->height < 320*240 &&
                               m->bit_rate  <= II_BITRATE     &&
@@ -248,35 +248,35 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
         if (s->msmpeg4_version == MSMP4_WMV1) {
             ff_msmpeg4_encode_ext_header(s);
             if (m->bit_rate > MBAC_BITRATE)
-                put_bits(&s->pb, 1, s->per_mb_rl_table);
+                put_bits(&s->pb, 1, ms->per_mb_rl_table);
         }
 
         if (s->msmpeg4_version > MSMP4_V2) {
-            if(!s->per_mb_rl_table){
-                ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index);
-                ff_msmpeg4_code012(&s->pb, s->rl_table_index);
+            if (!ms->per_mb_rl_table){
+                ff_msmpeg4_code012(&s->pb, ms->rl_chroma_table_index);
+                ff_msmpeg4_code012(&s->pb, ms->rl_table_index);
             }
 
-            put_bits(&s->pb, 1, s->dc_table_index);
+            put_bits(&s->pb, 1, ms->dc_table_index);
         }
     } else {
-        put_bits(&s->pb, 1, s->use_skip_mb_code);
+        put_bits(&s->pb, 1, ms->use_skip_mb_code);
 
         if (s->msmpeg4_version == MSMP4_WMV1 && m->bit_rate > MBAC_BITRATE)
-            put_bits(&s->pb, 1, s->per_mb_rl_table);
+            put_bits(&s->pb, 1, ms->per_mb_rl_table);
 
         if (s->msmpeg4_version > MSMP4_V2) {
-            if(!s->per_mb_rl_table)
-                ff_msmpeg4_code012(&s->pb, s->rl_table_index);
+            if (!ms->per_mb_rl_table)
+                ff_msmpeg4_code012(&s->pb, ms->rl_table_index);
 
-            put_bits(&s->pb, 1, s->dc_table_index);
+            put_bits(&s->pb, 1, ms->dc_table_index);
 
-            put_bits(&s->pb, 1, s->mv_table_index);
+            put_bits(&s->pb, 1, ms->mv_table_index);
         }
     }
 
-    s->esc3_level_length= 0;
-    s->esc3_run_length= 0;
+    s->esc3_level_length = 0;
+    ms->esc3_run_length  = 0;
 
     return 0;
 }
@@ -308,10 +308,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
         av_assert0(!s->flipflop_rounding);
 }
 
-void ff_msmpeg4_encode_motion(MpegEncContext * s,
+void ff_msmpeg4_encode_motion(MSMPEG4EncContext *const ms,
                                   int mx, int my)
 {
-    const uint32_t *const mv_vector_table = mv_vector_tables[s->mv_table_index];
+    MpegEncContext *const s = &ms->m.s;
+    const uint32_t *const mv_vector_table = mv_vector_tables[ms->mv_table_index];
     uint32_t code;
 
     /* modulo encoding */
@@ -382,6 +383,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
                               int16_t block[][64],
                               int motion_x, int motion_y)
 {
+    MSMPEG4EncContext *const ms = mpv_to_msmpeg4(s);
     int cbp, coded_cbp, i;
     int pred_x, pred_y;
 
@@ -394,7 +396,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
             if (s->block_last_index[i] >= 0)
                 cbp |= 1 << (5 - i);
         }
-        if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) {
+        if (ms->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) {
             /* skip macroblock */
             put_bits(&s->pb, 1, 1);
             s->last_bits++;
@@ -402,7 +404,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
 
             return;
         }
-        if (s->use_skip_mb_code)
+        if (ms->use_skip_mb_code)
             put_bits(&s->pb, 1, 0);     /* mb coded */
 
         if (s->msmpeg4_version <= MSMP4_V2) {
@@ -430,8 +432,8 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
 
             /* motion vector */
             ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
-            ff_msmpeg4_encode_motion(s, motion_x - pred_x,
-                                  motion_y - pred_y);
+            ff_msmpeg4_encode_motion(ms, motion_x - pred_x,
+                                     motion_y - pred_y);
         }
 
         s->mv_bits += get_bits_diff(s);
@@ -452,7 +454,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
                 put_bits(&s->pb,
                          ff_v2_intra_cbpc[cbp&3][1], ff_v2_intra_cbpc[cbp&3][0]);
             } else {
-                if (s->use_skip_mb_code)
+                if (ms->use_skip_mb_code)
                     put_bits(&s->pb, 1, 0);     /* mb coded */
                 put_bits(&s->pb,
                          ff_v2_mb_type[(cbp&3) + 4][1],
@@ -479,7 +481,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
                 put_bits(&s->pb,
                          ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]);
             } else {
-                if (s->use_skip_mb_code)
+                if (ms->use_skip_mb_code)
                     put_bits(&s->pb, 1, 0);     /* mb coded */
                 put_bits(&s->pb,
                          ff_table_mb_non_intra[cbp][1],
@@ -501,8 +503,9 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
     }
 }
 
-static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr)
+static void msmpeg4_encode_dc(MSMPEG4EncContext *const ms, int level, int n, int *dir_ptr)
 {
+    MpegEncContext *const s = &ms->m.s;
     int sign, code;
     int pred;
 
@@ -539,8 +542,8 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr
         if (code > DC_MAX)
             code = DC_MAX;
 
-        put_bits(&s->pb, ff_msmp4_dc_tables[s->dc_table_index][n >= 4][code][1],
-                         ff_msmp4_dc_tables[s->dc_table_index][n >= 4][code][0]);
+        put_bits(&s->pb, ff_msmp4_dc_tables[ms->dc_table_index][n >= 4][code][1],
+                         ff_msmp4_dc_tables[ms->dc_table_index][n >= 4][code][0]);
 
         if (code == DC_MAX)
             put_bits(&s->pb, 8, level);
@@ -563,18 +566,18 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
     const uint8_t *scantable;
 
     if (s->mb_intra) {
-        msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir);
+        msmpeg4_encode_dc(ms, block[0], n, &dc_pred_dir);
         i = 1;
         if (n < 4) {
-            rl = &ff_rl_table[s->rl_table_index];
+            rl = &ff_rl_table[ms->rl_table_index];
         } else {
-            rl = &ff_rl_table[3 + s->rl_chroma_table_index];
+            rl = &ff_rl_table[3 + ms->rl_chroma_table_index];
         }
         run_diff = s->msmpeg4_version >= MSMP4_WMV1;
         scantable= s->intra_scantable.permutated;
     } else {
         i = 0;
-        rl = &ff_rl_table[3 + s->rl_table_index];
+        rl = &ff_rl_table[3 + ms->rl_table_index];
         run_diff = s->msmpeg4_version > MSMP4_V2;
         scantable= s->inter_scantable.permutated;
     }
@@ -635,16 +638,16 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
                         put_bits(&s->pb, 1, 0);
                         put_bits(&s->pb, 1, last);
                         if (s->msmpeg4_version >= MSMP4_WMV1) {
-                            if(s->esc3_level_length==0){
-                                s->esc3_level_length=8;
-                                s->esc3_run_length= 6;
+                            if (s->esc3_level_length == 0) {
+                                s->esc3_level_length = 8;
+                                ms->esc3_run_length  = 6;
                                 //ESCLVLSZ + ESCRUNSZ
                                 if(s->qscale<8)
                                     put_bits(&s->pb, 6, 3);
                                 else
                                     put_bits(&s->pb, 8, 3);
                             }
-                            put_bits(&s->pb, s->esc3_run_length, run);
+                            put_bits(&s->pb, ms->esc3_run_length, run);
                             put_bits(&s->pb, 1, sign);
                             put_bits(&s->pb, s->esc3_level_length, level);
                         }else{
diff --git a/libavcodec/msmpeg4enc.h b/libavcodec/msmpeg4enc.h
index dde1fb6b93..bce1265bb5 100644
--- a/libavcodec/msmpeg4enc.h
+++ b/libavcodec/msmpeg4enc.h
@@ -29,15 +29,29 @@
 typedef struct MSMPEG4EncContext {
     MPVMainEncContext m;
 
+    int mv_table_index;
+    int rl_table_index;
+    int rl_chroma_table_index;
+    int dc_table_index;
+    int use_skip_mb_code;
+    int per_mb_rl_table;
+    int esc3_run_length;
+
     /** [mb_intra][isChroma][level][run][last] */
     unsigned ac_stats[2][2][MAX_LEVEL + 1][MAX_RUN + 1][2];
 } MSMPEG4EncContext;
 
+static inline MSMPEG4EncContext *mpv_to_msmpeg4(MpegEncContext *s)
+{
+    // Only legal because no MSMPEG-4 decoder uses slice-threading.
+    return (MSMPEG4EncContext*)s;
+}
+
 void ff_msmpeg4_encode_init(MPVMainEncContext *m);
 void ff_msmpeg4_encode_ext_header(MpegEncContext *s);
 void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n);
 void ff_msmpeg4_handle_slices(MpegEncContext *s);
-void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);
+void ff_msmpeg4_encode_motion(MSMPEG4EncContext *ms, int mx, int my);
 
 void ff_msmpeg4_code012(PutBitContext *pb, int n);
 
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index 6c25fdb5fa..f2285c396b 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -343,7 +343,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx,
         .mv_fields.bits = {
             .mv_mode                       = vc1_get_MVMODE(v),
             .mv_mode2                      = vc1_get_MVMODE2(v),
-            .mv_table                      = (v->fcm == PROGRESSIVE ? s->mv_table_index : v->imvtab),
+            .mv_table                      = (v->fcm == PROGRESSIVE ? v->mv_table_index : v->imvtab),
             .two_mv_block_pattern_table    = v->twomvbptab,
             .four_mv_switch                = v->fourmvswitch,
             .four_mv_block_pattern_table   = v->fourmvbptab,
@@ -371,7 +371,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx,
             .frame_level_transform_type    = vc1_get_TTFRM(v),
             .transform_ac_codingset_idx1   = v->c_ac_table_index,
             .transform_ac_codingset_idx2   = v->y_ac_table_index,
-            .intra_transform_dc_table      = v->s.dc_table_index,
+            .intra_transform_dc_table      = v->dc_table_index,
         },
     };
 
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index dec3e16ea2..1d642cc7f6 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -765,7 +765,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
             return AVERROR_INVALIDDATA;
 
         /* Hopefully this is correct for P-frames */
-        v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
+        v->mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
         v->cbptab = get_bits(gb, 2);
         v->cbpcy_vlc = ff_vc1_cbpcy_p_vlc[v->cbptab];
 
@@ -804,7 +804,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
         av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
                "Imode: %i, Invert: %i\n", status>>1, status&1);
 
-        v->s.mv_table_index = get_bits(gb, 2);
+        v->mv_table_index   = get_bits(gb, 2);
         v->cbptab           = get_bits(gb, 2);
         v->cbpcy_vlc        = ff_vc1_cbpcy_p_vlc[v->cbptab];
 
@@ -833,7 +833,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
             v->y_ac_table_index = decode012(gb);
         }
         /* DC Syntax */
-        v->s.dc_table_index = get_bits1(gb);
+        v->dc_table_index = get_bits1(gb);
     }
 
     if (v->s.pict_type == AV_PICTURE_TYPE_BI) {
@@ -1158,7 +1158,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
                    "Imode: %i, Invert: %i\n", status>>1, status&1);
 
             /* Hopefully this is correct for P-frames */
-            v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
+            v->mv_table_index   = get_bits(gb, 2); //but using ff_vc1_ tables
             v->cbptab           = get_bits(gb, 2);
             v->cbpcy_vlc        = ff_vc1_cbpcy_p_vlc[v->cbptab];
         } else if (v->fcm == ILACE_FRAME) { // frame interlaced
@@ -1295,7 +1295,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
                 return -1;
             av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
                    "Imode: %i, Invert: %i\n", status>>1, status&1);
-            v->s.mv_table_index = get_bits(gb, 2);
+            v->mv_table_index = get_bits(gb, 2);
             v->cbptab = get_bits(gb, 2);
             v->cbpcy_vlc = ff_vc1_cbpcy_p_vlc[v->cbptab];
         }
@@ -1330,7 +1330,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
     }
 
     /* DC Syntax */
-    v->s.dc_table_index = get_bits1(gb);
+    v->dc_table_index = get_bits1(gb);
     if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
         && v->dquant) {
         av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index b7339bcd5f..e8762350a2 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -246,6 +246,7 @@ typedef struct VC1Context{
     uint8_t dqsbedge;
     uint8_t dqbilevel;
     //@}
+    int dc_table_index;
     /** AC coding set indexes
      * @see 8.1.1.10, p(1)10
      */
@@ -253,6 +254,8 @@ typedef struct VC1Context{
     int c_ac_table_index;    ///< Chroma index from ACFRM element
     int y_ac_table_index;    ///< Luma index from AC2FRM element
     //@}
+    int esc3_level_length;
+    int esc3_run_length;
     int ttfrm;               ///< Transform type info present at frame level
     uint8_t ttmbf;           ///< Transform type flag
     int *ttblk_base, *ttblk; ///< Transform type at the block level
@@ -282,6 +285,7 @@ typedef struct VC1Context{
     uint8_t pquantizer;             ///< Uniform (over sequence) quantizer in use
     const VLCElem *cbpcy_vlc;       ///< CBPCY VLC table
     int tt_index;                   ///< Index for Transform Type tables (to decode TTMB)
+    int mv_table_index;
     uint8_t* mv_type_mb_plane;      ///< bitplane for mv_type == (4MV)
     uint8_t* direct_mb_plane;       ///< bitplane for "direct" MBs
     uint8_t* forward_mb_plane;      ///< bitplane for "forward" MBs
diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 26adfbca1d..1661fdd742 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -227,7 +227,7 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed)
  * @param _dmv_y Vertical differential for decoded MV
  */
 #define GET_MVDATA(_dmv_x, _dmv_y)                                      \
-    index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index],     \
+    index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[v->mv_table_index],     \
                          VC1_MV_DIFF_VLC_BITS, 2);                      \
     if (index > 36) {                                                   \
         mb_has_coeffs = 1;                                              \
@@ -549,19 +549,19 @@ static int vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip,
             sign = get_bits1(gb);
         } else {
             lst = get_bits1(gb);
-            if (v->s.esc3_level_length == 0) {
+            if (v->esc3_level_length == 0) {
                 if (v->pq < 8 || v->dquantfrm) { // table 59
-                    v->s.esc3_level_length = get_bits(gb, 3);
-                    if (!v->s.esc3_level_length)
-                        v->s.esc3_level_length = get_bits(gb, 2) + 8;
+                    v->esc3_level_length = get_bits(gb, 3);
+                    if (!v->esc3_level_length)
+                        v->esc3_level_length = get_bits(gb, 2) + 8;
                 } else { // table 60
-                    v->s.esc3_level_length = get_unary(gb, 1, 6) + 2;
+                    v->esc3_level_length = get_unary(gb, 1, 6) + 2;
                 }
-                v->s.esc3_run_length = 3 + get_bits(gb, 2);
+                v->esc3_run_length = 3 + get_bits(gb, 2);
             }
-            run   = get_bits(gb, v->s.esc3_run_length);
+            run   = get_bits(gb, v->esc3_run_length);
             sign  = get_bits1(gb);
-            level = get_bits(gb, v->s.esc3_level_length);
+            level = get_bits(gb, v->esc3_level_length);
         }
     }
 
@@ -590,7 +590,7 @@ static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
     int dcdiff, scale;
 
     /* Get DC differential */
-    dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
+    dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[v->dc_table_index][n >= 4],
                       MSMP4_DC_VLC_BITS, 3);
     if (dcdiff) {
         const int m = (v->pq == 1 || v->pq == 2) ? 3 - v->pq : 0;
@@ -723,7 +723,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
     int quant = FFABS(mquant);
 
     /* Get DC differential */
-    dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
+    dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[v->dc_table_index][n >= 4],
                       MSMP4_DC_VLC_BITS, 3);
     if (dcdiff) {
         const int m = (quant == 1 || quant == 2) ? 3 - quant : 0;
@@ -911,7 +911,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     s->y_dc_scale = ff_wmv3_dc_scale_table[quant];
 
     /* Get DC differential */
-    dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[s->dc_table_index][n >= 4],
+    dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_vlc[v->dc_table_index][n >= 4],
                       MSMP4_DC_VLC_BITS, 3);
     if (dcdiff) {
         const int m = (quant == 1 || quant == 2) ? 3 - quant : 0;
@@ -2946,7 +2946,7 @@ static void vc1_decode_skip_blocks(VC1Context *v)
 void ff_vc1_decode_blocks(VC1Context *v)
 {
 
-    v->s.esc3_level_length = 0;
+    v->esc3_level_length = 0;
     if (v->x8_type) {
         ff_intrax8_decode_picture(&v->x8, v->s.cur_pic.ptr,
                                   &v->s.gb, &v->s.mb_x, &v->s.mb_y,
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 02c3dc2535..964d6a4c06 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -248,16 +248,16 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
 
         if (!w->j_type) {
             if (w->per_mb_rl_bit)
-                s->per_mb_rl_table = get_bits1(&s->gb);
+                w->ms.per_mb_rl_table = get_bits1(&s->gb);
             else
-                s->per_mb_rl_table = 0;
+                w->ms.per_mb_rl_table = 0;
 
-            if (!s->per_mb_rl_table) {
-                s->rl_chroma_table_index = decode012(&s->gb);
-                s->rl_table_index        = decode012(&s->gb);
+            if (!w->ms.per_mb_rl_table) {
+                w->ms.rl_chroma_table_index = decode012(&s->gb);
+                w->ms.rl_table_index        = decode012(&s->gb);
             }
 
-            s->dc_table_index = get_bits1(&s->gb);
+            w->ms.dc_table_index = get_bits1(&s->gb);
 
             // at minimum one bit per macroblock is required at least in a valid frame,
             // we discard frames much smaller than this. Frames smaller than 1/8 of the
@@ -272,8 +272,8 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
         if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
             av_log(s->avctx, AV_LOG_DEBUG,
                    "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n",
-                   s->qscale, s->rl_chroma_table_index, s->rl_table_index,
-                   s->dc_table_index, s->per_mb_rl_table, w->j_type);
+                   s->qscale, w->ms.rl_chroma_table_index, w->ms.rl_table_index,
+                   w->ms.dc_table_index, w->ms.per_mb_rl_table, w->j_type);
         }
     } else {
         int cbp_index;
@@ -298,20 +298,20 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
         }
 
         if (w->per_mb_rl_bit)
-            s->per_mb_rl_table = get_bits1(&s->gb);
+            w->ms.per_mb_rl_table = get_bits1(&s->gb);
         else
-            s->per_mb_rl_table = 0;
+            w->ms.per_mb_rl_table = 0;
 
-        if (!s->per_mb_rl_table) {
-            s->rl_table_index        = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
+        if (!w->ms.per_mb_rl_table) {
+            w->ms.rl_table_index        = decode012(&s->gb);
+            w->ms.rl_chroma_table_index = w->ms.rl_table_index;
         }
 
         if (get_bits_left(&s->gb) < 2)
             return AVERROR_INVALIDDATA;
 
-        s->dc_table_index   = get_bits1(&s->gb);
-        s->mv_table_index   = get_bits1(&s->gb);
+        w->ms.dc_table_index = get_bits1(&s->gb);
+        w->ms.mv_table_index = get_bits1(&s->gb);
 
         s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && w->ms.bit_rate <= II_BITRATE);
         s->no_rounding     ^= 1;
@@ -320,15 +320,15 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
             av_log(s->avctx, AV_LOG_DEBUG,
                    "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d "
                    "per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n",
-                   s->rl_table_index, s->rl_chroma_table_index,
-                   s->dc_table_index, s->mv_table_index,
-                   s->per_mb_rl_table, s->qscale, s->mspel,
+                   w->ms.rl_table_index, w->ms.rl_chroma_table_index,
+                   w->ms.dc_table_index, w->ms.mv_table_index,
+                   w->ms.per_mb_rl_table, s->qscale, s->mspel,
                    w->per_mb_abt, w->abt_type, w->cbp_table_index,
                    s->inter_intra_pred);
         }
     }
-    s->esc3_level_length = 0;
-    s->esc3_run_length   = 0;
+    w->ms.esc3_level_length = 0;
+    w->ms.esc3_run_length   = 0;
 
     if (w->j_type) {
         ff_intrax8_decode_picture(&w->x8, s->cur_pic.ptr,
@@ -349,7 +349,7 @@ static inline void wmv2_decode_motion(WMV2DecContext *w, int *mx_ptr, int *my_pt
 {
     MpegEncContext *const s = &w->ms.m;
 
-    ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr);
+    ff_msmpeg4_decode_motion(&w->ms, mx_ptr, my_ptr);
 
     if ((((*mx_ptr) | (*my_ptr)) & 1) && s->mspel)
         w->common.hshift = get_bits1(&s->gb);
@@ -423,19 +423,23 @@ static inline int wmv2_decode_inter_block(WMV2DecContext *w, int16_t *block,
 
         sub_cbp = sub_cbp_table[decode012(&s->gb)];
 
-        if (sub_cbp & 1)
-            if ((ret = ff_msmpeg4_decode_block(s, block, n, 1, scantable)) < 0)
+        if (sub_cbp & 1) {
+            ret = ff_msmpeg4_decode_block(&w->ms, block, n, 1, scantable);
+            if (ret < 0)
                 return ret;
+        }
 
-        if (sub_cbp & 2)
-            if ((ret = ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable)) < 0)
+        if (sub_cbp & 2) {
+            ret = ff_msmpeg4_decode_block(&w->ms, w->abt_block2[n], n, 1, scantable);
+            if (ret < 0)
                 return ret;
+        }
 
         s->block_last_index[n] = 63;
 
         return 0;
     } else {
-        return ff_msmpeg4_decode_block(s, block, n, 1,
+        return ff_msmpeg4_decode_block(&w->ms, block, n, 1,
                                        s->inter_scantable.permutated);
     }
 }
@@ -445,6 +449,7 @@ static int wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
     /* The following is only allowed because this encoder
      * does not use slice threading. */
     WMV2DecContext *const w = (WMV2DecContext *) s;
+    MSMP4DecContext *const ms = &w->ms;
     int cbp, code, i, ret;
     uint8_t *coded_val;
 
@@ -498,9 +503,9 @@ static int wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
 
         if (cbp) {
             s->bdsp.clear_blocks(s->block[0]);
-            if (s->per_mb_rl_table) {
-                s->rl_table_index        = decode012(&s->gb);
-                s->rl_chroma_table_index = s->rl_table_index;
+            if (ms->per_mb_rl_table) {
+                ms->rl_table_index        = decode012(&s->gb);
+                ms->rl_chroma_table_index = ms->rl_table_index;
             }
 
             if (w->abt_flag && w->per_mb_abt) {
@@ -539,14 +544,15 @@ static int wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
             ff_dlog(s->avctx, "%d%d %d %d/",
                     s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
         }
-        if (s->per_mb_rl_table && cbp) {
-            s->rl_table_index        = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
+        if (ms->per_mb_rl_table && cbp) {
+            ms->rl_table_index        = decode012(&s->gb);
+            ms->rl_chroma_table_index = ms->rl_table_index;
         }
 
         s->bdsp.clear_blocks(s->block[0]);
         for (i = 0; i < 6; i++) {
-            if ((ret = ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL)) < 0) {
+            ret = ff_msmpeg4_decode_block(ms, block[i], i, (cbp >> (5 - i)) & 1, NULL);
+            if (ret < 0) {
                 av_log(s->avctx, AV_LOG_ERROR,
                        "\nerror while decoding intra block: %d x %d (%d)\n",
                        s->mb_x, s->mb_y, i);
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 6eda38d05f..81b0ace053 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -75,6 +75,7 @@ static int encode_ext_header(WMV2EncContext *w)
 static int wmv2_encode_picture_header(MPVMainEncContext *const m)
 {
     WMV2EncContext *const w = (WMV2EncContext *) m;
+    MSMPEG4EncContext *const ms = &w->msmpeg4;
     MpegEncContext *const s = &m->s;
 
     put_bits(&s->pb, 1, s->pict_type - 1);
@@ -82,9 +83,9 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
         put_bits(&s->pb, 7, 0);
     put_bits(&s->pb, 5, s->qscale);
 
-    s->dc_table_index  = 1;
-    s->mv_table_index  = 1; /* only if P-frame */
-    s->per_mb_rl_table = 0;
+    ms->dc_table_index  = 1;
+    ms->mv_table_index  = 1; /* only if P-frame */
+    ms->per_mb_rl_table = 0;
     s->mspel           = 0;
     w->per_mb_abt      = 0;
     w->abt_type        = 0;
@@ -98,14 +99,14 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
             put_bits(&s->pb, 1, w->j_type);
 
         if (w->per_mb_rl_bit)
-            put_bits(&s->pb, 1, s->per_mb_rl_table);
+            put_bits(&s->pb, 1, ms->per_mb_rl_table);
 
-        if (!s->per_mb_rl_table) {
-            ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index);
-            ff_msmpeg4_code012(&s->pb, s->rl_table_index);
+        if (!ms->per_mb_rl_table) {
+            ff_msmpeg4_code012(&s->pb, ms->rl_chroma_table_index);
+            ff_msmpeg4_code012(&s->pb, ms->rl_table_index);
         }
 
-        put_bits(&s->pb, 1, s->dc_table_index);
+        put_bits(&s->pb, 1, ms->dc_table_index);
 
         s->inter_intra_pred = 0;
     } else {
@@ -126,19 +127,19 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
         }
 
         if (w->per_mb_rl_bit)
-            put_bits(&s->pb, 1, s->per_mb_rl_table);
+            put_bits(&s->pb, 1, ms->per_mb_rl_table);
 
-        if (!s->per_mb_rl_table) {
-            ff_msmpeg4_code012(&s->pb, s->rl_table_index);
-            s->rl_chroma_table_index = s->rl_table_index;
+        if (!ms->per_mb_rl_table) {
+            ff_msmpeg4_code012(&s->pb, ms->rl_table_index);
+            ms->rl_chroma_table_index = ms->rl_table_index;
         }
-        put_bits(&s->pb, 1, s->dc_table_index);
-        put_bits(&s->pb, 1, s->mv_table_index);
+        put_bits(&s->pb, 1, ms->dc_table_index);
+        put_bits(&s->pb, 1, ms->mv_table_index);
 
         s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && m->bit_rate <= II_BITRATE);
     }
     s->esc3_level_length = 0;
-    s->esc3_run_length   = 0;
+    ms->esc3_run_length  = 0;
 
     return 0;
 }
@@ -170,7 +171,7 @@ static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
         s->misc_bits += get_bits_diff(s);
         /* motion vector */
         ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
-        ff_msmpeg4_encode_motion(s, motion_x - pred_x,
+        ff_msmpeg4_encode_motion(&w->msmpeg4, motion_x - pred_x,
                                  motion_y - pred_y);
         s->mv_bits += get_bits_diff(s);
     } else {
-- 
2.45.2


[-- Attachment #49: 0048-avcodec-mpegvideo-Move-allocating-encoder-buffers-to.patch --]
[-- Type: text/x-patch, Size: 5931 bytes --]

From 0faa3cf487081776a9b577b0fdfb20c4d9494ca7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Oct 2022 18:27:17 +0200
Subject: [PATCH 48/77] avcodec/mpegvideo: Move allocating encoder buffers to
 mpegvideoenc.c

dct_error_sum and me.map are allocated per slice-context
and therefore their allocation has not been moved to
mpegvideoenc.c in 0154fb43e328b13da8943e66b38dc1b5ab9315af.

This commit changes this by allocating them jointly and
moving said allocations to mpegvideo_enc.c like the other
encoder-only buffers.
The buffers are suitably aligned to ensure that no false
sharing occurs.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.c     | 17 ------------
 libavcodec/mpegvideo_enc.c | 54 ++++++++++++++++++++++++++++++++++++++
 libavcodec/mpegvideoenc.h  |  3 +++
 3 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index bc367fba07..8055e6c0e2 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -351,17 +351,6 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
 
 static av_cold int init_duplicate_context(MpegEncContext *s)
 {
-    if (s->encoding) {
-        s->me.map = av_mallocz(2 * ME_MAP_SIZE * sizeof(*s->me.map));
-        if (!s->me.map)
-            return AVERROR(ENOMEM);
-        s->me.score_map = s->me.map + ME_MAP_SIZE;
-
-        if (s->noise_reduction) {
-            if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_error_sum,  2))
-                return AVERROR(ENOMEM);
-        }
-    }
     if (!FF_ALLOCZ_TYPED_ARRAY(s->blocks,  1 + s->encoding))
         return AVERROR(ENOMEM);
     s->block = s->blocks[0];
@@ -420,9 +409,6 @@ static av_cold void free_duplicate_context(MpegEncContext *s)
     s->sc.obmc_scratchpad = NULL;
     s->sc.linesize = 0;
 
-    av_freep(&s->dct_error_sum);
-    av_freep(&s->me.map);
-    s->me.score_map = NULL;
     av_freep(&s->blocks);
     av_freep(&s->ac_val_base);
     s->block = NULL;
@@ -646,9 +632,6 @@ static void clear_context(MpegEncContext *s)
 
     memset(s->thread_context, 0, sizeof(s->thread_context));
 
-    s->me.map = NULL;
-    s->me.score_map = NULL;
-    s->dct_error_sum = NULL;
     s->block = NULL;
     s->blocks = NULL;
     s->ac_val_base = NULL;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 116c974098..f6bd9be56b 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -33,6 +33,7 @@
 
 #include "config_components.h"
 
+#include <assert.h>
 #include <stdint.h>
 
 #include "libavutil/emms.h"
@@ -420,6 +421,53 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
     return 0;
 }
 
+static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avctx)
+{
+    MpegEncContext *const s = &m->s;
+    // Align the following per-thread buffers to avoid false sharing.
+    enum {
+#ifndef _MSC_VER
+        /// The number is supposed to match/exceed the cache-line size.
+        ALIGN = FFMAX(128, _Alignof(max_align_t)),
+#else
+        ALIGN = 128,
+#endif
+        ME_MAP_ALLOC_SIZE = FFALIGN(2 * ME_MAP_SIZE * sizeof(*s->me.map), ALIGN),
+        DCT_ERROR_SIZE    = FFALIGN(2 * sizeof(*s->dct_error_sum), ALIGN),
+    };
+    static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
+                  "Need checks for potential overflow.");
+    unsigned nb_slices = s->slice_context_count;
+    char *dct_error = NULL, *me_map;
+
+    if (s->noise_reduction) {
+        dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
+        if (!dct_error)
+            return AVERROR(ENOMEM);
+        m->dct_error_sum_base = dct_error;
+        dct_error += FFALIGN((uintptr_t)dct_error, ALIGN) - (uintptr_t)dct_error;
+    }
+    me_map = av_mallocz(ALIGN - 1 + nb_slices * ME_MAP_ALLOC_SIZE);
+    if (!me_map)
+        return AVERROR(ENOMEM);
+    m->me_map_base = me_map;
+    me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;
+
+    for (unsigned i = 0; i < nb_slices; ++i) {
+        MpegEncContext *const s2 = s->thread_context[i];
+
+        if (dct_error) {
+            s2->dct_error_sum = (void*)dct_error;
+            dct_error        += DCT_ERROR_SIZE;
+        }
+        s2->me.map       = (uint32_t*)me_map;
+        s2->me.score_map = s2->me.map + ME_MAP_SIZE;
+        me_map          += ME_MAP_ALLOC_SIZE;
+    }
+
+    return 0;
+}
+
 /* init video encoder */
 av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 {
@@ -923,6 +971,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
+    ret = init_buffers(m, avctx);
+    if (ret < 0)
+        return ret;
+
     /* Allocate MV tables; the MV and MB tables will be copied
      * to slice contexts by ff_update_duplicate_context().  */
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
@@ -1067,6 +1119,8 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_freep(&s->b_field_mv_table_base);
     av_freep(&s->b_field_select_table[0][0]);
     av_freep(&s->p_field_select_table[0]);
+    av_freep(&m->dct_error_sum_base);
+    av_freep(&m->me_map_base);
 
     av_freep(&s->mb_type);
     av_freep(&s->lambda_table);
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 57b91d169a..dfd86d76cc 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -98,6 +98,9 @@ typedef struct MPVMainEncContext {
 
     int64_t mb_var_sum;            ///< sum of MB variance for current frame
     int64_t mc_mb_var_sum;         ///< motion compensated MB variance for current frame
+
+    char *me_map_base;             ///< backs MotionEstContext.(map|score_map)
+    char *dct_error_sum_base;      ///< backs dct_error_sum
 } MPVMainEncContext;
 
 static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)
-- 
2.45.2


[-- Attachment #50: 0049-avcodec-mpegvideo-Move-encoder-only-base-arrays-to-M.patch --]
[-- Type: text/x-patch, Size: 9430 bytes --]

From 1c0ec9ed6a7234fefabda44086f85ca4ca2db31d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 09:02:05 +0100
Subject: [PATCH 49/77] avcodec/mpegvideo: Move encoder-only base arrays to
 MPVMainEncContext

Also allocate them jointly (thereby reducing the number of base
arrays considerably) and already set them on all slice contexts;
don't rely on ff_update_duplicate_context().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  9 +---
 libavcodec/mpegvideo_enc.c | 92 +++++++++++++++++---------------------
 libavcodec/mpegvideoenc.h  |  1 +
 3 files changed, 43 insertions(+), 59 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 39ca4b3d1a..609052786e 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -207,14 +207,7 @@ typedef struct MpegEncContext {
     H263DSPContext h263dsp;
     int f_code;                 ///< forward MV resolution
     int b_code;                 ///< backward MV resolution for B-frames (MPEG-4)
-    int16_t (*p_mv_table_base)[2];
-    int16_t (*b_forw_mv_table_base)[2];
-    int16_t (*b_back_mv_table_base)[2];
-    int16_t (*b_bidir_forw_mv_table_base)[2];
-    int16_t (*b_bidir_back_mv_table_base)[2];
-    int16_t (*b_direct_mv_table_base)[2];
     int16_t (*p_field_mv_table_base)[2];
-    int16_t (*b_field_mv_table_base)[2];
     int16_t (*p_mv_table)[2];            ///< MV table (1MV per MB) P-frame encoding
     int16_t (*b_forw_mv_table)[2];       ///< MV table (1MV per MB) forward mode B-frame encoding
     int16_t (*b_back_mv_table)[2];       ///< MV table (1MV per MB) backward mode B-frame encoding
@@ -224,7 +217,7 @@ typedef struct MpegEncContext {
     int16_t (*p_field_mv_table[2][2])[2];   ///< MV table (2MV per MB) interlaced P-frame encoding
     int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding
     uint8_t (*p_field_select_table[2]);  ///< Only the first element is allocated
-    uint8_t (*b_field_select_table[2][2]); ///< Only the first element is allocated
+    uint8_t (*b_field_select_table[2][2]); ///< allocated jointly with p_field_select_table
 
     /* The following fields are encoder-only */
     uint16_t *mb_var;           ///< Table for MB variances
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index f6bd9be56b..2331bbbb06 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -437,8 +437,10 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     };
     static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
                   "Need checks for potential overflow.");
-    unsigned nb_slices = s->slice_context_count;
+    unsigned nb_slices = s->slice_context_count, mv_table_size;
     char *dct_error = NULL, *me_map;
+    int nb_mv_tables = 6;
+    int16_t (*mv_table)[2];
 
     if (s->noise_reduction) {
         dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
@@ -453,8 +455,23 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     m->me_map_base = me_map;
     me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;
 
+    mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
+    if (s->codec_id == AV_CODEC_ID_MPEG4 ||
+        (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+        nb_mv_tables += 8;
+        if (!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * (2 + 4), mv_table_size))
+            return AVERROR(ENOMEM);
+    }
+
+    mv_table = av_calloc(mv_table_size, nb_mv_tables * sizeof(*mv_table));
+    if (!mv_table)
+        return AVERROR(ENOMEM);
+    m->mv_table_base = mv_table;
+    mv_table += s->mb_stride + 1;
+
     for (unsigned i = 0; i < nb_slices; ++i) {
         MpegEncContext *const s2 = s->thread_context[i];
+        int16_t (*tmp_mv_table)[2] = mv_table;
 
         if (dct_error) {
             s2->dct_error_sum = (void*)dct_error;
@@ -463,6 +480,27 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
         s2->me.map       = (uint32_t*)me_map;
         s2->me.score_map = s2->me.map + ME_MAP_SIZE;
         me_map          += ME_MAP_ALLOC_SIZE;
+
+        s2->p_mv_table            = tmp_mv_table;
+        s2->b_forw_mv_table       = tmp_mv_table += mv_table_size;
+        s2->b_back_mv_table       = tmp_mv_table += mv_table_size;
+        s2->b_bidir_forw_mv_table = tmp_mv_table += mv_table_size;
+        s2->b_bidir_back_mv_table = tmp_mv_table += mv_table_size;
+        s2->b_direct_mv_table     = tmp_mv_table += mv_table_size;
+
+        if (s->p_field_select_table[0]) { // MPEG-4 or INTERLACED_ME above
+            uint8_t *field_select = s->p_field_select_table[0];
+            s2->p_field_select_table[0] = field_select;
+            s2->p_field_select_table[1] = field_select += 2 * mv_table_size;
+
+            for (int j = 0; j < 2; j++) {
+                for (int k = 0; k < 2; k++) {
+                    for (int l = 0; l < 2; l++)
+                        s2->b_field_mv_table[j][k][l] = tmp_mv_table += mv_table_size;
+                    s2->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
+                }
+            }
+        }
     }
 
     return 0;
@@ -475,7 +513,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     MpegEncContext    *const s = &m->s;
     AVCPBProperties *cpb_props;
     int i, ret;
-    int mb_array_size, mv_table_size;
+    int mb_array_size;
 
     mpv_encode_defaults(m);
 
@@ -975,23 +1013,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    /* Allocate MV tables; the MV and MB tables will be copied
-     * to slice contexts by ff_update_duplicate_context().  */
-    mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
-    if (!FF_ALLOCZ_TYPED_ARRAY(s->p_mv_table_base,            mv_table_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->b_forw_mv_table_base,       mv_table_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->b_back_mv_table_base,       mv_table_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_forw_mv_table_base, mv_table_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_back_mv_table_base, mv_table_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->b_direct_mv_table_base,     mv_table_size))
-        return AVERROR(ENOMEM);
-    s->p_mv_table            = s->p_mv_table_base + s->mb_stride + 1;
-    s->b_forw_mv_table       = s->b_forw_mv_table_base + s->mb_stride + 1;
-    s->b_back_mv_table       = s->b_back_mv_table_base + s->mb_stride + 1;
-    s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + s->mb_stride + 1;
-    s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + s->mb_stride + 1;
-    s->b_direct_mv_table     = s->b_direct_mv_table_base + s->mb_stride + 1;
-
     /* Allocate MB type table */
     mb_array_size = s->mb_stride * s->mb_height;
     if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type,      mb_array_size) ||
@@ -1001,30 +1022,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         !(s->mb_mean = av_mallocz(mb_array_size)))
         return AVERROR(ENOMEM);
 
-    if (s->codec_id == AV_CODEC_ID_MPEG4 ||
-        (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
-        int16_t (*tmp1)[2];
-        uint8_t *tmp2;
-        if (!(tmp1 = ALLOCZ_ARRAYS(s->b_field_mv_table_base, 8, mv_table_size)) ||
-            !(tmp2 = ALLOCZ_ARRAYS(s->b_field_select_table[0][0], 2 * 4, mv_table_size)) ||
-            !ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * 2, mv_table_size))
-            return AVERROR(ENOMEM);
-
-        s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * mv_table_size;
-        tmp1 += s->mb_stride + 1;
-
-        for (int i = 0; i < 2; i++) {
-            for (int j = 0; j < 2; j++) {
-                for (int k = 0; k < 2; k++) {
-                    s->b_field_mv_table[i][j][k] = tmp1;
-                    tmp1 += mv_table_size;
-                }
-                s->b_field_select_table[i][j] = tmp2;
-                tmp2 += 2 * mv_table_size;
-            }
-        }
-    }
-
     if (s->noise_reduction) {
         if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
             return AVERROR(ENOMEM);
@@ -1110,14 +1107,7 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
 
     av_freep(&avctx->stats_out);
 
-    av_freep(&s->p_mv_table_base);
-    av_freep(&s->b_forw_mv_table_base);
-    av_freep(&s->b_back_mv_table_base);
-    av_freep(&s->b_bidir_forw_mv_table_base);
-    av_freep(&s->b_bidir_back_mv_table_base);
-    av_freep(&s->b_direct_mv_table_base);
-    av_freep(&s->b_field_mv_table_base);
-    av_freep(&s->b_field_select_table[0][0]);
+    av_freep(&m->mv_table_base);
     av_freep(&s->p_field_select_table[0]);
     av_freep(&m->dct_error_sum_base);
     av_freep(&m->me_map_base);
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index dfd86d76cc..6097ea7a9c 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -101,6 +101,7 @@ typedef struct MPVMainEncContext {
 
     char *me_map_base;             ///< backs MotionEstContext.(map|score_map)
     char *dct_error_sum_base;      ///< backs dct_error_sum
+    int16_t (*mv_table_base)[2];
 } MPVMainEncContext;
 
 static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)
-- 
2.45.2


[-- Attachment #51: 0050-avcodec-mpegvideo_enc-Don-t-allocate-B-frame-bufs-wi.patch --]
[-- Type: text/x-patch, Size: 3036 bytes --]

From faf62fc8fb7c5a3462655872274b4cd66a755d9b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 09:18:41 +0100
Subject: [PATCH 50/77] avcodec/mpegvideo_enc: Don't allocate B-frame bufs
 without B frames

(Checking in the same way for intra_only is not straightforward,
because at least p_mv_table is written to even in intra_only
mode.)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 2331bbbb06..680ce7d153 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -439,7 +439,7 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
                   "Need checks for potential overflow.");
     unsigned nb_slices = s->slice_context_count, mv_table_size;
     char *dct_error = NULL, *me_map;
-    int nb_mv_tables = 6;
+    int has_b_frames = !!m->max_b_frames, nb_mv_tables = 1 + 5 * has_b_frames;
     int16_t (*mv_table)[2];
 
     if (s->noise_reduction) {
@@ -458,8 +458,8 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
-        nb_mv_tables += 8;
-        if (!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * (2 + 4), mv_table_size))
+        nb_mv_tables += 8 * has_b_frames;
+        if (!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * (2 + 4 * has_b_frames), mv_table_size))
             return AVERROR(ENOMEM);
     }
 
@@ -482,17 +482,20 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
         me_map          += ME_MAP_ALLOC_SIZE;
 
         s2->p_mv_table            = tmp_mv_table;
+        if (has_b_frames) {
         s2->b_forw_mv_table       = tmp_mv_table += mv_table_size;
         s2->b_back_mv_table       = tmp_mv_table += mv_table_size;
         s2->b_bidir_forw_mv_table = tmp_mv_table += mv_table_size;
         s2->b_bidir_back_mv_table = tmp_mv_table += mv_table_size;
         s2->b_direct_mv_table     = tmp_mv_table += mv_table_size;
+        }
 
         if (s->p_field_select_table[0]) { // MPEG-4 or INTERLACED_ME above
             uint8_t *field_select = s->p_field_select_table[0];
             s2->p_field_select_table[0] = field_select;
             s2->p_field_select_table[1] = field_select += 2 * mv_table_size;
 
+            if (has_b_frames) {
             for (int j = 0; j < 2; j++) {
                 for (int k = 0; k < 2; k++) {
                     for (int l = 0; l < 2; l++)
@@ -500,6 +503,7 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
                     s2->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
                 }
             }
+            }
         }
     }
 
-- 
2.45.2


[-- Attachment #52: 0051-avcodec-mpegvideo_enc-Reindent-after-the-previous-co.patch --]
[-- Type: text/x-patch, Size: 2546 bytes --]

From c7e7076efbd4cc121ce55a6316cd4016e6cfbff9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 09:39:37 +0100
Subject: [PATCH 51/77] avcodec/mpegvideo_enc: Reindent after the previous
 commit

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 680ce7d153..85d6b1faff 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -483,11 +483,11 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
 
         s2->p_mv_table            = tmp_mv_table;
         if (has_b_frames) {
-        s2->b_forw_mv_table       = tmp_mv_table += mv_table_size;
-        s2->b_back_mv_table       = tmp_mv_table += mv_table_size;
-        s2->b_bidir_forw_mv_table = tmp_mv_table += mv_table_size;
-        s2->b_bidir_back_mv_table = tmp_mv_table += mv_table_size;
-        s2->b_direct_mv_table     = tmp_mv_table += mv_table_size;
+            s2->b_forw_mv_table       = tmp_mv_table += mv_table_size;
+            s2->b_back_mv_table       = tmp_mv_table += mv_table_size;
+            s2->b_bidir_forw_mv_table = tmp_mv_table += mv_table_size;
+            s2->b_bidir_back_mv_table = tmp_mv_table += mv_table_size;
+            s2->b_direct_mv_table     = tmp_mv_table += mv_table_size;
         }
 
         if (s->p_field_select_table[0]) { // MPEG-4 or INTERLACED_ME above
@@ -496,14 +496,14 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
             s2->p_field_select_table[1] = field_select += 2 * mv_table_size;
 
             if (has_b_frames) {
-            for (int j = 0; j < 2; j++) {
-                for (int k = 0; k < 2; k++) {
-                    for (int l = 0; l < 2; l++)
-                        s2->b_field_mv_table[j][k][l] = tmp_mv_table += mv_table_size;
-                    s2->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
+                for (int j = 0; j < 2; j++) {
+                    for (int k = 0; k < 2; k++) {
+                        for (int l = 0; l < 2; l++)
+                            s2->b_field_mv_table[j][k][l] = tmp_mv_table += mv_table_size;
+                        s2->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
+                    }
                 }
             }
-            }
         }
     }
 
-- 
2.45.2


[-- Attachment #53: 0052-avcodec-mpegvideo_enc-Move-allocating-remaining-buff.patch --]
[-- Type: text/x-patch, Size: 4288 bytes --]

From 0f97322ab966d1265e4cf7e07ade68c3bf73ebb9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 10:21:30 +0100
Subject: [PATCH 52/77] avcodec/mpegvideo_enc: Move allocating remaining
 buffers to init_buffers

Also allocate mb_type, mc_mb_var, mb_var and mb_mean jointly
while just at it.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 85d6b1faff..0c2ed2e931 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -437,12 +437,14 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     };
     static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
                   "Need checks for potential overflow.");
-    unsigned nb_slices = s->slice_context_count, mv_table_size;
+    unsigned nb_slices = s->slice_context_count, mv_table_size, mb_array_size;
     char *dct_error = NULL, *me_map;
     int has_b_frames = !!m->max_b_frames, nb_mv_tables = 1 + 5 * has_b_frames;
     int16_t (*mv_table)[2];
 
     if (s->noise_reduction) {
+        if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
+            return AVERROR(ENOMEM);
         dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
         if (!dct_error)
             return AVERROR(ENOMEM);
@@ -455,6 +457,14 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     m->me_map_base = me_map;
     me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;
 
+    /* Allocate MB type table */
+    mb_array_size = s->mb_stride * s->mb_height;
+    s->mb_type = av_calloc(mb_array_size, 3 * sizeof(*s->mb_type) + sizeof(*s->mb_mean));
+    if (!s->mb_type)
+        return AVERROR(ENOMEM);
+    if (!FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size))
+        return AVERROR(ENOMEM);
+
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
@@ -474,9 +484,17 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
         int16_t (*tmp_mv_table)[2] = mv_table;
 
         if (dct_error) {
+            s2->dct_offset    = s->dct_offset;
             s2->dct_error_sum = (void*)dct_error;
             dct_error        += DCT_ERROR_SIZE;
         }
+
+        s2->mb_type      = s->mb_type;
+        s2->mc_mb_var    = s2->mb_type   + mb_array_size;
+        s2->mb_var       = s2->mc_mb_var + mb_array_size;
+        s2->mb_mean      = (uint8_t*)(s2->mb_var + mb_array_size);
+        s2->lambda_table = s->lambda_table;
+
         s2->me.map       = (uint32_t*)me_map;
         s2->me.score_map = s2->me.map + ME_MAP_SIZE;
         me_map          += ME_MAP_ALLOC_SIZE;
@@ -517,7 +535,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     MpegEncContext    *const s = &m->s;
     AVCPBProperties *cpb_props;
     int i, ret;
-    int mb_array_size;
 
     mpv_encode_defaults(m);
 
@@ -1017,20 +1034,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    /* Allocate MB type table */
-    mb_array_size = s->mb_stride * s->mb_height;
-    if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type,      mb_array_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->mc_mb_var,    mb_array_size) ||
-        !FF_ALLOCZ_TYPED_ARRAY(s->mb_var, mb_array_size) ||
-        !(s->mb_mean = av_mallocz(mb_array_size)))
-        return AVERROR(ENOMEM);
-
-    if (s->noise_reduction) {
-        if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
-            return AVERROR(ENOMEM);
-    }
-
     ff_dct_encode_init(s);
 
     if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
@@ -1122,9 +1125,6 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     av_freep(&s->q_intra_matrix);
     av_freep(&s->q_intra_matrix16);
     av_freep(&s->dct_offset);
-    av_freep(&s->mb_var);
-    av_freep(&s->mc_mb_var);
-    av_freep(&s->mb_mean);
 
     return 0;
 }
-- 
2.45.2


[-- Attachment #54: 0053-avcodec-mpegvideo-Move-noise_reduction-to-MPVMainEnc.patch --]
[-- Type: text/x-patch, Size: 5083 bytes --]

From 6204361baa5d94d66eced3e21ee2180ce561e8fd Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 10:30:48 +0100
Subject: [PATCH 53/77] avcodec/mpegvideo: Move noise_reduction to
 MPVMainEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  2 --
 libavcodec/mpegvideo_enc.c | 19 +++++++++++--------
 libavcodec/mpegvideoenc.h  |  4 +++-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 609052786e..69efc81096 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -473,8 +473,6 @@ typedef struct MpegEncContext {
 
     int error_rate;
 
-    int noise_reduction;
-
     int intra_penalty;
 } MpegEncContext;
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 0c2ed2e931..b32b8fe768 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -442,7 +442,7 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     int has_b_frames = !!m->max_b_frames, nb_mv_tables = 1 + 5 * has_b_frames;
     int16_t (*mv_table)[2];
 
-    if (s->noise_reduction) {
+    if (m->noise_reduction) {
         if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
             return AVERROR(ENOMEM);
         dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
@@ -1877,8 +1877,9 @@ static void frame_end(MPVMainEncContext *const m)
         s->last_non_b_pict_type = s->pict_type;
 }
 
-static void update_noise_reduction(MpegEncContext *s)
+static void update_noise_reduction(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
     int intra, i;
 
     for (intra = 0; intra < 2; intra++) {
@@ -1890,7 +1891,7 @@ static void update_noise_reduction(MpegEncContext *s)
         }
 
         for (i = 0; i < 64; i++) {
-            s->dct_offset[intra][i] = (s->noise_reduction *
+            s->dct_offset[intra][i] = (m->noise_reduction *
                                        s->dct_count[intra] +
                                        s->dct_error_sum[intra][i] / 2) /
                                       (s->dct_error_sum[intra][i] + 1);
@@ -1898,8 +1899,10 @@ static void update_noise_reduction(MpegEncContext *s)
     }
 }
 
-static void frame_start(MpegEncContext *s)
+static void frame_start(MPVMainEncContext *const m)
 {
+    MpegEncContext *const s = &m->s;
+
     s->cur_pic.ptr->f->pict_type = s->pict_type;
 
     if (s->pict_type != AV_PICTURE_TYPE_B) {
@@ -1907,9 +1910,9 @@ static void frame_start(MpegEncContext *s)
         ff_mpv_replace_picture(&s->next_pic, &s->cur_pic);
     }
 
+    av_assert2(!!m->noise_reduction == !!s->dct_error_sum);
     if (s->dct_error_sum) {
-        av_assert2(s->noise_reduction && s->encoding);
-        update_noise_reduction(s);
+        update_noise_reduction(m);
     }
 }
 
@@ -1959,7 +1962,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
         s->pict_type = s->new_pic->pict_type;
         //emms_c();
-        frame_start(s);
+        frame_start(m);
 vbv_retry:
         ret = encode_picture(m, pkt);
         if (growing_buffer) {
@@ -3598,7 +3601,7 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
     MERGE(encoding_error[1]);
     MERGE(encoding_error[2]);
 
-    if (dst->noise_reduction){
+    if (dst->dct_error_sum) {
         for(i=0; i<64; i++){
             MERGE(dct_error_sum[0][i]);
             MERGE(dct_error_sum[1][i]);
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 6097ea7a9c..d101c92cbb 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -68,6 +68,8 @@ typedef struct MPVMainEncContext {
     int b_sensitivity;
     int brd_scale;
 
+    int noise_reduction;
+
     float border_masking;
     int lmin, lmax;
     int vbv_ignore_qmax;
@@ -199,7 +201,7 @@ FF_MPV_OPT_CMP_FUNC, \
 {"skip_factor", "Frame skip factor",                                FF_MPV_MAIN_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_exp", "Frame skip exponent",                                 FF_MPV_MAIN_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"skip_cmp", "Frame skip compare function",                         FF_MPV_MAIN_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
-{"noise_reduction", "Noise reduction",                              FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"noise_reduction", "Noise reduction",                              FF_MPV_MAIN_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"ps", "RTP payload size in bytes",                             FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 
 #define FF_MPV_COMMON_BFRAME_OPTS \
-- 
2.45.2


[-- Attachment #55: 0054-avcodec-mpegvideo-Support-custom-slice-context-sizes.patch --]
[-- Type: text/x-patch, Size: 1973 bytes --]

From dd3a973dd2480a77f04673ff95ff4e8c2a7526c5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 14:52:36 +0100
Subject: [PATCH 54/77] avcodec/mpegvideo: Support custom slice context sizes

This is in preparation for adding a special slice context for
the encoders and moving all the encoder-specific fields to it.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.c | 3 ++-
 libavcodec/mpegvideo.h | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 8055e6c0e2..126fefa1be 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -375,6 +375,7 @@ static av_cold int init_duplicate_context(MpegEncContext *s)
 av_cold int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
 {
     int nb_slices = s->slice_context_count, ret;
+    size_t slice_size = s->slice_ctx_size ? s->slice_ctx_size : sizeof(*s);
 
     s->parent = s;
 
@@ -382,7 +383,7 @@ av_cold int ff_mpv_init_duplicate_contexts(MpegEncContext *s)
      * fields allocated in init_duplicate_context are NULL after
      * copying. This prevents double-frees upon allocation error. */
     for (int i = 1; i < nb_slices; i++) {
-        s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));
+        s->thread_context[i] = av_memdup(s, slice_size);
         if (!s->thread_context[i])
             return AVERROR(ENOMEM);
         if ((ret = init_duplicate_context(s->thread_context[i])) < 0)
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 69efc81096..02894ce68f 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -469,6 +469,9 @@ typedef struct MpegEncContext {
      * a frame size change */
     int context_reinit;
 
+    /// If set, ff_mpv_common_init() will allocate slice contexts of this size
+    unsigned slice_ctx_size;
+
     ERContext er;
 
     int error_rate;
-- 
2.45.2


[-- Attachment #56: 0055-avcodec-mpegvideo-Move-last-pic-information-to-MPVMa.patch --]
[-- Type: text/x-patch, Size: 6705 bytes --]

From cb00bce3c7de503711cf83183ee8e8c44e48f168 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 29 Jan 2022 05:25:25 +0100
Subject: [PATCH 55/77] avcodec/mpegvideo: Move last-pic information to
 MPVMainEncContext

last_pict_type, last_non_b_pict_type and last_lambda_for
are only used by the encoder's main thread.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     |  3 ---
 libavcodec/mpegvideo_enc.c | 16 ++++++++--------
 libavcodec/mpegvideoenc.h  |  3 +++
 libavcodec/msmpeg4enc.c    |  4 ++--
 libavcodec/ratecontrol.c   |  4 ++--
 libavcodec/snowenc.c       |  2 +-
 6 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 02894ce68f..c16fb1c703 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -185,10 +185,7 @@ typedef struct MpegEncContext {
     int adaptive_quant;         ///< use adaptive quantization
     int dquant;                 ///< qscale difference to prev qscale
     int pict_type;              ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
-    int last_pict_type; //FIXME removes
-    int last_non_b_pict_type;   ///< used for MPEG-4 gmc B-frames & ratecontrol
     int droppable;
-    int last_lambda_for[5];     ///< last lambda for a specific pict type
     int skipdct;                ///< skip dct and code zero residual
 
     /* motion compensation */
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index b32b8fe768..9f44c37b3d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1515,9 +1515,9 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
         return AVERROR(ENOMEM);
 
     //emms_c();
-    p_lambda = s->last_lambda_for[AV_PICTURE_TYPE_P];
+    p_lambda = m->last_lambda_for[AV_PICTURE_TYPE_P];
     //p_lambda * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;
-    b_lambda = s->last_lambda_for[AV_PICTURE_TYPE_B];
+    b_lambda = m->last_lambda_for[AV_PICTURE_TYPE_B];
     if (!b_lambda) // FIXME we should do this somewhere else
         b_lambda = p_lambda;
     lambda2  = (b_lambda * b_lambda + (1 << FF_LAMBDA_SHIFT) / 2) >>
@@ -1871,10 +1871,10 @@ static void frame_end(MPVMainEncContext *const m)
 
     emms_c();
 
-    s->last_pict_type                 = s->pict_type;
-    s->last_lambda_for [s->pict_type] = s->cur_pic.ptr->f->quality;
+    m->last_pict_type                = s->pict_type;
+    m->last_lambda_for[s->pict_type] = s->cur_pic.ptr->f->quality;
     if (s->pict_type!= AV_PICTURE_TYPE_B)
-        s->last_non_b_pict_type = s->pict_type;
+        m->last_non_b_pict_type = s->pict_type;
 }
 
 static void update_noise_reduction(MPVMainEncContext *const m)
@@ -3702,9 +3702,9 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         ff_get_2pass_fcode(m);
     } else if (!(s->avctx->flags & AV_CODEC_FLAG_QSCALE)) {
         if(s->pict_type==AV_PICTURE_TYPE_B)
-            s->lambda= s->last_lambda_for[s->pict_type];
+            s->lambda = m->last_lambda_for[s->pict_type];
         else
-            s->lambda= s->last_lambda_for[s->last_non_b_pict_type];
+            s->lambda = m->last_lambda_for[m->last_non_b_pict_type];
         update_qscale(m);
     }
 
@@ -3735,7 +3735,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         s->lambda  = (s->lambda  * s->me_penalty_compensation + 128) >> 8;
         s->lambda2 = (s->lambda2 * (int64_t) s->me_penalty_compensation + 128) >> 8;
         if (s->pict_type != AV_PICTURE_TYPE_B) {
-            if ((s->me_pre && s->last_non_b_pict_type == AV_PICTURE_TYPE_I) ||
+            if ((s->me_pre && m->last_non_b_pict_type == AV_PICTURE_TYPE_I) ||
                 s->me_pre == 2) {
                 s->avctx->execute(s->avctx, pre_estimate_motion_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
             }
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index d101c92cbb..7054881c05 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -96,6 +96,9 @@ typedef struct MPVMainEncContext {
     int stuffing_bits;             ///< bits used for stuffing
     int next_lambda;               ///< next lambda used for retrying to encode a frame
     int fixed_qscale;              ///< fixed qscale if non zero
+    int last_lambda_for[5];        ///< last lambda for a specific pict type
+    int last_pict_type;            //FIXME removes
+    int last_non_b_pict_type;      ///< used for MPEG-4 gmc B-frames & ratecontrol
     RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
 
     int64_t mb_var_sum;            ///< sum of MB variance for current frame
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 78197756ae..bba0493f01 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -203,8 +203,8 @@ static void find_best_tables(MSMPEG4EncContext *ms)
     ms->rl_table_index        =        best;
     ms->rl_chroma_table_index = chroma_best;
 
-    if(s->pict_type != s->last_non_b_pict_type){
-        ms->rl_table_index = 2;
+    if (s->pict_type != ms->m.last_non_b_pict_type) {
+        ms->rl_table_index= 2;
         if(s->pict_type==AV_PICTURE_TYPE_I)
             ms->rl_chroma_table_index = 1;
         else
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 0d2bf8fb30..b131f61b70 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -940,10 +940,10 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
     /* update predictors */
     if (picture_number > 2 && !dry_run) {
         const int64_t last_var =
-            s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum
+            m->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum
                                                    : rcc->last_mc_mb_var_sum;
         av_assert1(m->frame_bits >= m->stuffing_bits);
-        update_predictor(&rcc->pred[s->last_pict_type],
+        update_predictor(&rcc->pred[m->last_pict_type],
                          rcc->last_qscale,
                          sqrt(last_var),
                          m->frame_bits - m->stuffing_bits);
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index b4a329158f..e6cf2a290c 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -2058,7 +2058,7 @@ redo_frame:
     }
     if(avctx->flags&AV_CODEC_FLAG_PASS1)
         ff_write_pass1_stats(&enc->m);
-    mpv->last_pict_type = mpv->pict_type;
+    enc->m.last_pict_type = mpv->pict_type;
 
     emms_c();
 
-- 
2.45.2


[-- Attachment #57: 0056-avcodec-h261-ituh263-enc-Don-t-set-ptr_lastgob-unnec.patch --]
[-- Type: text/x-patch, Size: 1567 bytes --]

From fb595f470839cb25414e1c2b3f47ee371cd809ef Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 16 Mar 2025 15:52:29 +0100
Subject: [PATCH 56/77] avcodec/{h261,ituh263}enc: Don't set ptr_lastgob
 unnecessarily

It will be overwritten later in encode_thread() anyway.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261enc.c    | 3 ---
 libavcodec/ituh263enc.c | 2 --
 2 files changed, 5 deletions(-)

diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 81711b3a16..da8736a78c 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -74,9 +74,6 @@ static int h261_encode_picture_header(MPVMainEncContext *const m)
 
     align_put_bits(&s->pb);
 
-    /* Update the pointer to last GOB */
-    s->ptr_lastgob = put_bits_ptr(&s->pb);
-
     put_bits(&s->pb, 20, 0x10); /* PSC */
 
     temp_ref = s->picture_number * 30000LL * s->avctx->time_base.num /
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index deaf7dc5c6..5a2af09b18 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -249,8 +249,6 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
 
     align_put_bits(&s->pb);
 
-    /* Update the pointer to last GOB */
-    s->ptr_lastgob = put_bits_ptr(&s->pb);
     put_bits(&s->pb, 22, 0x20); /* PSC */
     temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->time_base.num / //FIXME use timestamp
                          (coded_frame_rate_base * (int64_t)s->avctx->time_base.den);
-- 
2.45.2


[-- Attachment #58: 0057-avcodec-mpegvideoenc-Remove-declaration-of-inexisten.patch --]
[-- Type: text/x-patch, Size: 1173 bytes --]

From ec4ea816a792349a0e88c58a329704d045724367 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 15:06:07 +0100
Subject: [PATCH 57/77] avcodec/mpegvideoenc: Remove declaration of inexistent
 function

ff_MPV_encode_init_x86() has been renamed to ff_dct_encode_init_x86()
in 6b33e918996e8a4e40071cb0a273c23de22ce1fc in FFmpeg; libav renamed
it to ff_mpv_encode_init_x86() in commit
6b33e918996e8a4e40071cb0a273c23de22ce1fc. This hasn't been noticed
in c1df467d73ee8c6e792ec27c126c5f0e2bc1af9d when merging.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideoenc.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 7054881c05..a082830ab1 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -226,7 +226,6 @@ FF_MPV_OPT_CMP_FUNC, \
 extern const AVClass ff_mpv_enc_class;
 
 int ff_mpv_encode_init(AVCodecContext *avctx);
-void ff_mpv_encode_init_x86(MpegEncContext *s);
 
 int ff_mpv_encode_end(AVCodecContext *avctx);
 int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
-- 
2.45.2


[-- Attachment #59: 0058-avcodec-mpegvideo_enc-Call-ff_mpv_common_init-later.patch --]
[-- Type: text/x-patch, Size: 2545 bytes --]

From 2b38ab06b0fc8a778b10842eda2b37cd173d8639 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 16:29:07 +0100
Subject: [PATCH 58/77] avcodec/mpegvideo_enc: Call ff_mpv_common_init() later

Namely after the main slice context has already been initialized,
so that this initialized state is directly copied to the newly
created slice contexts without relying on it being copied
by ff_update_duplicate_context(). This is in preparation for further
commits.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 9f44c37b3d..f9b8d96c83 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1011,9 +1011,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     /* init */
     ff_mpv_idct_init(s);
-    if ((ret = ff_mpv_common_init(s)) < 0)
-        return ret;
-
     ff_fdctdsp_init(&s->fdsp, avctx);
     ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
     ff_pixblockdsp_init(&s->pdsp, avctx);
@@ -1030,10 +1027,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     if (ret < 0)
         return ret;
 
-    ret = init_buffers(m, avctx);
-    if (ret < 0)
-        return ret;
-
     ff_dct_encode_init(s);
 
     if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
@@ -1047,13 +1040,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
     }
 
-    if (s->slice_context_count > 1) {
-        s->rtp_mode = 1;
-
-        if (avctx->codec_id == AV_CODEC_ID_H263P)
-            s->h263_slice_structured = 1;
-    }
-
     if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) {
         ff_h263_encode_init(m);
 #if CONFIG_MSMPEG4ENC
@@ -1062,6 +1048,23 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 #endif
     }
 
+    ret = ff_mpv_common_init(s);
+    if (ret < 0)
+        return ret;
+
+    if (s->slice_context_count > 1) {
+        for (int i = 0; i < s->slice_context_count; ++i) {
+            s->thread_context[i]->rtp_mode = 1;
+
+            if (avctx->codec_id == AV_CODEC_ID_H263P)
+                s->thread_context[i]->h263_slice_structured = 1;
+        }
+    }
+
+    ret = init_buffers(m, avctx);
+    if (ret < 0)
+        return ret;
+
     ret = ff_rate_control_init(m);
     if (ret < 0)
         return ret;
-- 
2.45.2


[-- Attachment #60: 0059-avcodec-mpeg4videoenc-Move-initializations-before-ff.patch --]
[-- Type: text/x-patch, Size: 3892 bytes --]

From 925461e15f60a5b44fc59acfc790fcb5a6e9e12f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 18 Mar 2025 18:32:18 +0100
Subject: [PATCH 59/77] avcodec/mpeg4videoenc: Move initializations before
 ff_mpv_encode_init()

This avoids relying on ff_update_duplicate_context() to copy
these fields to the slice contexts.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/ituh263enc.c    |  9 +++++----
 libavcodec/mpeg4videoenc.c | 26 +++++++++++++-------------
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 5a2af09b18..876e178070 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -826,6 +826,11 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
 
     s->me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
 
+    ff_h263dsp_init(&s->h263dsp);
+
+    if (s->codec_id == AV_CODEC_ID_MPEG4)
+        return;
+
     s->intra_ac_vlc_length     =s->inter_ac_vlc_length     = uni_h263_inter_rl_len;
     s->intra_ac_vlc_last_length=s->inter_ac_vlc_last_length= uni_h263_inter_rl_len + 128*64;
     if(s->h263_aic){
@@ -842,8 +847,6 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
 
     // use fcodes >1 only for MPEG-4 & H.263 & H.263+ FIXME
     switch(s->codec_id){
-    case AV_CODEC_ID_MPEG4:
-        break;
     case AV_CODEC_ID_H263P:
         if(s->umvplus)
             m->fcode_tab = umv_fcode_tab + MAX_MV;
@@ -875,8 +878,6 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
         m->encode_picture_header = h263_encode_picture_header;
     if (!s->encode_mb)
         s->encode_mb = h263_encode_mb;
-
-    ff_h263dsp_init(&s->h263dsp);
 }
 
 void ff_h263_encode_mba(MpegEncContext *s)
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 4c31e7e9c8..ddb6958229 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1305,6 +1305,19 @@ static av_cold int encode_init(AVCodecContext *avctx)
     m->encode_picture_header = mpeg4_encode_picture_header;
     s->encode_mb             = mpeg4_encode_mb;
 
+    m->fcode_tab                = fcode_tab + MAX_MV;
+
+    s->min_qcoeff               = -2048;
+    s->max_qcoeff               = 2047;
+    s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
+    s->intra_ac_vlc_last_length = uni_mpeg4_intra_rl_len + 128 * 64;
+    s->inter_ac_vlc_length      = uni_mpeg4_inter_rl_len;
+    s->inter_ac_vlc_last_length = uni_mpeg4_inter_rl_len + 128 * 64;
+    s->luma_dc_vlc_length       = uni_DCtab_lum_len;
+    s->ac_esc_length            = 7 + 2 + 1 + 6 + 1 + 12 + 1;
+    s->y_dc_scale_table         = ff_mpeg4_y_dc_scale_table;
+    s->c_dc_scale_table         = ff_mpeg4_c_dc_scale_table;
+
     ff_qpeldsp_init(&s->qdsp);
     if ((ret = ff_mpv_encode_init(avctx)) < 0)
         return ret;
@@ -1322,19 +1335,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     m4->time_increment_bits     = av_log2(avctx->time_base.den - 1) + 1;
 
-    m->fcode_tab                = fcode_tab + MAX_MV;
-
-    s->min_qcoeff               = -2048;
-    s->max_qcoeff               = 2047;
-    s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
-    s->intra_ac_vlc_last_length = uni_mpeg4_intra_rl_len + 128 * 64;
-    s->inter_ac_vlc_length      = uni_mpeg4_inter_rl_len;
-    s->inter_ac_vlc_last_length = uni_mpeg4_inter_rl_len + 128 * 64;
-    s->luma_dc_vlc_length       = uni_DCtab_lum_len;
-    s->ac_esc_length            = 7 + 2 + 1 + 6 + 1 + 12 + 1;
-    s->y_dc_scale_table         = ff_mpeg4_y_dc_scale_table;
-    s->c_dc_scale_table         = ff_mpeg4_c_dc_scale_table;
-
     if (s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
         s->avctx->extradata = av_malloc(1024);
         if (!s->avctx->extradata)
-- 
2.45.2


[-- Attachment #61: 0060-avcodec-mpegvideo-Move-me_pre-me_penalty_compensatio.patch --]
[-- Type: text/x-patch, Size: 4171 bytes --]

From f2ed672f2ef4f157a60ad15cc6833a9f9d56108c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 00:39:31 +0100
Subject: [PATCH 60/77] avcodec/mpegvideo: Move me_pre, me_penalty_compensation
 to MPVMainEncCtx

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo.h     | 2 --
 libavcodec/mpegvideo_enc.c | 8 ++++----
 libavcodec/mpegvideoenc.h  | 7 +++++--
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index c16fb1c703..1ff2924052 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -223,8 +223,6 @@ typedef struct MpegEncContext {
     uint64_t encoding_error[MPV_MAX_PLANES];
 
     int motion_est;                      ///< ME algorithm
-    int me_penalty_compensation;
-    int me_pre;                          ///< prepass for motion estimation
     int mv_dir;
 #define MV_DIR_FORWARD   1
 #define MV_DIR_BACKWARD  2
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index f9b8d96c83..33241d6cb0 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3735,11 +3735,11 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 
     /* Estimate motion for every MB */
     if(s->pict_type != AV_PICTURE_TYPE_I){
-        s->lambda  = (s->lambda  * s->me_penalty_compensation + 128) >> 8;
-        s->lambda2 = (s->lambda2 * (int64_t) s->me_penalty_compensation + 128) >> 8;
+        s->lambda  = (s->lambda  * m->me_penalty_compensation + 128) >> 8;
+        s->lambda2 = (s->lambda2 * (int64_t) m->me_penalty_compensation + 128) >> 8;
         if (s->pict_type != AV_PICTURE_TYPE_B) {
-            if ((s->me_pre && m->last_non_b_pict_type == AV_PICTURE_TYPE_I) ||
-                s->me_pre == 2) {
+            if ((m->me_pre && m->last_non_b_pict_type == AV_PICTURE_TYPE_I) ||
+                m->me_pre == 2) {
                 s->avctx->execute(s->avctx, pre_estimate_motion_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
             }
         }
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index a082830ab1..37e1546b50 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -101,6 +101,9 @@ typedef struct MPVMainEncContext {
     int last_non_b_pict_type;      ///< used for MPEG-4 gmc B-frames & ratecontrol
     RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
 
+    int me_penalty_compensation;
+    int me_pre;                          ///< prepass for motion estimation
+
     int64_t mb_var_sum;            ///< sum of MB variance for current frame
     int64_t mc_mb_var_sum;         ///< motion compensated MB variance for current frame
 
@@ -218,8 +221,8 @@ FF_MPV_OPT_CMP_FUNC, \
 { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
-{"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
-{"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_MAIN_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"mepre", "pre motion estimation", FF_MPV_MAIN_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 {"intra_penalty", "Penalty for intra blocks in block decision", FF_MPV_OFFSET(intra_penalty), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX/2, FF_MPV_OPT_FLAGS }, \
 {"sc_threshold", "Scene change threshold",                          FF_MPV_MAIN_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
 
-- 
2.45.2


[-- Attachment #62: 0061-avcodec-mpegvideo-Move-motion_est-to-MotionEstContex.patch --]
[-- Type: text/x-patch, Size: 6387 bytes --]

From 62330ba619b526ff730457e5f6084b91433425ff Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 00:48:33 +0100
Subject: [PATCH 61/77] avcodec/mpegvideo: Move motion_est to MotionEstContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/motion_est.c   | 7 ++++---
 libavcodec/motion_est.h   | 1 +
 libavcodec/mpegvideo.h    | 1 -
 libavcodec/mpegvideoenc.h | 2 +-
 libavcodec/snowenc.c      | 2 +-
 libavcodec/svq1enc.c      | 5 +----
 6 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 7c08fe53eb..88164de6a5 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -919,7 +919,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
     s->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
     c->mb_var_sum_temp += (varc+128)>>8;
 
-    if (s->motion_est != FF_ME_ZERO) {
+    if (c->motion_est != FF_ME_ZERO) {
         const int mot_stride = s->b8_stride;
         const int mot_xy = s->block_index[0];
 
@@ -1127,7 +1127,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
 
     get_limits(s, 16*mb_x, 16*mb_y, 1);
 
-    if (s->motion_est != FF_ME_ZERO) {
+    if (c->motion_est != FF_ME_ZERO) {
         P_LEFT[0] = mv_table[mot_xy - 1][0];
         P_LEFT[1] = mv_table[mot_xy - 1][1];
 
@@ -1599,8 +1599,9 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
 int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2], int type)
 {
     MpegEncContext *const s = &m->s;
+    MotionEstContext *const c = &s->me;
 
-    if (s->motion_est != FF_ME_ZERO) {
+    if (c->motion_est != FF_ME_ZERO) {
         int score[8];
         int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2);
         const uint8_t * fcode_tab = m->fcode_tab;
diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h
index d8a2cab3a0..5fa96161c6 100644
--- a/libavcodec/motion_est.h
+++ b/libavcodec/motion_est.h
@@ -48,6 +48,7 @@ typedef struct MPVMainEncContext MPVMainEncContext;
  */
 typedef struct MotionEstContext {
     AVCodecContext *avctx;
+    int motion_est;                 ///< ME algorithm
     int skip;                       ///< set if ME is skipped for the current MB
     int co_located_mv[4][2];        ///< mv from last P-frame for direct mode ME
     int direct_basis_mv[4][2];
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 1ff2924052..85227fdb8f 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -222,7 +222,6 @@ typedef struct MpegEncContext {
     uint8_t *mb_mean;           ///< Table for MB luminance
     uint64_t encoding_error[MPV_MAX_PLANES];
 
-    int motion_est;                      ///< ME algorithm
     int mv_dir;
 #define MV_DIR_FORWARD   1
 #define MV_DIR_BACKWARD  2
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 37e1546b50..bc8a3e80d5 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -217,7 +217,7 @@ FF_MPV_OPT_CMP_FUNC, \
 
 #define FF_MPV_COMMON_MOTION_EST_OPTS \
 { "mv0",            "always try a mb with mv=<0,0>",                     0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 },    0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
-{"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
+{"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(me.motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
 { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index e6cf2a290c..fc2a56a808 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1866,7 +1866,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         mpv->b8_stride  = 2 * mpv->mb_width + 1;
         mpv->f_code     = 1;
         mpv->pict_type  = pic->pict_type;
-        mpv->motion_est = enc->motion_est;
+        mpv->me.motion_est = enc->motion_est;
         mpv->me.scene_change_score = 0;
         mpv->me.dia_size = avctx->dia_size;
         mpv->quarter_sample  = (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0;
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 40e3fd0045..652dc11b03 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -96,8 +96,6 @@ typedef struct SVQ1EncContext {
 
     uint8_t *scratchbuf;
 
-    int motion_est;
-
     SVQ1EncDSPContext svq1encdsp;
 } SVQ1EncContext;
 
@@ -339,7 +337,6 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
         s->m.b8_stride                     = 2 * s->m.mb_width + 1;
         s->m.f_code                        = 1;
         s->m.pict_type                     = s->pict_type;
-        s->m.motion_est                    = s->motion_est;
         s->m.me.scene_change_score         = 0;
         // s->m.out_format                    = FMT_H263;
         // s->m.unrestricted_mv               = 1;
@@ -719,7 +716,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 #define OFFSET(x) offsetof(struct SVQ1EncContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "motion-est", "Motion estimation algorithm", OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, .unit = "motion-est"},
+    { "motion-est", "Motion estimation algorithm", OFFSET(m.me.motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, .unit = "motion-est"},
         { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
         { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
         { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
-- 
2.45.2


[-- Attachment #63: 0062-avcodec-motion_est-Don-t-use-MpegEncContext.avctx.patch --]
[-- Type: text/x-patch, Size: 6683 bytes --]

From b6a01ec0933a169f204bb225091032b03d18e781 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 01:26:18 +0100
Subject: [PATCH 62/77] avcodec/motion_est: Don't use MpegEncContext.avctx

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/motion_est.c          | 29 +++++++++++++++--------------
 libavcodec/motion_est_template.c |  2 +-
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 88164de6a5..ffad3dbc79 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -372,7 +372,7 @@ void ff_me_init_pic(MpegEncContext *s)
     MotionEstContext * const c= &s->me;
 
 /*FIXME s->no_rounding b_type*/
-    if (s->avctx->flags & AV_CODEC_FLAG_QPEL) {
+    if (c->avctx->flags & AV_CODEC_FLAG_QPEL) {
         c->qpel_avg = s->qdsp.avg_qpel_pixels_tab;
         if (s->no_rounding)
             c->qpel_put = s->qdsp.put_no_rnd_qpel_pixels_tab;
@@ -984,7 +984,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             mx *= 1 << shift;
             my *= 1 << shift;
         }
-        if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
+        if ((c->avctx->flags & AV_CODEC_FLAG_4MV)
            && !c->skip && varc>50<<8 && vard>10<<8){
             if(h263_mv4_search(s, mx, my, shift) < INT_MAX)
                 mb_type|=CANDIDATE_MB_TYPE_INTER4V;
@@ -992,7 +992,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             set_p_mv_tables(s, mx, my, 0);
         }else
             set_p_mv_tables(s, mx, my, 1);
-        if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
+        if ((c->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
            && !c->skip){ //FIXME varc/d checks
             if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
                 mb_type |= CANDIDATE_MB_TYPE_INTER_I;
@@ -1005,7 +1005,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
             dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
 
-        if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
+        if ((c->avctx->flags & AV_CODEC_FLAG_4MV)
            && !c->skip && varc>50<<8 && vard>10<<8){
             int dmin4= h263_mv4_search(s, mx, my, shift);
             if(dmin4 < dmin){
@@ -1013,7 +1013,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
                 dmin=dmin4;
             }
         }
-        if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
+        if ((c->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
            && !c->skip){ //FIXME varc/d checks
             int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);
             if(dmin_i < dmin){
@@ -1269,10 +1269,10 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
                           pred_bx, pred_by,
                           0, 16);
 
-    if(s->avctx->bidir_refine){
+    if (c->avctx->bidir_refine) {
         int end;
         static const uint8_t limittab[5]={0,8,32,64,80};
-        const int limit= limittab[s->avctx->bidir_refine];
+        const int limit = limittab[c->avctx->bidir_refine];
         static const int8_t vect[][4]={
 { 0, 0, 0, 1}, { 0, 0, 0,-1}, { 0, 0, 1, 0}, { 0, 0,-1, 0}, { 0, 1, 0, 0}, { 0,-1, 0, 0}, { 1, 0, 0, 0}, {-1, 0, 0, 0},
 
@@ -1526,13 +1526,13 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
     c->skip=0;
     bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +
            2 * c->mb_penalty_factor;
-    ff_dlog(s->avctx, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
+    ff_dlog(c->avctx, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
 
     c->skip=0;
     fbmin= bidir_refine(s, mb_x, mb_y) + c->mb_penalty_factor;
-    ff_dlog(s->avctx, "%d %d %d %d\n", dmin, fmin, bmin, fbmin);
+    ff_dlog(c->avctx, "%d %d %d %d\n", dmin, fmin, bmin, fbmin);
 
-    if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
+    if (c->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
 //FIXME mb type penalty
         c->skip=0;
         c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
@@ -1603,14 +1603,15 @@ int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2],
 
     if (c->motion_est != FF_ME_ZERO) {
         int score[8];
-        int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2);
+        int i, y, range = c->avctx->me_range ? c->avctx->me_range : (INT_MAX/2);
         const uint8_t * fcode_tab = m->fcode_tab;
         int best_fcode=-1;
         int best_score=-10000000;
 
         if (s->msmpeg4_version != MSMP4_UNUSED)
             range= FFMIN(range, 16);
-        else if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)
+        else if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
+                 c->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)
             range= FFMIN(range, 256);
 
         for(i=0; i<8; i++) score[i]= s->mb_num*(8-i);
@@ -1661,11 +1662,11 @@ void ff_fix_long_p_mvs(MpegEncContext * s, int type)
     range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
 
     av_assert0(range <= 16 || s->msmpeg4_version == MSMP4_UNUSED);
-    av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
+    av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && c->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
 
     if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
 
-    if (s->avctx->flags & AV_CODEC_FLAG_4MV) {
+    if (c->avctx->flags & AV_CODEC_FLAG_4MV) {
         const int wrap= s->b8_stride;
 
         /* clip / convert to intra 8x8 type MVs */
diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c
index b2701aa32e..5498f9c982 100644
--- a/libavcodec/motion_est_template.c
+++ b/libavcodec/motion_est_template.c
@@ -906,7 +906,7 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
         CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
                         (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
     }else{
-        if(dmin<((h*h*s->avctx->mv0_threshold)>>8)
+        if (dmin < ((h * h * c->avctx->mv0_threshold) >> 8)
                     && ( P_LEFT[0]    |P_LEFT[1]
                         |P_TOP[0]     |P_TOP[1]
                         |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){
-- 
2.45.2


[-- Attachment #64: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [FFmpeg-devel] [PATCH 01/77] avcodec/mpegvideo(_enc)?: Mark init, close functions as, av_cold
  2025-03-19 21:18 [FFmpeg-devel] [PATCH 01/77] avcodec/mpegvideo(_enc)?: Mark init, close functions as, av_cold Andreas Rheinhardt
@ 2025-03-19 21:20 ` Andreas Rheinhardt
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-19 21:20 UTC (permalink / raw)
  To: ffmpeg-devel

[-- Attachment #1: Type: text/plain, Size: 348 bytes --]

Andreas Rheinhardt:
> First part of a patchset; the second part will be sent separately
> because the complete set crosses the ML thresholds ("Message body is too
> big: 1731572 bytes with a limit of 1000 KB"). A complete branch can be
> found here: https://github.com/mkver/FFmpeg/tree/mpvenc
> 
> - Andreas

And here is the remainder.

- Andreas

[-- Attachment #2: 0063-avcodec-mpegvideoenc-Add-MPVEncContext.patch --]
[-- Type: text/x-patch, Size: 636549 bytes --]

From 4eec2a3654509741e7a46fb788e4b3004a5f05cc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 08:11:01 +0100
Subject: [PATCH 63/77] avcodec/mpegvideoenc: Add MPVEncContext

Many of the fields of MpegEncContext (which is also used by decoders)
are actually only used by encoders. Therefore this commit adds
a new encoder-only structure and moves all of the encoder-only
fields to it except for those which require more explicit
synchronisation between the main slice context and the other
slice contexts. This synchronisation is currently mainly provided
by ff_update_thread_context() which simply copies most of
the main slice context over the other slice contexts. Fields
which are moved to the new MPVEncContext no longer participate
in this (which is desired, because it is horrible and for the
fields b) below wasteful) which means that some fields can only
be moved when explicit synchronisation code is added in later commits.

More explicitly, this commit moves the following fields:
a) Fields not copied by ff_update_duplicate_context():
dct_error_sum and dct_count; the former does not need synchronisation,
the latter is synchronised in merge_context_after_encode().
b) Fields which do not change after initialisation (these fields
could also be put into MPVMainEncContext at the cost of
an indirection to access them): lambda_table, adaptive_quant,
{luma,chroma}_elim_threshold, new_pic, fdsp, mpvencdsp, pdsp,
{p,b_forw,b_back,b_bidir_forw,b_bidir_back,b_direct,b_field}_mv_table,
[pb]_field_select_table, mb_{type,var,mean}, mc_mb_var, {min,max}_qcoeff,
{inter,intra}_quant_bias, ac_esc_length, the *_vlc_length fields,
the q_{intra,inter,chroma_intra}_matrix{,16}, dct_offset, mb_info,
mjpeg_ctx, rtp_mode, rtp_payload_size, encode_mb, all function
pointers, mpv_flags, quantizer_noise_shaping,
frame_reconstruction_bitfield, error_rate and intra_penalty.
c) Fields which are already (re)set explicitly: The PutBitContexts
pb, tex_pb, pb2; dquant, skipdct, encoding_error, the statistics
fields {mv,i_tex,p_tex,misc,last}_bits and i_count; last_mv_dir,
esc_pos (reset when writing the header).
d) Fields which are only used by encoders not supporting slice
threading for which synchronisation doesn't matter: esc3_level_length
and the remaining mb_info fields.
e) coded_score: This field is only really used when FF_MPV_FLAG_CBP_RD
is set (which implies trellis) and even then it is only used for
non-intra blocks. For these blocks dct_quantize_trellis_c() either
sets coded_score[n] or returns a last_non_zero value of -1
in which case coded_score will be reset in encode_mb_internal().
Therefore no old values are ever used.

The MotionEstContext has not been moved yet.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/aarch64/me_cmp_init_aarch64.c    |   58 +-
 libavcodec/arm/me_cmp_init_arm.c            |   11 +-
 libavcodec/dnxhdenc.c                       |  283 ++-
 libavcodec/dnxhdenc.h                       |    4 +-
 libavcodec/flvenc.c                         |   32 +-
 libavcodec/h261enc.c                        |  104 +-
 libavcodec/h261enc.h                        |    4 +-
 libavcodec/h263enc.h                        |   26 +-
 libavcodec/ituh263enc.c                     |  248 ++-
 libavcodec/me_cmp.c                         |  100 +-
 libavcodec/me_cmp.h                         |    6 +-
 libavcodec/mips/me_cmp_mips.h               |   32 +-
 libavcodec/mips/me_cmp_msa.c                |   28 +-
 libavcodec/mips/mpegvideo_mips.h            |    3 +-
 libavcodec/mips/mpegvideoenc_init_mips.c    |    2 +-
 libavcodec/mips/mpegvideoenc_mmi.c          |    4 +-
 libavcodec/mips/mpegvideoencdsp_init_mips.c |    1 +
 libavcodec/mips/pixblockdsp_init_mips.c     |    1 +
 libavcodec/mips/pixblockdsp_mips.h          |    3 +-
 libavcodec/mjpegenc.c                       |   86 +-
 libavcodec/mjpegenc.h                       |    8 +-
 libavcodec/motion_est.c                     |  499 ++---
 libavcodec/motion_est.h                     |   20 +-
 libavcodec/motion_est_template.c            |  104 +-
 libavcodec/mpeg12enc.c                      |  460 ++--
 libavcodec/mpeg12enc.h                      |   10 +-
 libavcodec/mpeg4videoenc.c                  |  505 +++--
 libavcodec/mpeg4videoenc.h                  |   12 +-
 libavcodec/mpegvideo.c                      |    3 -
 libavcodec/mpegvideo.h                      |  123 +-
 libavcodec/mpegvideo_dec.c                  |    2 +-
 libavcodec/mpegvideo_enc.c                  | 2105 ++++++++++---------
 libavcodec/mpegvideoenc.h                   |  155 +-
 libavcodec/msmpeg4enc.c                     |  156 +-
 libavcodec/msmpeg4enc.h                     |    8 +-
 libavcodec/ppc/me_cmp.c                     |   20 +-
 libavcodec/ratecontrol.c                    |  253 ++-
 libavcodec/riscv/me_cmp_init.c              |   44 +-
 libavcodec/rv10enc.c                        |   16 +-
 libavcodec/rv20enc.c                        |   36 +-
 libavcodec/snow_dwt.c                       |   14 +-
 libavcodec/snow_dwt.h                       |    6 +-
 libavcodec/snowenc.c                        |  128 +-
 libavcodec/speedhqenc.c                     |   28 +-
 libavcodec/speedhqenc.h                     |    6 +-
 libavcodec/svq1enc.c                        |  126 +-
 libavcodec/wmv2enc.c                        |   66 +-
 libavcodec/x86/me_cmp.asm                   |   16 +-
 libavcodec/x86/me_cmp_init.c                |   62 +-
 libavcodec/x86/mpegvideoenc.c               |    9 +-
 libavcodec/x86/mpegvideoenc_template.c      |   38 +-
 tests/checkasm/motion.c                     |    2 +-
 52 files changed, 3046 insertions(+), 3030 deletions(-)

diff --git a/libavcodec/aarch64/me_cmp_init_aarch64.c b/libavcodec/aarch64/me_cmp_init_aarch64.c
index fa2724403d..dac6676886 100644
--- a/libavcodec/aarch64/me_cmp_init_aarch64.c
+++ b/libavcodec/aarch64/me_cmp_init_aarch64.c
@@ -21,66 +21,66 @@
 #include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/aarch64/cpu.h"
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideoenc.h"
 
-int ff_pix_abs16_neon(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs16_neon(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                       ptrdiff_t stride, int h);
-int ff_pix_abs16_xy2_neon(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs16_xy2_neon(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                           ptrdiff_t stride, int h);
-int ff_pix_abs16_x2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_x2_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_pix_abs16_y2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_y2_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_pix_abs8_neon(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs8_neon(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                      ptrdiff_t stride, int h);
 
-int sse16_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int sse16_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                ptrdiff_t stride, int h);
-int sse8_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int sse8_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
               ptrdiff_t stride, int h);
-int sse4_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int sse4_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
               ptrdiff_t stride, int h);
 
-int vsad16_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int vsad16_neon(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                 ptrdiff_t stride, int h);
-int vsad_intra16_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+int vsad_intra16_neon(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy,
                       ptrdiff_t stride, int h) ;
-int vsad_intra8_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+int vsad_intra8_neon(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy,
                      ptrdiff_t stride, int h) ;
-int vsse16_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int vsse16_neon(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                 ptrdiff_t stride, int h);
-int vsse_intra16_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+int vsse_intra16_neon(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy,
                       ptrdiff_t stride, int h);
 int nsse16_neon(int multiplier, const uint8_t *s, const uint8_t *s2,
                 ptrdiff_t stride, int h);
-int nsse16_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int nsse16_neon_wrapper(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                         ptrdiff_t stride, int h);
-int pix_median_abs16_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int pix_median_abs16_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h);
-int pix_median_abs8_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int pix_median_abs8_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_pix_abs8_x2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_x2_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h);
-int ff_pix_abs8_y2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_y2_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h);
-int ff_pix_abs8_xy2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_xy2_neon(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
 
 int nsse8_neon(int multiplier, const uint8_t *s, const uint8_t *s2,
                ptrdiff_t stride, int h);
-int nsse8_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int nsse8_neon_wrapper(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                        ptrdiff_t stride, int h);
 
-int vsse8_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int vsse8_neon(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                ptrdiff_t stride, int h);
 
-int vsse_intra8_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+int vsse_intra8_neon(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy,
                      ptrdiff_t stride, int h);
 
 #if HAVE_DOTPROD
-int sse16_neon_dotprod(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int sse16_neon_dotprod(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h);
-int vsse_intra16_neon_dotprod(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int vsse_intra16_neon_dotprod(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                               ptrdiff_t stride, int h);
 #endif
 
@@ -129,20 +129,20 @@ av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
 #endif
 }
 
-int nsse16_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int nsse16_neon_wrapper(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                         ptrdiff_t stride, int h)
 {
     if (c)
-        return nsse16_neon(c->avctx->nsse_weight, s1, s2, stride, h);
+        return nsse16_neon(c->c.avctx->nsse_weight, s1, s2, stride, h);
     else
         return nsse16_neon(8, s1, s2, stride, h);
 }
 
-int nsse8_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+int nsse8_neon_wrapper(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                        ptrdiff_t stride, int h)
 {
     if (c)
-        return nsse8_neon(c->avctx->nsse_weight, s1, s2, stride, h);
+        return nsse8_neon(c->c.avctx->nsse_weight, s1, s2, stride, h);
     else
         return nsse8_neon(8, s1, s2, stride, h);
 }
diff --git a/libavcodec/arm/me_cmp_init_arm.c b/libavcodec/arm/me_cmp_init_arm.c
index 8c556f1755..a47e2bc4fa 100644
--- a/libavcodec/arm/me_cmp_init_arm.c
+++ b/libavcodec/arm/me_cmp_init_arm.c
@@ -23,19 +23,18 @@
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/me_cmp.h"
-#include "libavcodec/mpegvideo.h"
 
-int ff_pix_abs16_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs16_armv6(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                        ptrdiff_t stride, int h);
-int ff_pix_abs16_x2_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs16_x2_armv6(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                           ptrdiff_t stride, int h);
-int ff_pix_abs16_y2_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs16_y2_armv6(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                           ptrdiff_t stride, int h);
 
-int ff_pix_abs8_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_pix_abs8_armv6(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                       ptrdiff_t stride, int h);
 
-int ff_sse16_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+int ff_sse16_armv6(MPVEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                    ptrdiff_t stride, int h);
 
 av_cold void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx)
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 6009e392f8..a8f8ab3cd9 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -117,12 +117,12 @@ void dnxhd_10bit_get_pixels_8x4_sym(int16_t *restrict block,
     memcpy(block + 4 * 8, pixels + 3 * line_size, 8 * sizeof(*block));
 }
 
-static int dnxhd_10bit_dct_quantize_444(MpegEncContext *ctx, int16_t *block,
+static int dnxhd_10bit_dct_quantize_444(MPVEncContext *ctx, int16_t *block,
                                         int n, int qscale, int *overflow)
 {
     int i, j, level, last_non_zero, start_i;
     const int *qmat;
-    const uint8_t *scantable= ctx->intra_scantable.scantable;
+    const uint8_t *scantable = ctx->c.intra_scantable.scantable;
     int bias;
     int max = 0;
     unsigned int threshold1, threshold2;
@@ -169,17 +169,17 @@ static int dnxhd_10bit_dct_quantize_444(MpegEncContext *ctx, int16_t *block,
     *overflow = ctx->max_qcoeff < max; //overflow might have happened
 
     /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */
-    if (ctx->idsp.perm_type != FF_IDCT_PERM_NONE)
-        ff_block_permute(block, ctx->idsp.idct_permutation,
+    if (ctx->c.idsp.perm_type != FF_IDCT_PERM_NONE)
+        ff_block_permute(block, ctx->c.idsp.idct_permutation,
                          scantable, last_non_zero);
 
     return last_non_zero;
 }
 
-static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block,
+static int dnxhd_10bit_dct_quantize(MPVEncContext *ctx, int16_t *block,
                                     int n, int qscale, int *overflow)
 {
-    const uint8_t *scantable= ctx->intra_scantable.scantable;
+    const uint8_t *scantable = ctx->c.intra_scantable.scantable;
     const int *qmat = n<4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale];
     int last_non_zero = 0;
     int i;
@@ -200,8 +200,8 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block,
     }
 
     /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */
-    if (ctx->idsp.perm_type != FF_IDCT_PERM_NONE)
-        ff_block_permute(block, ctx->idsp.idct_permutation,
+    if (ctx->c.idsp.perm_type != FF_IDCT_PERM_NONE)
+        ff_block_permute(block, ctx->c.idsp.idct_permutation,
                          scantable, last_non_zero);
 
     return last_non_zero;
@@ -266,34 +266,33 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
 {
     // init first elem to 1 to avoid div by 0 in convert_matrix
     uint16_t weight_matrix[64] = { 1, }; // convert_matrix needs uint16_t*
-    int qscale, i;
     const uint8_t *luma_weight_table   = ctx->cid_table->luma_weight;
     const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight;
 
-    if (!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l,   ctx->m.avctx->qmax + 1) ||
-        !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c,   ctx->m.avctx->qmax + 1) ||
-        !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l16, ctx->m.avctx->qmax + 1) ||
-        !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c16, ctx->m.avctx->qmax + 1))
+    if (!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l,   ctx->m.c.avctx->qmax + 1) ||
+        !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c,   ctx->m.c.avctx->qmax + 1) ||
+        !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l16, ctx->m.c.avctx->qmax + 1) ||
+        !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c16, ctx->m.c.avctx->qmax + 1))
         return AVERROR(ENOMEM);
 
     if (ctx->bit_depth == 8) {
-        for (i = 1; i < 64; i++) {
-            int j = ctx->m.idsp.idct_permutation[ff_zigzag_direct[i]];
+        for (int i = 1; i < 64; i++) {
+            int j = ctx->m.c.idsp.idct_permutation[ff_zigzag_direct[i]];
             weight_matrix[j] = ctx->cid_table->luma_weight[i];
         }
         ff_convert_matrix(&ctx->m, ctx->qmatrix_l, ctx->qmatrix_l16,
                           weight_matrix, ctx->intra_quant_bias, 1,
-                          ctx->m.avctx->qmax, 1);
-        for (i = 1; i < 64; i++) {
-            int j = ctx->m.idsp.idct_permutation[ff_zigzag_direct[i]];
+                          ctx->m.c.avctx->qmax, 1);
+        for (int i = 1; i < 64; i++) {
+            int j = ctx->m.c.idsp.idct_permutation[ff_zigzag_direct[i]];
             weight_matrix[j] = ctx->cid_table->chroma_weight[i];
         }
         ff_convert_matrix(&ctx->m, ctx->qmatrix_c, ctx->qmatrix_c16,
                           weight_matrix, ctx->intra_quant_bias, 1,
-                          ctx->m.avctx->qmax, 1);
+                          ctx->m.c.avctx->qmax, 1);
 
-        for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
-            for (i = 0; i < 64; i++) {
+        for (int qscale = 1; qscale <= ctx->m.c.avctx->qmax; qscale++) {
+            for (int i = 0; i < 64; i++) {
                 ctx->qmatrix_l[qscale][i]      <<= 2;
                 ctx->qmatrix_c[qscale][i]      <<= 2;
                 ctx->qmatrix_l16[qscale][0][i] <<= 2;
@@ -304,8 +303,8 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
         }
     } else {
         // 10-bit
-        for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
-            for (i = 1; i < 64; i++) {
+        for (int qscale = 1; qscale <= ctx->m.c.avctx->qmax; qscale++) {
+            for (int i = 1; i < 64; i++) {
                 int j = ff_zigzag_direct[i];
 
                 /* The quantization formula from the VC-3 standard is:
@@ -337,12 +336,12 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
 
 static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)
 {
-    if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_rc, (ctx->m.avctx->qmax + 1) * ctx->m.mb_num))
+    if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_rc, (ctx->m.c.avctx->qmax + 1) * ctx->m.c.mb_num))
         return AVERROR(ENOMEM);
 
-    if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) {
-        if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp,     ctx->m.mb_num) ||
-            !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp_tmp, ctx->m.mb_num))
+    if (ctx->m.c.avctx->mb_decision != FF_MB_DECISION_RD) {
+        if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp,     ctx->m.c.mb_num) ||
+            !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp_tmp, ctx->m.c.mb_num))
             return AVERROR(ENOMEM);
     }
     ctx->frame_bits = (ctx->coding_unit_size -
@@ -414,21 +413,21 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
     ctx->cid_table = ff_dnxhd_get_cid_table(ctx->cid);
     av_assert0(ctx->cid_table);
 
-    ctx->m.avctx    = avctx;
-    ctx->m.mb_intra = 1;
-    ctx->m.h263_aic = 1;
+    ctx->m.c.avctx    = avctx;
+    ctx->m.c.mb_intra = 1;
+    ctx->m.c.h263_aic = 1;
 
     avctx->bits_per_raw_sample = ctx->bit_depth;
 
-    ff_blockdsp_init(&ctx->m.bdsp);
+    ff_blockdsp_init(&ctx->m.c.bdsp);
     ff_fdctdsp_init(&ctx->m.fdsp, avctx);
-    ff_mpv_idct_init(&ctx->m);
+    ff_mpv_idct_init(&ctx->m.c);
     ff_mpegvideoencdsp_init(&ctx->m.mpvencdsp, avctx);
     ff_pixblockdsp_init(&ctx->m.pdsp, avctx);
     ff_dct_encode_init(&ctx->m);
 
     if (ctx->profile != AV_PROFILE_DNXHD)
-        ff_videodsp_init(&ctx->m.vdsp, ctx->bit_depth);
+        ff_videodsp_init(&ctx->m.c.vdsp, ctx->bit_depth);
 
     if (ctx->is_444 || ctx->profile == AV_PROFILE_DNXHR_HQX) {
         ctx->m.dct_quantize     = dnxhd_10bit_dct_quantize_444;
@@ -445,12 +444,12 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
 
     ff_dnxhdenc_init(ctx);
 
-    ctx->m.mb_height = (avctx->height + 15) / 16;
-    ctx->m.mb_width  = (avctx->width  + 15) / 16;
+    ctx->m.c.mb_height = (avctx->height + 15) / 16;
+    ctx->m.c.mb_width  = (avctx->width  + 15) / 16;
 
     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
         ctx->interlaced   = 1;
-        ctx->m.mb_height /= 2;
+        ctx->m.c.mb_height /= 2;
     }
 
     if (ctx->interlaced && ctx->profile != AV_PROFILE_DNXHD) {
@@ -459,7 +458,7 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width;
+    ctx->m.c.mb_num = ctx->m.c.mb_height * ctx->m.c.mb_width;
 
     if (ctx->cid_table->frame_size == DNXHD_VARIABLE) {
         ctx->frame_size = ff_dnxhd_get_hr_frame_size(ctx->cid,
@@ -471,8 +470,8 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
         ctx->coding_unit_size = ctx->cid_table->coding_unit_size;
     }
 
-    if (ctx->m.mb_height > 68)
-        ctx->data_offset = 0x170 + (ctx->m.mb_height << 2);
+    if (ctx->m.c.mb_height > 68)
+        ctx->data_offset = 0x170 + (ctx->m.c.mb_height << 2);
     else
         ctx->data_offset = 0x280;
 
@@ -490,10 +489,10 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
     if ((ret = dnxhd_init_rc(ctx)) < 0)
         return ret;
 
-    if (!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_size, ctx->m.mb_height) ||
-        !FF_ALLOCZ_TYPED_ARRAY(ctx->slice_offs, ctx->m.mb_height) ||
-        !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_bits,    ctx->m.mb_num)    ||
-        !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_qscale,  ctx->m.mb_num))
+    if (!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_size, ctx->m.c.mb_height) ||
+        !FF_ALLOCZ_TYPED_ARRAY(ctx->slice_offs, ctx->m.c.mb_height) ||
+        !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_bits,    ctx->m.c.mb_num)    ||
+        !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_qscale,  ctx->m.c.mb_num))
         return AVERROR(ENOMEM);
 
     if (avctx->active_thread_type == FF_THREAD_SLICE) {
@@ -548,8 +547,8 @@ static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
     buf[0x5f] = 0x01; // UDL
 
     buf[0x167] = 0x02; // reserved
-    AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
-    AV_WB16(buf + 0x16c, ctx->m.mb_height); // Ns
+    AV_WB16(buf + 0x16a, ctx->m.c.mb_height * 4 + 4); // MSIPS
+    AV_WB16(buf + 0x16c, ctx->m.c.mb_height); // Ns
     buf[0x16f] = 0x10; // reserved
 
     ctx->msip = buf + 0x170;
@@ -577,11 +576,11 @@ void dnxhd_encode_block(PutBitContext *pb, DNXHDEncContext *ctx,
     int last_non_zero = 0;
     int slevel, i, j;
 
-    dnxhd_encode_dc(pb, ctx, block[0] - ctx->m.last_dc[n]);
-    ctx->m.last_dc[n] = block[0];
+    dnxhd_encode_dc(pb, ctx, block[0] - ctx->m.c.last_dc[n]);
+    ctx->m.c.last_dc[n] = block[0];
 
     for (i = 1; i <= last_index; i++) {
-        j = ctx->m.intra_scantable.permutated[i];
+        j = ctx->m.c.intra_scantable.permutated[i];
         slevel = block[j];
         if (slevel) {
             int run_level = i - last_non_zero - 1;
@@ -613,7 +612,7 @@ void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n,
     }
 
     for (i = 1; i <= last_index; i++) {
-        int j = ctx->m.intra_scantable.permutated[i];
+        int j = ctx->m.c.intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             if (level < 0) {
@@ -661,7 +660,7 @@ int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, int16_t *block, int last_index)
     int bits = 0;
     int i, j, level;
     for (i = 1; i <= last_index; i++) {
-        j = ctx->m.intra_scantable.permutated[i];
+        j = ctx->m.c.intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             int run_level = i - last_non_zero - 1;
@@ -680,36 +679,36 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
     const int bw = 1 << bs;
     int dct_y_offset = ctx->dct_y_offset;
     int dct_uv_offset = ctx->dct_uv_offset;
-    int linesize = ctx->m.linesize;
-    int uvlinesize = ctx->m.uvlinesize;
+    int linesize = ctx->m.c.linesize;
+    int uvlinesize = ctx->m.c.uvlinesize;
     const uint8_t *ptr_y = ctx->thread[0]->src[0] +
-                           ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs + 1);
+                           ((mb_y << 4) * ctx->m.c.linesize) + (mb_x << bs + 1);
     const uint8_t *ptr_u = ctx->thread[0]->src[1] +
-                           ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs + ctx->is_444);
+                           ((mb_y << 4) * ctx->m.c.uvlinesize) + (mb_x << bs + ctx->is_444);
     const uint8_t *ptr_v = ctx->thread[0]->src[2] +
-                           ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs + ctx->is_444);
+                           ((mb_y << 4) * ctx->m.c.uvlinesize) + (mb_x << bs + ctx->is_444);
     PixblockDSPContext *pdsp = &ctx->m.pdsp;
-    VideoDSPContext *vdsp = &ctx->m.vdsp;
+    VideoDSPContext *vdsp = &ctx->m.c.vdsp;
 
-    if (ctx->bit_depth != 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width ||
-                                                           (mb_y << 4) + 16 > ctx->m.avctx->height)) {
-        int y_w = ctx->m.avctx->width  - (mb_x << 4);
-        int y_h = ctx->m.avctx->height - (mb_y << 4);
+    if (ctx->bit_depth != 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.c.avctx->width ||
+                                                           (mb_y << 4) + 16 > ctx->m.c.avctx->height)) {
+        int y_w = ctx->m.c.avctx->width  - (mb_x << 4);
+        int y_h = ctx->m.c.avctx->height - (mb_y << 4);
         int uv_w = (y_w + 1) / 2;
         int uv_h = y_h;
         linesize = 16;
         uvlinesize = 8;
 
         vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y,
-                               linesize, ctx->m.linesize,
+                               linesize, ctx->m.c.linesize,
                                linesize, 16,
                                0, 0, y_w, y_h);
         vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u,
-                               uvlinesize, ctx->m.uvlinesize,
+                               uvlinesize, ctx->m.c.uvlinesize,
                                uvlinesize, 16,
                                0, 0, uv_w, uv_h);
         vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v,
-                               uvlinesize, ctx->m.uvlinesize,
+                               uvlinesize, ctx->m.c.uvlinesize,
                                uvlinesize, 16,
                                0, 0, uv_w, uv_h);
 
@@ -718,25 +717,25 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
         ptr_y = &ctx->edge_buf_y[0];
         ptr_u = &ctx->edge_buf_uv[0][0];
         ptr_v = &ctx->edge_buf_uv[1][0];
-    } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width ||
-                                                                  (mb_y << 4) + 16 > ctx->m.avctx->height)) {
-        int y_w = ctx->m.avctx->width  - (mb_x << 4);
-        int y_h = ctx->m.avctx->height - (mb_y << 4);
+    } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.c.avctx->width ||
+                                                                  (mb_y << 4) + 16 > ctx->m.c.avctx->height)) {
+        int y_w = ctx->m.c.avctx->width  - (mb_x << 4);
+        int y_h = ctx->m.c.avctx->height - (mb_y << 4);
         int uv_w = ctx->is_444 ? y_w : (y_w + 1) / 2;
         int uv_h = y_h;
         linesize = 32;
         uvlinesize = 16 + 16 * ctx->is_444;
 
         vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y,
-                               linesize, ctx->m.linesize,
+                               linesize, ctx->m.c.linesize,
                                linesize / 2, 16,
                                0, 0, y_w, y_h);
         vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u,
-                               uvlinesize, ctx->m.uvlinesize,
+                               uvlinesize, ctx->m.c.uvlinesize,
                                uvlinesize / 2, 16,
                                0, 0, uv_w, uv_h);
         vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v,
-                               uvlinesize, ctx->m.uvlinesize,
+                               uvlinesize, ctx->m.c.uvlinesize,
                                uvlinesize / 2, 16,
                                0, 0, uv_w, uv_h);
 
@@ -753,7 +752,7 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
         pdsp->get_pixels(ctx->blocks[2], ptr_u,      uvlinesize);
         pdsp->get_pixels(ctx->blocks[3], ptr_v,      uvlinesize);
 
-        if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
+        if (mb_y + 1 == ctx->m.c.mb_height && ctx->m.c.avctx->height == 1080) {
             if (ctx->interlaced) {
                 ctx->get_pixels_8x4_sym(ctx->blocks[4],
                                         ptr_y + dct_y_offset,
@@ -768,10 +767,10 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
                                         ptr_v + dct_uv_offset,
                                         uvlinesize);
             } else {
-                ctx->m.bdsp.clear_block(ctx->blocks[4]);
-                ctx->m.bdsp.clear_block(ctx->blocks[5]);
-                ctx->m.bdsp.clear_block(ctx->blocks[6]);
-                ctx->m.bdsp.clear_block(ctx->blocks[7]);
+                ctx->m.c.bdsp.clear_block(ctx->blocks[4]);
+                ctx->m.c.bdsp.clear_block(ctx->blocks[5]);
+                ctx->m.c.bdsp.clear_block(ctx->blocks[6]);
+                ctx->m.c.bdsp.clear_block(ctx->blocks[7]);
             }
         } else {
             pdsp->get_pixels(ctx->blocks[4],
@@ -819,17 +818,17 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg,
                                   int jobnr, int threadnr)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
-    int mb_y = jobnr, mb_x;
+    int mb_y = jobnr;
     int qscale = ctx->qscale;
     LOCAL_ALIGNED_16(int16_t, block, [64]);
     ctx = ctx->thread[threadnr];
 
-    ctx->m.last_dc[0] =
-    ctx->m.last_dc[1] =
-    ctx->m.last_dc[2] = 1 << (ctx->bit_depth + 2);
+    ctx->m.c.last_dc[0] =
+    ctx->m.c.last_dc[1] =
+    ctx->m.c.last_dc[2] = 1 << (ctx->bit_depth + 2);
 
-    for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
-        unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+    for (int mb_x = 0; mb_x < ctx->m.c.mb_width; mb_x++) {
+        unsigned mb = mb_y * ctx->m.c.mb_width + mb_x;
         int ssd     = 0;
         int ac_bits = 0;
         int dc_bits = 0;
@@ -848,7 +847,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg,
                                              qscale, &overflow);
             ac_bits   += dnxhd_calc_ac_bits(ctx, block, last_index);
 
-            diff = block[0] - ctx->m.last_dc[n];
+            diff = block[0] - ctx->m.c.last_dc[n];
             if (diff < 0)
                 nbits = av_log2_16bit(-2 * diff);
             else
@@ -857,16 +856,16 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg,
             av_assert1(nbits < ctx->bit_depth + 4);
             dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
 
-            ctx->m.last_dc[n] = block[0];
+            ctx->m.c.last_dc[n] = block[0];
 
             if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
                 dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
-                ctx->m.idsp.idct(block);
+                ctx->m.c.idsp.idct(block);
                 ssd += dnxhd_ssd_block(block, src_block);
             }
         }
-        ctx->mb_rc[(qscale * ctx->m.mb_num) + mb].ssd  = ssd;
-        ctx->mb_rc[(qscale * ctx->m.mb_num) + mb].bits = ac_bits + dc_bits + 12 +
+        ctx->mb_rc[(qscale * ctx->m.c.mb_num) + mb].ssd  = ssd;
+        ctx->mb_rc[(qscale * ctx->m.c.mb_num) + mb].bits = ac_bits + dc_bits + 12 +
                                      (1 + ctx->is_444) * 8 * ctx->vlc_bits[0];
     }
     return 0;
@@ -877,16 +876,16 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg,
 {
     DNXHDEncContext *ctx = avctx->priv_data;
     PutBitContext pb0, *const pb = &pb0;
-    int mb_y = jobnr, mb_x;
+    int mb_y = jobnr;
     ctx = ctx->thread[threadnr];
     init_put_bits(pb, (uint8_t *)arg + ctx->data_offset + ctx->slice_offs[jobnr],
                   ctx->slice_size[jobnr]);
 
-    ctx->m.last_dc[0] =
-    ctx->m.last_dc[1] =
-    ctx->m.last_dc[2] = 1 << (ctx->bit_depth + 2);
-    for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
-        unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+    ctx->m.c.last_dc[0] =
+    ctx->m.c.last_dc[1] =
+    ctx->m.c.last_dc[2] = 1 << (ctx->bit_depth + 2);
+    for (int mb_x = 0; mb_x < ctx->m.c.mb_width; mb_x++) {
+        unsigned mb = mb_y * ctx->m.c.mb_width + mb_x;
         int qscale = ctx->mb_qscale[mb];
         int i;
 
@@ -912,14 +911,12 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg,
 
 static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx)
 {
-    int mb_y, mb_x;
-    int offset = 0;
-    for (mb_y = 0; mb_y < ctx->m.mb_height; mb_y++) {
+    for (int mb_y = 0, offset = 0; mb_y < ctx->m.c.mb_height; mb_y++) {
         int thread_size;
         ctx->slice_offs[mb_y] = offset;
         ctx->slice_size[mb_y] = 0;
-        for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
-            unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+        for (int mb_x = 0; mb_x < ctx->m.c.mb_width; mb_x++) {
+            unsigned mb = mb_y * ctx->m.c.mb_width + mb_x;
             ctx->slice_size[mb_y] += ctx->mb_bits[mb];
         }
         ctx->slice_size[mb_y]   = (ctx->slice_size[mb_y] + 31U) & ~31U;
@@ -933,28 +930,28 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg,
                                int jobnr, int threadnr)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
-    int mb_y = jobnr, mb_x, x, y;
-    int partial_last_row = (mb_y == ctx->m.mb_height - 1) &&
+    int mb_y = jobnr, x, y;
+    int partial_last_row = (mb_y == ctx->m.c.mb_height - 1) &&
                            ((avctx->height >> ctx->interlaced) & 0xF);
 
     ctx = ctx->thread[threadnr];
     if (ctx->bit_depth == 8) {
-        const uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize);
-        for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) {
-            unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+        const uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.c.linesize);
+        for (int mb_x = 0; mb_x < ctx->m.c.mb_width; ++mb_x, pix += 16) {
+            unsigned mb = mb_y * ctx->m.c.mb_width + mb_x;
             int sum;
             int varc;
 
             if (!partial_last_row && mb_x * 16 <= avctx->width - 16 && (avctx->width % 16) == 0) {
-                sum  = ctx->m.mpvencdsp.pix_sum(pix, ctx->m.linesize);
-                varc = ctx->m.mpvencdsp.pix_norm1(pix, ctx->m.linesize);
+                sum  = ctx->m.mpvencdsp.pix_sum(pix, ctx->m.c.linesize);
+                varc = ctx->m.mpvencdsp.pix_norm1(pix, ctx->m.c.linesize);
             } else {
                 int bw = FFMIN(avctx->width - 16 * mb_x, 16);
                 int bh = FFMIN((avctx->height >> ctx->interlaced) - 16 * mb_y, 16);
                 sum = varc = 0;
                 for (y = 0; y < bh; y++) {
                     for (x = 0; x < bw; x++) {
-                        uint8_t val = pix[x + y * ctx->m.linesize];
+                        uint8_t val = pix[x + y * ctx->m.c.linesize];
                         sum  += val;
                         varc += val * val;
                     }
@@ -966,11 +963,11 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg,
             ctx->mb_cmp[mb].mb    = mb;
         }
     } else { // 10-bit
-        const int linesize = ctx->m.linesize >> 1;
-        for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x) {
+        const int linesize = ctx->m.c.linesize >> 1;
+        for (int mb_x = 0; mb_x < ctx->m.c.mb_width; ++mb_x) {
             const uint16_t *pix = (const uint16_t *)ctx->thread[0]->src[0] +
                                      ((mb_y << 4) * linesize) + (mb_x << 4);
-            unsigned mb  = mb_y * ctx->m.mb_width + mb_x;
+            unsigned mb  = mb_y * ctx->m.c.mb_width + mb_x;
             int sum = 0;
             int sqsum = 0;
             int bw = FFMIN(avctx->width - 16 * mb_x, 16);
@@ -1001,12 +998,11 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
 {
     int lambda, up_step, down_step;
     int last_lower = INT_MAX, last_higher = 0;
-    int x, y, q;
 
-    for (q = 1; q < avctx->qmax; q++) {
+    for (int q = 1; q < avctx->qmax; q++) {
         ctx->qscale = q;
         avctx->execute2(avctx, dnxhd_calc_bits_thread,
-                        NULL, NULL, ctx->m.mb_height);
+                        NULL, NULL, ctx->m.c.mb_height);
     }
     up_step = down_step = 2 << LAMBDA_FRAC_BITS;
     lambda  = ctx->lambda;
@@ -1018,14 +1014,14 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
             lambda++;
             end = 1; // need to set final qscales/bits
         }
-        for (y = 0; y < ctx->m.mb_height; y++) {
-            for (x = 0; x < ctx->m.mb_width; x++) {
+        for (int y = 0; y < ctx->m.c.mb_height; y++) {
+            for (int x = 0; x < ctx->m.c.mb_width; x++) {
                 unsigned min = UINT_MAX;
                 int qscale = 1;
-                int mb     = y * ctx->m.mb_width + x;
+                int mb     = y * ctx->m.c.mb_width + x;
                 int rc = 0;
-                for (q = 1; q < avctx->qmax; q++) {
-                    int i = (q*ctx->m.mb_num) + mb;
+                for (int q = 1; q < avctx->qmax; q++) {
+                    int i = (q*ctx->m.c.mb_num) + mb;
                     unsigned score = ctx->mb_rc[i].bits * lambda +
                                      ((unsigned) ctx->mb_rc[i].ssd << LAMBDA_FRAC_BITS);
                     if (score < min) {
@@ -1082,18 +1078,17 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx)
     int last_higher = 0;
     int last_lower = INT_MAX;
     int qscale;
-    int x, y;
 
     qscale = ctx->qscale;
     for (;;) {
         bits = 0;
         ctx->qscale = qscale;
         // XXX avoid recalculating bits
-        ctx->m.avctx->execute2(ctx->m.avctx, dnxhd_calc_bits_thread,
-                               NULL, NULL, ctx->m.mb_height);
-        for (y = 0; y < ctx->m.mb_height; y++) {
-            for (x = 0; x < ctx->m.mb_width; x++)
-                bits += ctx->mb_rc[(qscale*ctx->m.mb_num) + (y*ctx->m.mb_width+x)].bits;
+        ctx->m.c.avctx->execute2(ctx->m.c.avctx, dnxhd_calc_bits_thread,
+                               NULL, NULL, ctx->m.c.mb_height);
+        for (int y = 0; y < ctx->m.c.mb_height; y++) {
+            for (int x = 0; x < ctx->m.c.mb_width; x++)
+                bits += ctx->mb_rc[(qscale*ctx->m.c.mb_num) + (y*ctx->m.c.mb_width+x)].bits;
             bits = (bits+31)&~31; // padding
             if (bits > ctx->frame_bits)
                 break;
@@ -1122,7 +1117,7 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx)
             else
                 qscale += up_step++;
             down_step = 1;
-            if (qscale >= ctx->m.avctx->qmax)
+            if (qscale >= ctx->m.c.avctx->qmax)
                 return AVERROR(EINVAL);
         }
     }
@@ -1189,24 +1184,24 @@ static void radix_sort(RCCMPEntry *data, RCCMPEntry *tmp, int size)
 static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
 {
     int max_bits = 0;
-    int ret, x, y;
+    int ret;
     if ((ret = dnxhd_find_qscale(ctx)) < 0)
         return ret;
-    for (y = 0; y < ctx->m.mb_height; y++) {
-        for (x = 0; x < ctx->m.mb_width; x++) {
-            int mb = y * ctx->m.mb_width + x;
-            int rc = (ctx->qscale * ctx->m.mb_num ) + mb;
+    for (int y = 0; y < ctx->m.c.mb_height; y++) {
+        for (int x = 0; x < ctx->m.c.mb_width; x++) {
+            int mb = y * ctx->m.c.mb_width + x;
+            int rc = (ctx->qscale * ctx->m.c.mb_num ) + mb;
             int delta_bits;
             ctx->mb_qscale[mb] = ctx->qscale;
             ctx->mb_bits[mb] = ctx->mb_rc[rc].bits;
             max_bits += ctx->mb_rc[rc].bits;
             if (!RC_VARIANCE) {
                 delta_bits = ctx->mb_rc[rc].bits -
-                             ctx->mb_rc[rc + ctx->m.mb_num].bits;
+                             ctx->mb_rc[rc + ctx->m.c.mb_num].bits;
                 ctx->mb_cmp[mb].mb = mb;
                 ctx->mb_cmp[mb].value =
                     delta_bits ? ((ctx->mb_rc[rc].ssd -
-                                   ctx->mb_rc[rc + ctx->m.mb_num].ssd) * 100) /
+                                   ctx->mb_rc[rc + ctx->m.c.mb_num].ssd) * 100) /
                                   delta_bits
                                : INT_MIN; // avoid increasing qscale
             }
@@ -1216,17 +1211,17 @@ static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
     if (!ret) {
         if (RC_VARIANCE)
             avctx->execute2(avctx, dnxhd_mb_var_thread,
-                            NULL, NULL, ctx->m.mb_height);
-        radix_sort(ctx->mb_cmp, ctx->mb_cmp_tmp, ctx->m.mb_num);
+                            NULL, NULL, ctx->m.c.mb_height);
+        radix_sort(ctx->mb_cmp, ctx->mb_cmp_tmp, ctx->m.c.mb_num);
 retry:
-        for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
+        for (int x = 0; x < ctx->m.c.mb_num && max_bits > ctx->frame_bits; x++) {
             int mb = ctx->mb_cmp[x].mb;
-            int rc = (ctx->qscale * ctx->m.mb_num ) + mb;
+            int rc = (ctx->qscale * ctx->m.c.mb_num ) + mb;
             max_bits -= ctx->mb_rc[rc].bits -
-                        ctx->mb_rc[rc + ctx->m.mb_num].bits;
+                        ctx->mb_rc[rc + ctx->m.c.mb_num].bits;
             if (ctx->mb_qscale[mb] < 255)
                 ctx->mb_qscale[mb]++;
-            ctx->mb_bits[mb]   = ctx->mb_rc[rc + ctx->m.mb_num].bits;
+            ctx->mb_bits[mb]   = ctx->mb_rc[rc + ctx->m.c.mb_num].bits;
         }
 
         if (max_bits > ctx->frame_bits)
@@ -1237,13 +1232,11 @@ retry:
 
 static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
 {
-    int i;
-
-    for (i = 0; i < ctx->m.avctx->thread_count; i++) {
-        ctx->thread[i]->m.linesize    = frame->linesize[0] << ctx->interlaced;
-        ctx->thread[i]->m.uvlinesize  = frame->linesize[1] << ctx->interlaced;
-        ctx->thread[i]->dct_y_offset  = ctx->m.linesize  *8;
-        ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
+    for (int i = 0; i < ctx->m.c.avctx->thread_count; i++) {
+        ctx->thread[i]->m.c.linesize    = frame->linesize[0] << ctx->interlaced;
+        ctx->thread[i]->m.c.uvlinesize  = frame->linesize[1] << ctx->interlaced;
+        ctx->thread[i]->dct_y_offset    = ctx->m.c.linesize  *8;
+        ctx->thread[i]->dct_uv_offset   = ctx->m.c.uvlinesize*8;
     }
 
     ctx->cur_field = (frame->flags & AV_FRAME_FLAG_INTERLACED) &&
@@ -1286,13 +1279,13 @@ encode_coding_unit:
     dnxhd_setup_threads_slices(ctx);
 
     offset = 0;
-    for (i = 0; i < ctx->m.mb_height; i++) {
+    for (i = 0; i < ctx->m.c.mb_height; i++) {
         AV_WB32(ctx->msip + i * 4, offset);
         offset += ctx->slice_size[i];
         av_assert1(!(ctx->slice_size[i] & 3));
     }
 
-    avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.mb_height);
+    avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.c.mb_height);
 
     av_assert1(ctx->data_offset + offset + 4 <= ctx->coding_unit_size);
     memset(buf + ctx->data_offset + offset, 0,
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index 00d486babd..7540607cdc 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -28,7 +28,7 @@
 
 #include "libavutil/mem_internal.h"
 
-#include "mpegvideo.h"
+#include "mpegvideoenc.h"
 #include "dnxhddata.h"
 
 typedef struct RCCMPEntry {
@@ -43,7 +43,7 @@ typedef struct RCEntry {
 
 typedef struct DNXHDEncContext {
     AVClass *class;
-    MpegEncContext m; ///< Used for quantization dsp functions
+    MPVEncContext m; ///< Used for quantization dsp functions
 
     int cid;
     int profile;
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index b4a30fe558..df1a650222 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -25,42 +25,42 @@
 
 int ff_flv_encode_picture_header(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int format;
 
     align_put_bits(&s->pb);
 
     put_bits(&s->pb, 17, 1);
     /* 0: H.263 escape codes 1: 11-bit escape codes */
-    put_bits(&s->pb, 5, (s->h263_flv - 1));
+    put_bits(&s->pb, 5, (s->c.h263_flv - 1));
     put_bits(&s->pb, 8,
-             (((int64_t) s->picture_number * 30 * s->avctx->time_base.num) /   // FIXME use timestamp
-              s->avctx->time_base.den) & 0xff);   /* TemporalReference */
-    if (s->width == 352 && s->height == 288)
+             (((int64_t) s->c.picture_number * 30 * s->c.avctx->time_base.num) /   // FIXME use timestamp
+              s->c.avctx->time_base.den) & 0xff);   /* TemporalReference */
+    if (s->c.width == 352 && s->c.height == 288)
         format = 2;
-    else if (s->width == 176 && s->height == 144)
+    else if (s->c.width == 176 && s->c.height == 144)
         format = 3;
-    else if (s->width == 128 && s->height == 96)
+    else if (s->c.width == 128 && s->c.height == 96)
         format = 4;
-    else if (s->width == 320 && s->height == 240)
+    else if (s->c.width == 320 && s->c.height == 240)
         format = 5;
-    else if (s->width == 160 && s->height == 120)
+    else if (s->c.width == 160 && s->c.height == 120)
         format = 6;
-    else if (s->width <= 255 && s->height <= 255)
+    else if (s->c.width <= 255 && s->c.height <= 255)
         format = 0;   /* use 1 byte width & height */
     else
         format = 1;   /* use 2 bytes width & height */
     put_bits(&s->pb, 3, format);   /* PictureSize */
     if (format == 0) {
-        put_bits(&s->pb, 8, s->width);
-        put_bits(&s->pb, 8, s->height);
+        put_bits(&s->pb, 8, s->c.width);
+        put_bits(&s->pb, 8, s->c.height);
     } else if (format == 1) {
-        put_bits(&s->pb, 16, s->width);
-        put_bits(&s->pb, 16, s->height);
+        put_bits(&s->pb, 16, s->c.width);
+        put_bits(&s->pb, 16, s->c.height);
     }
-    put_bits(&s->pb, 2, s->pict_type == AV_PICTURE_TYPE_P);   /* PictureType */
+    put_bits(&s->pb, 2, s->c.pict_type == AV_PICTURE_TYPE_P);   /* PictureType */
     put_bits(&s->pb, 1, 1);   /* DeblockingFlag: on */
-    put_bits(&s->pb, 5, s->qscale);   /* Quantizer */
+    put_bits(&s->pb, 5, s->c.qscale);   /* Quantizer */
     put_bits(&s->pb, 1, 0);   /* ExtraInformation */
 
     return 0;
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index da8736a78c..7c3c8752df 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -69,20 +69,20 @@ typedef struct H261EncContext {
 static int h261_encode_picture_header(MPVMainEncContext *const m)
 {
     H261EncContext *const h = (H261EncContext *)m;
-    MpegEncContext *const s = &h->s.s;
+    MPVEncContext *const s = &h->s.s;
     int temp_ref;
 
     align_put_bits(&s->pb);
 
     put_bits(&s->pb, 20, 0x10); /* PSC */
 
-    temp_ref = s->picture_number * 30000LL * s->avctx->time_base.num /
-               (1001LL * s->avctx->time_base.den);   // FIXME maybe this should use a timestamp
+    temp_ref = s->c.picture_number * 30000LL * s->c.avctx->time_base.num /
+               (1001LL * s->c.avctx->time_base.den);   // FIXME maybe this should use a timestamp
     put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */
 
     put_bits(&s->pb, 1, 0); /* split screen off */
     put_bits(&s->pb, 1, 0); /* camera  off */
-    put_bits(&s->pb, 1, s->pict_type == AV_PICTURE_TYPE_I); /* freeze picture release on/off */
+    put_bits(&s->pb, 1, s->c.pict_type == AV_PICTURE_TYPE_I); /* freeze picture release on/off */
 
     put_bits(&s->pb, 1, h->format); /* 0 == QCIF, 1 == CIF */
 
@@ -91,7 +91,7 @@ static int h261_encode_picture_header(MPVMainEncContext *const m)
 
     put_bits(&s->pb, 1, 0); /* no PEI */
     h->gob_number = h->format - 1;
-    s->mb_skip_run = 0;
+    s->c.mb_skip_run = 0;
 
     return 0;
 }
@@ -99,7 +99,7 @@ static int h261_encode_picture_header(MPVMainEncContext *const m)
 /**
  * Encode a group of blocks header.
  */
-static void h261_encode_gob_header(MpegEncContext *s, int mb_line)
+static void h261_encode_gob_header(MPVEncContext *const s, int mb_line)
 {
     H261EncContext *const h = (H261EncContext *)s;
     if (h->format == H261_QCIF) {
@@ -109,38 +109,38 @@ static void h261_encode_gob_header(MpegEncContext *s, int mb_line)
     }
     put_bits(&s->pb, 16, 1);            /* GBSC */
     put_bits(&s->pb, 4, h->gob_number); /* GN */
-    put_bits(&s->pb, 5, s->qscale);     /* GQUANT */
+    put_bits(&s->pb, 5, s->c.qscale);     /* GQUANT */
     put_bits(&s->pb, 1, 0);             /* no GEI */
-    s->mb_skip_run = 0;
-    s->last_mv[0][0][0] = 0;
-    s->last_mv[0][0][1] = 0;
+    s->c.mb_skip_run = 0;
+    s->c.last_mv[0][0][0] = 0;
+    s->c.last_mv[0][0][1] = 0;
 }
 
-void ff_h261_reorder_mb_index(MpegEncContext *s)
+void ff_h261_reorder_mb_index(MPVEncContext *const s)
 {
     const H261EncContext *const h = (H261EncContext*)s;
-    int index = s->mb_x + s->mb_y * s->mb_width;
+    int index = s->c.mb_x + s->c.mb_y * s->c.mb_width;
 
     if (index % 11 == 0) {
         if (index % 33 == 0)
             h261_encode_gob_header(s, 0);
-        s->last_mv[0][0][0] = 0;
-        s->last_mv[0][0][1] = 0;
+        s->c.last_mv[0][0][0] = 0;
+        s->c.last_mv[0][0][1] = 0;
     }
 
     /* for CIF the GOB's are fragmented in the middle of a scanline
      * that's why we need to adjust the x and y index of the macroblocks */
     if (h->format == H261_CIF) {
-        s->mb_x  = index % 11;
+        s->c.mb_x  = index % 11;
         index   /= 11;
-        s->mb_y  = index % 3;
+        s->c.mb_y  = index % 3;
         index   /= 3;
-        s->mb_x += 11 * (index % 2);
+        s->c.mb_x += 11 * (index % 2);
         index   /= 2;
-        s->mb_y += 3 * index;
+        s->c.mb_y += 3 * index;
 
-        ff_init_block_index(s);
-        ff_update_block_index(s, 8, 0, 1);
+        ff_init_block_index(&s->c);
+        ff_update_block_index(&s->c, 8, 0, 1);
     }
 }
 
@@ -150,12 +150,12 @@ static void h261_encode_motion(PutBitContext *pb, int val)
                  h261_mv_codes[MV_TAB_OFFSET + val][0]);
 }
 
-static inline int get_cbp(MpegEncContext *s, int16_t block[6][64])
+static inline int get_cbp(const int block_last_index[6])
 {
     int i, cbp;
     cbp = 0;
     for (i = 0; i < 6; i++)
-        if (s->block_last_index[i] >= 0)
+        if (block_last_index[i] >= 0)
             cbp |= 1 << (5 - i);
     return cbp;
 }
@@ -167,10 +167,10 @@ static inline int get_cbp(MpegEncContext *s, int16_t block[6][64])
  */
 static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
 {
-    MpegEncContext *const s = &h->s.s;
+    MPVEncContext *const s = &h->s.s;
     int level, run, i, j, last_index, last_non_zero;
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         /* DC coef */
         level = block[0];
         /* 255 cannot be represented, so we clamp */
@@ -189,7 +189,7 @@ static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
             put_bits(&s->pb, 8, level);
         i = 1;
     } else if ((block[0] == 1 || block[0] == -1) &&
-               (s->block_last_index[n] > -1)) {
+               (s->c.block_last_index[n] > -1)) {
         // special case
         put_bits(&s->pb, 2, block[0] > 0 ? 2 : 3);
         i = 1;
@@ -198,10 +198,10 @@ static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
     }
 
     /* AC coefs */
-    last_index    = s->block_last_index[n];
+    last_index    = s->c.block_last_index[n];
     last_non_zero = i - 1;
     for (; i <= last_index; i++) {
-        j     = s->intra_scantable.permutated[i];
+        j     = s->c.intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             run    = i - last_non_zero - 1;
@@ -225,7 +225,7 @@ static void h261_encode_block(H261EncContext *h, int16_t *block, int n)
         put_bits(&s->pb, 2, 0x2); // EOB
 }
 
-static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
+static void h261_encode_mb(MPVEncContext *const s, int16_t block[6][64],
                            int motion_x, int motion_y)
 {
     /* The following is only allowed because this encoder
@@ -238,36 +238,36 @@ static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
 
     com->mtype = 0;
 
-    if (!s->mb_intra) {
+    if (!s->c.mb_intra) {
         /* compute cbp */
-        cbp = get_cbp(s, block);
+        cbp = get_cbp(s->c.block_last_index);
 
         /* mvd indicates if this block is motion compensated */
         mvd = motion_x | motion_y;
 
         if ((cbp | mvd) == 0) {
             /* skip macroblock */
-            s->mb_skip_run++;
-            s->last_mv[0][0][0] = 0;
-            s->last_mv[0][0][1] = 0;
-            s->qscale -= s->dquant;
+            s->c.mb_skip_run++;
+            s->c.last_mv[0][0][0] = 0;
+            s->c.last_mv[0][0][1] = 0;
+            s->c.qscale -= s->dquant;
             return;
         }
     }
 
     /* MB is not skipped, encode MBA */
     put_bits(&s->pb,
-             ff_h261_mba_bits[s->mb_skip_run],
-             ff_h261_mba_code[s->mb_skip_run]);
-    s->mb_skip_run = 0;
+             ff_h261_mba_bits[s->c.mb_skip_run],
+             ff_h261_mba_code[s->c.mb_skip_run]);
+    s->c.mb_skip_run = 0;
 
     /* calculate MTYPE */
-    if (!s->mb_intra) {
+    if (!s->c.mb_intra) {
         com->mtype++;
 
-        if (mvd || s->loop_filter)
+        if (mvd || s->c.loop_filter)
             com->mtype += 3;
-        if (s->loop_filter)
+        if (s->c.loop_filter)
             com->mtype += 3;
         if (cbp)
             com->mtype++;
@@ -277,7 +277,7 @@ static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
     if (s->dquant && cbp) {
         com->mtype++;
     } else
-        s->qscale -= s->dquant;
+        s->c.qscale -= s->dquant;
 
     put_bits(&s->pb,
              ff_h261_mtype_bits[com->mtype],
@@ -286,15 +286,15 @@ static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
     com->mtype = ff_h261_mtype_map[com->mtype];
 
     if (IS_QUANT(com->mtype)) {
-        ff_set_qscale(s, s->qscale + s->dquant);
-        put_bits(&s->pb, 5, s->qscale);
+        ff_set_qscale(&s->c, s->c.qscale + s->dquant);
+        put_bits(&s->pb, 5, s->c.qscale);
     }
 
     if (IS_16X16(com->mtype)) {
-        mv_diff_x       = (motion_x >> 1) - s->last_mv[0][0][0];
-        mv_diff_y       = (motion_y >> 1) - s->last_mv[0][0][1];
-        s->last_mv[0][0][0] = (motion_x >> 1);
-        s->last_mv[0][0][1] = (motion_y >> 1);
+        mv_diff_x       = (motion_x >> 1) - s->c.last_mv[0][0][0];
+        mv_diff_y       = (motion_y >> 1) - s->c.last_mv[0][0][1];
+        s->c.last_mv[0][0][0] = (motion_x >> 1);
+        s->c.last_mv[0][0][1] = (motion_y >> 1);
         h261_encode_motion(&s->pb, mv_diff_x);
         h261_encode_motion(&s->pb, mv_diff_y);
     }
@@ -310,8 +310,8 @@ static void h261_encode_mb(MpegEncContext *const s, int16_t block[6][64],
         h261_encode_block(h, block[i], i);
 
     if (!IS_16X16(com->mtype)) {
-        s->last_mv[0][0][0] = 0;
-        s->last_mv[0][0][1] = 0;
+        s->c.last_mv[0][0][0] = 0;
+        s->c.last_mv[0][0][1] = 0;
     }
 }
 
@@ -356,7 +356,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
     H261EncContext *const h = avctx->priv_data;
-    MpegEncContext *const s = &h->s.s;
+    MPVEncContext *const s = &h->s.s;
 
     if (avctx->width == 176 && avctx->height == 144) {
         h->format = H261_QCIF;
@@ -369,7 +369,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
                avctx->width, avctx->height);
         return AVERROR(EINVAL);
     }
-    s->private_ctx = &h->common;
+    s->c.private_ctx = &h->common;
     h->s.encode_picture_header = h261_encode_picture_header;
     s->encode_mb               = h261_encode_mb;
 
@@ -377,7 +377,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
     s->max_qcoeff       = 127;
     s->ac_esc_length    = H261_ESC_LEN;
 
-    s->me.mv_penalty = mv_penalty;
+    s->c.me.mv_penalty = mv_penalty;
 
     s->intra_ac_vlc_length      = s->inter_ac_vlc_length      = uni_h261_rl_len;
     s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len_last;
diff --git a/libavcodec/h261enc.h b/libavcodec/h261enc.h
index 79cdd31c2f..77f072a5e7 100644
--- a/libavcodec/h261enc.h
+++ b/libavcodec/h261enc.h
@@ -28,8 +28,8 @@
 #ifndef AVCODEC_H261ENC_H
 #define AVCODEC_H261ENC_H
 
-#include "mpegvideo.h"
+typedef struct MPVEncContext MPVEncContext;
 
-void ff_h261_reorder_mb_index(MpegEncContext *s);
+void ff_h261_reorder_mb_index(MPVEncContext *s);
 
 #endif
diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index dd9caa7969..1f459a332c 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -27,22 +27,22 @@
 const uint8_t (*ff_h263_get_mv_penalty(void))[MAX_DMV*2+1];
 
 void ff_h263_encode_init(MPVMainEncContext *m);
-void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
-void ff_h263_encode_mba(MpegEncContext *s);
+void ff_h263_encode_gob_header(MPVEncContext *s, int mb_line);
+void ff_h263_encode_mba(MPVEncContext *s);
 
-void ff_clean_h263_qscales(MpegEncContext *s);
+void ff_clean_h263_qscales(MPVEncContext *s);
 
 void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code);
-void ff_h263_update_mb(MpegEncContext *s);
+void ff_h263_update_mb(MPVEncContext *s);
 
-static inline void ff_h263_encode_motion_vector(MpegEncContext * s,
+static inline void ff_h263_encode_motion_vector(MPVEncContext *s,
                                                 int x, int y, int f_code)
 {
     ff_h263_encode_motion(&s->pb, x, f_code);
     ff_h263_encode_motion(&s->pb, y, f_code);
 }
 
-static inline int get_p_cbp(MpegEncContext * s,
+static inline int get_p_cbp(MPVEncContext *const s,
                       int16_t block[6][64],
                       int motion_x, int motion_y){
     int cbp;
@@ -51,8 +51,8 @@ static inline int get_p_cbp(MpegEncContext * s,
         int best_cbpy_score = INT_MAX;
         int best_cbpc_score = INT_MAX;
         int cbpc = (-1), cbpy = (-1);
-        const int offset = (s->mv_type == MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0);
-        const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
+        const int offset = (s->c.mv_type == MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0);
+        const int lambda = s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6);
 
         for (int i = 0; i < 4; i++) {
             int score = ff_h263_inter_MCBPC_bits[i + offset] * lambda;
@@ -78,21 +78,21 @@ static inline int get_p_cbp(MpegEncContext * s,
             }
         }
         cbp = cbpc + 4 * cbpy;
-        if (!(motion_x | motion_y | s->dquant) && s->mv_type == MV_TYPE_16X16) {
+        if (!(motion_x | motion_y | s->dquant) && s->c.mv_type == MV_TYPE_16X16) {
             if (best_cbpy_score + best_cbpc_score + 2 * lambda >= 0)
                 cbp= 0;
         }
 
         for (int i = 0; i < 6; i++) {
-            if (s->block_last_index[i] >= 0 && !((cbp >> (5 - i)) & 1)) {
-                s->block_last_index[i] = -1;
-                s->bdsp.clear_block(s->block[i]);
+            if (s->c.block_last_index[i] >= 0 && !((cbp >> (5 - i)) & 1)) {
+                s->c.block_last_index[i] = -1;
+                s->c.bdsp.clear_block(s->c.block[i]);
             }
         }
     } else {
         cbp = 0;
         for (int i = 0; i < 6; i++) {
-            if (s->block_last_index[i] >= 0)
+            if (s->c.block_last_index[i] >= 0)
                 cbp |= 1 << (5 - i);
         }
     }
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 876e178070..6bd7b6a6cd 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -223,19 +223,19 @@ av_const int ff_h263_aspect_to_info(AVRational aspect){
 
 static int h263_encode_picture_header(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *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;
     int best_error= INT_MAX;
     int custom_pcf;
 
-    if(s->h263_plus){
+    if(s->c.h263_plus){
         for(i=0; i<2; i++){
             int div, error;
-            div= (s->avctx->time_base.num*1800000LL + 500LL*s->avctx->time_base.den) / ((1000LL+i)*s->avctx->time_base.den);
+            div= (s->c.avctx->time_base.num*1800000LL + 500LL*s->c.avctx->time_base.den) / ((1000LL+i)*s->c.avctx->time_base.den);
             div= av_clip(div, 1, 127);
-            error= FFABS(s->avctx->time_base.num*1800000LL - (1000LL+i)*s->avctx->time_base.den*div);
+            error= FFABS(s->c.avctx->time_base.num*1800000LL - (1000LL+i)*s->c.avctx->time_base.den*div);
             if(error < best_error){
                 best_error= error;
                 best_divisor= div;
@@ -250,8 +250,8 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
     align_put_bits(&s->pb);
 
     put_bits(&s->pb, 22, 0x20); /* PSC */
-    temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->time_base.num / //FIXME use timestamp
-                         (coded_frame_rate_base * (int64_t)s->avctx->time_base.den);
+    temp_ref= s->c.picture_number * (int64_t)coded_frame_rate * s->c.avctx->time_base.num / //FIXME use timestamp
+                         (coded_frame_rate_base * (int64_t)s->c.avctx->time_base.den);
     put_sbits(&s->pb, 8, temp_ref); /* TemporalReference */
 
     put_bits(&s->pb, 1, 1);     /* marker */
@@ -260,19 +260,19 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
     put_bits(&s->pb, 1, 0);     /* camera  off */
     put_bits(&s->pb, 1, 0);     /* freeze picture release off */
 
-    format = ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format), s->width, s->height);
-    if (!s->h263_plus) {
+    format = ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format), s->c.width, s->c.height);
+    if (!s->c.h263_plus) {
         /* H.263v1 */
         put_bits(&s->pb, 3, format);
-        put_bits(&s->pb, 1, (s->pict_type == AV_PICTURE_TYPE_P));
+        put_bits(&s->pb, 1, (s->c.pict_type == AV_PICTURE_TYPE_P));
         /* By now UMV IS DISABLED ON H.263v1, since the restrictions
         of H.263v1 UMV implies to check the predicted MV after
         calculation of the current MB to see if we're on the limits */
         put_bits(&s->pb, 1, 0);         /* Unrestricted Motion Vector: off */
         put_bits(&s->pb, 1, 0);         /* SAC: off */
-        put_bits(&s->pb, 1, s->obmc);   /* Advanced Prediction */
+        put_bits(&s->pb, 1, s->c.obmc);   /* Advanced Prediction */
         put_bits(&s->pb, 1, 0);         /* only I/P-frames, no PB-frame */
-        put_bits(&s->pb, 5, s->qscale);
+        put_bits(&s->pb, 5, s->c.qscale);
         put_bits(&s->pb, 1, 0);         /* Continuous Presence Multipoint mode: off */
     } else {
         int ufep=1;
@@ -287,24 +287,24 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
             put_bits(&s->pb, 3, format);
 
         put_bits(&s->pb,1, custom_pcf);
-        put_bits(&s->pb,1, s->umvplus); /* Unrestricted Motion Vector */
+        put_bits(&s->pb,1, s->c.umvplus); /* Unrestricted Motion Vector */
         put_bits(&s->pb,1,0); /* SAC: off */
-        put_bits(&s->pb,1,s->obmc); /* Advanced Prediction Mode */
-        put_bits(&s->pb,1,s->h263_aic); /* Advanced Intra Coding */
-        put_bits(&s->pb,1,s->loop_filter); /* Deblocking Filter */
-        put_bits(&s->pb,1,s->h263_slice_structured); /* Slice Structured */
+        put_bits(&s->pb,1,s->c.obmc); /* Advanced Prediction Mode */
+        put_bits(&s->pb,1,s->c.h263_aic); /* Advanced Intra Coding */
+        put_bits(&s->pb,1,s->c.loop_filter); /* Deblocking Filter */
+        put_bits(&s->pb,1,s->c.h263_slice_structured); /* Slice Structured */
         put_bits(&s->pb,1,0); /* Reference Picture Selection: off */
         put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */
-        put_bits(&s->pb,1,s->alt_inter_vlc); /* Alternative Inter VLC */
-        put_bits(&s->pb,1,s->modified_quant); /* Modified Quantization: */
+        put_bits(&s->pb,1,s->c.alt_inter_vlc); /* Alternative Inter VLC */
+        put_bits(&s->pb,1,s->c.modified_quant); /* Modified Quantization: */
         put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
         put_bits(&s->pb,3,0); /* Reserved */
 
-        put_bits(&s->pb, 3, s->pict_type == AV_PICTURE_TYPE_P);
+        put_bits(&s->pb, 3, s->c.pict_type == AV_PICTURE_TYPE_P);
 
         put_bits(&s->pb,1,0); /* Reference Picture Resampling: off */
         put_bits(&s->pb,1,0); /* Reduced-Resolution Update: off */
-        put_bits(&s->pb,1,s->no_rounding); /* Rounding Type */
+        put_bits(&s->pb,1,s->c.no_rounding); /* Rounding Type */
         put_bits(&s->pb,2,0); /* Reserved */
         put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
 
@@ -313,15 +313,15 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
 
         if (format == 8) {
             /* Custom Picture Format (CPFMT) */
-            unsigned aspect_ratio_info = ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio);
+            unsigned aspect_ratio_info = ff_h263_aspect_to_info(s->c.avctx->sample_aspect_ratio);
 
             put_bits(&s->pb,4, aspect_ratio_info);
-            put_bits(&s->pb,9,(s->width >> 2) - 1);
+            put_bits(&s->pb,9,(s->c.width >> 2) - 1);
             put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
-            put_bits(&s->pb,9,(s->height >> 2));
+            put_bits(&s->pb,9,(s->c.height >> 2));
             if (aspect_ratio_info == FF_ASPECT_EXTENDED){
-                put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num);
-                put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den);
+                put_bits(&s->pb, 8, s->c.avctx->sample_aspect_ratio.num);
+                put_bits(&s->pb, 8, s->c.avctx->sample_aspect_ratio.den);
             }
         }
         if (custom_pcf) {
@@ -333,22 +333,22 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
         }
 
         /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
-        if (s->umvplus)
+        if (s->c.umvplus)
 //            put_bits(&s->pb,1,1); /* Limited according tables of Annex D */
 //FIXME check actual requested range
             put_bits(&s->pb,2,1); /* unlimited */
-        if(s->h263_slice_structured)
+        if(s->c.h263_slice_structured)
             put_bits(&s->pb,2,0); /* no weird submodes */
 
-        put_bits(&s->pb, 5, s->qscale);
+        put_bits(&s->pb, 5, s->c.qscale);
     }
 
     put_bits(&s->pb, 1, 0);     /* no PEI */
 
-    if(s->h263_slice_structured){
+    if(s->c.h263_slice_structured){
         put_bits(&s->pb, 1, 1);
 
-        av_assert1(s->mb_x == 0 && s->mb_y == 0);
+        av_assert1(s->c.mb_x == 0 && s->c.mb_y == 0);
         ff_h263_encode_mba(s);
 
         put_bits(&s->pb, 1, 1);
@@ -360,50 +360,51 @@ static int h263_encode_picture_header(MPVMainEncContext *const m)
 /**
  * Encode a group of blocks header.
  */
-void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line)
+void ff_h263_encode_gob_header(MPVEncContext *const s, int mb_line)
 {
     put_bits(&s->pb, 17, 1); /* GBSC */
 
-    if(s->h263_slice_structured){
+    if(s->c.h263_slice_structured){
         put_bits(&s->pb, 1, 1);
 
         ff_h263_encode_mba(s);
 
-        if(s->mb_num > 1583)
+        if(s->c.mb_num > 1583)
             put_bits(&s->pb, 1, 1);
-        put_bits(&s->pb, 5, s->qscale); /* GQUANT */
+        put_bits(&s->pb, 5, s->c.qscale); /* GQUANT */
         put_bits(&s->pb, 1, 1);
-        put_bits(&s->pb, 2, s->pict_type == AV_PICTURE_TYPE_I); /* GFID */
+        put_bits(&s->pb, 2, s->c.pict_type == AV_PICTURE_TYPE_I); /* GFID */
     }else{
-        int gob_number= mb_line / s->gob_index;
+        int gob_number= mb_line / s->c.gob_index;
 
         put_bits(&s->pb, 5, gob_number); /* GN */
-        put_bits(&s->pb, 2, s->pict_type == AV_PICTURE_TYPE_I); /* GFID */
-        put_bits(&s->pb, 5, s->qscale); /* GQUANT */
+        put_bits(&s->pb, 2, s->c.pict_type == AV_PICTURE_TYPE_I); /* GFID */
+        put_bits(&s->pb, 5, s->c.qscale); /* GQUANT */
     }
 }
 
 /**
  * modify qscale so that encoding is actually possible in H.263 (limit difference to -2..2)
  */
-void ff_clean_h263_qscales(MpegEncContext *s){
-    int i;
-    int8_t * const qscale_table = s->cur_pic.qscale_table;
+void ff_clean_h263_qscales(MPVEncContext *const s)
+{
+    int8_t * const qscale_table = s->c.cur_pic.qscale_table;
 
-    for(i=1; i<s->mb_num; i++){
-        if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i-1] ] >2)
-            qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i-1] ]+2;
+    for (int i = 1; i < s->c.mb_num; i++) {
+        if (qscale_table[ s->c.mb_index2xy[i] ] - qscale_table[ s->c.mb_index2xy[i-1] ] > 2)
+            qscale_table[ s->c.mb_index2xy[i] ] = qscale_table[ s->c.mb_index2xy[i-1] ] + 2;
     }
-    for(i=s->mb_num-2; i>=0; i--){
-        if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i+1] ] >2)
-            qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i+1] ]+2;
+    for(int i = s->c.mb_num - 2; i >= 0; i--) {
+        if (qscale_table[ s->c.mb_index2xy[i] ] - qscale_table[ s->c.mb_index2xy[i+1] ] > 2)
+            qscale_table[ s->c.mb_index2xy[i] ] = qscale_table[ s->c.mb_index2xy[i+1] ] + 2;
     }
 
-    if(s->codec_id != AV_CODEC_ID_H263P){
-        for(i=1; i<s->mb_num; i++){
-            int mb_xy= s->mb_index2xy[i];
+    if (s->c.codec_id != AV_CODEC_ID_H263P) {
+        for (int i = 1; i < s->c.mb_num; i++) {
+            int mb_xy = s->c.mb_index2xy[i];
 
-            if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){
+            if (qscale_table[mb_xy] != qscale_table[s->c.mb_index2xy[i - 1]] &&
+                (s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_INTER4V)) {
                 s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER;
             }
         }
@@ -417,13 +418,13 @@ static const int dquant_code[5]= {1,0,9,2,3};
  * @param block the 8x8 block
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static void h263_encode_block(MpegEncContext * s, int16_t * block, int n)
+static void h263_encode_block(MPVEncContext *const s, int16_t block[], int n)
 {
     int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code;
     const RLTable *rl;
 
     rl = &ff_h263_rl_inter;
-    if (s->mb_intra && !s->h263_aic) {
+    if (s->c.mb_intra && !s->c.h263_aic) {
         /* DC coef */
         level = block[0];
         /* 255 cannot be represented, so we clamp */
@@ -443,19 +444,19 @@ static void h263_encode_block(MpegEncContext * s, int16_t * block, int n)
         i = 1;
     } else {
         i = 0;
-        if (s->h263_aic && s->mb_intra)
+        if (s->c.h263_aic && s->c.mb_intra)
             rl = &ff_rl_intra_aic;
 
-        if(s->alt_inter_vlc && !s->mb_intra){
+        if(s->c.alt_inter_vlc && !s->c.mb_intra){
             int aic_vlc_bits=0;
             int inter_vlc_bits=0;
             int wrong_pos=-1;
             int aic_code;
 
-            last_index = s->block_last_index[n];
+            last_index = s->c.block_last_index[n];
             last_non_zero = i - 1;
             for (; i <= last_index; i++) {
-                j = s->intra_scantable.permutated[i];
+                j = s->c.intra_scantable.permutated[i];
                 level = block[j];
                 if (level) {
                     run = i - last_non_zero - 1;
@@ -486,10 +487,10 @@ static void h263_encode_block(MpegEncContext * s, int16_t * block, int n)
     }
 
     /* AC coefs */
-    last_index = s->block_last_index[n];
+    last_index = s->c.block_last_index[n];
     last_non_zero = i - 1;
     for (; i <= last_index; i++) {
-        j = s->intra_scantable.permutated[i];
+        j = s->c.intra_scantable.permutated[i];
         level = block[j];
         if (level) {
             run = i - last_non_zero - 1;
@@ -503,7 +504,7 @@ static void h263_encode_block(MpegEncContext * s, int16_t * block, int n)
             code = get_rl_index(rl, last, run, level);
             put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
             if (code == rl->n) {
-              if(!CONFIG_FLV_ENCODER || s->h263_flv <= 1){
+              if(!CONFIG_FLV_ENCODER || s->c.h263_flv <= 1){
                 put_bits(&s->pb, 1, last);
                 put_bits(&s->pb, 6, run);
 
@@ -565,22 +566,22 @@ static void h263p_encode_umotion(PutBitContext *pb, int val)
     }
 }
 
-static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
+static int h263_pred_dc(MPVEncContext *const s, int n, int16_t **dc_val_ptr)
 {
     int x, y, wrap, a, c, pred_dc;
     int16_t *dc_val;
 
     /* find prediction */
     if (n < 4) {
-        x = 2 * s->mb_x + (n & 1);
-        y = 2 * s->mb_y + ((n & 2) >> 1);
-        wrap = s->b8_stride;
-        dc_val = s->dc_val[0];
+        x = 2 * s->c.mb_x + (n & 1);
+        y = 2 * s->c.mb_y + ((n & 2) >> 1);
+        wrap = s->c.b8_stride;
+        dc_val = s->c.dc_val[0];
     } else {
-        x = s->mb_x;
-        y = s->mb_y;
-        wrap = s->mb_stride;
-        dc_val = s->dc_val[n - 4 + 1];
+        x = s->c.mb_x;
+        y = s->c.mb_y;
+        wrap = s->c.mb_stride;
+        dc_val = s->c.dc_val[n - 4 + 1];
     }
     /* B C
      * A X
@@ -589,9 +590,9 @@ static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
     c = dc_val[(x) + (y - 1) * wrap];
 
     /* No prediction outside GOB boundary */
-    if (s->first_slice_line && n != 3) {
+    if (s->c.first_slice_line && n != 3) {
         if (n != 2) c = 1024;
-        if (n != 1 && s->mb_x == s->resync_mb_x) a = 1024;
+        if (n != 1 && s->c.mb_x == s->c.resync_mb_x) a = 1024;
     }
     /* just DC prediction */
     if (a != 1024 && c != 1024)
@@ -606,7 +607,7 @@ static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
     return pred_dc;
 }
 
-static void h263_encode_mb(MpegEncContext *const s,
+static void h263_encode_mb(MPVEncContext *const s,
                            int16_t block[][64],
                            int motion_x, int motion_y)
 {
@@ -614,13 +615,13 @@ static void h263_encode_mb(MpegEncContext *const s,
     int16_t pred_dc;
     int16_t rec_intradc[6];
     int16_t *dc_ptr[6];
-    const int interleaved_stats = s->avctx->flags & AV_CODEC_FLAG_PASS1;
+    const int interleaved_stats = s->c.avctx->flags & AV_CODEC_FLAG_PASS1;
 
-    if (!s->mb_intra) {
+    if (!s->c.mb_intra) {
         /* compute cbp */
         cbp= get_p_cbp(s, block, motion_x, motion_y);
 
-        if ((cbp | motion_x | motion_y | s->dquant | (s->mv_type - MV_TYPE_16X16)) == 0) {
+        if ((cbp | motion_x | motion_y | s->dquant | (s->c.mv_type - MV_TYPE_16X16)) == 0) {
             /* skip macroblock */
             put_bits(&s->pb, 1, 1);
             if(interleaved_stats){
@@ -634,10 +635,10 @@ static void h263_encode_mb(MpegEncContext *const s,
 
         cbpc = cbp & 3;
         cbpy = cbp >> 2;
-        if(s->alt_inter_vlc==0 || cbpc!=3)
+        if(s->c.alt_inter_vlc==0 || cbpc!=3)
             cbpy ^= 0xF;
         if(s->dquant) cbpc+= 8;
-        if(s->mv_type==MV_TYPE_16X16){
+        if(s->c.mv_type==MV_TYPE_16X16){
             put_bits(&s->pb,
                     ff_h263_inter_MCBPC_bits[cbpc],
                     ff_h263_inter_MCBPC_code[cbpc]);
@@ -651,9 +652,9 @@ static void h263_encode_mb(MpegEncContext *const s,
             }
 
             /* motion vectors: 16x16 mode */
-            ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+            ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
 
-            if (!s->umvplus) {
+            if (!s->c.umvplus) {
                 ff_h263_encode_motion_vector(s, motion_x - pred_x,
                                                 motion_y - pred_y, 1);
             }
@@ -678,11 +679,11 @@ static void h263_encode_mb(MpegEncContext *const s,
 
             for(i=0; i<4; i++){
                 /* motion vectors: 8x8 mode*/
-                ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+                ff_h263_pred_motion(&s->c, i, 0, &pred_x, &pred_y);
 
-                motion_x = s->cur_pic.motion_val[0][s->block_index[i]][0];
-                motion_y = s->cur_pic.motion_val[0][s->block_index[i]][1];
-                if (!s->umvplus) {
+                motion_x = s->c.cur_pic.motion_val[0][s->c.block_index[i]][0];
+                motion_y = s->c.cur_pic.motion_val[0][s->c.block_index[i]][1];
+                if (!s->c.umvplus) {
                     ff_h263_encode_motion_vector(s, motion_x - pred_x,
                                                     motion_y - pred_y, 1);
                 }
@@ -700,17 +701,14 @@ static void h263_encode_mb(MpegEncContext *const s,
             s->mv_bits+= get_bits_diff(s);
         }
     } else {
-        av_assert2(s->mb_intra);
+        av_assert2(s->c.mb_intra);
 
         cbp = 0;
-        if (s->h263_aic) {
+        if (s->c.h263_aic) {
             /* Predict DC */
             for(i=0; i<6; i++) {
                 int16_t level = block[i][0];
-                int scale;
-
-                if(i<4) scale= s->y_dc_scale;
-                else    scale= s->c_dc_scale;
+                int scale = i < 4 ? s->c.y_dc_scale : s->c.c_dc_scale;
 
                 pred_dc = h263_pred_dc(s, i, &dc_ptr[i]);
                 level -= pred_dc;
@@ -720,7 +718,7 @@ static void h263_encode_mb(MpegEncContext *const s,
                 else
                     level = (level - (scale>>1))/scale;
 
-                if(!s->modified_quant){
+                if (!s->c.modified_quant) {
                     if (level < -127)
                         level = -127;
                     else if (level > 127)
@@ -743,20 +741,20 @@ static void h263_encode_mb(MpegEncContext *const s,
                 /* Update AC/DC tables */
                 *dc_ptr[i] = rec_intradc[i];
                 /* AIC can change CBP */
-                if (s->block_last_index[i] > 0 ||
-                    (s->block_last_index[i] == 0 && level !=0))
+                if (s->c.block_last_index[i] > 0 ||
+                    (s->c.block_last_index[i] == 0 && level !=0))
                     cbp |= 1 << (5 - i);
             }
         }else{
             for(i=0; i<6; i++) {
                 /* compute cbp */
-                if (s->block_last_index[i] >= 1)
+                if (s->c.block_last_index[i] >= 1)
                     cbp |= 1 << (5 - i);
             }
         }
 
         cbpc = cbp & 3;
-        if (s->pict_type == AV_PICTURE_TYPE_I) {
+        if (s->c.pict_type == AV_PICTURE_TYPE_I) {
             if(s->dquant) cbpc+=4;
             put_bits(&s->pb,
                 ff_h263_intra_MCBPC_bits[cbpc],
@@ -768,7 +766,7 @@ static void h263_encode_mb(MpegEncContext *const s,
                 ff_h263_inter_MCBPC_bits[cbpc + 4],
                 ff_h263_inter_MCBPC_code[cbpc + 4]);
         }
-        if (s->h263_aic) {
+        if (s->c.h263_aic) {
             /* XXX: currently, we do not try to use ac prediction */
             put_bits(&s->pb, 1, 0);     /* no AC prediction */
         }
@@ -787,14 +785,12 @@ static void h263_encode_mb(MpegEncContext *const s,
         h263_encode_block(s, block[i], i);
 
         /* Update INTRADC for decoding */
-        if (s->h263_aic && s->mb_intra) {
+        if (s->c.h263_aic && s->c.mb_intra)
             block[i][0] = rec_intradc[i];
-
-        }
     }
 
     if(interleaved_stats){
-        if (!s->mb_intra) {
+        if (!s->c.mb_intra) {
             s->p_tex_bits+= get_bits_diff(s);
         }else{
             s->i_tex_bits+= get_bits_diff(s);
@@ -803,54 +799,54 @@ static void h263_encode_mb(MpegEncContext *const s,
     }
 }
 
-void ff_h263_update_mb(MpegEncContext *s)
+void ff_h263_update_mb(MPVEncContext *const s)
 {
-    const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
+    const int mb_xy = s->c.mb_y * s->c.mb_stride + s->c.mb_x;
 
-    if (s->cur_pic.mbskip_table)
-        s->cur_pic.mbskip_table[mb_xy] = s->mb_skipped;
+    if (s->c.cur_pic.mbskip_table)
+        s->c.cur_pic.mbskip_table[mb_xy] = s->c.mb_skipped;
 
-    if (s->mv_type == MV_TYPE_8X8)
-        s->cur_pic.mb_type[mb_xy] = MB_TYPE_FORWARD_MV | MB_TYPE_8x8;
-    else if(s->mb_intra)
-        s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA;
+    if (s->c.mv_type == MV_TYPE_8X8)
+        s->c.cur_pic.mb_type[mb_xy] = MB_TYPE_FORWARD_MV | MB_TYPE_8x8;
+    else if(s->c.mb_intra)
+        s->c.cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA;
     else
-        s->cur_pic.mb_type[mb_xy] = MB_TYPE_FORWARD_MV | MB_TYPE_16x16;
+        s->c.cur_pic.mb_type[mb_xy] = MB_TYPE_FORWARD_MV | MB_TYPE_16x16;
 
-    ff_h263_update_motion_val(s);
+    ff_h263_update_motion_val(&s->c);
 }
 
 av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    s->me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
+    s->c.me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
 
-    ff_h263dsp_init(&s->h263dsp);
+    ff_h263dsp_init(&s->c.h263dsp);
 
-    if (s->codec_id == AV_CODEC_ID_MPEG4)
+    if (s->c.codec_id == AV_CODEC_ID_MPEG4)
         return;
 
     s->intra_ac_vlc_length     =s->inter_ac_vlc_length     = uni_h263_inter_rl_len;
     s->intra_ac_vlc_last_length=s->inter_ac_vlc_last_length= uni_h263_inter_rl_len + 128*64;
-    if(s->h263_aic){
+    if (s->c.h263_aic) {
         s->intra_ac_vlc_length     = uni_h263_intra_aic_rl_len;
         s->intra_ac_vlc_last_length= uni_h263_intra_aic_rl_len + 128*64;
 
-        s->y_dc_scale_table =
-        s->c_dc_scale_table = ff_aic_dc_scale_table;
+        s->c.y_dc_scale_table =
+        s->c.c_dc_scale_table = ff_aic_dc_scale_table;
     }
     s->ac_esc_length= 7+1+6+8;
 
-    if (s->modified_quant)
-        s->chroma_qscale_table = ff_h263_chroma_qscale_table;
+    if (s->c.modified_quant)
+        s->c.chroma_qscale_table = ff_h263_chroma_qscale_table;
 
     // use fcodes >1 only for MPEG-4 & H.263 & H.263+ FIXME
-    switch(s->codec_id){
+    switch(s->c.codec_id){
     case AV_CODEC_ID_H263P:
-        if(s->umvplus)
+        if (s->c.umvplus)
             m->fcode_tab = umv_fcode_tab + MAX_MV;
-        if(s->modified_quant){
+        if (s->c.modified_quant) {
             s->min_qcoeff= -2047;
             s->max_qcoeff=  2047;
         }else{
@@ -861,7 +857,7 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
         // 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) {
+        if (s->c.h263_flv > 1) {
             s->min_qcoeff= -1023;
             s->max_qcoeff=  1023;
         } else {
@@ -880,14 +876,14 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
         s->encode_mb = h263_encode_mb;
 }
 
-void ff_h263_encode_mba(MpegEncContext *s)
+void ff_h263_encode_mba(MPVEncContext *const s)
 {
     int i, mb_pos;
 
     for(i=0; i<6; i++){
-        if(s->mb_num-1 <= ff_mba_max[i]) break;
+        if(s->c.mb_num-1 <= ff_mba_max[i]) break;
     }
-    mb_pos= s->mb_x + s->mb_width*s->mb_y;
+    mb_pos= s->c.mb_x + s->c.mb_width*s->c.mb_y;
     put_bits(&s->pb, ff_mba_length[i], mb_pos);
 }
 
@@ -895,7 +891,7 @@ void ff_h263_encode_mba(MpegEncContext *s)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption h263_options[] = {
     { "obmc",         "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
-    { "mb_info",      "emit macroblock info for RFC 2190 packetization, the parameter value is the maximum payload size", OFFSET(mb_info), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+    { "mb_info",      "emit macroblock info for RFC 2190 packetization, the parameter value is the maximum payload size", FF_MPV_OFFSET(mb_info), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
     FF_MPV_COMMON_OPTS
     FF_MPV_COMMON_MOTION_EST_OPTS
     { NULL },
diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c
index f3e2f2482e..09a830d15e 100644
--- a/libavcodec/me_cmp.c
+++ b/libavcodec/me_cmp.c
@@ -69,7 +69,7 @@ const uint32_t ff_square_tab[512] = {
     57600, 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, 62001, 62500, 63001, 63504, 64009, 64516, 65025,
 };
 
-static int sse4_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sse4_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                   ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -86,7 +86,7 @@ static int sse4_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
     return s;
 }
 
-static int sse8_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sse8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                   ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -107,7 +107,7 @@ static int sse8_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
     return s;
 }
 
-static int sse16_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sse16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                    ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -149,7 +149,7 @@ static int sum_abs_dctelem_c(const int16_t *block)
 #define avg2(a, b) (((a) + (b) + 1) >> 1)
 #define avg4(a, b, c, d) (((a) + (b) + (c) + (d) + 2) >> 2)
 
-static inline int pix_abs16_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static inline int pix_abs16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                               ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -177,7 +177,7 @@ static inline int pix_abs16_c(MpegEncContext *v, const uint8_t *pix1, const uint
     return s;
 }
 
-static inline int pix_median_abs16_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static inline int pix_median_abs16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                              ptrdiff_t stride, int h)
 {
     int s = 0, i, j;
@@ -216,7 +216,7 @@ static inline int pix_median_abs16_c(MpegEncContext *v, const uint8_t *pix1, con
     return s;
 }
 
-static int pix_abs16_x2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int pix_abs16_x2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -244,7 +244,7 @@ static int pix_abs16_x2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t
     return s;
 }
 
-static int pix_abs16_y2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int pix_abs16_y2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -274,7 +274,7 @@ static int pix_abs16_y2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t
     return s;
 }
 
-static int pix_abs16_xy2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int pix_abs16_xy2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                            ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -304,7 +304,7 @@ static int pix_abs16_xy2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t
     return s;
 }
 
-static inline int pix_abs8_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static inline int pix_abs8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                              ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -324,7 +324,7 @@ static inline int pix_abs8_c(MpegEncContext *v, const uint8_t *pix1, const uint8
     return s;
 }
 
-static inline int pix_median_abs8_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static inline int pix_median_abs8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                              ptrdiff_t stride, int h)
 {
     int s = 0, i, j;
@@ -355,7 +355,7 @@ static inline int pix_median_abs8_c(MpegEncContext *v, const uint8_t *pix1, cons
     return s;
 }
 
-static int pix_abs8_x2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int pix_abs8_x2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -375,7 +375,7 @@ static int pix_abs8_x2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *
     return s;
 }
 
-static int pix_abs8_y2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int pix_abs8_y2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -397,7 +397,7 @@ static int pix_abs8_y2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *
     return s;
 }
 
-static int pix_abs8_xy2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int pix_abs8_xy2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h)
 {
     int s = 0, i;
@@ -419,7 +419,7 @@ static int pix_abs8_xy2_c(MpegEncContext *v, const uint8_t *pix1, const uint8_t
     return s;
 }
 
-static int nsse16_c(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+static int nsse16_c(MPVEncContext *const c, const uint8_t *s1, const uint8_t *s2,
                     ptrdiff_t stride, int h)
 {
     int score1 = 0, score2 = 0, x, y;
@@ -439,12 +439,12 @@ static int nsse16_c(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
     }
 
     if (c)
-        return score1 + FFABS(score2) * c->avctx->nsse_weight;
+        return score1 + FFABS(score2) * c->c.avctx->nsse_weight;
     else
         return score1 + FFABS(score2) * 8;
 }
 
-static int nsse8_c(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+static int nsse8_c(MPVEncContext *const c, const uint8_t *s1, const uint8_t *s2,
                    ptrdiff_t stride, int h)
 {
     int score1 = 0, score2 = 0, x, y;
@@ -464,12 +464,12 @@ static int nsse8_c(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
     }
 
     if (c)
-        return score1 + FFABS(score2) * c->avctx->nsse_weight;
+        return score1 + FFABS(score2) * c->c.avctx->nsse_weight;
     else
         return score1 + FFABS(score2) * 8;
 }
 
-static int zero_cmp(MpegEncContext *s, const uint8_t *a, const uint8_t *b,
+static int zero_cmp(MPVEncContext *s, const uint8_t *a, const uint8_t *b,
                     ptrdiff_t stride, int h)
 {
     return 0;
@@ -546,7 +546,7 @@ av_cold int ff_set_cmp(const MECmpContext *c, me_cmp_func *cmp, int type, int mp
 
 #define BUTTERFLYA(x, y) (FFABS((x) + (y)) + FFABS((x) - (y)))
 
-static int hadamard8_diff8x8_c(MpegEncContext *s, const uint8_t *dst,
+static int hadamard8_diff8x8_c(MPVEncContext *unused, const uint8_t *dst,
                                const uint8_t *src, ptrdiff_t stride, int h)
 {
     int i, temp[64], sum = 0;
@@ -596,7 +596,7 @@ static int hadamard8_diff8x8_c(MpegEncContext *s, const uint8_t *dst,
     return sum;
 }
 
-static int hadamard8_intra8x8_c(MpegEncContext *s, const uint8_t *src,
+static int hadamard8_intra8x8_c(MPVEncContext *unused, const uint8_t *src,
                                 const uint8_t *dummy, ptrdiff_t stride, int h)
 {
     int i, temp[64], sum = 0;
@@ -646,7 +646,7 @@ static int hadamard8_intra8x8_c(MpegEncContext *s, const uint8_t *src,
     return sum;
 }
 
-static int dct_sad8x8_c(MpegEncContext *s, const uint8_t *src1,
+static int dct_sad8x8_c(MPVEncContext *const s, const uint8_t *src1,
                         const uint8_t *src2, ptrdiff_t stride, int h)
 {
     LOCAL_ALIGNED_16(int16_t, temp, [64]);
@@ -685,7 +685,7 @@ static int dct_sad8x8_c(MpegEncContext *s, const uint8_t *src1,
         DST(7, (a4 >> 2) - a7);                         \
     }
 
-static int dct264_sad8x8_c(MpegEncContext *s, const uint8_t *src1,
+static int dct264_sad8x8_c(MPVEncContext *const s, const uint8_t *src1,
                            const uint8_t *src2, ptrdiff_t stride, int h)
 {
     int16_t dct[8][8];
@@ -710,7 +710,7 @@ static int dct264_sad8x8_c(MpegEncContext *s, const uint8_t *src1,
 }
 #endif
 
-static int dct_max8x8_c(MpegEncContext *s, const uint8_t *src1,
+static int dct_max8x8_c(MPVEncContext *const s, const uint8_t *src1,
                         const uint8_t *src2, ptrdiff_t stride, int h)
 {
     LOCAL_ALIGNED_16(int16_t, temp, [64]);
@@ -725,22 +725,22 @@ static int dct_max8x8_c(MpegEncContext *s, const uint8_t *src1,
     return sum;
 }
 
-static int quant_psnr8x8_c(MpegEncContext *s, const uint8_t *src1,
+static int quant_psnr8x8_c(MPVEncContext *const s, const uint8_t *src1,
                            const uint8_t *src2, ptrdiff_t stride, int h)
 {
     LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]);
     int16_t *const bak = temp + 64;
     int sum = 0, i;
 
-    s->mb_intra = 0;
+    s->c.mb_intra = 0;
 
     s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
 
     memcpy(bak, temp, 64 * sizeof(int16_t));
 
-    s->block_last_index[0 /* FIXME */] =
-        s->dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
-    s->dct_unquantize_inter(s, temp, 0, s->qscale);
+    s->c.block_last_index[0 /* FIXME */] =
+        s->dct_quantize(s, temp, 0 /* FIXME */, s->c.qscale, &i);
+    s->c.dct_unquantize_inter(&s->c, temp, 0, s->c.qscale);
     ff_simple_idct_int16_8bit(temp); // FIXME
 
     for (i = 0; i < 64; i++)
@@ -749,10 +749,10 @@ static int quant_psnr8x8_c(MpegEncContext *s, const uint8_t *src1,
     return sum;
 }
 
-static int rd8x8_c(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2,
+static int rd8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2,
                    ptrdiff_t stride, int h)
 {
-    const uint8_t *scantable = s->intra_scantable.permutated;
+    const uint8_t *scantable = s->c.intra_scantable.permutated;
     LOCAL_ALIGNED_16(int16_t, temp, [64]);
     LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]);
     LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]);
@@ -765,13 +765,13 @@ static int rd8x8_c(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2,
 
     s->pdsp.diff_pixels(temp, lsrc1, lsrc2, 8);
 
-    s->block_last_index[0 /* FIXME */] =
+    s->c.block_last_index[0 /* FIXME */] =
     last                               =
-        s->dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
+        s->dct_quantize(s, temp, 0 /* FIXME */, s->c.qscale, &i);
 
     bits = 0;
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         start_i     = 1;
         length      = s->intra_ac_vlc_length;
         last_length = s->intra_ac_vlc_last_length;
@@ -811,23 +811,23 @@ static int rd8x8_c(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2,
     }
 
     if (last >= 0) {
-        if (s->mb_intra)
-            s->dct_unquantize_intra(s, temp, 0, s->qscale);
+        if (s->c.mb_intra)
+            s->c.dct_unquantize_intra(&s->c, temp, 0, s->c.qscale);
         else
-            s->dct_unquantize_inter(s, temp, 0, s->qscale);
+            s->c.dct_unquantize_inter(&s->c, temp, 0, s->c.qscale);
     }
 
-    s->idsp.idct_add(lsrc2, 8, temp);
+    s->c.idsp.idct_add(lsrc2, 8, temp);
 
     distortion = s->sse_cmp[1](NULL, lsrc2, lsrc1, 8, 8);
 
-    return distortion + ((bits * s->qscale * s->qscale * 109 + 64) >> 7);
+    return distortion + ((bits * s->c.qscale * s->c.qscale * 109 + 64) >> 7);
 }
 
-static int bit8x8_c(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2,
+static int bit8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2,
                     ptrdiff_t stride, int h)
 {
-    const uint8_t *scantable = s->intra_scantable.permutated;
+    const uint8_t *scantable = s->c.intra_scantable.permutated;
     LOCAL_ALIGNED_16(int16_t, temp, [64]);
     int i, last, run, bits, level, start_i;
     const int esc_length = s->ac_esc_length;
@@ -835,13 +835,13 @@ static int bit8x8_c(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2,
 
     s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
 
-    s->block_last_index[0 /* FIXME */] =
+    s->c.block_last_index[0 /* FIXME */] =
     last                               =
-        s->dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
+        s->dct_quantize(s, temp, 0 /* FIXME */, s->c.qscale, &i);
 
     bits = 0;
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         start_i     = 1;
         length      = s->intra_ac_vlc_length;
         last_length = s->intra_ac_vlc_last_length;
@@ -884,7 +884,7 @@ static int bit8x8_c(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2,
 }
 
 #define VSAD_INTRA(size)                                                \
-static int vsad_intra ## size ## _c(MpegEncContext *c,                  \
+static int vsad_intra ## size ## _c(MPVEncContext *unused,              \
                                     const uint8_t *s, const uint8_t *dummy, \
                                     ptrdiff_t stride, int h)            \
 {                                                                       \
@@ -906,7 +906,7 @@ VSAD_INTRA(8)
 VSAD_INTRA(16)
 
 #define VSAD(size)                                                             \
-static int vsad ## size ## _c(MpegEncContext *c,                               \
+static int vsad ## size ## _c(MPVEncContext *unused,                           \
                               const uint8_t *s1, const uint8_t *s2,            \
                               ptrdiff_t stride, int h)                               \
 {                                                                              \
@@ -926,7 +926,7 @@ VSAD(16)
 
 #define SQ(a) ((a) * (a))
 #define VSSE_INTRA(size)                                                \
-static int vsse_intra ## size ## _c(MpegEncContext *c,                  \
+static int vsse_intra ## size ## _c(MPVEncContext *unused,              \
                                     const uint8_t *s, const uint8_t *dummy, \
                                     ptrdiff_t stride, int h)            \
 {                                                                       \
@@ -948,8 +948,8 @@ VSSE_INTRA(8)
 VSSE_INTRA(16)
 
 #define VSSE(size)                                                             \
-static int vsse ## size ## _c(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2, \
-                              ptrdiff_t stride, int h)                         \
+static int vsse ## size ## _c(MPVEncContext *unused, const uint8_t *s1,        \
+                              const uint8_t *s2, ptrdiff_t stride, int h)      \
 {                                                                              \
     int score = 0, x, y;                                                       \
                                                                                \
@@ -966,8 +966,8 @@ VSSE(8)
 VSSE(16)
 
 #define WRAPPER8_16_SQ(name8, name16)                                   \
-static int name16(MpegEncContext *s, const uint8_t *dst, const uint8_t *src, \
-                  ptrdiff_t stride, int h)                              \
+static int name16(MPVEncContext *const s, const uint8_t *dst,           \
+                  const uint8_t *src, ptrdiff_t stride, int h)          \
 {                                                                       \
     int score = 0;                                                      \
                                                                         \
diff --git a/libavcodec/me_cmp.h b/libavcodec/me_cmp.h
index 0857ed03e2..f1dbcd5146 100644
--- a/libavcodec/me_cmp.h
+++ b/libavcodec/me_cmp.h
@@ -41,13 +41,13 @@ EXTERN const uint32_t ff_square_tab[512];
  * !future video codecs might need functions with less strict alignment
  */
 
-struct MpegEncContext;
+typedef struct MPVEncContext MPVEncContext;
 /* Motion estimation:
  * h is limited to { width / 2, width, 2 * width },
  * but never larger than 16 and never smaller than 2.
  * Although currently h < 4 is not used as functions with
  * width < 8 are neither used nor implemented. */
-typedef int (*me_cmp_func)(struct MpegEncContext *c,
+typedef int (*me_cmp_func)(MPVEncContext *c,
                            const uint8_t *blk1 /* align width (8 or 16) */,
                            const uint8_t *blk2 /* align 1 */, ptrdiff_t stride,
                            int h);
@@ -86,7 +86,7 @@ void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx);
  * Fill the function pointer array cmp[6] with me_cmp_funcs from
  * c based upon type. If mpvenc is not set, an error is returned
  * if the type of comparison functions requires an initialized
- * MpegEncContext.
+ * MPVEncContext.
  */
 int ff_set_cmp(const MECmpContext *c, me_cmp_func *cmp,
                int type, int mpvenc);
diff --git a/libavcodec/mips/me_cmp_mips.h b/libavcodec/mips/me_cmp_mips.h
index 72b7de70b4..7e2c926d3a 100644
--- a/libavcodec/mips/me_cmp_mips.h
+++ b/libavcodec/mips/me_cmp_mips.h
@@ -21,38 +21,38 @@
 #ifndef AVCODEC_MIPS_ME_CMP_MIPS_H
 #define AVCODEC_MIPS_ME_CMP_MIPS_H
 
-#include "../mpegvideo.h"
+#include "../mpegvideoenc.h"
 #include "libavcodec/bit_depth_template.c"
 
-int ff_hadamard8_diff8x8_msa(MpegEncContext *s, const uint8_t *dst, const uint8_t *src,
+int ff_hadamard8_diff8x8_msa(MPVEncContext *s, const uint8_t *dst, const uint8_t *src,
                              ptrdiff_t stride, int h);
-int ff_hadamard8_intra8x8_msa(MpegEncContext *s, const uint8_t *dst, const uint8_t *src,
+int ff_hadamard8_intra8x8_msa(MPVEncContext *s, const uint8_t *dst, const uint8_t *src,
                               ptrdiff_t stride, int h);
-int ff_hadamard8_diff16_msa(MpegEncContext *s, const uint8_t *dst, const uint8_t *src,
+int ff_hadamard8_diff16_msa(MPVEncContext *s, const uint8_t *dst, const uint8_t *src,
                             ptrdiff_t stride, int h);
-int ff_hadamard8_intra16_msa(MpegEncContext *s, const uint8_t *dst, const uint8_t *src,
+int ff_hadamard8_intra16_msa(MPVEncContext *s, const uint8_t *dst, const uint8_t *src,
                              ptrdiff_t stride, int h);
-int ff_pix_abs16_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                      ptrdiff_t stride, int h);
-int ff_pix_abs16_x2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_x2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h);
-int ff_pix_abs16_y2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_y2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h);
-int ff_pix_abs16_xy2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_xy2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_pix_abs8_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                     ptrdiff_t stride, int h);
-int ff_pix_abs8_x2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_x2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h);
-int ff_pix_abs8_y2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_y2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h);
-int ff_pix_abs8_xy2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_xy2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h);
-int ff_sse16_msa(MpegEncContext *v, const uint8_t *pu8Src, const uint8_t *pu8Ref,
+int ff_sse16_msa(MPVEncContext *v, const uint8_t *pu8Src, const uint8_t *pu8Ref,
                  ptrdiff_t stride, int i32Height);
-int ff_sse8_msa(MpegEncContext *v, const uint8_t *pu8Src, const uint8_t *pu8Ref,
+int ff_sse8_msa(MPVEncContext *v, const uint8_t *pu8Src, const uint8_t *pu8Ref,
                 ptrdiff_t stride, int i32Height);
-int ff_sse4_msa(MpegEncContext *v, const uint8_t *pu8Src, const uint8_t *pu8Ref,
+int ff_sse4_msa(MPVEncContext *v, const uint8_t *pu8Src, const uint8_t *pu8Ref,
                 ptrdiff_t stride, int i32Height);
 void ff_add_pixels8_msa(const uint8_t *restrict pixels, int16_t *block,
                         ptrdiff_t stride);
diff --git a/libavcodec/mips/me_cmp_msa.c b/libavcodec/mips/me_cmp_msa.c
index 351494161f..8ecc6352e6 100644
--- a/libavcodec/mips/me_cmp_msa.c
+++ b/libavcodec/mips/me_cmp_msa.c
@@ -732,79 +732,79 @@ static int32_t hadamard_intra_8x8_msa(const uint8_t *src, int32_t src_stride,
     return sum_res;
 }
 
-int ff_pix_abs16_msa(MpegEncContext *v, const uint8_t *src, const uint8_t *ref,
+int ff_pix_abs16_msa(MPVEncContext *v, const uint8_t *src, const uint8_t *ref,
                      ptrdiff_t stride, int height)
 {
     return sad_16width_msa(src, stride, ref, stride, height);
 }
 
-int ff_pix_abs8_msa(MpegEncContext *v, const uint8_t *src, const uint8_t *ref,
+int ff_pix_abs8_msa(MPVEncContext *v, const uint8_t *src, const uint8_t *ref,
                     ptrdiff_t stride, int height)
 {
     return sad_8width_msa(src, stride, ref, stride, height);
 }
 
-int ff_pix_abs16_x2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_x2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h)
 {
     return sad_horiz_bilinear_filter_16width_msa(pix1, stride, pix2, stride, h);
 }
 
-int ff_pix_abs16_y2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_y2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h)
 {
     return sad_vert_bilinear_filter_16width_msa(pix1, stride, pix2, stride, h);
 }
 
-int ff_pix_abs16_xy2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_xy2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h)
 {
     return sad_hv_bilinear_filter_16width_msa(pix1, stride, pix2, stride, h);
 }
 
-int ff_pix_abs8_x2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_x2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h)
 {
     return sad_horiz_bilinear_filter_8width_msa(pix1, stride, pix2, stride, h);
 }
 
-int ff_pix_abs8_y2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_y2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h)
 {
     return sad_vert_bilinear_filter_8width_msa(pix1, stride, pix2, stride, h);
 }
 
-int ff_pix_abs8_xy2_msa(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_xy2_msa(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h)
 {
     return sad_hv_bilinear_filter_8width_msa(pix1, stride, pix2, stride, h);
 }
 
-int ff_sse16_msa(MpegEncContext *v, const uint8_t *src, const uint8_t *ref,
+int ff_sse16_msa(MPVEncContext *v, const uint8_t *src, const uint8_t *ref,
                  ptrdiff_t stride, int height)
 {
     return sse_16width_msa(src, stride, ref, stride, height);
 }
 
-int ff_sse8_msa(MpegEncContext *v, const uint8_t *src, const uint8_t *ref,
+int ff_sse8_msa(MPVEncContext *v, const uint8_t *src, const uint8_t *ref,
                 ptrdiff_t stride, int height)
 {
     return sse_8width_msa(src, stride, ref, stride, height);
 }
 
-int ff_sse4_msa(MpegEncContext *v, const uint8_t *src, const uint8_t *ref,
+int ff_sse4_msa(MPVEncContext *v, const uint8_t *src, const uint8_t *ref,
                 ptrdiff_t stride, int height)
 {
     return sse_4width_msa(src, stride, ref, stride, height);
 }
 
-int ff_hadamard8_diff8x8_msa(MpegEncContext *s, const uint8_t *dst, const uint8_t *src,
+int ff_hadamard8_diff8x8_msa(MPVEncContext *s, const uint8_t *dst, const uint8_t *src,
                              ptrdiff_t stride, int h)
 {
     return hadamard_diff_8x8_msa(src, stride, dst, stride);
 }
 
-int ff_hadamard8_intra8x8_msa(MpegEncContext *s, const uint8_t *src, const uint8_t *dummy,
+int ff_hadamard8_intra8x8_msa(MPVEncContext *s, const uint8_t *src, const uint8_t *dummy,
                               ptrdiff_t stride, int h)
 {
     return hadamard_intra_8x8_msa(src, stride, dummy, stride);
@@ -812,7 +812,7 @@ int ff_hadamard8_intra8x8_msa(MpegEncContext *s, const uint8_t *src, const uint8
 
 /* Hadamard Transform functions */
 #define WRAPPER8_16_SQ(name8, name16)                      \
-int name16(MpegEncContext *s, const uint8_t *dst, const uint8_t *src,  \
+int name16(MPVEncContext *s, const uint8_t *dst, const uint8_t *src,  \
            ptrdiff_t stride, int h)                        \
 {                                                          \
     int score = 0;                                         \
diff --git a/libavcodec/mips/mpegvideo_mips.h b/libavcodec/mips/mpegvideo_mips.h
index 760d7b3295..72ffed6985 100644
--- a/libavcodec/mips/mpegvideo_mips.h
+++ b/libavcodec/mips/mpegvideo_mips.h
@@ -22,6 +22,7 @@
 #define AVCODEC_MIPS_MPEGVIDEO_MIPS_H
 
 #include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideoenc.h"
 
 void ff_dct_unquantize_h263_intra_mmi(MpegEncContext *s, int16_t *block,
         int n, int qscale);
@@ -33,6 +34,6 @@ void ff_dct_unquantize_mpeg1_inter_mmi(MpegEncContext *s, int16_t *block,
         int n, int qscale);
 void ff_dct_unquantize_mpeg2_intra_mmi(MpegEncContext *s, int16_t *block,
         int n, int qscale);
-void ff_denoise_dct_mmi(MpegEncContext *s, int16_t *block);
+void ff_denoise_dct_mmi(MPVEncContext *s, int16_t *block);
 
 #endif /* AVCODEC_MIPS_MPEGVIDEO_MIPS_H */
diff --git a/libavcodec/mips/mpegvideoenc_init_mips.c b/libavcodec/mips/mpegvideoenc_init_mips.c
index 5ef0664937..7831973eb8 100644
--- a/libavcodec/mips/mpegvideoenc_init_mips.c
+++ b/libavcodec/mips/mpegvideoenc_init_mips.c
@@ -23,7 +23,7 @@
 #include "libavcodec/mpegvideoenc.h"
 #include "mpegvideo_mips.h"
 
-av_cold void ff_mpvenc_dct_init_mips(MpegEncContext *s)
+av_cold void ff_mpvenc_dct_init_mips(MPVEncContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/mips/mpegvideoenc_mmi.c b/libavcodec/mips/mpegvideoenc_mmi.c
index 65da155e9f..085be3b0ec 100644
--- a/libavcodec/mips/mpegvideoenc_mmi.c
+++ b/libavcodec/mips/mpegvideoenc_mmi.c
@@ -25,9 +25,9 @@
 #include "mpegvideo_mips.h"
 #include "libavutil/mips/mmiutils.h"
 
-void ff_denoise_dct_mmi(MpegEncContext *s, int16_t *block)
+void ff_denoise_dct_mmi(MPVEncContext *s, int16_t *block)
 {
-    const int intra = s->mb_intra;
+    const int intra = s->c.mb_intra;
     int *sum = s->dct_error_sum[intra];
     uint16_t *offset = s->dct_offset[intra];
     double ftmp[8];
diff --git a/libavcodec/mips/mpegvideoencdsp_init_mips.c b/libavcodec/mips/mpegvideoencdsp_init_mips.c
index 3efbeec34a..24a17b91db 100644
--- a/libavcodec/mips/mpegvideoencdsp_init_mips.c
+++ b/libavcodec/mips/mpegvideoencdsp_init_mips.c
@@ -21,6 +21,7 @@
 #include "libavutil/attributes.h"
 #include "libavutil/mips/cpu.h"
 #include "libavcodec/bit_depth_template.c"
+#include "libavcodec/mpegvideoencdsp.h"
 #include "h263dsp_mips.h"
 
 av_cold void ff_mpegvideoencdsp_init_mips(MpegvideoEncDSPContext *c,
diff --git a/libavcodec/mips/pixblockdsp_init_mips.c b/libavcodec/mips/pixblockdsp_init_mips.c
index 2e2d70953b..00f189d558 100644
--- a/libavcodec/mips/pixblockdsp_init_mips.c
+++ b/libavcodec/mips/pixblockdsp_init_mips.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/mips/cpu.h"
+#include "libavcodec/pixblockdsp.h"
 #include "pixblockdsp_mips.h"
 
 void ff_pixblockdsp_init_mips(PixblockDSPContext *c, AVCodecContext *avctx,
diff --git a/libavcodec/mips/pixblockdsp_mips.h b/libavcodec/mips/pixblockdsp_mips.h
index 7fd137cd09..fc387ea427 100644
--- a/libavcodec/mips/pixblockdsp_mips.h
+++ b/libavcodec/mips/pixblockdsp_mips.h
@@ -22,7 +22,8 @@
 #ifndef AVCODEC_MIPS_PIXBLOCKDSP_MIPS_H
 #define AVCODEC_MIPS_PIXBLOCKDSP_MIPS_H
 
-#include "../mpegvideo.h"
+#include <stdint.h>
+#include <stddef.h>
 
 void ff_diff_pixels_msa(int16_t *restrict block, const uint8_t *src1,
                         const uint8_t *src2, ptrdiff_t stride);
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index a6f202da0a..668065011c 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -61,8 +61,8 @@ typedef struct MJpegHuffmanCode {
 
 /* The following is the private context of MJPEG/AMV decoder.
  * Note that when using slice threading only the main thread's
- * MpegEncContext is followed by a MjpegContext; the other threads
- * can access this shared context via MpegEncContext.mjpeg. */
+ * MPVEncContext is followed by a MjpegContext; the other threads
+ * can access this shared context via MPVEncContext.mjpeg. */
 typedef struct MJPEGEncContext {
     MPVMainEncContext mpeg;
     MJpegContext   mjpeg;
@@ -92,22 +92,22 @@ static av_cold void init_uni_ac_vlc(const uint8_t huff_size_ac[256],
     }
 }
 
-static void mjpeg_encode_picture_header(MpegEncContext *s)
+static void mjpeg_encode_picture_header(MPVEncContext *const s)
 {
-    ff_mjpeg_encode_picture_header(s->avctx, &s->pb, s->cur_pic.ptr->f, s->mjpeg_ctx,
-                                   s->intra_scantable.permutated, 0,
-                                   s->intra_matrix, s->chroma_intra_matrix,
-                                   s->slice_context_count > 1);
+    ff_mjpeg_encode_picture_header(s->c.avctx, &s->pb, s->c.cur_pic.ptr->f, s->mjpeg_ctx,
+                                   s->c.intra_scantable.permutated, 0,
+                                   s->c.intra_matrix, s->c.chroma_intra_matrix,
+                                   s->c.slice_context_count > 1);
 
     s->esc_pos = put_bytes_count(&s->pb, 0);
-    for (int i = 1; i < s->slice_context_count; i++)
-        s->thread_context[i]->esc_pos = 0;
+    for (int i = 1; i < s->c.slice_context_count; i++)
+        s->c.enc_contexts[i]->esc_pos = 0;
 }
 
 static int mjpeg_amv_encode_picture_header(MPVMainEncContext *const m)
 {
     MJPEGEncContext *const m2 = (MJPEGEncContext*)m;
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *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 || m2->mjpeg.huffman != HUFFMAN_TABLE_OPTIMAL)
@@ -120,11 +120,11 @@ static int mjpeg_amv_encode_picture_header(MPVMainEncContext *const m)
 /**
  * Encodes and outputs the entire frame in the JPEG format.
  *
- * @param s The MpegEncContext.
+ * @param main The MPVMainEncContext.
  */
 static void mjpeg_encode_picture_frame(MPVMainEncContext *const main)
 {
-    MpegEncContext *const s = &main->s;
+    MPVEncContext *const s = &main->s;
     int nbits, code, table_id;
     MJpegContext *m = s->mjpeg_ctx;
     uint8_t  *huff_size[4] = { m->huff_size_dc_luminance,
@@ -232,14 +232,14 @@ static void mjpeg_build_optimal_huffman(MJpegContext *m)
  *
  * Header + values + stuffing.
  *
- * @param s The MpegEncContext.
+ * @param s The MPVEncContext.
  * @return int Error code, 0 if successful.
  */
-int ff_mjpeg_encode_stuffing(MpegEncContext *s)
+int ff_mjpeg_encode_stuffing(MPVEncContext *const s)
 {
     MJpegContext *const m = s->mjpeg_ctx;
     PutBitContext *pbc = &s->pb;
-    int mb_y = s->mb_y - !s->mb_x;
+    int mb_y = s->c.mb_y - !s->c.mb_x;
     int ret;
 
 #if CONFIG_MJPEG_ENCODER
@@ -267,19 +267,19 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s)
     ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100,
                                             put_bits_count(&s->pb) / 4 + 1000);
     if (ret < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "Buffer reallocation failed\n");
+        av_log(s->c.avctx, AV_LOG_ERROR, "Buffer reallocation failed\n");
         goto fail;
     }
 
     ff_mjpeg_escape_FF(pbc, s->esc_pos);
 
-    if (s->slice_context_count > 1 && mb_y < s->mb_height - 1)
+    if (s->c.slice_context_count > 1 && mb_y < s->c.mb_height - 1)
         put_marker(pbc, RST0 + (mb_y&7));
     s->esc_pos = put_bytes_count(pbc, 0);
 
 fail:
     for (int i = 0; i < 3; i++)
-        s->last_dc[i] = 128 << s->intra_dc_precision;
+        s->c.last_dc[i] = 128 << s->c.intra_dc_precision;
 
     return ret;
 }
@@ -287,14 +287,14 @@ fail:
 static int alloc_huffman(MJPEGEncContext *const m2)
 {
     MJpegContext   *const m = &m2->mjpeg;
-    MpegEncContext *const s = &m2->mpeg.s;
+    MPVEncContext *const s = &m2->mpeg.s;
     static const char blocks_per_mb[] = {
         [CHROMA_420] = 6, [CHROMA_422] = 8, [CHROMA_444] = 12
     };
     size_t num_blocks, num_codes;
 
     // Make sure we have enough space to hold this frame.
-    num_blocks = s->mb_num * blocks_per_mb[s->chroma_format];
+    num_blocks = s->c.mb_num * blocks_per_mb[s->c.chroma_format];
     num_codes = num_blocks * 64;
 
     m->huff_buffer = av_malloc_array(num_codes,
@@ -358,11 +358,11 @@ static void mjpeg_encode_coef(MJpegContext *s, uint8_t table_id, int val, int ru
 /**
  * Add the block's data into the JPEG buffer.
  *
- * @param s The MpegEncContext that contains the JPEG buffer.
+ * @param s The MPVEncContext that contains the JPEG buffer.
  * @param block The block.
  * @param n The block's index or number.
  */
-static void record_block(MpegEncContext *s, int16_t *block, int n)
+static void record_block(MPVEncContext *const s, int16_t block[], int n)
 {
     int i, j, table_id;
     int component, dc, last_index, val, run;
@@ -372,20 +372,20 @@ static void record_block(MpegEncContext *s, int16_t *block, int n)
     component = (n <= 3 ? 0 : (n&1) + 1);
     table_id = (n <= 3 ? 0 : 1);
     dc = block[0]; /* overflow is impossible */
-    val = dc - s->last_dc[component];
+    val = dc - s->c.last_dc[component];
 
     mjpeg_encode_coef(m, table_id, val, 0);
 
-    s->last_dc[component] = dc;
+    s->c.last_dc[component] = dc;
 
     /* AC coefs */
 
     run = 0;
-    last_index = s->block_last_index[n];
+    last_index = s->c.block_last_index[n];
     table_id |= 2;
 
     for(i=1;i<=last_index;i++) {
-        j = s->intra_scantable.permutated[i];
+        j = s->c.intra_scantable.permutated[i];
         val = block[j];
 
         if (val == 0) {
@@ -405,7 +405,7 @@ static void record_block(MpegEncContext *s, int16_t *block, int n)
         mjpeg_encode_code(m, table_id, 0);
 }
 
-static void encode_block(MpegEncContext *s, int16_t *block, int n)
+static void encode_block(MPVEncContext *const s, int16_t block[], int n)
 {
     int mant, nbits, code, i, j;
     int component, dc, run, last_index, val;
@@ -416,7 +416,7 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
     /* DC coef */
     component = (n <= 3 ? 0 : (n&1) + 1);
     dc = block[0]; /* overflow is impossible */
-    val = dc - s->last_dc[component];
+    val = dc - s->c.last_dc[component];
     if (n < 4) {
         ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
         huff_size_ac = m->huff_size_ac_luminance;
@@ -426,14 +426,14 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
         huff_size_ac = m->huff_size_ac_chrominance;
         huff_code_ac = m->huff_code_ac_chrominance;
     }
-    s->last_dc[component] = dc;
+    s->c.last_dc[component] = dc;
 
     /* AC coefs */
 
     run = 0;
-    last_index = s->block_last_index[n];
+    last_index = s->c.block_last_index[n];
     for(i=1;i<=last_index;i++) {
-        j = s->intra_scantable.permutated[i];
+        j = s->c.intra_scantable.permutated[i];
         val = block[j];
         if (val == 0) {
             run++;
@@ -463,10 +463,10 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
         put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
 }
 
-static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
+static void mjpeg_record_mb(MPVEncContext *const s, int16_t block[][64],
                             int unused_x, int unused_y)
 {
-    if (s->chroma_format == CHROMA_444) {
+    if (s->c.chroma_format == CHROMA_444) {
         record_block(s, block[0], 0);
         record_block(s, block[2], 2);
         record_block(s, block[4], 4);
@@ -474,7 +474,7 @@ static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
         record_block(s, block[5], 5);
         record_block(s, block[9], 9);
 
-        if (16*s->mb_x+8 < s->width) {
+        if (16*s->c.mb_x+8 < s->c.width) {
             record_block(s, block[1],   1);
             record_block(s, block[3],   3);
             record_block(s, block[6],   6);
@@ -485,7 +485,7 @@ static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
     } else {
         for (int i = 0; i < 5; i++)
             record_block(s, block[i], i);
-        if (s->chroma_format == CHROMA_420) {
+        if (s->c.chroma_format == CHROMA_420) {
             record_block(s, block[5], 5);
         } else {
             record_block(s, block[6], 6);
@@ -495,10 +495,10 @@ static void mjpeg_record_mb(MpegEncContext *const s, int16_t block[][64],
     }
 }
 
-static void mjpeg_encode_mb(MpegEncContext *const s, int16_t block[][64],
+static void mjpeg_encode_mb(MPVEncContext *const s, int16_t block[][64],
                             int unused_x, int unused_y)
 {
-    if (s->chroma_format == CHROMA_444) {
+    if (s->c.chroma_format == CHROMA_444) {
         encode_block(s, block[0], 0);
         encode_block(s, block[2], 2);
         encode_block(s, block[4], 4);
@@ -506,7 +506,7 @@ static void mjpeg_encode_mb(MpegEncContext *const s, int16_t block[][64],
         encode_block(s, block[5], 5);
         encode_block(s, block[9], 9);
 
-        if (16 * s->mb_x + 8 < s->width) {
+        if (16 * s->c.mb_x + 8 < s->c.width) {
             encode_block(s, block[1], 1);
             encode_block(s, block[3], 3);
             encode_block(s, block[6], 6);
@@ -517,7 +517,7 @@ static void mjpeg_encode_mb(MpegEncContext *const s, int16_t block[][64],
     } else {
         for (int i = 0; i < 5; i++)
             encode_block(s, block[i], i);
-        if (s->chroma_format == CHROMA_420) {
+        if (s->c.chroma_format == CHROMA_420) {
             encode_block(s, block[5], 5);
         } else {
             encode_block(s, block[6], 6);
@@ -533,7 +533,7 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
 {
     MJPEGEncContext *const m2 = avctx->priv_data;
     MJpegContext    *const m  = &m2->mjpeg;
-    MpegEncContext  *const s  = &m2->mpeg.s;
+    MPVEncContext  *const s  = &m2->mpeg.s;
     int ret;
 
     s->mjpeg_ctx = m;
@@ -597,7 +597,7 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
     // Buffers start out empty.
     m->huff_ncode = 0;
 
-    if (s->slice_context_count > 1)
+    if (s->c.slice_context_count > 1)
         m->huffman = HUFFMAN_TABLE_DEFAULT;
 
     if (m->huffman == HUFFMAN_TABLE_OPTIMAL) {
@@ -615,7 +615,7 @@ static av_cold int mjpeg_encode_init(AVCodecContext *avctx)
 static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
                               const AVFrame *pic_arg, int *got_packet)
 {
-    MpegEncContext *s = avctx->priv_data;
+    MPVEncContext *const s = avctx->priv_data;
     AVFrame *pic;
     int i, ret;
     int chroma_v_shift = 1; /* AMV is 420-only */
@@ -635,7 +635,7 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
     //picture should be flipped upside-down
     for(i=0; i < 3; i++) {
         int vsample = i ? 2 >> chroma_v_shift : 2;
-        pic->data[i] += pic->linesize[i] * (vsample * s->height / V_MAX - 1);
+        pic->data[i] += pic->linesize[i] * (vsample * s->c.height / V_MAX - 1);
         pic->linesize[i] *= -1;
     }
     ret = ff_mpv_encode_picture(avctx, pkt, pic, got_packet);
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index ceacba9893..92feed28b4 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -56,9 +56,9 @@ typedef struct MJpegContext {
     uint8_t huff_size_ac_chrominance[256];  ///< AC chrominance Huffman table size.
     uint16_t huff_code_ac_chrominance[256]; ///< AC chrominance Huffman table codes.
 
-    /** Storage for AC luminance VLC (in MpegEncContext) */
+    /** Storage for AC luminance VLC */
     uint8_t uni_ac_vlc_len[64 * 64 * 2];
-    /** Storage for AC chrominance VLC (in MpegEncContext) */
+    /** Storage for AC chrominance VLC */
     uint8_t uni_chroma_ac_vlc_len[64 * 64 * 2];
 
     // Default DC tables have exactly 12 values
@@ -92,8 +92,8 @@ static inline void put_marker(PutBitContext *p, enum JpegMarker code)
     put_bits(p, 8, code);
 }
 
-typedef struct MpegEncContext MpegEncContext;
+typedef struct MPVEncContext MPVEncContext;
 
-int  ff_mjpeg_encode_stuffing(MpegEncContext *s);
+int ff_mjpeg_encode_stuffing(MPVEncContext *s);
 
 #endif /* AVCODEC_MJPEGENC_H */
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index ffad3dbc79..923bf5687b 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -46,7 +46,7 @@
 #define ME_MAP_SHIFT 3
 #define ME_MAP_MV_BITS 11
 
-static int sad_hpel_motion_search(MpegEncContext * s,
+static int sad_hpel_motion_search(MPVEncContext *const s,
                                   int *mx_ptr, int *my_ptr, int dmin,
                                   int src_index, int ref_index,
                                   int size, int h);
@@ -106,10 +106,10 @@ static int get_flags(MotionEstContext *c, int direct, int chroma){
            + (chroma ? FLAG_CHROMA : 0);
 }
 
-static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+static av_always_inline int cmp_direct_inline(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     const int stride= c->stride;
     const int hx = subx + x * (1 << (1 + qpel));
     const int hy = suby + y * (1 << (1 + qpel));
@@ -119,10 +119,10 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co
     //FIXME check chroma 4mv, (no crashes ...)
         av_assert2(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1));
         if(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)){
-            const int time_pp= s->pp_time;
-            const int time_pb= s->pb_time;
+            const int time_pp = s->c.pp_time;
+            const int time_pb = s->c.pb_time;
             const int mask= 2*qpel+1;
-            if(s->mv_type==MV_TYPE_8X8){
+            if (s->c.mv_type == MV_TYPE_8X8) {
                 int i;
                 for(i=0; i<4; i++){
                     int fx = c->direct_basis_mv[i][0] + hx;
@@ -159,14 +159,14 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co
                     c->qpel_avg[1][bxy](c->temp     + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride     + 8*stride, stride);
                     c->qpel_avg[1][bxy](c->temp + 8 + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8 + 8*stride, stride);
                 }else{
-                    av_assert2((fx>>1) + 16*s->mb_x >= -16);
-                    av_assert2((fy>>1) + 16*s->mb_y >= -16);
-                    av_assert2((fx>>1) + 16*s->mb_x <= s->width);
-                    av_assert2((fy>>1) + 16*s->mb_y <= s->height);
-                    av_assert2((bx>>1) + 16*s->mb_x >= -16);
-                    av_assert2((by>>1) + 16*s->mb_y >= -16);
-                    av_assert2((bx>>1) + 16*s->mb_x <= s->width);
-                    av_assert2((by>>1) + 16*s->mb_y <= s->height);
+                    av_assert2((fx>>1) + 16*s->c.mb_x >= -16);
+                    av_assert2((fy>>1) + 16*s->c.mb_y >= -16);
+                    av_assert2((fx>>1) + 16*s->c.mb_x <= s->c.width);
+                    av_assert2((fy>>1) + 16*s->c.mb_y <= s->c.height);
+                    av_assert2((bx>>1) + 16*s->c.mb_x >= -16);
+                    av_assert2((by>>1) + 16*s->c.mb_y >= -16);
+                    av_assert2((bx>>1) + 16*s->c.mb_x <= s->c.width);
+                    av_assert2((by>>1) + 16*s->c.mb_y <= s->c.height);
 
                     c->hpel_put[0][fxy](c->temp, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 16);
                     c->hpel_avg[0][bxy](c->temp, ref[8] + (bx>>1) + (by>>1)*stride, stride, 16);
@@ -178,10 +178,10 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co
     return d;
 }
 
-static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+static av_always_inline int cmp_inline(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma){
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     const int stride= c->stride;
     const int uvstride= c->uvstride;
     const int dxy= subx + (suby<<(1+qpel)); //FIXME log2_subpel?
@@ -230,13 +230,13 @@ static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int
     return d;
 }
 
-static int cmp_simple(MpegEncContext *s, const int x, const int y,
+static int cmp_simple(MPVEncContext *const s, const int x, const int y,
                       int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func){
     return cmp_inline(s,x,y,0,0,0,16,ref_index,src_index, cmp_func, chroma_cmp_func, 0, 0);
 }
 
-static int cmp_fpel_internal(MpegEncContext *s, const int x, const int y,
+static int cmp_fpel_internal(MPVEncContext *const s, const int x, const int y,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
     if(flags&FLAG_DIRECT){
@@ -246,7 +246,7 @@ static int cmp_fpel_internal(MpegEncContext *s, const int x, const int y,
     }
 }
 
-static int cmp_internal(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+static int cmp_internal(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
     if(flags&FLAG_DIRECT){
@@ -259,7 +259,7 @@ static int cmp_internal(MpegEncContext *s, const int x, const int y, const int s
 /** @brief compares a block (either a full macroblock or a partition thereof)
     against a proposed motion-compensated prediction of that block
  */
-static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+static av_always_inline int cmp(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
     if(av_builtin_constant_p(flags) && av_builtin_constant_p(h) && av_builtin_constant_p(size)
@@ -274,7 +274,7 @@ static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, con
     }
 }
 
-static int cmp_hpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+static int cmp_hpel(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
     if(flags&FLAG_DIRECT){
@@ -284,7 +284,7 @@ static int cmp_hpel(MpegEncContext *s, const int x, const int y, const int subx,
     }
 }
 
-static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+static int cmp_qpel(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
     if(flags&FLAG_DIRECT){
@@ -296,7 +296,7 @@ static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx,
 
 #include "motion_est_template.c"
 
-static int zero_cmp(MpegEncContext *s, const uint8_t *a, const uint8_t *b,
+static int zero_cmp(MPVEncContext *const s, const uint8_t *a, const uint8_t *b,
                     ptrdiff_t stride, int h)
 {
     return 0;
@@ -367,32 +367,32 @@ av_cold int ff_me_init(MotionEstContext *c, AVCodecContext *avctx,
     return 0;
 }
 
-void ff_me_init_pic(MpegEncContext *s)
+void ff_me_init_pic(MPVEncContext *const s)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
 
-/*FIXME s->no_rounding b_type*/
+/*FIXME s->c.no_rounding b_type*/
     if (c->avctx->flags & AV_CODEC_FLAG_QPEL) {
-        c->qpel_avg = s->qdsp.avg_qpel_pixels_tab;
-        if (s->no_rounding)
-            c->qpel_put = s->qdsp.put_no_rnd_qpel_pixels_tab;
+        c->qpel_avg = s->c.qdsp.avg_qpel_pixels_tab;
+        if (s->c.no_rounding)
+            c->qpel_put = s->c.qdsp.put_no_rnd_qpel_pixels_tab;
         else
-            c->qpel_put = s->qdsp.put_qpel_pixels_tab;
+            c->qpel_put = s->c.qdsp.put_qpel_pixels_tab;
     }
-    c->hpel_avg = s->hdsp.avg_pixels_tab;
-    if (s->no_rounding)
-        c->hpel_put = s->hdsp.put_no_rnd_pixels_tab;
+    c->hpel_avg = s->c.hdsp.avg_pixels_tab;
+    if (s->c.no_rounding)
+        c->hpel_put = s->c.hdsp.put_no_rnd_pixels_tab;
     else
-        c->hpel_put = s->hdsp.put_pixels_tab;
+        c->hpel_put = s->c.hdsp.put_pixels_tab;
 
-    if(s->linesize){
-        c->stride  = s->linesize;
-        c->uvstride= s->uvlinesize;
+    if (s->c.linesize) {
+        c->stride   = s->c.linesize;
+        c->uvstride = s->c.uvlinesize;
     }else{
-        c->stride  = 16*s->mb_width + 32;
-        c->uvstride=  8*s->mb_width + 16;
+        c->stride   = 16*s->c.mb_width + 32;
+        c->uvstride =  8*s->c.mb_width + 16;
     }
-    if (s->codec_id != AV_CODEC_ID_SNOW) {
+    if (s->c.codec_id != AV_CODEC_ID_SNOW) {
         c->hpel_put[2][0]= c->hpel_put[2][1]=
         c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
     }
@@ -405,12 +405,12 @@ void ff_me_init_pic(MpegEncContext *s)
     COPY3_IF_LT(dminh, d, dx, x, dy, y)\
 }
 
-static int sad_hpel_motion_search(MpegEncContext * s,
+static int sad_hpel_motion_search(MPVEncContext *const s,
                                   int *mx_ptr, int *my_ptr, int dmin,
                                   int src_index, int ref_index,
                                   int size, int h)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     const int penalty_factor= c->sub_penalty_factor;
     int mx, my, dminh;
     const uint8_t *pix, *ptr;
@@ -510,58 +510,58 @@ static int sad_hpel_motion_search(MpegEncContext * s,
     return dminh;
 }
 
-static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
+static inline void set_p_mv_tables(MPVEncContext *const s, int mx, int my, int mv4)
 {
-    const int xy= s->mb_x + s->mb_y*s->mb_stride;
+    const int xy = s->c.mb_x + s->c.mb_y * s->c.mb_stride;
 
     s->p_mv_table[xy][0] = mx;
     s->p_mv_table[xy][1] = my;
 
     /* has already been set to the 4 MV if 4MV is done */
     if(mv4){
-        int mot_xy= s->block_index[0];
-
-        s->cur_pic.motion_val[0][mot_xy    ][0] = mx;
-        s->cur_pic.motion_val[0][mot_xy    ][1] = my;
-        s->cur_pic.motion_val[0][mot_xy + 1][0] = mx;
-        s->cur_pic.motion_val[0][mot_xy + 1][1] = my;
-
-        mot_xy += s->b8_stride;
-        s->cur_pic.motion_val[0][mot_xy    ][0] = mx;
-        s->cur_pic.motion_val[0][mot_xy    ][1] = my;
-        s->cur_pic.motion_val[0][mot_xy + 1][0] = mx;
-        s->cur_pic.motion_val[0][mot_xy + 1][1] = my;
+        int mot_xy = s->c.block_index[0];
+
+        s->c.cur_pic.motion_val[0][mot_xy    ][0] = mx;
+        s->c.cur_pic.motion_val[0][mot_xy    ][1] = my;
+        s->c.cur_pic.motion_val[0][mot_xy + 1][0] = mx;
+        s->c.cur_pic.motion_val[0][mot_xy + 1][1] = my;
+
+        mot_xy += s->c.b8_stride;
+        s->c.cur_pic.motion_val[0][mot_xy    ][0] = mx;
+        s->c.cur_pic.motion_val[0][mot_xy    ][1] = my;
+        s->c.cur_pic.motion_val[0][mot_xy + 1][0] = mx;
+        s->c.cur_pic.motion_val[0][mot_xy + 1][1] = my;
     }
 }
 
 /**
  * get fullpel ME search limits.
  */
-static inline void get_limits(MpegEncContext *s, int x, int y, int bframe)
+static inline void get_limits(MPVEncContext *const s, int x, int y, int bframe)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL));
     int max_range = MAX_MV >> (1 + !!(c->flags&FLAG_QPEL));
 /*
     if(c->avctx->me_range) c->range= c->avctx->me_range >> 1;
     else                   c->range= 16;
 */
-    if (s->unrestricted_mv) {
+    if (s->c.unrestricted_mv) {
         c->xmin = - x - 16;
         c->ymin = - y - 16;
-        c->xmax = - x + s->width;
-        c->ymax = - y + s->height;
-    } else if (!(av_builtin_constant_p(bframe) && bframe) && s->out_format == FMT_H261){
+        c->xmax = - x + s->c.width;
+        c->ymax = - y + s->c.height;
+    } else if (!(av_builtin_constant_p(bframe) && bframe) && s->c.out_format == FMT_H261){
         // Search range of H.261 is different from other codec standards
         c->xmin = (x > 15) ? - 15 : 0;
         c->ymin = (y > 15) ? - 15 : 0;
-        c->xmax = (x < s->mb_width * 16 - 16) ? 15 : 0;
-        c->ymax = (y < s->mb_height * 16 - 16) ? 15 : 0;
+        c->xmax = (x < s->c.mb_width * 16 - 16) ? 15 : 0;
+        c->ymax = (y < s->c.mb_height * 16 - 16) ? 15 : 0;
     } else {
         c->xmin = - x;
         c->ymin = - y;
-        c->xmax = - x + s->mb_width *16 - 16;
-        c->ymax = - y + s->mb_height*16 - 16;
+        c->xmax = - x + s->c.mb_width *16 - 16;
+        c->ymax = - y + s->c.mb_height*16 - 16;
     }
     if(!range || range > max_range)
         range = max_range;
@@ -584,9 +584,9 @@ static inline void init_mv4_ref(MotionEstContext *c){
     c->src[3][0] = c->src[2][0] + 8;
 }
 
-static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
+static inline int h263_mv4_search(MPVEncContext *const s, int mx, int my, int shift)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     const int size= 1;
     const int h=8;
     int block;
@@ -595,7 +595,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
     int same=1;
     const int stride= c->stride;
     const uint8_t *mv_penalty = c->current_mv_penalty;
-    int safety_clipping= s->unrestricted_mv && (s->width&15) && (s->height&15);
+    int safety_clipping = s->c.unrestricted_mv && (s->c.width&15) && (s->c.height&15);
 
     init_mv4_ref(c);
 
@@ -604,28 +604,28 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         int pred_x4, pred_y4;
         int dmin4;
         static const int off[4]= {2, 1, 1, -1};
-        const int mot_stride = s->b8_stride;
-        const int mot_xy = s->block_index[block];
+        const int mot_stride = s->c.b8_stride;
+        const int mot_xy = s->c.block_index[block];
 
         if(safety_clipping){
-            c->xmax = - 16*s->mb_x + s->width  - 8*(block &1);
-            c->ymax = - 16*s->mb_y + s->height - 8*(block>>1);
+            c->xmax = - 16*s->c.mb_x + s->c.width  - 8*(block &1);
+            c->ymax = - 16*s->c.mb_y + s->c.height - 8*(block>>1);
         }
 
-        P_LEFT[0] = s->cur_pic.motion_val[0][mot_xy - 1][0];
-        P_LEFT[1] = s->cur_pic.motion_val[0][mot_xy - 1][1];
+        P_LEFT[0] = s->c.cur_pic.motion_val[0][mot_xy - 1][0];
+        P_LEFT[1] = s->c.cur_pic.motion_val[0][mot_xy - 1][1];
 
         if (P_LEFT[0] > c->xmax * (1 << shift)) P_LEFT[0] = c->xmax * (1 << shift);
 
         /* special case for first line */
-        if (s->first_slice_line && block<2) {
+        if (s->c.first_slice_line && block < 2) {
             c->pred_x= pred_x4= P_LEFT[0];
             c->pred_y= pred_y4= P_LEFT[1];
         } else {
-            P_TOP[0]      = s->cur_pic.motion_val[0][mot_xy - mot_stride             ][0];
-            P_TOP[1]      = s->cur_pic.motion_val[0][mot_xy - mot_stride             ][1];
-            P_TOPRIGHT[0] = s->cur_pic.motion_val[0][mot_xy - mot_stride + off[block]][0];
-            P_TOPRIGHT[1] = s->cur_pic.motion_val[0][mot_xy - mot_stride + off[block]][1];
+            P_TOP[0]      = s->c.cur_pic.motion_val[0][mot_xy - mot_stride             ][0];
+            P_TOP[1]      = s->c.cur_pic.motion_val[0][mot_xy - mot_stride             ][1];
+            P_TOPRIGHT[0] = s->c.cur_pic.motion_val[0][mot_xy - mot_stride + off[block]][0];
+            P_TOPRIGHT[1] = s->c.cur_pic.motion_val[0][mot_xy - mot_stride + off[block]][1];
             if (P_TOP[1]      > c->ymax * (1 << shift)) P_TOP[1]      = c->ymax * (1 << shift);
             if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift);
             if (P_TOPRIGHT[0] > c->xmax * (1 << shift)) P_TOPRIGHT[0] = c->xmax * (1 << shift);
@@ -641,7 +641,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         P_MV1[1]= my;
         if(safety_clipping)
             for(i=1; i<10; i++){
-                if (s->first_slice_line && block<2 && i>1 && i<9)
+                if (s->c.first_slice_line && block < 2 && i > 1 && i < 9)
                     continue;
                 if (i>4 && i<9)
                     continue;
@@ -657,7 +657,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             int dxy;
             const int offset= ((block&1) + (block>>1)*stride)*8;
             uint8_t *dest_y = c->scratchpad + offset;
-            if(s->quarter_sample){
+            if (s->c.quarter_sample) {
                 const uint8_t *ref = c->ref[block][0] + (mx4>>2) + (my4>>2)*stride;
                 dxy = ((my4 & 3) << 2) | (mx4 & 3);
 
@@ -672,7 +672,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         }else
             dmin_sum+= dmin4;
 
-        if(s->quarter_sample){
+        if (s->c.quarter_sample) {
             mx4_sum+= mx4/2;
             my4_sum+= my4/2;
         }else{
@@ -680,8 +680,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             my4_sum+= my4;
         }
 
-        s->cur_pic.motion_val[0][s->block_index[block]][0] = mx4;
-        s->cur_pic.motion_val[0][s->block_index[block]][1] = my4;
+        s->c.cur_pic.motion_val[0][s->c.block_index[block]][0] = mx4;
+        s->c.cur_pic.motion_val[0][s->c.block_index[block]][1] = my4;
 
         if(mx4 != mx || my4 != my) same=0;
     }
@@ -692,7 +692,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
     if (c->me_sub_cmp[0] != c->mb_cmp[0]) {
         dmin_sum += c->mb_cmp[0](s,
                                  s->new_pic->data[0] +
-                                 s->mb_x * 16 + s->mb_y * 16 * stride,
+                                 s->c.mb_x * 16 + s->c.mb_y * 16 * stride,
                                  c->scratchpad, stride, 16);
     }
 
@@ -705,13 +705,13 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         my= ff_h263_round_chroma(my4_sum);
         dxy = ((my & 1) << 1) | (mx & 1);
 
-        offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
+        offset = (s->c.mb_x*8 + (mx>>1)) + (s->c.mb_y*8 + (my>>1))*s->c.uvlinesize;
 
-        c->hpel_put[1][dxy](c->scratchpad    , s->last_pic.data[1] + offset, s->uvlinesize, 8);
-        c->hpel_put[1][dxy](c->scratchpad + 8, s->last_pic.data[2] + offset, s->uvlinesize, 8);
+        c->hpel_put[1][dxy](c->scratchpad    , s->c.last_pic.data[1] + offset, s->c.uvlinesize, 8);
+        c->hpel_put[1][dxy](c->scratchpad + 8, s->c.last_pic.data[2] + offset, s->c.uvlinesize, 8);
 
-        dmin_sum += c->mb_cmp[1](s, s->new_pic->data[1] + s->mb_x * 8 + s->mb_y * 8 * s->uvlinesize, c->scratchpad,     s->uvlinesize, 8);
-        dmin_sum += c->mb_cmp[1](s, s->new_pic->data[2] + s->mb_x * 8 + s->mb_y * 8 * s->uvlinesize, c->scratchpad + 8, s->uvlinesize, 8);
+        dmin_sum += c->mb_cmp[1](s, s->new_pic->data[1] + s->c.mb_x * 8 + s->c.mb_y * 8 * s->c.uvlinesize, c->scratchpad,     s->c.uvlinesize, 8);
+        dmin_sum += c->mb_cmp[1](s, s->new_pic->data[2] + s->c.mb_x * 8 + s->c.mb_y * 8 * s->c.uvlinesize, c->scratchpad + 8, s->c.uvlinesize, 8);
     }
 
     c->pred_x= mx;
@@ -719,7 +719,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
 
     switch(c->avctx->mb_cmp&0xFF){
     /*case FF_CMP_SSE:
-        return dmin_sum+ 32*s->qscale*s->qscale;*/
+        return dmin_sum+ 32*s->c.qscale*s->c.qscale;*/
     case FF_CMP_RD:
         return dmin_sum;
     default:
@@ -727,33 +727,34 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
     }
 }
 
-static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){
-    MotionEstContext * const c= &s->me;
+static inline void init_interlaced_ref(MPVEncContext *const s, int ref_index)
+{
+    MotionEstContext *const c = &s->c.me;
 
-    c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize;
-    c->src[1][0] = c->src[0][0] + s->linesize;
+    c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->c.linesize;
+    c->src[1][0] = c->src[0][0] + s->c.linesize;
     if(c->flags & FLAG_CHROMA){
-        c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize;
-        c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize;
-        c->src[1][1] = c->src[0][1] + s->uvlinesize;
-        c->src[1][2] = c->src[0][2] + s->uvlinesize;
+        c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->c.uvlinesize;
+        c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->c.uvlinesize;
+        c->src[1][1] = c->src[0][1] + s->c.uvlinesize;
+        c->src[1][2] = c->src[0][2] + s->c.uvlinesize;
     }
 }
 
-static int interlaced_search(MpegEncContext *s, int ref_index,
+static int interlaced_search(MPVEncContext *const s, int ref_index,
                              int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     const int size=0;
     const int h=8;
     int block;
     int P[10][2];
     const uint8_t * const mv_penalty = c->current_mv_penalty;
     int same=1;
-    const int stride= 2*s->linesize;
+    const int stride = 2*s->c.linesize;
     int dmin_sum= 0;
-    const int mot_stride= s->mb_stride;
-    const int xy= s->mb_x + s->mb_y*mot_stride;
+    const int mot_stride = s->c.mb_stride;
+    const int xy = s->c.mb_x + s->c.mb_y*mot_stride;
 
     c->ymin>>=1;
     c->ymax>>=1;
@@ -784,7 +785,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
             c->pred_x= P_LEFT[0];
             c->pred_y= P_LEFT[1];
 
-            if(!s->first_slice_line){
+            if (!s->c.first_slice_line) {
                 P_TOP[0]      = mv_table[xy - mot_stride][0];
                 P_TOP[1]      = mv_table[xy - mot_stride][1];
                 P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0];
@@ -850,7 +851,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
 
     switch(c->avctx->mb_cmp&0xFF){
     /*case FF_CMP_SSE:
-        return dmin_sum+ 32*s->qscale*s->qscale;*/
+        return dmin_sum+ 32*s->c.qscale*s->c.qscale;*/
     case FF_CMP_RD:
         return dmin_sum;
     default:
@@ -883,57 +884,57 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
     }
 }
 
-void ff_estimate_p_frame_motion(MpegEncContext * s,
+void ff_estimate_p_frame_motion(MPVEncContext *const s,
                                 int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     const uint8_t *pix, *ppix;
     int sum, mx = 0, my = 0, dmin = 0;
     int varc;            ///< the variance of the block (sum of squared (p[y][x]-average))
     int vard;            ///< sum of squared differences with the estimated motion vector
     int P[10][2];
-    const int shift= 1+s->quarter_sample;
+    const int shift = 1 + s->c.quarter_sample;
     int mb_type=0;
 
-    init_ref(c, s->new_pic->data, s->last_pic.data, NULL, 16*mb_x, 16*mb_y, 0);
+    init_ref(c, s->new_pic->data, s->c.last_pic.data, NULL, 16*mb_x, 16*mb_y, 0);
 
-    av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
-    av_assert0(s->linesize == c->stride);
-    av_assert0(s->uvlinesize == c->uvstride);
+    av_assert0(s->c.quarter_sample==0 || s->c.quarter_sample==1);
+    av_assert0(s->c.linesize == c->stride);
+    av_assert0(s->c.uvlinesize == c->uvstride);
 
-    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
-    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
-    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
-    c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
+    c->penalty_factor     = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_cmp);
+    c->sub_penalty_factor = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_sub_cmp);
+    c->mb_penalty_factor  = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->mb_cmp);
+    c->current_mv_penalty = c->mv_penalty[s->c.f_code] + MAX_DMV;
 
     get_limits(s, 16*mb_x, 16*mb_y, 0);
     c->skip=0;
 
     /* intra / predictive decision */
     pix = c->src[0][0];
-    sum  = s->mpvencdsp.pix_sum(pix, s->linesize);
-    varc = s->mpvencdsp.pix_norm1(pix, s->linesize) -
+    sum  = s->mpvencdsp.pix_sum(pix, s->c.linesize);
+    varc = s->mpvencdsp.pix_norm1(pix, s->c.linesize) -
            (((unsigned) sum * sum) >> 8) + 500;
 
-    s->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
-    s->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
+    s->mb_mean[s->c.mb_stride * mb_y + mb_x] = (sum  + 128) >> 8;
+    s->mb_var [s->c.mb_stride * mb_y + mb_x] = (varc + 128) >> 8;
     c->mb_var_sum_temp += (varc+128)>>8;
 
     if (c->motion_est != FF_ME_ZERO) {
-        const int mot_stride = s->b8_stride;
-        const int mot_xy = s->block_index[0];
+        const int mot_stride = s->c.b8_stride;
+        const int mot_xy = s->c.block_index[0];
 
-        P_LEFT[0] = s->cur_pic.motion_val[0][mot_xy - 1][0];
-        P_LEFT[1] = s->cur_pic.motion_val[0][mot_xy - 1][1];
+        P_LEFT[0] = s->c.cur_pic.motion_val[0][mot_xy - 1][0];
+        P_LEFT[1] = s->c.cur_pic.motion_val[0][mot_xy - 1][1];
 
         if (P_LEFT[0] > (c->xmax << shift))
             P_LEFT[0] =  c->xmax << shift;
 
-        if (!s->first_slice_line) {
-            P_TOP[0]      = s->cur_pic.motion_val[0][mot_xy - mot_stride    ][0];
-            P_TOP[1]      = s->cur_pic.motion_val[0][mot_xy - mot_stride    ][1];
-            P_TOPRIGHT[0] = s->cur_pic.motion_val[0][mot_xy - mot_stride + 2][0];
-            P_TOPRIGHT[1] = s->cur_pic.motion_val[0][mot_xy - mot_stride + 2][1];
+        if (!s->c.first_slice_line) {
+            P_TOP[0]      = s->c.cur_pic.motion_val[0][mot_xy - mot_stride    ][0];
+            P_TOP[1]      = s->c.cur_pic.motion_val[0][mot_xy - mot_stride    ][1];
+            P_TOPRIGHT[0] = s->c.cur_pic.motion_val[0][mot_xy - mot_stride + 2][0];
+            P_TOPRIGHT[1] = s->c.cur_pic.motion_val[0][mot_xy - mot_stride + 2][1];
             if (P_TOP[1] > (c->ymax << shift))
                 P_TOP[1] =  c->ymax << shift;
             if (P_TOPRIGHT[0] < (c->xmin * (1 << shift)))
@@ -944,7 +945,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
             P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
 
-            if (s->out_format == FMT_H263) {
+            if (s->c.out_format == FMT_H263) {
                 c->pred_x = P_MEDIAN[0];
                 c->pred_y = P_MEDIAN[1];
             } else { /* MPEG-1 at least */
@@ -959,22 +960,22 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
     }
 
     /* At this point (mx,my) are full-pell and the relative displacement */
-    ppix = c->ref[0][0] + (my * s->linesize) + mx;
+    ppix = c->ref[0][0] + (my * s->c.linesize) + mx;
 
-    vard = c->sse(NULL, pix, ppix, s->linesize, 16);
+    vard = c->sse(NULL, pix, ppix, s->c.linesize, 16);
 
-    s->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
+    s->mc_mb_var[s->c.mb_stride * mb_y + mb_x] = (vard+128)>>8;
     c->mc_mb_var_sum_temp += (vard+128)>>8;
 
     if (c->avctx->mb_decision > FF_MB_DECISION_SIMPLE) {
-        int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
-        int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
+        int p_score = FFMIN(vard, varc - 500 + (s->c.lambda2 >> FF_LAMBDA_SHIFT)*100);
+        int i_score = varc - 500 + (s->c.lambda2 >> FF_LAMBDA_SHIFT)*20;
         c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
 
         if (vard*2 + 200*256 > varc && !s->intra_penalty)
             mb_type|= CANDIDATE_MB_TYPE_INTRA;
-        if (varc*2 + 200*256 > vard || s->qscale > 24){
-//        if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){
+        if (varc*2 + 200*256 > vard || s->c.qscale > 24){
+//        if (varc*2 + 200*256 + 50*(s->c.lambda2>>FF_LAMBDA_SHIFT) > vard){
             mb_type|= CANDIDATE_MB_TYPE_INTER;
             c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
             if (s->mpv_flags & FF_MPV_FLAG_MV0)
@@ -994,7 +995,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             set_p_mv_tables(s, mx, my, 1);
         if ((c->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
            && !c->skip){ //FIXME varc/d checks
-            if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
+            if(interlaced_search(s, 0, s->c.p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
                 mb_type |= CANDIDATE_MB_TYPE_INTER_I;
         }
     }else{
@@ -1015,7 +1016,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         }
         if ((c->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
            && !c->skip){ //FIXME varc/d checks
-            int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);
+            int dmin_i= interlaced_search(s, 0, s->c.p_field_mv_table, s->p_field_select_table, mx, my, 0);
             if(dmin_i < dmin){
                 mb_type = CANDIDATE_MB_TYPE_INTER_I;
                 dmin= dmin_i;
@@ -1032,46 +1033,46 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             mean*= 0x01010101;
 
             for(i=0; i<16; i++){
-                *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean;
-                *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean;
-                *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean;
-                *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean;
+                *(uint32_t*)(&c->scratchpad[i*s->c.linesize+ 0]) = mean;
+                *(uint32_t*)(&c->scratchpad[i*s->c.linesize+ 4]) = mean;
+                *(uint32_t*)(&c->scratchpad[i*s->c.linesize+ 8]) = mean;
+                *(uint32_t*)(&c->scratchpad[i*s->c.linesize+12]) = mean;
             }
 
-            intra_score= c->mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);
+            intra_score= c->mb_cmp[0](s, c->scratchpad, pix, s->c.linesize, 16);
         }
         intra_score += c->mb_penalty_factor*16 + s->intra_penalty;
 
         if(intra_score < dmin){
             mb_type= CANDIDATE_MB_TYPE_INTRA;
-            s->cur_pic.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
+            s->c.cur_pic.mb_type[mb_y*s->c.mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
         }else
-            s->cur_pic.mb_type[mb_y*s->mb_stride + mb_x] = 0;
+            s->c.cur_pic.mb_type[mb_y*s->c.mb_stride + mb_x] = 0;
 
         {
-            int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
-            int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
+            int p_score = FFMIN(vard, varc-500+(s->c.lambda2>>FF_LAMBDA_SHIFT)*100);
+            int i_score = varc-500+(s->c.lambda2>>FF_LAMBDA_SHIFT)*20;
             c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
         }
     }
 
-    s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type;
+    s->mb_type[mb_y*s->c.mb_stride + mb_x] = mb_type;
 }
 
-int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
+int ff_pre_estimate_p_frame_motion(MPVEncContext *const s,
                                     int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext *const c = &s->c.me;
     int mx, my, dmin;
     int P[10][2];
-    const int shift= 1+s->quarter_sample;
-    const int xy= mb_x + mb_y*s->mb_stride;
-    init_ref(c, s->new_pic->data, s->last_pic.data, NULL, 16*mb_x, 16*mb_y, 0);
+    const int shift = 1 + s->c.quarter_sample;
+    const int xy    = mb_x + mb_y*s->c.mb_stride;
+    init_ref(c, s->new_pic->data, s->c.last_pic.data, NULL, 16*mb_x, 16*mb_y, 0);
 
-    av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
+    av_assert0(s->c.quarter_sample==0 || s->c.quarter_sample==1);
 
-    c->pre_penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp);
-    c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
+    c->pre_penalty_factor = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_pre_cmp);
+    c->current_mv_penalty = c->mv_penalty[s->c.f_code] + MAX_DMV;
 
     get_limits(s, 16*mb_x, 16*mb_y, 0);
     c->skip=0;
@@ -1082,16 +1083,16 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
     if(P_LEFT[0]       < (c->xmin<<shift)) P_LEFT[0]       = (c->xmin<<shift);
 
     /* special case for first line */
-    if (s->first_slice_line) {
+    if (s->c.first_slice_line) {
         c->pred_x= P_LEFT[0];
         c->pred_y= P_LEFT[1];
         P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]=
         P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME
     } else {
-        P_TOP[0]      = s->p_mv_table[xy + s->mb_stride    ][0];
-        P_TOP[1]      = s->p_mv_table[xy + s->mb_stride    ][1];
-        P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0];
-        P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1];
+        P_TOP[0]      = s->p_mv_table[xy + s->c.mb_stride    ][0];
+        P_TOP[1]      = s->p_mv_table[xy + s->c.mb_stride    ][1];
+        P_TOPRIGHT[0] = s->p_mv_table[xy + s->c.mb_stride - 1][0];
+        P_TOPRIGHT[1] = s->p_mv_table[xy + s->c.mb_stride - 1][1];
         if(P_TOP[1]      < (c->ymin<<shift)) P_TOP[1]     = (c->ymin<<shift);
         if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
         if(P_TOPRIGHT[1] < (c->ymin<<shift)) P_TOPRIGHT[1]= (c->ymin<<shift);
@@ -1111,14 +1112,14 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
     return dmin;
 }
 
-static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
+static int estimate_motion_b(MPVEncContext *const s, int mb_x, int mb_y,
                              int16_t (*mv_table)[2], int ref_index, int f_code)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     int mx = 0, my = 0, dmin = 0;
     int P[10][2];
-    const int shift= 1+s->quarter_sample;
-    const int mot_stride = s->mb_stride;
+    const int shift= 1+s->c.quarter_sample;
+    const int mot_stride = s->c.mb_stride;
     const int mot_xy = mb_y*mot_stride + mb_x;
     const uint8_t * const mv_penalty = c->mv_penalty[f_code] + MAX_DMV;
     int mv_scale;
@@ -1134,7 +1135,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
         if (P_LEFT[0] > (c->xmax << shift)) P_LEFT[0] = (c->xmax << shift);
 
         /* special case for first line */
-        if (!s->first_slice_line) {
+        if (!s->c.first_slice_line) {
             P_TOP[0]      = mv_table[mot_xy - mot_stride    ][0];
             P_TOP[1]      = mv_table[mot_xy - mot_stride    ][1];
             P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0];
@@ -1150,9 +1151,9 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
         c->pred_y = P_LEFT[1];
 
         if(mv_table == s->b_forw_mv_table){
-            mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);
+            mv_scale= (s->c.pb_time<<16) / (s->c.pp_time<<shift);
         }else{
-            mv_scale = ((s->pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<<shift);
+            mv_scale = ((s->c.pb_time - s->c.pp_time) * (1 << 16)) / (s->c.pp_time<<shift);
         }
 
         dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16);
@@ -1163,14 +1164,14 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
     if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
         dmin= get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1);
 
-//    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
+//    s->mb_type[mb_y*s->c.mb_width + mb_x]= mb_type;
     mv_table[mot_xy][0]= mx;
     mv_table[mot_xy][1]= my;
 
     return dmin;
 }
 
-static inline int check_bidir_mv(MpegEncContext * s,
+static inline int check_bidir_mv(MPVEncContext *const s,
                    int motion_fx, int motion_fy,
                    int motion_bx, int motion_by,
                    int pred_fx, int pred_fy,
@@ -1180,9 +1181,9 @@ static inline int check_bidir_mv(MpegEncContext * s,
     //FIXME optimize?
     //FIXME better f_code prediction (max mv & distance)
     //FIXME pointers
-    MotionEstContext * const c= &s->me;
-    const uint8_t * const mv_penalty_f = c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame
-    const uint8_t * const mv_penalty_b = c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame
+    MotionEstContext * const c= &s->c.me;
+    const uint8_t * const mv_penalty_f = c->mv_penalty[s->c.f_code] + MAX_DMV; // f_code of the prev frame
+    const uint8_t * const mv_penalty_b = c->mv_penalty[s->c.b_code] + MAX_DMV; // f_code of the prev frame
     int stride= c->stride;
     uint8_t *dest_y = c->scratchpad;
     const uint8_t *ptr;
@@ -1193,34 +1194,34 @@ static inline int check_bidir_mv(MpegEncContext * s,
     const uint8_t *const *ref_data  = c->ref[0];
     const uint8_t *const *ref2_data = c->ref[2];
 
-    if(s->quarter_sample){
+    if(s->c.quarter_sample){
         dxy = ((motion_fy & 3) << 2) | (motion_fx & 3);
         src_x = motion_fx >> 2;
         src_y = motion_fy >> 2;
 
         ptr = ref_data[0] + (src_y * stride) + src_x;
-        s->qdsp.put_qpel_pixels_tab[0][dxy](dest_y, ptr, stride);
+        s->c.qdsp.put_qpel_pixels_tab[0][dxy](dest_y, ptr, stride);
 
         dxy = ((motion_by & 3) << 2) | (motion_bx & 3);
         src_x = motion_bx >> 2;
         src_y = motion_by >> 2;
 
         ptr = ref2_data[0] + (src_y * stride) + src_x;
-        s->qdsp.avg_qpel_pixels_tab[size][dxy](dest_y, ptr, stride);
+        s->c.qdsp.avg_qpel_pixels_tab[size][dxy](dest_y, ptr, stride);
     }else{
         dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);
         src_x = motion_fx >> 1;
         src_y = motion_fy >> 1;
 
         ptr = ref_data[0] + (src_y * stride) + src_x;
-        s->hdsp.put_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
+        s->c.hdsp.put_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
 
         dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
         src_x = motion_bx >> 1;
         src_y = motion_by >> 1;
 
         ptr = ref2_data[0] + (src_y * stride) + src_x;
-        s->hdsp.avg_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
+        s->c.hdsp.avg_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
     }
 
     fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor
@@ -1235,10 +1236,10 @@ static inline int check_bidir_mv(MpegEncContext * s,
 }
 
 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/
-static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
+static inline int bidir_refine(MPVEncContext *const s, int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->me;
-    const int mot_stride = s->mb_stride;
+    MotionEstContext * const c= &s->c.me;
+    const int mot_stride = s->c.mb_stride;
     const int xy = mb_y *mot_stride + mb_x;
     int fbmin;
     int pred_fx= s->b_bidir_forw_mv_table[xy-1][0];
@@ -1382,16 +1383,16 @@ CHECK_BIDIR(-(a),-(b),-(c),-(d))
     return fbmin;
 }
 
-static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
+static inline int direct_search(MPVEncContext *const s, int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     int P[10][2];
-    const int mot_stride = s->mb_stride;
+    const int mot_stride = s->c.mb_stride;
     const int mot_xy = mb_y*mot_stride + mb_x;
-    const int shift= 1+s->quarter_sample;
+    const int shift= 1+s->c.quarter_sample;
     int dmin, i;
-    const int time_pp= s->pp_time;
-    const int time_pb= s->pb_time;
+    const int time_pp= s->c.pp_time;
+    const int time_pb= s->c.pb_time;
     int mx, my, xmin, xmax, ymin, ymax;
     int16_t (*mv_table)[2]= s->b_direct_mv_table;
 
@@ -1399,18 +1400,18 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
     ymin= xmin=(-32)>>shift;
     ymax= xmax=   31>>shift;
 
-    if (IS_8X8(s->next_pic.mb_type[mot_xy])) {
-        s->mv_type= MV_TYPE_8X8;
+    if (IS_8X8(s->c.next_pic.mb_type[mot_xy])) {
+        s->c.mv_type= MV_TYPE_8X8;
     }else{
-        s->mv_type= MV_TYPE_16X16;
+        s->c.mv_type= MV_TYPE_16X16;
     }
 
     for(i=0; i<4; i++){
-        int index= s->block_index[i];
+        int index= s->c.block_index[i];
         int min, max;
 
-        c->co_located_mv[i][0] = s->next_pic.motion_val[0][index][0];
-        c->co_located_mv[i][1] = s->next_pic.motion_val[0][index][1];
+        c->co_located_mv[i][0] = s->c.next_pic.motion_val[0][index][0];
+        c->co_located_mv[i][1] = s->c.next_pic.motion_val[0][index][1];
         c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
         c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
 //        c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
@@ -1420,17 +1421,17 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
         min= FFMIN(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
         max+= 16*mb_x + 1; // +-1 is for the simpler rounding
         min+= 16*mb_x - 1;
-        xmax= FFMIN(xmax, s->width - max);
+        xmax= FFMIN(xmax, s->c.width - max);
         xmin= FFMAX(xmin, - 16     - min);
 
         max= FFMAX(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
         min= FFMIN(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
         max+= 16*mb_y + 1; // +-1 is for the simpler rounding
         min+= 16*mb_y - 1;
-        ymax= FFMIN(ymax, s->height - max);
+        ymax= FFMIN(ymax, s->c.height - max);
         ymin= FFMAX(ymin, - 16      - min);
 
-        if(s->mv_type == MV_TYPE_16X16) break;
+        if(s->c.mv_type == MV_TYPE_16X16) break;
     }
 
     av_assert2(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16);
@@ -1455,7 +1456,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
     P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin * (1 << shift), ymax << shift);
 
     /* special case for first line */
-    if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped
+    if (!s->c.first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped
         P_TOP[0]      = av_clip(mv_table[mot_xy - mot_stride    ][0], xmin * (1 << shift), xmax << shift);
         P_TOP[1]      = av_clip(mv_table[mot_xy - mot_stride    ][1], ymin * (1 << shift), ymax << shift);
         P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1][0], xmin * (1 << shift), xmax << shift);
@@ -1484,47 +1485,47 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
     return dmin;
 }
 
-void ff_estimate_b_frame_motion(MpegEncContext * s,
+void ff_estimate_b_frame_motion(MPVEncContext *const s,
                              int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     int fmin, bmin, dmin, fbmin, bimin, fimin;
     int type=0;
-    const int xy = mb_y*s->mb_stride + mb_x;
-    init_ref(c, s->new_pic->data, s->last_pic.data,
-             s->next_pic.data, 16 * mb_x, 16 * mb_y, 2);
+    const int xy = mb_y*s->c.mb_stride + mb_x;
+    init_ref(c, s->new_pic->data, s->c.last_pic.data,
+             s->c.next_pic.data, 16 * mb_x, 16 * mb_y, 2);
 
     get_limits(s, 16*mb_x, 16*mb_y, 1);
 
     c->skip=0;
 
-    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_pic.mbskip_table[xy]) {
+    if (s->c.codec_id == AV_CODEC_ID_MPEG4 && s->c.next_pic.mbskip_table[xy]) {
         int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
 
         score= ((unsigned)(score*score + 128*256))>>16;
         c->mc_mb_var_sum_temp += score;
-        s->mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
-        s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0;
+        s->mc_mb_var[mb_y*s->c.mb_stride + mb_x] = score; //FIXME use SSE
+        s->mb_type[mb_y*s->c.mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0;
 
         return;
     }
 
-    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
-    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
-    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
+    c->penalty_factor    = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_cmp);
+    c->sub_penalty_factor= get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_sub_cmp);
+    c->mb_penalty_factor = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->mb_cmp);
 
-    if (s->codec_id == AV_CODEC_ID_MPEG4)
+    if (s->c.codec_id == AV_CODEC_ID_MPEG4)
         dmin= direct_search(s, mb_x, mb_y);
     else
         dmin= INT_MAX;
 
 // FIXME penalty stuff for non-MPEG-4
     c->skip=0;
-    fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) +
+    fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->c.f_code) +
            3 * c->mb_penalty_factor;
 
     c->skip=0;
-    bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +
+    bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->c.b_code) +
            2 * c->mb_penalty_factor;
     ff_dlog(c->avctx, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
 
@@ -1535,11 +1536,11 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
     if (c->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
 //FIXME mb type penalty
         c->skip=0;
-        c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
+        c->current_mv_penalty= c->mv_penalty[s->c.f_code] + MAX_DMV;
         fimin= interlaced_search(s, 0,
                                  s->b_field_mv_table[0], s->b_field_select_table[0],
                                  s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0);
-        c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_DMV;
+        c->current_mv_penalty= c->mv_penalty[s->c.b_code] + MAX_DMV;
         bimin= interlaced_search(s, 2,
                                  s->b_field_mv_table[1], s->b_field_select_table[1],
                                  s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0);
@@ -1573,7 +1574,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
 
         score= ((unsigned)(score*score + 128*256))>>16;
         c->mc_mb_var_sum_temp += score;
-        s->mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
+        s->mc_mb_var[mb_y*s->c.mb_stride + mb_x] = score; //FIXME use SSE
     }
 
     if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
@@ -1587,39 +1588,39 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
         }
          //FIXME something smarter
         if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB
-        if (s->codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT &&
+        if (s->c.codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT &&
             s->mpv_flags & FF_MPV_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy])
             type |= CANDIDATE_MB_TYPE_DIRECT0;
     }
 
-    s->mb_type[mb_y*s->mb_stride + mb_x]= type;
+    s->mb_type[mb_y*s->c.mb_stride + mb_x]= type;
 }
 
 /* find best f_code for ME which do unlimited searches */
 int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2], int type)
 {
-    MpegEncContext *const s = &m->s;
-    MotionEstContext *const c = &s->me;
+    MPVEncContext *const s = &m->s;
+    MotionEstContext *const c = &s->c.me;
 
     if (c->motion_est != FF_ME_ZERO) {
         int score[8];
-        int i, y, range = c->avctx->me_range ? c->avctx->me_range : (INT_MAX/2);
+        int i, range = c->avctx->me_range ? c->avctx->me_range : (INT_MAX/2);
         const uint8_t * fcode_tab = m->fcode_tab;
         int best_fcode=-1;
         int best_score=-10000000;
 
-        if (s->msmpeg4_version != MSMP4_UNUSED)
+        if (s->c.msmpeg4_version != MSMP4_UNUSED)
             range= FFMIN(range, 16);
-        else if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
+        else if (s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO &&
                  c->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)
             range= FFMIN(range, 256);
 
-        for(i=0; i<8; i++) score[i]= s->mb_num*(8-i);
+        for(i=0; i<8; i++) score[i]= s->c.mb_num*(8-i);
 
-        for(y=0; y<s->mb_height; y++){
+        for (int y = 0; y < s->c.mb_height; y++) {
             int x;
-            int xy= y*s->mb_stride;
-            for(x=0; x<s->mb_width; x++, xy++){
+            int xy= y*s->c.mb_stride;
+            for(x=0; x<s->c.mb_width; x++, xy++){
                 if(s->mb_type[xy] & type){
                     int mx= mv_table[xy][0];
                     int my= mv_table[xy][1];
@@ -1631,7 +1632,7 @@ int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2],
                         continue;
 
                     for(j=0; j<fcode && j<8; j++){
-                        if (s->pict_type == AV_PICTURE_TYPE_B ||
+                        if (s->c.pict_type == AV_PICTURE_TYPE_B ||
                             s->mc_mb_var[xy] < s->mb_var[xy])
                             score[j]-= 170;
                     }
@@ -1652,42 +1653,42 @@ int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2],
     }
 }
 
-void ff_fix_long_p_mvs(MpegEncContext * s, int type)
+void ff_fix_long_p_mvs(MPVEncContext *const s, int type)
 {
-    MotionEstContext * const c= &s->me;
-    const int f_code= s->f_code;
+    MotionEstContext * const c= &s->c.me;
+    const int f_code= s->c.f_code;
     int y, range;
-    av_assert0(s->pict_type==AV_PICTURE_TYPE_P);
+    av_assert0(s->c.pict_type==AV_PICTURE_TYPE_P);
 
-    range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
+    range = (((s->c.out_format == FMT_MPEG1 || s->c.msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
 
-    av_assert0(range <= 16 || s->msmpeg4_version == MSMP4_UNUSED);
-    av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && c->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
+    av_assert0(range <= 16 || s->c.msmpeg4_version == MSMP4_UNUSED);
+    av_assert0(range <=256 || !(s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO && c->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
 
     if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
 
     if (c->avctx->flags & AV_CODEC_FLAG_4MV) {
-        const int wrap= s->b8_stride;
+        const int wrap= s->c.b8_stride;
 
         /* clip / convert to intra 8x8 type MVs */
-        for(y=0; y<s->mb_height; y++){
+        for(y=0; y<s->c.mb_height; y++){
             int xy= y*2*wrap;
-            int i= y*s->mb_stride;
+            int i= y*s->c.mb_stride;
             int x;
 
-            for(x=0; x<s->mb_width; x++){
+            for(x=0; x<s->c.mb_width; x++){
                 if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){
                     int block;
                     for(block=0; block<4; block++){
                         int off= (block& 1) + (block>>1)*wrap;
-                        int mx = s->cur_pic.motion_val[0][ xy + off ][0];
-                        int my = s->cur_pic.motion_val[0][ xy + off ][1];
+                        int mx = s->c.cur_pic.motion_val[0][ xy + off ][0];
+                        int my = s->c.cur_pic.motion_val[0][ xy + off ][1];
 
                         if(   mx >=range || mx <-range
                            || my >=range || my <-range){
                             s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
                             s->mb_type[i] |= type;
-                            s->cur_pic.mb_type[i] = type;
+                            s->c.cur_pic.mb_type[i] = type;
                         }
                     }
                 }
@@ -1701,14 +1702,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s, int type)
 /**
  * @param truncate 1 for truncation, 0 for using intra
  */
-void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
+void ff_fix_long_mvs(MPVEncContext *const s, uint8_t *field_select_table, int field_select,
                      int16_t (*mv_table)[2], int f_code, int type, int truncate)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     int y, h_range, v_range;
 
     // RAL: 8 in MPEG-1, 16 in MPEG-4
-    int range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
+    int range = (((s->c.out_format == FMT_MPEG1 || s->c.msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
 
     if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
 
@@ -1716,10 +1717,10 @@ void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_
     v_range= field_select_table ? range>>1 : range;
 
     /* clip / convert to intra 16x16 type MVs */
-    for(y=0; y<s->mb_height; y++){
+    for(y=0; y<s->c.mb_height; y++){
         int x;
-        int xy= y*s->mb_stride;
-        for(x=0; x<s->mb_width; x++){
+        int xy= y*s->c.mb_stride;
+        for(x=0; x<s->c.mb_width; x++){
             if (s->mb_type[xy] & type){    // RAL: "type" test added...
                 if (!field_select_table || field_select_table[xy] == field_select) {
                     if(   mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range
diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h
index 5fa96161c6..16975abfe1 100644
--- a/libavcodec/motion_est.h
+++ b/libavcodec/motion_est.h
@@ -28,7 +28,7 @@
 #include "me_cmp.h"
 #include "qpeldsp.h"
 
-struct MpegEncContext;
+typedef struct MPVEncContext MPVEncContext;
 typedef struct MPVMainEncContext MPVMainEncContext;
 
 #if ARCH_IA64 // Limit static arrays to avoid gcc failing "short data segment overflowed"
@@ -100,7 +100,7 @@ typedef struct MotionEstContext {
     qpel_mc_func(*qpel_avg)[16];
     const uint8_t (*mv_penalty)[MAX_DMV * 2 + 1]; ///< bit amount needed to encode a MV
     const uint8_t *current_mv_penalty;
-    int (*sub_motion_search)(struct MpegEncContext *s,
+    int (*sub_motion_search)(MPVEncContext *s,
                              int *mx_ptr, int *my_ptr, int dmin,
                              int src_index, int ref_index,
                              int size, int h);
@@ -122,27 +122,27 @@ static inline int ff_h263_round_chroma(int x)
 int ff_me_init(MotionEstContext *c, struct AVCodecContext *avctx,
                const struct MECmpContext *mecc, int mpvenc);
 
-void ff_me_init_pic(struct MpegEncContext *s);
+void ff_me_init_pic(MPVEncContext *s);
 
-void ff_estimate_p_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y);
-void ff_estimate_b_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y);
+void ff_estimate_p_frame_motion(MPVEncContext *s, int mb_x, int mb_y);
+void ff_estimate_b_frame_motion(MPVEncContext *s, int mb_x, int mb_y);
 
-int ff_pre_estimate_p_frame_motion(struct MpegEncContext *s,
+int ff_pre_estimate_p_frame_motion(MPVEncContext *s,
                                    int mb_x, int mb_y);
 
-int ff_epzs_motion_search(struct MpegEncContext *s, int *mx_ptr, int *my_ptr,
+int ff_epzs_motion_search(MPVEncContext *s, int *mx_ptr, int *my_ptr,
                           int P[10][2], int src_index, int ref_index,
                           const int16_t (*last_mv)[2], int ref_mv_scale,
                           int size, int h);
 
-int ff_get_mb_score(struct MpegEncContext *s, int mx, int my, int src_index,
+int ff_get_mb_score(MPVEncContext *s, int mx, int my, int src_index,
                     int ref_index, int size, int h, int add_rate);
 
 int ff_get_best_fcode(MPVMainEncContext *m,
                       const int16_t (*mv_table)[2], int type);
 
-void ff_fix_long_p_mvs(struct MpegEncContext *s, int type);
-void ff_fix_long_mvs(struct MpegEncContext *s, uint8_t *field_select_table,
+void ff_fix_long_p_mvs(MPVEncContext *s, int type);
+void ff_fix_long_mvs(MPVEncContext *s, uint8_t *field_select_table,
                      int field_select, int16_t (*mv_table)[2], int f_code,
                      int type, int truncate);
 
diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c
index 5498f9c982..7c7e645625 100644
--- a/libavcodec/motion_est_template.c
+++ b/libavcodec/motion_est_template.c
@@ -25,7 +25,7 @@
  */
 
 #include "libavutil/qsort.h"
-#include "mpegvideo.h"
+#include "mpegvideoenc.h"
 
 //Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
 #define LOAD_COMMON\
@@ -47,12 +47,12 @@
     COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
 }
 
-static int hpel_motion_search(MpegEncContext * s,
+static int hpel_motion_search(MPVEncContext *const s,
                                   int *mx_ptr, int *my_ptr, int dmin,
                                   int src_index, int ref_index,
                                   int size, int h)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     const int mx = *mx_ptr;
     const int my = *my_ptr;
     const int penalty_factor= c->sub_penalty_factor;
@@ -152,7 +152,7 @@ static int hpel_motion_search(MpegEncContext * s,
     return dmin;
 }
 
-static int no_sub_motion_search(MpegEncContext * s,
+static int no_sub_motion_search(MPVEncContext *const s,
           int *mx_ptr, int *my_ptr, int dmin,
                                   int src_index, int ref_index,
                                   int size, int h)
@@ -162,11 +162,11 @@ static int no_sub_motion_search(MpegEncContext * s,
     return dmin;
 }
 
-static inline int get_mb_score(MpegEncContext *s, int mx, int my,
+static inline int get_mb_score(MPVEncContext *const s, int mx, int my,
                                int src_index, int ref_index, int size,
                                int h, int add_rate)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     const int penalty_factor= c->mb_penalty_factor;
     const int flags= c->mb_flags;
     const int qpel= flags & FLAG_QPEL;
@@ -189,7 +189,7 @@ static inline int get_mb_score(MpegEncContext *s, int mx, int my,
     return d;
 }
 
-int ff_get_mb_score(MpegEncContext *s, int mx, int my, int src_index,
+int ff_get_mb_score(MPVEncContext *const s, int mx, int my, int src_index,
                     int ref_index, int size, int h, int add_rate)
 {
     return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
@@ -204,12 +204,12 @@ int ff_get_mb_score(MpegEncContext *s, int mx, int my, int src_index,
     COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
 }
 
-static int qpel_motion_search(MpegEncContext * s,
+static int qpel_motion_search(MPVEncContext *const s,
                                   int *mx_ptr, int *my_ptr, int dmin,
                                   int src_index, int ref_index,
                                   int size, int h)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     const int mx = *mx_ptr;
     const int my = *my_ptr;
     const int penalty_factor= c->sub_penalty_factor;
@@ -256,7 +256,7 @@ static int qpel_motion_search(MpegEncContext * s,
         int best_pos[8][2];
 
         memset(best, 64, sizeof(int)*8);
-        if(s->me.dia_size>=2){
+        if(s->c.me.dia_size>=2){
             const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
             const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
             const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
@@ -403,21 +403,21 @@ static int qpel_motion_search(MpegEncContext * s,
 }
 
 #define check(x,y,S,v)\
-if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
-if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
-if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
-if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
+if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->c.mb_x, s->c.mb_y);\
+if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->c.mb_x, s->c.mb_y);\
+if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->c.mb_x, s->c.mb_y);\
+if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->c.mb_x, s->c.mb_y);\
 
 #define LOAD_COMMON2\
     uint32_t *map= c->map;\
     const int qpel= flags&FLAG_QPEL;\
     const int shift= 1+qpel;\
 
-static av_always_inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
+static av_always_inline int small_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     int next_dir=-1;
     LOAD_COMMON
@@ -454,11 +454,11 @@ static av_always_inline int small_diamond_search(MpegEncContext * s, int *best,
     }
 }
 
-static int funny_diamond_search(MpegEncContext * s, int *best, int dmin,
+static int funny_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     int dia_size;
     LOAD_COMMON
@@ -496,11 +496,11 @@ static int funny_diamond_search(MpegEncContext * s, int *best, int dmin,
     return dmin;
 }
 
-static int hex_search(MpegEncContext * s, int *best, int dmin,
+static int hex_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags, int dia_size)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -530,11 +530,11 @@ static int hex_search(MpegEncContext * s, int *best, int dmin,
     return dmin;
 }
 
-static int l2s_dia_search(MpegEncContext * s, int *best, int dmin,
+static int l2s_dia_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -568,11 +568,11 @@ static int l2s_dia_search(MpegEncContext * s, int *best, int dmin,
     return dmin;
 }
 
-static int umh_search(MpegEncContext * s, int *best, int dmin,
+static int umh_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -615,11 +615,11 @@ static int umh_search(MpegEncContext * s, int *best, int dmin,
     return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2);
 }
 
-static int full_search(MpegEncContext * s, int *best, int dmin,
+static int full_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -678,11 +678,11 @@ static int full_search(MpegEncContext * s, int *best, int dmin,
 }
 
 #define MAX_SAB_SIZE ME_MAP_SIZE
-static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,
+static int sab_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     Minima minima[MAX_SAB_SIZE];
     const int minima_count= FFABS(c->dia_size);
@@ -768,11 +768,11 @@ static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,
     return dmin;
 }
 
-static int var_diamond_search(MpegEncContext * s, int *best, int dmin,
+static int var_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     me_cmp_func cmpf, chroma_cmpf;
     int dia_size;
     LOAD_COMMON
@@ -829,10 +829,10 @@ static int var_diamond_search(MpegEncContext * s, int *best, int dmin,
     return dmin;
 }
 
-static av_always_inline int diamond_search(MpegEncContext * s, int *best, int dmin,
+static av_always_inline int diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags){
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     if(c->dia_size==-1)
         return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
     else if(c->dia_size<-1)
@@ -857,11 +857,11 @@ static av_always_inline int diamond_search(MpegEncContext * s, int *best, int dm
    it takes fewer iterations. And it increases the chance that we find the
    optimal mv.
  */
-static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx_ptr, int *my_ptr,
+static av_always_inline int epzs_motion_search_internal(MPVEncContext *const s, int *mx_ptr, int *my_ptr,
                              int P[10][2], int src_index, int ref_index, const int16_t (*last_mv)[2],
                              int ref_mv_scale, int flags, int size, int h)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     int best[2]={0, 0};      /**< x and y coordinates of the best motion vector.
                                i.e. the difference between the position of the
                                block currently being encoded and the position of
@@ -871,8 +871,8 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
                                corresponding to the mv stored in best[]. */
     unsigned map_generation;
     int penalty_factor;
-    const int ref_mv_stride= s->mb_stride; //pass as arg  FIXME
-    const int ref_mv_xy = s->mb_x + s->mb_y * ref_mv_stride; // add to last_mv before passing FIXME
+    const int ref_mv_stride= s->c.mb_stride; //pass as arg  FIXME
+    const int ref_mv_xy = s->c.mb_x + s->c.mb_y * ref_mv_stride; // add to last_mv before passing FIXME
     me_cmp_func cmpf, chroma_cmpf;
 
     LOAD_COMMON
@@ -896,12 +896,12 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
     score_map[0]= dmin;
 
     //FIXME precalc first term below?
-    if ((s->pict_type == AV_PICTURE_TYPE_B && !(c->flags & FLAG_DIRECT)) ||
+    if ((s->c.pict_type == AV_PICTURE_TYPE_B && !(c->flags & FLAG_DIRECT)) ||
         s->mpv_flags & FF_MPV_FLAG_MV0)
         dmin += (mv_penalty[pred_x] + mv_penalty[pred_y])*penalty_factor;
 
     /* first line */
-    if (s->first_slice_line) {
+    if (s->c.first_slice_line) {
         CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
         CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
                         (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
@@ -930,13 +930,13 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
         if(c->pre_pass){
             CHECK_CLIPPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16,
                             (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
-            if(!s->first_slice_line)
+            if(!s->c.first_slice_line)
                 CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
                                 (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
         }else{
             CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
                             (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
-            if(s->mb_y+1<s->end_mb_y)  //FIXME replace at least with last_slice_line
+            if(s->c.mb_y+1<s->c.end_mb_y)  //FIXME replace at least with last_slice_line
                 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
                                 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
         }
@@ -944,10 +944,10 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
 
     if(c->avctx->last_predictor_count){
         const int count= c->avctx->last_predictor_count;
-        const int xstart= FFMAX(0, s->mb_x - count);
-        const int ystart= FFMAX(0, s->mb_y - count);
-        const int xend= FFMIN(s->mb_width , s->mb_x + count + 1);
-        const int yend= FFMIN(s->mb_height, s->mb_y + count + 1);
+        const int xstart= FFMAX(0, s->c.mb_x - count);
+        const int ystart= FFMAX(0, s->c.mb_y - count);
+        const int xend= FFMIN(s->c.mb_width , s->c.mb_x + count + 1);
+        const int yend= FFMIN(s->c.mb_height, s->c.mb_y + count + 1);
         int mb_y;
 
         for(mb_y=ystart; mb_y<yend; mb_y++){
@@ -974,12 +974,12 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
 }
 
 //this function is dedicated to the brain damaged gcc
-int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr,
+int ff_epzs_motion_search(MPVEncContext *const s, int *mx_ptr, int *my_ptr,
                           int P[10][2], int src_index, int ref_index,
                           const int16_t (*last_mv)[2], int ref_mv_scale,
                           int size, int h)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
 //FIXME convert other functions in the same way if faster
     if(c->flags==0 && h==16 && size==0){
         return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
@@ -990,19 +990,19 @@ int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr,
     }
 }
 
-static int epzs_motion_search2(MpegEncContext * s,
+static int epzs_motion_search2(MPVEncContext *const s,
                              int *mx_ptr, int *my_ptr, int P[10][2],
                              int src_index, int ref_index, const int16_t (*last_mv)[2],
                              int ref_mv_scale, const int size)
 {
-    MotionEstContext * const c= &s->me;
+    MotionEstContext * const c= &s->c.me;
     int best[2]={0, 0};
     int d, dmin;
     unsigned map_generation;
     const int penalty_factor= c->penalty_factor;
     const int h=8;
-    const int ref_mv_stride= s->mb_stride;
-    const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
+    const int ref_mv_stride= s->c.mb_stride;
+    const int ref_mv_xy= s->c.mb_x + s->c.mb_y *ref_mv_stride;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     int flags= c->flags;
@@ -1016,7 +1016,7 @@ static int epzs_motion_search2(MpegEncContext * s,
     dmin = 1000000;
 
     /* first line */
-    if (s->first_slice_line) {
+    if (s->c.first_slice_line) {
         CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
         CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
                         (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
@@ -1034,7 +1034,7 @@ static int epzs_motion_search2(MpegEncContext * s,
     if(dmin>64*4){
         CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
                         (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
-        if(s->mb_y+1<s->end_mb_y)  //FIXME replace at least with last_slice_line
+        if(s->c.mb_y+1<s->c.end_mb_y)  //FIXME replace at least with last_slice_line
             CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
                             (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
     }
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index ae87f28d66..5a91f9fff1 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -137,7 +137,7 @@ av_cold void ff_mpeg1_init_uni_ac_vlc(const int8_t max_level[],
 }
 
 #if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
-static void put_header(MpegEncContext *s, uint32_t header)
+static void put_header(MPVEncContext *const s, uint32_t header)
 {
     align_put_bits(&s->pb);
     put_bits32(&s->pb, header);
@@ -146,16 +146,16 @@ static void put_header(MpegEncContext *s, uint32_t header)
 /* put sequence header if needed */
 static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
 {
-    MpegEncContext *const s = &mpeg12->mpeg.s;
+    MPVEncContext *const s = &mpeg12->mpeg.s;
     unsigned int vbv_buffer_size, fps, v;
     int constraint_parameter_flag;
     AVRational framerate = ff_mpeg12_frame_rate_tab[mpeg12->frame_rate_index];
     uint64_t time_code;
     int64_t best_aspect_error = INT64_MAX;
-    AVRational aspect_ratio = s->avctx->sample_aspect_ratio;
+    AVRational aspect_ratio = s->c.avctx->sample_aspect_ratio;
     int aspect_ratio_info;
 
-    if (!(s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY))
+    if (!(s->c.cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY))
         return;
 
     if (aspect_ratio.num == 0 || aspect_ratio.den == 0)
@@ -164,15 +164,15 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
     /* MPEG-1 header repeated every GOP */
     put_header(s, SEQ_START_CODE);
 
-    put_sbits(&s->pb, 12, s->width  & 0xFFF);
-    put_sbits(&s->pb, 12, s->height & 0xFFF);
+    put_sbits(&s->pb, 12, s->c.width  & 0xFFF);
+    put_sbits(&s->pb, 12, s->c.height & 0xFFF);
 
     for (int i = 1; i < 15; i++) {
         int64_t error = aspect_ratio.num * (1LL<<32) / aspect_ratio.den;
-        if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO || i <= 1)
+        if (s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO || i <= 1)
             error -= (1LL<<32) / ff_mpeg1_aspect[i];
         else
-            error -= (1LL<<32)*ff_mpeg2_aspect[i].num * s->height / s->width / ff_mpeg2_aspect[i].den;
+            error -= (1LL<<32)*ff_mpeg2_aspect[i].num * s->c.height / s->c.width / ff_mpeg2_aspect[i].den;
 
         error = FFABS(error);
 
@@ -185,16 +185,16 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
     put_bits(&s->pb, 4, aspect_ratio_info);
     put_bits(&s->pb, 4, mpeg12->frame_rate_index);
 
-    if (s->avctx->rc_max_rate) {
-        v = (s->avctx->rc_max_rate + 399) / 400;
-        if (v > 0x3ffff && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
+    if (s->c.avctx->rc_max_rate) {
+        v = (s->c.avctx->rc_max_rate + 399) / 400;
+        if (v > 0x3ffff && s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO)
             v = 0x3ffff;
     } else {
         v = 0x3FFFF;
     }
 
-    if (s->avctx->rc_buffer_size)
-        vbv_buffer_size = s->avctx->rc_buffer_size;
+    if (s->c.avctx->rc_buffer_size)
+        vbv_buffer_size = s->c.avctx->rc_buffer_size;
     else
         /* VBV calculation: Scaled so that a VCD has the proper
          * VBV size of 40 kilobytes */
@@ -206,48 +206,48 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
     put_sbits(&s->pb, 10, vbv_buffer_size);
 
     constraint_parameter_flag =
-        s->width  <= 768                                    &&
-        s->height <= 576                                    &&
-        s->mb_width * s->mb_height                 <= 396   &&
-        s->mb_width * s->mb_height * framerate.num <= 396 * 25 * framerate.den &&
+        s->c.width  <= 768                                    &&
+        s->c.height <= 576                                    &&
+        s->c.mb_width * s->c.mb_height                 <= 396   &&
+        s->c.mb_width * s->c.mb_height * framerate.num <= 396 * 25 * framerate.den &&
         framerate.num <= framerate.den * 30                 &&
-        s->avctx->me_range                                  &&
-        s->avctx->me_range < 128                            &&
+        s->c.avctx->me_range                                  &&
+        s->c.avctx->me_range < 128                            &&
         vbv_buffer_size <= 20                               &&
         v <= 1856000 / 400                                  &&
-        s->codec_id == AV_CODEC_ID_MPEG1VIDEO;
+        s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO;
 
     put_bits(&s->pb, 1, constraint_parameter_flag);
 
-    ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
-    ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
+    ff_write_quant_matrix(&s->pb, s->c.avctx->intra_matrix);
+    ff_write_quant_matrix(&s->pb, s->c.avctx->inter_matrix);
 
-    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+    if (s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO) {
         const AVFrameSideData *side_data;
-        int width = s->width;
-        int height = s->height;
+        int width = s->c.width;
+        int height = s->c.height;
         int use_seq_disp_ext;
 
         put_header(s, EXT_START_CODE);
         put_bits(&s->pb, 4, 1);                 // seq ext
 
-        put_bits(&s->pb, 1, s->avctx->profile == AV_PROFILE_MPEG2_422); // escx 1 for 4:2:2 profile
+        put_bits(&s->pb, 1, s->c.avctx->profile == AV_PROFILE_MPEG2_422); // escx 1 for 4:2:2 profile
 
-        put_bits(&s->pb, 3, s->avctx->profile); // profile
-        put_bits(&s->pb, 4, s->avctx->level);   // level
+        put_bits(&s->pb, 3, s->c.avctx->profile); // profile
+        put_bits(&s->pb, 4, s->c.avctx->level);   // level
 
-        put_bits(&s->pb, 1, s->progressive_sequence);
-        put_bits(&s->pb, 2, s->chroma_format);
-        put_bits(&s->pb, 2, s->width  >> 12);
-        put_bits(&s->pb, 2, s->height >> 12);
+        put_bits(&s->pb, 1, s->c.progressive_sequence);
+        put_bits(&s->pb, 2, s->c.chroma_format);
+        put_bits(&s->pb, 2, s->c.width  >> 12);
+        put_bits(&s->pb, 2, s->c.height >> 12);
         put_bits(&s->pb, 12, v >> 18);          // bitrate ext
         put_bits(&s->pb, 1, 1);                 // marker
         put_bits(&s->pb, 8, vbv_buffer_size >> 10); // vbv buffer ext
-        put_bits(&s->pb, 1, s->low_delay);
+        put_bits(&s->pb, 1, s->c.low_delay);
         put_bits(&s->pb, 2, mpeg12->frame_rate_ext.num-1); // frame_rate_ext_n
         put_bits(&s->pb, 5, mpeg12->frame_rate_ext.den-1); // frame_rate_ext_d
 
-        side_data = av_frame_get_side_data(s->cur_pic.ptr->f, AV_FRAME_DATA_PANSCAN);
+        side_data = av_frame_get_side_data(s->c.cur_pic.ptr->f, AV_FRAME_DATA_PANSCAN);
         if (side_data) {
             const AVPanScan *pan_scan = (AVPanScan *)side_data->data;
             if (pan_scan->width && pan_scan->height) {
@@ -256,11 +256,11 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
             }
         }
 
-        use_seq_disp_ext = (width != s->width ||
-                            height != s->height ||
-                            s->avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
-                            s->avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
-                            s->avctx->colorspace != AVCOL_SPC_UNSPECIFIED ||
+        use_seq_disp_ext = (width != s->c.width ||
+                            height != s->c.height ||
+                            s->c.avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
+                            s->c.avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
+                            s->c.avctx->colorspace != AVCOL_SPC_UNSPECIFIED ||
                             mpeg12->video_format != VIDEO_FORMAT_UNSPECIFIED);
 
         if (mpeg12->seq_disp_ext == 1 ||
@@ -269,9 +269,9 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
             put_bits(&s->pb, 4, 2);                         // sequence display extension
             put_bits(&s->pb, 3, mpeg12->video_format);      // video_format
             put_bits(&s->pb, 1, 1);                         // colour_description
-            put_bits(&s->pb, 8, s->avctx->color_primaries); // colour_primaries
-            put_bits(&s->pb, 8, s->avctx->color_trc);       // transfer_characteristics
-            put_bits(&s->pb, 8, s->avctx->colorspace);      // matrix_coefficients
+            put_bits(&s->pb, 8, s->c.avctx->color_primaries); // colour_primaries
+            put_bits(&s->pb, 8, s->c.avctx->color_trc);       // transfer_characteristics
+            put_bits(&s->pb, 8, s->c.avctx->colorspace);      // matrix_coefficients
             put_bits(&s->pb, 14, width);                    // display_horizontal_size
             put_bits(&s->pb, 1, 1);                         // marker_bit
             put_bits(&s->pb, 14, height);                   // display_vertical_size
@@ -284,10 +284,10 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
     /* time code: we must convert from the real frame rate to a
      * fake MPEG frame rate in case of low frame rate */
     fps       = (framerate.num + framerate.den / 2) / framerate.den;
-    time_code = s->cur_pic.ptr->coded_picture_number +
+    time_code = s->c.cur_pic.ptr->coded_picture_number +
                 mpeg12->timecode_frame_start;
 
-    mpeg12->gop_picture_number = s->cur_pic.ptr->coded_picture_number;
+    mpeg12->gop_picture_number = s->c.cur_pic.ptr->coded_picture_number;
 
     av_assert0(mpeg12->drop_frame_timecode == !!(mpeg12->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
     if (mpeg12->drop_frame_timecode)
@@ -298,12 +298,12 @@ static void mpeg1_encode_sequence_header(MPEG12EncContext *mpeg12)
     put_bits(&s->pb, 1, 1);
     put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
     put_bits(&s->pb, 6, (uint32_t)((time_code % fps)));
-    put_bits(&s->pb, 1, !!(s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) ||
+    put_bits(&s->pb, 1, !!(s->c.avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) ||
                         mpeg12->mpeg.intra_only || !mpeg12->gop_picture_number);
     put_bits(&s->pb, 1, 0);                     // broken link
 }
 
-static inline void encode_mb_skip_run(MpegEncContext *s, int run)
+static inline void encode_mb_skip_run(MPVEncContext *const s, int run)
 {
     while (run >= 33) {
         put_bits(&s->pb, 11, 0x008);
@@ -313,20 +313,20 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run)
              ff_mpeg12_mbAddrIncrTable[run][0]);
 }
 
-static av_always_inline void put_qscale(MpegEncContext *s)
+static av_always_inline void put_qscale(MPVEncContext *const s)
 {
-    put_bits(&s->pb, 5, s->qscale);
+    put_bits(&s->pb, 5, s->c.qscale);
 }
 
-void ff_mpeg1_encode_slice_header(MpegEncContext *s)
+void ff_mpeg1_encode_slice_header(MPVEncContext *const s)
 {
-    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->height > 2800) {
-        put_header(s, SLICE_MIN_START_CODE + (s->mb_y & 127));
+    if (s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO && s->c.height > 2800) {
+        put_header(s, SLICE_MIN_START_CODE + (s->c.mb_y & 127));
         /* slice_vertical_position_extension */
-        put_bits(&s->pb, 3, s->mb_y >> 7);
+        put_bits(&s->pb, 3, s->c.mb_y >> 7);
     } else {
-        av_assert1(s->mb_y <= SLICE_MAX_START_CODE - SLICE_MIN_START_CODE);
-        put_header(s, SLICE_MIN_START_CODE + s->mb_y);
+        av_assert1(s->c.mb_y <= SLICE_MAX_START_CODE - SLICE_MIN_START_CODE);
+        put_header(s, SLICE_MIN_START_CODE + s->c.mb_y);
     }
     put_qscale(s);
     /* slice extra information */
@@ -336,7 +336,7 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s)
 static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
 {
     MPEG12EncContext *const mpeg12 = (MPEG12EncContext*)m;
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     const AVFrameSideData *side_data;
 
     mpeg1_encode_sequence_header(mpeg12);
@@ -345,74 +345,74 @@ static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
     put_header(s, PICTURE_START_CODE);
     /* temporal reference */
 
-    // RAL: s->picture_number instead of s->fake_picture_number
+    // RAL: s->c.picture_number instead of s->fake_picture_number
     put_bits(&s->pb, 10,
-             (s->picture_number - mpeg12->gop_picture_number) & 0x3ff);
-    put_bits(&s->pb, 3, s->pict_type);
+             (s->c.picture_number - mpeg12->gop_picture_number) & 0x3ff);
+    put_bits(&s->pb, 3, s->c.pict_type);
 
     m->vbv_delay_pos = put_bytes_count(&s->pb, 0);
     put_bits(&s->pb, 16, 0xFFFF);               /* vbv_delay */
 
     // RAL: Forward f_code also needed for B-frames
-    if (s->pict_type == AV_PICTURE_TYPE_P ||
-        s->pict_type == AV_PICTURE_TYPE_B) {
+    if (s->c.pict_type == AV_PICTURE_TYPE_P ||
+        s->c.pict_type == AV_PICTURE_TYPE_B) {
         put_bits(&s->pb, 1, 0);                 /* half pel coordinates */
-        if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
-            put_bits(&s->pb, 3, s->f_code);     /* forward_f_code */
+        if (s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO)
+            put_bits(&s->pb, 3, s->c.f_code);     /* forward_f_code */
         else
             put_bits(&s->pb, 3, 7);             /* forward_f_code */
     }
 
     // RAL: Backward f_code necessary for B-frames
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
+    if (s->c.pict_type == AV_PICTURE_TYPE_B) {
         put_bits(&s->pb, 1, 0);                 /* half pel coordinates */
-        if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
-            put_bits(&s->pb, 3, s->b_code);     /* backward_f_code */
+        if (s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO)
+            put_bits(&s->pb, 3, s->c.b_code);     /* backward_f_code */
         else
             put_bits(&s->pb, 3, 7);             /* backward_f_code */
     }
 
     put_bits(&s->pb, 1, 0);                     /* extra bit picture */
 
-    s->frame_pred_frame_dct = 1;
-    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+    s->c.frame_pred_frame_dct = 1;
+    if (s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO) {
         put_header(s, EXT_START_CODE);
         put_bits(&s->pb, 4, 8);                 /* pic ext */
-        if (s->pict_type == AV_PICTURE_TYPE_P ||
-            s->pict_type == AV_PICTURE_TYPE_B) {
-            put_bits(&s->pb, 4, s->f_code);
-            put_bits(&s->pb, 4, s->f_code);
+        if (s->c.pict_type == AV_PICTURE_TYPE_P ||
+            s->c.pict_type == AV_PICTURE_TYPE_B) {
+            put_bits(&s->pb, 4, s->c.f_code);
+            put_bits(&s->pb, 4, s->c.f_code);
         } else {
             put_bits(&s->pb, 8, 255);
         }
-        if (s->pict_type == AV_PICTURE_TYPE_B) {
-            put_bits(&s->pb, 4, s->b_code);
-            put_bits(&s->pb, 4, s->b_code);
+        if (s->c.pict_type == AV_PICTURE_TYPE_B) {
+            put_bits(&s->pb, 4, s->c.b_code);
+            put_bits(&s->pb, 4, s->c.b_code);
         } else {
             put_bits(&s->pb, 8, 255);
         }
-        put_bits(&s->pb, 2, s->intra_dc_precision);
+        put_bits(&s->pb, 2, s->c.intra_dc_precision);
 
-        av_assert0(s->picture_structure == PICT_FRAME);
-        put_bits(&s->pb, 2, s->picture_structure);
-        if (s->progressive_sequence)
+        av_assert0(s->c.picture_structure == PICT_FRAME);
+        put_bits(&s->pb, 2, s->c.picture_structure);
+        if (s->c.progressive_sequence)
             put_bits(&s->pb, 1, 0);             /* no repeat */
         else
-            put_bits(&s->pb, 1, !!(s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
+            put_bits(&s->pb, 1, !!(s->c.cur_pic.ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
         /* XXX: optimize the generation of this flag with entropy measures */
-        s->frame_pred_frame_dct = s->progressive_sequence;
-
-        put_bits(&s->pb, 1, s->frame_pred_frame_dct);
-        put_bits(&s->pb, 1, s->concealment_motion_vectors);
-        put_bits(&s->pb, 1, s->q_scale_type);
-        put_bits(&s->pb, 1, s->intra_vlc_format);
-        put_bits(&s->pb, 1, s->alternate_scan);
-        put_bits(&s->pb, 1, s->repeat_first_field);
-        s->progressive_frame = s->progressive_sequence;
+        s->c.frame_pred_frame_dct = s->c.progressive_sequence;
+
+        put_bits(&s->pb, 1, s->c.frame_pred_frame_dct);
+        put_bits(&s->pb, 1, s->c.concealment_motion_vectors);
+        put_bits(&s->pb, 1, s->c.q_scale_type);
+        put_bits(&s->pb, 1, s->c.intra_vlc_format);
+        put_bits(&s->pb, 1, s->c.alternate_scan);
+        put_bits(&s->pb, 1, s->c.repeat_first_field);
+        s->c.progressive_frame = s->c.progressive_sequence;
         /* chroma_420_type */
-        put_bits(&s->pb, 1, s->chroma_format ==
-                            CHROMA_420 ? s->progressive_frame : 0);
-        put_bits(&s->pb, 1, s->progressive_frame);
+        put_bits(&s->pb, 1, s->c.chroma_format ==
+                            CHROMA_420 ? s->c.progressive_frame : 0);
+        put_bits(&s->pb, 1, s->c.progressive_frame);
         put_bits(&s->pb, 1, 0);                 /* composite_display_flag */
     }
     if (mpeg12->scan_offset) {
@@ -422,7 +422,7 @@ static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
         for (i = 0; i < sizeof(svcd_scan_offset_placeholder); i++)
             put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]);
     }
-    side_data = av_frame_get_side_data(s->cur_pic.ptr->f,
+    side_data = av_frame_get_side_data(s->c.cur_pic.ptr->f,
                                        AV_FRAME_DATA_STEREO3D);
     if (side_data) {
         const AVStereo3D *stereo = (AVStereo3D *)side_data->data;
@@ -460,7 +460,7 @@ static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
     }
 
     if (CONFIG_MPEG2VIDEO_ENCODER && mpeg12->a53_cc) {
-        side_data = av_frame_get_side_data(s->cur_pic.ptr->f,
+        side_data = av_frame_get_side_data(s->c.cur_pic.ptr->f,
             AV_FRAME_DATA_A53_CC);
         if (side_data) {
             if (side_data->size <= A53_MAX_CC_COUNT * 3 && side_data->size % 3 == 0) {
@@ -476,33 +476,33 @@ static int mpeg1_encode_picture_header(MPVMainEncContext *const m)
 
                 put_bits(&s->pb, 8, 0xff);                  // marker_bits
             } else {
-                av_log(s->avctx, AV_LOG_WARNING,
+                av_log(s->c.avctx, AV_LOG_WARNING,
                     "Closed Caption size (%"SIZE_SPECIFIER") can not exceed "
                     "93 bytes and must be a multiple of 3\n", side_data->size);
             }
         }
     }
 
-    s->mb_y = 0;
+    s->c.mb_y = 0;
     ff_mpeg1_encode_slice_header(s);
 
     return 0;
 }
 
-static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
+static inline void put_mb_modes(MPVEncContext *const s, int n, int bits,
                                 int has_mv, int field_motion)
 {
     put_bits(&s->pb, n, bits);
-    if (!s->frame_pred_frame_dct) {
+    if (!s->c.frame_pred_frame_dct) {
         if (has_mv)
             /* motion_type: frame/field */
             put_bits(&s->pb, 2, 2 - field_motion);
-        put_bits(&s->pb, 1, s->interlaced_dct);
+        put_bits(&s->pb, 1, s->c.interlaced_dct);
     }
 }
 
 // RAL: Parameter added: f_or_b_code
-static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
+static void mpeg1_encode_motion(MPVEncContext *const s, int val, int f_or_b_code)
 {
     if (val == 0) {
         /* zero vector, corresponds to ff_mpeg12_mbMotionVectorTable[0] */
@@ -539,7 +539,7 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
     }
 }
 
-static inline void encode_dc(MpegEncContext *s, int diff, int component)
+static inline void encode_dc(MPVEncContext *const s, int diff, int component)
 {
     unsigned int diff_u = diff + 255;
     if (diff_u >= 511) {
@@ -573,23 +573,23 @@ static inline void encode_dc(MpegEncContext *s, int diff, int component)
     }
 }
 
-static void mpeg1_encode_block(MpegEncContext *s, const int16_t *block, int n)
+static void mpeg1_encode_block(MPVEncContext *const s, const int16_t block[], int n)
 {
     int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
     int code, component;
     const uint16_t (*table_vlc)[2] = ff_mpeg1_vlc_table;
 
-    last_index = s->block_last_index[n];
+    last_index = s->c.block_last_index[n];
 
     /* DC coef */
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         component = (n <= 3 ? 0 : (n & 1) + 1);
         dc        = block[0];                   /* overflow is impossible */
-        diff      = dc - s->last_dc[component];
+        diff      = dc - s->c.last_dc[component];
         encode_dc(s, diff, component);
-        s->last_dc[component] = dc;
+        s->c.last_dc[component] = dc;
         i = 1;
-        if (s->intra_vlc_format)
+        if (s->c.intra_vlc_format)
             table_vlc = ff_mpeg2_vlc_table;
     } else {
         /* encode the first coefficient: needs to be done here because
@@ -610,7 +610,7 @@ static void mpeg1_encode_block(MpegEncContext *s, const int16_t *block, int n)
     last_non_zero = i - 1;
 
     for (; i <= last_index; i++) {
-        j     = s->intra_scantable.permutated[i];
+        j     = s->c.intra_scantable.permutated[i];
         level = block[j];
 
 next_coef:
@@ -634,7 +634,7 @@ next_coef:
                 put_bits(&s->pb, 6, 0x01);
                 /* escape: only clip in this case */
                 put_bits(&s->pb, 6, run);
-                if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+                if (s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO) {
                     if (alevel < 128) {
                         put_sbits(&s->pb, 8, level);
                     } else {
@@ -654,55 +654,55 @@ next_coef:
     put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]);
 }
 
-static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
+static av_always_inline void mpeg1_encode_mb_internal(MPVEncContext *const s,
                                                       const int16_t block[8][64],
                                                       int motion_x, int motion_y,
                                                       int mb_block_count,
                                                       int chroma_y_shift)
 {
 /* MPEG-1 is always 420. */
-#define IS_MPEG1(s) (chroma_y_shift == 1 && (s)->codec_id == AV_CODEC_ID_MPEG1VIDEO)
+#define IS_MPEG1(s) (chroma_y_shift == 1 && (s)->c.codec_id == AV_CODEC_ID_MPEG1VIDEO)
     int i, cbp;
-    const int mb_x     = s->mb_x;
-    const int mb_y     = s->mb_y;
-    const int first_mb = mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;
+    const int mb_x     = s->c.mb_x;
+    const int mb_y     = s->c.mb_y;
+    const int first_mb = mb_x == s->c.resync_mb_x && mb_y == s->c.resync_mb_y;
 
     /* compute cbp */
     cbp = 0;
     for (i = 0; i < mb_block_count; i++)
-        if (s->block_last_index[i] >= 0)
+        if (s->c.block_last_index[i] >= 0)
             cbp |= 1 << (mb_block_count - 1 - i);
 
-    if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 &&
-        (mb_x != s->mb_width - 1 ||
-         (mb_y != s->end_mb_y - 1 && IS_MPEG1(s))) &&
-        ((s->pict_type == AV_PICTURE_TYPE_P && (motion_x | motion_y) == 0) ||
-         (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir &&
-          (((s->mv_dir & MV_DIR_FORWARD)
-            ? ((s->mv[0][0][0] - s->last_mv[0][0][0]) |
-               (s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
-           ((s->mv_dir & MV_DIR_BACKWARD)
-            ? ((s->mv[1][0][0] - s->last_mv[1][0][0]) |
-               (s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
-        s->mb_skip_run++;
-        s->qscale -= s->dquant;
+    if (cbp == 0 && !first_mb && s->c.mv_type == MV_TYPE_16X16 &&
+        (mb_x != s->c.mb_width - 1 ||
+         (mb_y != s->c.end_mb_y - 1 && IS_MPEG1(s))) &&
+        ((s->c.pict_type == AV_PICTURE_TYPE_P && (motion_x | motion_y) == 0) ||
+         (s->c.pict_type == AV_PICTURE_TYPE_B && s->c.mv_dir == s->last_mv_dir &&
+          (((s->c.mv_dir & MV_DIR_FORWARD)
+            ? ((s->c.mv[0][0][0] - s->c.last_mv[0][0][0]) |
+               (s->c.mv[0][0][1] - s->c.last_mv[0][0][1])) : 0) |
+           ((s->c.mv_dir & MV_DIR_BACKWARD)
+            ? ((s->c.mv[1][0][0] - s->c.last_mv[1][0][0]) |
+               (s->c.mv[1][0][1] - s->c.last_mv[1][0][1])) : 0)) == 0))) {
+        s->c.mb_skip_run++;
+        s->c.qscale -= s->dquant;
         s->misc_bits++;
         s->last_bits++;
-        if (s->pict_type == AV_PICTURE_TYPE_P) {
-            s->last_mv[0][0][0] =
-            s->last_mv[0][0][1] =
-            s->last_mv[0][1][0] =
-            s->last_mv[0][1][1] = 0;
+        if (s->c.pict_type == AV_PICTURE_TYPE_P) {
+            s->c.last_mv[0][0][0] =
+            s->c.last_mv[0][0][1] =
+            s->c.last_mv[0][1][0] =
+            s->c.last_mv[0][1][1] = 0;
         }
     } else {
         if (first_mb) {
-            av_assert0(s->mb_skip_run == 0);
-            encode_mb_skip_run(s, s->mb_x);
+            av_assert0(s->c.mb_skip_run == 0);
+            encode_mb_skip_run(s, s->c.mb_x);
         } else {
-            encode_mb_skip_run(s, s->mb_skip_run);
+            encode_mb_skip_run(s, s->c.mb_skip_run);
         }
 
-        if (s->pict_type == AV_PICTURE_TYPE_I) {
+        if (s->c.pict_type == AV_PICTURE_TYPE_I) {
             if (s->dquant && cbp) {
                 /* macroblock_type: macroblock_quant = 1 */
                 put_mb_modes(s, 2, 1, 0, 0);
@@ -710,23 +710,23 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
             } else {
                 /* macroblock_type: macroblock_quant = 0 */
                 put_mb_modes(s, 1, 1, 0, 0);
-                s->qscale -= s->dquant;
+                s->c.qscale -= s->dquant;
             }
             s->misc_bits += get_bits_diff(s);
             s->i_count++;
-        } else if (s->mb_intra) {
+        } else if (s->c.mb_intra) {
             if (s->dquant && cbp) {
                 put_mb_modes(s, 6, 0x01, 0, 0);
                 put_qscale(s);
             } else {
                 put_mb_modes(s, 5, 0x03, 0, 0);
-                s->qscale -= s->dquant;
+                s->c.qscale -= s->dquant;
             }
             s->misc_bits += get_bits_diff(s);
             s->i_count++;
-            memset(s->last_mv, 0, sizeof(s->last_mv));
-        } else if (s->pict_type == AV_PICTURE_TYPE_P) {
-            if (s->mv_type == MV_TYPE_16X16) {
+            memset(s->c.last_mv, 0, sizeof(s->c.last_mv));
+        } else if (s->c.pict_type == AV_PICTURE_TYPE_P) {
+            if (s->c.mv_type == MV_TYPE_16X16) {
                 if (cbp != 0) {
                     if ((motion_x | motion_y) == 0) {
                         if (s->dquant) {
@@ -748,34 +748,34 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
                         s->misc_bits += get_bits_diff(s);
                         // RAL: f_code parameter added
                         mpeg1_encode_motion(s,
-                                            motion_x - s->last_mv[0][0][0],
-                                            s->f_code);
+                                            motion_x - s->c.last_mv[0][0][0],
+                                            s->c.f_code);
                         // RAL: f_code parameter added
                         mpeg1_encode_motion(s,
-                                            motion_y - s->last_mv[0][0][1],
-                                            s->f_code);
+                                            motion_y - s->c.last_mv[0][0][1],
+                                            s->c.f_code);
                         s->mv_bits += get_bits_diff(s);
                     }
                 } else {
                     put_bits(&s->pb, 3, 1);         /* motion only */
-                    if (!s->frame_pred_frame_dct)
+                    if (!s->c.frame_pred_frame_dct)
                         put_bits(&s->pb, 2, 2);     /* motion_type: frame */
                     s->misc_bits += get_bits_diff(s);
                     // RAL: f_code parameter added
                     mpeg1_encode_motion(s,
-                                        motion_x - s->last_mv[0][0][0],
-                                        s->f_code);
+                                        motion_x - s->c.last_mv[0][0][0],
+                                        s->c.f_code);
                     // RAL: f_code parameter added
                     mpeg1_encode_motion(s,
-                                        motion_y - s->last_mv[0][0][1],
-                                        s->f_code);
-                    s->qscale  -= s->dquant;
+                                        motion_y - s->c.last_mv[0][0][1],
+                                        s->c.f_code);
+                    s->c.qscale  -= s->dquant;
                     s->mv_bits += get_bits_diff(s);
                 }
-                s->last_mv[0][1][0] = s->last_mv[0][0][0] = motion_x;
-                s->last_mv[0][1][1] = s->last_mv[0][0][1] = motion_y;
+                s->c.last_mv[0][1][0] = s->c.last_mv[0][0][0] = motion_x;
+                s->c.last_mv[0][1][1] = s->c.last_mv[0][0][1] = motion_y;
             } else {
-                av_assert2(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);
+                av_assert2(!s->c.frame_pred_frame_dct && s->c.mv_type == MV_TYPE_FIELD);
 
                 if (cbp) {
                     if (s->dquant) {
@@ -787,19 +787,19 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
                 } else {
                     put_bits(&s->pb, 3, 1);             /* motion only */
                     put_bits(&s->pb, 2, 1);             /* motion_type: field */
-                    s->qscale -= s->dquant;
+                    s->c.qscale -= s->dquant;
                 }
                 s->misc_bits += get_bits_diff(s);
                 for (i = 0; i < 2; i++) {
-                    put_bits(&s->pb, 1, s->field_select[0][i]);
+                    put_bits(&s->pb, 1, s->c.field_select[0][i]);
                     mpeg1_encode_motion(s,
-                                        s->mv[0][i][0] - s->last_mv[0][i][0],
-                                        s->f_code);
+                                        s->c.mv[0][i][0] - s->c.last_mv[0][i][0],
+                                        s->c.f_code);
                     mpeg1_encode_motion(s,
-                                        s->mv[0][i][1] - (s->last_mv[0][i][1] >> 1),
-                                        s->f_code);
-                    s->last_mv[0][i][0] = s->mv[0][i][0];
-                    s->last_mv[0][i][1] = 2 * s->mv[0][i][1];
+                                        s->c.mv[0][i][1] - (s->c.last_mv[0][i][1] >> 1),
+                                        s->c.f_code);
+                    s->c.last_mv[0][i][0] = s->c.mv[0][i][0];
+                    s->c.last_mv[0][i][1] = 2 * s->c.mv[0][i][1];
                 }
                 s->mv_bits += get_bits_diff(s);
             }
@@ -816,91 +816,91 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
                 }
             }
         } else {
-            if (s->mv_type == MV_TYPE_16X16) {
+            if (s->c.mv_type == MV_TYPE_16X16) {
                 if (cbp) {                      // With coded bloc pattern
                     if (s->dquant) {
-                        if (s->mv_dir == MV_DIR_FORWARD)
+                        if (s->c.mv_dir == MV_DIR_FORWARD)
                             put_mb_modes(s, 6, 3, 1, 0);
                         else
-                            put_mb_modes(s, 8 - s->mv_dir, 2, 1, 0);
+                            put_mb_modes(s, 8 - s->c.mv_dir, 2, 1, 0);
                         put_qscale(s);
                     } else {
-                        put_mb_modes(s, 5 - s->mv_dir, 3, 1, 0);
+                        put_mb_modes(s, 5 - s->c.mv_dir, 3, 1, 0);
                     }
                 } else {                        // No coded bloc pattern
-                    put_bits(&s->pb, 5 - s->mv_dir, 2);
-                    if (!s->frame_pred_frame_dct)
+                    put_bits(&s->pb, 5 - s->c.mv_dir, 2);
+                    if (!s->c.frame_pred_frame_dct)
                         put_bits(&s->pb, 2, 2); /* motion_type: frame */
-                    s->qscale -= s->dquant;
+                    s->c.qscale -= s->dquant;
                 }
                 s->misc_bits += get_bits_diff(s);
-                if (s->mv_dir & MV_DIR_FORWARD) {
+                if (s->c.mv_dir & MV_DIR_FORWARD) {
                     mpeg1_encode_motion(s,
-                                        s->mv[0][0][0] - s->last_mv[0][0][0],
-                                        s->f_code);
+                                        s->c.mv[0][0][0] - s->c.last_mv[0][0][0],
+                                        s->c.f_code);
                     mpeg1_encode_motion(s,
-                                        s->mv[0][0][1] - s->last_mv[0][0][1],
-                                        s->f_code);
-                    s->last_mv[0][0][0] =
-                    s->last_mv[0][1][0] = s->mv[0][0][0];
-                    s->last_mv[0][0][1] =
-                    s->last_mv[0][1][1] = s->mv[0][0][1];
+                                        s->c.mv[0][0][1] - s->c.last_mv[0][0][1],
+                                        s->c.f_code);
+                    s->c.last_mv[0][0][0] =
+                    s->c.last_mv[0][1][0] = s->c.mv[0][0][0];
+                    s->c.last_mv[0][0][1] =
+                    s->c.last_mv[0][1][1] = s->c.mv[0][0][1];
                 }
-                if (s->mv_dir & MV_DIR_BACKWARD) {
+                if (s->c.mv_dir & MV_DIR_BACKWARD) {
                     mpeg1_encode_motion(s,
-                                        s->mv[1][0][0] - s->last_mv[1][0][0],
-                                        s->b_code);
+                                        s->c.mv[1][0][0] - s->c.last_mv[1][0][0],
+                                        s->c.b_code);
                     mpeg1_encode_motion(s,
-                                        s->mv[1][0][1] - s->last_mv[1][0][1],
-                                        s->b_code);
-                    s->last_mv[1][0][0] =
-                    s->last_mv[1][1][0] = s->mv[1][0][0];
-                    s->last_mv[1][0][1] =
-                    s->last_mv[1][1][1] = s->mv[1][0][1];
+                                        s->c.mv[1][0][1] - s->c.last_mv[1][0][1],
+                                        s->c.b_code);
+                    s->c.last_mv[1][0][0] =
+                    s->c.last_mv[1][1][0] = s->c.mv[1][0][0];
+                    s->c.last_mv[1][0][1] =
+                    s->c.last_mv[1][1][1] = s->c.mv[1][0][1];
                 }
             } else {
-                av_assert2(s->mv_type == MV_TYPE_FIELD);
-                av_assert2(!s->frame_pred_frame_dct);
+                av_assert2(s->c.mv_type == MV_TYPE_FIELD);
+                av_assert2(!s->c.frame_pred_frame_dct);
                 if (cbp) {                      // With coded bloc pattern
                     if (s->dquant) {
-                        if (s->mv_dir == MV_DIR_FORWARD)
+                        if (s->c.mv_dir == MV_DIR_FORWARD)
                             put_mb_modes(s, 6, 3, 1, 1);
                         else
-                            put_mb_modes(s, 8 - s->mv_dir, 2, 1, 1);
+                            put_mb_modes(s, 8 - s->c.mv_dir, 2, 1, 1);
                         put_qscale(s);
                     } else {
-                        put_mb_modes(s, 5 - s->mv_dir, 3, 1, 1);
+                        put_mb_modes(s, 5 - s->c.mv_dir, 3, 1, 1);
                     }
                 } else {                        // No coded bloc pattern
-                    put_bits(&s->pb, 5 - s->mv_dir, 2);
+                    put_bits(&s->pb, 5 - s->c.mv_dir, 2);
                     put_bits(&s->pb, 2, 1);     /* motion_type: field */
-                    s->qscale -= s->dquant;
+                    s->c.qscale -= s->dquant;
                 }
                 s->misc_bits += get_bits_diff(s);
-                if (s->mv_dir & MV_DIR_FORWARD) {
+                if (s->c.mv_dir & MV_DIR_FORWARD) {
                     for (i = 0; i < 2; i++) {
-                        put_bits(&s->pb, 1, s->field_select[0][i]);
+                        put_bits(&s->pb, 1, s->c.field_select[0][i]);
                         mpeg1_encode_motion(s,
-                                            s->mv[0][i][0] - s->last_mv[0][i][0],
-                                            s->f_code);
+                                            s->c.mv[0][i][0] - s->c.last_mv[0][i][0],
+                                            s->c.f_code);
                         mpeg1_encode_motion(s,
-                                            s->mv[0][i][1] - (s->last_mv[0][i][1] >> 1),
-                                            s->f_code);
-                        s->last_mv[0][i][0] = s->mv[0][i][0];
-                        s->last_mv[0][i][1] = s->mv[0][i][1] * 2;
+                                            s->c.mv[0][i][1] - (s->c.last_mv[0][i][1] >> 1),
+                                            s->c.f_code);
+                        s->c.last_mv[0][i][0] = s->c.mv[0][i][0];
+                        s->c.last_mv[0][i][1] = s->c.mv[0][i][1] * 2;
                     }
                 }
-                if (s->mv_dir & MV_DIR_BACKWARD) {
+                if (s->c.mv_dir & MV_DIR_BACKWARD) {
                     for (i = 0; i < 2; i++) {
-                        put_bits(&s->pb, 1, s->field_select[1][i]);
+                        put_bits(&s->pb, 1, s->c.field_select[1][i]);
                         mpeg1_encode_motion(s,
-                                            s->mv[1][i][0] - s->last_mv[1][i][0],
-                                            s->b_code);
+                                            s->c.mv[1][i][0] - s->c.last_mv[1][i][0],
+                                            s->c.b_code);
                         mpeg1_encode_motion(s,
-                                            s->mv[1][i][1] - (s->last_mv[1][i][1] >> 1),
-                                            s->b_code);
-                        s->last_mv[1][i][0] = s->mv[1][i][0];
-                        s->last_mv[1][i][1] = s->mv[1][i][1] * 2;
+                                            s->c.mv[1][i][1] - (s->c.last_mv[1][i][1] >> 1),
+                                            s->c.b_code);
+                        s->c.last_mv[1][i][0] = s->c.mv[1][i][0];
+                        s->c.last_mv[1][i][1] = s->c.mv[1][i][1] * 2;
                     }
                 }
             }
@@ -921,20 +921,20 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
         for (i = 0; i < mb_block_count; i++)
             if (cbp & (1 << (mb_block_count - 1 - i)))
                 mpeg1_encode_block(s, block[i], i);
-        s->mb_skip_run = 0;
-        if (s->mb_intra)
+        s->c.mb_skip_run = 0;
+        if (s->c.mb_intra)
             s->i_tex_bits += get_bits_diff(s);
         else
             s->p_tex_bits += get_bits_diff(s);
     }
 }
 
-static void mpeg12_encode_mb(MpegEncContext *s, int16_t block[][64],
+static void mpeg12_encode_mb(MPVEncContext *const s, int16_t block[][64],
                              int motion_x, int motion_y)
 {
-    if (!s->mb_intra)
-        s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 128 << s->intra_dc_precision;
-    if (s->chroma_format == CHROMA_420)
+    if (!s->c.mb_intra)
+        s->c.last_dc[0] = s->c.last_dc[1] = s->c.last_dc[2] = 128 << s->c.intra_dc_precision;
+    if (s->c.chroma_format == CHROMA_420)
         mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6, 1);
     else
         mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8, 0);
@@ -1048,7 +1048,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     static AVOnce init_static_once = AV_ONCE_INIT;
     MPEG12EncContext *const mpeg12 = avctx->priv_data;
     MPVMainEncContext *const m = &mpeg12->mpeg;
-    MpegEncContext    *const s = &m->s;
+    MPVEncContext    *const s = &m->s;
     int ret;
     int max_size = avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 16383 : 4095;
 
@@ -1071,7 +1071,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
-    if (s->q_scale_type == 1) {
+    if (s->c.q_scale_type == 1) {
         if (avctx->qmax > 28) {
             av_log(avctx, AV_LOG_ERROR,
                    "non linear quant only supports qmax <= 28 currently\n");
@@ -1113,7 +1113,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     m->encode_picture_header = mpeg1_encode_picture_header;
     s->encode_mb             = mpeg12_encode_mb;
 
-    s->me.mv_penalty = mv_penalty;
+    s->c.me.mv_penalty = mv_penalty;
     m->fcode_tab     = fcode_tab + MAX_MV;
     if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
         s->min_qcoeff = -255;
@@ -1121,9 +1121,9 @@ static av_cold int encode_init(AVCodecContext *avctx)
     } else {
         s->min_qcoeff = -2047;
         s->max_qcoeff = 2047;
-        s->mpeg_quant = 1;
+        s->c.mpeg_quant = 1;
     }
-    if (s->intra_vlc_format) {
+    if (s->c.intra_vlc_format) {
         s->intra_ac_vlc_length      =
         s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len;
     } else {
@@ -1138,7 +1138,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         return ret;
 
     if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
-        s->thread_context[s->slice_context_count - 1]->start_mb_y >
+        s->c.thread_context[s->c.slice_context_count - 1]->start_mb_y >
             SLICE_MAX_START_CODE - SLICE_MIN_START_CODE) {
         // MPEG-1 slices must not start at a MB row number that would make
         // their start code > SLICE_MAX_START_CODE. So make the last slice
@@ -1148,15 +1148,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
                       "the case in which there is no work to do for some "
                       "slice contexts.");
         const int mb_height = SLICE_MAX_START_CODE - SLICE_MIN_START_CODE;
-        const int nb_slices = s->slice_context_count - 1;
+        const int nb_slices = s->c.slice_context_count - 1;
 
-        s->thread_context[nb_slices]->start_mb_y = mb_height;
+        s->c.thread_context[nb_slices]->start_mb_y = mb_height;
 
         av_assert1(nb_slices >= 1);
         for (int i = 0; i < nb_slices; i++) {
-            s->thread_context[i]->start_mb_y =
+            s->c.thread_context[i]->start_mb_y =
                 (mb_height * (i    ) + nb_slices / 2) / nb_slices;
-            s->thread_context[i]->end_mb_y   =
+            s->c.thread_context[i]->end_mb_y   =
                 (mb_height * (i + 1) + nb_slices / 2) / nb_slices;
         }
     }
@@ -1229,9 +1229,9 @@ static const AVOption mpeg1_options[] = {
 static const AVOption mpeg2_options[] = {
     COMMON_OPTS
     { "intra_vlc",        "Use MPEG-2 intra VLC table.",
-      FF_MPV_OFFSET(intra_vlc_format),    AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
-    { "non_linear_quant", "Use nonlinear quantizer.",    FF_MPV_OFFSET(q_scale_type),   AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
-    { "alternate_scan",   "Enable alternate scantable.", FF_MPV_OFFSET(alternate_scan), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+      FF_MPV_OFFSET(c.intra_vlc_format),    AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+    { "non_linear_quant", "Use nonlinear quantizer.",    FF_MPV_OFFSET(c.q_scale_type),   AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+    { "alternate_scan",   "Enable alternate scantable.", FF_MPV_OFFSET(c.alternate_scan), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
     { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc),         AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
     { "seq_disp_ext",     "Write sequence_display_extension blocks.", OFFSET(seq_disp_ext), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE, .unit = "seq_disp_ext" },
     {     "auto",   NULL, 0, AV_OPT_TYPE_CONST,  {.i64 = -1},  0, 0, VE, .unit = "seq_disp_ext" },
diff --git a/libavcodec/mpeg12enc.h b/libavcodec/mpeg12enc.h
index 8ffa471a63..a8aeadbb3e 100644
--- a/libavcodec/mpeg12enc.h
+++ b/libavcodec/mpeg12enc.h
@@ -24,16 +24,16 @@
 
 #include <stdint.h>
 
-#include "mpegvideo.h"
+#include "mpegvideoenc.h"
 #include "mpegvideodata.h"
 
-void ff_mpeg1_encode_slice_header(MpegEncContext *s);
+void ff_mpeg1_encode_slice_header(MPVEncContext *s);
 
 // Must not be called before intra_dc_precision has been sanitized in ff_mpv_encode_init()
-static inline void ff_mpeg1_encode_init(MpegEncContext *s)
+static inline void ff_mpeg1_encode_init(MPVEncContext *s)
 {
-    s->y_dc_scale_table =
-    s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
+    s->c.y_dc_scale_table =
+    s->c.c_dc_scale_table = ff_mpeg12_dc_scale_table[s->c.intra_dc_precision];
 }
 
 #endif /* AVCODEC_MPEG12ENC_H */
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index ddb6958229..9f933b517e 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -86,7 +86,7 @@ static inline Mpeg4EncContext *mainctx_to_mpeg4(MPVMainEncContext *m)
  * Return the number of bits that encoding the 8x8 block in block would need.
  * @param[in]  block_last_index last index in scantable order that refers to a non zero element in block.
  */
-static inline int get_block_rate(MpegEncContext *s, int16_t block[64],
+static inline int get_block_rate(MPVEncContext *const s, int16_t block[64],
                                  int block_last_index, const uint8_t scantable[64])
 {
     int last = 0;
@@ -115,113 +115,113 @@ static inline int get_block_rate(MpegEncContext *s, int16_t block[64],
 
 /**
  * Restore the ac coefficients in block that have been changed by decide_ac_pred().
- * This function also restores s->block_last_index.
+ * This function also restores s->c.block_last_index.
  * @param[in,out] block MB coefficients, these will be restored
  * @param[in] dir ac prediction direction for each 8x8 block
  * @param[out] st scantable for each 8x8 block
  * @param[in] zigzag_last_index index referring to the last non zero coefficient in zigzag order
  */
-static inline void restore_ac_coeffs(MpegEncContext *s, int16_t block[6][64],
+static inline void restore_ac_coeffs(MPVEncContext *const s, int16_t block[6][64],
                                      const int dir[6], const uint8_t *st[6],
                                      const int zigzag_last_index[6])
 {
     int i, n;
-    memcpy(s->block_last_index, zigzag_last_index, sizeof(int) * 6);
+    memcpy(s->c.block_last_index, zigzag_last_index, sizeof(int) * 6);
 
     for (n = 0; n < 6; n++) {
-        int16_t *ac_val = &s->ac_val[0][0][0] + s->block_index[n] * 16;
+        int16_t *ac_val = &s->c.ac_val[0][0][0] + s->c.block_index[n] * 16;
 
-        st[n] = s->intra_scantable.permutated;
+        st[n] = s->c.intra_scantable.permutated;
         if (dir[n]) {
             /* top prediction */
             for (i = 1; i < 8; i++)
-                block[n][s->idsp.idct_permutation[i]] = ac_val[i + 8];
+                block[n][s->c.idsp.idct_permutation[i]] = ac_val[i + 8];
         } else {
             /* left prediction */
             for (i = 1; i < 8; i++)
-                block[n][s->idsp.idct_permutation[i << 3]] = ac_val[i];
+                block[n][s->c.idsp.idct_permutation[i << 3]] = ac_val[i];
         }
     }
 }
 
 /**
  * Return the optimal value (0 or 1) for the ac_pred element for the given MB in MPEG-4.
- * This function will also update s->block_last_index and s->ac_val.
+ * This function will also update s->c.block_last_index and s->c.ac_val.
  * @param[in,out] block MB coefficients, these will be updated if 1 is returned
  * @param[in] dir ac prediction direction for each 8x8 block
  * @param[out] st scantable for each 8x8 block
  * @param[out] zigzag_last_index index referring to the last non zero coefficient in zigzag order
  */
-static inline int decide_ac_pred(MpegEncContext *s, int16_t block[6][64],
+static inline int decide_ac_pred(MPVEncContext *const s, int16_t block[6][64],
                                  const int dir[6], const uint8_t *st[6],
                                  int zigzag_last_index[6])
 {
     int score = 0;
     int i, n;
-    const int8_t *const qscale_table = s->cur_pic.qscale_table;
+    const int8_t *const qscale_table = s->c.cur_pic.qscale_table;
 
-    memcpy(zigzag_last_index, s->block_last_index, sizeof(int) * 6);
+    memcpy(zigzag_last_index, s->c.block_last_index, sizeof(int) * 6);
 
     for (n = 0; n < 6; n++) {
         int16_t *ac_val, *ac_val1;
 
-        score -= get_block_rate(s, block[n], s->block_last_index[n],
-                                s->intra_scantable.permutated);
+        score -= get_block_rate(s, block[n], s->c.block_last_index[n],
+                                s->c.intra_scantable.permutated);
 
-        ac_val  = &s->ac_val[0][0][0] + s->block_index[n] * 16;
+        ac_val  = &s->c.ac_val[0][0][0] + s->c.block_index[n] * 16;
         ac_val1 = ac_val;
         if (dir[n]) {
-            const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
+            const int xy = s->c.mb_x + s->c.mb_y * s->c.mb_stride - s->c.mb_stride;
             /* top prediction */
-            ac_val -= s->block_wrap[n] * 16;
-            if (s->mb_y == 0 || s->qscale == qscale_table[xy] || n == 2 || n == 3) {
+            ac_val -= s->c.block_wrap[n] * 16;
+            if (s->c.mb_y == 0 || s->c.qscale == qscale_table[xy] || n == 2 || n == 3) {
                 /* same qscale */
                 for (i = 1; i < 8; i++) {
-                    const int level = block[n][s->idsp.idct_permutation[i]];
-                    block[n][s->idsp.idct_permutation[i]] = level - ac_val[i + 8];
-                    ac_val1[i]     = block[n][s->idsp.idct_permutation[i << 3]];
+                    const int level = block[n][s->c.idsp.idct_permutation[i]];
+                    block[n][s->c.idsp.idct_permutation[i]] = level - ac_val[i + 8];
+                    ac_val1[i]     = block[n][s->c.idsp.idct_permutation[i << 3]];
                     ac_val1[i + 8] = level;
                 }
             } else {
                 /* different qscale, we must rescale */
                 for (i = 1; i < 8; i++) {
-                    const int level = block[n][s->idsp.idct_permutation[i]];
-                    block[n][s->idsp.idct_permutation[i]] = level - ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
-                    ac_val1[i]     = block[n][s->idsp.idct_permutation[i << 3]];
+                    const int level = block[n][s->c.idsp.idct_permutation[i]];
+                    block[n][s->c.idsp.idct_permutation[i]] = level - ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->c.qscale);
+                    ac_val1[i]     = block[n][s->c.idsp.idct_permutation[i << 3]];
                     ac_val1[i + 8] = level;
                 }
             }
-            st[n] = s->permutated_intra_h_scantable;
+            st[n] = s->c.permutated_intra_h_scantable;
         } else {
-            const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
+            const int xy = s->c.mb_x - 1 + s->c.mb_y * s->c.mb_stride;
             /* left prediction */
             ac_val -= 16;
-            if (s->mb_x == 0 || s->qscale == qscale_table[xy] || n == 1 || n == 3) {
+            if (s->c.mb_x == 0 || s->c.qscale == qscale_table[xy] || n == 1 || n == 3) {
                 /* same qscale */
                 for (i = 1; i < 8; i++) {
-                    const int level = block[n][s->idsp.idct_permutation[i << 3]];
-                    block[n][s->idsp.idct_permutation[i << 3]] = level - ac_val[i];
+                    const int level = block[n][s->c.idsp.idct_permutation[i << 3]];
+                    block[n][s->c.idsp.idct_permutation[i << 3]] = level - ac_val[i];
                     ac_val1[i]     = level;
-                    ac_val1[i + 8] = block[n][s->idsp.idct_permutation[i]];
+                    ac_val1[i + 8] = block[n][s->c.idsp.idct_permutation[i]];
                 }
             } else {
                 /* different qscale, we must rescale */
                 for (i = 1; i < 8; i++) {
-                    const int level = block[n][s->idsp.idct_permutation[i << 3]];
-                    block[n][s->idsp.idct_permutation[i << 3]] = level - ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
+                    const int level = block[n][s->c.idsp.idct_permutation[i << 3]];
+                    block[n][s->c.idsp.idct_permutation[i << 3]] = level - ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->c.qscale);
                     ac_val1[i]     = level;
-                    ac_val1[i + 8] = block[n][s->idsp.idct_permutation[i]];
+                    ac_val1[i + 8] = block[n][s->c.idsp.idct_permutation[i]];
                 }
             }
-            st[n] = s->permutated_intra_v_scantable;
+            st[n] = s->c.permutated_intra_v_scantable;
         }
 
         for (i = 63; i > 0; i--)  // FIXME optimize
             if (block[n][st[n][i]])
                 break;
-        s->block_last_index[n] = i;
+        s->c.block_last_index[n] = i;
 
-        score += get_block_rate(s, block[n], s->block_last_index[n], st[n]);
+        score += get_block_rate(s, block[n], s->c.block_last_index[n], st[n]);
     }
 
     if (score < 0) {
@@ -235,39 +235,38 @@ static inline int decide_ac_pred(MpegEncContext *s, int16_t block[6][64],
 /**
  * modify mb_type & qscale so that encoding is actually possible in MPEG-4
  */
-void ff_clean_mpeg4_qscales(MpegEncContext *s)
+void ff_clean_mpeg4_qscales(MPVEncContext *const s)
 {
-    int i;
-    int8_t *const qscale_table = s->cur_pic.qscale_table;
+    int8_t *const qscale_table = s->c.cur_pic.qscale_table;
 
     ff_clean_h263_qscales(s);
 
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
+    if (s->c.pict_type == AV_PICTURE_TYPE_B) {
         int odd = 0;
         /* ok, come on, this isn't funny anymore, there's more code for
          * handling this MPEG-4 mess than for the actual adaptive quantization */
 
-        for (i = 0; i < s->mb_num; i++) {
-            int mb_xy = s->mb_index2xy[i];
+        for (int i = 0; i < s->c.mb_num; i++) {
+            int mb_xy = s->c.mb_index2xy[i];
             odd += qscale_table[mb_xy] & 1;
         }
 
-        if (2 * odd > s->mb_num)
+        if (2 * odd > s->c.mb_num)
             odd = 1;
         else
             odd = 0;
 
-        for (i = 0; i < s->mb_num; i++) {
-            int mb_xy = s->mb_index2xy[i];
+        for (int i = 0; i < s->c.mb_num; i++) {
+            int mb_xy = s->c.mb_index2xy[i];
             if ((qscale_table[mb_xy] & 1) != odd)
                 qscale_table[mb_xy]++;
             if (qscale_table[mb_xy] > 31)
                 qscale_table[mb_xy] = 31;
         }
 
-        for (i = 1; i < s->mb_num; i++) {
-            int mb_xy = s->mb_index2xy[i];
-            if (qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i - 1]] &&
+        for (int i = 1; i < s->c.mb_num; i++) {
+            int mb_xy = s->c.mb_index2xy[i];
+            if (qscale_table[mb_xy] != qscale_table[s->c.mb_index2xy[i - 1]] &&
                 (s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_DIRECT)) {
                 s->mb_type[mb_xy] |= CANDIDATE_MB_TYPE_BIDIR;
             }
@@ -304,7 +303,7 @@ static inline int mpeg4_get_dc_length(int level, int n)
  * Encode an 8x8 block.
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static inline void mpeg4_encode_block(const MpegEncContext *s,
+static inline void mpeg4_encode_block(const MPVEncContext *const s,
                                       const int16_t *block, int n, int intra_dc,
                                       const uint8_t *scan_table, PutBitContext *dc_pb,
                                       PutBitContext *ac_pb)
@@ -312,9 +311,9 @@ static inline void mpeg4_encode_block(const MpegEncContext *s,
     int i, last_non_zero;
     const uint32_t *bits_tab;
     const uint8_t *len_tab;
-    const int last_index = s->block_last_index[n];
+    const int last_index = s->c.block_last_index[n];
 
-    if (s->mb_intra) {  // Note gcc (3.2.1 at least) will optimize this away
+    if (s->c.mb_intra) {  // Note gcc (3.2.1 at least) will optimize this away
         /* MPEG-4 based DC predictor */
         mpeg4_encode_dc(dc_pb, intra_dc, n);
         if (last_index < 1)
@@ -365,16 +364,16 @@ static inline void mpeg4_encode_block(const MpegEncContext *s,
     }
 }
 
-static int mpeg4_get_block_length(MpegEncContext *s,
+static int mpeg4_get_block_length(MPVEncContext *const s,
                                   const int16_t *block, int n,
                                   int intra_dc, const uint8_t *scan_table)
 {
     int i, last_non_zero;
     const uint8_t *len_tab;
-    const int last_index = s->block_last_index[n];
+    const int last_index = s->c.block_last_index[n];
     int len = 0;
 
-    if (s->mb_intra) {  // Note gcc (3.2.1 at least) will optimize this away
+    if (s->c.mb_intra) {  // Note gcc (3.2.1 at least) will optimize this away
         /* MPEG-4 based DC predictor */
         len += mpeg4_get_dc_length(intra_dc, n);
         if (last_index < 1)
@@ -419,7 +418,7 @@ static int mpeg4_get_block_length(MpegEncContext *s,
     return len;
 }
 
-static inline void mpeg4_encode_blocks(MpegEncContext *s,
+static inline void mpeg4_encode_blocks(MPVEncContext *const s,
                                        const int16_t block[6][64],
                                        const int intra_dc[6],
                                        const uint8_t * const *scan_table,
@@ -429,7 +428,7 @@ static inline void mpeg4_encode_blocks(MpegEncContext *s,
     int i;
 
     if (scan_table) {
-        if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT) {
+        if (s->c.avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT) {
             for (i = 0; i < 6; i++)
                 skip_put_bits(&s->pb,
                               mpeg4_get_block_length(s, block[i], i,
@@ -441,28 +440,28 @@ static inline void mpeg4_encode_blocks(MpegEncContext *s,
                                    intra_dc[i], scan_table[i], dc_pb, ac_pb);
         }
     } else {
-        if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT) {
+        if (s->c.avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT) {
             for (i = 0; i < 6; i++)
                 skip_put_bits(&s->pb,
                               mpeg4_get_block_length(s, block[i], i, 0,
-                                                     s->intra_scantable.permutated));
+                                                     s->c.intra_scantable.permutated));
         } else {
             /* encode each block */
             for (i = 0; i < 6; i++)
                 mpeg4_encode_block(s, block[i], i, 0,
-                                   s->intra_scantable.permutated, dc_pb, ac_pb);
+                                   s->c.intra_scantable.permutated, dc_pb, ac_pb);
         }
     }
 }
 
-static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
+static inline int get_b_cbp(MPVEncContext *const s, int16_t block[6][64],
                             int motion_x, int motion_y, int mb_type)
 {
     int cbp = 0, i;
 
     if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) {
         int score        = 0;
-        const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
+        const int lambda = s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6);
 
         for (i = 0; i < 6; i++) {
             if (s->coded_score[i] < 0) {
@@ -482,14 +481,14 @@ static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
         }
 
         for (i = 0; i < 6; i++) {
-            if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i)) & 1) == 0) {
-                s->block_last_index[i] = -1;
-                s->bdsp.clear_block(s->block[i]);
+            if (s->c.block_last_index[i] >= 0 && ((cbp >> (5 - i)) & 1) == 0) {
+                s->c.block_last_index[i] = -1;
+                s->c.bdsp.clear_block(s->c.block[i]);
             }
         }
     } else {
         for (i = 0; i < 6; i++) {
-            if (s->block_last_index[i] >= 0)
+            if (s->c.block_last_index[i] >= 0)
                 cbp |= 1 << (5 - i);
         }
     }
@@ -499,29 +498,29 @@ static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
 // FIXME this is duplicated to h263.c
 static const int dquant_code[5] = { 1, 0, 9, 2, 3 };
 
-static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
+static void mpeg4_encode_mb(MPVEncContext *const s, int16_t block[][64],
                             int motion_x, int motion_y)
 {
     int cbpc, cbpy, pred_x, pred_y;
-    PutBitContext *const pb2    = s->data_partitioning ? &s->pb2 : &s->pb;
-    PutBitContext *const tex_pb = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb;
-    PutBitContext *const dc_pb  = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb;
-    const int interleaved_stats = (s->avctx->flags & AV_CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0;
+    PutBitContext *const pb2    = s->c.data_partitioning ? &s->pb2 : &s->pb;
+    PutBitContext *const tex_pb = s->c.data_partitioning && s->c.pict_type != AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb;
+    PutBitContext *const dc_pb  = s->c.data_partitioning && s->c.pict_type != AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb;
+    const int interleaved_stats = (s->c.avctx->flags & AV_CODEC_FLAG_PASS1) && !s->c.data_partitioning ? 1 : 0;
 
-    if (!s->mb_intra) {
+    if (!s->c.mb_intra) {
         int i, cbp;
 
-        if (s->pict_type == AV_PICTURE_TYPE_B) {
+        if (s->c.pict_type == AV_PICTURE_TYPE_B) {
             /* convert from mv_dir to type */
             static const int mb_type_table[8] = { -1, 3, 2, 1, -1, -1, -1, 0 };
-            int mb_type = mb_type_table[s->mv_dir];
+            int mb_type = mb_type_table[s->c.mv_dir];
 
-            if (s->mb_x == 0) {
+            if (s->c.mb_x == 0) {
                 for (i = 0; i < 2; i++)
-                    s->last_mv[i][0][0] =
-                    s->last_mv[i][0][1] =
-                    s->last_mv[i][1][0] =
-                    s->last_mv[i][1][1] = 0;
+                    s->c.last_mv[i][0][0] =
+                    s->c.last_mv[i][0][1] =
+                    s->c.last_mv[i][1][0] =
+                    s->c.last_mv[i][1][1] = 0;
             }
 
             av_assert2(s->dquant >= -2 && s->dquant <= 2);
@@ -529,14 +528,14 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
             av_assert2(mb_type >= 0);
 
             /* nothing to do if this MB was skipped in the next P-frame */
-            if (s->next_pic.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) {  // FIXME avoid DCT & ...
-                s->mv[0][0][0] =
-                s->mv[0][0][1] =
-                s->mv[1][0][0] =
-                s->mv[1][0][1] = 0;
-                s->mv_dir  = MV_DIR_FORWARD;  // doesn't matter
-                s->qscale -= s->dquant;
-//                s->mb_skipped = 1;
+            if (s->c.next_pic.mbskip_table[s->c.mb_y * s->c.mb_stride + s->c.mb_x]) {  // FIXME avoid DCT & ...
+                s->c.mv[0][0][0] =
+                s->c.mv[0][0][1] =
+                s->c.mv[1][0][0] =
+                s->c.mv[1][0][1] = 0;
+                s->c.mv_dir  = MV_DIR_FORWARD;  // doesn't matter
+                s->c.qscale -= s->dquant;
+//                s->c.mb_skipped = 1;
 
                 return;
             }
@@ -568,71 +567,71 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                 else
                     put_bits(&s->pb, 1, 0);
             } else
-                s->qscale -= s->dquant;
+                s->c.qscale -= s->dquant;
 
-            if (!s->progressive_sequence) {
+            if (!s->c.progressive_sequence) {
                 if (cbp)
-                    put_bits(&s->pb, 1, s->interlaced_dct);
+                    put_bits(&s->pb, 1, s->c.interlaced_dct);
                 if (mb_type)                  // not direct mode
-                    put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD);
+                    put_bits(&s->pb, 1, s->c.mv_type == MV_TYPE_FIELD);
             }
 
             if (interleaved_stats)
                 s->misc_bits += get_bits_diff(s);
 
             if (!mb_type) {
-                av_assert2(s->mv_dir & MV_DIRECT);
+                av_assert2(s->c.mv_dir & MV_DIRECT);
                 ff_h263_encode_motion_vector(s, motion_x, motion_y, 1);
             } else {
                 av_assert2(mb_type > 0 && mb_type < 4);
-                if (s->mv_type != MV_TYPE_FIELD) {
-                    if (s->mv_dir & MV_DIR_FORWARD) {
+                if (s->c.mv_type != MV_TYPE_FIELD) {
+                    if (s->c.mv_dir & MV_DIR_FORWARD) {
                         ff_h263_encode_motion_vector(s,
-                                                     s->mv[0][0][0] - s->last_mv[0][0][0],
-                                                     s->mv[0][0][1] - s->last_mv[0][0][1],
-                                                     s->f_code);
-                        s->last_mv[0][0][0] =
-                        s->last_mv[0][1][0] = s->mv[0][0][0];
-                        s->last_mv[0][0][1] =
-                        s->last_mv[0][1][1] = s->mv[0][0][1];
+                                                     s->c.mv[0][0][0] - s->c.last_mv[0][0][0],
+                                                     s->c.mv[0][0][1] - s->c.last_mv[0][0][1],
+                                                     s->c.f_code);
+                        s->c.last_mv[0][0][0] =
+                        s->c.last_mv[0][1][0] = s->c.mv[0][0][0];
+                        s->c.last_mv[0][0][1] =
+                        s->c.last_mv[0][1][1] = s->c.mv[0][0][1];
                     }
-                    if (s->mv_dir & MV_DIR_BACKWARD) {
+                    if (s->c.mv_dir & MV_DIR_BACKWARD) {
                         ff_h263_encode_motion_vector(s,
-                                                     s->mv[1][0][0] - s->last_mv[1][0][0],
-                                                     s->mv[1][0][1] - s->last_mv[1][0][1],
-                                                     s->b_code);
-                        s->last_mv[1][0][0] =
-                        s->last_mv[1][1][0] = s->mv[1][0][0];
-                        s->last_mv[1][0][1] =
-                        s->last_mv[1][1][1] = s->mv[1][0][1];
+                                                     s->c.mv[1][0][0] - s->c.last_mv[1][0][0],
+                                                     s->c.mv[1][0][1] - s->c.last_mv[1][0][1],
+                                                     s->c.b_code);
+                        s->c.last_mv[1][0][0] =
+                        s->c.last_mv[1][1][0] = s->c.mv[1][0][0];
+                        s->c.last_mv[1][0][1] =
+                        s->c.last_mv[1][1][1] = s->c.mv[1][0][1];
                     }
                 } else {
-                    if (s->mv_dir & MV_DIR_FORWARD) {
-                        put_bits(&s->pb, 1, s->field_select[0][0]);
-                        put_bits(&s->pb, 1, s->field_select[0][1]);
+                    if (s->c.mv_dir & MV_DIR_FORWARD) {
+                        put_bits(&s->pb, 1, s->c.field_select[0][0]);
+                        put_bits(&s->pb, 1, s->c.field_select[0][1]);
                     }
-                    if (s->mv_dir & MV_DIR_BACKWARD) {
-                        put_bits(&s->pb, 1, s->field_select[1][0]);
-                        put_bits(&s->pb, 1, s->field_select[1][1]);
+                    if (s->c.mv_dir & MV_DIR_BACKWARD) {
+                        put_bits(&s->pb, 1, s->c.field_select[1][0]);
+                        put_bits(&s->pb, 1, s->c.field_select[1][1]);
                     }
-                    if (s->mv_dir & MV_DIR_FORWARD) {
+                    if (s->c.mv_dir & MV_DIR_FORWARD) {
                         for (i = 0; i < 2; i++) {
                             ff_h263_encode_motion_vector(s,
-                                                         s->mv[0][i][0] - s->last_mv[0][i][0],
-                                                         s->mv[0][i][1] - s->last_mv[0][i][1] / 2,
-                                                         s->f_code);
-                            s->last_mv[0][i][0] = s->mv[0][i][0];
-                            s->last_mv[0][i][1] = s->mv[0][i][1] * 2;
+                                                         s->c.mv[0][i][0] - s->c.last_mv[0][i][0],
+                                                         s->c.mv[0][i][1] - s->c.last_mv[0][i][1] / 2,
+                                                         s->c.f_code);
+                            s->c.last_mv[0][i][0] = s->c.mv[0][i][0];
+                            s->c.last_mv[0][i][1] = s->c.mv[0][i][1] * 2;
                         }
                     }
-                    if (s->mv_dir & MV_DIR_BACKWARD) {
+                    if (s->c.mv_dir & MV_DIR_BACKWARD) {
                         for (i = 0; i < 2; i++) {
                             ff_h263_encode_motion_vector(s,
-                                                         s->mv[1][i][0] - s->last_mv[1][i][0],
-                                                         s->mv[1][i][1] - s->last_mv[1][i][1] / 2,
-                                                         s->b_code);
-                            s->last_mv[1][i][0] = s->mv[1][i][0];
-                            s->last_mv[1][i][1] = s->mv[1][i][1] * 2;
+                                                         s->c.mv[1][i][0] - s->c.last_mv[1][i][0],
+                                                         s->c.mv[1][i][1] - s->c.last_mv[1][i][1] / 2,
+                                                         s->c.b_code);
+                            s->c.last_mv[1][i][0] = s->c.mv[1][i][0];
+                            s->c.last_mv[1][i][1] = s->c.mv[1][i][1] * 2;
                         }
                     }
                 }
@@ -645,11 +644,11 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
 
             if (interleaved_stats)
                 s->p_tex_bits += get_bits_diff(s);
-        } else { /* s->pict_type==AV_PICTURE_TYPE_B */
+        } else { /* s->c.pict_type==AV_PICTURE_TYPE_B */
             cbp = get_p_cbp(s, block, motion_x, motion_y);
 
             if ((cbp | motion_x | motion_y | s->dquant) == 0 &&
-                s->mv_type == MV_TYPE_16X16) {
+                s->c.mv_type == MV_TYPE_16X16) {
                 const MPVMainEncContext *const m = slice_to_mainenc(s);
                 /* Check if the B-frames can skip it too, as we must skip it
                  * if we skip here why didn't they just compress
@@ -658,13 +657,13 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                     int x, y, offset;
                     const uint8_t *p_pic;
 
-                    x = s->mb_x * 16;
-                    y = s->mb_y * 16;
+                    x = s->c.mb_x * 16;
+                    y = s->c.mb_y * 16;
 
-                    offset = x + y * s->linesize;
+                    offset = x + y * s->c.linesize;
                     p_pic  = s->new_pic->data[0] + offset;
 
-                    s->mb_skipped = 1;
+                    s->c.mb_skipped = 1;
                     for (int i = 0; i < m->max_b_frames; i++) {
                         const uint8_t *b_pic;
                         int diff;
@@ -677,29 +676,29 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                         if (!pic->shared)
                             b_pic += INPLACE_OFFSET;
 
-                        if (x + 16 > s->width || y + 16 > s->height) {
+                        if (x + 16 > s->c.width || y + 16 > s->c.height) {
                             int x1, y1;
-                            int xe = FFMIN(16, s->width - x);
-                            int ye = FFMIN(16, s->height - y);
+                            int xe = FFMIN(16, s->c.width - x);
+                            int ye = FFMIN(16, s->c.height - y);
                             diff = 0;
                             for (y1 = 0; y1 < ye; y1++) {
                                 for (x1 = 0; x1 < xe; x1++) {
-                                    diff += FFABS(p_pic[x1 + y1 * s->linesize] - b_pic[x1 + y1 * s->linesize]);
+                                    diff += FFABS(p_pic[x1 + y1 * s->c.linesize] - b_pic[x1 + y1 * s->c.linesize]);
                                 }
                             }
                             diff = diff * 256 / (xe * ye);
                         } else {
-                            diff = s->sad_cmp[0](NULL, p_pic, b_pic, s->linesize, 16);
+                            diff = s->sad_cmp[0](NULL, p_pic, b_pic, s->c.linesize, 16);
                         }
-                        if (diff > s->qscale * 70) {  // FIXME check that 70 is optimal
-                            s->mb_skipped = 0;
+                        if (diff > s->c.qscale * 70) {  // FIXME check that 70 is optimal
+                            s->c.mb_skipped = 0;
                             break;
                         }
                     }
                 } else
-                    s->mb_skipped = 1;
+                    s->c.mb_skipped = 1;
 
-                if (s->mb_skipped == 1) {
+                if (s->c.mb_skipped == 1) {
                     /* skip macroblock */
                     put_bits(&s->pb, 1, 1);
 
@@ -716,7 +715,7 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
             cbpc  = cbp & 3;
             cbpy  = cbp >> 2;
             cbpy ^= 0xf;
-            if (s->mv_type == MV_TYPE_16X16) {
+            if (s->c.mv_type == MV_TYPE_16X16) {
                 if (s->dquant)
                     cbpc += 8;
                 put_bits(&s->pb,
@@ -727,9 +726,9 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                 if (s->dquant)
                     put_bits(pb2, 2, dquant_code[s->dquant + 2]);
 
-                if (!s->progressive_sequence) {
+                if (!s->c.progressive_sequence) {
                     if (cbp)
-                        put_bits(pb2, 1, s->interlaced_dct);
+                        put_bits(pb2, 1, s->c.interlaced_dct);
                     put_bits(pb2, 1, 0);
                 }
 
@@ -737,13 +736,13 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                     s->misc_bits += get_bits_diff(s);
 
                 /* motion vectors: 16x16 mode */
-                ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+                ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
 
                 ff_h263_encode_motion_vector(s,
                                              motion_x - pred_x,
                                              motion_y - pred_y,
-                                             s->f_code);
-            } else if (s->mv_type == MV_TYPE_FIELD) {
+                                             s->c.f_code);
+            } else if (s->c.mv_type == MV_TYPE_FIELD) {
                 if (s->dquant)
                     cbpc += 8;
                 put_bits(&s->pb,
@@ -754,50 +753,50 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                 if (s->dquant)
                     put_bits(pb2, 2, dquant_code[s->dquant + 2]);
 
-                av_assert2(!s->progressive_sequence);
+                av_assert2(!s->c.progressive_sequence);
                 if (cbp)
-                    put_bits(pb2, 1, s->interlaced_dct);
+                    put_bits(pb2, 1, s->c.interlaced_dct);
                 put_bits(pb2, 1, 1);
 
                 if (interleaved_stats)
                     s->misc_bits += get_bits_diff(s);
 
                 /* motion vectors: 16x8 interlaced mode */
-                ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+                ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
                 pred_y /= 2;
 
-                put_bits(&s->pb, 1, s->field_select[0][0]);
-                put_bits(&s->pb, 1, s->field_select[0][1]);
+                put_bits(&s->pb, 1, s->c.field_select[0][0]);
+                put_bits(&s->pb, 1, s->c.field_select[0][1]);
 
                 ff_h263_encode_motion_vector(s,
-                                             s->mv[0][0][0] - pred_x,
-                                             s->mv[0][0][1] - pred_y,
-                                             s->f_code);
+                                             s->c.mv[0][0][0] - pred_x,
+                                             s->c.mv[0][0][1] - pred_y,
+                                             s->c.f_code);
                 ff_h263_encode_motion_vector(s,
-                                             s->mv[0][1][0] - pred_x,
-                                             s->mv[0][1][1] - pred_y,
-                                             s->f_code);
+                                             s->c.mv[0][1][0] - pred_x,
+                                             s->c.mv[0][1][1] - pred_y,
+                                             s->c.f_code);
             } else {
-                av_assert2(s->mv_type == MV_TYPE_8X8);
+                av_assert2(s->c.mv_type == MV_TYPE_8X8);
                 put_bits(&s->pb,
                          ff_h263_inter_MCBPC_bits[cbpc + 16],
                          ff_h263_inter_MCBPC_code[cbpc + 16]);
                 put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
 
-                if (!s->progressive_sequence && cbp)
-                    put_bits(pb2, 1, s->interlaced_dct);
+                if (!s->c.progressive_sequence && cbp)
+                    put_bits(pb2, 1, s->c.interlaced_dct);
 
                 if (interleaved_stats)
                     s->misc_bits += get_bits_diff(s);
 
                 for (i = 0; i < 4; i++) {
                     /* motion vectors: 8x8 mode*/
-                    ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+                    ff_h263_pred_motion(&s->c, i, 0, &pred_x, &pred_y);
 
                     ff_h263_encode_motion_vector(s,
-                                                 s->cur_pic.motion_val[0][s->block_index[i]][0] - pred_x,
-                                                 s->cur_pic.motion_val[0][s->block_index[i]][1] - pred_y,
-                                                 s->f_code);
+                                                 s->c.cur_pic.motion_val[0][s->c.block_index[i]][0] - pred_x,
+                                                 s->c.cur_pic.motion_val[0][s->c.block_index[i]][1] - pred_y,
+                                                 s->c.f_code);
                 }
             }
 
@@ -818,29 +817,29 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
         int i;
 
         for (int i = 0; i < 6; i++) {
-            int pred  = ff_mpeg4_pred_dc(s, i, &dir[i]);
-            int scale = i < 4 ? s->y_dc_scale : s->c_dc_scale;
+            int pred  = ff_mpeg4_pred_dc(&s->c, i, &dir[i]);
+            int scale = i < 4 ? s->c.y_dc_scale : s->c.c_dc_scale;
 
             pred = FASTDIV((pred + (scale >> 1)), scale);
             dc_diff[i] = block[i][0] - pred;
-            s->dc_val[0][s->block_index[i]] = av_clip_uintp2(block[i][0] * scale, 11);
+            s->c.dc_val[0][s->c.block_index[i]] = av_clip_uintp2(block[i][0] * scale, 11);
         }
 
-        if (s->avctx->flags & AV_CODEC_FLAG_AC_PRED) {
-            s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
+        if (s->c.avctx->flags & AV_CODEC_FLAG_AC_PRED) {
+            s->c.ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
         } else {
             for (i = 0; i < 6; i++)
-                scan_table[i] = s->intra_scantable.permutated;
+                scan_table[i] = s->c.intra_scantable.permutated;
         }
 
         /* compute cbp */
         cbp = 0;
         for (i = 0; i < 6; i++)
-            if (s->block_last_index[i] >= 1)
+            if (s->c.block_last_index[i] >= 1)
                 cbp |= 1 << (5 - i);
 
         cbpc = cbp & 3;
-        if (s->pict_type == AV_PICTURE_TYPE_I) {
+        if (s->c.pict_type == AV_PICTURE_TYPE_I) {
             if (s->dquant)
                 cbpc += 4;
             put_bits(&s->pb,
@@ -854,14 +853,14 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
                      ff_h263_inter_MCBPC_bits[cbpc + 4],
                      ff_h263_inter_MCBPC_code[cbpc + 4]);
         }
-        put_bits(pb2, 1, s->ac_pred);
+        put_bits(pb2, 1, s->c.ac_pred);
         cbpy = cbp >> 2;
         put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
         if (s->dquant)
             put_bits(dc_pb, 2, dquant_code[s->dquant + 2]);
 
-        if (!s->progressive_sequence)
-            put_bits(dc_pb, 1, s->interlaced_dct);
+        if (!s->c.progressive_sequence)
+            put_bits(dc_pb, 1, s->c.interlaced_dct);
 
         if (interleaved_stats)
             s->misc_bits += get_bits_diff(s);
@@ -874,7 +873,7 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64],
 
         /* restore ac coeffs & last_index stuff
          * if we messed them up with the prediction */
-        if (s->ac_pred)
+        if (s->c.ac_pred)
             restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index);
     }
 }
@@ -890,31 +889,31 @@ void ff_mpeg4_stuffing(PutBitContext *pbc)
 }
 
 /* must be called before writing the header */
-void ff_set_mpeg4_time(MpegEncContext *s)
+void ff_set_mpeg4_time(MPVEncContext *const s)
 {
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
-        ff_mpeg4_init_direct_mv(s);
+    if (s->c.pict_type == AV_PICTURE_TYPE_B) {
+        ff_mpeg4_init_direct_mv(&s->c);
     } else {
-        s->last_time_base = s->time_base;
-        s->time_base      = FFUDIV(s->time, s->avctx->time_base.den);
+        s->c.last_time_base = s->c.time_base;
+        s->c.time_base      = FFUDIV(s->c.time, s->c.avctx->time_base.den);
     }
 }
 
 static void mpeg4_encode_gop_header(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int64_t hours, minutes, seconds;
     int64_t time;
 
     put_bits32(&s->pb, GOP_STARTCODE);
 
-    time = s->cur_pic.ptr->f->pts;
+    time = s->c.cur_pic.ptr->f->pts;
     if (m->reordered_input_picture[1])
         time = FFMIN(time, m->reordered_input_picture[1]->f->pts);
-    time = time * s->avctx->time_base.num;
-    s->last_time_base = FFUDIV(time, s->avctx->time_base.den);
+    time = time * s->c.avctx->time_base.num;
+    s->c.last_time_base = FFUDIV(time, s->c.avctx->time_base.den);
 
-    seconds = FFUDIV(time, s->avctx->time_base.den);
+    seconds = FFUDIV(time, s->c.avctx->time_base.den);
     minutes = FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60);
     hours   = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60);
     hours   = FFUMOD(hours  , 24);
@@ -924,7 +923,7 @@ static void mpeg4_encode_gop_header(MPVMainEncContext *const m)
     put_bits(&s->pb, 1, 1);
     put_bits(&s->pb, 6, seconds);
 
-    put_bits(&s->pb, 1, !!(s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP));
+    put_bits(&s->pb, 1, !!(s->c.avctx->flags & AV_CODEC_FLAG_CLOSED_GOP));
     put_bits(&s->pb, 1, 0);  // broken link == NO
 
     ff_mpeg4_stuffing(&s->pb);
@@ -932,20 +931,20 @@ static void mpeg4_encode_gop_header(MPVMainEncContext *const m)
 
 static void mpeg4_encode_visual_object_header(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int profile_and_level_indication;
     int vo_ver_id;
 
-    if (s->avctx->profile != AV_PROFILE_UNKNOWN) {
-        profile_and_level_indication = s->avctx->profile << 4;
-    } else if (m->max_b_frames || s->quarter_sample) {
+    if (s->c.avctx->profile != AV_PROFILE_UNKNOWN) {
+        profile_and_level_indication = s->c.avctx->profile << 4;
+    } else if (m->max_b_frames || s->c.quarter_sample) {
         profile_and_level_indication = 0xF0;  // adv simple
     } else {
         profile_and_level_indication = 0x00;  // simple
     }
 
-    if (s->avctx->level != AV_LEVEL_UNKNOWN)
-        profile_and_level_indication |= s->avctx->level;
+    if (s->c.avctx->level != AV_LEVEL_UNKNOWN)
+        profile_and_level_indication |= s->c.avctx->level;
     else
         profile_and_level_indication |= 1;   // level 1
 
@@ -977,10 +976,10 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
                                     int vo_number,
                                     int vol_number)
 {
-    MpegEncContext *const s = &m4->m.s;
+    MPVEncContext *const s = &m4->m.s;
     int vo_ver_id, vo_type, aspect_ratio_info;
 
-    if (m4->m.max_b_frames || s->quarter_sample) {
+    if (m4->m.max_b_frames || s->c.quarter_sample) {
         vo_ver_id  = 5;
         vo_type = ADV_SIMPLE_VO_TYPE;
     } else {
@@ -997,35 +996,35 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
     put_bits(&s->pb, 4, vo_ver_id);     /* is obj layer ver id */
     put_bits(&s->pb, 3, 1);             /* is obj layer priority */
 
-    aspect_ratio_info = ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio);
+    aspect_ratio_info = ff_h263_aspect_to_info(s->c.avctx->sample_aspect_ratio);
 
     put_bits(&s->pb, 4, aspect_ratio_info); /* aspect ratio info */
     if (aspect_ratio_info == FF_ASPECT_EXTENDED) {
-        av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den,
-                   s->avctx->sample_aspect_ratio.num,  s->avctx->sample_aspect_ratio.den, 255);
-        put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num);
-        put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den);
+        av_reduce(&s->c.avctx->sample_aspect_ratio.num, &s->c.avctx->sample_aspect_ratio.den,
+                   s->c.avctx->sample_aspect_ratio.num,  s->c.avctx->sample_aspect_ratio.den, 255);
+        put_bits(&s->pb, 8, s->c.avctx->sample_aspect_ratio.num);
+        put_bits(&s->pb, 8, s->c.avctx->sample_aspect_ratio.den);
     }
 
     put_bits(&s->pb, 1, 1);             /* vol control parameters= yes */
     put_bits(&s->pb, 2, 1);             /* chroma format YUV 420/YV12 */
-    put_bits(&s->pb, 1, s->low_delay);
+    put_bits(&s->pb, 1, s->c.low_delay);
     put_bits(&s->pb, 1, 0);             /* vbv parameters= no */
 
     put_bits(&s->pb, 2, RECT_SHAPE);    /* vol shape= rectangle */
     put_bits(&s->pb, 1, 1);             /* marker bit */
 
-    put_bits(&s->pb, 16, s->avctx->time_base.den);
+    put_bits(&s->pb, 16, s->c.avctx->time_base.den);
     if (m4->time_increment_bits < 1)
         m4->time_increment_bits = 1;
     put_bits(&s->pb, 1, 1);             /* marker bit */
     put_bits(&s->pb, 1, 0);             /* fixed vop rate=no */
     put_bits(&s->pb, 1, 1);             /* marker bit */
-    put_bits(&s->pb, 13, s->width);     /* vol width */
+    put_bits(&s->pb, 13, s->c.width);     /* vol width */
     put_bits(&s->pb, 1, 1);             /* marker bit */
-    put_bits(&s->pb, 13, s->height);    /* vol height */
+    put_bits(&s->pb, 13, s->c.height);    /* vol height */
     put_bits(&s->pb, 1, 1);             /* marker bit */
-    put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1);
+    put_bits(&s->pb, 1, s->c.progressive_sequence ? 0 : 1);
     put_bits(&s->pb, 1, 1);             /* obmc disable */
     if (vo_ver_id == 1)
         put_bits(&s->pb, 1, 0);       /* sprite enable */
@@ -1033,19 +1032,19 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
         put_bits(&s->pb, 2, 0);       /* sprite enable */
 
     put_bits(&s->pb, 1, 0);             /* not 8 bit == false */
-    put_bits(&s->pb, 1, s->mpeg_quant); /* quant type = (0 = H.263 style) */
+    put_bits(&s->pb, 1, s->c.mpeg_quant); /* quant type = (0 = H.263 style) */
 
-    if (s->mpeg_quant) {
-        ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
-        ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
+    if (s->c.mpeg_quant) {
+        ff_write_quant_matrix(&s->pb, s->c.avctx->intra_matrix);
+        ff_write_quant_matrix(&s->pb, s->c.avctx->inter_matrix);
     }
 
     if (vo_ver_id != 1)
-        put_bits(&s->pb, 1, s->quarter_sample);
+        put_bits(&s->pb, 1, s->c.quarter_sample);
     put_bits(&s->pb, 1, 1);             /* complexity estimation disable */
     put_bits(&s->pb, 1, s->rtp_mode ? 0 : 1); /* resync marker disable */
-    put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0);
-    if (s->data_partitioning)
+    put_bits(&s->pb, 1, s->c.data_partitioning ? 1 : 0);
+    if (s->c.data_partitioning)
         put_bits(&s->pb, 1, 0);         /* no rvlc */
 
     if (vo_ver_id != 1) {
@@ -1057,7 +1056,7 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
     ff_mpeg4_stuffing(&s->pb);
 
     /* user data */
-    if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
+    if (!(s->c.avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
         put_bits32(&s->pb, USER_DATA_STARTCODE);
         ff_put_string(&s->pb, LIBAVCODEC_IDENT, 0);
     }
@@ -1067,32 +1066,32 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4,
 static int mpeg4_encode_picture_header(MPVMainEncContext *const m)
 {
     Mpeg4EncContext *const m4 = mainctx_to_mpeg4(m);
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     uint64_t time_incr;
     int64_t time_div, time_mod;
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
-        if (!(s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
-            if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT)  // HACK, the reference sw is buggy
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
+        if (!(s->c.avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
+            if (s->c.avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT)  // HACK, the reference sw is buggy
                 mpeg4_encode_visual_object_header(m);
-            if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->picture_number == 0)  // HACK, the reference sw is buggy
+            if (s->c.avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->c.picture_number == 0)  // HACK, the reference sw is buggy
                 mpeg4_encode_vol_header(m4, 0, 0);
         }
         mpeg4_encode_gop_header(m);
     }
 
-    s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
+    s->c.partitioned_frame = s->c.data_partitioning && s->c.pict_type != AV_PICTURE_TYPE_B;
 
     put_bits32(&s->pb, VOP_STARTCODE);      /* vop header */
-    put_bits(&s->pb, 2, s->pict_type - 1);  /* pict type: I = 0 , P = 1 */
+    put_bits(&s->pb, 2, s->c.pict_type - 1);  /* pict type: I = 0 , P = 1 */
 
-    time_div  = FFUDIV(s->time, s->avctx->time_base.den);
-    time_mod  = FFUMOD(s->time, s->avctx->time_base.den);
-    time_incr = time_div - s->last_time_base;
+    time_div  = FFUDIV(s->c.time, s->c.avctx->time_base.den);
+    time_mod  = FFUMOD(s->c.time, s->c.avctx->time_base.den);
+    time_incr = time_div - s->c.last_time_base;
 
     // This limits the frame duration to max 1 day
     if (time_incr > 3600*24) {
-        av_log(s->avctx, AV_LOG_ERROR, "time_incr %"PRIu64" too large\n", time_incr);
+        av_log(s->c.avctx, AV_LOG_ERROR, "time_incr %"PRIu64" too large\n", time_incr);
         return AVERROR(EINVAL);
     }
     while (time_incr--)
@@ -1104,22 +1103,22 @@ static int mpeg4_encode_picture_header(MPVMainEncContext *const m)
     put_bits(&s->pb, m4->time_increment_bits, time_mod); /* time increment */
     put_bits(&s->pb, 1, 1);                             /* marker */
     put_bits(&s->pb, 1, 1);                             /* vop coded */
-    if (s->pict_type == AV_PICTURE_TYPE_P) {
-        put_bits(&s->pb, 1, s->no_rounding);    /* rounding type */
+    if (s->c.pict_type == AV_PICTURE_TYPE_P) {
+        put_bits(&s->pb, 1, s->c.no_rounding);    /* rounding type */
     }
     put_bits(&s->pb, 3, 0);     /* intra dc VLC threshold */
-    if (!s->progressive_sequence) {
-        put_bits(&s->pb, 1, !!(s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
-        put_bits(&s->pb, 1, s->alternate_scan);
+    if (!s->c.progressive_sequence) {
+        put_bits(&s->pb, 1, !!(s->c.cur_pic.ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
+        put_bits(&s->pb, 1, s->c.alternate_scan);
     }
     // FIXME sprite stuff
 
-    put_bits(&s->pb, 5, s->qscale);
+    put_bits(&s->pb, 5, s->c.qscale);
 
-    if (s->pict_type != AV_PICTURE_TYPE_I)
-        put_bits(&s->pb, 3, s->f_code);  /* fcode_for */
-    if (s->pict_type == AV_PICTURE_TYPE_B)
-        put_bits(&s->pb, 3, s->b_code);  /* fcode_back */
+    if (s->c.pict_type != AV_PICTURE_TYPE_I)
+        put_bits(&s->pb, 3, s->c.f_code);  /* fcode_for */
+    if (s->c.pict_type == AV_PICTURE_TYPE_B)
+        put_bits(&s->pb, 3, s->c.b_code);  /* fcode_back */
 
     return 0;
 }
@@ -1294,7 +1293,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     static AVOnce init_static_once = AV_ONCE_INIT;
     Mpeg4EncContext *const m4 = avctx->priv_data;
     MPVMainEncContext *const m = &m4->m;
-    MpegEncContext  *const  s = &m->s;
+    MPVEncContext *const s = &m->s;
     int ret;
 
     if (avctx->width >= (1<<13) || avctx->height >= (1<<13)) {
@@ -1315,10 +1314,10 @@ static av_cold int encode_init(AVCodecContext *avctx)
     s->inter_ac_vlc_last_length = uni_mpeg4_inter_rl_len + 128 * 64;
     s->luma_dc_vlc_length       = uni_DCtab_lum_len;
     s->ac_esc_length            = 7 + 2 + 1 + 6 + 1 + 12 + 1;
-    s->y_dc_scale_table         = ff_mpeg4_y_dc_scale_table;
-    s->c_dc_scale_table         = ff_mpeg4_c_dc_scale_table;
+    s->c.y_dc_scale_table         = ff_mpeg4_y_dc_scale_table;
+    s->c.c_dc_scale_table         = ff_mpeg4_c_dc_scale_table;
 
-    ff_qpeldsp_init(&s->qdsp);
+    ff_qpeldsp_init(&s->c.qdsp);
     if ((ret = ff_mpv_encode_init(avctx)) < 0)
         return ret;
 
@@ -1335,23 +1334,23 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     m4->time_increment_bits     = av_log2(avctx->time_base.den - 1) + 1;
 
-    if (s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
-        s->avctx->extradata = av_malloc(1024);
-        if (!s->avctx->extradata)
+    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
+        avctx->extradata = av_malloc(1024);
+        if (!avctx->extradata)
             return AVERROR(ENOMEM);
-        init_put_bits(&s->pb, s->avctx->extradata, 1024);
+        init_put_bits(&s->pb, avctx->extradata, 1024);
 
         mpeg4_encode_visual_object_header(m);
         mpeg4_encode_vol_header(m4, 0, 0);
 
 //            ff_mpeg4_stuffing(&s->pb); ?
         flush_put_bits(&s->pb);
-        s->avctx->extradata_size = put_bytes_output(&s->pb);
+        avctx->extradata_size = put_bytes_output(&s->pb);
     }
     return 0;
 }
 
-void ff_mpeg4_init_partitions(MpegEncContext *s)
+void ff_mpeg4_init_partitions(MPVEncContext *const s)
 {
     uint8_t *start = put_bits_ptr(&s->pb);
     uint8_t *end   = s->pb.buf_end;
@@ -1364,13 +1363,13 @@ void ff_mpeg4_init_partitions(MpegEncContext *s)
     init_put_bits(&s->pb2, start + pb_size + tex_size, pb_size);
 }
 
-void ff_mpeg4_merge_partitions(MpegEncContext *s)
+void ff_mpeg4_merge_partitions(MPVEncContext *const s)
 {
     const int pb2_len    = put_bits_count(&s->pb2);
     const int tex_pb_len = put_bits_count(&s->tex_pb);
     const int bits       = put_bits_count(&s->pb);
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
         put_bits(&s->pb, 19, DC_MARKER);
         s->misc_bits  += 19 + pb2_len + bits - s->last_bits;
         s->i_tex_bits += tex_pb_len;
@@ -1390,19 +1389,19 @@ void ff_mpeg4_merge_partitions(MpegEncContext *s)
     s->last_bits = put_bits_count(&s->pb);
 }
 
-void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
+void ff_mpeg4_encode_video_packet_header(MPVEncContext *const s)
 {
-    int mb_num_bits = av_log2(s->mb_num - 1) + 1;
+    int mb_num_bits = av_log2(s->c.mb_num - 1) + 1;
 
-    put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0);
+    put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(&s->c), 0);
     put_bits(&s->pb, 1, 1);
 
-    put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y * s->mb_width);
-    put_bits(&s->pb, 5 /* quant_precision */, s->qscale);
+    put_bits(&s->pb, mb_num_bits, s->c.mb_x + s->c.mb_y * s->c.mb_width);
+    put_bits(&s->pb, 5 /* quant_precision */, s->c.qscale);
     put_bits(&s->pb, 1, 0); /* no HEC */
 }
 
-#define OFFSET(x) offsetof(MpegEncContext, x)
+#define OFFSET(x) offsetof(MPVEncContext, c.x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
     { "data_partitioning", "Use data partitioning.",      OFFSET(data_partitioning), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
diff --git a/libavcodec/mpeg4videoenc.h b/libavcodec/mpeg4videoenc.h
index 0727be6750..815f16f073 100644
--- a/libavcodec/mpeg4videoenc.h
+++ b/libavcodec/mpeg4videoenc.h
@@ -27,14 +27,14 @@
 
 #include "put_bits.h"
 
-typedef struct MpegEncContext MpegEncContext;
+typedef struct MPVEncContext MPVEncContext;
 
-void ff_set_mpeg4_time(MpegEncContext *s);
+void ff_set_mpeg4_time(MPVEncContext *s);
 
-void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
+void ff_mpeg4_encode_video_packet_header(MPVEncContext *s);
 void ff_mpeg4_stuffing(PutBitContext *pbc);
-void ff_mpeg4_init_partitions(MpegEncContext *s);
-void ff_mpeg4_merge_partitions(MpegEncContext *s);
-void ff_clean_mpeg4_qscales(MpegEncContext *s);
+void ff_mpeg4_init_partitions(MPVEncContext *s);
+void ff_mpeg4_merge_partitions(MPVEncContext *s);
+void ff_clean_mpeg4_qscales(MPVEncContext *s);
 
 #endif
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 126fefa1be..a65125cc13 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -435,9 +435,6 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
     COPY(start_mb_y);
     COPY(end_mb_y);
     COPY(me.map_generation);
-    COPY(dct_error_sum);
-    COPY(dct_count[0]);
-    COPY(dct_count[1]);
     COPY(ac_val_base);
     COPY(ac_val[0]);
     COPY(ac_val[1]);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 85227fdb8f..adaa0cf2d0 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -30,18 +30,13 @@
 
 #include "blockdsp.h"
 #include "error_resilience.h"
-#include "fdctdsp.h"
 #include "get_bits.h"
 #include "h264chroma.h"
 #include "h263dsp.h"
 #include "hpeldsp.h"
 #include "idctdsp.h"
-#include "me_cmp.h"
 #include "motion_est.h"
 #include "mpegpicture.h"
-#include "mpegvideoencdsp.h"
-#include "pixblockdsp.h"
-#include "put_bits.h"
 #include "qpeldsp.h"
 #include "videodsp.h"
 
@@ -105,8 +100,6 @@ typedef struct MpegEncContext {
 
     enum AVCodecID codec_id;     /* see AV_CODEC_ID_xxx */
     int encoding;     ///< true if we are encoding (vs decoding)
-    int luma_elim_threshold;
-    int chroma_elim_threshold;
     int workaround_bugs;       ///< workaround bugs in encoders which cannot be detected automatically
     int codec_tag;             ///< internal codec_tag upper case converted from avctx codec_tag
     /* the following fields are managed internally by the encoder */
@@ -125,12 +118,12 @@ typedef struct MpegEncContext {
 
     BufferPoolContext buffer_pools;
 
-    /** bit output */
-    PutBitContext pb;
-
     int start_mb_y;            ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
     int end_mb_y;              ///< end   mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
-    struct MpegEncContext *thread_context[MAX_THREADS];
+    union {
+        struct MpegEncContext *thread_context[MAX_THREADS];
+        struct MPVEncContext  *enc_contexts[MAX_THREADS];
+    };
     int slice_context_count;   ///< number of used thread_contexts
 
     /**
@@ -145,12 +138,6 @@ typedef struct MpegEncContext {
      */
     MPVWorkPicture next_pic;
 
-    /**
-     * Reference to the source picture for encoding.
-     * note, linesize & data, might not match the source picture (for field pictures)
-     */
-    AVFrame *new_pic;
-
     /**
      * copy of the current picture structure.
      * note, linesize & data, might not match the current picture (for field pictures)
@@ -181,46 +168,24 @@ typedef struct MpegEncContext {
     int chroma_qscale;          ///< chroma QP
     unsigned int lambda;        ///< Lagrange multiplier used in rate distortion
     unsigned int lambda2;       ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
-    int *lambda_table;
-    int adaptive_quant;         ///< use adaptive quantization
-    int dquant;                 ///< qscale difference to prev qscale
     int pict_type;              ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
     int droppable;
-    int skipdct;                ///< skip dct and code zero residual
 
     /* motion compensation */
     int unrestricted_mv;        ///< mv can point outside of the coded picture
     int h263_long_vectors;      ///< use horrible H.263v1 long vector mode
 
     BlockDSPContext bdsp;
-    FDCTDSPContext fdsp;
     H264ChromaContext h264chroma;
     HpelDSPContext hdsp;
     IDCTDSPContext idsp;
-    MpegvideoEncDSPContext mpvencdsp;
-    PixblockDSPContext pdsp;
     QpelDSPContext qdsp;
     VideoDSPContext vdsp;
     H263DSPContext h263dsp;
     int f_code;                 ///< forward MV resolution
     int b_code;                 ///< backward MV resolution for B-frames (MPEG-4)
     int16_t (*p_field_mv_table_base)[2];
-    int16_t (*p_mv_table)[2];            ///< MV table (1MV per MB) P-frame encoding
-    int16_t (*b_forw_mv_table)[2];       ///< MV table (1MV per MB) forward mode B-frame encoding
-    int16_t (*b_back_mv_table)[2];       ///< MV table (1MV per MB) backward mode B-frame encoding
-    int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame encoding
-    int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame encoding
-    int16_t (*b_direct_mv_table)[2];     ///< MV table (1MV per MB) direct mode B-frame encoding
     int16_t (*p_field_mv_table[2][2])[2];   ///< MV table (2MV per MB) interlaced P-frame encoding
-    int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding
-    uint8_t (*p_field_select_table[2]);  ///< Only the first element is allocated
-    uint8_t (*b_field_select_table[2][2]); ///< allocated jointly with p_field_select_table
-
-    /* The following fields are encoder-only */
-    uint16_t *mb_var;           ///< Table for MB variances
-    uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
-    uint8_t *mb_mean;           ///< Table for MB luminance
-    uint64_t encoding_error[MPV_MAX_PLANES];
 
     int mv_dir;
 #define MV_DIR_FORWARD   1
@@ -251,7 +216,6 @@ typedef struct MpegEncContext {
     int mb_x, mb_y;
     int mb_skip_run;
     int mb_intra;
-    uint16_t *mb_type;  ///< Table for candidate MB types for encoding (defines in mpegvideoenc.h)
 
     int block_index[6]; ///< index to current MB in block based arrays with edges
     int block_wrap[6];
@@ -265,43 +229,6 @@ typedef struct MpegEncContext {
     uint16_t inter_matrix[64];
     uint16_t chroma_inter_matrix[64];
 
-    int intra_quant_bias;    ///< bias for the quantizer
-    int inter_quant_bias;    ///< bias for the quantizer
-    int min_qcoeff;          ///< minimum encodable coefficient
-    int max_qcoeff;          ///< maximum encodable coefficient
-    int ac_esc_length;       ///< num of bits needed to encode the longest esc
-    uint8_t *intra_ac_vlc_length;
-    uint8_t *intra_ac_vlc_last_length;
-    uint8_t *intra_chroma_ac_vlc_length;
-    uint8_t *intra_chroma_ac_vlc_last_length;
-    uint8_t *inter_ac_vlc_length;
-    uint8_t *inter_ac_vlc_last_length;
-    uint8_t *luma_dc_vlc_length;
-
-    int coded_score[12];
-
-    /** precomputed matrix (combine qscale and DCT renorm) */
-    int (*q_intra_matrix)[64];
-    int (*q_chroma_intra_matrix)[64];
-    int (*q_inter_matrix)[64];
-    /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
-    uint16_t (*q_intra_matrix16)[2][64];
-    uint16_t (*q_chroma_intra_matrix16)[2][64];
-    uint16_t (*q_inter_matrix16)[2][64];
-
-    /* noise reduction */
-    int (*dct_error_sum)[64];
-    int dct_count[2];
-    uint16_t (*dct_offset)[64];
-
-    /* statistics, used for 2-pass encoding */
-    int mv_bits;
-    int i_tex_bits;
-    int p_tex_bits;
-    int i_count;
-    int misc_bits; ///< cbp, mb_type
-    int last_bits; ///< temp var used for calculating the above vars
-
     /* error concealment / resync */
     int resync_mb_x;                 ///< x position of last resync marker
     int resync_mb_y;                 ///< y position of last resync marker
@@ -311,10 +238,6 @@ typedef struct MpegEncContext {
     /* H.263 specific */
     int gob_index;
     int obmc;                       ///< overlapped block motion compensation
-    int mb_info;                    ///< interval for outputting info about mb offsets as side data
-    int prev_mb_info, last_mb_info;
-    uint8_t *mb_info_ptr;
-    int mb_info_size;
     int ehc_mode;
 
     /* H.263+ specific */
@@ -342,8 +265,6 @@ typedef struct MpegEncContext {
     int data_partitioning;           ///< data partitioning flag from header
     int partitioned_frame;           ///< is current frame partitioned
     int low_delay;                   ///< no reordering needed / has no B-frames
-    PutBitContext tex_pb;            ///< used for data partitioned VOPs
-    PutBitContext pb2;               ///< used for data partitioned VOPs
     int mpeg_quant;
     int padding_bug_score;             ///< used to detect the VERY common padding bug in MPEG-4
 
@@ -354,10 +275,6 @@ typedef struct MpegEncContext {
     int rv10_version; ///< RV10 version: 0 or 3
     int rv10_first_dc_coded[3];
 
-    /* MJPEG specific */
-    struct MJpegContext *mjpeg_ctx;
-    int esc_pos;
-
     /* MSMPEG4 specific */
     int slice_height;      ///< in macroblocks
     int first_slice_line;  ///< used in MPEG-4 too to handle resync markers
@@ -371,16 +288,12 @@ typedef struct MpegEncContext {
         MSMP4_WMV2,
         MSMP4_VC1,        ///< for VC1 (image), WMV3 (image) and MSS2.
     } msmpeg4_version;
-    int esc3_level_length;
     int inter_intra_pred;
     int mspel;
 
     /* decompression specific */
     GetBitContext gb;
 
-    /* MPEG-1 specific */
-    int last_mv_dir;         ///< last mv_dir, used for B-frame encoding
-
     /* MPEG-2-specific - I wished not to have to support this mess. */
     int progressive_sequence;
     int mpeg_f_code[2][2];
@@ -409,19 +322,9 @@ typedef struct MpegEncContext {
     int interlaced_dct;
     int first_field;         ///< is 1 for the first field of a field picture 0 otherwise
 
-    /* RTP specific */
-    int rtp_mode;
-    int rtp_payload_size;
-
-    uint8_t *ptr_lastgob;
-
     int16_t (*block)[64]; ///< points to one of the following blocks
     int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
-    union {
     int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch()
-        void (*encode_mb)(struct MpegEncContext *s, int16_t block[][64],
-                          int motion_x, int motion_y);
-    };
 
 #define SLICE_OK         0
 #define SLICE_ERROR     -1
@@ -444,20 +347,6 @@ typedef struct MpegEncContext {
                            int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)
                            int16_t *block/*align 16*/, int n, int qscale);
-    int (*dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
-    void (*denoise_dct)(struct MpegEncContext *s, int16_t *block);
-
-    int mpv_flags;      ///< flags set by private options
-    int quantizer_noise_shaping;
-
-    me_cmp_func ildct_cmp[2]; ///< 0 = intra, 1 = non-intra
-    me_cmp_func n_sse_cmp[2]; ///< either SSE or NSSE cmp func
-    me_cmp_func sad_cmp[2];
-    me_cmp_func sse_cmp[2];
-    int (*sum_abs_dctelem)(const int16_t *block);
-
-    /// Bitfield containing information which frames to reconstruct.
-    int frame_reconstruction_bitfield;
 
     /* flag to indicate a reinitialization is required, e.g. after
      * a frame size change */
@@ -467,10 +356,6 @@ typedef struct MpegEncContext {
     unsigned slice_ctx_size;
 
     ERContext er;
-
-    int error_rate;
-
-    int intra_penalty;
 } MpegEncContext;
 
 
diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c
index 2856dbfbd6..8c84b59c5e 100644
--- a/libavcodec/mpegvideo_dec.c
+++ b/libavcodec/mpegvideo_dec.c
@@ -136,7 +136,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 
     // MPEG-2/interlacing info
     memcpy(&s->progressive_sequence, &s1->progressive_sequence,
-           (char *) &s1->rtp_mode - (char *) &s1->progressive_sequence);
+           (char *) &s1->first_field + sizeof(s1->first_field) - (char *) &s1->progressive_sequence);
 
     return 0;
 }
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 33241d6cb0..7061ad0719 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -84,13 +84,13 @@
 #define QMAT_SHIFT 21
 
 static int encode_picture(MPVMainEncContext *const s, const AVPacket *pkt);
-static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale);
-static int sse_mb(MpegEncContext *s);
-static void denoise_dct_c(MpegEncContext *s, int16_t *block);
-static int dct_quantize_c(MpegEncContext *s,
+static int dct_quantize_refine(MPVEncContext *const s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale);
+static int sse_mb(MPVEncContext *const s);
+static void denoise_dct_c(MPVEncContext *const s, int16_t *block);
+static int dct_quantize_c(MPVEncContext *const s,
                           int16_t *block, int n,
                           int qscale, int *overflow);
-static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
+static int dct_quantize_trellis_c(MPVEncContext *const s, int16_t *block, int n, int qscale, int *overflow);
 
 static uint8_t default_fcode_tab[MAX_MV * 2 + 1];
 
@@ -107,7 +107,7 @@ const AVClass ff_mpv_enc_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
+void ff_convert_matrix(MPVEncContext *const s, int (*qmat)[64],
                        uint16_t (*qmat16)[2][64],
                        const uint16_t *quant_matrix,
                        int bias, int qmin, int qmax, int intra)
@@ -120,7 +120,7 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
         int i;
         int qscale2;
 
-        if (s->q_scale_type) qscale2 = ff_mpeg2_non_linear_qscale[qscale];
+        if (s->c.q_scale_type) qscale2 = ff_mpeg2_non_linear_qscale[qscale];
         else                 qscale2 = qscale << 1;
 
         if (fdsp->fdct == ff_jpeg_fdct_islow_8  ||
@@ -129,7 +129,7 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
 #endif /* CONFIG_FAANDCT */
             fdsp->fdct == ff_jpeg_fdct_islow_10) {
             for (i = 0; i < 64; i++) {
-                const int j = s->idsp.idct_permutation[i];
+                const int j = s->c.idsp.idct_permutation[i];
                 int64_t den = (int64_t) qscale2 * quant_matrix[j];
                 /* 1 * 1 <= qscale2 * quant_matrix[j] <= 112 * 255
                  * Assume x = qscale2 * quant_matrix[j]
@@ -141,7 +141,7 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
             }
         } else if (fdsp->fdct == ff_fdct_ifast) {
             for (i = 0; i < 64; i++) {
-                const int j = s->idsp.idct_permutation[i];
+                const int j = s->c.idsp.idct_permutation[i];
                 int64_t den = ff_aanscales[i] * (int64_t) qscale2 * quant_matrix[j];
                 /* 1247 * 1 * 1 <= ff_aanscales[i] * qscale2 * quant_matrix[j] <= 31521 * 112 * 255
                  * Assume x = ff_aanscales[i] * qscale2 * quant_matrix[j]
@@ -153,7 +153,7 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
             }
         } else {
             for (i = 0; i < 64; i++) {
-                const int j = s->idsp.idct_permutation[i];
+                const int j = s->c.idsp.idct_permutation[i];
                 int64_t den = (int64_t) qscale2 * quant_matrix[j];
                 /* 1 * 1 <= qscale2 * quant_matrix[j] <= 112 * 255
                  * Assume x = qscale2 * quant_matrix[j]
@@ -188,7 +188,7 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
         }
     }
     if (shift) {
-        av_log(s->avctx, AV_LOG_INFO,
+        av_log(s->c.avctx, AV_LOG_INFO,
                "Warning, QMAT_SHIFT is larger than %d, overflows possible\n",
                QMAT_SHIFT - shift);
     }
@@ -196,31 +196,31 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
 
 static inline void update_qscale(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    if (s->q_scale_type == 1 && 0) {
+    if (s->c.q_scale_type == 1 && 0) {
         int i;
         int bestdiff=INT_MAX;
         int best = 1;
 
         for (i = 0 ; i<FF_ARRAY_ELEMS(ff_mpeg2_non_linear_qscale); i++) {
-            int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->lambda * 139);
-            if (ff_mpeg2_non_linear_qscale[i] < s->avctx->qmin ||
-                (ff_mpeg2_non_linear_qscale[i] > s->avctx->qmax && !m->vbv_ignore_qmax))
+            int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->c.lambda * 139);
+            if (ff_mpeg2_non_linear_qscale[i] < s->c.avctx->qmin ||
+                (ff_mpeg2_non_linear_qscale[i] > s->c.avctx->qmax && !m->vbv_ignore_qmax))
                 continue;
             if (diff < bestdiff) {
                 bestdiff = diff;
                 best = i;
             }
         }
-        s->qscale = best;
+        s->c.qscale = best;
     } else {
-        s->qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >>
+        s->c.qscale = (s->c.lambda * 139 + FF_LAMBDA_SCALE * 64) >>
                     (FF_LAMBDA_SHIFT + 7);
-        s->qscale = av_clip(s->qscale, s->avctx->qmin, m->vbv_ignore_qmax ? 31 : s->avctx->qmax);
+        s->c.qscale = av_clip(s->c.qscale, s->c.avctx->qmin, m->vbv_ignore_qmax ? 31 : s->c.avctx->qmax);
     }
 
-    s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
+    s->c.lambda2 = (s->c.lambda * s->c.lambda + FF_LAMBDA_SCALE / 2) >>
                  FF_LAMBDA_SHIFT;
 }
 
@@ -238,34 +238,34 @@ void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix)
 }
 
 /**
- * init s->cur_pic.qscale_table from s->lambda_table
+ * init s->c.cur_pic.qscale_table from s->lambda_table
  */
-static void init_qscale_tab(MpegEncContext *s)
+static void init_qscale_tab(MPVEncContext *const s)
 {
-    int8_t * const qscale_table = s->cur_pic.qscale_table;
+    int8_t * const qscale_table = s->c.cur_pic.qscale_table;
     int i;
 
-    for (i = 0; i < s->mb_num; i++) {
-        unsigned int lam = s->lambda_table[s->mb_index2xy[i]];
+    for (i = 0; i < s->c.mb_num; i++) {
+        unsigned int lam = s->lambda_table[s->c.mb_index2xy[i]];
         int qp = (lam * 139 + FF_LAMBDA_SCALE * 64) >> (FF_LAMBDA_SHIFT + 7);
-        qscale_table[s->mb_index2xy[i]] = av_clip(qp, s->avctx->qmin,
-                                                  s->avctx->qmax);
+        qscale_table[s->c.mb_index2xy[i]] = av_clip(qp, s->c.avctx->qmin,
+                                                  s->c.avctx->qmax);
     }
 }
 
-static void update_duplicate_context_after_me(MpegEncContext *dst,
-                                              const MpegEncContext *src)
+static void update_duplicate_context_after_me(MPVEncContext *const dst,
+                                              const MPVEncContext *const src)
 {
-#define COPY(a) dst->a= src->a
-    COPY(pict_type);
-    COPY(f_code);
-    COPY(b_code);
-    COPY(qscale);
-    COPY(lambda);
-    COPY(lambda2);
-    COPY(frame_pred_frame_dct); // FIXME don't set in encode_header
-    COPY(progressive_frame);    // FIXME don't set in encode_header
-    COPY(partitioned_frame);    // FIXME don't set in encode_header
+#define COPY(a) dst->a = src->a
+    COPY(c.pict_type);
+    COPY(c.f_code);
+    COPY(c.b_code);
+    COPY(c.qscale);
+    COPY(c.lambda);
+    COPY(c.lambda2);
+    COPY(c.frame_pred_frame_dct); // FIXME don't set in encode_header
+    COPY(c.progressive_frame);    // FIXME don't set in encode_header
+    COPY(c.partitioned_frame);    // FIXME don't set in encode_header
 #undef COPY
 }
 
@@ -276,26 +276,26 @@ static av_cold void mpv_encode_init_static(void)
 }
 
 /**
- * Set the given MpegEncContext to defaults for encoding.
+ * Set the given MPVEncContext to defaults for encoding.
  */
 static av_cold void mpv_encode_defaults(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     static AVOnce init_static_once = AV_ONCE_INIT;
 
-    ff_mpv_common_defaults(s);
+    ff_mpv_common_defaults(&s->c);
 
     if (!m->fcode_tab) {
         m->fcode_tab = default_fcode_tab + MAX_MV;
         ff_thread_once(&init_static_once, mpv_encode_init_static);
     }
-    if (!s->y_dc_scale_table) {
-        s->y_dc_scale_table =
-        s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
+    if (!s->c.y_dc_scale_table) {
+        s->c.y_dc_scale_table =
+        s->c.c_dc_scale_table = ff_mpeg1_dc_scale_table;
     }
 }
 
-av_cold void ff_dct_encode_init(MpegEncContext *s)
+av_cold void ff_dct_encode_init(MPVEncContext *const s)
 {
     s->dct_quantize = dct_quantize_c;
     s->denoise_dct  = denoise_dct_c;
@@ -306,19 +306,19 @@ av_cold void ff_dct_encode_init(MpegEncContext *s)
     ff_dct_encode_init_x86(s);
 #endif
 
-    if (s->avctx->trellis)
+    if (s->c.avctx->trellis)
         s->dct_quantize  = dct_quantize_trellis_c;
 }
 
 static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     MECmpContext mecc;
     me_cmp_func me_cmp[6];
     int ret;
 
     ff_me_cmp_init(&mecc, avctx);
-    ret = ff_me_init(&s->me, avctx, &mecc, 1);
+    ret = ff_me_init(&s->c.me, avctx, &mecc, 1);
     if (ret < 0)
         return ret;
     ret = ff_set_cmp(&mecc, me_cmp, m->frame_skip_cmp, 1);
@@ -355,8 +355,8 @@ static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx
 #define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * sizeof(*(p))))
 static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avctx)
 {
-    MpegEncContext *const s = &m->s;
-    const int nb_matrices = 1 + (s->out_format == FMT_MJPEG) + !m->intra_only;
+    MPVEncContext *const s = &m->s;
+    const int nb_matrices = 1 + (s->c.out_format == FMT_MJPEG) + !m->intra_only;
     const uint16_t *intra_matrix, *inter_matrix;
     int ret;
 
@@ -364,7 +364,7 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
         !ALLOCZ_ARRAYS(s->q_intra_matrix16, 32, nb_matrices))
         return AVERROR(ENOMEM);
 
-    if (s->out_format == FMT_MJPEG) {
+    if (s->c.out_format == FMT_MJPEG) {
         s->q_chroma_intra_matrix   = s->q_intra_matrix   + 32;
         s->q_chroma_intra_matrix16 = s->q_intra_matrix16 + 32;
         // No need to set q_inter_matrix
@@ -380,11 +380,11 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
         s->q_inter_matrix16 = s->q_intra_matrix16 + 32;
     }
 
-    if (CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4 &&
-        s->mpeg_quant) {
+    if (CONFIG_MPEG4_ENCODER && s->c.codec_id == AV_CODEC_ID_MPEG4 &&
+        s->c.mpeg_quant) {
         intra_matrix = ff_mpeg4_default_intra_matrix;
         inter_matrix = ff_mpeg4_default_non_intra_matrix;
-    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
+    } else if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
         intra_matrix =
         inter_matrix = ff_mpeg1_default_non_intra_matrix;
     } else {
@@ -399,10 +399,10 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
 
     /* init q matrix */
     for (int i = 0; i < 64; i++) {
-        int j = s->idsp.idct_permutation[i];
+        int j = s->c.idsp.idct_permutation[i];
 
-        s->intra_matrix[j] = s->chroma_intra_matrix[j] = intra_matrix[i];
-        s->inter_matrix[j] = inter_matrix[i];
+        s->c.intra_matrix[j] = s->c.chroma_intra_matrix[j] = intra_matrix[i];
+        s->c.inter_matrix[j] = inter_matrix[i];
     }
 
     /* precompute matrix */
@@ -411,11 +411,11 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
         return ret;
 
     ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
-                      s->intra_matrix, s->intra_quant_bias, avctx->qmin,
+                      s->c.intra_matrix, s->intra_quant_bias, avctx->qmin,
                       31, 1);
     if (s->q_inter_matrix)
         ff_convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16,
-                          s->inter_matrix, s->inter_quant_bias, avctx->qmin,
+                          s->c.inter_matrix, s->inter_quant_bias, avctx->qmin,
                           31, 0);
 
     return 0;
@@ -423,7 +423,7 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
 
 static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avctx)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     // Align the following per-thread buffers to avoid false sharing.
     enum {
 #ifndef _MSC_VER
@@ -432,12 +432,12 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
 #else
         ALIGN = 128,
 #endif
-        ME_MAP_ALLOC_SIZE = FFALIGN(2 * ME_MAP_SIZE * sizeof(*s->me.map), ALIGN),
+        ME_MAP_ALLOC_SIZE = FFALIGN(2 * ME_MAP_SIZE * sizeof(*s->c.me.map), ALIGN),
         DCT_ERROR_SIZE    = FFALIGN(2 * sizeof(*s->dct_error_sum), ALIGN),
     };
     static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
                   "Need checks for potential overflow.");
-    unsigned nb_slices = s->slice_context_count, mv_table_size, mb_array_size;
+    unsigned nb_slices = s->c.slice_context_count, mv_table_size, mb_array_size;
     char *dct_error = NULL, *me_map;
     int has_b_frames = !!m->max_b_frames, nb_mv_tables = 1 + 5 * has_b_frames;
     int16_t (*mv_table)[2];
@@ -458,16 +458,16 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;
 
     /* Allocate MB type table */
-    mb_array_size = s->mb_stride * s->mb_height;
+    mb_array_size = s->c.mb_stride * s->c.mb_height;
     s->mb_type = av_calloc(mb_array_size, 3 * sizeof(*s->mb_type) + sizeof(*s->mb_mean));
     if (!s->mb_type)
         return AVERROR(ENOMEM);
     if (!FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size))
         return AVERROR(ENOMEM);
 
-    mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
-    if (s->codec_id == AV_CODEC_ID_MPEG4 ||
-        (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+    mv_table_size = (s->c.mb_height + 2) * s->c.mb_stride + 1;
+    if (s->c.codec_id == AV_CODEC_ID_MPEG4 ||
+        (s->c.avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
         nb_mv_tables += 8 * has_b_frames;
         if (!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * (2 + 4 * has_b_frames), mv_table_size))
             return AVERROR(ENOMEM);
@@ -477,10 +477,10 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
     if (!mv_table)
         return AVERROR(ENOMEM);
     m->mv_table_base = mv_table;
-    mv_table += s->mb_stride + 1;
+    mv_table += s->c.mb_stride + 1;
 
     for (unsigned i = 0; i < nb_slices; ++i) {
-        MpegEncContext *const s2 = s->thread_context[i];
+        MPVEncContext *const s2 = s->c.enc_contexts[i];
         int16_t (*tmp_mv_table)[2] = mv_table;
 
         if (dct_error) {
@@ -495,8 +495,8 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
         s2->mb_mean      = (uint8_t*)(s2->mb_var + mb_array_size);
         s2->lambda_table = s->lambda_table;
 
-        s2->me.map       = (uint32_t*)me_map;
-        s2->me.score_map = s2->me.map + ME_MAP_SIZE;
+        s2->c.me.map     = (uint32_t*)me_map;
+        s2->c.me.score_map = s2->c.me.map + ME_MAP_SIZE;
         me_map          += ME_MAP_ALLOC_SIZE;
 
         s2->p_mv_table            = tmp_mv_table;
@@ -532,7 +532,7 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
 av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 {
     MPVMainEncContext *const m = avctx->priv_data;
-    MpegEncContext    *const s = &m->s;
+    MPVEncContext    *const s = &m->s;
     AVCPBProperties *cpb_props;
     int i, ret;
 
@@ -541,24 +541,24 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_YUVJ444P:
     case AV_PIX_FMT_YUV444P:
-        s->chroma_format = CHROMA_444;
+        s->c.chroma_format = CHROMA_444;
         break;
     case AV_PIX_FMT_YUVJ422P:
     case AV_PIX_FMT_YUV422P:
-        s->chroma_format = CHROMA_422;
+        s->c.chroma_format = CHROMA_422;
         break;
     case AV_PIX_FMT_YUVJ420P:
     case AV_PIX_FMT_YUV420P:
     default:
-        s->chroma_format = CHROMA_420;
+        s->c.chroma_format = CHROMA_420;
         break;
     }
 
     avctx->bits_per_raw_sample = av_clip(avctx->bits_per_raw_sample, 0, 8);
 
     m->bit_rate = avctx->bit_rate;
-    s->width    = avctx->width;
-    s->height   = avctx->height;
+    s->c.width    = avctx->width;
+    s->c.height   = avctx->height;
     if (avctx->gop_size > 600 &&
         avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
         av_log(avctx, AV_LOG_WARNING,
@@ -567,7 +567,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         avctx->gop_size = 600;
     }
     m->gop_size     = avctx->gop_size;
-    s->avctx        = avctx;
+    s->c.avctx        = avctx;
     if (avctx->max_b_frames > MPVENC_MAX_B_FRAMES) {
         av_log(avctx, AV_LOG_ERROR, "Too many B-frames requested, maximum "
                "is " AV_STRINGIFY(MPVENC_MAX_B_FRAMES) ".\n");
@@ -578,30 +578,30 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
     m->max_b_frames = avctx->max_b_frames;
-    s->codec_id     = avctx->codec->id;
+    s->c.codec_id     = avctx->codec->id;
     if (m->max_b_frames && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
         av_log(avctx, AV_LOG_ERROR, "B-frames not supported by codec\n");
         return AVERROR(EINVAL);
     }
 
-    s->quarter_sample     = (avctx->flags & AV_CODEC_FLAG_QPEL) != 0;
+    s->c.quarter_sample     = (avctx->flags & AV_CODEC_FLAG_QPEL) != 0;
     s->rtp_mode           = !!s->rtp_payload_size;
-    s->intra_dc_precision = avctx->intra_dc_precision;
+    s->c.intra_dc_precision = avctx->intra_dc_precision;
 
     // workaround some differences between how applications specify dc precision
-    if (s->intra_dc_precision < 0) {
-        s->intra_dc_precision += 8;
-    } else if (s->intra_dc_precision >= 8)
-        s->intra_dc_precision -= 8;
+    if (s->c.intra_dc_precision < 0) {
+        s->c.intra_dc_precision += 8;
+    } else if (s->c.intra_dc_precision >= 8)
+        s->c.intra_dc_precision -= 8;
 
-    if (s->intra_dc_precision < 0) {
+    if (s->c.intra_dc_precision < 0) {
         av_log(avctx, AV_LOG_ERROR,
                 "intra dc precision must be positive, note some applications use"
                 " 0 and some 8 as base meaning 8bit, the value must not be smaller than that\n");
         return AVERROR(EINVAL);
     }
 
-    if (s->intra_dc_precision > (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 3 : 0)) {
+    if (s->c.intra_dc_precision > (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 3 : 0)) {
         av_log(avctx, AV_LOG_ERROR, "intra dc precision too large\n");
         return AVERROR(EINVAL);
     }
@@ -626,7 +626,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                          (s->mpv_flags & FF_MPV_FLAG_QP_RD)) &&
                         !m->fixed_qscale;
 
-    s->loop_filter = !!(avctx->flags & AV_CODEC_FLAG_LOOP_FILTER);
+    s->c.loop_filter = !!(avctx->flags & AV_CODEC_FLAG_LOOP_FILTER);
 
     if (avctx->rc_max_rate && !avctx->rc_buffer_size) {
         switch(avctx->codec_id) {
@@ -700,27 +700,27 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
             avctx->bit_rate_tolerance = INT_MAX;
     }
 
-    if ((avctx->flags & AV_CODEC_FLAG_4MV) && s->codec_id != AV_CODEC_ID_MPEG4 &&
-        s->codec_id != AV_CODEC_ID_H263 && s->codec_id != AV_CODEC_ID_H263P &&
-        s->codec_id != AV_CODEC_ID_FLV1) {
+    if ((avctx->flags & AV_CODEC_FLAG_4MV) && s->c.codec_id != AV_CODEC_ID_MPEG4 &&
+        s->c.codec_id != AV_CODEC_ID_H263 && s->c.codec_id != AV_CODEC_ID_H263P &&
+        s->c.codec_id != AV_CODEC_ID_FLV1) {
         av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n");
         return AVERROR(EINVAL);
     }
 
-    if (s->obmc && avctx->mb_decision != FF_MB_DECISION_SIMPLE) {
+    if (s->c.obmc && avctx->mb_decision != FF_MB_DECISION_SIMPLE) {
         av_log(avctx, AV_LOG_ERROR,
                "OBMC is only supported with simple mb decision\n");
         return AVERROR(EINVAL);
     }
 
-    if (s->quarter_sample && s->codec_id != AV_CODEC_ID_MPEG4) {
+    if (s->c.quarter_sample && s->c.codec_id != AV_CODEC_ID_MPEG4) {
         av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n");
         return AVERROR(EINVAL);
     }
 
-    if ((s->codec_id == AV_CODEC_ID_MPEG4 ||
-         s->codec_id == AV_CODEC_ID_H263  ||
-         s->codec_id == AV_CODEC_ID_H263P) &&
+    if ((s->c.codec_id == AV_CODEC_ID_MPEG4 ||
+         s->c.codec_id == AV_CODEC_ID_H263  ||
+         s->c.codec_id == AV_CODEC_ID_H263P) &&
         (avctx->sample_aspect_ratio.num > 255 ||
          avctx->sample_aspect_ratio.den > 255)) {
         av_log(avctx, AV_LOG_WARNING,
@@ -730,44 +730,44 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                    avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den, 255);
     }
 
-    if ((s->codec_id == AV_CODEC_ID_H263  ||
-         s->codec_id == AV_CODEC_ID_H263P) &&
+    if ((s->c.codec_id == AV_CODEC_ID_H263  ||
+         s->c.codec_id == AV_CODEC_ID_H263P) &&
         (avctx->width  > 2048 ||
          avctx->height > 1152 )) {
         av_log(avctx, AV_LOG_ERROR, "H.263 does not support resolutions above 2048x1152\n");
         return AVERROR(EINVAL);
     }
-    if (s->codec_id == AV_CODEC_ID_FLV1 &&
+    if (s->c.codec_id == AV_CODEC_ID_FLV1 &&
         (avctx->width  > 65535 ||
          avctx->height > 65535 )) {
         av_log(avctx, AV_LOG_ERROR, "FLV does not support resolutions above 16bit\n");
         return AVERROR(EINVAL);
     }
-    if ((s->codec_id == AV_CODEC_ID_H263  ||
-         s->codec_id == AV_CODEC_ID_H263P ||
-         s->codec_id == AV_CODEC_ID_RV20) &&
+    if ((s->c.codec_id == AV_CODEC_ID_H263  ||
+         s->c.codec_id == AV_CODEC_ID_H263P ||
+         s->c.codec_id == AV_CODEC_ID_RV20) &&
         ((avctx->width &3) ||
          (avctx->height&3) )) {
         av_log(avctx, AV_LOG_ERROR, "width and height must be a multiple of 4\n");
         return AVERROR(EINVAL);
     }
 
-    if (s->codec_id == AV_CODEC_ID_RV10 &&
+    if (s->c.codec_id == AV_CODEC_ID_RV10 &&
         (avctx->width &15 ||
          avctx->height&15 )) {
         av_log(avctx, AV_LOG_ERROR, "width and height must be a multiple of 16\n");
         return AVERROR(EINVAL);
     }
 
-    if ((s->codec_id == AV_CODEC_ID_WMV1 ||
-         s->codec_id == AV_CODEC_ID_WMV2) &&
+    if ((s->c.codec_id == AV_CODEC_ID_WMV1 ||
+         s->c.codec_id == AV_CODEC_ID_WMV2) &&
          avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "width must be multiple of 2\n");
         return AVERROR(EINVAL);
     }
 
     if ((avctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME)) &&
-        s->codec_id != AV_CODEC_ID_MPEG4 && s->codec_id != AV_CODEC_ID_MPEG2VIDEO) {
+        s->c.codec_id != AV_CODEC_ID_MPEG4 && s->c.codec_id != AV_CODEC_ID_MPEG2VIDEO) {
         av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n");
         return AVERROR(EINVAL);
     }
@@ -792,7 +792,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     }
 
     if (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) {
-        if (s->codec_id != AV_CODEC_ID_MPEG2VIDEO &&
+        if (s->c.codec_id != AV_CODEC_ID_MPEG2VIDEO &&
             avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
             av_log(avctx, AV_LOG_ERROR,
                    "low delay forcing is only available for mpeg2, "
@@ -826,7 +826,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         //return -1;
     }
 
-    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG || s->codec_id == AV_CODEC_ID_AMV || s->codec_id == AV_CODEC_ID_SPEEDHQ) {
+    if (s->c.mpeg_quant || s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO || s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO || s->c.codec_id == AV_CODEC_ID_MJPEG || s->c.codec_id == AV_CODEC_ID_AMV || s->c.codec_id == AV_CODEC_ID_SPEEDHQ) {
         // (a + x * 3 / 8) / x
         s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3);
         s->inter_quant_bias = 0;
@@ -849,148 +849,148 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         s->rtp_mode   = 1;
         /* fallthrough */
     case AV_CODEC_ID_MPEG1VIDEO:
-        s->out_format = FMT_MPEG1;
-        s->low_delay  = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY);
-        avctx->delay  = s->low_delay ? 0 : (m->max_b_frames + 1);
+        s->c.out_format = FMT_MPEG1;
+        s->c.low_delay  = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY);
+        avctx->delay  = s->c.low_delay ? 0 : (m->max_b_frames + 1);
         ff_mpeg1_encode_init(s);
         break;
 #endif
 #if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER
     case AV_CODEC_ID_MJPEG:
     case AV_CODEC_ID_AMV:
-        s->out_format = FMT_MJPEG;
+        s->c.out_format = FMT_MJPEG;
         m->intra_only = 1; /* force intra only for jpeg */
         avctx->delay = 0;
-        s->low_delay = 1;
+        s->c.low_delay = 1;
         break;
 #endif
     case AV_CODEC_ID_SPEEDHQ:
-        s->out_format = FMT_SPEEDHQ;
+        s->c.out_format = FMT_SPEEDHQ;
         m->intra_only = 1; /* force intra only for SHQ */
         avctx->delay = 0;
-        s->low_delay = 1;
+        s->c.low_delay = 1;
         break;
     case AV_CODEC_ID_H261:
-        s->out_format = FMT_H261;
+        s->c.out_format = FMT_H261;
         avctx->delay  = 0;
-        s->low_delay  = 1;
+        s->c.low_delay  = 1;
         s->rtp_mode   = 0; /* Sliced encoding not supported */
         break;
     case AV_CODEC_ID_H263:
         if (!CONFIG_H263_ENCODER)
             return AVERROR_ENCODER_NOT_FOUND;
         if (ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format),
-                             s->width, s->height) == 8) {
+                             s->c.width, s->c.height) == 8) {
             av_log(avctx, AV_LOG_ERROR,
                    "The specified picture size of %dx%d is not valid for "
                    "the H.263 codec.\nValid sizes are 128x96, 176x144, "
                    "352x288, 704x576, and 1408x1152. "
-                   "Try H.263+.\n", s->width, s->height);
+                   "Try H.263+.\n", s->c.width, s->c.height);
             return AVERROR(EINVAL);
         }
-        s->out_format = FMT_H263;
+        s->c.out_format = FMT_H263;
         avctx->delay  = 0;
-        s->low_delay  = 1;
+        s->c.low_delay  = 1;
         break;
     case AV_CODEC_ID_H263P:
-        s->out_format = FMT_H263;
-        s->h263_plus  = 1;
+        s->c.out_format = FMT_H263;
+        s->c.h263_plus  = 1;
         /* Fx */
-        s->h263_aic        = (avctx->flags & AV_CODEC_FLAG_AC_PRED) ? 1 : 0;
-        s->modified_quant  = s->h263_aic;
-        s->loop_filter     = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
-        s->unrestricted_mv = s->obmc || s->loop_filter || s->umvplus;
-        s->flipflop_rounding = 1;
+        s->c.h263_aic        = (avctx->flags & AV_CODEC_FLAG_AC_PRED) ? 1 : 0;
+        s->c.modified_quant  = s->c.h263_aic;
+        s->c.loop_filter     = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+        s->c.unrestricted_mv = s->c.obmc || s->c.loop_filter || s->c.umvplus;
+        s->c.flipflop_rounding = 1;
 
         /* /Fx */
         /* These are just to be sure */
         avctx->delay = 0;
-        s->low_delay = 1;
+        s->c.low_delay = 1;
         break;
     case AV_CODEC_ID_FLV1:
-        s->out_format      = FMT_H263;
-        s->h263_flv        = 2; /* format = 1; 11-bit codes */
-        s->unrestricted_mv = 1;
+        s->c.out_format      = FMT_H263;
+        s->c.h263_flv        = 2; /* format = 1; 11-bit codes */
+        s->c.unrestricted_mv = 1;
         s->rtp_mode  = 0; /* don't allow GOB */
         avctx->delay = 0;
-        s->low_delay = 1;
+        s->c.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;
+        s->c.out_format = FMT_H263;
         avctx->delay  = 0;
-        s->low_delay  = 1;
+        s->c.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;
+        s->c.out_format      = FMT_H263;
         avctx->delay       = 0;
-        s->low_delay       = 1;
-        s->modified_quant  = 1;
-        s->h263_aic        = 1;
-        s->h263_plus       = 1;
-        s->loop_filter     = 1;
-        s->unrestricted_mv = 0;
+        s->c.low_delay       = 1;
+        s->c.modified_quant  = 1;
+        s->c.h263_aic        = 1;
+        s->c.h263_plus       = 1;
+        s->c.loop_filter     = 1;
+        s->c.unrestricted_mv = 0;
         break;
 #endif
     case AV_CODEC_ID_MPEG4:
-        s->out_format      = FMT_H263;
-        s->h263_pred       = 1;
-        s->unrestricted_mv = 1;
-        s->flipflop_rounding = 1;
-        s->low_delay       = m->max_b_frames ? 0 : 1;
-        avctx->delay       = s->low_delay ? 0 : (m->max_b_frames + 1);
+        s->c.out_format      = FMT_H263;
+        s->c.h263_pred       = 1;
+        s->c.unrestricted_mv = 1;
+        s->c.flipflop_rounding = 1;
+        s->c.low_delay       = m->max_b_frames ? 0 : 1;
+        avctx->delay       = s->c.low_delay ? 0 : (m->max_b_frames + 1);
         break;
     case AV_CODEC_ID_MSMPEG4V2:
-        s->out_format      = FMT_H263;
-        s->h263_pred       = 1;
-        s->unrestricted_mv = 1;
-        s->msmpeg4_version = MSMP4_V2;
+        s->c.out_format      = FMT_H263;
+        s->c.h263_pred       = 1;
+        s->c.unrestricted_mv = 1;
+        s->c.msmpeg4_version = MSMP4_V2;
         avctx->delay       = 0;
-        s->low_delay       = 1;
+        s->c.low_delay       = 1;
         break;
     case AV_CODEC_ID_MSMPEG4V3:
-        s->out_format        = FMT_H263;
-        s->h263_pred         = 1;
-        s->unrestricted_mv   = 1;
-        s->msmpeg4_version   = MSMP4_V3;
-        s->flipflop_rounding = 1;
+        s->c.out_format        = FMT_H263;
+        s->c.h263_pred         = 1;
+        s->c.unrestricted_mv   = 1;
+        s->c.msmpeg4_version   = MSMP4_V3;
+        s->c.flipflop_rounding = 1;
         avctx->delay         = 0;
-        s->low_delay         = 1;
+        s->c.low_delay         = 1;
         break;
     case AV_CODEC_ID_WMV1:
-        s->out_format        = FMT_H263;
-        s->h263_pred         = 1;
-        s->unrestricted_mv   = 1;
-        s->msmpeg4_version   = MSMP4_WMV1;
-        s->flipflop_rounding = 1;
+        s->c.out_format        = FMT_H263;
+        s->c.h263_pred         = 1;
+        s->c.unrestricted_mv   = 1;
+        s->c.msmpeg4_version   = MSMP4_WMV1;
+        s->c.flipflop_rounding = 1;
         avctx->delay         = 0;
-        s->low_delay         = 1;
+        s->c.low_delay         = 1;
         break;
     case AV_CODEC_ID_WMV2:
-        s->out_format        = FMT_H263;
-        s->h263_pred         = 1;
-        s->unrestricted_mv   = 1;
-        s->msmpeg4_version   = MSMP4_WMV2;
-        s->flipflop_rounding = 1;
+        s->c.out_format        = FMT_H263;
+        s->c.h263_pred         = 1;
+        s->c.unrestricted_mv   = 1;
+        s->c.msmpeg4_version   = MSMP4_WMV2;
+        s->c.flipflop_rounding = 1;
         avctx->delay         = 0;
-        s->low_delay         = 1;
+        s->c.low_delay         = 1;
         break;
     default:
         return AVERROR(EINVAL);
     }
 
-    avctx->has_b_frames = !s->low_delay;
+    avctx->has_b_frames = !s->c.low_delay;
 
-    s->encoding = 1;
+    s->c.encoding = 1;
 
-    s->progressive_frame    =
-    s->progressive_sequence = !(avctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT |
-                                                AV_CODEC_FLAG_INTERLACED_ME) ||
-                                s->alternate_scan);
+    s->c.progressive_frame    =
+    s->c.progressive_sequence = !(avctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT |
+                                                  AV_CODEC_FLAG_INTERLACED_ME) ||
+                                s->c.alternate_scan);
 
     if (avctx->flags & AV_CODEC_FLAG_PSNR || avctx->mb_decision == FF_MB_DECISION_RD ||
         m->frame_skip_threshold || m->frame_skip_factor) {
@@ -1009,8 +1009,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         m->lmin = m->lmax;
     }
 
-    /* init */
-    ff_mpv_idct_init(s);
+    /* ff_mpv_common_init() will copy (memdup) the contents main slice
+     * to the slice contexts, so we initialize various fields of it
+     * before calling ff_mpv_common_init(). */
+    ff_mpv_idct_init(&s->c);
     ff_fdctdsp_init(&s->fdsp, avctx);
     ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
     ff_pixblockdsp_init(&s->pdsp, avctx);
@@ -1020,7 +1022,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
         !(s->new_pic = av_frame_alloc()) ||
-        !(s->picture_pool = ff_mpv_alloc_pic_pool(0)))
+        !(s->c.picture_pool = ff_mpv_alloc_pic_pool(0)))
         return AVERROR(ENOMEM);
 
     ret = init_matrices(m, avctx);
@@ -1029,35 +1031,36 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     ff_dct_encode_init(s);
 
-    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
-        s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
-        s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
-    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
-        s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
-        s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
+    if (s->c.mpeg_quant || s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+        s->c.dct_unquantize_intra = s->c.dct_unquantize_mpeg2_intra;
+        s->c.dct_unquantize_inter = s->c.dct_unquantize_mpeg2_inter;
+    } else if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
+        s->c.dct_unquantize_intra = s->c.dct_unquantize_h263_intra;
+        s->c.dct_unquantize_inter = s->c.dct_unquantize_h263_inter;
     } else {
-        s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
-        s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
+        s->c.dct_unquantize_intra = s->c.dct_unquantize_mpeg1_intra;
+        s->c.dct_unquantize_inter = s->c.dct_unquantize_mpeg1_inter;
     }
 
-    if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) {
+    if (CONFIG_H263_ENCODER && s->c.out_format == FMT_H263) {
         ff_h263_encode_init(m);
 #if CONFIG_MSMPEG4ENC
-        if (s->msmpeg4_version != MSMP4_UNUSED)
+        if (s->c.msmpeg4_version != MSMP4_UNUSED)
             ff_msmpeg4_encode_init(m);
 #endif
     }
 
-    ret = ff_mpv_common_init(s);
+    s->c.slice_ctx_size = sizeof(*s);
+    ret = ff_mpv_common_init(&s->c);
     if (ret < 0)
         return ret;
 
-    if (s->slice_context_count > 1) {
-        for (int i = 0; i < s->slice_context_count; ++i) {
-            s->thread_context[i]->rtp_mode = 1;
+    if (s->c.slice_context_count > 1) {
+        for (int i = 0; i < s->c.slice_context_count; ++i) {
+            s->c.enc_contexts[i]->rtp_mode = 1;
 
             if (avctx->codec_id == AV_CODEC_ID_H263P)
-                s->thread_context[i]->h263_slice_structured = 1;
+                s->c.enc_contexts[i]->c.h263_slice_structured = 1;
         }
     }
 
@@ -1076,8 +1079,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
                 return AVERROR(ENOMEM);
 
             m->tmp_frames[i]->format = AV_PIX_FMT_YUV420P;
-            m->tmp_frames[i]->width  = s->width  >> m->brd_scale;
-            m->tmp_frames[i]->height = s->height >> m->brd_scale;
+            m->tmp_frames[i]->width  = s->c.width  >> m->brd_scale;
+            m->tmp_frames[i]->height = s->c.height >> m->brd_scale;
 
             ret = av_frame_get_buffer(m->tmp_frames[i], 0);
             if (ret < 0)
@@ -1099,12 +1102,12 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
 {
     MPVMainEncContext *const m = avctx->priv_data;
-    MpegEncContext    *const s = &m->s;
+    MPVEncContext    *const s = &m->s;
 
     ff_rate_control_uninit(&m->rc_context);
 
-    ff_mpv_common_end(s);
-    av_refstruct_pool_uninit(&s->picture_pool);
+    ff_mpv_common_end(&s->c);
+    av_refstruct_pool_uninit(&s->c.picture_pool);
 
     for (int i = 0; i < MPVENC_MAX_B_FRAMES + 1; i++) {
         av_refstruct_unref(&m->input_picture[i]);
@@ -1133,88 +1136,88 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
 }
 
 /* put block[] to dest[] */
-static inline void put_dct(MpegEncContext *s,
+static inline void put_dct(MPVEncContext *const s,
                            int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
-    s->dct_unquantize_intra(s, block, i, qscale);
-    s->idsp.idct_put(dest, line_size, block);
+    s->c.dct_unquantize_intra(&s->c, block, i, qscale);
+    s->c.idsp.idct_put(dest, line_size, block);
 }
 
-static inline void add_dequant_dct(MpegEncContext *s,
+static inline void add_dequant_dct(MPVEncContext *const s,
                            int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
-    if (s->block_last_index[i] >= 0) {
-        s->dct_unquantize_inter(s, block, i, qscale);
+    if (s->c.block_last_index[i] >= 0) {
+        s->c.dct_unquantize_inter(&s->c, block, i, qscale);
 
-        s->idsp.idct_add(dest, line_size, block);
+        s->c.idsp.idct_add(dest, line_size, block);
     }
 }
 
 /**
  * Performs dequantization and IDCT (if necessary)
  */
-static void mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64])
+static void mpv_reconstruct_mb(MPVEncContext *const s, int16_t block[12][64])
 {
-    if (s->avctx->debug & FF_DEBUG_DCT_COEFF) {
+    if (s->c.avctx->debug & FF_DEBUG_DCT_COEFF) {
        /* print DCT coefficients */
-       av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
+       av_log(s->c.avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->c.mb_x, s->c.mb_y);
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 64; j++) {
-               av_log(s->avctx, AV_LOG_DEBUG, "%5d",
-                      block[i][s->idsp.idct_permutation[j]]);
+               av_log(s->c.avctx, AV_LOG_DEBUG, "%5d",
+                      block[i][s->c.idsp.idct_permutation[j]]);
            }
-           av_log(s->avctx, AV_LOG_DEBUG, "\n");
+           av_log(s->c.avctx, AV_LOG_DEBUG, "\n");
        }
     }
 
-    if ((1 << s->pict_type) & s->frame_reconstruction_bitfield) {
-        uint8_t *dest_y = s->dest[0], *dest_cb = s->dest[1], *dest_cr = s->dest[2];
+    if ((1 << s->c.pict_type) & s->frame_reconstruction_bitfield) {
+        uint8_t *dest_y = s->c.dest[0], *dest_cb = s->c.dest[1], *dest_cr = s->c.dest[2];
         int dct_linesize, dct_offset;
-        const int linesize   = s->cur_pic.linesize[0];
-        const int uvlinesize = s->cur_pic.linesize[1];
+        const int linesize   = s->c.cur_pic.linesize[0];
+        const int uvlinesize = s->c.cur_pic.linesize[1];
         const int block_size = 8;
 
-        dct_linesize = linesize << s->interlaced_dct;
-        dct_offset   = s->interlaced_dct ? linesize : linesize * block_size;
+        dct_linesize = linesize << s->c.interlaced_dct;
+        dct_offset   = s->c.interlaced_dct ? linesize : linesize * block_size;
 
-        if (!s->mb_intra) {
+        if (!s->c.mb_intra) {
             /* No MC, as that was already done otherwise */
-            add_dequant_dct(s, block[0], 0, dest_y                          , dct_linesize, s->qscale);
-            add_dequant_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->qscale);
-            add_dequant_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->qscale);
-            add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
-
-            if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
-                if (s->chroma_y_shift) {
-                    add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
-                    add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
+            add_dequant_dct(s, block[0], 0, dest_y                          , dct_linesize, s->c.qscale);
+            add_dequant_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->c.qscale);
+            add_dequant_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->c.qscale);
+            add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->c.qscale);
+
+            if (!CONFIG_GRAY || !(s->c.avctx->flags & AV_CODEC_FLAG_GRAY)) {
+                if (s->c.chroma_y_shift) {
+                    add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->c.chroma_qscale);
+                    add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->c.chroma_qscale);
                 } else {
                     dct_linesize >>= 1;
                     dct_offset   >>= 1;
-                    add_dequant_dct(s, block[4], 4, dest_cb,              dct_linesize, s->chroma_qscale);
-                    add_dequant_dct(s, block[5], 5, dest_cr,              dct_linesize, s->chroma_qscale);
-                    add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
-                    add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
+                    add_dequant_dct(s, block[4], 4, dest_cb,              dct_linesize, s->c.chroma_qscale);
+                    add_dequant_dct(s, block[5], 5, dest_cr,              dct_linesize, s->c.chroma_qscale);
+                    add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->c.chroma_qscale);
+                    add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->c.chroma_qscale);
                 }
             }
         } else {
             /* dct only in intra block */
-            put_dct(s, block[0], 0, dest_y                          , dct_linesize, s->qscale);
-            put_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->qscale);
-            put_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->qscale);
-            put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
-
-            if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
-                if (s->chroma_y_shift) {
-                    put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale);
-                    put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale);
+            put_dct(s, block[0], 0, dest_y                          , dct_linesize, s->c.qscale);
+            put_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->c.qscale);
+            put_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->c.qscale);
+            put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->c.qscale);
+
+            if (!CONFIG_GRAY || !(s->c.avctx->flags & AV_CODEC_FLAG_GRAY)) {
+                if (s->c.chroma_y_shift) {
+                    put_dct(s, block[4], 4, dest_cb, uvlinesize, s->c.chroma_qscale);
+                    put_dct(s, block[5], 5, dest_cr, uvlinesize, s->c.chroma_qscale);
                 } else {
                     dct_offset   >>= 1;
                     dct_linesize >>= 1;
-                    put_dct(s, block[4], 4, dest_cb,              dct_linesize, s->chroma_qscale);
-                    put_dct(s, block[5], 5, dest_cr,              dct_linesize, s->chroma_qscale);
-                    put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale);
-                    put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale);
+                    put_dct(s, block[4], 4, dest_cb,              dct_linesize, s->c.chroma_qscale);
+                    put_dct(s, block[5], 5, dest_cr,              dct_linesize, s->c.chroma_qscale);
+                    put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->c.chroma_qscale);
+                    put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->c.chroma_qscale);
                 }
             }
         }
@@ -1235,14 +1238,14 @@ static int get_sae(const uint8_t *src, int ref, int stride)
     return acc;
 }
 
-static int get_intra_count(MpegEncContext *s, const uint8_t *src,
+static int get_intra_count(MPVEncContext *const s, const uint8_t *src,
                            const uint8_t *ref, int stride)
 {
     int x, y, w, h;
     int acc = 0;
 
-    w = s->width  & ~15;
-    h = s->height & ~15;
+    w = s->c.width  & ~15;
+    h = s->c.height & ~15;
 
     for (y = 0; y < h; y += 16) {
         for (x = 0; x < w; x += 16) {
@@ -1262,9 +1265,9 @@ static int get_intra_count(MpegEncContext *s, const uint8_t *src,
  * Allocates new buffers for an AVFrame and copies the properties
  * from another AVFrame.
  */
-static int prepare_picture(MpegEncContext *s, AVFrame *f, const AVFrame *props_frame)
+static int prepare_picture(MPVEncContext *const s, AVFrame *f, const AVFrame *props_frame)
 {
-    AVCodecContext *avctx = s->avctx;
+    AVCodecContext *avctx = s->c.avctx;
     int ret;
 
     f->width  = avctx->width  + 2 * EDGE_WIDTH;
@@ -1274,14 +1277,14 @@ static int prepare_picture(MpegEncContext *s, AVFrame *f, const AVFrame *props_f
     if (ret < 0)
         return ret;
 
-    ret = ff_mpv_pic_check_linesize(avctx, f, &s->linesize, &s->uvlinesize);
+    ret = ff_mpv_pic_check_linesize(avctx, f, &s->c.linesize, &s->c.uvlinesize);
     if (ret < 0)
         return ret;
 
     for (int i = 0; f->data[i]; i++) {
-        int offset = (EDGE_WIDTH >> (i ? s->chroma_y_shift : 0)) *
+        int offset = (EDGE_WIDTH >> (i ? s->c.chroma_y_shift : 0)) *
                      f->linesize[i] +
-                     (EDGE_WIDTH >> (i ? s->chroma_x_shift : 0));
+                     (EDGE_WIDTH >> (i ? s->c.chroma_x_shift : 0));
         f->data[i] += offset;
     }
     f->width  = avctx->width;
@@ -1296,12 +1299,12 @@ static int prepare_picture(MpegEncContext *s, AVFrame *f, const AVFrame *props_f
 
 static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     MPVPicture *pic = NULL;
     int64_t pts;
     int display_picture_number = 0, ret;
     int encoding_delay = m->max_b_frames ? m->max_b_frames
-                                         : (s->low_delay ? 0 : 1);
+                                         : (s->c.low_delay ? 0 : 1);
     int flush_offset = 1;
     int direct = 1;
 
@@ -1316,13 +1319,13 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
                 int64_t last = m->user_specified_pts;
 
                 if (pts <= last) {
-                    av_log(s->avctx, AV_LOG_ERROR,
+                    av_log(s->c.avctx, AV_LOG_ERROR,
                            "Invalid pts (%"PRId64") <= last (%"PRId64")\n",
                            pts, last);
                     return AVERROR(EINVAL);
                 }
 
-                if (!s->low_delay && display_picture_number == 1)
+                if (!s->c.low_delay && display_picture_number == 1)
                     m->dts_delta = pts - last;
             }
             m->user_specified_pts = pts;
@@ -1330,7 +1333,7 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
             if (m->user_specified_pts != AV_NOPTS_VALUE) {
                 m->user_specified_pts =
                 pts = m->user_specified_pts + 1;
-                av_log(s->avctx, AV_LOG_INFO,
+                av_log(s->c.avctx, AV_LOG_INFO,
                        "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n",
                        pts);
             } else {
@@ -1338,21 +1341,21 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
             }
         }
 
-        if (pic_arg->linesize[0] != s->linesize ||
-            pic_arg->linesize[1] != s->uvlinesize ||
-            pic_arg->linesize[2] != s->uvlinesize)
+        if (pic_arg->linesize[0] != s->c.linesize ||
+            pic_arg->linesize[1] != s->c.uvlinesize ||
+            pic_arg->linesize[2] != s->c.uvlinesize)
             direct = 0;
-        if ((s->width & 15) || (s->height & 15))
+        if ((s->c.width & 15) || (s->c.height & 15))
             direct = 0;
         if (((intptr_t)(pic_arg->data[0])) & (STRIDE_ALIGN-1))
             direct = 0;
-        if (s->linesize & (STRIDE_ALIGN-1))
+        if (s->c.linesize & (STRIDE_ALIGN-1))
             direct = 0;
 
-        ff_dlog(s->avctx, "%d %d %"PTRDIFF_SPECIFIER" %"PTRDIFF_SPECIFIER"\n", pic_arg->linesize[0],
-                pic_arg->linesize[1], s->linesize, s->uvlinesize);
+        ff_dlog(s->c.avctx, "%d %d %"PTRDIFF_SPECIFIER" %"PTRDIFF_SPECIFIER"\n", pic_arg->linesize[0],
+                pic_arg->linesize[1], s->c.linesize, s->c.uvlinesize);
 
-        pic = av_refstruct_pool_get(s->picture_pool);
+        pic = av_refstruct_pool_get(s->c.picture_pool);
         if (!pic)
             return AVERROR(ENOMEM);
 
@@ -1367,21 +1370,21 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
 
             for (int i = 0; i < 3; i++) {
                 ptrdiff_t src_stride = pic_arg->linesize[i];
-                ptrdiff_t dst_stride = i ? s->uvlinesize : s->linesize;
-                int h_shift = i ? s->chroma_x_shift : 0;
-                int v_shift = i ? s->chroma_y_shift : 0;
-                int w = AV_CEIL_RSHIFT(s->width , h_shift);
-                int h = AV_CEIL_RSHIFT(s->height, v_shift);
+                ptrdiff_t dst_stride = i ? s->c.uvlinesize : s->c.linesize;
+                int h_shift = i ? s->c.chroma_x_shift : 0;
+                int v_shift = i ? s->c.chroma_y_shift : 0;
+                int w = AV_CEIL_RSHIFT(s->c.width , h_shift);
+                int h = AV_CEIL_RSHIFT(s->c.height, v_shift);
                 const uint8_t *src = pic_arg->data[i];
                 uint8_t *dst = pic->f->data[i];
                 int vpad = 16;
 
-                if (   s->codec_id == AV_CODEC_ID_MPEG2VIDEO
-                    && !s->progressive_sequence
-                    && FFALIGN(s->height, 32) - s->height > 16)
+                if (   s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO
+                    && !s->c.progressive_sequence
+                    && FFALIGN(s->c.height, 32) - s->c.height > 16)
                     vpad = 32;
 
-                if (!s->avctx->rc_buffer_size)
+                if (!s->c.avctx->rc_buffer_size)
                     dst += INPLACE_OFFSET;
 
                 if (src_stride == dst_stride)
@@ -1395,7 +1398,7 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg
                         src += src_stride;
                     }
                 }
-                if ((s->width & 15) || (s->height & (vpad-1))) {
+                if ((s->c.width & 15) || (s->c.height & (vpad-1))) {
                     s->mpvencdsp.draw_edges(dst, dst_stride,
                                             w, h,
                                             16 >> h_shift,
@@ -1438,7 +1441,7 @@ fail:
 static int skip_check(MPVMainEncContext *const m,
                       const MPVPicture *p, const MPVPicture *ref)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int x, y, plane;
     int score = 0;
     int64_t score64 = 0;
@@ -1446,8 +1449,8 @@ static int skip_check(MPVMainEncContext *const m,
     for (plane = 0; plane < 3; plane++) {
         const int stride = p->f->linesize[plane];
         const int bw = plane ? 1 : 2;
-        for (y = 0; y < s->mb_height * bw; y++) {
-            for (x = 0; x < s->mb_width * bw; x++) {
+        for (y = 0; y < s->c.mb_height * bw; y++) {
+            for (x = 0; x < s->c.mb_width * bw; x++) {
                 int off = p->shared ? 0 : 16;
                 const uint8_t *dptr = p->f->data[plane] + 8 * (x + y * stride) + off;
                 const uint8_t *rptr = ref->f->data[plane] + 8 * (x + y * stride);
@@ -1468,12 +1471,12 @@ static int skip_check(MPVMainEncContext *const m,
     if (score)
         score64 = score;
     if (m->frame_skip_exp < 0)
-        score64 = pow(score64 / (double)(s->mb_width * s->mb_height),
+        score64 = pow(score64 / (double)(s->c.mb_width * s->c.mb_height),
                       -1.0/m->frame_skip_exp);
 
     if (score64 < m->frame_skip_threshold)
         return 1;
-    if (score64 < ((m->frame_skip_factor * (int64_t) s->lambda) >> 8))
+    if (score64 < ((m->frame_skip_factor * (int64_t) s->c.lambda) >> 8))
         return 1;
     return 0;
 }
@@ -1501,11 +1504,11 @@ static int encode_frame(AVCodecContext *c, const AVFrame *frame, AVPacket *pkt)
 
 static int estimate_best_b_count(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     AVPacket *pkt;
     const int scale = m->brd_scale;
-    int width  = s->width  >> scale;
-    int height = s->height >> scale;
+    int width  = s->c.width  >> scale;
+    int height = s->c.height >> scale;
     int out_size, p_lambda, b_lambda, lambda2;
     int64_t best_rd  = INT64_MAX;
     int best_b_count = -1;
@@ -1519,7 +1522,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
 
     //emms_c();
     p_lambda = m->last_lambda_for[AV_PICTURE_TYPE_P];
-    //p_lambda * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;
+    //p_lambda * FFABS(s->c.avctx->b_quant_factor) + s->c.avctx->b_quant_offset;
     b_lambda = m->last_lambda_for[AV_PICTURE_TYPE_B];
     if (!b_lambda) // FIXME we should do this somewhere else
         b_lambda = p_lambda;
@@ -1528,7 +1531,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
 
     for (int i = 0; i < m->max_b_frames + 2; i++) {
         const MPVPicture *pre_input_ptr = i ? m->input_picture[i - 1] :
-                                           s->next_pic.ptr;
+                                           s->c.next_pic.ptr;
 
         if (pre_input_ptr) {
             const uint8_t *data[4];
@@ -1574,16 +1577,16 @@ static int estimate_best_b_count(MPVMainEncContext *const m)
         c->width        = width;
         c->height       = height;
         c->flags        = AV_CODEC_FLAG_QSCALE | AV_CODEC_FLAG_PSNR;
-        c->flags       |= s->avctx->flags & AV_CODEC_FLAG_QPEL;
-        c->mb_decision  = s->avctx->mb_decision;
-        c->me_cmp       = s->avctx->me_cmp;
-        c->mb_cmp       = s->avctx->mb_cmp;
-        c->me_sub_cmp   = s->avctx->me_sub_cmp;
+        c->flags       |= s->c.avctx->flags & AV_CODEC_FLAG_QPEL;
+        c->mb_decision  = s->c.avctx->mb_decision;
+        c->me_cmp       = s->c.avctx->me_cmp;
+        c->mb_cmp       = s->c.avctx->mb_cmp;
+        c->me_sub_cmp   = s->c.avctx->me_sub_cmp;
         c->pix_fmt      = AV_PIX_FMT_YUV420P;
-        c->time_base    = s->avctx->time_base;
+        c->time_base    = s->c.avctx->time_base;
         c->max_b_frames = m->max_b_frames;
 
-        ret = avcodec_open2(c, s->avctx->codec, NULL);
+        ret = avcodec_open2(c, s->c.avctx->codec, NULL);
         if (ret < 0)
             goto fail;
 
@@ -1654,7 +1657,7 @@ fail:
  */
 static int set_bframe_chain_length(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
     /* Either nothing to do or can't do anything */
     if (m->reordered_input_picture[0] || !m->input_picture[0])
@@ -1663,8 +1666,8 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
     /* set next picture type & ordering */
     if (m->frame_skip_threshold || m->frame_skip_factor) {
         if (m->picture_in_gop_number < m->gop_size &&
-            s->next_pic.ptr &&
-            skip_check(m, m->input_picture[0], s->next_pic.ptr)) {
+            s->c.next_pic.ptr &&
+            skip_check(m, m->input_picture[0], s->c.next_pic.ptr)) {
             // FIXME check that the gop check above is +-1 correct
             av_refstruct_unref(&m->input_picture[0]);
 
@@ -1675,7 +1678,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
     }
 
     if (/* m->picture_in_gop_number >= m->gop_size || */
-        !s->next_pic.ptr || m->intra_only) {
+        !s->c.next_pic.ptr || m->intra_only) {
         m->reordered_input_picture[0] = m->input_picture[0];
         m->input_picture[0] = NULL;
         m->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I;
@@ -1684,7 +1687,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
     } else {
         int b_frames = 0;
 
-        if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
+        if (s->c.avctx->flags & AV_CODEC_FLAG_PASS2) {
             for (int i = 0; i < m->max_b_frames + 1; i++) {
                 int pict_num = m->input_picture[0]->display_picture_number + i;
 
@@ -1712,13 +1715,13 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
                         get_intra_count(s,
                                         m->input_picture[i    ]->f->data[0],
                                         m->input_picture[i - 1]->f->data[0],
-                                        s->linesize) + 1;
+                                        s->c.linesize) + 1;
                 }
             }
             for (int i = 0; i < m->max_b_frames + 1; i++) {
                 if (!m->input_picture[i] ||
                     m->input_picture[i]->b_frame_score - 1 >
-                        s->mb_num / m->b_sensitivity) {
+                        s->c.mb_num / m->b_sensitivity) {
                     b_frames = FFMAX(0, i - 1);
                     break;
                 }
@@ -1744,7 +1747,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
         }
         if (m->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_B &&
             b_frames == m->max_b_frames) {
-            av_log(s->avctx, AV_LOG_ERROR,
+            av_log(s->c.avctx, AV_LOG_ERROR,
                     "warning, too many B-frames in a row\n");
         }
 
@@ -1753,13 +1756,13 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
                 m->gop_size > m->picture_in_gop_number) {
                 b_frames = m->gop_size - m->picture_in_gop_number - 1;
             } else {
-                if (s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)
+                if (s->c.avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)
                     b_frames = 0;
                 m->input_picture[b_frames]->f->pict_type = AV_PICTURE_TYPE_I;
             }
         }
 
-        if ((s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) && b_frames &&
+        if ((s->c.avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) && b_frames &&
             m->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_I)
             b_frames--;
 
@@ -1784,7 +1787,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
 
 static int select_input_picture(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int ret;
 
     av_assert1(!m->reordered_input_picture[0]);
@@ -1804,7 +1807,7 @@ static int select_input_picture(MPVMainEncContext *const m)
         m->reordered_input_picture[0]->reference =
            m->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_B;
 
-        if (m->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
+        if (m->reordered_input_picture[0]->shared || s->c.avctx->rc_buffer_size) {
             // input is a shared pix, so we can't modify it -> allocate a new
             // one & ensure that the shared one is reuseable
             av_frame_move_ref(s->new_pic, m->reordered_input_picture[0]->f);
@@ -1822,18 +1825,18 @@ static int select_input_picture(MPVMainEncContext *const m)
                     s->new_pic->data[i] += INPLACE_OFFSET;
             }
         }
-        s->cur_pic.ptr = m->reordered_input_picture[0];
+        s->c.cur_pic.ptr = m->reordered_input_picture[0];
         m->reordered_input_picture[0] = NULL;
-        av_assert1(s->mb_width  == s->buffer_pools.alloc_mb_width);
-        av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height);
-        av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride);
-        ret = ff_mpv_alloc_pic_accessories(s->avctx, &s->cur_pic,
-                                           &s->sc, &s->buffer_pools, s->mb_height);
+        av_assert1(s->c.mb_width  == s->c.buffer_pools.alloc_mb_width);
+        av_assert1(s->c.mb_height == s->c.buffer_pools.alloc_mb_height);
+        av_assert1(s->c.mb_stride == s->c.buffer_pools.alloc_mb_stride);
+        ret = ff_mpv_alloc_pic_accessories(s->c.avctx, &s->c.cur_pic,
+                                           &s->c.sc, &s->c.buffer_pools, s->c.mb_height);
         if (ret < 0) {
-            ff_mpv_unref_picture(&s->cur_pic);
+            ff_mpv_unref_picture(&s->c.cur_pic);
             return ret;
         }
-        s->picture_number = s->cur_pic.ptr->display_picture_number;
+        s->c.picture_number = s->c.cur_pic.ptr->display_picture_number;
 
     }
     return 0;
@@ -1844,29 +1847,29 @@ fail:
 
 static void frame_end(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    if (s->unrestricted_mv &&
-        s->cur_pic.reference &&
+    if (s->c.unrestricted_mv &&
+        s->c.cur_pic.reference &&
         !m->intra_only) {
-        int hshift = s->chroma_x_shift;
-        int vshift = s->chroma_y_shift;
-        s->mpvencdsp.draw_edges(s->cur_pic.data[0],
-                                s->cur_pic.linesize[0],
-                                s->h_edge_pos, s->v_edge_pos,
+        int hshift = s->c.chroma_x_shift;
+        int vshift = s->c.chroma_y_shift;
+        s->mpvencdsp.draw_edges(s->c.cur_pic.data[0],
+                                s->c.cur_pic.linesize[0],
+                                s->c.h_edge_pos, s->c.v_edge_pos,
                                 EDGE_WIDTH, EDGE_WIDTH,
                                 EDGE_TOP | EDGE_BOTTOM);
-        s->mpvencdsp.draw_edges(s->cur_pic.data[1],
-                                s->cur_pic.linesize[1],
-                                s->h_edge_pos >> hshift,
-                                s->v_edge_pos >> vshift,
+        s->mpvencdsp.draw_edges(s->c.cur_pic.data[1],
+                                s->c.cur_pic.linesize[1],
+                                s->c.h_edge_pos >> hshift,
+                                s->c.v_edge_pos >> vshift,
                                 EDGE_WIDTH >> hshift,
                                 EDGE_WIDTH >> vshift,
                                 EDGE_TOP | EDGE_BOTTOM);
-        s->mpvencdsp.draw_edges(s->cur_pic.data[2],
-                                s->cur_pic.linesize[2],
-                                s->h_edge_pos >> hshift,
-                                s->v_edge_pos >> vshift,
+        s->mpvencdsp.draw_edges(s->c.cur_pic.data[2],
+                                s->c.cur_pic.linesize[2],
+                                s->c.h_edge_pos >> hshift,
+                                s->c.v_edge_pos >> vshift,
                                 EDGE_WIDTH >> hshift,
                                 EDGE_WIDTH >> vshift,
                                 EDGE_TOP | EDGE_BOTTOM);
@@ -1874,15 +1877,15 @@ static void frame_end(MPVMainEncContext *const m)
 
     emms_c();
 
-    m->last_pict_type                = s->pict_type;
-    m->last_lambda_for[s->pict_type] = s->cur_pic.ptr->f->quality;
-    if (s->pict_type!= AV_PICTURE_TYPE_B)
-        m->last_non_b_pict_type = s->pict_type;
+    m->last_pict_type                = s->c.pict_type;
+    m->last_lambda_for[s->c.pict_type] = s->c.cur_pic.ptr->f->quality;
+    if (s->c.pict_type!= AV_PICTURE_TYPE_B)
+        m->last_non_b_pict_type = s->c.pict_type;
 }
 
 static void update_noise_reduction(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int intra, i;
 
     for (intra = 0; intra < 2; intra++) {
@@ -1904,13 +1907,13 @@ static void update_noise_reduction(MPVMainEncContext *const m)
 
 static void frame_start(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    s->cur_pic.ptr->f->pict_type = s->pict_type;
+    s->c.cur_pic.ptr->f->pict_type = s->c.pict_type;
 
-    if (s->pict_type != AV_PICTURE_TYPE_B) {
-        ff_mpv_replace_picture(&s->last_pic, &s->next_pic);
-        ff_mpv_replace_picture(&s->next_pic, &s->cur_pic);
+    if (s->c.pict_type != AV_PICTURE_TYPE_B) {
+        ff_mpv_replace_picture(&s->c.last_pic, &s->c.next_pic);
+        ff_mpv_replace_picture(&s->c.next_pic, &s->c.cur_pic);
     }
 
     av_assert2(!!m->noise_reduction == !!s->dct_error_sum);
@@ -1923,11 +1926,11 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
                           const AVFrame *pic_arg, int *got_packet)
 {
     MPVMainEncContext *const m = avctx->priv_data;
-    MpegEncContext    *const s = &m->s;
+    MPVEncContext    *const s = &m->s;
     int stuffing_count, ret;
-    int context_count = s->slice_context_count;
+    int context_count = s->c.slice_context_count;
 
-    ff_mpv_unref_picture(&s->cur_pic);
+    ff_mpv_unref_picture(&s->c.cur_pic);
 
     m->vbv_ignore_qmax = 0;
 
@@ -1943,8 +1946,8 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
     /* output? */
     if (s->new_pic->data[0]) {
-        int growing_buffer = context_count == 1 && !s->data_partitioning;
-        size_t pkt_size = 10000 + s->mb_width * s->mb_height *
+        int growing_buffer = context_count == 1 && !s->c.data_partitioning;
+        size_t pkt_size = 10000 + s->c.mb_width * s->c.mb_height *
                                   (growing_buffer ? 64 : (MAX_MB_BYTES + 100));
         if (CONFIG_MJPEG_ENCODER && avctx->codec_id == AV_CODEC_ID_MJPEG) {
             ret = ff_mjpeg_add_icc_profile_size(avctx, s->new_pic, &pkt_size);
@@ -1957,13 +1960,13 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
         if (s->mb_info) {
             s->mb_info_ptr = av_packet_new_side_data(pkt,
                                  AV_PKT_DATA_H263_MB_INFO,
-                                 s->mb_width*s->mb_height*12);
+                                 s->c.mb_width*s->c.mb_height*12);
             if (!s->mb_info_ptr)
                 return AVERROR(ENOMEM);
             s->prev_mb_info = s->last_mb_info = s->mb_info_size = 0;
         }
 
-        s->pict_type = s->new_pic->pict_type;
+        s->c.pict_type = s->new_pic->pict_type;
         //emms_c();
         frame_start(m);
 vbv_retry:
@@ -1978,7 +1981,7 @@ vbv_retry:
 
         frame_end(m);
 
-       if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) && s->out_format == FMT_MJPEG)
+       if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) && s->c.out_format == FMT_MJPEG)
             ff_mjpeg_encode_picture_trailer(&s->pb, m->header_bits);
 
         if (avctx->rc_buffer_size) {
@@ -1988,25 +1991,24 @@ vbv_retry:
             int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139;
 
             if (put_bits_count(&s->pb) > max_size &&
-                s->lambda < m->lmax) {
-                m->next_lambda = FFMAX(s->lambda + min_step, s->lambda *
-                                       (s->qscale + 1) / s->qscale);
+                s->c.lambda < m->lmax) {
+                m->next_lambda = FFMAX(s->c.lambda + min_step, s->c.lambda *
+                                       (s->c.qscale + 1) / s->c.qscale);
                 if (s->adaptive_quant) {
-                    int i;
-                    for (i = 0; i < s->mb_height * s->mb_stride; i++)
+                    for (int i = 0; i < s->c.mb_height * s->c.mb_stride; i++)
                         s->lambda_table[i] =
                             FFMAX(s->lambda_table[i] + min_step,
-                                  s->lambda_table[i] * (s->qscale + 1) /
-                                  s->qscale);
+                                  s->lambda_table[i] * (s->c.qscale + 1) /
+                                  s->c.qscale);
                 }
-                s->mb_skipped = 0;        // done in frame_start()
+                s->c.mb_skipped = 0;        // done in frame_start()
                 // done in encode_picture() so we must undo it
-                if (s->pict_type == AV_PICTURE_TYPE_P) {
-                    s->no_rounding ^= s->flipflop_rounding;
+                if (s->c.pict_type == AV_PICTURE_TYPE_P) {
+                    s->c.no_rounding ^= s->c.flipflop_rounding;
                 }
-                if (s->pict_type != AV_PICTURE_TYPE_B) {
-                    s->time_base       = s->last_time_base;
-                    s->last_non_b_time = s->time - s->pp_time;
+                if (s->c.pict_type != AV_PICTURE_TYPE_B) {
+                    s->c.time_base       = s->c.last_time_base;
+                    s->c.last_non_b_time = s->c.time - s->c.pp_time;
                 }
                 m->vbv_ignore_qmax = 1;
                 av_log(avctx, AV_LOG_VERBOSE, "reencoding frame due to VBV\n");
@@ -2021,10 +2023,10 @@ vbv_retry:
 
         for (int i = 0; i < MPV_MAX_PLANES; i++)
             avctx->error[i] += s->encoding_error[i];
-        ff_side_data_set_encoder_stats(pkt, s->cur_pic.ptr->f->quality,
+        ff_side_data_set_encoder_stats(pkt, s->c.cur_pic.ptr->f->quality,
                                        s->encoding_error,
                                        (avctx->flags&AV_CODEC_FLAG_PSNR) ? MPV_MAX_PLANES : 0,
-                                       s->pict_type);
+                                       s->c.pict_type);
 
         if (avctx->flags & AV_CODEC_FLAG_PASS1)
             assert(put_bits_count(&s->pb) == m->header_bits + s->mv_bits +
@@ -2041,7 +2043,7 @@ vbv_retry:
                 return -1;
             }
 
-            switch (s->codec_id) {
+            switch (s->c.codec_id) {
             case AV_CODEC_ID_MPEG1VIDEO:
             case AV_CODEC_ID_MPEG2VIDEO:
                 while (stuffing_count--) {
@@ -2067,7 +2069,7 @@ vbv_retry:
         /* update MPEG-1/2 vbv_delay for CBR */
         if (avctx->rc_max_rate                          &&
             avctx->rc_min_rate == avctx->rc_max_rate &&
-            s->out_format == FMT_MPEG1                     &&
+            s->c.out_format == FMT_MPEG1                     &&
             90000LL * (avctx->rc_buffer_size - 1) <=
                 avctx->rc_max_rate * 0xFFFFLL) {
             AVCPBProperties *props;
@@ -2085,7 +2087,7 @@ vbv_retry:
                 av_log(avctx, AV_LOG_ERROR,
                        "Internal error, negative bits\n");
 
-            av_assert1(s->repeat_first_field == 0);
+            av_assert1(s->c.repeat_first_field == 0);
 
             vbv_delay = bits * 90000 / avctx->rc_max_rate;
             min_delay = (minbits * 90000LL + avctx->rc_max_rate - 1) /
@@ -2115,10 +2117,10 @@ vbv_retry:
         }
         m->total_bits += m->frame_bits;
 
-        pkt->pts = s->cur_pic.ptr->f->pts;
-        pkt->duration = s->cur_pic.ptr->f->duration;
-        if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {
-            if (!s->cur_pic.ptr->coded_picture_number)
+        pkt->pts = s->c.cur_pic.ptr->f->pts;
+        pkt->duration = s->c.cur_pic.ptr->f->duration;
+        if (!s->c.low_delay && s->c.pict_type != AV_PICTURE_TYPE_B) {
+            if (!s->c.cur_pic.ptr->coded_picture_number)
                 pkt->dts = pkt->pts - m->dts_delta;
             else
                 pkt->dts = m->reordered_pts;
@@ -2128,12 +2130,12 @@ vbv_retry:
 
         // the no-delay case is handled in generic code
         if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY) {
-            ret = ff_encode_reordered_opaque(avctx, pkt, s->cur_pic.ptr->f);
+            ret = ff_encode_reordered_opaque(avctx, pkt, s->c.cur_pic.ptr->f);
             if (ret < 0)
                 return ret;
         }
 
-        if (s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
+        if (s->c.cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
             pkt->flags |= AV_PKT_FLAG_KEY;
         if (s->mb_info)
             av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);
@@ -2141,7 +2143,7 @@ vbv_retry:
         m->frame_bits = 0;
     }
 
-    ff_mpv_unref_picture(&s->cur_pic);
+    ff_mpv_unref_picture(&s->c.cur_pic);
 
     av_assert1((m->frame_bits & 7) == 0);
 
@@ -2150,7 +2152,7 @@ vbv_retry:
     return 0;
 }
 
-static inline void dct_single_coeff_elimination(MpegEncContext *s,
+static inline void dct_single_coeff_elimination(MPVEncContext *const s,
                                                 int n, int threshold)
 {
     static const char tab[64] = {
@@ -2166,8 +2168,8 @@ static inline void dct_single_coeff_elimination(MpegEncContext *s,
     int score = 0;
     int run = 0;
     int i;
-    int16_t *block = s->block[n];
-    const int last_index = s->block_last_index[n];
+    int16_t *block = s->c.block[n];
+    const int last_index = s->c.block_last_index[n];
     int skip_dc;
 
     if (threshold < 0) {
@@ -2181,7 +2183,7 @@ static inline void dct_single_coeff_elimination(MpegEncContext *s,
         return;
 
     for (i = 0; i <= last_index; i++) {
-        const int j = s->intra_scantable.permutated[i];
+        const int j = s->c.intra_scantable.permutated[i];
         const int level = FFABS(block[j]);
         if (level == 1) {
             if (skip_dc && i == 0)
@@ -2197,16 +2199,16 @@ static inline void dct_single_coeff_elimination(MpegEncContext *s,
     if (score >= threshold)
         return;
     for (i = skip_dc; i <= last_index; i++) {
-        const int j = s->intra_scantable.permutated[i];
+        const int j = s->c.intra_scantable.permutated[i];
         block[j] = 0;
     }
     if (block[0])
-        s->block_last_index[n] = 0;
+        s->c.block_last_index[n] = 0;
     else
-        s->block_last_index[n] = -1;
+        s->c.block_last_index[n] = -1;
 }
 
-static inline void clip_coeffs(MpegEncContext *s, int16_t *block,
+static inline void clip_coeffs(const MPVEncContext *const s, int16_t block[],
                                int last_index)
 {
     int i;
@@ -2214,13 +2216,13 @@ static inline void clip_coeffs(MpegEncContext *s, int16_t *block,
     const int minlevel = s->min_qcoeff;
     int overflow = 0;
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         i = 1; // skip clipping of intra dc
     } else
         i = 0;
 
     for (; i <= last_index; i++) {
-        const int j = s->intra_scantable.permutated[i];
+        const int j = s->c.intra_scantable.permutated[i];
         int level = block[j];
 
         if (level > maxlevel) {
@@ -2234,8 +2236,8 @@ static inline void clip_coeffs(MpegEncContext *s, int16_t *block,
         block[j] = level;
     }
 
-    if (overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE)
-        av_log(s->avctx, AV_LOG_INFO,
+    if (overflow && s->c.avctx->mb_decision == FF_MB_DECISION_SIMPLE)
+        av_log(s->c.avctx, AV_LOG_INFO,
                "warning, clipping %d dct coefficients to %d..%d\n",
                overflow, minlevel, maxlevel);
 }
@@ -2264,7 +2266,7 @@ static void get_visual_weight(int16_t *weight, const uint8_t *ptr, int stride)
     }
 }
 
-static av_always_inline void encode_mb_internal(MpegEncContext *s,
+static av_always_inline void encode_mb_internal(MPVEncContext *const s,
                                                 int motion_x, int motion_y,
                                                 int mb_block_height,
                                                 int mb_block_width,
@@ -2276,15 +2278,15 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
 /* Interlaced DCT is only possible with MPEG-2 and MPEG-4
  * and neither of these encoders currently supports 444. */
 #define INTERLACED_DCT(s) ((chroma_format == CHROMA_420 || chroma_format == CHROMA_422) && \
-                           (s)->avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
+                           (s)->c.avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
     int16_t weight[12][64];
     int16_t orig[12][64];
-    const int mb_x = s->mb_x;
-    const int mb_y = s->mb_y;
+    const int mb_x = s->c.mb_x;
+    const int mb_y = s->c.mb_y;
     int i;
     int skip_dct[12];
-    int dct_offset = s->linesize * 8; // default for progressive frames
-    int uv_dct_offset = s->uvlinesize * 8;
+    int dct_offset = s->c.linesize * 8; // default for progressive frames
+    int uv_dct_offset = s->c.uvlinesize * 8;
     const uint8_t *ptr_y, *ptr_cb, *ptr_cr;
     ptrdiff_t wrap_y, wrap_c;
 
@@ -2292,37 +2294,37 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         skip_dct[i] = s->skipdct;
 
     if (s->adaptive_quant) {
-        const int last_qp = s->qscale;
-        const int mb_xy = mb_x + mb_y * s->mb_stride;
+        const int last_qp = s->c.qscale;
+        const int mb_xy = mb_x + mb_y * s->c.mb_stride;
 
-        s->lambda = s->lambda_table[mb_xy];
-        s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
-                     FF_LAMBDA_SHIFT;
+        s->c.lambda = s->lambda_table[mb_xy];
+        s->c.lambda2 = (s->c.lambda * s->c.lambda + FF_LAMBDA_SCALE / 2) >>
+                       FF_LAMBDA_SHIFT;
 
         if (!(s->mpv_flags & FF_MPV_FLAG_QP_RD)) {
-            s->dquant = s->cur_pic.qscale_table[mb_xy] - last_qp;
+            s->dquant = s->c.cur_pic.qscale_table[mb_xy] - last_qp;
 
-            if (s->out_format == FMT_H263) {
+            if (s->c.out_format == FMT_H263) {
                 s->dquant = av_clip(s->dquant, -2, 2);
 
-                if (s->codec_id == AV_CODEC_ID_MPEG4) {
-                    if (!s->mb_intra) {
-                        if (s->pict_type == AV_PICTURE_TYPE_B) {
-                            if (s->dquant & 1 || s->mv_dir & MV_DIRECT)
+                if (s->c.codec_id == AV_CODEC_ID_MPEG4) {
+                    if (!s->c.mb_intra) {
+                        if (s->c.pict_type == AV_PICTURE_TYPE_B) {
+                            if (s->dquant & 1 || s->c.mv_dir & MV_DIRECT)
                                 s->dquant = 0;
                         }
-                        if (s->mv_type == MV_TYPE_8X8)
+                        if (s->c.mv_type == MV_TYPE_8X8)
                             s->dquant = 0;
                     }
                 }
             }
         }
-        ff_set_qscale(s, last_qp + s->dquant);
+        ff_set_qscale(&s->c, last_qp + s->dquant);
     } else if (s->mpv_flags & FF_MPV_FLAG_QP_RD)
-        ff_set_qscale(s, s->qscale + s->dquant);
+        ff_set_qscale(&s->c, s->c.qscale + s->dquant);
 
-    wrap_y = s->linesize;
-    wrap_c = s->uvlinesize;
+    wrap_y = s->c.linesize;
+    wrap_c = s->c.uvlinesize;
     ptr_y  = s->new_pic->data[0] +
              (mb_y * 16 * wrap_y)              + mb_x * 16;
     ptr_cb = s->new_pic->data[1] +
@@ -2330,22 +2332,23 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
     ptr_cr = s->new_pic->data[2] +
              (mb_y * mb_block_height * wrap_c) + mb_x * mb_block_width;
 
-    if((mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) && s->codec_id != AV_CODEC_ID_AMV){
-        uint8_t *ebuf = s->sc.edge_emu_buffer + 38 * wrap_y;
-        int cw = (s->width  + chroma_x_shift) >> chroma_x_shift;
-        int ch = (s->height + chroma_y_shift) >> chroma_y_shift;
-        s->vdsp.emulated_edge_mc(ebuf, ptr_y,
+    if ((mb_x * 16 + 16 > s->c.width || mb_y * 16 + 16 > s->c.height) &&
+        s->c.codec_id != AV_CODEC_ID_AMV) {
+        uint8_t *ebuf = s->c.sc.edge_emu_buffer + 38 * wrap_y;
+        int cw = (s->c.width  + chroma_x_shift) >> chroma_x_shift;
+        int ch = (s->c.height + chroma_y_shift) >> chroma_y_shift;
+        s->c.vdsp.emulated_edge_mc(ebuf, ptr_y,
                                  wrap_y, wrap_y,
                                  16, 16, mb_x * 16, mb_y * 16,
-                                 s->width, s->height);
+                                 s->c.width, s->c.height);
         ptr_y = ebuf;
-        s->vdsp.emulated_edge_mc(ebuf + 16 * wrap_y, ptr_cb,
+        s->c.vdsp.emulated_edge_mc(ebuf + 16 * wrap_y, ptr_cb,
                                  wrap_c, wrap_c,
                                  mb_block_width, mb_block_height,
                                  mb_x * mb_block_width, mb_y * mb_block_height,
                                  cw, ch);
         ptr_cb = ebuf + 16 * wrap_y;
-        s->vdsp.emulated_edge_mc(ebuf + 16 * wrap_y + 16, ptr_cr,
+        s->c.vdsp.emulated_edge_mc(ebuf + 16 * wrap_y + 16, ptr_cr,
                                  wrap_c, wrap_c,
                                  mb_block_width, mb_block_height,
                                  mb_x * mb_block_width, mb_y * mb_block_height,
@@ -2353,11 +2356,11 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         ptr_cr = ebuf + 16 * wrap_y + 16;
     }
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         if (INTERLACED_DCT(s)) {
             int progressive_score, interlaced_score;
 
-            s->interlaced_dct = 0;
+            s->c.interlaced_dct = 0;
             progressive_score = s->ildct_cmp[1](s, ptr_y, NULL, wrap_y, 8) +
                                 s->ildct_cmp[1](s, ptr_y + wrap_y * 8,
                                                 NULL, wrap_y, 8) - 400;
@@ -2368,7 +2371,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
                                    s->ildct_cmp[1](s, ptr_y + wrap_y,
                                                    NULL, wrap_y * 2, 8);
                 if (progressive_score > interlaced_score) {
-                    s->interlaced_dct = 1;
+                    s->c.interlaced_dct = 1;
 
                     dct_offset = wrap_y;
                     uv_dct_offset = wrap_c;
@@ -2380,27 +2383,27 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
             }
         }
 
-        s->pdsp.get_pixels(s->block[0], ptr_y,                  wrap_y);
-        s->pdsp.get_pixels(s->block[1], ptr_y + 8,              wrap_y);
-        s->pdsp.get_pixels(s->block[2], ptr_y + dct_offset,     wrap_y);
-        s->pdsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y);
+        s->pdsp.get_pixels(s->c.block[0], ptr_y,                  wrap_y);
+        s->pdsp.get_pixels(s->c.block[1], ptr_y + 8,              wrap_y);
+        s->pdsp.get_pixels(s->c.block[2], ptr_y + dct_offset,     wrap_y);
+        s->pdsp.get_pixels(s->c.block[3], ptr_y + dct_offset + 8, wrap_y);
 
-        if (s->avctx->flags & AV_CODEC_FLAG_GRAY) {
+        if (s->c.avctx->flags & AV_CODEC_FLAG_GRAY) {
             skip_dct[4] = 1;
             skip_dct[5] = 1;
         } else {
-            s->pdsp.get_pixels(s->block[4], ptr_cb, wrap_c);
-            s->pdsp.get_pixels(s->block[5], ptr_cr, wrap_c);
+            s->pdsp.get_pixels(s->c.block[4], ptr_cb, wrap_c);
+            s->pdsp.get_pixels(s->c.block[5], ptr_cr, wrap_c);
             if (chroma_format == CHROMA_422) {
-                s->pdsp.get_pixels(s->block[6], ptr_cb + uv_dct_offset, wrap_c);
-                s->pdsp.get_pixels(s->block[7], ptr_cr + uv_dct_offset, wrap_c);
+                s->pdsp.get_pixels(s->c.block[6], ptr_cb + uv_dct_offset, wrap_c);
+                s->pdsp.get_pixels(s->c.block[7], ptr_cr + uv_dct_offset, wrap_c);
             } else if (chroma_format == CHROMA_444) {
-                s->pdsp.get_pixels(s->block[ 6], ptr_cb + 8, wrap_c);
-                s->pdsp.get_pixels(s->block[ 7], ptr_cr + 8, wrap_c);
-                s->pdsp.get_pixels(s->block[ 8], ptr_cb + uv_dct_offset, wrap_c);
-                s->pdsp.get_pixels(s->block[ 9], ptr_cr + uv_dct_offset, wrap_c);
-                s->pdsp.get_pixels(s->block[10], ptr_cb + uv_dct_offset + 8, wrap_c);
-                s->pdsp.get_pixels(s->block[11], ptr_cr + uv_dct_offset + 8, wrap_c);
+                s->pdsp.get_pixels(s->c.block[ 6], ptr_cb + 8, wrap_c);
+                s->pdsp.get_pixels(s->c.block[ 7], ptr_cr + 8, wrap_c);
+                s->pdsp.get_pixels(s->c.block[ 8], ptr_cb + uv_dct_offset, wrap_c);
+                s->pdsp.get_pixels(s->c.block[ 9], ptr_cr + uv_dct_offset, wrap_c);
+                s->pdsp.get_pixels(s->c.block[10], ptr_cb + uv_dct_offset + 8, wrap_c);
+                s->pdsp.get_pixels(s->c.block[11], ptr_cr + uv_dct_offset + 8, wrap_c);
             }
         }
     } else {
@@ -2408,41 +2411,41 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         qpel_mc_func (*op_qpix)[16];
         uint8_t *dest_y, *dest_cb, *dest_cr;
 
-        dest_y  = s->dest[0];
-        dest_cb = s->dest[1];
-        dest_cr = s->dest[2];
+        dest_y  = s->c.dest[0];
+        dest_cb = s->c.dest[1];
+        dest_cr = s->c.dest[2];
 
-        if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) {
-            op_pix  = s->hdsp.put_pixels_tab;
-            op_qpix = s->qdsp.put_qpel_pixels_tab;
+        if ((!s->c.no_rounding) || s->c.pict_type == AV_PICTURE_TYPE_B) {
+            op_pix  = s->c.hdsp.put_pixels_tab;
+            op_qpix = s->c.qdsp.put_qpel_pixels_tab;
         } else {
-            op_pix  = s->hdsp.put_no_rnd_pixels_tab;
-            op_qpix = s->qdsp.put_no_rnd_qpel_pixels_tab;
+            op_pix  = s->c.hdsp.put_no_rnd_pixels_tab;
+            op_qpix = s->c.qdsp.put_no_rnd_qpel_pixels_tab;
         }
 
-        if (s->mv_dir & MV_DIR_FORWARD) {
-            ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 0,
-                          s->last_pic.data,
+        if (s->c.mv_dir & MV_DIR_FORWARD) {
+            ff_mpv_motion(&s->c, dest_y, dest_cb, dest_cr, 0,
+                          s->c.last_pic.data,
                           op_pix, op_qpix);
-            op_pix  = s->hdsp.avg_pixels_tab;
-            op_qpix = s->qdsp.avg_qpel_pixels_tab;
+            op_pix  = s->c.hdsp.avg_pixels_tab;
+            op_qpix = s->c.qdsp.avg_qpel_pixels_tab;
         }
-        if (s->mv_dir & MV_DIR_BACKWARD) {
-            ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 1,
-                          s->next_pic.data,
+        if (s->c.mv_dir & MV_DIR_BACKWARD) {
+            ff_mpv_motion(&s->c, dest_y, dest_cb, dest_cr, 1,
+                          s->c.next_pic.data,
                           op_pix, op_qpix);
         }
 
         if (INTERLACED_DCT(s)) {
             int progressive_score, interlaced_score;
 
-            s->interlaced_dct = 0;
+            s->c.interlaced_dct = 0;
             progressive_score = s->ildct_cmp[0](s, dest_y, ptr_y, wrap_y, 8) +
                                 s->ildct_cmp[0](s, dest_y + wrap_y * 8,
                                                 ptr_y + wrap_y * 8,
                                                 wrap_y, 8) - 400;
 
-            if (s->avctx->ildct_cmp == FF_CMP_VSSE)
+            if (s->c.avctx->ildct_cmp == FF_CMP_VSSE)
                 progressive_score -= 400;
 
             if (progressive_score > 0) {
@@ -2453,7 +2456,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
                                                    wrap_y * 2, 8);
 
                 if (progressive_score > interlaced_score) {
-                    s->interlaced_dct = 1;
+                    s->c.interlaced_dct = 1;
 
                     dct_offset = wrap_y;
                     uv_dct_offset = wrap_c;
@@ -2464,51 +2467,51 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
             }
         }
 
-        s->pdsp.diff_pixels(s->block[0], ptr_y, dest_y, wrap_y);
-        s->pdsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y);
-        s->pdsp.diff_pixels(s->block[2], ptr_y + dct_offset,
+        s->pdsp.diff_pixels(s->c.block[0], ptr_y, dest_y, wrap_y);
+        s->pdsp.diff_pixels(s->c.block[1], ptr_y + 8, dest_y + 8, wrap_y);
+        s->pdsp.diff_pixels(s->c.block[2], ptr_y + dct_offset,
                             dest_y + dct_offset, wrap_y);
-        s->pdsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8,
+        s->pdsp.diff_pixels(s->c.block[3], ptr_y + dct_offset + 8,
                             dest_y + dct_offset + 8, wrap_y);
 
-        if (s->avctx->flags & AV_CODEC_FLAG_GRAY) {
+        if (s->c.avctx->flags & AV_CODEC_FLAG_GRAY) {
             skip_dct[4] = 1;
             skip_dct[5] = 1;
         } else {
-            s->pdsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c);
-            s->pdsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
+            s->pdsp.diff_pixels(s->c.block[4], ptr_cb, dest_cb, wrap_c);
+            s->pdsp.diff_pixels(s->c.block[5], ptr_cr, dest_cr, wrap_c);
             if (!chroma_y_shift) { /* 422 */
-                s->pdsp.diff_pixels(s->block[6], ptr_cb + uv_dct_offset,
+                s->pdsp.diff_pixels(s->c.block[6], ptr_cb + uv_dct_offset,
                                     dest_cb + uv_dct_offset, wrap_c);
-                s->pdsp.diff_pixels(s->block[7], ptr_cr + uv_dct_offset,
+                s->pdsp.diff_pixels(s->c.block[7], ptr_cr + uv_dct_offset,
                                     dest_cr + uv_dct_offset, wrap_c);
             }
         }
         /* pre quantization */
-        if (s->mc_mb_var[s->mb_stride * mb_y + mb_x] < 2 * s->qscale * s->qscale) {
+        if (s->mc_mb_var[s->c.mb_stride * mb_y + mb_x] < 2 * s->c.qscale * s->c.qscale) {
             // FIXME optimize
-            if (s->sad_cmp[1](NULL, ptr_y, dest_y, wrap_y, 8) < 20 * s->qscale)
+            if (s->sad_cmp[1](NULL, ptr_y, dest_y, wrap_y, 8) < 20 * s->c.qscale)
                 skip_dct[0] = 1;
-            if (s->sad_cmp[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20 * s->qscale)
+            if (s->sad_cmp[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20 * s->c.qscale)
                 skip_dct[1] = 1;
             if (s->sad_cmp[1](NULL, ptr_y + dct_offset, dest_y + dct_offset,
-                              wrap_y, 8) < 20 * s->qscale)
+                              wrap_y, 8) < 20 * s->c.qscale)
                 skip_dct[2] = 1;
             if (s->sad_cmp[1](NULL, ptr_y + dct_offset + 8, dest_y + dct_offset + 8,
-                              wrap_y, 8) < 20 * s->qscale)
+                              wrap_y, 8) < 20 * s->c.qscale)
                 skip_dct[3] = 1;
-            if (s->sad_cmp[1](NULL, ptr_cb, dest_cb, wrap_c, 8) < 20 * s->qscale)
+            if (s->sad_cmp[1](NULL, ptr_cb, dest_cb, wrap_c, 8) < 20 * s->c.qscale)
                 skip_dct[4] = 1;
-            if (s->sad_cmp[1](NULL, ptr_cr, dest_cr, wrap_c, 8) < 20 * s->qscale)
+            if (s->sad_cmp[1](NULL, ptr_cr, dest_cr, wrap_c, 8) < 20 * s->c.qscale)
                 skip_dct[5] = 1;
             if (!chroma_y_shift) { /* 422 */
                 if (s->sad_cmp[1](NULL, ptr_cb + uv_dct_offset,
                                   dest_cb + uv_dct_offset,
-                                  wrap_c, 8) < 20 * s->qscale)
+                                  wrap_c, 8) < 20 * s->c.qscale)
                     skip_dct[6] = 1;
                 if (s->sad_cmp[1](NULL, ptr_cr + uv_dct_offset,
                                   dest_cr + uv_dct_offset,
-                                  wrap_c, 8) < 20 * s->qscale)
+                                  wrap_c, 8) < 20 * s->c.qscale)
                     skip_dct[7] = 1;
             }
         }
@@ -2535,102 +2538,102 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
                 get_visual_weight(weight[7], ptr_cr + uv_dct_offset,
                                   wrap_c);
         }
-        memcpy(orig[0], s->block[0], sizeof(int16_t) * 64 * mb_block_count);
+        memcpy(orig[0], s->c.block[0], sizeof(int16_t) * 64 * mb_block_count);
     }
 
     /* DCT & quantize */
-    av_assert2(s->out_format != FMT_MJPEG || s->qscale == 8);
+    av_assert2(s->c.out_format != FMT_MJPEG || s->c.qscale == 8);
     {
         for (i = 0; i < mb_block_count; i++) {
             if (!skip_dct[i]) {
                 int overflow;
-                s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow);
+                s->c.block_last_index[i] = s->dct_quantize(s, s->c.block[i], i, s->c.qscale, &overflow);
                 // FIXME we could decide to change to quantizer instead of
                 // clipping
                 // JS: I don't think that would be a good idea it could lower
                 //     quality instead of improve it. Just INTRADC clipping
                 //     deserves changes in quantizer
                 if (overflow)
-                    clip_coeffs(s, s->block[i], s->block_last_index[i]);
+                    clip_coeffs(s, s->c.block[i], s->c.block_last_index[i]);
             } else
-                s->block_last_index[i] = -1;
+                s->c.block_last_index[i] = -1;
         }
         if (s->quantizer_noise_shaping) {
             for (i = 0; i < mb_block_count; i++) {
                 if (!skip_dct[i]) {
-                    s->block_last_index[i] =
-                        dct_quantize_refine(s, s->block[i], weight[i],
-                                            orig[i], i, s->qscale);
+                    s->c.block_last_index[i] =
+                        dct_quantize_refine(s, s->c.block[i], weight[i],
+                                            orig[i], i, s->c.qscale);
                 }
             }
         }
 
-        if (s->luma_elim_threshold && !s->mb_intra)
+        if (s->luma_elim_threshold && !s->c.mb_intra)
             for (i = 0; i < 4; i++)
                 dct_single_coeff_elimination(s, i, s->luma_elim_threshold);
-        if (s->chroma_elim_threshold && !s->mb_intra)
+        if (s->chroma_elim_threshold && !s->c.mb_intra)
             for (i = 4; i < mb_block_count; i++)
                 dct_single_coeff_elimination(s, i, s->chroma_elim_threshold);
 
         if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) {
             for (i = 0; i < mb_block_count; i++) {
-                if (s->block_last_index[i] == -1)
+                if (s->c.block_last_index[i] == -1)
                     s->coded_score[i] = INT_MAX / 256;
             }
         }
     }
 
-    if ((s->avctx->flags & AV_CODEC_FLAG_GRAY) && s->mb_intra) {
-        s->block_last_index[4] =
-        s->block_last_index[5] = 0;
-        s->block[4][0] =
-        s->block[5][0] = (1024 + s->c_dc_scale / 2) / s->c_dc_scale;
+    if ((s->c.avctx->flags & AV_CODEC_FLAG_GRAY) && s->c.mb_intra) {
+        s->c.block_last_index[4] =
+        s->c.block_last_index[5] = 0;
+        s->c.block[4][0] =
+        s->c.block[5][0] = (1024 + s->c.c_dc_scale / 2) / s->c.c_dc_scale;
         if (!chroma_y_shift) { /* 422 / 444 */
             for (i=6; i<12; i++) {
-                s->block_last_index[i] = 0;
-                s->block[i][0] = s->block[4][0];
+                s->c.block_last_index[i] = 0;
+                s->c.block[i][0] = s->c.block[4][0];
             }
         }
     }
 
     // non c quantize code returns incorrect block_last_index FIXME
-    if (s->alternate_scan && s->dct_quantize != dct_quantize_c) {
+    if (s->c.alternate_scan && s->dct_quantize != dct_quantize_c) {
         for (i = 0; i < mb_block_count; i++) {
             int j;
-            if (s->block_last_index[i] > 0) {
+            if (s->c.block_last_index[i] > 0) {
                 for (j = 63; j > 0; j--) {
-                    if (s->block[i][s->intra_scantable.permutated[j]])
+                    if (s->c.block[i][s->c.intra_scantable.permutated[j]])
                         break;
                 }
-                s->block_last_index[i] = j;
+                s->c.block_last_index[i] = j;
             }
         }
     }
 
-    s->encode_mb(s, s->block, motion_x, motion_y);
+    s->encode_mb(s, s->c.block, motion_x, motion_y);
 }
 
-static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
+static void encode_mb(MPVEncContext *const s, int motion_x, int motion_y)
 {
-    if (s->chroma_format == CHROMA_420)
+    if (s->c.chroma_format == CHROMA_420)
         encode_mb_internal(s, motion_x, motion_y,  8, 8, 6, 1, 1, CHROMA_420);
-    else if (s->chroma_format == CHROMA_422)
+    else if (s->c.chroma_format == CHROMA_422)
         encode_mb_internal(s, motion_x, motion_y, 16, 8, 8, 1, 0, CHROMA_422);
     else
         encode_mb_internal(s, motion_x, motion_y, 16, 16, 12, 0, 0, CHROMA_444);
 }
 
-static inline void copy_context_before_encode(MpegEncContext *d,
-                                              const MpegEncContext *s)
+static inline void copy_context_before_encode(MPVEncContext *const d,
+                                              const MPVEncContext *const s)
 {
     int i;
 
-    memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
+    memcpy(d->c.last_mv, s->c.last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
 
     /* MPEG-1 */
-    d->mb_skip_run= s->mb_skip_run;
+    d->c.mb_skip_run = s->c.mb_skip_run;
     for(i=0; i<3; i++)
-        d->last_dc[i] = s->last_dc[i];
+        d->c.last_dc[i] = s->c.last_dc[i];
 
     /* statistics */
     d->mv_bits= s->mv_bits;
@@ -2640,25 +2643,25 @@ static inline void copy_context_before_encode(MpegEncContext *d,
     d->misc_bits= s->misc_bits;
     d->last_bits= 0;
 
-    d->mb_skipped= 0;
-    d->qscale= s->qscale;
+    d->c.mb_skipped = 0;
+    d->c.qscale = s->c.qscale;
     d->dquant= s->dquant;
 
     d->esc3_level_length= s->esc3_level_length;
 }
 
-static inline void copy_context_after_encode(MpegEncContext *d,
-                                             const MpegEncContext *s)
+static inline void copy_context_after_encode(MPVEncContext *const d,
+                                             const MPVEncContext *const s)
 {
     int i;
 
-    memcpy(d->mv, s->mv, 2*4*2*sizeof(int));
-    memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
+    memcpy(d->c.mv, s->c.mv, 2*4*2*sizeof(int));
+    memcpy(d->c.last_mv, s->c.last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
 
     /* MPEG-1 */
-    d->mb_skip_run= s->mb_skip_run;
+    d->c.mb_skip_run = s->c.mb_skip_run;
     for(i=0; i<3; i++)
-        d->last_dc[i] = s->last_dc[i];
+        d->c.last_dc[i] = s->c.last_dc[i];
 
     /* statistics */
     d->mv_bits= s->mv_bits;
@@ -2667,25 +2670,25 @@ static inline void copy_context_after_encode(MpegEncContext *d,
     d->i_count= s->i_count;
     d->misc_bits= s->misc_bits;
 
-    d->mb_intra= s->mb_intra;
-    d->mb_skipped= s->mb_skipped;
-    d->mv_type= s->mv_type;
-    d->mv_dir= s->mv_dir;
+    d->c.mb_intra   = s->c.mb_intra;
+    d->c.mb_skipped = s->c.mb_skipped;
+    d->c.mv_type    = s->c.mv_type;
+    d->c.mv_dir     = s->c.mv_dir;
     d->pb= s->pb;
-    if(s->data_partitioning){
+    if (s->c.data_partitioning) {
         d->pb2= s->pb2;
         d->tex_pb= s->tex_pb;
     }
-    d->block= s->block;
+    d->c.block = s->c.block;
     for(i=0; i<8; i++)
-        d->block_last_index[i]= s->block_last_index[i];
-    d->interlaced_dct= s->interlaced_dct;
-    d->qscale= s->qscale;
+        d->c.block_last_index[i]= s->c.block_last_index[i];
+    d->c.interlaced_dct = s->c.interlaced_dct;
+    d->c.qscale = s->c.qscale;
 
     d->esc3_level_length= s->esc3_level_length;
 }
 
-static void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncContext *best,
+static void encode_mb_hq(MPVEncContext *const s, MPVEncContext *const backup, MPVEncContext *const best,
                          PutBitContext pb[2], PutBitContext pb2[2], PutBitContext tex_pb[2],
                          int *dmin, int *next_block, int motion_x, int motion_y)
 {
@@ -2694,38 +2697,38 @@ static void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncConte
 
     copy_context_before_encode(s, backup);
 
-    s->block= s->blocks[*next_block];
-    s->pb= pb[*next_block];
-    if(s->data_partitioning){
+    s->c.block = s->c.blocks[*next_block];
+    s->pb      = pb[*next_block];
+    if (s->c.data_partitioning) {
         s->pb2   = pb2   [*next_block];
         s->tex_pb= tex_pb[*next_block];
     }
 
     if(*next_block){
-        memcpy(dest_backup, s->dest, sizeof(s->dest));
-        s->dest[0] = s->sc.rd_scratchpad;
-        s->dest[1] = s->sc.rd_scratchpad + 16*s->linesize;
-        s->dest[2] = s->sc.rd_scratchpad + 16*s->linesize + 8;
-        av_assert0(s->linesize >= 32); //FIXME
+        memcpy(dest_backup, s->c.dest, sizeof(s->c.dest));
+        s->c.dest[0] = s->c.sc.rd_scratchpad;
+        s->c.dest[1] = s->c.sc.rd_scratchpad + 16*s->c.linesize;
+        s->c.dest[2] = s->c.sc.rd_scratchpad + 16*s->c.linesize + 8;
+        av_assert0(s->c.linesize >= 32); //FIXME
     }
 
     encode_mb(s, motion_x, motion_y);
 
     score= put_bits_count(&s->pb);
-    if(s->data_partitioning){
+    if (s->c.data_partitioning) {
         score+= put_bits_count(&s->pb2);
         score+= put_bits_count(&s->tex_pb);
     }
 
-    if(s->avctx->mb_decision == FF_MB_DECISION_RD){
-        mpv_reconstruct_mb(s, s->block);
+    if(s->c.avctx->mb_decision == FF_MB_DECISION_RD){
+        mpv_reconstruct_mb(s, s->c.block);
 
-        score *= s->lambda2;
+        score *= s->c.lambda2;
         score += sse_mb(s) << FF_LAMBDA_SHIFT;
     }
 
     if(*next_block){
-        memcpy(s->dest, dest_backup, sizeof(s->dest));
+        memcpy(s->c.dest, dest_backup, sizeof(s->c.dest));
     }
 
     if(score<*dmin){
@@ -2736,7 +2739,8 @@ static void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncConte
     }
 }
 
-static int sse(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2, int w, int h, int stride){
+static int sse(const MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, int w, int h, int stride)
+{
     const uint32_t *sq = ff_square_tab + 256;
     int acc=0;
     int x,y;
@@ -2757,129 +2761,128 @@ static int sse(MpegEncContext *s, const uint8_t *src1, const uint8_t *src2, int
     return acc;
 }
 
-static int sse_mb(MpegEncContext *s){
+static int sse_mb(MPVEncContext *const s)
+{
     int w= 16;
     int h= 16;
-    int chroma_mb_w = w >> s->chroma_x_shift;
-    int chroma_mb_h = h >> s->chroma_y_shift;
+    int chroma_mb_w = w >> s->c.chroma_x_shift;
+    int chroma_mb_h = h >> s->c.chroma_y_shift;
 
-    if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
-    if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;
+    if (s->c.mb_x*16 + 16 > s->c.width ) w = s->c.width - s->c.mb_x*16;
+    if (s->c.mb_y*16 + 16 > s->c.height) h = s->c.height- s->c.mb_y*16;
 
     if(w==16 && h==16)
-        return s->n_sse_cmp[0](s, s->new_pic->data[0] + s->mb_x * 16 + s->mb_y * s->linesize * 16,
-                               s->dest[0], s->linesize, 16) +
-               s->n_sse_cmp[1](s, s->new_pic->data[1] + s->mb_x * chroma_mb_w + s->mb_y * s->uvlinesize * chroma_mb_h,
-                               s->dest[1], s->uvlinesize, chroma_mb_h) +
-               s->n_sse_cmp[1](s, s->new_pic->data[2] + s->mb_x * chroma_mb_w + s->mb_y * s->uvlinesize * chroma_mb_h,
-                               s->dest[2], s->uvlinesize, chroma_mb_h);
+        return s->n_sse_cmp[0](s, s->new_pic->data[0] + s->c.mb_x * 16 + s->c.mb_y * s->c.linesize * 16,
+                               s->c.dest[0], s->c.linesize, 16) +
+               s->n_sse_cmp[1](s, s->new_pic->data[1] + s->c.mb_x * chroma_mb_w + s->c.mb_y * s->c.uvlinesize * chroma_mb_h,
+                               s->c.dest[1], s->c.uvlinesize, chroma_mb_h) +
+               s->n_sse_cmp[1](s, s->new_pic->data[2] + s->c.mb_x * chroma_mb_w + s->c.mb_y * s->c.uvlinesize * chroma_mb_h,
+                               s->c.dest[2], s->c.uvlinesize, chroma_mb_h);
     else
-        return  sse(s, s->new_pic->data[0] + s->mb_x * 16 + s->mb_y * s->linesize * 16,
-                    s->dest[0], w, h, s->linesize) +
-                sse(s, s->new_pic->data[1] + s->mb_x * chroma_mb_w + s->mb_y * s->uvlinesize * chroma_mb_h,
-                    s->dest[1], w >> s->chroma_x_shift, h >> s->chroma_y_shift, s->uvlinesize) +
-                sse(s, s->new_pic->data[2] + s->mb_x * chroma_mb_w + s->mb_y * s->uvlinesize * chroma_mb_h,
-                    s->dest[2], w >> s->chroma_x_shift, h >> s->chroma_y_shift, s->uvlinesize);
+        return  sse(s, s->new_pic->data[0] + s->c.mb_x * 16 + s->c.mb_y * s->c.linesize * 16,
+                    s->c.dest[0], w, h, s->c.linesize) +
+                sse(s, s->new_pic->data[1] + s->c.mb_x * chroma_mb_w + s->c.mb_y * s->c.uvlinesize * chroma_mb_h,
+                    s->c.dest[1], w >> s->c.chroma_x_shift, h >> s->c.chroma_y_shift, s->c.uvlinesize) +
+                sse(s, s->new_pic->data[2] + s->c.mb_x * chroma_mb_w + s->c.mb_y * s->c.uvlinesize * chroma_mb_h,
+                    s->c.dest[2], w >> s->c.chroma_x_shift, h >> s->c.chroma_y_shift, s->c.uvlinesize);
 }
 
 static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){
-    MpegEncContext *s= *(void**)arg;
+    MPVEncContext *const s = *(void**)arg;
 
 
-    s->me.pre_pass=1;
-    s->me.dia_size= s->avctx->pre_dia_size;
-    s->first_slice_line=1;
-    for(s->mb_y= s->end_mb_y-1; s->mb_y >= s->start_mb_y; s->mb_y--) {
-        for(s->mb_x=s->mb_width-1; s->mb_x >=0 ;s->mb_x--) {
-            ff_pre_estimate_p_frame_motion(s, s->mb_x, s->mb_y);
-        }
-        s->first_slice_line=0;
+    s->c.me.pre_pass = 1;
+    s->c.me.dia_size = s->c.avctx->pre_dia_size;
+    s->c.first_slice_line = 1;
+    for (s->c.mb_y = s->c.end_mb_y - 1; s->c.mb_y >= s->c.start_mb_y; s->c.mb_y--) {
+        for (s->c.mb_x = s->c.mb_width - 1; s->c.mb_x >=0 ; s->c.mb_x--)
+            ff_pre_estimate_p_frame_motion(s, s->c.mb_x, s->c.mb_y);
+        s->c.first_slice_line = 0;
     }
 
-    s->me.pre_pass=0;
+    s->c.me.pre_pass = 0;
 
     return 0;
 }
 
 static int estimate_motion_thread(AVCodecContext *c, void *arg){
-    MpegEncContext *s= *(void**)arg;
-
-    s->me.dia_size= s->avctx->dia_size;
-    s->first_slice_line=1;
-    for(s->mb_y= s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
-        s->mb_x=0; //for block init below
-        ff_init_block_index(s);
-        for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) {
-            s->block_index[0]+=2;
-            s->block_index[1]+=2;
-            s->block_index[2]+=2;
-            s->block_index[3]+=2;
+    MPVEncContext *const s = *(void**)arg;
+
+    s->c.me.dia_size= s->c.avctx->dia_size;
+    s->c.first_slice_line=1;
+    for (s->c.mb_y = s->c.start_mb_y; s->c.mb_y < s->c.end_mb_y; s->c.mb_y++) {
+        s->c.mb_x=0; //for block init below
+        ff_init_block_index(&s->c);
+        for (s->c.mb_x = 0; s->c.mb_x < s->c.mb_width; s->c.mb_x++) {
+            s->c.block_index[0] += 2;
+            s->c.block_index[1] += 2;
+            s->c.block_index[2] += 2;
+            s->c.block_index[3] += 2;
 
             /* compute motion vector & mb_type and store in context */
-            if(s->pict_type==AV_PICTURE_TYPE_B)
-                ff_estimate_b_frame_motion(s, s->mb_x, s->mb_y);
+            if(s->c.pict_type==AV_PICTURE_TYPE_B)
+                ff_estimate_b_frame_motion(s, s->c.mb_x, s->c.mb_y);
             else
-                ff_estimate_p_frame_motion(s, s->mb_x, s->mb_y);
+                ff_estimate_p_frame_motion(s, s->c.mb_x, s->c.mb_y);
         }
-        s->first_slice_line=0;
+        s->c.first_slice_line = 0;
     }
     return 0;
 }
 
 static int mb_var_thread(AVCodecContext *c, void *arg){
-    MpegEncContext *s= *(void**)arg;
-    int mb_x, mb_y;
+    MPVEncContext *const s = *(void**)arg;
 
-    for(mb_y=s->start_mb_y; mb_y < s->end_mb_y; mb_y++) {
-        for(mb_x=0; mb_x < s->mb_width; mb_x++) {
+    for (int mb_y = s->c.start_mb_y; mb_y < s->c.end_mb_y; mb_y++) {
+        for (int mb_x = 0; mb_x < s->c.mb_width; mb_x++) {
             int xx = mb_x * 16;
             int yy = mb_y * 16;
-            const uint8_t *pix = s->new_pic->data[0] + (yy * s->linesize) + xx;
+            const uint8_t *pix = s->new_pic->data[0] + (yy * s->c.linesize) + xx;
             int varc;
-            int sum = s->mpvencdsp.pix_sum(pix, s->linesize);
+            int sum = s->mpvencdsp.pix_sum(pix, s->c.linesize);
 
-            varc = (s->mpvencdsp.pix_norm1(pix, s->linesize) -
+            varc = (s->mpvencdsp.pix_norm1(pix, s->c.linesize) -
                     (((unsigned) sum * sum) >> 8) + 500 + 128) >> 8;
 
-            s->mb_var [s->mb_stride * mb_y + mb_x] = varc;
-            s->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
-            s->me.mb_var_sum_temp    += varc;
+            s->mb_var [s->c.mb_stride * mb_y + mb_x] = varc;
+            s->mb_mean[s->c.mb_stride * mb_y + mb_x] = (sum+128)>>8;
+            s->c.me.mb_var_sum_temp    += varc;
         }
     }
     return 0;
 }
 
-static void write_slice_end(MpegEncContext *s){
-    if(CONFIG_MPEG4_ENCODER && s->codec_id==AV_CODEC_ID_MPEG4){
-        if(s->partitioned_frame){
+static void write_slice_end(MPVEncContext *const s)
+{
+    if(CONFIG_MPEG4_ENCODER && s->c.codec_id == AV_CODEC_ID_MPEG4) {
+        if (s->c.partitioned_frame)
             ff_mpeg4_merge_partitions(s);
-        }
 
         ff_mpeg4_stuffing(&s->pb);
     } else if ((CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER) &&
-               s->out_format == FMT_MJPEG) {
+               s->c.out_format == FMT_MJPEG) {
         ff_mjpeg_encode_stuffing(s);
-    } else if (CONFIG_SPEEDHQ_ENCODER && s->out_format == FMT_SPEEDHQ) {
+    } else if (CONFIG_SPEEDHQ_ENCODER && s->c.out_format == FMT_SPEEDHQ) {
         ff_speedhq_end_slice(s);
     }
 
     flush_put_bits(&s->pb);
 
-    if ((s->avctx->flags & AV_CODEC_FLAG_PASS1) && !s->partitioned_frame)
+    if ((s->c.avctx->flags & AV_CODEC_FLAG_PASS1) && !s->c.partitioned_frame)
         s->misc_bits+= get_bits_diff(s);
 }
 
-static void write_mb_info(MpegEncContext *s)
+static void write_mb_info(MPVEncContext *const s)
 {
     uint8_t *ptr = s->mb_info_ptr + s->mb_info_size - 12;
     int offset = put_bits_count(&s->pb);
-    int mba  = s->mb_x + s->mb_width * (s->mb_y % s->gob_index);
-    int gobn = s->mb_y / s->gob_index;
+    int mba  = s->c.mb_x + s->c.mb_width * (s->c.mb_y % s->c.gob_index);
+    int gobn = s->c.mb_y / s->c.gob_index;
     int pred_x, pred_y;
     if (CONFIG_H263_ENCODER)
-        ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+        ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
     bytestream_put_le32(&ptr, offset);
-    bytestream_put_byte(&ptr, s->qscale);
+    bytestream_put_byte(&ptr, s->c.qscale);
     bytestream_put_byte(&ptr, gobn);
     bytestream_put_le16(&ptr, mba);
     bytestream_put_byte(&ptr, pred_x); /* hmv1 */
@@ -2889,7 +2892,7 @@ static void write_mb_info(MpegEncContext *s)
     bytestream_put_byte(&ptr, 0); /* vmv2 */
 }
 
-static void update_mb_info(MpegEncContext *s, int startcode)
+static void update_mb_info(MPVEncContext *const s, int startcode)
 {
     if (!s->mb_info)
         return;
@@ -2912,32 +2915,32 @@ static void update_mb_info(MpegEncContext *s, int startcode)
     write_mb_info(s);
 }
 
-int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase)
+int ff_mpv_reallocate_putbitbuffer(MPVEncContext *const s, size_t threshold, size_t size_increase)
 {
     if (put_bytes_left(&s->pb, 0) < threshold
-        && s->slice_context_count == 1
-        && s->pb.buf == s->avctx->internal->byte_buffer) {
+        && s->c.slice_context_count == 1
+        && s->pb.buf == s->c.avctx->internal->byte_buffer) {
         int lastgob_pos = s->ptr_lastgob - s->pb.buf;
 
         uint8_t *new_buffer = NULL;
         int new_buffer_size = 0;
 
-        if ((s->avctx->internal->byte_buffer_size + size_increase) >= INT_MAX/8) {
-            av_log(s->avctx, AV_LOG_ERROR, "Cannot reallocate putbit buffer\n");
+        if ((s->c.avctx->internal->byte_buffer_size + size_increase) >= INT_MAX/8) {
+            av_log(s->c.avctx, AV_LOG_ERROR, "Cannot reallocate putbit buffer\n");
             return AVERROR(ENOMEM);
         }
 
         emms_c();
 
         av_fast_padded_malloc(&new_buffer, &new_buffer_size,
-                              s->avctx->internal->byte_buffer_size + size_increase);
+                              s->c.avctx->internal->byte_buffer_size + size_increase);
         if (!new_buffer)
             return AVERROR(ENOMEM);
 
-        memcpy(new_buffer, s->avctx->internal->byte_buffer, s->avctx->internal->byte_buffer_size);
-        av_free(s->avctx->internal->byte_buffer);
-        s->avctx->internal->byte_buffer      = new_buffer;
-        s->avctx->internal->byte_buffer_size = new_buffer_size;
+        memcpy(new_buffer, s->c.avctx->internal->byte_buffer, s->c.avctx->internal->byte_buffer_size);
+        av_free(s->c.avctx->internal->byte_buffer);
+        s->c.avctx->internal->byte_buffer      = new_buffer;
+        s->c.avctx->internal->byte_buffer_size = new_buffer_size;
         rebase_put_bits(&s->pb, new_buffer, new_buffer_size);
         s->ptr_lastgob   = s->pb.buf + lastgob_pos;
     }
@@ -2947,11 +2950,10 @@ int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t s
 }
 
 static int encode_thread(AVCodecContext *c, void *arg){
-    MpegEncContext *s= *(void**)arg;
-    int mb_x, mb_y, mb_y_order;
-    int chr_h= 16>>s->chroma_y_shift;
+    MPVEncContext *const s = *(void**)arg;
+    int chr_h = 16 >> s->c.chroma_y_shift;
     int i, j;
-    MpegEncContext best_s = { 0 }, backup_s;
+    MPVEncContext best_s = { 0 }, backup_s;
     uint8_t bit_buf[2][MAX_MB_BYTES];
     uint8_t bit_buf2[2][MAX_MB_BYTES];
     uint8_t bit_buf_tex[2][MAX_MB_BYTES];
@@ -2973,82 +2975,83 @@ static int encode_thread(AVCodecContext *c, void *arg){
     for(i=0; i<3; i++){
         /* init last dc values */
         /* note: quant matrix value (8) is implied here */
-        s->last_dc[i] = 128 << s->intra_dc_precision;
+        s->c.last_dc[i] = 128 << s->c.intra_dc_precision;
 
         s->encoding_error[i] = 0;
     }
-    if(s->codec_id==AV_CODEC_ID_AMV){
-        s->last_dc[0] = 128*8/13;
-        s->last_dc[1] = 128*8/14;
-        s->last_dc[2] = 128*8/14;
+    if (s->c.codec_id == AV_CODEC_ID_AMV) {
+        s->c.last_dc[0] = 128 * 8 / 13;
+        s->c.last_dc[1] = 128 * 8 / 14;
+        s->c.last_dc[2] = 128 * 8 / 14;
     }
-    s->mb_skip_run = 0;
-    memset(s->last_mv, 0, sizeof(s->last_mv));
+    s->c.mb_skip_run = 0;
+    memset(s->c.last_mv, 0, sizeof(s->c.last_mv));
 
     s->last_mv_dir = 0;
 
-    switch(s->codec_id){
+    switch(s->c.codec_id){
     case AV_CODEC_ID_H263:
     case AV_CODEC_ID_H263P:
     case AV_CODEC_ID_FLV1:
         if (CONFIG_H263_ENCODER)
-            s->gob_index = H263_GOB_HEIGHT(s->height);
+            s->c.gob_index = H263_GOB_HEIGHT(s->c.height);
         break;
     case AV_CODEC_ID_MPEG4:
-        if(CONFIG_MPEG4_ENCODER && s->partitioned_frame)
+        if(CONFIG_MPEG4_ENCODER && s->c.partitioned_frame)
             ff_mpeg4_init_partitions(s);
         break;
     }
 
-    s->resync_mb_x=0;
-    s->resync_mb_y=0;
-    s->first_slice_line = 1;
+    s->c.resync_mb_x = 0;
+    s->c.resync_mb_y = 0;
+    s->c.first_slice_line = 1;
     s->ptr_lastgob = s->pb.buf;
-    for (mb_y_order = s->start_mb_y; mb_y_order < s->end_mb_y; mb_y_order++) {
-        if (CONFIG_SPEEDHQ_ENCODER && s->codec_id == AV_CODEC_ID_SPEEDHQ) {
+    for (int mb_y_order = s->c.start_mb_y; mb_y_order < s->c.end_mb_y; mb_y_order++) {
+        int mb_y;
+        if (CONFIG_SPEEDHQ_ENCODER && s->c.codec_id == AV_CODEC_ID_SPEEDHQ) {
             int first_in_slice;
-            mb_y = ff_speedhq_mb_y_order_to_mb(mb_y_order, s->mb_height, &first_in_slice);
-            if (first_in_slice && mb_y_order != s->start_mb_y)
+            mb_y = ff_speedhq_mb_y_order_to_mb(mb_y_order, s->c.mb_height, &first_in_slice);
+            if (first_in_slice && mb_y_order != s->c.start_mb_y)
                 ff_speedhq_end_slice(s);
-            s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 1024 << s->intra_dc_precision;
+            s->c.last_dc[0] = s->c.last_dc[1] = s->c.last_dc[2] = 1024 << s->c.intra_dc_precision;
         } else {
             mb_y = mb_y_order;
         }
-        s->mb_x=0;
-        s->mb_y= mb_y;
+        s->c.mb_x = 0;
+        s->c.mb_y = mb_y;
 
-        ff_set_qscale(s, s->qscale);
-        ff_init_block_index(s);
+        ff_set_qscale(&s->c, s->c.qscale);
+        ff_init_block_index(&s->c);
 
-        for(mb_x=0; mb_x < s->mb_width; mb_x++) {
-            int xy= mb_y*s->mb_stride + mb_x; // removed const, H261 needs to adjust this
+        for (int mb_x = 0; mb_x < s->c.mb_width; mb_x++) {
+            int xy = mb_y*s->c.mb_stride + mb_x; // removed const, H261 needs to adjust this
             int mb_type= s->mb_type[xy];
 //            int d;
             int dmin= INT_MAX;
             int dir;
-            int size_increase =  s->avctx->internal->byte_buffer_size/4
-                               + s->mb_width*MAX_MB_BYTES;
+            int size_increase =  s->c.avctx->internal->byte_buffer_size/4
+                               + s->c.mb_width*MAX_MB_BYTES;
 
             ff_mpv_reallocate_putbitbuffer(s, MAX_MB_BYTES, size_increase);
             if (put_bytes_left(&s->pb, 0) < MAX_MB_BYTES){
-                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                av_log(s->c.avctx, AV_LOG_ERROR, "encoded frame too large\n");
                 return -1;
             }
-            if(s->data_partitioning){
+            if (s->c.data_partitioning) {
                 if (put_bytes_left(&s->pb2,    0) < MAX_MB_BYTES ||
                     put_bytes_left(&s->tex_pb, 0) < MAX_MB_BYTES) {
-                    av_log(s->avctx, AV_LOG_ERROR, "encoded partitioned frame too large\n");
+                    av_log(s->c.avctx, AV_LOG_ERROR, "encoded partitioned frame too large\n");
                     return -1;
                 }
             }
 
-            s->mb_x = mb_x;
-            s->mb_y = mb_y;  // moved into loop, can get changed by H.261
-            ff_update_block_index(s, 8, 0, s->chroma_x_shift);
+            s->c.mb_x = mb_x;
+            s->c.mb_y = mb_y;  // moved into loop, can get changed by H.261
+            ff_update_block_index(&s->c, 8, 0, s->c.chroma_x_shift);
 
-            if(CONFIG_H261_ENCODER && s->codec_id == AV_CODEC_ID_H261){
+            if(CONFIG_H261_ENCODER && s->c.codec_id == AV_CODEC_ID_H261){
                 ff_h261_reorder_mb_index(s);
-                xy= s->mb_y*s->mb_stride + s->mb_x;
+                xy = s->c.mb_y*s->c.mb_stride + s->c.mb_x;
                 mb_type= s->mb_type[xy];
             }
 
@@ -3063,40 +3066,39 @@ static int encode_thread(AVCodecContext *c, void *arg){
                                current_packet_size >= s->rtp_payload_size &&
                                mb_y + mb_x > 0;
 
-                if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1;
+                if (s->c.start_mb_y == mb_y && mb_y > 0 && mb_x == 0) is_gob_start = 1;
 
-                switch(s->codec_id){
+                switch(s->c.codec_id){
                 case AV_CODEC_ID_H263:
                 case AV_CODEC_ID_H263P:
-                    if(!s->h263_slice_structured)
-                        if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0;
+                    if (!s->c.h263_slice_structured)
+                        if (s->c.mb_x || s->c.mb_y % s->c.gob_index) is_gob_start = 0;
                     break;
                 case AV_CODEC_ID_MPEG2VIDEO:
-                    if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
+                    if (s->c.mb_x == 0 && s->c.mb_y != 0) is_gob_start = 1;
                 case AV_CODEC_ID_MPEG1VIDEO:
-                    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->mb_y >= 175 ||
-                        s->mb_skip_run)
+                    if (s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO && s->c.mb_y >= 175 ||
+                        s->c.mb_skip_run)
                         is_gob_start=0;
                     break;
                 case AV_CODEC_ID_MJPEG:
-                    if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
+                    if (s->c.mb_x == 0 && s->c.mb_y != 0) is_gob_start = 1;
                     break;
                 }
 
                 if(is_gob_start){
-                    if(s->start_mb_y != mb_y || mb_x!=0){
+                    if (s->c.start_mb_y != mb_y || mb_x != 0) {
                         write_slice_end(s);
 
-                        if(CONFIG_MPEG4_ENCODER && s->codec_id==AV_CODEC_ID_MPEG4 && s->partitioned_frame){
+                        if (CONFIG_MPEG4_ENCODER && s->c.codec_id==AV_CODEC_ID_MPEG4 && s->c.partitioned_frame)
                             ff_mpeg4_init_partitions(s);
-                        }
                     }
 
                     av_assert2((put_bits_count(&s->pb)&7) == 0);
                     current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob;
 
-                    if (s->error_rate && s->resync_mb_x + s->resync_mb_y > 0) {
-                        int r = put_bytes_count(&s->pb, 0) + s->picture_number + 16 + s->mb_x + s->mb_y;
+                    if (s->error_rate && s->c.resync_mb_x + s->c.resync_mb_y > 0) {
+                        int r = put_bytes_count(&s->pb, 0) + s->c.picture_number + 16 + s->c.mb_x + s->c.mb_y;
                         int d = 100 / s->error_rate;
                         if(r % d == 0){
                             current_packet_size=0;
@@ -3105,18 +3107,18 @@ static int encode_thread(AVCodecContext *c, void *arg){
                         }
                     }
 
-                    switch(s->codec_id){
+                    switch (s->c.codec_id) {
                     case AV_CODEC_ID_MPEG4:
                         if (CONFIG_MPEG4_ENCODER) {
                             ff_mpeg4_encode_video_packet_header(s);
-                            ff_mpeg4_clean_buffers(s);
+                            ff_mpeg4_clean_buffers(&s->c);
                         }
                     break;
                     case AV_CODEC_ID_MPEG1VIDEO:
                     case AV_CODEC_ID_MPEG2VIDEO:
                         if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) {
                             ff_mpeg1_encode_slice_header(s);
-                            ff_mpeg1_clean_buffers(s);
+                            ff_mpeg1_clean_buffers(&s->c);
                         }
                     break;
                     case AV_CODEC_ID_H263:
@@ -3128,25 +3130,25 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     break;
                     }
 
-                    if (s->avctx->flags & AV_CODEC_FLAG_PASS1) {
+                    if (s->c.avctx->flags & AV_CODEC_FLAG_PASS1) {
                         int bits= put_bits_count(&s->pb);
                         s->misc_bits+= bits - s->last_bits;
                         s->last_bits= bits;
                     }
 
-                    s->ptr_lastgob += current_packet_size;
-                    s->first_slice_line=1;
-                    s->resync_mb_x=mb_x;
-                    s->resync_mb_y=mb_y;
+                    s->ptr_lastgob       += current_packet_size;
+                    s->c.first_slice_line = 1;
+                    s->c.resync_mb_x      = mb_x;
+                    s->c.resync_mb_y      = mb_y;
                 }
             }
 
-            if(  (s->resync_mb_x   == s->mb_x)
-               && s->resync_mb_y+1 == s->mb_y){
-                s->first_slice_line=0;
+            if(  (s->c.resync_mb_x   == s->c.mb_x)
+               && s->c.resync_mb_y+1 == s->c.mb_y){
+                s->c.first_slice_line = 0;
             }
 
-            s->mb_skipped=0;
+            s->c.mb_skipped = 0;
             s->dquant=0; //only for QP_RD
 
             update_mb_info(s, 0);
@@ -3157,173 +3159,173 @@ static int encode_thread(AVCodecContext *c, void *arg){
 
                 copy_context_before_encode(&backup_s, s);
                 backup_s.pb= s->pb;
-                best_s.data_partitioning= s->data_partitioning;
-                best_s.partitioned_frame= s->partitioned_frame;
-                if(s->data_partitioning){
+                best_s.c.data_partitioning = s->c.data_partitioning;
+                best_s.c.partitioned_frame = s->c.partitioned_frame;
+                if (s->c.data_partitioning) {
                     backup_s.pb2= s->pb2;
                     backup_s.tex_pb= s->tex_pb;
                 }
 
                 if(mb_type&CANDIDATE_MB_TYPE_INTER){
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_16X16;
-                    s->mb_intra= 0;
-                    s->mv[0][0][0] = s->p_mv_table[xy][0];
-                    s->mv[0][0][1] = s->p_mv_table[xy][1];
+                    s->c.mv_dir      = MV_DIR_FORWARD;
+                    s->c.mv_type     = MV_TYPE_16X16;
+                    s->c.mb_intra    = 0;
+                    s->c.mv[0][0][0] = s->p_mv_table[xy][0];
+                    s->c.mv[0][0][1] = s->p_mv_table[xy][1];
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
-                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
+                                 &dmin, &next_block, s->c.mv[0][0][0], s->c.mv[0][0][1]);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_INTER_I){
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir   = MV_DIR_FORWARD;
+                    s->c.mv_type  = MV_TYPE_FIELD;
+                    s->c.mb_intra = 0;
                     for(i=0; i<2; i++){
-                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];
-                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];
-                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];
+                        j = s->c.field_select[0][i] = s->p_field_select_table[i][xy];
+                        s->c.mv[0][i][0] = s->c.p_field_mv_table[i][j][xy][0];
+                        s->c.mv[0][i][1] = s->c.p_field_mv_table[i][j][xy][1];
                     }
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_16X16;
-                    s->mb_intra= 0;
-                    s->mv[0][0][0] = 0;
-                    s->mv[0][0][1] = 0;
+                    s->c.mv_dir      = MV_DIR_FORWARD;
+                    s->c.mv_type     = MV_TYPE_16X16;
+                    s->c.mb_intra    = 0;
+                    s->c.mv[0][0][0] = 0;
+                    s->c.mv[0][0][1] = 0;
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
-                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
+                                 &dmin, &next_block, s->c.mv[0][0][0], s->c.mv[0][0][1]);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_INTER4V){
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_8X8;
-                    s->mb_intra= 0;
+                    s->c.mv_dir   = MV_DIR_FORWARD;
+                    s->c.mv_type  = MV_TYPE_8X8;
+                    s->c.mb_intra = 0;
                     for(i=0; i<4; i++){
-                        s->mv[0][i][0] = s->cur_pic.motion_val[0][s->block_index[i]][0];
-                        s->mv[0][i][1] = s->cur_pic.motion_val[0][s->block_index[i]][1];
+                        s->c.mv[0][i][0] = s->c.cur_pic.motion_val[0][s->c.block_index[i]][0];
+                        s->c.mv[0][i][1] = s->c.cur_pic.motion_val[0][s->c.block_index[i]][1];
                     }
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_FORWARD){
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_16X16;
-                    s->mb_intra= 0;
-                    s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
-                    s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
+                    s->c.mv_dir      = MV_DIR_FORWARD;
+                    s->c.mv_type     = MV_TYPE_16X16;
+                    s->c.mb_intra    = 0;
+                    s->c.mv[0][0][0] = s->b_forw_mv_table[xy][0];
+                    s->c.mv[0][0][1] = s->b_forw_mv_table[xy][1];
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
-                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
+                                 &dmin, &next_block, s->c.mv[0][0][0], s->c.mv[0][0][1]);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){
-                    s->mv_dir = MV_DIR_BACKWARD;
-                    s->mv_type = MV_TYPE_16X16;
-                    s->mb_intra= 0;
-                    s->mv[1][0][0] = s->b_back_mv_table[xy][0];
-                    s->mv[1][0][1] = s->b_back_mv_table[xy][1];
+                    s->c.mv_dir      = MV_DIR_BACKWARD;
+                    s->c.mv_type     = MV_TYPE_16X16;
+                    s->c.mb_intra    = 0;
+                    s->c.mv[1][0][0] = s->b_back_mv_table[xy][0];
+                    s->c.mv[1][0][1] = s->b_back_mv_table[xy][1];
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
-                                 &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]);
+                                 &dmin, &next_block, s->c.mv[1][0][0], s->c.mv[1][0][1]);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_BIDIR){
-                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-                    s->mv_type = MV_TYPE_16X16;
-                    s->mb_intra= 0;
-                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
-                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
-                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
-                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
+                    s->c.mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
+                    s->c.mv_type = MV_TYPE_16X16;
+                    s->c.mb_intra= 0;
+                    s->c.mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
+                    s->c.mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
+                    s->c.mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
+                    s->c.mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_FORWARD;
+                    s->c.mv_type = MV_TYPE_FIELD;
+                    s->c.mb_intra= 0;
                     for(i=0; i<2; i++){
-                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];
-                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
-                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
+                        j = s->c.field_select[0][i] = s->b_field_select_table[0][i][xy];
+                        s->c.mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
+                        s->c.mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
                     }
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){
-                    s->mv_dir = MV_DIR_BACKWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_BACKWARD;
+                    s->c.mv_type = MV_TYPE_FIELD;
+                    s->c.mb_intra= 0;
                     for(i=0; i<2; i++){
-                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];
-                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
-                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
+                        j = s->c.field_select[1][i] = s->b_field_select_table[1][i][xy];
+                        s->c.mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
+                        s->c.mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
                     }
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){
-                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir   = MV_DIR_FORWARD | MV_DIR_BACKWARD;
+                    s->c.mv_type  = MV_TYPE_FIELD;
+                    s->c.mb_intra = 0;
                     for(dir=0; dir<2; dir++){
                         for(i=0; i<2; i++){
-                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];
-                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
-                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
+                            j = s->c.field_select[dir][i] = s->b_field_select_table[dir][i][xy];
+                            s->c.mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
+                            s->c.mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
                         }
                     }
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&CANDIDATE_MB_TYPE_INTRA){
-                    s->mv_dir = 0;
-                    s->mv_type = MV_TYPE_16X16;
-                    s->mb_intra= 1;
-                    s->mv[0][0][0] = 0;
-                    s->mv[0][0][1] = 0;
+                    s->c.mv_dir      = 0;
+                    s->c.mv_type     = MV_TYPE_16X16;
+                    s->c.mb_intra    = 1;
+                    s->c.mv[0][0][0] = 0;
+                    s->c.mv[0][0][1] = 0;
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
-                    s->mbintra_table[xy] = 1;
+                    s->c.mbintra_table[xy] = 1;
                 }
 
                 if ((s->mpv_flags & FF_MPV_FLAG_QP_RD) && dmin < INT_MAX) {
-                    if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD
-                        const int last_qp= backup_s.qscale;
+                    if (best_s.c.mv_type == MV_TYPE_16X16) { //FIXME move 4mv after QPRD
+                        const int last_qp = backup_s.c.qscale;
                         int qpi, qp, dc[6];
                         int16_t ac[6][16];
-                        const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;
+                        const int mvdir = (best_s.c.mv_dir & MV_DIR_BACKWARD) ? 1 : 0;
                         static const int dquant_tab[4]={-1,1,-2,2};
-                        int storecoefs = s->mb_intra && s->dc_val[0];
+                        int storecoefs = s->c.mb_intra && s->c.dc_val[0];
 
                         av_assert2(backup_s.dquant == 0);
 
                         //FIXME intra
-                        s->mv_dir= best_s.mv_dir;
-                        s->mv_type = MV_TYPE_16X16;
-                        s->mb_intra= best_s.mb_intra;
-                        s->mv[0][0][0] = best_s.mv[0][0][0];
-                        s->mv[0][0][1] = best_s.mv[0][0][1];
-                        s->mv[1][0][0] = best_s.mv[1][0][0];
-                        s->mv[1][0][1] = best_s.mv[1][0][1];
-
-                        qpi = s->pict_type == AV_PICTURE_TYPE_B ? 2 : 0;
+                        s->c.mv_dir   = best_s.c.mv_dir;
+                        s->c.mv_type  = MV_TYPE_16X16;
+                        s->c.mb_intra = best_s.c.mb_intra;
+                        s->c.mv[0][0][0] = best_s.c.mv[0][0][0];
+                        s->c.mv[0][0][1] = best_s.c.mv[0][0][1];
+                        s->c.mv[1][0][0] = best_s.c.mv[1][0][0];
+                        s->c.mv[1][0][1] = best_s.c.mv[1][0][1];
+
+                        qpi = s->c.pict_type == AV_PICTURE_TYPE_B ? 2 : 0;
                         for(; qpi<4; qpi++){
                             int dquant= dquant_tab[qpi];
                             qp= last_qp + dquant;
-                            if(qp < s->avctx->qmin || qp > s->avctx->qmax)
+                            if (qp < s->c.avctx->qmin || qp > s->c.avctx->qmax)
                                 continue;
                             backup_s.dquant= dquant;
                             if(storecoefs){
                                 for(i=0; i<6; i++){
-                                    dc[i]= s->dc_val[0][ s->block_index[i] ];
-                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(int16_t)*16);
+                                    dc[i] = s->c.dc_val[0][s->c.block_index[i]];
+                                    memcpy(ac[i], s->c.ac_val[0][s->c.block_index[i]], sizeof(int16_t)*16);
                                 }
                             }
 
                             encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
-                                         &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]);
-                            if(best_s.qscale != qp){
+                                         &dmin, &next_block, s->c.mv[mvdir][0][0], s->c.mv[mvdir][0][1]);
+                            if (best_s.c.qscale != qp) {
                                 if(storecoefs){
                                     for(i=0; i<6; i++){
-                                        s->dc_val[0][ s->block_index[i] ]= dc[i];
-                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(int16_t)*16);
+                                        s->c.dc_val[0][s->c.block_index[i]] = dc[i];
+                                        memcpy(s->c.ac_val[0][s->c.block_index[i]], ac[i], sizeof(int16_t)*16);
                                     }
                                 }
                             }
@@ -3335,45 +3337,45 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     int my= s->b_direct_mv_table[xy][1];
 
                     backup_s.dquant = 0;
-                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
-                    s->mb_intra= 0;
-                    ff_mpeg4_set_direct_mv(s, mx, my);
+                    s->c.mv_dir     = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
+                    s->c.mb_intra   = 0;
+                    ff_mpeg4_set_direct_mv(&s->c, mx, my);
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, mx, my);
                 }
                 if(CONFIG_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT0){
                     backup_s.dquant = 0;
-                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
-                    s->mb_intra= 0;
-                    ff_mpeg4_set_direct_mv(s, 0, 0);
+                    s->c.mv_dir   = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
+                    s->c.mb_intra = 0;
+                    ff_mpeg4_set_direct_mv(&s->c, 0, 0);
                     encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
                 }
-                if (!best_s.mb_intra && s->mpv_flags & FF_MPV_FLAG_SKIP_RD) {
+                if (!best_s.c.mb_intra && s->mpv_flags & FF_MPV_FLAG_SKIP_RD) {
                     int coded=0;
                     for(i=0; i<6; i++)
-                        coded |= s->block_last_index[i];
+                        coded |= s->c.block_last_index[i];
                     if(coded){
                         int mx,my;
-                        memcpy(s->mv, best_s.mv, sizeof(s->mv));
-                        if(CONFIG_MPEG4_ENCODER && best_s.mv_dir & MV_DIRECT){
+                        memcpy(s->c.mv, best_s.c.mv, sizeof(s->c.mv));
+                        if (CONFIG_MPEG4_ENCODER && best_s.c.mv_dir & MV_DIRECT) {
                             mx=my=0; //FIXME find the one we actually used
-                            ff_mpeg4_set_direct_mv(s, mx, my);
-                        }else if(best_s.mv_dir&MV_DIR_BACKWARD){
-                            mx= s->mv[1][0][0];
-                            my= s->mv[1][0][1];
+                            ff_mpeg4_set_direct_mv(&s->c, mx, my);
+                        } else if (best_s.c.mv_dir & MV_DIR_BACKWARD) {
+                            mx = s->c.mv[1][0][0];
+                            my = s->c.mv[1][0][1];
                         }else{
-                            mx= s->mv[0][0][0];
-                            my= s->mv[0][0][1];
+                            mx = s->c.mv[0][0][0];
+                            my = s->c.mv[0][0][1];
                         }
 
-                        s->mv_dir= best_s.mv_dir;
-                        s->mv_type = best_s.mv_type;
-                        s->mb_intra= 0;
-/*                        s->mv[0][0][0] = best_s.mv[0][0][0];
-                        s->mv[0][0][1] = best_s.mv[0][0][1];
-                        s->mv[1][0][0] = best_s.mv[1][0][0];
-                        s->mv[1][0][1] = best_s.mv[1][0][1];*/
+                        s->c.mv_dir   = best_s.c.mv_dir;
+                        s->c.mv_type  = best_s.c.mv_type;
+                        s->c.mb_intra = 0;
+/*                        s->c.mv[0][0][0] = best_s.mv[0][0][0];
+                        s->c.mv[0][0][1] = best_s.mv[0][0][1];
+                        s->c.mv[1][0][0] = best_s.mv[1][0][0];
+                        s->c.mv[1][0][1] = best_s.mv[1][0][1];*/
                         backup_s.dquant= 0;
                         s->skipdct=1;
                         encode_mb_hq(s, &backup_s, &best_s, pb, pb2, tex_pb,
@@ -3389,7 +3391,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                 ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count);
                 s->pb= backup_s.pb;
 
-                if(s->data_partitioning){
+                if (s->c.data_partitioning) {
                     pb2_bits_count= put_bits_count(&s->pb2);
                     flush_put_bits(&s->pb2);
                     ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count);
@@ -3403,178 +3405,178 @@ static int encode_thread(AVCodecContext *c, void *arg){
                 s->last_bits= put_bits_count(&s->pb);
 
                 if (CONFIG_H263_ENCODER &&
-                    s->out_format == FMT_H263 && s->pict_type!=AV_PICTURE_TYPE_B)
+                    s->c.out_format == FMT_H263 && s->c.pict_type!=AV_PICTURE_TYPE_B)
                     ff_h263_update_mb(s);
 
                 if(next_block==0){ //FIXME 16 vs linesize16
-                    s->hdsp.put_pixels_tab[0][0](s->dest[0], s->sc.rd_scratchpad                     , s->linesize  ,16);
-                    s->hdsp.put_pixels_tab[1][0](s->dest[1], s->sc.rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);
-                    s->hdsp.put_pixels_tab[1][0](s->dest[2], s->sc.rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8);
+                    s->c.hdsp.put_pixels_tab[0][0](s->c.dest[0], s->c.sc.rd_scratchpad                     , s->c.linesize  ,16);
+                    s->c.hdsp.put_pixels_tab[1][0](s->c.dest[1], s->c.sc.rd_scratchpad + 16*s->c.linesize    , s->c.uvlinesize, 8);
+                    s->c.hdsp.put_pixels_tab[1][0](s->c.dest[2], s->c.sc.rd_scratchpad + 16*s->c.linesize + 8, s->c.uvlinesize, 8);
                 }
 
-                if(s->avctx->mb_decision == FF_MB_DECISION_BITS)
-                    mpv_reconstruct_mb(s, s->block);
+                if(s->c.avctx->mb_decision == FF_MB_DECISION_BITS)
+                    mpv_reconstruct_mb(s, s->c.block);
             } else {
                 int motion_x = 0, motion_y = 0;
-                s->mv_type=MV_TYPE_16X16;
+                s->c.mv_type=MV_TYPE_16X16;
                 // only one MB-Type possible
 
                 switch(mb_type){
                 case CANDIDATE_MB_TYPE_INTRA:
-                    s->mv_dir = 0;
-                    s->mb_intra= 1;
-                    motion_x= s->mv[0][0][0] = 0;
-                    motion_y= s->mv[0][0][1] = 0;
-                    s->mbintra_table[xy] = 1;
+                    s->c.mv_dir = 0;
+                    s->c.mb_intra= 1;
+                    motion_x= s->c.mv[0][0][0] = 0;
+                    motion_y= s->c.mv[0][0][1] = 0;
+                    s->c.mbintra_table[xy] = 1;
                     break;
                 case CANDIDATE_MB_TYPE_INTER:
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mb_intra= 0;
-                    motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0];
-                    motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1];
+                    s->c.mv_dir = MV_DIR_FORWARD;
+                    s->c.mb_intra= 0;
+                    motion_x= s->c.mv[0][0][0] = s->p_mv_table[xy][0];
+                    motion_y= s->c.mv[0][0][1] = s->p_mv_table[xy][1];
                     break;
                 case CANDIDATE_MB_TYPE_INTER_I:
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_FORWARD;
+                    s->c.mv_type = MV_TYPE_FIELD;
+                    s->c.mb_intra= 0;
                     for(i=0; i<2; i++){
-                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];
-                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];
-                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];
+                        j= s->c.field_select[0][i] = s->p_field_select_table[i][xy];
+                        s->c.mv[0][i][0] = s->c.p_field_mv_table[i][j][xy][0];
+                        s->c.mv[0][i][1] = s->c.p_field_mv_table[i][j][xy][1];
                     }
                     break;
                 case CANDIDATE_MB_TYPE_INTER4V:
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_8X8;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_FORWARD;
+                    s->c.mv_type = MV_TYPE_8X8;
+                    s->c.mb_intra= 0;
                     for(i=0; i<4; i++){
-                        s->mv[0][i][0] = s->cur_pic.motion_val[0][s->block_index[i]][0];
-                        s->mv[0][i][1] = s->cur_pic.motion_val[0][s->block_index[i]][1];
+                        s->c.mv[0][i][0] = s->c.cur_pic.motion_val[0][s->c.block_index[i]][0];
+                        s->c.mv[0][i][1] = s->c.cur_pic.motion_val[0][s->c.block_index[i]][1];
                     }
                     break;
                 case CANDIDATE_MB_TYPE_DIRECT:
                     if (CONFIG_MPEG4_ENCODER) {
-                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
-                        s->mb_intra= 0;
+                        s->c.mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
+                        s->c.mb_intra= 0;
                         motion_x=s->b_direct_mv_table[xy][0];
                         motion_y=s->b_direct_mv_table[xy][1];
-                        ff_mpeg4_set_direct_mv(s, motion_x, motion_y);
+                        ff_mpeg4_set_direct_mv(&s->c, motion_x, motion_y);
                     }
                     break;
                 case CANDIDATE_MB_TYPE_DIRECT0:
                     if (CONFIG_MPEG4_ENCODER) {
-                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
-                        s->mb_intra= 0;
-                        ff_mpeg4_set_direct_mv(s, 0, 0);
+                        s->c.mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
+                        s->c.mb_intra= 0;
+                        ff_mpeg4_set_direct_mv(&s->c, 0, 0);
                     }
                     break;
                 case CANDIDATE_MB_TYPE_BIDIR:
-                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-                    s->mb_intra= 0;
-                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
-                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
-                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
-                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
+                    s->c.mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
+                    s->c.mb_intra= 0;
+                    s->c.mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
+                    s->c.mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
+                    s->c.mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
+                    s->c.mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
                     break;
                 case CANDIDATE_MB_TYPE_BACKWARD:
-                    s->mv_dir = MV_DIR_BACKWARD;
-                    s->mb_intra= 0;
-                    motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0];
-                    motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1];
+                    s->c.mv_dir = MV_DIR_BACKWARD;
+                    s->c.mb_intra= 0;
+                    motion_x= s->c.mv[1][0][0] = s->b_back_mv_table[xy][0];
+                    motion_y= s->c.mv[1][0][1] = s->b_back_mv_table[xy][1];
                     break;
                 case CANDIDATE_MB_TYPE_FORWARD:
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mb_intra= 0;
-                    motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
-                    motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
+                    s->c.mv_dir = MV_DIR_FORWARD;
+                    s->c.mb_intra= 0;
+                    motion_x= s->c.mv[0][0][0] = s->b_forw_mv_table[xy][0];
+                    motion_y= s->c.mv[0][0][1] = s->b_forw_mv_table[xy][1];
                     break;
                 case CANDIDATE_MB_TYPE_FORWARD_I:
-                    s->mv_dir = MV_DIR_FORWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_FORWARD;
+                    s->c.mv_type = MV_TYPE_FIELD;
+                    s->c.mb_intra= 0;
                     for(i=0; i<2; i++){
-                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];
-                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
-                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
+                        j= s->c.field_select[0][i] = s->b_field_select_table[0][i][xy];
+                        s->c.mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
+                        s->c.mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
                     }
                     break;
                 case CANDIDATE_MB_TYPE_BACKWARD_I:
-                    s->mv_dir = MV_DIR_BACKWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_BACKWARD;
+                    s->c.mv_type = MV_TYPE_FIELD;
+                    s->c.mb_intra= 0;
                     for(i=0; i<2; i++){
-                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];
-                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
-                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
+                        j= s->c.field_select[1][i] = s->b_field_select_table[1][i][xy];
+                        s->c.mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
+                        s->c.mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
                     }
                     break;
                 case CANDIDATE_MB_TYPE_BIDIR_I:
-                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-                    s->mv_type = MV_TYPE_FIELD;
-                    s->mb_intra= 0;
+                    s->c.mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
+                    s->c.mv_type = MV_TYPE_FIELD;
+                    s->c.mb_intra= 0;
                     for(dir=0; dir<2; dir++){
                         for(i=0; i<2; i++){
-                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];
-                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
-                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
+                            j= s->c.field_select[dir][i] = s->b_field_select_table[dir][i][xy];
+                            s->c.mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
+                            s->c.mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
                         }
                     }
                     break;
                 default:
-                    av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\n");
+                    av_log(s->c.avctx, AV_LOG_ERROR, "illegal MB type\n");
                 }
 
                 encode_mb(s, motion_x, motion_y);
 
                 // RAL: Update last macroblock type
-                s->last_mv_dir = s->mv_dir;
+                s->last_mv_dir = s->c.mv_dir;
 
                 if (CONFIG_H263_ENCODER &&
-                    s->out_format == FMT_H263 && s->pict_type!=AV_PICTURE_TYPE_B)
+                    s->c.out_format == FMT_H263 && s->c.pict_type != AV_PICTURE_TYPE_B)
                     ff_h263_update_mb(s);
 
-                mpv_reconstruct_mb(s, s->block);
+                mpv_reconstruct_mb(s, s->c.block);
             }
 
-            s->cur_pic.qscale_table[xy] = s->qscale;
+            s->c.cur_pic.qscale_table[xy] = s->c.qscale;
 
             /* clean the MV table in IPS frames for direct mode in B-frames */
-            if(s->mb_intra /* && I,P,S_TYPE */){
+            if (s->c.mb_intra /* && I,P,S_TYPE */) {
                 s->p_mv_table[xy][0]=0;
                 s->p_mv_table[xy][1]=0;
-            } else if ((s->h263_pred || s->h263_aic) && s->mbintra_table[xy])
-                ff_clean_intra_table_entries(s);
+            } else if ((s->c.h263_pred || s->c.h263_aic) && s->c.mbintra_table[xy])
+                ff_clean_intra_table_entries(&s->c);
 
-            if (s->avctx->flags & AV_CODEC_FLAG_PSNR) {
+            if (s->c.avctx->flags & AV_CODEC_FLAG_PSNR) {
                 int w= 16;
                 int h= 16;
 
-                if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
-                if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;
+                if(s->c.mb_x*16 + 16 > s->c.width ) w= s->c.width - s->c.mb_x*16;
+                if(s->c.mb_y*16 + 16 > s->c.height) h= s->c.height- s->c.mb_y*16;
 
                 s->encoding_error[0] += sse(
-                    s, s->new_pic->data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
-                    s->dest[0], w, h, s->linesize);
+                    s, s->new_pic->data[0] + s->c.mb_x*16 + s->c.mb_y*s->c.linesize*16,
+                    s->c.dest[0], w, h, s->c.linesize);
                 s->encoding_error[1] += sse(
-                    s, s->new_pic->data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*chr_h,
-                    s->dest[1], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
+                    s, s->new_pic->data[1] + s->c.mb_x*8  + s->c.mb_y*s->c.uvlinesize*chr_h,
+                    s->c.dest[1], w>>1, h>>s->c.chroma_y_shift, s->c.uvlinesize);
                 s->encoding_error[2] += sse(
-                    s, s->new_pic->data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*chr_h,
-                    s->dest[2], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
+                    s, s->new_pic->data[2] + s->c.mb_x*8  + s->c.mb_y*s->c.uvlinesize*chr_h,
+                    s->c.dest[2], w>>1, h>>s->c.chroma_y_shift, s->c.uvlinesize);
             }
-            if(s->loop_filter){
-                if(CONFIG_H263_ENCODER && s->out_format == FMT_H263)
-                    ff_h263_loop_filter(s);
+            if (s->c.loop_filter) {
+                if (CONFIG_H263_ENCODER && s->c.out_format == FMT_H263)
+                    ff_h263_loop_filter(&s->c);
             }
-            ff_dlog(s->avctx, "MB %d %d bits\n",
-                    s->mb_x + s->mb_y * s->mb_stride, put_bits_count(&s->pb));
+            ff_dlog(s->c.avctx, "MB %d %d bits\n",
+                    s->c.mb_x + s->c.mb_y * s->c.mb_stride, put_bits_count(&s->pb));
         }
     }
 
 #if CONFIG_MSMPEG4ENC
     //not beautiful here but we must write it before flushing so it has to be here
-    if (s->msmpeg4_version != MSMP4_UNUSED && s->msmpeg4_version < MSMP4_WMV1 &&
-        s->pict_type == AV_PICTURE_TYPE_I)
+    if (s->c.msmpeg4_version != MSMP4_UNUSED && s->c.msmpeg4_version < MSMP4_WMV1 &&
+        s->c.pict_type == AV_PICTURE_TYPE_I)
         ff_msmpeg4_encode_ext_header(s);
 #endif
 
@@ -3584,13 +3586,15 @@ static int encode_thread(AVCodecContext *c, void *arg){
 }
 
 #define MERGE(field) dst->field += src->field; src->field=0
-static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){
-    MERGE(me.scene_change_score);
-    MERGE(me.mc_mb_var_sum_temp);
-    MERGE(me.mb_var_sum_temp);
+static void merge_context_after_me(MPVEncContext *const dst, MPVEncContext *const src)
+{
+    MERGE(c.me.scene_change_score);
+    MERGE(c.me.mc_mb_var_sum_temp);
+    MERGE(c.me.mb_var_sum_temp);
 }
 
-static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){
+static void merge_context_after_encode(MPVEncContext *const dst, MPVEncContext *const src)
+{
     int i;
 
     MERGE(dct_count[0]); //note, the other dct vars are not part of the context
@@ -3619,22 +3623,22 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
 
 static int estimate_qp(MPVMainEncContext *const m, int dry_run)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
     if (m->next_lambda){
-        s->cur_pic.ptr->f->quality = m->next_lambda;
+        s->c.cur_pic.ptr->f->quality = m->next_lambda;
         if(!dry_run) m->next_lambda= 0;
     } else if (!m->fixed_qscale) {
         int quality = ff_rate_estimate_qscale(m, dry_run);
-        s->cur_pic.ptr->f->quality = quality;
-        if (s->cur_pic.ptr->f->quality < 0)
+        s->c.cur_pic.ptr->f->quality = quality;
+        if (s->c.cur_pic.ptr->f->quality < 0)
             return -1;
     }
 
     if(s->adaptive_quant){
         init_qscale_tab(s);
 
-        switch(s->codec_id){
+        switch (s->c.codec_id) {
         case AV_CODEC_ID_MPEG4:
             if (CONFIG_MPEG4_ENCODER)
                 ff_clean_mpeg4_qscales(s);
@@ -3647,169 +3651,174 @@ static int estimate_qp(MPVMainEncContext *const m, int dry_run)
             break;
         }
 
-        s->lambda= s->lambda_table[0];
+        s->c.lambda= s->lambda_table[0];
         //FIXME broken
     }else
-        s->lambda = s->cur_pic.ptr->f->quality;
+        s->c.lambda = s->c.cur_pic.ptr->f->quality;
     update_qscale(m);
     return 0;
 }
 
 /* must be called before writing the header */
-static void set_frame_distances(MpegEncContext * s){
-    av_assert1(s->cur_pic.ptr->f->pts != AV_NOPTS_VALUE);
-    s->time = s->cur_pic.ptr->f->pts * s->avctx->time_base.num;
+static void set_frame_distances(MPVEncContext *const s)
+{
+    av_assert1(s->c.cur_pic.ptr->f->pts != AV_NOPTS_VALUE);
+    s->c.time = s->c.cur_pic.ptr->f->pts * s->c.avctx->time_base.num;
 
-    if(s->pict_type==AV_PICTURE_TYPE_B){
-        s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
-        av_assert1(s->pb_time > 0 && s->pb_time < s->pp_time);
+    if (s->c.pict_type == AV_PICTURE_TYPE_B) {
+        s->c.pb_time = s->c.pp_time - (s->c.last_non_b_time - s->c.time);
+        av_assert1(s->c.pb_time > 0 && s->c.pb_time < s->c.pp_time);
     }else{
-        s->pp_time= s->time - s->last_non_b_time;
-        s->last_non_b_time= s->time;
-        av_assert1(s->picture_number==0 || s->pp_time > 0);
+        s->c.pp_time = s->c.time - s->c.last_non_b_time;
+        s->c.last_non_b_time = s->c.time;
+        av_assert1(s->c.picture_number==0 || s->c.pp_time > 0);
     }
 }
 
 static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int i, ret;
     int bits;
-    int context_count = s->slice_context_count;
+    int context_count = s->c.slice_context_count;
 
     /* Reset the average MB variance */
-    s->me.mb_var_sum_temp    =
-    s->me.mc_mb_var_sum_temp = 0;
+    s->c.me.mb_var_sum_temp    =
+    s->c.me.mc_mb_var_sum_temp = 0;
 
     /* we need to initialize some time vars before we can encode B-frames */
     // RAL: Condition added for MPEG1VIDEO
-    if (s->out_format == FMT_MPEG1 || (s->h263_pred && s->msmpeg4_version == MSMP4_UNUSED))
+    if (s->c.out_format == FMT_MPEG1 || (s->c.h263_pred && s->c.msmpeg4_version == MSMP4_UNUSED))
         set_frame_distances(s);
-    if(CONFIG_MPEG4_ENCODER && s->codec_id == AV_CODEC_ID_MPEG4)
+    if (CONFIG_MPEG4_ENCODER && s->c.codec_id == AV_CODEC_ID_MPEG4)
         ff_set_mpeg4_time(s);
 
-    s->me.scene_change_score=0;
+    s->c.me.scene_change_score=0;
 
-//    s->lambda= s->cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
+//    s->c.lambda= s->c.cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
 
-    if(s->pict_type==AV_PICTURE_TYPE_I){
-        s->no_rounding = s->msmpeg4_version >= MSMP4_V3;
-    }else if(s->pict_type!=AV_PICTURE_TYPE_B){
-        s->no_rounding ^= s->flipflop_rounding;
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
+        s->c.no_rounding = s->c.msmpeg4_version >= MSMP4_V3;
+    } else if (s->c.pict_type != AV_PICTURE_TYPE_B) {
+        s->c.no_rounding ^= s->c.flipflop_rounding;
     }
 
-    if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
+    if (s->c.avctx->flags & AV_CODEC_FLAG_PASS2) {
         ret = estimate_qp(m, 1);
         if (ret < 0)
             return ret;
         ff_get_2pass_fcode(m);
-    } else if (!(s->avctx->flags & AV_CODEC_FLAG_QSCALE)) {
-        if(s->pict_type==AV_PICTURE_TYPE_B)
-            s->lambda = m->last_lambda_for[s->pict_type];
+    } else if (!(s->c.avctx->flags & AV_CODEC_FLAG_QSCALE)) {
+        if(s->c.pict_type==AV_PICTURE_TYPE_B)
+            s->c.lambda = m->last_lambda_for[s->c.pict_type];
         else
-            s->lambda = m->last_lambda_for[m->last_non_b_pict_type];
+            s->c.lambda = m->last_lambda_for[m->last_non_b_pict_type];
         update_qscale(m);
     }
 
     ff_me_init_pic(s);
 
-    s->mb_intra=0; //for the rate distortion & bit compare functions
+    s->c.mb_intra = 0; //for the rate distortion & bit compare functions
     for (int i = 0; i < context_count; i++) {
-        MpegEncContext *const slice = s->thread_context[i];
+        MPVEncContext *const slice = s->c.enc_contexts[i];
         uint8_t *start, *end;
         int h;
 
         if (i) {
-            ret = ff_update_duplicate_context(slice, s);
+            ret = ff_update_duplicate_context(&slice->c, &s->c);
             if (ret < 0)
                 return ret;
         }
-        slice->me.temp = slice->me.scratchpad = slice->sc.scratchpad_buf;
+        slice->c.me.temp = slice->c.me.scratchpad = slice->c.sc.scratchpad_buf;
 
-        h     = s->mb_height;
-        start = pkt->data + (size_t)(((int64_t) pkt->size) * slice->start_mb_y / h);
-        end   = pkt->data + (size_t)(((int64_t) pkt->size) * slice->  end_mb_y / h);
+        h     = s->c.mb_height;
+        start = pkt->data + (size_t)(((int64_t) pkt->size) * slice->c.start_mb_y / h);
+        end   = pkt->data + (size_t)(((int64_t) pkt->size) * slice->c.  end_mb_y / h);
 
-        init_put_bits(&s->thread_context[i]->pb, start, end - start);
+        init_put_bits(&s->c.enc_contexts[i]->pb, start, end - start);
     }
 
     /* Estimate motion for every MB */
-    if(s->pict_type != AV_PICTURE_TYPE_I){
-        s->lambda  = (s->lambda  * m->me_penalty_compensation + 128) >> 8;
-        s->lambda2 = (s->lambda2 * (int64_t) m->me_penalty_compensation + 128) >> 8;
-        if (s->pict_type != AV_PICTURE_TYPE_B) {
+    if (s->c.pict_type != AV_PICTURE_TYPE_I) {
+        s->c.lambda  = (s->c.lambda  * m->me_penalty_compensation + 128) >> 8;
+        s->c.lambda2 = (s->c.lambda2 * (int64_t) m->me_penalty_compensation + 128) >> 8;
+        if (s->c.pict_type != AV_PICTURE_TYPE_B) {
             if ((m->me_pre && m->last_non_b_pict_type == AV_PICTURE_TYPE_I) ||
                 m->me_pre == 2) {
-                s->avctx->execute(s->avctx, pre_estimate_motion_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
+                s->c.avctx->execute(s->c.avctx, pre_estimate_motion_thread,
+                                    &s->c.enc_contexts[0], NULL,
+                                    context_count, sizeof(void*));
             }
         }
 
-        s->avctx->execute(s->avctx, estimate_motion_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
-    }else /* if(s->pict_type == AV_PICTURE_TYPE_I) */{
+        s->c.avctx->execute(s->c.avctx, estimate_motion_thread, &s->c.enc_contexts[0],
+                            NULL, context_count, sizeof(void*));
+    }else /* if(s->c.pict_type == AV_PICTURE_TYPE_I) */{
         /* I-Frame */
-        for(i=0; i<s->mb_stride*s->mb_height; i++)
+        for (int i = 0; i < s->c.mb_stride * s->c.mb_height; i++)
             s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
 
         if (!m->fixed_qscale) {
             /* finding spatial complexity for I-frame rate control */
-            s->avctx->execute(s->avctx, mb_var_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
+            s->c.avctx->execute(s->c.avctx, mb_var_thread, &s->c.enc_contexts[0],
+                                NULL, context_count, sizeof(void*));
         }
     }
     for(i=1; i<context_count; i++){
-        merge_context_after_me(s, s->thread_context[i]);
+        merge_context_after_me(s, s->c.enc_contexts[i]);
     }
-    m->mc_mb_var_sum = s->me.mc_mb_var_sum_temp;
-    m->mb_var_sum    = s->me.   mb_var_sum_temp;
+    m->mc_mb_var_sum = s->c.me.mc_mb_var_sum_temp;
+    m->mb_var_sum    = s->c.me.   mb_var_sum_temp;
     emms_c();
 
-    if (s->me.scene_change_score > m->scenechange_threshold &&
-        s->pict_type == AV_PICTURE_TYPE_P) {
-        s->pict_type= AV_PICTURE_TYPE_I;
-        for(i=0; i<s->mb_stride*s->mb_height; i++)
-            s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
-        if (s->msmpeg4_version >= MSMP4_V3)
-            s->no_rounding=1;
-        ff_dlog(s->avctx, "Scene change detected, encoding as I Frame %"PRId64" %"PRId64"\n",
+    if (s->c.me.scene_change_score > m->scenechange_threshold &&
+        s->c.pict_type == AV_PICTURE_TYPE_P) {
+        s->c.pict_type = AV_PICTURE_TYPE_I;
+        for (int i = 0; i < s->c.mb_stride * s->c.mb_height; i++)
+            s->mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
+        if (s->c.msmpeg4_version >= MSMP4_V3)
+            s->c.no_rounding = 1;
+        ff_dlog(s->c.avctx, "Scene change detected, encoding as I Frame %"PRId64" %"PRId64"\n",
                 m->mb_var_sum, m->mc_mb_var_sum);
     }
 
-    if(!s->umvplus){
-        if(s->pict_type==AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
-            s->f_code = ff_get_best_fcode(m, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);
+    if (!s->c.umvplus) {
+        if (s->c.pict_type == AV_PICTURE_TYPE_P || s->c.pict_type == AV_PICTURE_TYPE_S) {
+            s->c.f_code = ff_get_best_fcode(m, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);
 
-            if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
+            if (s->c.avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
                 int a,b;
-                a = ff_get_best_fcode(m, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select
-                b = ff_get_best_fcode(m, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I);
-                s->f_code= FFMAX3(s->f_code, a, b);
+                a = ff_get_best_fcode(m, s->c.p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select
+                b = ff_get_best_fcode(m, s->c.p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I);
+                s->c.f_code= FFMAX3(s->c.f_code, a, b);
             }
 
             ff_fix_long_p_mvs(s, s->intra_penalty ? CANDIDATE_MB_TYPE_INTER : CANDIDATE_MB_TYPE_INTRA);
-            ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, !!s->intra_penalty);
-            if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
+            ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->c.f_code, CANDIDATE_MB_TYPE_INTER, !!s->intra_penalty);
+            if (s->c.avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
                 int j;
                 for(i=0; i<2; i++){
                     for(j=0; j<2; j++)
                         ff_fix_long_mvs(s, s->p_field_select_table[i], j,
-                                        s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, !!s->intra_penalty);
+                                        s->c.p_field_mv_table[i][j], s->c.f_code, CANDIDATE_MB_TYPE_INTER_I, !!s->intra_penalty);
                 }
             }
-        } else if (s->pict_type == AV_PICTURE_TYPE_B) {
+        } else if (s->c.pict_type == AV_PICTURE_TYPE_B) {
             int a, b;
 
             a = ff_get_best_fcode(m, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD);
             b = ff_get_best_fcode(m, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR);
-            s->f_code = FFMAX(a, b);
+            s->c.f_code = FFMAX(a, b);
 
             a = ff_get_best_fcode(m, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD);
             b = ff_get_best_fcode(m, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR);
-            s->b_code = FFMAX(a, b);
+            s->c.b_code = FFMAX(a, b);
 
-            ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1);
-            ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BACKWARD, 1);
-            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1);
-            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1);
-            if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
+            ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->c.f_code, CANDIDATE_MB_TYPE_FORWARD, 1);
+            ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->c.b_code, CANDIDATE_MB_TYPE_BACKWARD, 1);
+            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->c.f_code, CANDIDATE_MB_TYPE_BIDIR, 1);
+            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->c.b_code, CANDIDATE_MB_TYPE_BIDIR, 1);
+            if (s->c.avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
                 int dir, j;
                 for(dir=0; dir<2; dir++){
                     for(i=0; i<2; i++){
@@ -3817,7 +3826,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
                             int type= dir ? (CANDIDATE_MB_TYPE_BACKWARD_I|CANDIDATE_MB_TYPE_BIDIR_I)
                                           : (CANDIDATE_MB_TYPE_FORWARD_I |CANDIDATE_MB_TYPE_BIDIR_I);
                             ff_fix_long_mvs(s, s->b_field_select_table[dir][i], j,
-                                            s->b_field_mv_table[dir][i][j], dir ? s->b_code : s->f_code, type, 1);
+                                            s->b_field_mv_table[dir][i][j], dir ? s->c.b_code : s->c.f_code, type, 1);
                         }
                     }
                 }
@@ -3829,70 +3838,70 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     if (ret < 0)
         return ret;
 
-    if (s->qscale < 3 && s->max_qcoeff <= 128 &&
-        s->pict_type == AV_PICTURE_TYPE_I &&
-        !(s->avctx->flags & AV_CODEC_FLAG_QSCALE))
-        s->qscale= 3; //reduce clipping problems
+    if (s->c.qscale < 3 && s->max_qcoeff <= 128 &&
+        s->c.pict_type == AV_PICTURE_TYPE_I &&
+        !(s->c.avctx->flags & AV_CODEC_FLAG_QSCALE))
+        s->c.qscale= 3; //reduce clipping problems
 
-    if (s->out_format == FMT_MJPEG) {
-        ret = ff_check_codec_matrices(s->avctx, FF_MATRIX_TYPE_INTRA | FF_MATRIX_TYPE_CHROMA_INTRA, (7 + s->qscale) / s->qscale, 65535);
+    if (s->c.out_format == FMT_MJPEG) {
+        ret = ff_check_codec_matrices(s->c.avctx, FF_MATRIX_TYPE_INTRA | FF_MATRIX_TYPE_CHROMA_INTRA, (7 + s->c.qscale) / s->c.qscale, 65535);
         if (ret < 0)
             return ret;
 
-        if (s->codec_id != AV_CODEC_ID_AMV) {
+        if (s->c.codec_id != AV_CODEC_ID_AMV) {
             const uint16_t *  luma_matrix = ff_mpeg1_default_intra_matrix;
             const uint16_t *chroma_matrix = ff_mpeg1_default_intra_matrix;
 
-            if (s->avctx->intra_matrix) {
+            if (s->c.avctx->intra_matrix) {
                 chroma_matrix =
-                luma_matrix = s->avctx->intra_matrix;
+                luma_matrix = s->c.avctx->intra_matrix;
             }
-            if (s->avctx->chroma_intra_matrix)
-                chroma_matrix = s->avctx->chroma_intra_matrix;
+            if (s->c.avctx->chroma_intra_matrix)
+                chroma_matrix = s->c.avctx->chroma_intra_matrix;
 
             /* for mjpeg, we do include qscale in the matrix */
             for (int i = 1; i < 64; i++) {
-                int j = s->idsp.idct_permutation[i];
+                int j = s->c.idsp.idct_permutation[i];
 
-                s->chroma_intra_matrix[j] = av_clip_uint8((chroma_matrix[i] * s->qscale) >> 3);
-                s->       intra_matrix[j] = av_clip_uint8((  luma_matrix[i] * s->qscale) >> 3);
+                s->c.chroma_intra_matrix[j] = av_clip_uint8((chroma_matrix[i] * s->c.qscale) >> 3);
+                s->c.       intra_matrix[j] = av_clip_uint8((  luma_matrix[i] * s->c.qscale) >> 3);
             }
-            s->y_dc_scale_table =
-            s->c_dc_scale_table = ff_mpeg12_dc_scale_table[s->intra_dc_precision];
-            s->chroma_intra_matrix[0] =
-            s->intra_matrix[0]  = ff_mpeg12_dc_scale_table[s->intra_dc_precision][8];
+            s->c.y_dc_scale_table =
+            s->c.c_dc_scale_table = ff_mpeg12_dc_scale_table[s->c.intra_dc_precision];
+            s->c.chroma_intra_matrix[0] =
+            s->c.intra_matrix[0]  = ff_mpeg12_dc_scale_table[s->c.intra_dc_precision][8];
         } else {
             static const uint8_t y[32] = {13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13};
             static const uint8_t c[32] = {14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14};
             for (int i = 1; i < 64; i++) {
-                int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+                int j = s->c.idsp.idct_permutation[ff_zigzag_direct[i]];
 
-                s->intra_matrix[j]        = sp5x_qscale_five_quant_table[0][i];
-                s->chroma_intra_matrix[j] = sp5x_qscale_five_quant_table[1][i];
+                s->c.intra_matrix[j]        = sp5x_qscale_five_quant_table[0][i];
+                s->c.chroma_intra_matrix[j] = sp5x_qscale_five_quant_table[1][i];
             }
-            s->y_dc_scale_table = y;
-            s->c_dc_scale_table = c;
-            s->intra_matrix[0] = 13;
-            s->chroma_intra_matrix[0] = 14;
+            s->c.y_dc_scale_table = y;
+            s->c.c_dc_scale_table = c;
+            s->c.intra_matrix[0] = 13;
+            s->c.chroma_intra_matrix[0] = 14;
         }
         ff_convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
-                          s->intra_matrix, s->intra_quant_bias, 8, 8, 1);
+                          s->c.intra_matrix, s->intra_quant_bias, 8, 8, 1);
         ff_convert_matrix(s, s->q_chroma_intra_matrix, s->q_chroma_intra_matrix16,
-                          s->chroma_intra_matrix, s->intra_quant_bias, 8, 8, 1);
-        s->qscale = 8;
+                          s->c.chroma_intra_matrix, s->intra_quant_bias, 8, 8, 1);
+        s->c.qscale = 8;
     }
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
-        s->cur_pic.ptr->f->flags |= AV_FRAME_FLAG_KEY;
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
+        s->c.cur_pic.ptr->f->flags |= AV_FRAME_FLAG_KEY;
     } else {
-        s->cur_pic.ptr->f->flags &= ~AV_FRAME_FLAG_KEY;
+        s->c.cur_pic.ptr->f->flags &= ~AV_FRAME_FLAG_KEY;
     }
-    s->cur_pic.ptr->f->pict_type = s->pict_type;
+    s->c.cur_pic.ptr->f->pict_type = s->c.pict_type;
 
-    if (s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
+    if (s->c.cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
         m->picture_in_gop_number = 0;
 
-    s->mb_x = s->mb_y = 0;
+    s->c.mb_x = s->c.mb_y = 0;
     s->last_bits= put_bits_count(&s->pb);
     ret = m->encode_picture_header(m);
     if (ret < 0)
@@ -3901,20 +3910,22 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     m->header_bits = bits - s->last_bits;
 
     for(i=1; i<context_count; i++){
-        update_duplicate_context_after_me(s->thread_context[i], s);
+        update_duplicate_context_after_me(s->c.enc_contexts[i], s);
     }
-    s->avctx->execute(s->avctx, encode_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
+    s->c.avctx->execute(s->c.avctx, encode_thread, &s->c.enc_contexts[0],
+                        NULL, context_count, sizeof(void*));
     for(i=1; i<context_count; i++){
-        if (s->pb.buf_end == s->thread_context[i]->pb.buf)
-            set_put_bits_buffer_size(&s->pb, FFMIN(s->thread_context[i]->pb.buf_end - s->pb.buf, INT_MAX/8-BUF_BITS));
-        merge_context_after_encode(s, s->thread_context[i]);
+        if (s->pb.buf_end == s->c.enc_contexts[i]->pb.buf)
+            set_put_bits_buffer_size(&s->pb, FFMIN(s->c.enc_contexts[i]->pb.buf_end - s->pb.buf, INT_MAX/8-BUF_BITS));
+        merge_context_after_encode(s, s->c.enc_contexts[i]);
     }
     emms_c();
     return 0;
 }
 
-static void denoise_dct_c(MpegEncContext *s, int16_t *block){
-    const int intra= s->mb_intra;
+static void denoise_dct_c(MPVEncContext *const s, int16_t *block)
+{
+    const int intra= s->c.mb_intra;
     int i;
 
     s->dct_count[intra]++;
@@ -3937,7 +3948,7 @@ static void denoise_dct_c(MpegEncContext *s, int16_t *block){
     }
 }
 
-static int dct_quantize_trellis_c(MpegEncContext *s,
+static int dct_quantize_trellis_c(MPVEncContext *const s,
                                   int16_t *block, int n,
                                   int qscale, int *overflow){
     const int *qmat;
@@ -3961,7 +3972,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
     int qmul, qadd, start_i, last_non_zero, i, dc;
     const int esc_length= s->ac_esc_length;
     const uint8_t *length, *last_length;
-    const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
+    const int lambda= s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6);
     int mpeg2_qscale;
 
     s->fdsp.fdct(block);
@@ -3971,18 +3982,18 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
     qmul= qscale*16;
     qadd= ((qscale-1)|1)*8;
 
-    if (s->q_scale_type) mpeg2_qscale = ff_mpeg2_non_linear_qscale[qscale];
+    if (s->c.q_scale_type) mpeg2_qscale = ff_mpeg2_non_linear_qscale[qscale];
     else                 mpeg2_qscale = qscale << 1;
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         int q;
-        scantable= s->intra_scantable.scantable;
-        perm_scantable= s->intra_scantable.permutated;
-        if (!s->h263_aic) {
+        scantable= s->c.intra_scantable.scantable;
+        perm_scantable= s->c.intra_scantable.permutated;
+        if (!s->c.h263_aic) {
             if (n < 4)
-                q = s->y_dc_scale;
+                q = s->c.y_dc_scale;
             else
-                q = s->c_dc_scale;
+                q = s->c.c_dc_scale;
             q = q << 3;
         } else{
             /* For AIC we skip quant/dequant of INTRADC */
@@ -3995,8 +4006,8 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
         start_i = 1;
         last_non_zero = 0;
         qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale];
-        matrix = n < 4 ? s->intra_matrix : s->chroma_intra_matrix;
-        if(s->mpeg_quant || s->out_format == FMT_MPEG1 || s->out_format == FMT_MJPEG)
+        matrix = n < 4 ? s->c.intra_matrix : s->c.chroma_intra_matrix;
+        if (s->c.mpeg_quant || s->c.out_format == FMT_MPEG1 || s->c.out_format == FMT_MJPEG)
             bias= 1<<(QMAT_SHIFT-1);
 
         if (n > 3 && s->intra_chroma_ac_vlc_length) {
@@ -4007,12 +4018,12 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
             last_length= s->intra_ac_vlc_last_length;
         }
     } else {
-        scantable= s->inter_scantable.scantable;
-        perm_scantable= s->inter_scantable.permutated;
+        scantable      = s->c.inter_scantable.scantable;
+        perm_scantable = s->c.inter_scantable.permutated;
         start_i = 0;
         last_non_zero = -1;
         qmat = s->q_inter_matrix[qscale];
-        matrix = s->inter_matrix;
+        matrix = s->c.inter_matrix;
         length     = s->inter_ac_vlc_length;
         last_length= s->inter_ac_vlc_last_length;
     }
@@ -4086,14 +4097,14 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
 
             av_assert2(level);
 
-            if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
+            if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
                 unquant_coeff= alevel*qmul + qadd;
-            } else if(s->out_format == FMT_MJPEG) {
-                j = s->idsp.idct_permutation[scantable[i]];
+            } else if(s->c.out_format == FMT_MJPEG) {
+                j = s->c.idsp.idct_permutation[scantable[i]];
                 unquant_coeff = alevel * matrix[j] * 8;
             }else{ // MPEG-1
-                j = s->idsp.idct_permutation[scantable[i]]; // FIXME: optimize
-                if(s->mb_intra){
+                j = s->c.idsp.idct_permutation[scantable[i]]; // FIXME: optimize
+                if(s->c.mb_intra){
                         unquant_coeff = (int)(  alevel  * mpeg2_qscale * matrix[j]) >> 4;
                         unquant_coeff =   (unquant_coeff - 1) | 1;
                 }else{
@@ -4118,7 +4129,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
                     }
                 }
 
-                if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
+                if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
                     for(j=survivor_count-1; j>=0; j--){
                         int run= i - survivor[j];
                         int score= distortion + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda;
@@ -4144,7 +4155,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
                     }
                 }
 
-                if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
+                if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
                   for(j=survivor_count-1; j>=0; j--){
                         int run= i - survivor[j];
                         int score= distortion + score_tab[i-run];
@@ -4177,7 +4188,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
         survivor[ survivor_count++ ]= i+1;
     }
 
-    if(s->out_format != FMT_H263 && s->out_format != FMT_H261){
+    if(s->c.out_format != FMT_H263 && s->c.out_format != FMT_H261){
         last_score= 256*256*256*120;
         for(i= survivor[0]; i<=last_non_zero + 1; i++){
             int score= score_tab[i];
@@ -4211,7 +4222,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
             int alevel= FFABS(level);
             int unquant_coeff, score, distortion;
 
-            if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
+            if(s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261){
                     unquant_coeff= (alevel*qmul + qadd)>>3;
             } else{ // MPEG-1
                     unquant_coeff = (((  alevel  << 1) + 1) * mpeg2_qscale * ((int) matrix[0])) >> 5;
@@ -4270,7 +4281,7 @@ static void build_basis(uint8_t *perm){
     }
 }
 
-static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
+static int dct_quantize_refine(MPVEncContext *const s, //FIXME breaks denoise?
                         int16_t *block, int16_t *weight, int16_t *orig,
                         int n, int qscale){
     int16_t rem[64];
@@ -4286,21 +4297,21 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
     const uint8_t *length;
     const uint8_t *last_length;
     int lambda;
-    int rle_index, run, q = 1, sum; //q is only used when s->mb_intra is true
+    int rle_index, run, q = 1, sum; //q is only used when s->c.mb_intra is true
 
     if(basis[0][0] == 0)
-        build_basis(s->idsp.idct_permutation);
+        build_basis(s->c.idsp.idct_permutation);
 
     qmul= qscale*2;
     qadd= (qscale-1)|1;
-    if (s->mb_intra) {
-        scantable= s->intra_scantable.scantable;
-        perm_scantable= s->intra_scantable.permutated;
-        if (!s->h263_aic) {
+    if (s->c.mb_intra) {
+        scantable= s->c.intra_scantable.scantable;
+        perm_scantable= s->c.intra_scantable.permutated;
+        if (!s->c.h263_aic) {
             if (n < 4)
-                q = s->y_dc_scale;
+                q = s->c.y_dc_scale;
             else
-                q = s->c_dc_scale;
+                q = s->c.c_dc_scale;
         } else{
             /* For AIC we skip quant/dequant of INTRADC */
             q = 1;
@@ -4311,7 +4322,7 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
         dc= block[0]*q;
 //        block[0] = (block[0] + (q >> 1)) / q;
         start_i = 1;
-//        if(s->mpeg_quant || s->out_format == FMT_MPEG1)
+//        if(s->c.mpeg_quant || s->c.out_format == FMT_MPEG1)
 //            bias= 1<<(QMAT_SHIFT-1);
         if (n > 3 && s->intra_chroma_ac_vlc_length) {
             length     = s->intra_chroma_ac_vlc_length;
@@ -4321,14 +4332,14 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
             last_length= s->intra_ac_vlc_last_length;
         }
     } else {
-        scantable= s->inter_scantable.scantable;
-        perm_scantable= s->inter_scantable.permutated;
+        scantable= s->c.inter_scantable.scantable;
+        perm_scantable= s->c.inter_scantable.permutated;
         dc= 0;
         start_i = 0;
         length     = s->inter_ac_vlc_length;
         last_length= s->inter_ac_vlc_last_length;
     }
-    last_non_zero = s->block_last_index[n];
+    last_non_zero = s->c.block_last_index[n];
 
     dc += (1<<(RECON_SHIFT-1));
     for(i=0; i<64; i++){
@@ -4351,7 +4362,7 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
         av_assert2(w<(1<<6));
         sum += w*w;
     }
-    lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);
+    lambda= sum*(uint64_t)s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);
 
     run=0;
     rle_index=0;
@@ -4392,7 +4403,7 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
             const int level= block[0];
             int change, old_coeff;
 
-            av_assert2(s->mb_intra);
+            av_assert2(s->c.mb_intra);
 
             old_coeff= q*level;
 
@@ -4622,7 +4633,7 @@ void ff_block_permute(int16_t *block, const uint8_t *permutation,
     }
 }
 
-static int dct_quantize_c(MpegEncContext *s,
+static int dct_quantize_c(MPVEncContext *const s,
                           int16_t *block, int n,
                           int qscale, int *overflow)
 {
@@ -4638,13 +4649,13 @@ static int dct_quantize_c(MpegEncContext *s,
     if(s->dct_error_sum)
         s->denoise_dct(s, block);
 
-    if (s->mb_intra) {
-        scantable= s->intra_scantable.scantable;
-        if (!s->h263_aic) {
+    if (s->c.mb_intra) {
+        scantable= s->c.intra_scantable.scantable;
+        if (!s->c.h263_aic) {
             if (n < 4)
-                q = s->y_dc_scale;
+                q = s->c.y_dc_scale;
             else
-                q = s->c_dc_scale;
+                q = s->c.c_dc_scale;
             q = q << 3;
         } else
             /* For AIC we skip quant/dequant of INTRADC */
@@ -4657,7 +4668,7 @@ static int dct_quantize_c(MpegEncContext *s,
         qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale];
         bias= s->intra_quant_bias*(1<<(QMAT_SHIFT - QUANT_BIAS_SHIFT));
     } else {
-        scantable= s->inter_scantable.scantable;
+        scantable= s->c.inter_scantable.scantable;
         start_i = 0;
         last_non_zero = -1;
         qmat = s->q_inter_matrix[qscale];
@@ -4698,8 +4709,8 @@ static int dct_quantize_c(MpegEncContext *s,
     *overflow= s->max_qcoeff < max; //overflow might have happened
 
     /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */
-    if (s->idsp.perm_type != FF_IDCT_PERM_NONE)
-        ff_block_permute(block, s->idsp.idct_permutation,
+    if (s->c.idsp.perm_type != FF_IDCT_PERM_NONE)
+        ff_block_permute(block, s->c.idsp.idct_permutation,
                       scantable, last_non_zero);
 
     return last_non_zero;
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index bc8a3e80d5..1d124b1bd1 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -32,13 +32,142 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
+#include "fdctdsp.h"
 #include "mpegvideo.h"
+#include "mpegvideoencdsp.h"
+#include "pixblockdsp.h"
+#include "put_bits.h"
 #include "ratecontrol.h"
 
 #define MPVENC_MAX_B_FRAMES 16
 
+typedef struct MPVEncContext {
+    MpegEncContext c;           ///< the common base context
+
+    /** bit output */
+    PutBitContext pb;
+
+    int *lambda_table;
+    int adaptive_quant;         ///< use adaptive quantization
+    int dquant;                 ///< qscale difference to prev qscale
+    int skipdct;                ///< skip dct and code zero residual
+
+    int luma_elim_threshold;
+    int chroma_elim_threshold;
+
+    /**
+     * Reference to the source picture.
+     */
+    AVFrame *new_pic;
+
+    FDCTDSPContext fdsp;
+    MpegvideoEncDSPContext mpvencdsp;
+    PixblockDSPContext pdsp;
+
+    int16_t (*p_mv_table)[2];            ///< MV table (1MV per MB) P-frame
+    int16_t (*b_forw_mv_table)[2];       ///< MV table (1MV per MB) forward mode B-frame
+    int16_t (*b_back_mv_table)[2];       ///< MV table (1MV per MB) backward mode B-frame
+    int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame
+    int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame
+    int16_t (*b_direct_mv_table)[2];     ///< MV table (1MV per MB) direct mode B-frame
+    int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame
+    uint8_t (*p_field_select_table[2]);  ///< Only the first element is allocated
+    uint8_t (*b_field_select_table[2][2]); ///< allocated jointly with p_field_select_table
+
+    uint16_t *mb_type;          ///< Table for candidate MB types
+    uint16_t *mb_var;           ///< Table for MB variances
+    uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
+    uint8_t  *mb_mean;          ///< Table for MB luminance
+    uint64_t encoding_error[MPV_MAX_PLANES];
+
+    int intra_quant_bias;    ///< bias for the quantizer
+    int inter_quant_bias;    ///< bias for the quantizer
+    int min_qcoeff;          ///< minimum encodable coefficient
+    int max_qcoeff;          ///< maximum encodable coefficient
+    int ac_esc_length;       ///< num of bits needed to encode the longest esc
+    uint8_t *intra_ac_vlc_length;
+    uint8_t *intra_ac_vlc_last_length;
+    uint8_t *intra_chroma_ac_vlc_length;
+    uint8_t *intra_chroma_ac_vlc_last_length;
+    uint8_t *inter_ac_vlc_length;
+    uint8_t *inter_ac_vlc_last_length;
+    uint8_t *luma_dc_vlc_length;
+
+    int coded_score[12];
+
+    /** precomputed matrix (combine qscale and DCT renorm) */
+    int (*q_intra_matrix)[64];
+    int (*q_chroma_intra_matrix)[64];
+    int (*q_inter_matrix)[64];
+    /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
+    uint16_t (*q_intra_matrix16)[2][64];
+    uint16_t (*q_chroma_intra_matrix16)[2][64];
+    uint16_t (*q_inter_matrix16)[2][64];
+
+    /* noise reduction */
+    int (*dct_error_sum)[64];
+    int dct_count[2];
+    uint16_t (*dct_offset)[64];
+
+    /* statistics, used for 2-pass encoding */
+    int mv_bits;
+    int i_tex_bits;
+    int p_tex_bits;
+    int i_count;
+    int misc_bits; ///< cbp, mb_type
+    int last_bits; ///< temp var used for calculating the above vars
+
+    /* H.263 specific */
+    int mb_info;                   ///< interval for outputting info about mb offsets as side data
+    int prev_mb_info, last_mb_info;
+    int mb_info_size;
+    uint8_t *mb_info_ptr;
+
+    /* MPEG-4 specific */
+    PutBitContext tex_pb;          ///< used for data partitioned VOPs
+    PutBitContext pb2;             ///< used for data partitioned VOPs
+
+    /* MSMPEG4 specific */
+    int esc3_level_length;
+
+    /* MJPEG specific */
+    struct MJpegContext *mjpeg_ctx;
+    int esc_pos;
+
+    /* MPEG-1 specific */
+    int last_mv_dir;         ///< last mv_dir, used for B-frame encoding
+
+    /* RTP specific */
+    int rtp_mode;
+    int rtp_payload_size;
+
+    uint8_t *ptr_lastgob;
+
+    void (*encode_mb)(struct MPVEncContext *s, int16_t block[][64],
+                      int motion_x, int motion_y);
+
+    int (*dct_quantize)(struct MPVEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
+    void (*denoise_dct)(struct MPVEncContext *s, int16_t *block);
+
+    int mpv_flags;      ///< flags set by private options
+    int quantizer_noise_shaping;
+
+    me_cmp_func ildct_cmp[2]; ///< 0 = intra, 1 = non-intra
+    me_cmp_func n_sse_cmp[2]; ///< either SSE or NSSE cmp func
+    me_cmp_func sad_cmp[2];
+    me_cmp_func sse_cmp[2];
+    int (*sum_abs_dctelem)(const int16_t *block);
+
+    /// Bitfield containing information which frames to reconstruct.
+    int frame_reconstruction_bitfield;
+
+    int error_rate;
+
+    int intra_penalty;
+} MPVEncContext;
+
 typedef struct MPVMainEncContext {
-    MpegEncContext s;  ///< The main slicecontext
+    MPVEncContext s;               ///< The main slicecontext
 
     int scenechange_threshold;
 
@@ -112,14 +241,14 @@ typedef struct MPVMainEncContext {
     int16_t (*mv_table_base)[2];
 } MPVMainEncContext;
 
-static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)
+static inline const MPVMainEncContext *slice_to_mainenc(const MPVEncContext *s)
 {
 #ifdef NO_SLICE_THREADING_HERE
-    av_assert2(s->slice_context_count <= 1 &&
-               !(s->avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS));
+    av_assert2(s->c.slice_context_count <= 1 &&
+               !(s->c.avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS));
     return (const MPVMainEncContext*)s;
 #else
-    return s->encparent;
+    return s->c.encparent;
 #endif
 }
 
@@ -170,7 +299,7 @@ static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)
 { "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
 { "msad",   "Sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }
 
-#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
+#define FF_MPV_OFFSET(x) offsetof(MPVEncContext, x)
 #define FF_MPV_MAIN_OFFSET(x) offsetof(MPVMainEncContext, x)
 #define FF_RC_OFFSET(x)  offsetof(MPVMainEncContext, rc_context.x)
 #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
@@ -217,7 +346,7 @@ FF_MPV_OPT_CMP_FUNC, \
 
 #define FF_MPV_COMMON_MOTION_EST_OPTS \
 { "mv0",            "always try a mb with mv=<0,0>",                     0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 },    0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
-{"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(me.motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
+{"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(c.me.motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
 { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
@@ -233,21 +362,21 @@ int ff_mpv_encode_init(AVCodecContext *avctx);
 int ff_mpv_encode_end(AVCodecContext *avctx);
 int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
                           const AVFrame *frame, int *got_packet);
-int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase);
+int ff_mpv_reallocate_putbitbuffer(MPVEncContext *s, size_t threshold, size_t size_increase);
 
 void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
 
-void ff_dct_encode_init(MpegEncContext *s);
-void ff_mpvenc_dct_init_mips(MpegEncContext *s);
-void ff_dct_encode_init_x86(MpegEncContext *s);
+void ff_dct_encode_init(MPVEncContext *s);
+void ff_mpvenc_dct_init_mips(MPVEncContext *s);
+void ff_dct_encode_init_x86(MPVEncContext *s);
 
-void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[2][64],
+void ff_convert_matrix(MPVEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[2][64],
                        const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
 
 void ff_block_permute(int16_t *block, const uint8_t *permutation,
                       const uint8_t *scantable, int last);
 
-static inline int get_bits_diff(MpegEncContext *s)
+static inline int get_bits_diff(MPVEncContext *s)
 {
     const int bits = put_bits_count(&s->pb);
     const int last = s->last_bits;
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index bba0493f01..99e415303a 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -150,7 +150,7 @@ static av_cold void msmpeg4_encode_init_static(void)
 
 static void find_best_tables(MSMPEG4EncContext *ms)
 {
-    MpegEncContext *const s = &ms->m.s;
+    MPVEncContext *const s = &ms->m.s;
     int i;
     int best        = 0, best_size        = INT_MAX;
     int chroma_best = 0, best_chroma_size = INT_MAX;
@@ -174,7 +174,7 @@ static void find_best_tables(MSMPEG4EncContext *ms)
                     int intra_luma_count  = ms->ac_stats[1][0][level][run][last];
                     int intra_chroma_count= ms->ac_stats[1][1][level][run][last];
 
-                    if(s->pict_type==AV_PICTURE_TYPE_I){
+                    if(s->c.pict_type==AV_PICTURE_TYPE_I){
                         size       += intra_luma_count  *rl_length[i  ][level][run][last];
                         chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last];
                     }else{
@@ -196,16 +196,16 @@ static void find_best_tables(MSMPEG4EncContext *ms)
         }
     }
 
-    if(s->pict_type==AV_PICTURE_TYPE_P) chroma_best= best;
+    if(s->c.pict_type==AV_PICTURE_TYPE_P) chroma_best= best;
 
     memset(ms->ac_stats, 0, sizeof(ms->ac_stats));
 
     ms->rl_table_index        =        best;
     ms->rl_chroma_table_index = chroma_best;
 
-    if (s->pict_type != ms->m.last_non_b_pict_type) {
+    if (s->c.pict_type != ms->m.last_non_b_pict_type) {
         ms->rl_table_index= 2;
-        if(s->pict_type==AV_PICTURE_TYPE_I)
+        if(s->c.pict_type==AV_PICTURE_TYPE_I)
             ms->rl_chroma_table_index = 1;
         else
             ms->rl_chroma_table_index = 2;
@@ -217,15 +217,15 @@ static void find_best_tables(MSMPEG4EncContext *ms)
 static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
 {
     MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)m;
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
     find_best_tables(ms);
 
     align_put_bits(&s->pb);
-    put_bits(&s->pb, 2, s->pict_type - 1);
+    put_bits(&s->pb, 2, s->c.pict_type - 1);
 
-    put_bits(&s->pb, 5, s->qscale);
-    if (s->msmpeg4_version <= MSMP4_V2) {
+    put_bits(&s->pb, 5, s->c.qscale);
+    if (s->c.msmpeg4_version <= MSMP4_V2) {
         ms->rl_table_index = 2;
         ms->rl_chroma_table_index = 2;
     }
@@ -234,24 +234,24 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
     ms->mv_table_index   = 1; /* only if P-frame */
     ms->use_skip_mb_code = 1; /* only if P-frame */
     ms->per_mb_rl_table  = 0;
-    if (s->msmpeg4_version == MSMP4_WMV1)
-        s->inter_intra_pred = s->width * s->height < 320*240 &&
+    if (s->c.msmpeg4_version == MSMP4_WMV1)
+        s->c.inter_intra_pred = s->c.width * s->c.height < 320*240 &&
                               m->bit_rate  <= II_BITRATE     &&
-                              s->pict_type == AV_PICTURE_TYPE_P;
-    ff_dlog(s->avctx, "%d %"PRId64" %d %d %d\n", s->pict_type, m->bit_rate,
-            s->inter_intra_pred, s->width, s->height);
+                              s->c.pict_type == AV_PICTURE_TYPE_P;
+    ff_dlog(s->c.avctx, "%d %"PRId64" %d %d %d\n", s->c.pict_type, m->bit_rate,
+            s->c.inter_intra_pred, s->c.width, s->c.height);
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
-        s->slice_height= s->mb_height/1;
-        put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height);
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
+        s->c.slice_height = s->c.mb_height/1;
+        put_bits(&s->pb, 5, 0x16 + s->c.mb_height/s->c.slice_height);
 
-        if (s->msmpeg4_version == MSMP4_WMV1) {
+        if (s->c.msmpeg4_version == MSMP4_WMV1) {
             ff_msmpeg4_encode_ext_header(s);
             if (m->bit_rate > MBAC_BITRATE)
                 put_bits(&s->pb, 1, ms->per_mb_rl_table);
         }
 
-        if (s->msmpeg4_version > MSMP4_V2) {
+        if (s->c.msmpeg4_version > MSMP4_V2) {
             if (!ms->per_mb_rl_table){
                 ff_msmpeg4_code012(&s->pb, ms->rl_chroma_table_index);
                 ff_msmpeg4_code012(&s->pb, ms->rl_table_index);
@@ -262,10 +262,10 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
     } else {
         put_bits(&s->pb, 1, ms->use_skip_mb_code);
 
-        if (s->msmpeg4_version == MSMP4_WMV1 && m->bit_rate > MBAC_BITRATE)
+        if (s->c.msmpeg4_version == MSMP4_WMV1 && m->bit_rate > MBAC_BITRATE)
             put_bits(&s->pb, 1, ms->per_mb_rl_table);
 
-        if (s->msmpeg4_version > MSMP4_V2) {
+        if (s->c.msmpeg4_version > MSMP4_V2) {
             if (!ms->per_mb_rl_table)
                 ff_msmpeg4_code012(&s->pb, ms->rl_table_index);
 
@@ -281,18 +281,18 @@ static int msmpeg4_encode_picture_header(MPVMainEncContext *const m)
     return 0;
 }
 
-void ff_msmpeg4_encode_ext_header(MpegEncContext * s)
+void ff_msmpeg4_encode_ext_header(MPVEncContext *const s)
 {
     const MPVMainEncContext *const m = slice_to_mainenc(s);
     unsigned fps;
 
-    if (s->avctx->framerate.num > 0 && s->avctx->framerate.den > 0)
-        fps = s->avctx->framerate.num / s->avctx->framerate.den;
+    if (s->c.avctx->framerate.num > 0 && s->c.avctx->framerate.den > 0)
+        fps = s->c.avctx->framerate.num / s->c.avctx->framerate.den;
     else {
 FF_DISABLE_DEPRECATION_WARNINGS
-        fps = s->avctx->time_base.den / s->avctx->time_base.num
+        fps = s->c.avctx->time_base.den / s->c.avctx->time_base.num
 #if FF_API_TICKS_PER_FRAME
-            / FFMAX(s->avctx->ticks_per_frame, 1)
+            / FFMAX(s->c.avctx->ticks_per_frame, 1)
 #endif
             ;
 FF_ENABLE_DEPRECATION_WARNINGS
@@ -302,16 +302,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
     put_bits(&s->pb, 11, FFMIN(m->bit_rate / 1024, 2047));
 
-    if (s->msmpeg4_version >= MSMP4_V3)
-        put_bits(&s->pb, 1, s->flipflop_rounding);
+    if (s->c.msmpeg4_version >= MSMP4_V3)
+        put_bits(&s->pb, 1, s->c.flipflop_rounding);
     else
-        av_assert0(!s->flipflop_rounding);
+        av_assert0(!s->c.flipflop_rounding);
 }
 
 void ff_msmpeg4_encode_motion(MSMPEG4EncContext *const ms,
                                   int mx, int my)
 {
-    MpegEncContext *const s = &ms->m.s;
+    MPVEncContext *const s = &ms->m.s;
     const uint32_t *const mv_vector_table = mv_vector_tables[ms->mv_table_index];
     uint32_t code;
 
@@ -334,20 +334,21 @@ void ff_msmpeg4_encode_motion(MSMPEG4EncContext *const ms,
     put_bits(&s->pb, code & 0xff, code >> 8);
 }
 
-void ff_msmpeg4_handle_slices(MpegEncContext *s){
-    if (s->mb_x == 0) {
-        if (s->slice_height && (s->mb_y % s->slice_height) == 0) {
-            if (s->msmpeg4_version < MSMP4_WMV1) {
-                ff_mpeg4_clean_buffers(s);
+void ff_msmpeg4_handle_slices(MPVEncContext *const s)
+{
+    if (s->c.mb_x == 0) {
+        if (s->c.slice_height && (s->c.mb_y % s->c.slice_height) == 0) {
+            if (s->c.msmpeg4_version < MSMP4_WMV1) {
+                ff_mpeg4_clean_buffers(&s->c);
             }
-            s->first_slice_line = 1;
+            s->c.first_slice_line = 1;
         } else {
-            s->first_slice_line = 0;
+            s->c.first_slice_line = 0;
         }
     }
 }
 
-static void msmpeg4v2_encode_motion(MpegEncContext * s, int val)
+static void msmpeg4v2_encode_motion(MPVEncContext *const s, int val)
 {
     int range, bit_size, sign, code, bits;
 
@@ -355,7 +356,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val)
         /* zero vector; corresponds to ff_mvtab[0] */
         put_bits(&s->pb, 1, 0x1);
     } else {
-        bit_size = s->f_code - 1;
+        bit_size = s->c.f_code - 1;
         range = 1 << bit_size;
         if (val <= -64)
             val += 64;
@@ -379,7 +380,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val)
     }
 }
 
-static void msmpeg4_encode_mb(MpegEncContext *const s,
+static void msmpeg4_encode_mb(MPVEncContext *const s,
                               int16_t block[][64],
                               int motion_x, int motion_y)
 {
@@ -389,11 +390,11 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
 
     ff_msmpeg4_handle_slices(s);
 
-    if (!s->mb_intra) {
+    if (!s->c.mb_intra) {
         /* compute cbp */
         cbp = 0;
         for (i = 0; i < 6; i++) {
-            if (s->block_last_index[i] >= 0)
+            if (s->c.block_last_index[i] >= 0)
                 cbp |= 1 << (5 - i);
         }
         if (ms->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) {
@@ -407,7 +408,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
         if (ms->use_skip_mb_code)
             put_bits(&s->pb, 1, 0);     /* mb coded */
 
-        if (s->msmpeg4_version <= MSMP4_V2) {
+        if (s->c.msmpeg4_version <= MSMP4_V2) {
             put_bits(&s->pb,
                      ff_v2_mb_type[cbp&3][1],
                      ff_v2_mb_type[cbp&3][0]);
@@ -420,7 +421,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
 
             s->misc_bits += get_bits_diff(s);
 
-            ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+            ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
             msmpeg4v2_encode_motion(s, motion_x - pred_x);
             msmpeg4v2_encode_motion(s, motion_y - pred_y);
         }else{
@@ -431,7 +432,7 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
             s->misc_bits += get_bits_diff(s);
 
             /* motion vector */
-            ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+            ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
             ff_msmpeg4_encode_motion(ms, motion_x - pred_x,
                                      motion_y - pred_y);
         }
@@ -446,11 +447,11 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
         /* compute cbp */
         cbp = 0;
         for (int i = 0; i < 6; i++) {
-            int val = (s->block_last_index[i] >= 1);
+            int val = (s->c.block_last_index[i] >= 1);
             cbp |= val << (5 - i);
         }
-        if (s->msmpeg4_version <= MSMP4_V2) {
-            if (s->pict_type == AV_PICTURE_TYPE_I) {
+        if (s->c.msmpeg4_version <= MSMP4_V2) {
+            if (s->c.pict_type == AV_PICTURE_TYPE_I) {
                 put_bits(&s->pb,
                          ff_v2_intra_cbpc[cbp&3][1], ff_v2_intra_cbpc[cbp&3][0]);
             } else {
@@ -465,14 +466,14 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
                      ff_h263_cbpy_tab[cbp>>2][1],
                      ff_h263_cbpy_tab[cbp>>2][0]);
         }else{
-            if (s->pict_type == AV_PICTURE_TYPE_I) {
+            if (s->c.pict_type == AV_PICTURE_TYPE_I) {
                 /* compute coded_cbp; the 0x3 corresponds to chroma cbp;
                  * luma coded_cbp are set in the loop below */
                 coded_cbp = cbp & 0x3;
                 for (int i = 0; i < 4; i++) {
                     uint8_t *coded_block;
-                    int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block);
-                    int val = (s->block_last_index[i] >= 1);
+                    int pred = ff_msmpeg4_coded_block_pred(&s->c, i, &coded_block);
+                    int val = (s->c.block_last_index[i] >= 1);
                     *coded_block = val;
                     val ^= pred;
                     coded_cbp |= val << (5 - i);
@@ -488,9 +489,10 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
                          ff_table_mb_non_intra[cbp][0]);
             }
             put_bits(&s->pb, 1, 0);             /* no AC prediction yet */
-            if(s->inter_intra_pred){
-                s->h263_aic_dir=0;
-                put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]);
+            if (s->c.inter_intra_pred) {
+                s->c.h263_aic_dir = 0;
+                put_bits(&s->pb, ff_table_inter_intra[s->c.h263_aic_dir][1],
+                                 ff_table_inter_intra[s->c.h263_aic_dir][0]);
             }
         }
         s->misc_bits += get_bits_diff(s);
@@ -505,24 +507,24 @@ static void msmpeg4_encode_mb(MpegEncContext *const s,
 
 static void msmpeg4_encode_dc(MSMPEG4EncContext *const ms, int level, int n, int *dir_ptr)
 {
-    MpegEncContext *const s = &ms->m.s;
+    MPVEncContext *const s = &ms->m.s;
     int sign, code;
     int pred;
 
     int16_t *dc_val;
-    pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+    pred = ff_msmpeg4_pred_dc(&s->c, n, &dc_val, dir_ptr);
 
     /* update predictor */
     if (n < 4) {
-        *dc_val = level * s->y_dc_scale;
+        *dc_val = level * s->c.y_dc_scale;
     } else {
-        *dc_val = level * s->c_dc_scale;
+        *dc_val = level * s->c.c_dc_scale;
     }
 
     /* do the prediction */
     level -= pred;
 
-    if (s->msmpeg4_version <= MSMP4_V2) {
+    if (s->c.msmpeg4_version <= MSMP4_V2) {
         if (n < 4) {
             put_bits(&s->pb,
                      ff_v2_dc_lum_table[level + 256][1],
@@ -556,7 +558,7 @@ static void msmpeg4_encode_dc(MSMPEG4EncContext *const ms, int level, int n, int
 
 /* Encoding of a block; very similar to MPEG-4 except for a different
  * escape coding (same as H.263) and more VLC tables. */
-void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
+void ff_msmpeg4_encode_block(MPVEncContext *const s, int16_t * block, int n)
 {
     MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)s;
     int level, run, last, i, j, last_index;
@@ -565,7 +567,7 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
     const RLTable *rl;
     const uint8_t *scantable;
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         msmpeg4_encode_dc(ms, block[0], n, &dc_pred_dir);
         i = 1;
         if (n < 4) {
@@ -573,23 +575,23 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
         } else {
             rl = &ff_rl_table[3 + ms->rl_chroma_table_index];
         }
-        run_diff = s->msmpeg4_version >= MSMP4_WMV1;
-        scantable= s->intra_scantable.permutated;
+        run_diff = s->c.msmpeg4_version >= MSMP4_WMV1;
+        scantable= s->c.intra_scantable.permutated;
     } else {
         i = 0;
         rl = &ff_rl_table[3 + ms->rl_table_index];
-        run_diff = s->msmpeg4_version > MSMP4_V2;
-        scantable= s->inter_scantable.permutated;
+        run_diff = s->c.msmpeg4_version > MSMP4_V2;
+        scantable= s->c.inter_scantable.permutated;
     }
 
     /* recalculate block_last_index for M$ wmv1 */
-    if (s->msmpeg4_version >= MSMP4_WMV1 && s->block_last_index[n] > 0) {
+    if (s->c.msmpeg4_version >= MSMP4_WMV1 && s->c.block_last_index[n] > 0) {
         for(last_index=63; last_index>=0; last_index--){
             if(block[scantable[last_index]]) break;
         }
-        s->block_last_index[n]= last_index;
+        s->c.block_last_index[n]= last_index;
     }else
-        last_index = s->block_last_index[n];
+        last_index = s->c.block_last_index[n];
     /* AC coefs */
     last_non_zero = i - 1;
     for (; i <= last_index; i++) {
@@ -606,10 +608,10 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
             }
 
             if(level<=MAX_LEVEL && run<=MAX_RUN){
-                ms->ac_stats[s->mb_intra][n>3][level][run][last]++;
+                ms->ac_stats[s->c.mb_intra][n>3][level][run][last]++;
             }
 
-            ms->ac_stats[s->mb_intra][n > 3][40][63][0]++; //esc3 like
+            ms->ac_stats[s->c.mb_intra][n > 3][40][63][0]++; //esc3 like
 
             code = get_rl_index(rl, last, run, level);
             put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
@@ -629,7 +631,7 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
                     if (run1 < 0)
                         goto esc3;
                     code = get_rl_index(rl, last, run1+1, level);
-                    if (s->msmpeg4_version == MSMP4_WMV1 && code == rl->n)
+                    if (s->c.msmpeg4_version == MSMP4_WMV1 && code == rl->n)
                         goto esc3;
                     code = get_rl_index(rl, last, run1, level);
                     if (code == rl->n) {
@@ -637,12 +639,12 @@ void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
                         /* third escape */
                         put_bits(&s->pb, 1, 0);
                         put_bits(&s->pb, 1, last);
-                        if (s->msmpeg4_version >= MSMP4_WMV1) {
+                        if (s->c.msmpeg4_version >= MSMP4_WMV1) {
                             if (s->esc3_level_length == 0) {
                                 s->esc3_level_length = 8;
                                 ms->esc3_run_length  = 6;
                                 //ESCLVLSZ + ESCRUNSZ
-                                if(s->qscale<8)
+                                if(s->c.qscale<8)
                                     put_bits(&s->pb, 6, 3);
                                 else
                                     put_bits(&s->pb, 8, 3);
@@ -676,17 +678,17 @@ 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;
+    MPVEncContext *const s = &m->s;
     static AVOnce init_static_once = AV_ONCE_INIT;
 
-    ff_msmpeg4_common_init(s);
+    ff_msmpeg4_common_init(&s->c);
 
-    if (s->msmpeg4_version <= MSMP4_WMV1) {
+    if (s->c.msmpeg4_version <= MSMP4_WMV1) {
         m->encode_picture_header = msmpeg4_encode_picture_header;
         s->encode_mb             = msmpeg4_encode_mb;
     }
 
-    if (s->msmpeg4_version >= MSMP4_WMV1) {
+    if (s->c.msmpeg4_version >= MSMP4_WMV1) {
         s->min_qcoeff = -255;
         s->max_qcoeff =  255;
     }
diff --git a/libavcodec/msmpeg4enc.h b/libavcodec/msmpeg4enc.h
index bce1265bb5..167600f01f 100644
--- a/libavcodec/msmpeg4enc.h
+++ b/libavcodec/msmpeg4enc.h
@@ -41,16 +41,16 @@ typedef struct MSMPEG4EncContext {
     unsigned ac_stats[2][2][MAX_LEVEL + 1][MAX_RUN + 1][2];
 } MSMPEG4EncContext;
 
-static inline MSMPEG4EncContext *mpv_to_msmpeg4(MpegEncContext *s)
+static inline MSMPEG4EncContext *mpv_to_msmpeg4(MPVEncContext *s)
 {
     // Only legal because no MSMPEG-4 decoder uses slice-threading.
     return (MSMPEG4EncContext*)s;
 }
 
 void ff_msmpeg4_encode_init(MPVMainEncContext *m);
-void ff_msmpeg4_encode_ext_header(MpegEncContext *s);
-void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n);
-void ff_msmpeg4_handle_slices(MpegEncContext *s);
+void ff_msmpeg4_encode_ext_header(MPVEncContext *s);
+void ff_msmpeg4_encode_block(MPVEncContext * s, int16_t * block, int n);
+void ff_msmpeg4_handle_slices(MPVEncContext *s);
 void ff_msmpeg4_encode_motion(MSMPEG4EncContext *ms, int mx, int my);
 
 void ff_msmpeg4_code012(PutBitContext *pb, int n);
diff --git a/libavcodec/ppc/me_cmp.c b/libavcodec/ppc/me_cmp.c
index 90f21525d7..764e30da2a 100644
--- a/libavcodec/ppc/me_cmp.c
+++ b/libavcodec/ppc/me_cmp.c
@@ -51,7 +51,7 @@
     iv = vec_vsx_ld(1,  pix);\
 }
 #endif
-static int sad16_x2_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sad16_x2_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                             ptrdiff_t stride, int h)
 {
     int i;
@@ -91,7 +91,7 @@ static int sad16_x2_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_
     return s;
 }
 
-static int sad16_y2_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sad16_y2_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                             ptrdiff_t stride, int h)
 {
     int i;
@@ -141,7 +141,7 @@ static int sad16_y2_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_
     return s;
 }
 
-static int sad16_xy2_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sad16_xy2_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                              ptrdiff_t stride, int h)
 {
     int i;
@@ -230,7 +230,7 @@ static int sad16_xy2_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8
     return s;
 }
 
-static int sad16_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sad16_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h)
 {
     int i;
@@ -265,7 +265,7 @@ static int sad16_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *
     return s;
 }
 
-static int sad8_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sad8_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h)
 {
     int i;
@@ -309,7 +309,7 @@ static int sad8_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *p
 
 /* Sum of Squared Errors for an 8x8 block, AltiVec-enhanced.
  * It's the sad8_altivec code above w/ squaring added. */
-static int sse8_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sse8_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                         ptrdiff_t stride, int h)
 {
     int i;
@@ -354,7 +354,7 @@ static int sse8_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *p
 
 /* Sum of Squared Errors for a 16x16 block, AltiVec-enhanced.
  * It's the sad16_altivec code above w/ squaring added. */
-static int sse16_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+static int sse16_altivec(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h)
 {
     int i;
@@ -392,7 +392,7 @@ static int sse16_altivec(MpegEncContext *v, const uint8_t *pix1, const uint8_t *
     return s;
 }
 
-static int hadamard8_diff8x8_altivec(MpegEncContext *s, const uint8_t *dst,
+static int hadamard8_diff8x8_altivec(MPVEncContext *s, const uint8_t *dst,
                                      const uint8_t *src, ptrdiff_t stride, int h)
 {
     int __attribute__((aligned(16))) sum;
@@ -518,7 +518,7 @@ static int hadamard8_diff8x8_altivec(MpegEncContext *s, const uint8_t *dst,
  * On the 970, the hand-made RA is still a win (around 690 vs. around 780),
  * but xlc goes to around 660 on the regular C code...
  */
-static int hadamard8_diff16x8_altivec(MpegEncContext *s, const uint8_t *dst,
+static int hadamard8_diff16x8_altivec(MPVEncContext *s, const uint8_t *dst,
                                       const uint8_t *src, ptrdiff_t stride, int h)
 {
     int __attribute__((aligned(16))) sum;
@@ -709,7 +709,7 @@ static int hadamard8_diff16x8_altivec(MpegEncContext *s, const uint8_t *dst,
     return sum;
 }
 
-static int hadamard8_diff16_altivec(MpegEncContext *s, const uint8_t *dst,
+static int hadamard8_diff16_altivec(MPVEncContext *s, const uint8_t *dst,
                                     const uint8_t *src, ptrdiff_t stride, int h)
 {
     int score = hadamard8_diff16x8_altivec(s, dst, src, stride, 8);
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index b131f61b70..d60e14252e 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -37,20 +37,20 @@
 
 void ff_write_pass1_stats(MPVMainEncContext *const m)
 {
-    const MpegEncContext *const s = &m->s;
-    snprintf(s->avctx->stats_out, 256,
+    const MPVEncContext *const s = &m->s;
+    snprintf(s->c.avctx->stats_out, 256,
              "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d "
              "fcode:%d bcode:%d mc-var:%"PRId64" var:%"PRId64" icount:%d hbits:%d;\n",
-             s->cur_pic.ptr->display_picture_number,
-             s->cur_pic.ptr->coded_picture_number,
-             s->pict_type,
-             s->cur_pic.ptr->f->quality,
+             s->c.cur_pic.ptr->display_picture_number,
+             s->c.cur_pic.ptr->coded_picture_number,
+             s->c.pict_type,
+             s->c.cur_pic.ptr->f->quality,
              s->i_tex_bits,
              s->p_tex_bits,
              s->mv_bits,
              s->misc_bits,
-             s->f_code,
-             s->b_code,
+             s->c.f_code,
+             s->c.b_code,
              m->mc_mb_var_sum,
              m->mb_var_sum,
              s->i_count,
@@ -104,9 +104,9 @@ static double bits2qp_cb(void *rce, double qp)
 
 static double get_diff_limited_q(MPVMainEncContext *m, const RateControlEntry *rce, double q)
 {
-    MpegEncContext     *const   s = &m->s;
+    MPVEncContext      *const   s = &m->s;
     RateControlContext *const rcc = &m->rc_context;
-    AVCodecContext *a         = s->avctx;
+    AVCodecContext     *const   a = s->c.avctx;
     const int pict_type       = rce->new_pict_type;
     const double last_p_q     = rcc->last_qscale_for[AV_PICTURE_TYPE_P];
     const double last_non_b_q = rcc->last_qscale_for[rcc->last_non_b_pict_type];
@@ -144,7 +144,7 @@ static double get_diff_limited_q(MPVMainEncContext *m, const RateControlEntry *r
  */
 static void get_qminmax(int *qmin_ret, int *qmax_ret, MPVMainEncContext *const m, int pict_type)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int qmin = m->lmin;
     int qmax = m->lmax;
 
@@ -152,12 +152,12 @@ static void get_qminmax(int *qmin_ret, int *qmax_ret, MPVMainEncContext *const m
 
     switch (pict_type) {
     case AV_PICTURE_TYPE_B:
-        qmin = (int)(qmin * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5);
-        qmax = (int)(qmax * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5);
+        qmin = (int)(qmin * FFABS(s->c.avctx->b_quant_factor) + s->c.avctx->b_quant_offset + 0.5);
+        qmax = (int)(qmax * FFABS(s->c.avctx->b_quant_factor) + s->c.avctx->b_quant_offset + 0.5);
         break;
     case AV_PICTURE_TYPE_I:
-        qmin = (int)(qmin * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5);
-        qmax = (int)(qmax * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5);
+        qmin = (int)(qmin * FFABS(s->c.avctx->i_quant_factor) + s->c.avctx->i_quant_offset + 0.5);
+        qmax = (int)(qmax * FFABS(s->c.avctx->i_quant_factor) + s->c.avctx->i_quant_offset + 0.5);
         break;
     }
 
@@ -174,12 +174,12 @@ static void get_qminmax(int *qmin_ret, int *qmax_ret, MPVMainEncContext *const m
 static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *rce,
                             double q, int frame_num)
 {
-    MpegEncContext     *const   s = &m->s;
+    MPVEncContext      *const   s = &m->s;
     RateControlContext *const rcc = &m->rc_context;
-    const double buffer_size = s->avctx->rc_buffer_size;
-    const double fps         = get_fps(s->avctx);
-    const double min_rate    = s->avctx->rc_min_rate / fps;
-    const double max_rate    = s->avctx->rc_max_rate / fps;
+    const double buffer_size = s->c.avctx->rc_buffer_size;
+    const double fps         = get_fps(s->c.avctx);
+    const double min_rate    = s->c.avctx->rc_min_rate / fps;
+    const double max_rate    = s->c.avctx->rc_max_rate / fps;
     const int pict_type      = rce->new_pict_type;
     int qmin, qmax;
 
@@ -206,11 +206,11 @@ static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *
 
             q_limit = bits2qp(rce,
                               FFMAX((min_rate - buffer_size + rcc->buffer_index) *
-                                    s->avctx->rc_min_vbv_overflow_use, 1));
+                                    s->c.avctx->rc_min_vbv_overflow_use, 1));
 
             if (q > q_limit) {
-                if (s->avctx->debug & FF_DEBUG_RC)
-                    av_log(s->avctx, AV_LOG_DEBUG,
+                if (s->c.avctx->debug & FF_DEBUG_RC)
+                    av_log(s->c.avctx, AV_LOG_DEBUG,
                            "limiting QP %f -> %f\n", q, q_limit);
                 q = q_limit;
             }
@@ -226,17 +226,17 @@ static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *
 
             q_limit = bits2qp(rce,
                               FFMAX(rcc->buffer_index *
-                                    s->avctx->rc_max_available_vbv_use,
+                                    s->c.avctx->rc_max_available_vbv_use,
                                     1));
             if (q < q_limit) {
-                if (s->avctx->debug & FF_DEBUG_RC)
-                    av_log(s->avctx, AV_LOG_DEBUG,
+                if (s->c.avctx->debug & FF_DEBUG_RC)
+                    av_log(s->c.avctx, AV_LOG_DEBUG,
                            "limiting QP %f -> %f\n", q, q_limit);
                 q = q_limit;
             }
         }
     }
-    ff_dlog(s->avctx, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
+    ff_dlog(s->c.avctx, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
             q, max_rate, min_rate, buffer_size, rcc->buffer_index,
             rcc->buffer_aggressivity);
     if (rcc->qsquish == 0.0 || qmin == qmax) {
@@ -266,11 +266,11 @@ static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *
 static double get_qscale(MPVMainEncContext *const m, RateControlEntry *rce,
                          double rate_factor, int frame_num)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext  *const s = &m->s;
     RateControlContext *rcc = &m->rc_context;
-    AVCodecContext *a       = s->avctx;
+    AVCodecContext *const a = s->c.avctx;
     const int pict_type     = rce->new_pict_type;
-    const double mb_num     = s->mb_num;
+    const double mb_num     = s->c.mb_num;
     double q, bits;
     int i;
 
@@ -300,7 +300,7 @@ static double get_qscale(MPVMainEncContext *const m, RateControlEntry *rce,
 
     bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce);
     if (isnan(bits)) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", rcc->rc_eq);
+        av_log(s->c.avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", rcc->rc_eq);
         return -1;
     }
 
@@ -311,8 +311,8 @@ static double get_qscale(MPVMainEncContext *const m, RateControlEntry *rce,
     bits += 1.0; // avoid 1/0 issues
 
     /* user override */
-    for (i = 0; i < s->avctx->rc_override_count; i++) {
-        RcOverride *rco = s->avctx->rc_override;
+    for (i = 0; i < s->c.avctx->rc_override_count; i++) {
+        RcOverride *rco = s->c.avctx->rc_override;
         if (rco[i].start_frame > frame_num)
             continue;
         if (rco[i].end_frame < frame_num)
@@ -327,10 +327,10 @@ static double get_qscale(MPVMainEncContext *const m, RateControlEntry *rce,
     q = bits2qp(rce, bits);
 
     /* I/B difference */
-    if (pict_type == AV_PICTURE_TYPE_I && s->avctx->i_quant_factor < 0.0)
-        q = -q * s->avctx->i_quant_factor + s->avctx->i_quant_offset;
-    else if (pict_type == AV_PICTURE_TYPE_B && s->avctx->b_quant_factor < 0.0)
-        q = -q * s->avctx->b_quant_factor + s->avctx->b_quant_offset;
+    if (pict_type == AV_PICTURE_TYPE_I && s->c.avctx->i_quant_factor < 0.0)
+        q = -q * s->c.avctx->i_quant_factor + s->c.avctx->i_quant_offset;
+    else if (pict_type == AV_PICTURE_TYPE_B && s->c.avctx->b_quant_factor < 0.0)
+        q = -q * s->c.avctx->b_quant_factor + s->c.avctx->b_quant_offset;
     if (q < 1)
         q = 1;
 
@@ -340,10 +340,10 @@ static double get_qscale(MPVMainEncContext *const m, RateControlEntry *rce,
 static int init_pass2(MPVMainEncContext *const m)
 {
     RateControlContext *const rcc = &m->rc_context;
-    MpegEncContext     *const   s = &m->s;
-    AVCodecContext *a       = s->avctx;
+    MPVEncContext      *const   s = &m->s;
+    AVCodecContext     *const   a = s->c.avctx;
     int i, toobig;
-    AVRational fps         = get_fpsQ(s->avctx);
+    AVRational fps         = get_fpsQ(s->c.avctx);
     double complexity[5]   = { 0 }; // approximate bits at quant=1
     uint64_t const_bits[5] = { 0 }; // quantizer independent bits
     uint64_t all_const_bits;
@@ -376,7 +376,7 @@ static int init_pass2(MPVMainEncContext *const m)
                      const_bits[AV_PICTURE_TYPE_B];
 
     if (all_available_bits < all_const_bits) {
-        av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n");
+        av_log(s->c.avctx, AV_LOG_ERROR, "requested bitrate is too low\n");
         return -1;
     }
 
@@ -393,7 +393,7 @@ static int init_pass2(MPVMainEncContext *const m)
         expected_bits = 0;
         rate_factor  += step;
 
-        rcc->buffer_index = s->avctx->rc_buffer_size / 2;
+        rcc->buffer_index = s->c.avctx->rc_buffer_size / 2;
 
         /* find qscale */
         for (i = 0; i < rcc->num_entries; i++) {
@@ -453,7 +453,7 @@ static int init_pass2(MPVMainEncContext *const m)
             expected_bits     += bits;
         }
 
-        ff_dlog(s->avctx,
+        ff_dlog(s->c.avctx,
                 "expected_bits: %f all_available_bits: %d rate_factor: %f\n",
                 expected_bits, (int)all_available_bits, rate_factor);
         if (expected_bits > all_available_bits) {
@@ -467,32 +467,32 @@ static int init_pass2(MPVMainEncContext *const m)
     /* check bitrate calculations and print info */
     qscale_sum = 0.0;
     for (i = 0; i < rcc->num_entries; i++) {
-        ff_dlog(s->avctx, "[lavc rc] entry[%d].new_qscale = %.3f  qp = %.3f\n",
+        ff_dlog(s->c.avctx, "[lavc rc] entry[%d].new_qscale = %.3f  qp = %.3f\n",
                 i,
                 rcc->entry[i].new_qscale,
                 rcc->entry[i].new_qscale / FF_QP2LAMBDA);
         qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA,
-                              s->avctx->qmin, s->avctx->qmax);
+                              s->c.avctx->qmin, s->c.avctx->qmax);
     }
     av_assert0(toobig <= 40);
-    av_log(s->avctx, AV_LOG_DEBUG,
+    av_log(s->c.avctx, AV_LOG_DEBUG,
            "[lavc rc] requested bitrate: %"PRId64" bps  expected bitrate: %"PRId64" bps\n",
            m->bit_rate,
            (int64_t)(expected_bits / ((double)all_available_bits / m->bit_rate)));
-    av_log(s->avctx, AV_LOG_DEBUG,
+    av_log(s->c.avctx, AV_LOG_DEBUG,
            "[lavc rc] estimated target average qp: %.3f\n",
            (float)qscale_sum / rcc->num_entries);
     if (toobig == 0) {
-        av_log(s->avctx, AV_LOG_INFO,
+        av_log(s->c.avctx, AV_LOG_INFO,
                "[lavc rc] Using all of requested bitrate is not "
                "necessary for this video with these parameters.\n");
     } else if (toobig == 40) {
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(s->c.avctx, AV_LOG_ERROR,
                "[lavc rc] Error: bitrate too low for this video "
                "with these parameters.\n");
         return -1;
     } else if (fabs(expected_bits / all_available_bits - 1.0) > 0.01) {
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(s->c.avctx, AV_LOG_ERROR,
                "[lavc rc] Error: 2pass curve failed to converge\n");
         return -1;
     }
@@ -502,7 +502,7 @@ static int init_pass2(MPVMainEncContext *const m)
 
 av_cold int ff_rate_control_init(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext  *const s = &m->s;
     RateControlContext *rcc = &m->rc_context;
     int i, res;
     static const char * const const_names[] = {
@@ -540,19 +540,19 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
     };
     emms_c();
 
-    if (!s->avctx->rc_max_available_vbv_use && s->avctx->rc_buffer_size) {
-        if (s->avctx->rc_max_rate) {
-            s->avctx->rc_max_available_vbv_use = av_clipf(s->avctx->rc_max_rate/(s->avctx->rc_buffer_size*get_fps(s->avctx)), 1.0/3, 1.0);
+    if (!s->c.avctx->rc_max_available_vbv_use && s->c.avctx->rc_buffer_size) {
+        if (s->c.avctx->rc_max_rate) {
+            s->c.avctx->rc_max_available_vbv_use = av_clipf(s->c.avctx->rc_max_rate/(s->c.avctx->rc_buffer_size*get_fps(s->c.avctx)), 1.0/3, 1.0);
         } else
-            s->avctx->rc_max_available_vbv_use = 1.0;
+            s->c.avctx->rc_max_available_vbv_use = 1.0;
     }
 
     res = av_expr_parse(&rcc->rc_eq_eval,
                         rcc->rc_eq ? rcc->rc_eq : "tex^qComp",
                         const_names, func1_names, func1,
-                        NULL, NULL, 0, s->avctx);
+                        NULL, NULL, 0, s->c.avctx);
     if (res < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", rcc->rc_eq);
+        av_log(s->c.avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", rcc->rc_eq);
         return res;
     }
 
@@ -569,16 +569,16 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
 
         rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5;
     }
-    rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy;
+    rcc->buffer_index = s->c.avctx->rc_initial_buffer_occupancy;
     if (!rcc->buffer_index)
-        rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4;
+        rcc->buffer_index = s->c.avctx->rc_buffer_size * 3 / 4;
 
-    if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
+    if (s->c.avctx->flags & AV_CODEC_FLAG_PASS2) {
         int i;
         char *p;
 
         /* find number of pics */
-        p = s->avctx->stats_in;
+        p = s->c.avctx->stats_in;
         for (i = -1; p; i++)
             p = strchr(p + 1, ';');
         i += m->max_b_frames;
@@ -596,12 +596,12 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
 
             rce->pict_type  = rce->new_pict_type = AV_PICTURE_TYPE_P;
             rce->qscale     = rce->new_qscale    = FF_QP2LAMBDA * 2;
-            rce->misc_bits  = s->mb_num + 10;
-            rce->mb_var_sum = s->mb_num * 100;
+            rce->misc_bits  = s->c.mb_num + 10;
+            rce->mb_var_sum = s->c.mb_num * 100;
         }
 
         /* read stats */
-        p = s->avctx->stats_in;
+        p = s->c.avctx->stats_in;
         for (i = 0; i < rcc->num_entries - m->max_b_frames; i++) {
             RateControlEntry *rce;
             int picture_number;
@@ -630,7 +630,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
                         &rce->mc_mb_var_sum, &rce->mb_var_sum,
                         &rce->i_count, &rce->header_bits);
             if (e != 13) {
-                av_log(s->avctx, AV_LOG_ERROR,
+                av_log(s->c.avctx, AV_LOG_ERROR,
                        "statistics are damaged at line %d, parser out=%d\n",
                        i, e);
                 return -1;
@@ -644,21 +644,21 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
             return res;
     }
 
-    if (!(s->avctx->flags & AV_CODEC_FLAG_PASS2)) {
+    if (!(s->c.avctx->flags & AV_CODEC_FLAG_PASS2)) {
         rcc->short_term_qsum   = 0.001;
         rcc->short_term_qcount = 0.001;
 
         rcc->pass1_rc_eq_output_sum = 0.001;
         rcc->pass1_wanted_bits      = 0.001;
 
-        if (s->avctx->qblur > 1.0) {
-            av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n");
+        if (s->c.avctx->qblur > 1.0) {
+            av_log(s->c.avctx, AV_LOG_ERROR, "qblur too large\n");
             return -1;
         }
         /* init stuff with the user specified complexity */
         if (rcc->initial_cplx) {
             for (i = 0; i < 60 * 30; i++) {
-                double bits = rcc->initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
+                double bits = rcc->initial_cplx * (i / 10000.0 + 1.0) * s->c.mb_num;
                 RateControlEntry rce;
 
                 if (i % ((m->gop_size + 3) / 4) == 0)
@@ -669,16 +669,16 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
                     rce.pict_type = AV_PICTURE_TYPE_P;
 
                 rce.new_pict_type = rce.pict_type;
-                rce.mc_mb_var_sum = bits * s->mb_num / 100000;
-                rce.mb_var_sum    = s->mb_num;
+                rce.mc_mb_var_sum = bits * s->c.mb_num / 100000;
+                rce.mb_var_sum    = s->c.mb_num;
 
                 rce.qscale    = FF_QP2LAMBDA * 2;
                 rce.f_code    = 2;
                 rce.b_code    = 1;
                 rce.misc_bits = 1;
 
-                if (s->pict_type == AV_PICTURE_TYPE_I) {
-                    rce.i_count    = s->mb_num;
+                if (s->c.pict_type == AV_PICTURE_TYPE_I) {
+                    rce.i_count    = s->c.mb_num;
                     rce.i_tex_bits = bits;
                     rce.p_tex_bits = 0;
                     rce.mv_bits    = 0;
@@ -696,13 +696,13 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m)
                 get_qscale(m, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);
 
                 // FIXME misbehaves a little for variable fps
-                rcc->pass1_wanted_bits += m->bit_rate / get_fps(s->avctx);
+                rcc->pass1_wanted_bits += m->bit_rate / get_fps(s->c.avctx);
             }
         }
     }
 
     if (s->adaptive_quant) {
-        unsigned mb_array_size = s->mb_stride * s->mb_height;
+        unsigned mb_array_size = s->c.mb_stride * s->c.mb_height;
 
         rcc->cplx_tab = av_malloc_array(mb_array_size, 2 * sizeof(rcc->cplx_tab));
         if (!rcc->cplx_tab)
@@ -726,14 +726,14 @@ av_cold void ff_rate_control_uninit(RateControlContext *rcc)
 
 int ff_vbv_update(MPVMainEncContext *m, int frame_size)
 {
-    MpegEncContext     *const   s = &m->s;
+    MPVEncContext      *const   s = &m->s;
     RateControlContext *const rcc = &m->rc_context;
-    const double fps        = get_fps(s->avctx);
-    const int buffer_size   = s->avctx->rc_buffer_size;
-    const double min_rate   = s->avctx->rc_min_rate / fps;
-    const double max_rate   = s->avctx->rc_max_rate / fps;
+    const double fps        = get_fps(s->c.avctx);
+    const int buffer_size   = s->c.avctx->rc_buffer_size;
+    const double min_rate   = s->c.avctx->rc_min_rate / fps;
+    const double max_rate   = s->c.avctx->rc_max_rate / fps;
 
-    ff_dlog(s->avctx, "%d %f %d %f %f\n",
+    ff_dlog(s->c.avctx, "%d %f %d %f %f\n",
             buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
 
     if (buffer_size) {
@@ -741,9 +741,9 @@ int ff_vbv_update(MPVMainEncContext *m, int frame_size)
 
         rcc->buffer_index -= frame_size;
         if (rcc->buffer_index < 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");
-            if (frame_size > max_rate && s->qscale == s->avctx->qmax) {
-                av_log(s->avctx, AV_LOG_ERROR, "max bitrate possibly too small or try trellis with large lmax or increase qmax\n");
+            av_log(s->c.avctx, AV_LOG_ERROR, "rc buffer underflow\n");
+            if (frame_size > max_rate && s->c.qscale == s->c.avctx->qmax) {
+                av_log(s->c.avctx, AV_LOG_ERROR, "max bitrate possibly too small or try trellis with large lmax or increase qmax\n");
             }
             rcc->buffer_index = 0;
         }
@@ -754,12 +754,12 @@ int ff_vbv_update(MPVMainEncContext *m, int frame_size)
         if (rcc->buffer_index > buffer_size) {
             int stuffing = ceil((rcc->buffer_index - buffer_size) / 8);
 
-            if (stuffing < 4 && s->codec_id == AV_CODEC_ID_MPEG4)
+            if (stuffing < 4 && s->c.codec_id == AV_CODEC_ID_MPEG4)
                 stuffing = 4;
             rcc->buffer_index -= 8 * stuffing;
 
-            if (s->avctx->debug & FF_DEBUG_RC)
-                av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);
+            if (s->c.avctx->debug & FF_DEBUG_RC)
+                av_log(s->c.avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);
 
             return stuffing;
         }
@@ -787,31 +787,30 @@ static void update_predictor(Predictor *p, double q, double var, double size)
 static void adaptive_quantization(RateControlContext *const rcc,
                                   MPVMainEncContext *const m, double q)
 {
-    MpegEncContext *const s = &m->s;
-    int i;
-    const float lumi_masking         = s->avctx->lumi_masking / (128.0 * 128.0);
-    const float dark_masking         = s->avctx->dark_masking / (128.0 * 128.0);
-    const float temp_cplx_masking    = s->avctx->temporal_cplx_masking;
-    const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
-    const float p_masking            = s->avctx->p_masking;
+    MPVEncContext *const s = &m->s;
+    const float lumi_masking         = s->c.avctx->lumi_masking / (128.0 * 128.0);
+    const float dark_masking         = s->c.avctx->dark_masking / (128.0 * 128.0);
+    const float temp_cplx_masking    = s->c.avctx->temporal_cplx_masking;
+    const float spatial_cplx_masking = s->c.avctx->spatial_cplx_masking;
+    const float p_masking            = s->c.avctx->p_masking;
     const float border_masking       = m->border_masking;
     float bits_sum                   = 0.0;
     float cplx_sum                   = 0.0;
     float *cplx_tab                  = rcc->cplx_tab;
     float *bits_tab                  = rcc->bits_tab;
-    const int qmin                   = s->avctx->mb_lmin;
-    const int qmax                   = s->avctx->mb_lmax;
-    const int mb_width               = s->mb_width;
-    const int mb_height              = s->mb_height;
+    const int qmin                   = s->c.avctx->mb_lmin;
+    const int qmax                   = s->c.avctx->mb_lmax;
+    const int mb_width               = s->c.mb_width;
+    const int mb_height              = s->c.mb_height;
 
-    for (i = 0; i < s->mb_num; i++) {
-        const int mb_xy = s->mb_index2xy[i];
+    for (int i = 0; i < s->c.mb_num; i++) {
+        const int mb_xy = s->c.mb_index2xy[i];
         float temp_cplx = sqrt(s->mc_mb_var[mb_xy]); // FIXME merge in pow()
         float spat_cplx = sqrt(s->mb_var[mb_xy]);
         const int lumi  = s->mb_mean[mb_xy];
         float bits, cplx, factor;
-        int mb_x = mb_xy % s->mb_stride;
-        int mb_y = mb_xy / s->mb_stride;
+        int mb_x = mb_xy % s->c.mb_stride;
+        int mb_y = mb_xy / s->c.mb_stride;
         int mb_distance;
         float mb_factor = 0.0;
         if (spat_cplx < 4)
@@ -865,7 +864,7 @@ static void adaptive_quantization(RateControlContext *const rcc,
     /* handle qmin/qmax clipping */
     if (s->mpv_flags & FF_MPV_FLAG_NAQ) {
         float factor = bits_sum / cplx_sum;
-        for (i = 0; i < s->mb_num; i++) {
+        for (int i = 0; i < s->c.mb_num; i++) {
             float newq = q * cplx_tab[i] / bits_tab[i];
             newq *= factor;
 
@@ -883,8 +882,8 @@ static void adaptive_quantization(RateControlContext *const rcc,
             cplx_sum = 0.001;
     }
 
-    for (i = 0; i < s->mb_num; i++) {
-        const int mb_xy = s->mb_index2xy[i];
+    for (int i = 0; i < s->c.mb_num; i++) {
+        const int mb_xy = s->c.mb_index2xy[i];
         float newq      = q * cplx_tab[i] / bits_tab[i];
         int intq;
 
@@ -904,39 +903,39 @@ static void adaptive_quantization(RateControlContext *const rcc,
 
 void ff_get_2pass_fcode(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     const RateControlContext *rcc = &m->rc_context;
-    const RateControlEntry   *rce = &rcc->entry[s->picture_number];
+    const RateControlEntry   *rce = &rcc->entry[s->c.picture_number];
 
-    s->f_code = rce->f_code;
-    s->b_code = rce->b_code;
+    s->c.f_code = rce->f_code;
+    s->c.b_code = rce->b_code;
 }
 
 // FIXME rd or at least approx for dquant
 
 float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext  *const s = &m->s;
     RateControlContext *rcc = &m->rc_context;
+    AVCodecContext *const a = s->c.avctx;
     float q;
     int qmin, qmax;
     float br_compensation;
     double diff;
     double short_term_q;
     double fps;
-    int picture_number = s->picture_number;
+    int picture_number = s->c.picture_number;
     int64_t wanted_bits;
-    AVCodecContext *a       = s->avctx;
     RateControlEntry local_rce, *rce;
     double bits;
     double rate_factor;
     int64_t var;
-    const int pict_type = s->pict_type;
+    const int pict_type = s->c.pict_type;
     emms_c();
 
     get_qminmax(&qmin, &qmax, m, pict_type);
 
-    fps = get_fps(s->avctx);
+    fps = get_fps(s->c.avctx);
     /* update predictors */
     if (picture_number > 2 && !dry_run) {
         const int64_t last_var =
@@ -949,10 +948,10 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
                          m->frame_bits - m->stuffing_bits);
     }
 
-    if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
+    if (s->c.avctx->flags & AV_CODEC_FLAG_PASS2) {
         av_assert0(picture_number >= 0);
         if (picture_number >= rcc->num_entries) {
-            av_log(s->avctx, AV_LOG_ERROR, "Input is longer than 2-pass log file\n");
+            av_log(s->c.avctx, AV_LOG_ERROR, "Input is longer than 2-pass log file\n");
             return -1;
         }
         rce         = &rcc->entry[picture_number];
@@ -965,17 +964,17 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
         /* FIXME add a dts field to AVFrame and ensure it is set and use it
          * here instead of reordering but the reordering is simpler for now
          * until H.264 B-pyramid must be handled. */
-        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-            dts_pic = s->cur_pic.ptr;
+        if (s->c.pict_type == AV_PICTURE_TYPE_B || s->c.low_delay)
+            dts_pic = s->c.cur_pic.ptr;
         else
-            dts_pic = s->last_pic.ptr;
+            dts_pic = s->c.last_pic.ptr;
 
         if (!dts_pic || dts_pic->f->pts == AV_NOPTS_VALUE)
             wanted_bits_double = m->bit_rate * (double)picture_number / fps;
         else
             wanted_bits_double = m->bit_rate * (double)dts_pic->f->pts / fps;
         if (wanted_bits_double > INT64_MAX) {
-            av_log(s->avctx, AV_LOG_WARNING, "Bits exceed 64bit range\n");
+            av_log(s->c.avctx, AV_LOG_WARNING, "Bits exceed 64bit range\n");
             wanted_bits = INT64_MAX;
         } else
             wanted_bits = (int64_t)wanted_bits_double;
@@ -989,12 +988,12 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
     var = pict_type == AV_PICTURE_TYPE_I ? m->mb_var_sum : m->mc_mb_var_sum;
 
     short_term_q = 0; /* avoid warning */
-    if (s->avctx->flags & AV_CODEC_FLAG_PASS2) {
+    if (s->c.avctx->flags & AV_CODEC_FLAG_PASS2) {
         if (pict_type != AV_PICTURE_TYPE_I)
             av_assert0(pict_type == rce->new_pict_type);
 
         q = rce->new_qscale / br_compensation;
-        ff_dlog(s->avctx, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale,
+        ff_dlog(s->c.avctx, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale,
                 br_compensation, m->frame_bits, var, pict_type);
     } else {
         rce->pict_type     =
@@ -1002,13 +1001,13 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
         rce->mc_mb_var_sum = m->mc_mb_var_sum;
         rce->mb_var_sum    = m->mb_var_sum;
         rce->qscale        = FF_QP2LAMBDA * 2;
-        rce->f_code        = s->f_code;
-        rce->b_code        = s->b_code;
+        rce->f_code        = s->c.f_code;
+        rce->b_code        = s->c.b_code;
         rce->misc_bits     = 1;
 
         bits = predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
         if (pict_type == AV_PICTURE_TYPE_I) {
-            rce->i_count    = s->mb_num;
+            rce->i_count    = s->c.mb_num;
             rce->i_tex_bits = bits;
             rce->p_tex_bits = 0;
             rce->mv_bits    = 0;
@@ -1052,8 +1051,8 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
         av_assert0(q > 0.0);
     }
 
-    if (s->avctx->debug & FF_DEBUG_RC) {
-        av_log(s->avctx, AV_LOG_DEBUG,
+    if (s->c.avctx->debug & FF_DEBUG_RC) {
+        av_log(s->c.avctx, AV_LOG_DEBUG,
                "%c qp:%d<%2.1f<%d %d want:%"PRId64" total:%"PRId64" comp:%f st_q:%2.2f "
                "size:%d var:%"PRId64"/%"PRId64" br:%"PRId64" fps:%d\n",
                av_get_picture_type_char(pict_type),
diff --git a/libavcodec/riscv/me_cmp_init.c b/libavcodec/riscv/me_cmp_init.c
index f246e55cb1..f22dbff7f4 100644
--- a/libavcodec/riscv/me_cmp_init.c
+++ b/libavcodec/riscv/me_cmp_init.c
@@ -24,55 +24,55 @@
 #include "libavutil/cpu.h"
 #include "libavutil/riscv/cpu.h"
 #include "libavcodec/me_cmp.h"
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideoenc.h"
 
-int ff_pix_abs16_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                               ptrdiff_t stride, int h);
-int ff_pix_abs8_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                              ptrdiff_t stride, int h);
-int ff_pix_abs16_x2_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_x2_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_pix_abs8_x2_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_x2_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_pix_abs16_y2_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs16_y2_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h);
-int ff_pix_abs8_y2_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_pix_abs8_y2_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h);
 
-int ff_sse16_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sse16_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                    ptrdiff_t stride, int h);
-int ff_sse8_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sse8_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                    ptrdiff_t stride, int h);
-int ff_sse4_rvv(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sse4_rvv(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                    ptrdiff_t stride, int h);
 
-int ff_vsse16_rvv(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
-int ff_vsse8_rvv(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
-int ff_vsse_intra16_rvv(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
-int ff_vsse_intra8_rvv(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
-int ff_vsad16_rvv(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
-int ff_vsad8_rvv(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
-int ff_vsad_intra16_rvv(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
-int ff_vsad_intra8_rvv(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
+int ff_vsse16_rvv(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
+int ff_vsse8_rvv(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
+int ff_vsse_intra16_rvv(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
+int ff_vsse_intra8_rvv(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
+int ff_vsad16_rvv(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
+int ff_vsad8_rvv(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h);
+int ff_vsad_intra16_rvv(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
+int ff_vsad_intra8_rvv(MPVEncContext *c, const uint8_t *s, const uint8_t *dummy, ptrdiff_t stride, int h);
 int ff_nsse16_rvv(int multiplier, const uint8_t *s1, const uint8_t *s2,
                     ptrdiff_t stride, int h);
 int ff_nsse8_rvv(int multiplier, const uint8_t *s1, const uint8_t *s2,
                     ptrdiff_t stride, int h);
 
-static int nsse16_rvv_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+static int nsse16_rvv_wrapper(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                         ptrdiff_t stride, int h)
 {
     if (c)
-        return ff_nsse16_rvv(c->avctx->nsse_weight, s1, s2, stride, h);
+        return ff_nsse16_rvv(c->c.avctx->nsse_weight, s1, s2, stride, h);
     else
         return ff_nsse16_rvv(8, s1, s2, stride, h);
 }
 
-static int nsse8_rvv_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+static int nsse8_rvv_wrapper(MPVEncContext *c, const uint8_t *s1, const uint8_t *s2,
                         ptrdiff_t stride, int h)
 {
     if (c)
-        return ff_nsse8_rvv(c->avctx->nsse_weight, s1, s2, stride, h);
+        return ff_nsse8_rvv(c->c.avctx->nsse_weight, s1, s2, stride, h);
     else
         return ff_nsse8_rvv(8, s1, s2, stride, h);
 }
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index 0b5065212d..984fe3379d 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -33,33 +33,33 @@
 
 int ff_rv10_encode_picture_header(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int full_frame= 0;
 
     align_put_bits(&s->pb);
 
     put_bits(&s->pb, 1, 1);     /* marker */
 
-    put_bits(&s->pb, 1, (s->pict_type == AV_PICTURE_TYPE_P));
+    put_bits(&s->pb, 1, (s->c.pict_type == AV_PICTURE_TYPE_P));
 
     put_bits(&s->pb, 1, 0);     /* not PB-mframe */
 
-    put_bits(&s->pb, 5, s->qscale);
+    put_bits(&s->pb, 5, s->c.qscale);
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
         /* specific MPEG like DC coding not used */
     }
     /* if multiple packets per frame are sent, the position at which
        to display the macroblocks is coded here */
     if(!full_frame){
-        if (s->mb_width * s->mb_height >= (1U << 12)) {
-            avpriv_report_missing_feature(s->avctx, "Encoding frames with %d (>= 4096) macroblocks",
-                                          s->mb_width * s->mb_height);
+        if (s->c.mb_width * s->c.mb_height >= (1U << 12)) {
+            avpriv_report_missing_feature(s->c.avctx, "Encoding frames with %d (>= 4096) macroblocks",
+                                          s->c.mb_width * s->c.mb_height);
             return AVERROR(ENOSYS);
         }
         put_bits(&s->pb, 6, 0); /* mb_x */
         put_bits(&s->pb, 6, 0); /* mb_y */
-        put_bits(&s->pb, 12, s->mb_width * s->mb_height);
+        put_bits(&s->pb, 12, s->c.mb_width * s->c.mb_height);
     }
 
     put_bits(&s->pb, 3, 0);     /* ignored */
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index 1a59fd4c70..dea89c8be4 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -36,32 +36,32 @@
 
 int ff_rv20_encode_picture_header(MPVMainEncContext *const m)
 {
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    put_bits(&s->pb, 2, s->pict_type); //I 0 vs. 1 ?
+    put_bits(&s->pb, 2, s->c.pict_type); //I 0 vs. 1 ?
     put_bits(&s->pb, 1, 0);     /* unknown bit */
-    put_bits(&s->pb, 5, s->qscale);
+    put_bits(&s->pb, 5, s->c.qscale);
 
-    put_sbits(&s->pb, 8, s->picture_number); //FIXME wrong, but correct is not known
-    s->mb_x= s->mb_y= 0;
+    put_sbits(&s->pb, 8, s->c.picture_number); //FIXME wrong, but correct is not known
+    s->c.mb_x = s->c.mb_y = 0;
     ff_h263_encode_mba(s);
 
-    put_bits(&s->pb, 1, s->no_rounding);
+    put_bits(&s->pb, 1, s->c.no_rounding);
 
-    av_assert0(s->f_code == 1);
-    av_assert0(s->unrestricted_mv == 0);
-    av_assert0(s->alt_inter_vlc == 0);
-    av_assert0(s->umvplus == 0);
-    av_assert0(s->modified_quant==1);
-    av_assert0(s->loop_filter==1);
+    av_assert0(s->c.f_code == 1);
+    av_assert0(s->c.unrestricted_mv == 0);
+    av_assert0(s->c.alt_inter_vlc == 0);
+    av_assert0(s->c.umvplus == 0);
+    av_assert0(s->c.modified_quant==1);
+    av_assert0(s->c.loop_filter==1);
 
-    s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I;
-    if(s->h263_aic){
-        s->y_dc_scale_table=
-        s->c_dc_scale_table= ff_aic_dc_scale_table;
+    s->c.h263_aic= s->c.pict_type == AV_PICTURE_TYPE_I;
+    if(s->c.h263_aic){
+        s->c.y_dc_scale_table =
+        s->c.c_dc_scale_table = ff_aic_dc_scale_table;
     }else{
-        s->y_dc_scale_table=
-        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
+        s->c.y_dc_scale_table =
+        s->c.c_dc_scale_table = ff_mpeg1_dc_scale_table;
     }
     return 0;
 }
diff --git a/libavcodec/snow_dwt.c b/libavcodec/snow_dwt.c
index 1250597ee0..0f2b86e2cc 100644
--- a/libavcodec/snow_dwt.c
+++ b/libavcodec/snow_dwt.c
@@ -741,7 +741,7 @@ void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
                               decomposition_count, y);
 }
 
-static inline int w_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size,
+static inline int w_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size,
                       int w, int h, int type)
 {
     int s, i, j;
@@ -810,32 +810,32 @@ static inline int w_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8
     return s >> 9;
 }
 
-static int w53_8_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
+static int w53_8_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
 {
     return w_c(v, pix1, pix2, line_size, 8, h, 1);
 }
 
-static int w97_8_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
+static int w97_8_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
 {
     return w_c(v, pix1, pix2, line_size, 8, h, 0);
 }
 
-static int w53_16_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
+static int w53_16_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
 {
     return w_c(v, pix1, pix2, line_size, 16, h, 1);
 }
 
-static int w97_16_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
+static int w97_16_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
 {
     return w_c(v, pix1, pix2, line_size, 16, h, 0);
 }
 
-int ff_w53_32_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
+int ff_w53_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
 {
     return w_c(v, pix1, pix2, line_size, 32, h, 1);
 }
 
-int ff_w97_32_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
+int ff_w97_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
 {
     return w_c(v, pix1, pix2, line_size, 32, h, 0);
 }
diff --git a/libavcodec/snow_dwt.h b/libavcodec/snow_dwt.h
index 6e7d22c71a..b5803bc99a 100644
--- a/libavcodec/snow_dwt.h
+++ b/libavcodec/snow_dwt.h
@@ -26,7 +26,7 @@
 
 #include "libavutil/attributes.h"
 
-struct MpegEncContext;
+typedef struct MPVEncContext MPVEncContext;
 
 typedef int DWTELEM;
 typedef short IDWTELEM;
@@ -144,8 +144,8 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
                               int src_y, int src_stride, slice_buffer *sb,
                               int add, uint8_t *dst8);
 
-int ff_w53_32_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h);
-int ff_w97_32_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h);
+int ff_w53_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h);
+int ff_w97_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h);
 
 void ff_spatial_dwt(int *buffer, int *temp, int width, int height, int stride,
                     int type, int decomposition_count);
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index fc2a56a808..f9b10f7dab 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -61,7 +61,7 @@ typedef struct SnowEncContext {
     int scenechange_threshold;
 
     MECmpContext mecc;
-    MPVMainEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
+    MPVMainEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MPVEncContext, so this will be removed then (FIXME/XXX)
     MPVPicture cur_pic, last_pic;
 #define ME_CACHE_SIZE 1024
     unsigned me_cache[ME_CACHE_SIZE];
@@ -160,7 +160,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 {
     SnowEncContext *const enc = avctx->priv_data;
     SnowContext *const s = &enc->com;
-    MpegEncContext *const mpv = &enc->m.s;
+    MPVEncContext *const mpv = &enc->m.s;
     int plane_index, ret;
     int i;
 
@@ -217,7 +217,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     mcf(12,12)
 
     ff_me_cmp_init(&enc->mecc, avctx);
-    ret = ff_me_init(&mpv->me, avctx, &enc->mecc, 0);
+    ret = ff_me_init(&mpv->c.me, avctx, &enc->mecc, 0);
     if (ret < 0)
         return ret;
     ff_mpegvideoencdsp_init(&enc->mpvencdsp, avctx);
@@ -226,21 +226,21 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     s->version=0;
 
-    mpv->avctx   = avctx;
+    mpv->c.avctx   = avctx;
     enc->m.bit_rate = avctx->bit_rate;
     enc->m.lmin  = avctx->mb_lmin;
     enc->m.lmax  = avctx->mb_lmax;
-    mpv->mb_num  = (avctx->width * avctx->height + 255) / 256; // For ratecontrol
+    mpv->c.mb_num  = (avctx->width * avctx->height + 255) / 256; // For ratecontrol
 
-    mpv->me.temp      =
-    mpv->me.scratchpad = av_calloc(avctx->width + 64, 2*16*2*sizeof(uint8_t));
-    mpv->sc.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
-    mpv->me.map       = av_mallocz(2 * ME_MAP_SIZE * sizeof(*mpv->me.map));
-    if (!mpv->me.scratchpad || !mpv->me.map || !mpv->sc.obmc_scratchpad)
+    mpv->c.me.temp      =
+    mpv->c.me.scratchpad = av_calloc(avctx->width + 64, 2*16*2*sizeof(uint8_t));
+    mpv->c.sc.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
+    mpv->c.me.map       = av_mallocz(2 * ME_MAP_SIZE * sizeof(*mpv->c.me.map));
+    if (!mpv->c.me.scratchpad || !mpv->c.me.map || !mpv->c.sc.obmc_scratchpad)
         return AVERROR(ENOMEM);
-    mpv->me.score_map = mpv->me.map + ME_MAP_SIZE;
+    mpv->c.me.score_map = mpv->c.me.map + ME_MAP_SIZE;
 
-    mpv->me.mv_penalty = ff_h263_get_mv_penalty();
+    mpv->c.me.mv_penalty = ff_h263_get_mv_penalty();
 
     s->max_ref_frames = av_clip(avctx->refs, 1, MAX_REF_FRAMES);
 
@@ -369,7 +369,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
 static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
 {
     SnowContext      *const s = &enc->com;
-    MotionEstContext *const c = &enc->m.s.me;
+    MotionEstContext *const c = &enc->m.s.c.me;
     uint8_t p_buffer[1024];
     uint8_t i_buffer[1024];
     uint8_t p_state[sizeof(s->block_state)];
@@ -435,9 +435,9 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
     last_mv[2][0]= bottom->mx;
     last_mv[2][1]= bottom->my;
 
-    enc->m.s.mb_stride = 2;
-    enc->m.s.mb_x =
-    enc->m.s.mb_y = 0;
+    enc->m.s.c.mb_stride = 2;
+    enc->m.s.c.mb_x =
+    enc->m.s.c.mb_y = 0;
     c->skip= 0;
 
     av_assert1(c->  stride ==   stride);
@@ -446,7 +446,7 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
     c->penalty_factor    = get_penalty_factor(enc->lambda, enc->lambda2, c->avctx->me_cmp);
     c->sub_penalty_factor= get_penalty_factor(enc->lambda, enc->lambda2, c->avctx->me_sub_cmp);
     c->mb_penalty_factor = get_penalty_factor(enc->lambda, enc->lambda2, c->avctx->mb_cmp);
-    c->current_mv_penalty = c->mv_penalty[enc->m.s.f_code=1] + MAX_DMV;
+    c->current_mv_penalty = c->mv_penalty[enc->m.s.c.f_code=1] + MAX_DMV;
 
     c->xmin = - x*block_w - 16+3;
     c->ymin = - y*block_w - 16+3;
@@ -569,7 +569,7 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
         if (vard <= 64 || vard < varc)
             c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
         else
-            c->scene_change_score += enc->m.s.qscale;
+            c->scene_change_score += enc->m.s.c.qscale;
     }
 
     if(level!=s->block_max_depth){
@@ -672,7 +672,7 @@ static int get_dc(SnowEncContext *enc, int mb_x, int mb_y, int plane_index)
     const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     const int ref_stride= s->current_picture->linesize[plane_index];
     const uint8_t *src = s->input_picture->data[plane_index];
-    IDWTELEM *dst= (IDWTELEM*)enc->m.s.sc.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
+    IDWTELEM *dst= (IDWTELEM*)enc->m.s.c.sc.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
     const int b_stride = s->b_width << s->block_max_depth;
     const int w= p->width;
     const int h= p->height;
@@ -770,7 +770,7 @@ static int get_block_rd(SnowEncContext *enc, int mb_x, int mb_y,
     const int ref_stride= s->current_picture->linesize[plane_index];
     uint8_t *dst= s->current_picture->data[plane_index];
     const uint8_t *src = s->input_picture->data[plane_index];
-    IDWTELEM *pred= (IDWTELEM*)enc->m.s.sc.obmc_scratchpad + plane_index*block_size*block_size*4;
+    IDWTELEM *pred= (IDWTELEM*)enc->m.s.c.sc.obmc_scratchpad + plane_index*block_size*block_size*4;
     uint8_t *cur = s->scratchbuf;
     uint8_t *tmp = s->emu_edge_buffer;
     const int b_stride = s->b_width << s->block_max_depth;
@@ -840,12 +840,12 @@ static int get_block_rd(SnowEncContext *enc, int mb_x, int mb_y,
             distortion = 0;
             for(i=0; i<4; i++){
                 int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
-                distortion += enc->m.s.me.me_cmp[0](&enc->m.s, src + off, dst + off, ref_stride, 16);
+                distortion += enc->m.s.c.me.me_cmp[0](&enc->m.s, src + off, dst + off, ref_stride, 16);
             }
         }
     }else{
         av_assert2(block_w==8);
-        distortion = enc->m.s.me.me_cmp[0](&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
+        distortion = enc->m.s.c.me.me_cmp[0](&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
     }
 
     if(plane_index==0){
@@ -911,7 +911,7 @@ static int get_4block_rd(SnowEncContext *enc, int mb_x, int mb_y, int plane_inde
         }
 
         av_assert1(block_w== 8 || block_w==16);
-        distortion += enc->m.s.me.me_cmp[block_w==8](&enc->m.s, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
+        distortion += enc->m.s.c.me.me_cmp[block_w==8](&enc->m.s, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
     }
 
     if(plane_index==0){
@@ -1759,7 +1759,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 {
     SnowEncContext *const enc = avctx->priv_data;
     SnowContext *const s = &enc->com;
-    MpegEncContext *const mpv = &enc->m.s;
+    MPVEncContext *const mpv = &enc->m.s;
     RangeCoder * const c= &s->c;
     AVCodecInternal *avci = avctx->internal;
     AVFrame *pic;
@@ -1793,9 +1793,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     pic->pict_type = pict->pict_type;
     pic->quality = pict->quality;
 
-    mpv->picture_number = avctx->frame_num;
+    mpv->c.picture_number = avctx->frame_num;
     if(avctx->flags&AV_CODEC_FLAG_PASS2){
-        mpv->pict_type = pic->pict_type = enc->m.rc_context.entry[avctx->frame_num].new_pict_type;
+        mpv->c.pict_type = pic->pict_type = enc->m.rc_context.entry[avctx->frame_num].new_pict_type;
         s->keyframe = pic->pict_type == AV_PICTURE_TYPE_I;
         if(!(avctx->flags&AV_CODEC_FLAG_QSCALE)) {
             pic->quality = ff_rate_estimate_qscale(&enc->m, 0);
@@ -1804,7 +1804,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         }
     }else{
         s->keyframe= avctx->gop_size==0 || avctx->frame_num % avctx->gop_size == 0;
-        mpv->pict_type = pic->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+        mpv->c.pict_type = pic->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
     }
 
     if (enc->pass1_rc && avctx->frame_num == 0)
@@ -1841,9 +1841,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if (ret < 0)
         return ret;
 
-    mpv->cur_pic.ptr         = &enc->cur_pic;
-    mpv->cur_pic.ptr->f      = s->current_picture;
-    mpv->cur_pic.ptr->f->pts = pict->pts;
+    mpv->c.cur_pic.ptr         = &enc->cur_pic;
+    mpv->c.cur_pic.ptr->f      = s->current_picture;
+    mpv->c.cur_pic.ptr->f->pts = pict->pts;
     if(pic->pict_type == AV_PICTURE_TYPE_P){
         int block_width = (width +15)>>4;
         int block_height= (height+15)>>4;
@@ -1852,35 +1852,35 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         av_assert0(s->current_picture->data[0]);
         av_assert0(s->last_picture[0]->data[0]);
 
-        mpv->avctx = s->avctx;
-        mpv->last_pic.ptr    = &enc->last_pic;
-        mpv->last_pic.ptr->f = s->last_picture[0];
+        mpv->c.avctx = s->avctx;
+        mpv->c.last_pic.ptr    = &enc->last_pic;
+        mpv->c.last_pic.ptr->f = s->last_picture[0];
         mpv-> new_pic     = s->input_picture;
-        mpv->linesize   = stride;
-        mpv->uvlinesize = s->current_picture->linesize[1];
-        mpv->width      = width;
-        mpv->height     = height;
-        mpv->mb_width   = block_width;
-        mpv->mb_height  = block_height;
-        mpv->mb_stride  =     mpv->mb_width + 1;
-        mpv->b8_stride  = 2 * mpv->mb_width + 1;
-        mpv->f_code     = 1;
-        mpv->pict_type  = pic->pict_type;
-        mpv->me.motion_est = enc->motion_est;
-        mpv->me.scene_change_score = 0;
-        mpv->me.dia_size = avctx->dia_size;
-        mpv->quarter_sample  = (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0;
-        mpv->out_format      = FMT_H263;
-        mpv->unrestricted_mv = 1;
-
-        mpv->lambda = enc->lambda;
-        mpv->qscale = (mpv->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
-        enc->lambda2  = mpv->lambda2 = (mpv->lambda*mpv->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
-
-        mpv->qdsp = enc->qdsp; //move
-        mpv->hdsp = s->hdsp;
+        mpv->c.linesize   = stride;
+        mpv->c.uvlinesize = s->current_picture->linesize[1];
+        mpv->c.width      = width;
+        mpv->c.height     = height;
+        mpv->c.mb_width   = block_width;
+        mpv->c.mb_height  = block_height;
+        mpv->c.mb_stride  =     mpv->c.mb_width + 1;
+        mpv->c.b8_stride  = 2 * mpv->c.mb_width + 1;
+        mpv->c.f_code     = 1;
+        mpv->c.pict_type  = pic->pict_type;
+        mpv->c.me.motion_est = enc->motion_est;
+        mpv->c.me.scene_change_score = 0;
+        mpv->c.me.dia_size = avctx->dia_size;
+        mpv->c.quarter_sample  = (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0;
+        mpv->c.out_format      = FMT_H263;
+        mpv->c.unrestricted_mv = 1;
+
+        mpv->c.lambda = enc->lambda;
+        mpv->c.qscale = (mpv->c.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
+        enc->lambda2  = mpv->c.lambda2 = (mpv->c.lambda*mpv->c.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
+
+        mpv->c.qdsp = enc->qdsp; //move
+        mpv->c.hdsp = s->hdsp;
         ff_me_init_pic(mpv);
-        s->hdsp = mpv->hdsp;
+        s->hdsp = mpv->c.hdsp;
     }
 
     if (enc->pass1_rc) {
@@ -1901,7 +1901,7 @@ redo_frame:
         return AVERROR(EINVAL);
     }
 
-    mpv->pict_type = pic->pict_type;
+    mpv->c.pict_type = pic->pict_type;
     s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
 
     ff_snow_common_init_after_header(avctx);
@@ -1937,7 +1937,7 @@ redo_frame:
             if(   plane_index==0
                && pic->pict_type == AV_PICTURE_TYPE_P
                && !(avctx->flags&AV_CODEC_FLAG_PASS2)
-               && mpv->me.scene_change_score > enc->scenechange_threshold) {
+               && mpv->c.me.scene_change_score > enc->scenechange_threshold) {
                 ff_init_range_encoder(c, pkt->data, pkt->size);
                 ff_build_rac_states(c, (1LL<<32)/20, 256-8);
                 pic->pict_type= AV_PICTURE_TYPE_I;
@@ -2058,7 +2058,7 @@ redo_frame:
     }
     if(avctx->flags&AV_CODEC_FLAG_PASS1)
         ff_write_pass1_stats(&enc->m);
-    enc->m.last_pict_type = mpv->pict_type;
+    enc->m.last_pict_type = mpv->c.pict_type;
 
     emms_c();
 
@@ -2092,10 +2092,10 @@ static av_cold int encode_end(AVCodecContext *avctx)
         av_freep(&s->ref_scores[i]);
     }
 
-    enc->m.s.me.temp = NULL;
-    av_freep(&enc->m.s.me.scratchpad);
-    av_freep(&enc->m.s.me.map);
-    av_freep(&enc->m.s.sc.obmc_scratchpad);
+    enc->m.s.c.me.temp = NULL;
+    av_freep(&enc->m.s.c.me.scratchpad);
+    av_freep(&enc->m.s.c.me.map);
+    av_freep(&enc->m.s.c.sc.obmc_scratchpad);
 
     av_freep(&avctx->stats_out);
 
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 1e28702f18..7ddfb92076 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -98,9 +98,9 @@ static av_cold void speedhq_init_static_data(void)
 static int speedhq_encode_picture_header(MPVMainEncContext *const m)
 {
     SpeedHQEncContext *const ctx = (SpeedHQEncContext*)m;
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    put_bits_le(&s->pb, 8, 100 - s->qscale * 2);  /* FIXME why doubled */
+    put_bits_le(&s->pb, 8, 100 - s->c.qscale * 2);  /* FIXME why doubled */
     put_bits_le(&s->pb, 24, 4);  /* no second field */
 
     ctx->slice_start = 4;
@@ -110,7 +110,7 @@ static int speedhq_encode_picture_header(MPVMainEncContext *const m)
     return 0;
 }
 
-void ff_speedhq_end_slice(MpegEncContext *s)
+void ff_speedhq_end_slice(MPVEncContext *const s)
 {
     SpeedHQEncContext *ctx = (SpeedHQEncContext*)s;
     int slice_len;
@@ -158,7 +158,7 @@ static inline void encode_dc(PutBitContext *pb, int diff, int component)
     }
 }
 
-static void encode_block(MpegEncContext *s, int16_t *block, int n)
+static void encode_block(MPVEncContext *const s, const int16_t block[], int n)
 {
     int alevel, level, last_non_zero, dc, i, j, run, last_index, sign;
     int code;
@@ -167,16 +167,16 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
     /* DC coef */
     component = (n <= 3 ? 0 : (n&1) + 1);
     dc = block[0]; /* overflow is impossible */
-    val = s->last_dc[component] - dc;  /* opposite of most codecs */
+    val = s->c.last_dc[component] - dc;  /* opposite of most codecs */
     encode_dc(&s->pb, val, component);
-    s->last_dc[component] = dc;
+    s->c.last_dc[component] = dc;
 
     /* now quantify & encode AC coefs */
     last_non_zero = 0;
-    last_index = s->block_last_index[n];
+    last_index = s->c.block_last_index[n];
 
     for (i = 1; i <= last_index; i++) {
-        j     = s->intra_scantable.permutated[i];
+        j     = s->c.intra_scantable.permutated[i];
         level = block[j];
 
         /* encode using VLC */
@@ -207,14 +207,14 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
     put_bits_le(&s->pb, 4, 6);
 }
 
-static void speedhq_encode_mb(MpegEncContext *const s, int16_t block[12][64],
+static void speedhq_encode_mb(MPVEncContext *const s, int16_t block[12][64],
                               int unused_x, int unused_y)
 {
     int i;
     for(i=0;i<6;i++) {
         encode_block(s, block[i], i);
     }
-    if (s->chroma_format == CHROMA_444) {
+    if (s->c.chroma_format == CHROMA_444) {
         encode_block(s, block[8], 8);
         encode_block(s, block[9], 9);
 
@@ -223,7 +223,7 @@ static void speedhq_encode_mb(MpegEncContext *const s, int16_t block[12][64],
 
         encode_block(s, block[10], 10);
         encode_block(s, block[11], 11);
-    } else if (s->chroma_format == CHROMA_422) {
+    } else if (s->c.chroma_format == CHROMA_422) {
         encode_block(s, block[6], 6);
         encode_block(s, block[7], 7);
     }
@@ -235,7 +235,7 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
     MPVMainEncContext *const m = avctx->priv_data;
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
     int ret;
 
     if (avctx->width > 65500 || avctx->height > 65500) {
@@ -274,8 +274,8 @@ static av_cold int speedhq_encode_init(AVCodecContext *avctx)
     s->intra_chroma_ac_vlc_length      =
     s->intra_chroma_ac_vlc_last_length = uni_speedhq_ac_vlc_len;
 
-    s->y_dc_scale_table =
-    s->c_dc_scale_table = ff_mpeg12_dc_scale_table[3];
+    s->c.y_dc_scale_table =
+    s->c.c_dc_scale_table = ff_mpeg12_dc_scale_table[3];
 
     ret = ff_mpv_encode_init(avctx);
     if (ret < 0)
diff --git a/libavcodec/speedhqenc.h b/libavcodec/speedhqenc.h
index e804ce714a..568f82c76e 100644
--- a/libavcodec/speedhqenc.h
+++ b/libavcodec/speedhqenc.h
@@ -29,11 +29,9 @@
 #ifndef AVCODEC_SPEEDHQENC_H
 #define AVCODEC_SPEEDHQENC_H
 
-#include <stdint.h>
+typedef struct MPVEncContext MPVEncContext;
 
-#include "mpegvideo.h"
-
-void ff_speedhq_end_slice(MpegEncContext *s);
+void ff_speedhq_end_slice(MPVEncContext *s);
 
 static inline int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height)
 {
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 652dc11b03..ddc94dffe5 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -58,8 +58,8 @@
 typedef struct SVQ1EncContext {
     /* FIXME: Needed for motion estimation, should not be used for anything
      * else, the idea is to make the motion estimation eventually independent
-     * of MpegEncContext, so this will be removed then. */
-    MpegEncContext m;
+     * of MPVEncContext, so this will be removed then. */
+    MPVEncContext m;
     AVCodecContext *avctx;
     MECmpContext mecc;
     HpelDSPContext hdsp;
@@ -289,7 +289,8 @@ static int encode_block(SVQ1EncContext *s, uint8_t *src, uint8_t *ref,
     return best_score;
 }
 
-static void init_block_index(MpegEncContext *s){
+static void init_block_index(MpegEncContext *const s)
+{
     s->block_index[0]= s->b8_stride*(s->mb_y*2    )     + s->mb_x*2;
     s->block_index[1]= s->b8_stride*(s->mb_y*2    ) + 1 + s->mb_x*2;
     s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1)     + s->mb_x*2;
@@ -305,6 +306,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
                              unsigned char *decoded_plane,
                              int width, int height, int src_stride, int stride)
 {
+    MpegEncContext *const s2 = &s->m.c;
     int x, y;
     int i;
     int block_width, block_height;
@@ -323,36 +325,36 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
     block_height = (height + 15) / 16;
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        s->m.avctx                         = s->avctx;
-        s->m.last_pic.data[0]        = ref_plane;
-        s->m.linesize                      =
-        s->m.last_pic.linesize[0]    =
+        s2->avctx                         = s->avctx;
+        s2->last_pic.data[0]        = ref_plane;
+        s2->linesize                      =
+        s2->last_pic.linesize[0]    =
         s->m.new_pic->linesize[0]      =
-        s->m.cur_pic.linesize[0] = stride;
-        s->m.width                         = width;
-        s->m.height                        = height;
-        s->m.mb_width                      = block_width;
-        s->m.mb_height                     = block_height;
-        s->m.mb_stride                     = s->m.mb_width + 1;
-        s->m.b8_stride                     = 2 * s->m.mb_width + 1;
-        s->m.f_code                        = 1;
-        s->m.pict_type                     = s->pict_type;
-        s->m.me.scene_change_score         = 0;
-        // s->m.out_format                    = FMT_H263;
-        // s->m.unrestricted_mv               = 1;
-        s->m.lambda                        = s->quality;
-        s->m.qscale                        = s->m.lambda * 139 +
+        s2->cur_pic.linesize[0] = stride;
+        s2->width                         = width;
+        s2->height                        = height;
+        s2->mb_width                      = block_width;
+        s2->mb_height                     = block_height;
+        s2->mb_stride                     = s2->mb_width + 1;
+        s2->b8_stride                     = 2 * s2->mb_width + 1;
+        s2->f_code                        = 1;
+        s2->pict_type                     = s->pict_type;
+        s2->me.scene_change_score         = 0;
+        // s2->out_format                    = FMT_H263;
+        // s2->unrestricted_mv               = 1;
+        s2->lambda                        = s->quality;
+        s2->qscale                        = s2->lambda * 139 +
                                              FF_LAMBDA_SCALE * 64 >>
                                              FF_LAMBDA_SHIFT + 7;
-        s->m.lambda2                       = s->m.lambda * s->m.lambda +
+        s2->lambda2                       = s2->lambda * s2->lambda +
                                              FF_LAMBDA_SCALE / 2 >>
                                              FF_LAMBDA_SHIFT;
 
         if (!s->motion_val8[plane]) {
-            s->motion_val8[plane]  = av_mallocz((s->m.b8_stride *
+            s->motion_val8[plane]  = av_mallocz((s2->b8_stride *
                                                  block_height * 2 + 2) *
                                                 2 * sizeof(int16_t));
-            s->motion_val16[plane] = av_mallocz((s->m.mb_stride *
+            s->motion_val16[plane] = av_mallocz((s2->mb_stride *
                                                  (block_height + 2) + 1) *
                                                 2 * sizeof(int16_t));
             if (!s->motion_val8[plane] || !s->motion_val16[plane])
@@ -365,18 +367,18 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
         s->m.mb_mean   = (uint8_t *)s->dummy;
         s->m.mb_var    = (uint16_t *)s->dummy;
         s->m.mc_mb_var = (uint16_t *)s->dummy;
-        s->m.cur_pic.mb_type = s->dummy;
+        s2->cur_pic.mb_type = s->dummy;
 
-        s->m.cur_pic.motion_val[0]   = s->motion_val8[plane] + 2;
-        s->m.p_mv_table                      = s->motion_val16[plane] +
-                                               s->m.mb_stride + 1;
+        s2->cur_pic.motion_val[0]   = s->motion_val8[plane] + 2;
+        s->m.p_mv_table             = s->motion_val16[plane] +
+                                             s2->mb_stride + 1;
         ff_me_init_pic(&s->m);
 
-        s->m.me.dia_size      = s->avctx->dia_size;
-        s->m.first_slice_line = 1;
+        s2->me.dia_size      = s->avctx->dia_size;
+        s2->first_slice_line = 1;
         for (y = 0; y < block_height; y++) {
             s->m.new_pic->data[0]  = src - y * 16 * stride; // ugly
-            s->m.mb_y                  = y;
+            s2->mb_y                  = y;
 
             for (i = 0; i < 16 && i + 16 * y < height; i++) {
                 memcpy(&src[i * stride], &src_plane[(i + 16 * y) * src_stride],
@@ -389,20 +391,20 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
                        16 * block_width);
 
             for (x = 0; x < block_width; x++) {
-                s->m.mb_x = x;
-                init_block_index(&s->m);
+                s2->mb_x = x;
+                init_block_index(s2);
 
                 ff_estimate_p_frame_motion(&s->m, x, y);
             }
-            s->m.first_slice_line = 0;
+            s2->first_slice_line = 0;
         }
 
         ff_fix_long_p_mvs(&s->m, CANDIDATE_MB_TYPE_INTRA);
-        ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code,
+        ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s2->f_code,
                         CANDIDATE_MB_TYPE_INTER, 0);
     }
 
-    s->m.first_slice_line = 1;
+    s2->first_slice_line = 1;
     for (y = 0; y < block_height; y++) {
         for (i = 0; i < 16 && i + 16 * y < height; i++) {
             memcpy(&src[i * stride], &src_plane[(i + 16 * y) * src_stride],
@@ -413,7 +415,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
         for (; i < 16 && i + 16 * y < 16 * block_height; i++)
             memcpy(&src[i * stride], &src[(i - 1) * stride], 16 * block_width);
 
-        s->m.mb_y = y;
+        s2->mb_y = y;
         for (x = 0; x < block_width; x++) {
             uint8_t reorder_buffer[2][6][7 * 32];
             int count[2][6];
@@ -428,11 +430,11 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
                 return -1;
             }
 
-            s->m.mb_x = x;
-            init_block_index(&s->m);
+            s2->mb_x = x;
+            init_block_index(s2);
 
             if (s->pict_type == AV_PICTURE_TYPE_I ||
-                (s->m.mb_type[x + y * s->m.mb_stride] &
+                (s->m.mb_type[x + y * s2->mb_stride] &
                  CANDIDATE_MB_TYPE_INTRA)) {
                 for (i = 0; i < 6; i++)
                     init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i],
@@ -456,8 +458,8 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
                 int mx, my, pred_x, pred_y, dxy;
                 int16_t *motion_ptr;
 
-                motion_ptr = ff_h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y);
-                if (s->m.mb_type[x + y * s->m.mb_stride] &
+                motion_ptr = ff_h263_pred_motion(s2, 0, 0, &pred_x, &pred_y);
+                if (s->m.mb_type[x + y * s2->mb_stride] &
                     CANDIDATE_MB_TYPE_INTER) {
                     for (i = 0; i < 6; i++)
                         init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i],
@@ -506,10 +508,10 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
                     motion_ptr[1]                      =
                     motion_ptr[2]                      =
                     motion_ptr[3]                      =
-                    motion_ptr[0 + 2 * s->m.b8_stride] =
-                    motion_ptr[1 + 2 * s->m.b8_stride] =
-                    motion_ptr[2 + 2 * s->m.b8_stride] =
-                    motion_ptr[3 + 2 * s->m.b8_stride] = 0;
+                    motion_ptr[0 + 2 * s2->b8_stride] =
+                    motion_ptr[1 + 2 * s2->b8_stride] =
+                    motion_ptr[2 + 2 * s2->b8_stride] =
+                    motion_ptr[3 + 2 * s2->b8_stride] = 0;
                 }
             }
 
@@ -522,7 +524,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
             if (best == 0)
                 s->hdsp.put_pixels_tab[0][0](decoded, temp, stride, 16);
         }
-        s->m.first_slice_line = 0;
+        s2->first_slice_line = 0;
     }
     return 0;
 }
@@ -537,14 +539,14 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx)
                s->rd_total / (double)(avctx->width * avctx->height *
                                       avctx->frame_num));
 
-    av_freep(&s->m.me.scratchpad);
-    av_freep(&s->m.me.map);
+    av_freep(&s->m.c.me.scratchpad);
+    av_freep(&s->m.c.me.map);
     av_freep(&s->mb_type);
     av_freep(&s->dummy);
     av_freep(&s->scratchbuf);
 
     s->m.mb_type = NULL;
-    ff_mpv_common_end(&s->m);
+    ff_mpv_common_end(&s->m.c);
 
     for (i = 0; i < 3; i++) {
         av_freep(&s->motion_val8[i]);
@@ -583,7 +585,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
 
     ff_hpeldsp_init(&s->hdsp, avctx->flags);
     ff_me_cmp_init(&s->mecc, avctx);
-    ret = ff_me_init(&s->m.me, avctx, &s->mecc, 0);
+    ret = ff_me_init(&s->m.c.me, avctx, &s->mecc, 0);
     if (ret < 0)
         return ret;
     ff_mpegvideoencdsp_init(&s->m.mpvencdsp, avctx);
@@ -604,31 +606,31 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
     s->c_block_height = (s->frame_height / 4 + 15) / 16;
 
     s->avctx               = avctx;
-    s->m.avctx             = avctx;
+    s->m.c.avctx           = avctx;
 
-    if ((ret = ff_mpv_common_init(&s->m)) < 0) {
+    ret = ff_mpv_common_init(&s->m.c);
+    if (ret < 0)
         return ret;
-    }
 
-    s->m.picture_structure = PICT_FRAME;
-    s->m.me.temp           =
-    s->m.me.scratchpad     = av_mallocz((avctx->width + 64) *
+    s->m.c.picture_structure = PICT_FRAME;
+    s->m.c.me.temp           =
+    s->m.c.me.scratchpad     = av_mallocz((avctx->width + 64) *
                                         2 * 16 * 2 * sizeof(uint8_t));
     s->mb_type             = av_mallocz((s->y_block_width + 1) *
                                         s->y_block_height * sizeof(int16_t));
     s->dummy               = av_mallocz((s->y_block_width + 1) *
                                         s->y_block_height * sizeof(int32_t));
-    s->m.me.map            = av_mallocz(2 * ME_MAP_SIZE * sizeof(*s->m.me.map));
+    s->m.c.me.map            = av_mallocz(2 * ME_MAP_SIZE * sizeof(*s->m.c.me.map));
     s->m.new_pic       = av_frame_alloc();
 
-    if (!s->m.me.scratchpad || !s->m.me.map ||
+    if (!s->m.c.me.scratchpad || !s->m.c.me.map ||
         !s->mb_type || !s->dummy || !s->m.new_pic)
         return AVERROR(ENOMEM);
-    s->m.me.score_map = s->m.me.map + ME_MAP_SIZE;
+    s->m.c.me.score_map = s->m.c.me.map + ME_MAP_SIZE;
 
     ff_svq1enc_init(&s->svq1encdsp);
 
-    s->m.me.mv_penalty = ff_h263_get_mv_penalty();
+    s->m.c.me.mv_penalty = ff_h263_get_mv_penalty();
 
     return write_ident(avctx, s->avctx->flags & AV_CODEC_FLAG_BITEXACT ? "Lavc" : LIBAVCODEC_IDENT);
 }
@@ -716,7 +718,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 #define OFFSET(x) offsetof(struct SVQ1EncContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "motion-est", "Motion estimation algorithm", OFFSET(m.me.motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, .unit = "motion-est"},
+    { "motion-est", "Motion estimation algorithm", OFFSET(m.c.me.motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, .unit = "motion-est"},
         { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
         { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
         { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 81b0ace053..f9fd918dbf 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -48,17 +48,17 @@ typedef struct WMV2EncContext {
 
 static int encode_ext_header(WMV2EncContext *w)
 {
-    MpegEncContext *const s = &w->msmpeg4.m.s;
+    MPVEncContext *const s = &w->msmpeg4.m.s;
     PutBitContext pb;
     int code;
 
-    init_put_bits(&pb, s->avctx->extradata, WMV2_EXTRADATA_SIZE);
+    init_put_bits(&pb, s->c.avctx->extradata, WMV2_EXTRADATA_SIZE);
 
-    put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); // yes 29.97 -> 29
+    put_bits(&pb, 5, s->c.avctx->time_base.den / s->c.avctx->time_base.num); // yes 29.97 -> 29
     put_bits(&pb, 11, FFMIN(w->msmpeg4.m.bit_rate / 1024, 2047));
 
     put_bits(&pb, 1, w->mspel_bit        = 1);
-    put_bits(&pb, 1, s->loop_filter);
+    put_bits(&pb, 1, s->c.loop_filter);
     put_bits(&pb, 1, w->abt_flag         = 1);
     put_bits(&pb, 1, w->j_type_bit       = 1);
     put_bits(&pb, 1, w->top_left_mv_flag = 0);
@@ -67,7 +67,7 @@ static int encode_ext_header(WMV2EncContext *w)
 
     flush_put_bits(&pb);
 
-    s->slice_height = s->mb_height / code;
+    s->c.slice_height = s->c.mb_height / code;
 
     return 0;
 }
@@ -76,25 +76,25 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
 {
     WMV2EncContext *const w = (WMV2EncContext *) m;
     MSMPEG4EncContext *const ms = &w->msmpeg4;
-    MpegEncContext *const s = &m->s;
+    MPVEncContext *const s = &m->s;
 
-    put_bits(&s->pb, 1, s->pict_type - 1);
-    if (s->pict_type == AV_PICTURE_TYPE_I)
+    put_bits(&s->pb, 1, s->c.pict_type - 1);
+    if (s->c.pict_type == AV_PICTURE_TYPE_I)
         put_bits(&s->pb, 7, 0);
-    put_bits(&s->pb, 5, s->qscale);
+    put_bits(&s->pb, 5, s->c.qscale);
 
     ms->dc_table_index  = 1;
     ms->mv_table_index  = 1; /* only if P-frame */
     ms->per_mb_rl_table = 0;
-    s->mspel           = 0;
+    s->c.mspel          = 0;
     w->per_mb_abt      = 0;
     w->abt_type        = 0;
     w->j_type          = 0;
 
-    av_assert0(s->flipflop_rounding);
+    av_assert0(s->c.flipflop_rounding);
 
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
-        av_assert0(s->no_rounding == 1);
+    if (s->c.pict_type == AV_PICTURE_TYPE_I) {
+        av_assert0(s->c.no_rounding == 1);
         if (w->j_type_bit)
             put_bits(&s->pb, 1, w->j_type);
 
@@ -108,17 +108,17 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
 
         put_bits(&s->pb, 1, ms->dc_table_index);
 
-        s->inter_intra_pred = 0;
+        s->c.inter_intra_pred = 0;
     } else {
         int cbp_index;
 
         put_bits(&s->pb, 2, SKIP_TYPE_NONE);
 
         ff_msmpeg4_code012(&s->pb, cbp_index = 0);
-        w->cbp_table_index = wmv2_get_cbp_table_index(s, cbp_index);
+        w->cbp_table_index = wmv2_get_cbp_table_index(&s->c, cbp_index);
 
         if (w->mspel_bit)
-            put_bits(&s->pb, 1, s->mspel);
+            put_bits(&s->pb, 1, s->c.mspel);
 
         if (w->abt_flag) {
             put_bits(&s->pb, 1, w->per_mb_abt ^ 1);
@@ -136,7 +136,7 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
         put_bits(&s->pb, 1, ms->dc_table_index);
         put_bits(&s->pb, 1, ms->mv_table_index);
 
-        s->inter_intra_pred = 0; // (s->width * s->height < 320 * 240 && m->bit_rate <= II_BITRATE);
+        s->c.inter_intra_pred = 0; // (s->c.width * s->c.height < 320 * 240 && m->bit_rate <= II_BITRATE);
     }
     s->esc3_level_length = 0;
     ms->esc3_run_length  = 0;
@@ -147,7 +147,7 @@ static int wmv2_encode_picture_header(MPVMainEncContext *const m)
 /* Nearly identical to wmv1 but that is just because we do not use the
  * useless M$ crap features. It is duplicated here in case someone wants
  * to add support for these crap features. */
-static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
+static void wmv2_encode_mb(MPVEncContext *const s, int16_t block[][64],
                            int motion_x, int motion_y)
 {
     WMV2EncContext *const w = (WMV2EncContext *) s;
@@ -157,11 +157,11 @@ static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
 
     ff_msmpeg4_handle_slices(s);
 
-    if (!s->mb_intra) {
+    if (!s->c.mb_intra) {
         /* compute cbp */
         cbp = 0;
         for (i = 0; i < 6; i++)
-            if (s->block_last_index[i] >= 0)
+            if (s->c.block_last_index[i] >= 0)
                 cbp |= 1 << (5 - i);
 
         put_bits(&s->pb,
@@ -170,7 +170,7 @@ static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
 
         s->misc_bits += get_bits_diff(s);
         /* motion vector */
-        ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+        ff_h263_pred_motion(&s->c, 0, 0, &pred_x, &pred_y);
         ff_msmpeg4_encode_motion(&w->msmpeg4, motion_x - pred_x,
                                  motion_y - pred_y);
         s->mv_bits += get_bits_diff(s);
@@ -179,19 +179,19 @@ static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
         cbp       = 0;
         coded_cbp = 0;
         for (i = 0; i < 6; i++) {
-            int val, pred;
-            val  = (s->block_last_index[i] >= 1);
+            int val = (s->c.block_last_index[i] >= 1);
+
             cbp |= val << (5 - i);
             if (i < 4) {
                 /* predict value for close blocks only for luma */
-                pred         = ff_msmpeg4_coded_block_pred(s, i, &coded_block);
+                int pred     = ff_msmpeg4_coded_block_pred(&s->c, i, &coded_block);
                 *coded_block = val;
                 val          = val ^ pred;
             }
             coded_cbp |= val << (5 - i);
         }
 
-        if (s->pict_type == AV_PICTURE_TYPE_I)
+        if (s->c.pict_type == AV_PICTURE_TYPE_I)
             put_bits(&s->pb,
                      ff_msmp4_mb_i_table[coded_cbp][1],
                      ff_msmp4_mb_i_table[coded_cbp][0]);
@@ -200,18 +200,18 @@ static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
                      ff_wmv2_inter_table[w->cbp_table_index][cbp][1],
                      ff_wmv2_inter_table[w->cbp_table_index][cbp][0]);
         put_bits(&s->pb, 1, 0);         /* no AC prediction yet */
-        if (s->inter_intra_pred) {
-            s->h263_aic_dir = 0;
+        if (s->c.inter_intra_pred) {
+            s->c.h263_aic_dir = 0;
             put_bits(&s->pb,
-                     ff_table_inter_intra[s->h263_aic_dir][1],
-                     ff_table_inter_intra[s->h263_aic_dir][0]);
+                     ff_table_inter_intra[s->c.h263_aic_dir][1],
+                     ff_table_inter_intra[s->c.h263_aic_dir][0]);
         }
         s->misc_bits += get_bits_diff(s);
     }
 
     for (i = 0; i < 6; i++)
         ff_msmpeg4_encode_block(s, block[i], i);
-    if (s->mb_intra)
+    if (s->c.mb_intra)
         s->i_tex_bits += get_bits_diff(s);
     else
         s->p_tex_bits += get_bits_diff(s);
@@ -220,17 +220,17 @@ static void wmv2_encode_mb(MpegEncContext *const s, int16_t block[][64],
 static av_cold int wmv2_encode_init(AVCodecContext *avctx)
 {
     WMV2EncContext *const w = avctx->priv_data;
-    MpegEncContext *const s = &w->msmpeg4.m.s;
+    MPVEncContext *const s = &w->msmpeg4.m.s;
     int ret;
 
     w->msmpeg4.m.encode_picture_header = wmv2_encode_picture_header;
     s->encode_mb                       = wmv2_encode_mb;
-    s->private_ctx = &w->common;
+    s->c.private_ctx = &w->common;
     ret = ff_mpv_encode_init(avctx);
     if (ret < 0)
         return ret;
 
-    ff_wmv2_common_init(s);
+    ff_wmv2_common_init(&s->c);
 
     avctx->extradata_size = WMV2_EXTRADATA_SIZE;
     avctx->extradata      = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
diff --git a/libavcodec/x86/me_cmp.asm b/libavcodec/x86/me_cmp.asm
index 923eb8078b..a494cdeb64 100644
--- a/libavcodec/x86/me_cmp.asm
+++ b/libavcodec/x86/me_cmp.asm
@@ -214,7 +214,7 @@ hadamard8x8_diff %+ SUFFIX:
 hadamard8_16_wrapper %1, 3
 %elif cpuflag(mmx)
 ALIGN 16
-; int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, const uint8_t *src1,
+; int ff_hadamard8_diff_ ## cpu(MPVEncContext *s, const uint8_t *src1,
 ;                               const uint8_t *src2, ptrdiff_t stride, int h)
 ; r0 = void *s = unused, int h = unused (always 8)
 ; note how r1, r2 and r3 are not clobbered in this function, so 16x16
@@ -278,7 +278,7 @@ INIT_XMM ssse3
 %define ABS_SUM_8x8 ABS_SUM_8x8_64
 HADAMARD8_DIFF 9
 
-; int ff_sse*_*(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+; int ff_sse*_*(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
 ;               ptrdiff_t line_size, int h)
 
 %macro SUM_SQUARED_ERRORS 1
@@ -466,7 +466,7 @@ HF_NOISE 8
 HF_NOISE 16
 
 ;---------------------------------------------------------------------------------------
-;int ff_sad_<opt>(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
+;int ff_sad_<opt>(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
 ;---------------------------------------------------------------------------------------
 ;%1 = 8/16
 %macro SAD 1
@@ -521,7 +521,7 @@ INIT_XMM sse2
 SAD 16
 
 ;------------------------------------------------------------------------------------------
-;int ff_sad_x2_<opt>(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
+;int ff_sad_x2_<opt>(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
 ;------------------------------------------------------------------------------------------
 ;%1 = 8/16
 %macro SAD_X2 1
@@ -598,7 +598,7 @@ INIT_XMM sse2
 SAD_X2 16
 
 ;------------------------------------------------------------------------------------------
-;int ff_sad_y2_<opt>(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
+;int ff_sad_y2_<opt>(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
 ;------------------------------------------------------------------------------------------
 ;%1 = 8/16
 %macro SAD_Y2 1
@@ -668,7 +668,7 @@ INIT_XMM sse2
 SAD_Y2 16
 
 ;-------------------------------------------------------------------------------------------
-;int ff_sad_approx_xy2_<opt>(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
+;int ff_sad_approx_xy2_<opt>(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h);
 ;-------------------------------------------------------------------------------------------
 ;%1 = 8/16
 %macro SAD_APPROX_XY2 1
@@ -769,7 +769,7 @@ INIT_XMM sse2
 SAD_APPROX_XY2 16
 
 ;--------------------------------------------------------------------
-;int ff_vsad_intra(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+;int ff_vsad_intra(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
 ;                  ptrdiff_t line_size, int h);
 ;--------------------------------------------------------------------
 ; %1 = 8/16
@@ -830,7 +830,7 @@ INIT_XMM sse2
 VSAD_INTRA 16
 
 ;---------------------------------------------------------------------
-;int ff_vsad_approx(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+;int ff_vsad_approx(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
 ;                   ptrdiff_t line_size, int h);
 ;---------------------------------------------------------------------
 ; %1 = 8/16
diff --git a/libavcodec/x86/me_cmp_init.c b/libavcodec/x86/me_cmp_init.c
index 98b71b1894..45425f7109 100644
--- a/libavcodec/x86/me_cmp_init.c
+++ b/libavcodec/x86/me_cmp_init.c
@@ -28,59 +28,59 @@
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/me_cmp.h"
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideoenc.h"
 
 int ff_sum_abs_dctelem_sse2(const int16_t *block);
 int ff_sum_abs_dctelem_ssse3(const int16_t *block);
-int ff_sse8_mmx(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sse8_mmx(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                 ptrdiff_t stride, int h);
-int ff_sse16_mmx(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sse16_mmx(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                  ptrdiff_t stride, int h);
-int ff_sse16_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sse16_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                   ptrdiff_t stride, int h);
 int ff_hf_noise8_mmx(const uint8_t *pix1, ptrdiff_t stride, int h);
 int ff_hf_noise16_mmx(const uint8_t *pix1, ptrdiff_t stride, int h);
-int ff_sad8_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad8_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                    ptrdiff_t stride, int h);
-int ff_sad16_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                     ptrdiff_t stride, int h);
-int ff_sad16_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                   ptrdiff_t stride, int h);
-int ff_sad8_x2_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad8_x2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                       ptrdiff_t stride, int h);
-int ff_sad16_x2_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_x2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h);
-int ff_sad16_x2_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_x2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                      ptrdiff_t stride, int h);
-int ff_sad8_y2_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad8_y2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                       ptrdiff_t stride, int h);
-int ff_sad16_y2_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_y2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                        ptrdiff_t stride, int h);
-int ff_sad16_y2_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_y2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                      ptrdiff_t stride, int h);
-int ff_sad8_approx_xy2_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad8_approx_xy2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                               ptrdiff_t stride, int h);
-int ff_sad16_approx_xy2_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_approx_xy2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                                ptrdiff_t stride, int h);
-int ff_sad16_approx_xy2_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_sad16_approx_xy2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                              ptrdiff_t stride, int h);
-int ff_vsad_intra8_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_vsad_intra8_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                           ptrdiff_t stride, int h);
-int ff_vsad_intra16_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_vsad_intra16_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                            ptrdiff_t stride, int h);
-int ff_vsad_intra16_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_vsad_intra16_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                          ptrdiff_t stride, int h);
-int ff_vsad8_approx_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_vsad8_approx_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                     ptrdiff_t stride, int h);
-int ff_vsad16_approx_mmxext(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_vsad16_approx_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                      ptrdiff_t stride, int h);
-int ff_vsad16_approx_sse2(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+int ff_vsad16_approx_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
                    ptrdiff_t stride, int h);
 
-#define hadamard_func(cpu)                                                    \
-    int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, const uint8_t *src1,     \
+#define hadamard_func(cpu)                                                       \
+    int ff_hadamard8_diff_ ## cpu(MPVEncContext *s, const uint8_t *src1,         \
                                   const uint8_t *src2, ptrdiff_t stride, int h); \
-    int ff_hadamard8_diff16_ ## cpu(MpegEncContext *s, const uint8_t *src1,   \
+    int ff_hadamard8_diff16_ ## cpu(MPVEncContext *s, const uint8_t *src1,       \
                                     const uint8_t *src2, ptrdiff_t stride, int h);
 
 hadamard_func(mmxext)
@@ -88,7 +88,7 @@ hadamard_func(sse2)
 hadamard_func(ssse3)
 
 #if HAVE_X86ASM
-static int nsse16_mmx(MpegEncContext *c, const uint8_t *pix1, const uint8_t *pix2,
+static int nsse16_mmx(MPVEncContext *c, const uint8_t *pix1, const uint8_t *pix2,
                       ptrdiff_t stride, int h)
 {
     int score1, score2;
@@ -101,12 +101,12 @@ static int nsse16_mmx(MpegEncContext *c, const uint8_t *pix1, const uint8_t *pix
            - ff_hf_noise16_mmx(pix2, stride, h) - ff_hf_noise8_mmx(pix2+8, stride, h);
 
     if (c)
-        return score1 + FFABS(score2) * c->avctx->nsse_weight;
+        return score1 + FFABS(score2) * c->c.avctx->nsse_weight;
     else
         return score1 + FFABS(score2) * 8;
 }
 
-static int nsse8_mmx(MpegEncContext *c, const uint8_t *pix1, const uint8_t *pix2,
+static int nsse8_mmx(MPVEncContext *c, const uint8_t *pix1, const uint8_t *pix2,
                      ptrdiff_t stride, int h)
 {
     int score1 = ff_sse8_mmx(c, pix1, pix2, stride, h);
@@ -114,7 +114,7 @@ static int nsse8_mmx(MpegEncContext *c, const uint8_t *pix1, const uint8_t *pix2
                  ff_hf_noise8_mmx(pix2, stride, h);
 
     if (c)
-        return score1 + FFABS(score2) * c->avctx->nsse_weight;
+        return score1 + FFABS(score2) * c->c.avctx->nsse_weight;
     else
         return score1 + FFABS(score2) * 8;
 }
@@ -199,7 +199,7 @@ static inline int sum_mmx(void)
 }
 
 #define PIX_SADXY(suf)                                                  \
-static int sad8_xy2_ ## suf(MpegEncContext *v, const uint8_t *blk2,     \
+static int sad8_xy2_ ## suf(MPVEncContext *v, const uint8_t *blk2,      \
                             const uint8_t *blk1, ptrdiff_t stride, int h) \
 {                                                                       \
     __asm__ volatile (                                                  \
@@ -212,7 +212,7 @@ static int sad8_xy2_ ## suf(MpegEncContext *v, const uint8_t *blk2,     \
     return sum_ ## suf();                                               \
 }                                                                       \
                                                                         \
-static int sad16_xy2_ ## suf(MpegEncContext *v, const uint8_t *blk2,    \
+static int sad16_xy2_ ## suf(MPVEncContext *v, const uint8_t *blk2,     \
                              const uint8_t *blk1, ptrdiff_t stride, int h) \
 {                                                                       \
     __asm__ volatile (                                                  \
diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index 612e7ff758..99daccef3b 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -70,8 +70,9 @@ DECLARE_ALIGNED(16, static const uint16_t, inv_zigzag_direct16)[64] = {
 
 #if HAVE_INLINE_ASM
 #if HAVE_SSE2_INLINE
-static void  denoise_dct_sse2(MpegEncContext *s, int16_t *block){
-    const int intra= s->mb_intra;
+static void denoise_dct_sse2(MPVEncContext *const s, int16_t block[])
+{
+    const int intra= s->c.mb_intra;
     int *sum= s->dct_error_sum[intra];
     uint16_t *offset= s->dct_offset[intra];
 
@@ -128,9 +129,9 @@ static void  denoise_dct_sse2(MpegEncContext *s, int16_t *block){
 #endif /* HAVE_SSE2_INLINE */
 #endif /* HAVE_INLINE_ASM */
 
-av_cold void ff_dct_encode_init_x86(MpegEncContext *s)
+av_cold void ff_dct_encode_init_x86(MPVEncContext *const s)
 {
-    const int dct_algo = s->avctx->dct_algo;
+    const int dct_algo = s->c.avctx->dct_algo;
 
     if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) {
 #if HAVE_MMX_INLINE
diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c
index f937c7166b..08619ac570 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -26,7 +26,7 @@
 #include "libavutil/mem_internal.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/mpegutils.h"
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideoenc.h"
 #include "fdct.h"
 
 #undef MMREG_WIDTH
@@ -90,7 +90,7 @@
             "psubw "a", "b"             \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])
 #endif
 
-static int RENAME(dct_quantize)(MpegEncContext *s,
+static int RENAME(dct_quantize)(MPVEncContext *const s,
                             int16_t *block, int n,
                             int qscale, int *overflow)
 {
@@ -105,19 +105,19 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
     if(s->dct_error_sum)
         s->denoise_dct(s, block);
 
-    if (s->mb_intra) {
+    if (s->c.mb_intra) {
         int dummy;
         if (n < 4){
-            q = s->y_dc_scale;
+            q = s->c.y_dc_scale;
             bias = s->q_intra_matrix16[qscale][1];
             qmat = s->q_intra_matrix16[qscale][0];
         }else{
-            q = s->c_dc_scale;
+            q = s->c.c_dc_scale;
             bias = s->q_chroma_intra_matrix16[qscale][1];
             qmat = s->q_chroma_intra_matrix16[qscale][0];
         }
         /* note: block[0] is assumed to be positive */
-        if (!s->h263_aic) {
+        if (!s->c.h263_aic) {
         __asm__ volatile (
                 "mul %%ecx                \n\t"
                 : "=d" (level), "=a"(dummy)
@@ -136,7 +136,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
         qmat = s->q_inter_matrix16[qscale][0];
     }
 
-    if((s->out_format == FMT_H263 || s->out_format == FMT_H261) && s->mpeg_quant==0){
+    if((s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) && s->c.mpeg_quant==0){
 
         __asm__ volatile(
             "movd %%"FF_REG_a", "MM"3           \n\t" // last_non_zero_p1
@@ -220,11 +220,11 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
         : "g" (s->max_qcoeff)
     );
 
-    if(s->mb_intra) block[0]= level;
+    if(s->c.mb_intra) block[0]= level;
     else            block[0]= temp_block[0];
 
-    av_assert2(ARCH_X86_32 || s->idsp.perm_type != FF_IDCT_PERM_SIMPLE);
-    if (ARCH_X86_32 && s->idsp.perm_type == FF_IDCT_PERM_SIMPLE) {
+    av_assert2(ARCH_X86_32 || s->c.idsp.perm_type != FF_IDCT_PERM_SIMPLE);
+    if (ARCH_X86_32 && s->c.idsp.perm_type == FF_IDCT_PERM_SIMPLE) {
         if(last_non_zero_p1 <= 1) goto end;
         block[0x08] = temp_block[0x01]; block[0x10] = temp_block[0x08];
         block[0x20] = temp_block[0x10];
@@ -268,7 +268,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
         block[0x3E] = temp_block[0x3D]; block[0x27] = temp_block[0x36];
         block[0x3D] = temp_block[0x2F]; block[0x2F] = temp_block[0x37];
         block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];
-    }else if(s->idsp.perm_type == FF_IDCT_PERM_LIBMPEG2){
+    }else if(s->c.idsp.perm_type == FF_IDCT_PERM_LIBMPEG2){
         if(last_non_zero_p1 <= 1) goto end;
         block[0x04] = temp_block[0x01];
         block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10];
@@ -312,7 +312,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
         block[0x3E] = temp_block[0x3D]; block[0x33] = temp_block[0x36];
         block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37];
         block[0x3B] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];
-    } else if (s->idsp.perm_type == FF_IDCT_PERM_NONE) {
+    } else if (s->c.idsp.perm_type == FF_IDCT_PERM_NONE) {
         if(last_non_zero_p1 <= 1) goto end;
         block[0x01] = temp_block[0x01];
         block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10];
@@ -356,7 +356,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
         block[0x3D] = temp_block[0x3D]; block[0x36] = temp_block[0x36];
         block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37];
         block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];
-    } else if (s->idsp.perm_type == FF_IDCT_PERM_TRANSPOSE) {
+    } else if (s->c.idsp.perm_type == FF_IDCT_PERM_TRANSPOSE) {
         if(last_non_zero_p1 <= 1) goto end;
         block[0x08] = temp_block[0x01];
         block[0x01] = temp_block[0x08]; block[0x02] = temp_block[0x10];
@@ -401,12 +401,12 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
         block[0x3D] = temp_block[0x2F]; block[0x3E] = temp_block[0x37];
         block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];
     } else {
-        av_log(s->avctx, AV_LOG_DEBUG, "s->idsp.perm_type: %d\n",
-                (int)s->idsp.perm_type);
-        av_assert0(s->idsp.perm_type == FF_IDCT_PERM_NONE ||
-                s->idsp.perm_type == FF_IDCT_PERM_LIBMPEG2 ||
-                s->idsp.perm_type == FF_IDCT_PERM_SIMPLE ||
-                s->idsp.perm_type == FF_IDCT_PERM_TRANSPOSE);
+        av_log(s->c.avctx, AV_LOG_DEBUG, "s->c.idsp.perm_type: %d\n",
+                (int)s->c.idsp.perm_type);
+        av_assert0(s->c.idsp.perm_type == FF_IDCT_PERM_NONE ||
+                s->c.idsp.perm_type == FF_IDCT_PERM_LIBMPEG2 ||
+                s->c.idsp.perm_type == FF_IDCT_PERM_SIMPLE ||
+                s->c.idsp.perm_type == FF_IDCT_PERM_TRANSPOSE);
     }
     end:
     return last_non_zero_p1 - 1;
diff --git a/tests/checkasm/motion.c b/tests/checkasm/motion.c
index 7e322da0d5..960a41a8ed 100644
--- a/tests/checkasm/motion.c
+++ b/tests/checkasm/motion.c
@@ -51,7 +51,7 @@ static void test_motion(const char *name, me_cmp_func test_func)
     LOCAL_ALIGNED_16(uint8_t, img1, [WIDTH * HEIGHT]);
     LOCAL_ALIGNED_16(uint8_t, img2, [WIDTH * HEIGHT]);
 
-    declare_func_emms(AV_CPU_FLAG_MMX, int, struct MpegEncContext *c,
+    declare_func_emms(AV_CPU_FLAG_MMX, int, MPVEncContext *c,
                       const uint8_t *blk1 /* align width (8 or 16) */,
                       const uint8_t *blk2 /* align 1 */, ptrdiff_t stride,
                       int h);
-- 
2.45.2


[-- Attachment #3: 0064-avcodec-mpeg12enc-speedhqenc-Optimize-writing-escape.patch --]
[-- Type: text/x-patch, Size: 2639 bytes --]

From c595a3b0a336d6b06b8a18e3008a6b7e8f989c2d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 12:26:47 +0100
Subject: [PATCH 64/77] avcodec/mpeg12enc, speedhqenc: Optimize writing escape
 codes

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpeg12enc.c  | 9 ++++-----
 libavcodec/speedhqenc.c | 9 ++++-----
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 5a91f9fff1..584573b466 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -628,12 +628,11 @@ next_coef:
                 put_bits(&s->pb, table_vlc[code][1] + 1,
                          (table_vlc[code][0] << 1) + sign);
             } else {
-                /* Escape seems to be pretty rare <5% so I do not optimize it;
-                 * the following value is the common escape value for both
-                 * possible tables (i.e. table_vlc[111]). */
-                put_bits(&s->pb, 6, 0x01);
+                /* Escape seems to be pretty rare <5% so I do not optimize it.
+                 * The following encodes run together with the common escape
+                 * value of both tables 000001b. */
+                put_bits(&s->pb, 6 + 6, 0x01 << 6 | run);
                 /* escape: only clip in this case */
-                put_bits(&s->pb, 6, run);
                 if (s->c.codec_id == AV_CODEC_ID_MPEG1VIDEO) {
                     if (alevel < 128) {
                         put_sbits(&s->pb, 8, level);
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 7ddfb92076..ecba2cd840 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -194,11 +194,10 @@ static void encode_block(MPVEncContext *const s, const int16_t block[], int n)
                             ff_speedhq_vlc_table[code][0] | (sign << ff_speedhq_vlc_table[code][1]));
             } else {
                 /* escape seems to be pretty rare <5% so I do not optimize it;
-                 * the values correspond to ff_speedhq_vlc_table[121] */
-                put_bits_le(&s->pb, 6, 32);
-                /* escape: only clip in this case */
-                put_bits_le(&s->pb, 6, run);
-                put_bits_le(&s->pb, 12, level + 2048);
+                 * The following encodes the escape value 100000b together with
+                 * run and level. */
+                put_bits_le(&s->pb, 6 + 6 + 12, 0x20 | run << 6 |
+                                                (level + 2048) << 12);
             }
             last_non_zero = i;
         }
-- 
2.45.2


[-- Attachment #4: 0065-avcodec-mpegvideo_enc-Move-lambda-lambda2-to-MPVEncC.patch --]
[-- Type: text/x-patch, Size: 15602 bytes --]

From 100d33b5ec28f4535cbcc00061807f1095433c5e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 12:50:06 +0100
Subject: [PATCH 65/77] avcodec/mpegvideo_enc: Move lambda, lambda2 to
 MPVEncContext

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h263enc.h       |  2 +-
 libavcodec/motion_est.c    | 24 +++++++++++-----------
 libavcodec/mpeg4videoenc.c |  2 +-
 libavcodec/mpegvideo.h     |  2 --
 libavcodec/mpegvideo_enc.c | 42 ++++++++++++++++++++------------------
 libavcodec/mpegvideoenc.h  |  2 ++
 libavcodec/snowenc.c       |  6 +++---
 libavcodec/svq1enc.c       |  6 +++---
 8 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index 1f459a332c..63af3a576f 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -52,7 +52,7 @@ static inline int get_p_cbp(MPVEncContext *const s,
         int best_cbpc_score = INT_MAX;
         int cbpc = (-1), cbpy = (-1);
         const int offset = (s->c.mv_type == MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0);
-        const int lambda = s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6);
+        const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
 
         for (int i = 0; i < 4; i++) {
             int score = ff_h263_inter_MCBPC_bits[i + offset] * lambda;
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 923bf5687b..b2b888237b 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -902,9 +902,9 @@ void ff_estimate_p_frame_motion(MPVEncContext *const s,
     av_assert0(s->c.linesize == c->stride);
     av_assert0(s->c.uvlinesize == c->uvstride);
 
-    c->penalty_factor     = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_cmp);
-    c->sub_penalty_factor = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_sub_cmp);
-    c->mb_penalty_factor  = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->mb_cmp);
+    c->penalty_factor     = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
+    c->sub_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
+    c->mb_penalty_factor  = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
     c->current_mv_penalty = c->mv_penalty[s->c.f_code] + MAX_DMV;
 
     get_limits(s, 16*mb_x, 16*mb_y, 0);
@@ -968,14 +968,14 @@ void ff_estimate_p_frame_motion(MPVEncContext *const s,
     c->mc_mb_var_sum_temp += (vard+128)>>8;
 
     if (c->avctx->mb_decision > FF_MB_DECISION_SIMPLE) {
-        int p_score = FFMIN(vard, varc - 500 + (s->c.lambda2 >> FF_LAMBDA_SHIFT)*100);
-        int i_score = varc - 500 + (s->c.lambda2 >> FF_LAMBDA_SHIFT)*20;
+        int p_score = FFMIN(vard, varc - 500 + (s->lambda2 >> FF_LAMBDA_SHIFT)*100);
+        int i_score = varc - 500 + (s->lambda2 >> FF_LAMBDA_SHIFT)*20;
         c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
 
         if (vard*2 + 200*256 > varc && !s->intra_penalty)
             mb_type|= CANDIDATE_MB_TYPE_INTRA;
         if (varc*2 + 200*256 > vard || s->c.qscale > 24){
-//        if (varc*2 + 200*256 + 50*(s->c.lambda2>>FF_LAMBDA_SHIFT) > vard){
+//        if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){
             mb_type|= CANDIDATE_MB_TYPE_INTER;
             c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
             if (s->mpv_flags & FF_MPV_FLAG_MV0)
@@ -1050,8 +1050,8 @@ void ff_estimate_p_frame_motion(MPVEncContext *const s,
             s->c.cur_pic.mb_type[mb_y*s->c.mb_stride + mb_x] = 0;
 
         {
-            int p_score = FFMIN(vard, varc-500+(s->c.lambda2>>FF_LAMBDA_SHIFT)*100);
-            int i_score = varc-500+(s->c.lambda2>>FF_LAMBDA_SHIFT)*20;
+            int p_score = FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
+            int i_score = varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
             c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
         }
     }
@@ -1071,7 +1071,7 @@ int ff_pre_estimate_p_frame_motion(MPVEncContext *const s,
 
     av_assert0(s->c.quarter_sample==0 || s->c.quarter_sample==1);
 
-    c->pre_penalty_factor = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_pre_cmp);
+    c->pre_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp);
     c->current_mv_penalty = c->mv_penalty[s->c.f_code] + MAX_DMV;
 
     get_limits(s, 16*mb_x, 16*mb_y, 0);
@@ -1510,9 +1510,9 @@ void ff_estimate_b_frame_motion(MPVEncContext *const s,
         return;
     }
 
-    c->penalty_factor    = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_cmp);
-    c->sub_penalty_factor= get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->me_sub_cmp);
-    c->mb_penalty_factor = get_penalty_factor(s->c.lambda, s->c.lambda2, c->avctx->mb_cmp);
+    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
+    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
+    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
 
     if (s->c.codec_id == AV_CODEC_ID_MPEG4)
         dmin= direct_search(s, mb_x, mb_y);
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 9f933b517e..fefd94ee99 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -461,7 +461,7 @@ static inline int get_b_cbp(MPVEncContext *const s, int16_t block[6][64],
 
     if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) {
         int score        = 0;
-        const int lambda = s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6);
+        const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
 
         for (i = 0; i < 6; i++) {
             if (s->coded_score[i] < 0) {
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index adaa0cf2d0..5301338188 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -166,8 +166,6 @@ typedef struct MpegEncContext {
 
     int qscale;                 ///< QP
     int chroma_qscale;          ///< chroma QP
-    unsigned int lambda;        ///< Lagrange multiplier used in rate distortion
-    unsigned int lambda2;       ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
     int pict_type;              ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
     int droppable;
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 7061ad0719..6c1d157b64 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -204,7 +204,7 @@ static inline void update_qscale(MPVMainEncContext *const m)
         int best = 1;
 
         for (i = 0 ; i<FF_ARRAY_ELEMS(ff_mpeg2_non_linear_qscale); i++) {
-            int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->c.lambda * 139);
+            int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->lambda * 139);
             if (ff_mpeg2_non_linear_qscale[i] < s->c.avctx->qmin ||
                 (ff_mpeg2_non_linear_qscale[i] > s->c.avctx->qmax && !m->vbv_ignore_qmax))
                 continue;
@@ -215,12 +215,12 @@ static inline void update_qscale(MPVMainEncContext *const m)
         }
         s->c.qscale = best;
     } else {
-        s->c.qscale = (s->c.lambda * 139 + FF_LAMBDA_SCALE * 64) >>
+        s->c.qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >>
                     (FF_LAMBDA_SHIFT + 7);
         s->c.qscale = av_clip(s->c.qscale, s->c.avctx->qmin, m->vbv_ignore_qmax ? 31 : s->c.avctx->qmax);
     }
 
-    s->c.lambda2 = (s->c.lambda * s->c.lambda + FF_LAMBDA_SCALE / 2) >>
+    s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
                  FF_LAMBDA_SHIFT;
 }
 
@@ -261,8 +261,8 @@ static void update_duplicate_context_after_me(MPVEncContext *const dst,
     COPY(c.f_code);
     COPY(c.b_code);
     COPY(c.qscale);
-    COPY(c.lambda);
-    COPY(c.lambda2);
+    COPY(lambda);
+    COPY(lambda2);
     COPY(c.frame_pred_frame_dct); // FIXME don't set in encode_header
     COPY(c.progressive_frame);    // FIXME don't set in encode_header
     COPY(c.partitioned_frame);    // FIXME don't set in encode_header
@@ -1476,7 +1476,7 @@ static int skip_check(MPVMainEncContext *const m,
 
     if (score64 < m->frame_skip_threshold)
         return 1;
-    if (score64 < ((m->frame_skip_factor * (int64_t) s->c.lambda) >> 8))
+    if (score64 < ((m->frame_skip_factor * (int64_t) s->lambda) >> 8))
         return 1;
     return 0;
 }
@@ -1991,8 +1991,8 @@ vbv_retry:
             int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139;
 
             if (put_bits_count(&s->pb) > max_size &&
-                s->c.lambda < m->lmax) {
-                m->next_lambda = FFMAX(s->c.lambda + min_step, s->c.lambda *
+                s->lambda < m->lmax) {
+                m->next_lambda = FFMAX(s->lambda + min_step, s->lambda *
                                        (s->c.qscale + 1) / s->c.qscale);
                 if (s->adaptive_quant) {
                     for (int i = 0; i < s->c.mb_height * s->c.mb_stride; i++)
@@ -2297,8 +2297,8 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
         const int last_qp = s->c.qscale;
         const int mb_xy = mb_x + mb_y * s->c.mb_stride;
 
-        s->c.lambda = s->lambda_table[mb_xy];
-        s->c.lambda2 = (s->c.lambda * s->c.lambda + FF_LAMBDA_SCALE / 2) >>
+        s->lambda  = s->lambda_table[mb_xy];
+        s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
                        FF_LAMBDA_SHIFT;
 
         if (!(s->mpv_flags & FF_MPV_FLAG_QP_RD)) {
@@ -2723,7 +2723,7 @@ static void encode_mb_hq(MPVEncContext *const s, MPVEncContext *const backup, MP
     if(s->c.avctx->mb_decision == FF_MB_DECISION_RD){
         mpv_reconstruct_mb(s, s->c.block);
 
-        score *= s->c.lambda2;
+        score *= s->lambda2;
         score += sse_mb(s) << FF_LAMBDA_SHIFT;
     }
 
@@ -3651,10 +3651,10 @@ static int estimate_qp(MPVMainEncContext *const m, int dry_run)
             break;
         }
 
-        s->c.lambda= s->lambda_table[0];
+        s->lambda = s->lambda_table[0];
         //FIXME broken
     }else
-        s->c.lambda = s->c.cur_pic.ptr->f->quality;
+        s->lambda = s->c.cur_pic.ptr->f->quality;
     update_qscale(m);
     return 0;
 }
@@ -3695,7 +3695,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 
     s->c.me.scene_change_score=0;
 
-//    s->c.lambda= s->c.cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
+//    s->lambda = s->c.cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
 
     if (s->c.pict_type == AV_PICTURE_TYPE_I) {
         s->c.no_rounding = s->c.msmpeg4_version >= MSMP4_V3;
@@ -3710,9 +3710,9 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         ff_get_2pass_fcode(m);
     } else if (!(s->c.avctx->flags & AV_CODEC_FLAG_QSCALE)) {
         if(s->c.pict_type==AV_PICTURE_TYPE_B)
-            s->c.lambda = m->last_lambda_for[s->c.pict_type];
+            s->lambda = m->last_lambda_for[s->c.pict_type];
         else
-            s->c.lambda = m->last_lambda_for[m->last_non_b_pict_type];
+            s->lambda = m->last_lambda_for[m->last_non_b_pict_type];
         update_qscale(m);
     }
 
@@ -3728,6 +3728,8 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
             ret = ff_update_duplicate_context(&slice->c, &s->c);
             if (ret < 0)
                 return ret;
+            slice->lambda  = s->lambda;
+            slice->lambda2 = s->lambda2;
         }
         slice->c.me.temp = slice->c.me.scratchpad = slice->c.sc.scratchpad_buf;
 
@@ -3740,8 +3742,8 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
 
     /* Estimate motion for every MB */
     if (s->c.pict_type != AV_PICTURE_TYPE_I) {
-        s->c.lambda  = (s->c.lambda  * m->me_penalty_compensation + 128) >> 8;
-        s->c.lambda2 = (s->c.lambda2 * (int64_t) m->me_penalty_compensation + 128) >> 8;
+        s->lambda  = (s->lambda  * m->me_penalty_compensation + 128) >> 8;
+        s->lambda2 = (s->lambda2 * (int64_t) m->me_penalty_compensation + 128) >> 8;
         if (s->c.pict_type != AV_PICTURE_TYPE_B) {
             if ((m->me_pre && m->last_non_b_pict_type == AV_PICTURE_TYPE_I) ||
                 m->me_pre == 2) {
@@ -3972,7 +3974,7 @@ static int dct_quantize_trellis_c(MPVEncContext *const s,
     int qmul, qadd, start_i, last_non_zero, i, dc;
     const int esc_length= s->ac_esc_length;
     const uint8_t *length, *last_length;
-    const int lambda= s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6);
+    const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
     int mpeg2_qscale;
 
     s->fdsp.fdct(block);
@@ -4362,7 +4364,7 @@ static int dct_quantize_refine(MPVEncContext *const s, //FIXME breaks denoise?
         av_assert2(w<(1<<6));
         sum += w*w;
     }
-    lambda= sum*(uint64_t)s->c.lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);
+    lambda = sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);
 
     run=0;
     rle_index=0;
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 1d124b1bd1..a2b544d70e 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -47,6 +47,8 @@ typedef struct MPVEncContext {
     /** bit output */
     PutBitContext pb;
 
+    unsigned int lambda;        ///< Lagrange multiplier used in rate distortion
+    unsigned int lambda2;       ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
     int *lambda_table;
     int adaptive_quant;         ///< use adaptive quantization
     int dquant;                 ///< qscale difference to prev qscale
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index f9b10f7dab..269fc8a599 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1873,9 +1873,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         mpv->c.out_format      = FMT_H263;
         mpv->c.unrestricted_mv = 1;
 
-        mpv->c.lambda = enc->lambda;
-        mpv->c.qscale = (mpv->c.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
-        enc->lambda2  = mpv->c.lambda2 = (mpv->c.lambda*mpv->c.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
+        mpv->lambda   = enc->lambda;
+        mpv->c.qscale = (mpv->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
+        enc->lambda2  = mpv->lambda2 = (mpv->lambda*mpv->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
 
         mpv->c.qdsp = enc->qdsp; //move
         mpv->c.hdsp = s->hdsp;
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index ddc94dffe5..6e5146d6a5 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -342,11 +342,11 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
         s2->me.scene_change_score         = 0;
         // s2->out_format                    = FMT_H263;
         // s2->unrestricted_mv               = 1;
-        s2->lambda                        = s->quality;
-        s2->qscale                        = s2->lambda * 139 +
+        s->m.lambda                       = s->quality;
+        s2->qscale                        = s->m.lambda * 139 +
                                              FF_LAMBDA_SCALE * 64 >>
                                              FF_LAMBDA_SHIFT + 7;
-        s2->lambda2                       = s2->lambda * s2->lambda +
+        s->m.lambda2                      = s->m.lambda * s->m.lambda +
                                              FF_LAMBDA_SCALE / 2 >>
                                              FF_LAMBDA_SHIFT;
 
-- 
2.45.2


[-- Attachment #5: 0066-avcodec-mpegvideo_enc-Don-t-reset-statistics-twice.patch --]
[-- Type: text/x-patch, Size: 1735 bytes --]

From ac6283a7d26bad8814372ca70bb8e980a51209dd Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 12:53:44 +0100
Subject: [PATCH 66/77] avcodec/mpegvideo_enc: Don't reset statistics twice

This happens currently for the non-main slice contexts.
But these variables get reset at the start of encode_thread()
anyway for all slices, so this is unnecessary.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 6c1d157b64..7492a9fdbd 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3585,6 +3585,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
     return 0;
 }
 
+#define ADD(field)   dst->field += src->field;
 #define MERGE(field) dst->field += src->field; src->field=0
 static void merge_context_after_me(MPVEncContext *const dst, MPVEncContext *const src)
 {
@@ -3599,14 +3600,14 @@ static void merge_context_after_encode(MPVEncContext *const dst, MPVEncContext *
 
     MERGE(dct_count[0]); //note, the other dct vars are not part of the context
     MERGE(dct_count[1]);
-    MERGE(mv_bits);
-    MERGE(i_tex_bits);
-    MERGE(p_tex_bits);
-    MERGE(i_count);
-    MERGE(misc_bits);
-    MERGE(encoding_error[0]);
-    MERGE(encoding_error[1]);
-    MERGE(encoding_error[2]);
+    ADD(mv_bits);
+    ADD(i_tex_bits);
+    ADD(p_tex_bits);
+    ADD(i_count);
+    ADD(misc_bits);
+    ADD(encoding_error[0]);
+    ADD(encoding_error[1]);
+    ADD(encoding_error[2]);
 
     if (dst->dct_error_sum) {
         for(i=0; i<64; i++){
-- 
2.45.2


[-- Attachment #6: 0067-avcodec-mpegvideoenc-Constify-vlc-length-pointees.patch --]
[-- Type: text/x-patch, Size: 2584 bytes --]

From 658033593eb885ca4fe37804581aae52d886ed89 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 13:03:22 +0100
Subject: [PATCH 67/77] avcodec/mpegvideoenc: Constify vlc length pointees

These pointers point to static tables which must not be modified
by anyone after they have been initialized. So constify the pointees.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/me_cmp.c       |  4 ++--
 libavcodec/mpegvideoenc.h | 14 +++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c
index 09a830d15e..2a8ede5955 100644
--- a/libavcodec/me_cmp.c
+++ b/libavcodec/me_cmp.c
@@ -758,7 +758,7 @@ static int rd8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *s
     LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]);
     int i, last, run, bits, level, distortion, start_i;
     const int esc_length = s->ac_esc_length;
-    uint8_t *length, *last_length;
+    const uint8_t *length, *last_length;
 
     copy_block8(lsrc1, src1, 8, stride, 8);
     copy_block8(lsrc2, src2, 8, stride, 8);
@@ -831,7 +831,7 @@ static int bit8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *
     LOCAL_ALIGNED_16(int16_t, temp, [64]);
     int i, last, run, bits, level, start_i;
     const int esc_length = s->ac_esc_length;
-    uint8_t *length, *last_length;
+    const uint8_t *length, *last_length;
 
     s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
 
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index a2b544d70e..6985c41955 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -87,13 +87,13 @@ typedef struct MPVEncContext {
     int min_qcoeff;          ///< minimum encodable coefficient
     int max_qcoeff;          ///< maximum encodable coefficient
     int ac_esc_length;       ///< num of bits needed to encode the longest esc
-    uint8_t *intra_ac_vlc_length;
-    uint8_t *intra_ac_vlc_last_length;
-    uint8_t *intra_chroma_ac_vlc_length;
-    uint8_t *intra_chroma_ac_vlc_last_length;
-    uint8_t *inter_ac_vlc_length;
-    uint8_t *inter_ac_vlc_last_length;
-    uint8_t *luma_dc_vlc_length;
+    const uint8_t *intra_ac_vlc_length;
+    const uint8_t *intra_ac_vlc_last_length;
+    const uint8_t *intra_chroma_ac_vlc_length;
+    const uint8_t *intra_chroma_ac_vlc_last_length;
+    const uint8_t *inter_ac_vlc_length;
+    const uint8_t *inter_ac_vlc_last_length;
+    const uint8_t *luma_dc_vlc_length;
 
     int coded_score[12];
 
-- 
2.45.2


[-- Attachment #7: 0068-avcodec-motion_est-Move-ff_h263_round_chroma-to-h263.patch --]
[-- Type: text/x-patch, Size: 2953 bytes --]

From 8b1191cb43b627840d57568b36fdbfdc214f6070 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 13:26:37 +0100
Subject: [PATCH 68/77] avcodec/motion_est: Move ff_h263_round_chroma() to
 h263.h

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h263.h             | 10 ++++++++++
 libavcodec/motion_est.c       |  1 +
 libavcodec/motion_est.h       | 10 ----------
 libavcodec/mpegvideo_dec.c    |  1 +
 libavcodec/mpegvideo_motion.c |  1 +
 5 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index 27a5f31c59..59f937070e 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -27,6 +27,16 @@
 
 #define H263_GOB_HEIGHT(h) ((h) <= 400 ? 1 : (h) <= 800 ? 2 : 4)
 
+static inline int ff_h263_round_chroma(int x)
+{
+    //FIXME static or not?
+    static const uint8_t h263_chroma_roundtab[16] = {
+    //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+        0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
+    };
+    return h263_chroma_roundtab[x & 0xf] + (x >> 3);
+}
+
 av_const int ff_h263_aspect_to_info(AVRational aspect);
 int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir,
                              int *px, int *py);
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index b2b888237b..db610c3245 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -32,6 +32,7 @@
 #include <limits.h>
 
 #include "avcodec.h"
+#include "h263.h"
 #include "mathops.h"
 #include "motion_est.h"
 #include "mpegutils.h"
diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h
index 16975abfe1..fe3d61fafb 100644
--- a/libavcodec/motion_est.h
+++ b/libavcodec/motion_est.h
@@ -106,16 +106,6 @@ typedef struct MotionEstContext {
                              int size, int h);
 } MotionEstContext;
 
-static inline int ff_h263_round_chroma(int x)
-{
-    //FIXME static or not?
-    static const uint8_t h263_chroma_roundtab[16] = {
-    //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
-        0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
-    };
-    return h263_chroma_roundtab[x & 0xf] + (x >> 3);
-}
-
 /**
  * Performs one-time initialization of the MotionEstContext.
  */
diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c
index 8c84b59c5e..4019b4f0da 100644
--- a/libavcodec/mpegvideo_dec.c
+++ b/libavcodec/mpegvideo_dec.c
@@ -32,6 +32,7 @@
 
 #include "avcodec.h"
 #include "decode.h"
+#include "h263.h"
 #include "h264chroma.h"
 #include "internal.h"
 #include "mpegutils.h"
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index 6e9368dd9c..edc4931092 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -29,6 +29,7 @@
 
 #include "avcodec.h"
 #include "h261.h"
+#include "h263.h"
 #include "mpegutils.h"
 #include "mpegvideo.h"
 #include "mpeg4videodec.h"
-- 
2.45.2


[-- Attachment #8: 0069-avcodec-mpegvideo-Move-MotionEstContext-to-MPVEncCon.patch --]
[-- Type: text/x-patch, Size: 36306 bytes --]

From fd5e6878a9956b123c1d73d6472bc4acf420a7f5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 14:24:56 +0100
Subject: [PATCH 69/77] avcodec/mpegvideo: Move MotionEstContext to
 MPVEncContext

All that is necessary to do so is perform ff_me_init_pic()
on every slice.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261enc.c             |  2 +-
 libavcodec/ituh263enc.c          |  2 +-
 libavcodec/motion_est.c          | 36 ++++++++++++++--------------
 libavcodec/motion_est_template.c | 32 ++++++++++++-------------
 libavcodec/mpeg12enc.c           |  2 +-
 libavcodec/mpegvideo.c           |  6 -----
 libavcodec/mpegvideo.h           |  3 ---
 libavcodec/mpegvideo_enc.c       | 41 ++++++++++++++++----------------
 libavcodec/mpegvideoenc.h        |  4 +++-
 libavcodec/snowenc.c             | 36 ++++++++++++++--------------
 libavcodec/svq1enc.c             | 24 +++++++++----------
 11 files changed, 90 insertions(+), 98 deletions(-)

diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 7c3c8752df..ae5d7b1205 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -377,7 +377,7 @@ static av_cold int h261_encode_init(AVCodecContext *avctx)
     s->max_qcoeff       = 127;
     s->ac_esc_length    = H261_ESC_LEN;
 
-    s->c.me.mv_penalty = mv_penalty;
+    s->me.mv_penalty = mv_penalty;
 
     s->intra_ac_vlc_length      = s->inter_ac_vlc_length      = uni_h261_rl_len;
     s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len_last;
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 6bd7b6a6cd..2e087c518d 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -820,7 +820,7 @@ av_cold void ff_h263_encode_init(MPVMainEncContext *const m)
 {
     MPVEncContext *const s = &m->s;
 
-    s->c.me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
+    s->me.mv_penalty = ff_h263_get_mv_penalty(); // FIXME exact table for MSMPEG4 & H.263+
 
     ff_h263dsp_init(&s->c.h263dsp);
 
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index db610c3245..af06acd9b2 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -110,7 +110,7 @@ static int get_flags(MotionEstContext *c, int direct, int chroma){
 static av_always_inline int cmp_direct_inline(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int stride= c->stride;
     const int hx = subx + x * (1 << (1 + qpel));
     const int hy = suby + y * (1 << (1 + qpel));
@@ -182,7 +182,7 @@ static av_always_inline int cmp_direct_inline(MPVEncContext *const s, const int
 static av_always_inline int cmp_inline(MPVEncContext *const s, const int x, const int y, const int subx, const int suby,
                       const int size, const int h, int ref_index, int src_index,
                       me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma){
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int stride= c->stride;
     const int uvstride= c->uvstride;
     const int dxy= subx + (suby<<(1+qpel)); //FIXME log2_subpel?
@@ -370,7 +370,7 @@ av_cold int ff_me_init(MotionEstContext *c, AVCodecContext *avctx,
 
 void ff_me_init_pic(MPVEncContext *const s)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
 
 /*FIXME s->c.no_rounding b_type*/
     if (c->avctx->flags & AV_CODEC_FLAG_QPEL) {
@@ -411,7 +411,7 @@ static int sad_hpel_motion_search(MPVEncContext *const s,
                                   int src_index, int ref_index,
                                   int size, int h)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int penalty_factor= c->sub_penalty_factor;
     int mx, my, dminh;
     const uint8_t *pix, *ptr;
@@ -540,7 +540,7 @@ static inline void set_p_mv_tables(MPVEncContext *const s, int mx, int my, int m
  */
 static inline void get_limits(MPVEncContext *const s, int x, int y, int bframe)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL));
     int max_range = MAX_MV >> (1 + !!(c->flags&FLAG_QPEL));
 /*
@@ -587,7 +587,7 @@ static inline void init_mv4_ref(MotionEstContext *c){
 
 static inline int h263_mv4_search(MPVEncContext *const s, int mx, int my, int shift)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int size= 1;
     const int h=8;
     int block;
@@ -730,7 +730,7 @@ static inline int h263_mv4_search(MPVEncContext *const s, int mx, int my, int sh
 
 static inline void init_interlaced_ref(MPVEncContext *const s, int ref_index)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
 
     c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->c.linesize;
     c->src[1][0] = c->src[0][0] + s->c.linesize;
@@ -745,7 +745,7 @@ static inline void init_interlaced_ref(MPVEncContext *const s, int ref_index)
 static int interlaced_search(MPVEncContext *const s, int ref_index,
                              int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int size=0;
     const int h=8;
     int block;
@@ -888,7 +888,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
 void ff_estimate_p_frame_motion(MPVEncContext *const s,
                                 int mb_x, int mb_y)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     const uint8_t *pix, *ppix;
     int sum, mx = 0, my = 0, dmin = 0;
     int varc;            ///< the variance of the block (sum of squared (p[y][x]-average))
@@ -1063,7 +1063,7 @@ void ff_estimate_p_frame_motion(MPVEncContext *const s,
 int ff_pre_estimate_p_frame_motion(MPVEncContext *const s,
                                     int mb_x, int mb_y)
 {
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
     int mx, my, dmin;
     int P[10][2];
     const int shift = 1 + s->c.quarter_sample;
@@ -1116,7 +1116,7 @@ int ff_pre_estimate_p_frame_motion(MPVEncContext *const s,
 static int estimate_motion_b(MPVEncContext *const s, int mb_x, int mb_y,
                              int16_t (*mv_table)[2], int ref_index, int f_code)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     int mx = 0, my = 0, dmin = 0;
     int P[10][2];
     const int shift= 1+s->c.quarter_sample;
@@ -1182,7 +1182,7 @@ static inline int check_bidir_mv(MPVEncContext *const s,
     //FIXME optimize?
     //FIXME better f_code prediction (max mv & distance)
     //FIXME pointers
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     const uint8_t * const mv_penalty_f = c->mv_penalty[s->c.f_code] + MAX_DMV; // f_code of the prev frame
     const uint8_t * const mv_penalty_b = c->mv_penalty[s->c.b_code] + MAX_DMV; // f_code of the prev frame
     int stride= c->stride;
@@ -1239,7 +1239,7 @@ static inline int check_bidir_mv(MPVEncContext *const s,
 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/
 static inline int bidir_refine(MPVEncContext *const s, int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int mot_stride = s->c.mb_stride;
     const int xy = mb_y *mot_stride + mb_x;
     int fbmin;
@@ -1386,7 +1386,7 @@ CHECK_BIDIR(-(a),-(b),-(c),-(d))
 
 static inline int direct_search(MPVEncContext *const s, int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     int P[10][2];
     const int mot_stride = s->c.mb_stride;
     const int mot_xy = mb_y*mot_stride + mb_x;
@@ -1489,7 +1489,7 @@ static inline int direct_search(MPVEncContext *const s, int mb_x, int mb_y)
 void ff_estimate_b_frame_motion(MPVEncContext *const s,
                              int mb_x, int mb_y)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     int fmin, bmin, dmin, fbmin, bimin, fimin;
     int type=0;
     const int xy = mb_y*s->c.mb_stride + mb_x;
@@ -1601,7 +1601,7 @@ void ff_estimate_b_frame_motion(MPVEncContext *const s,
 int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2], int type)
 {
     MPVEncContext *const s = &m->s;
-    MotionEstContext *const c = &s->c.me;
+    MotionEstContext *const c = &s->me;
 
     if (c->motion_est != FF_ME_ZERO) {
         int score[8];
@@ -1656,7 +1656,7 @@ int ff_get_best_fcode(MPVMainEncContext *const m, const int16_t (*mv_table)[2],
 
 void ff_fix_long_p_mvs(MPVEncContext *const s, int type)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int f_code= s->c.f_code;
     int y, range;
     av_assert0(s->c.pict_type==AV_PICTURE_TYPE_P);
@@ -1706,7 +1706,7 @@ void ff_fix_long_p_mvs(MPVEncContext *const s, int type)
 void ff_fix_long_mvs(MPVEncContext *const s, uint8_t *field_select_table, int field_select,
                      int16_t (*mv_table)[2], int f_code, int type, int truncate)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     int y, h_range, v_range;
 
     // RAL: 8 in MPEG-1, 16 in MPEG-4
diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c
index 7c7e645625..aa669e0ee7 100644
--- a/libavcodec/motion_est_template.c
+++ b/libavcodec/motion_est_template.c
@@ -52,7 +52,7 @@ static int hpel_motion_search(MPVEncContext *const s,
                                   int src_index, int ref_index,
                                   int size, int h)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int mx = *mx_ptr;
     const int my = *my_ptr;
     const int penalty_factor= c->sub_penalty_factor;
@@ -166,7 +166,7 @@ static inline int get_mb_score(MPVEncContext *const s, int mx, int my,
                                int src_index, int ref_index, int size,
                                int h, int add_rate)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int penalty_factor= c->mb_penalty_factor;
     const int flags= c->mb_flags;
     const int qpel= flags & FLAG_QPEL;
@@ -209,7 +209,7 @@ static int qpel_motion_search(MPVEncContext *const s,
                                   int src_index, int ref_index,
                                   int size, int h)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     const int mx = *mx_ptr;
     const int my = *my_ptr;
     const int penalty_factor= c->sub_penalty_factor;
@@ -256,7 +256,7 @@ static int qpel_motion_search(MPVEncContext *const s,
         int best_pos[8][2];
 
         memset(best, 64, sizeof(int)*8);
-        if(s->c.me.dia_size>=2){
+        if(s->me.dia_size>=2){
             const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
             const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
             const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
@@ -417,7 +417,7 @@ static av_always_inline int small_diamond_search(MPVEncContext *const s, int *be
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     int next_dir=-1;
     LOAD_COMMON
@@ -458,7 +458,7 @@ static int funny_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     int dia_size;
     LOAD_COMMON
@@ -500,7 +500,7 @@ static int hex_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags, int dia_size)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -534,7 +534,7 @@ static int l2s_dia_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -572,7 +572,7 @@ static int umh_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -619,7 +619,7 @@ static int full_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     LOAD_COMMON
     LOAD_COMMON2
@@ -682,7 +682,7 @@ static int sab_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     Minima minima[MAX_SAB_SIZE];
     const int minima_count= FFABS(c->dia_size);
@@ -772,7 +772,7 @@ static int var_diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     me_cmp_func cmpf, chroma_cmpf;
     int dia_size;
     LOAD_COMMON
@@ -832,7 +832,7 @@ static int var_diamond_search(MPVEncContext *const s, int *best, int dmin,
 static av_always_inline int diamond_search(MPVEncContext *const s, int *best, int dmin,
                                        int src_index, int ref_index, const int penalty_factor,
                                        int size, int h, int flags){
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     if(c->dia_size==-1)
         return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
     else if(c->dia_size<-1)
@@ -861,7 +861,7 @@ static av_always_inline int epzs_motion_search_internal(MPVEncContext *const s,
                              int P[10][2], int src_index, int ref_index, const int16_t (*last_mv)[2],
                              int ref_mv_scale, int flags, int size, int h)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     int best[2]={0, 0};      /**< x and y coordinates of the best motion vector.
                                i.e. the difference between the position of the
                                block currently being encoded and the position of
@@ -979,7 +979,7 @@ int ff_epzs_motion_search(MPVEncContext *const s, int *mx_ptr, int *my_ptr,
                           const int16_t (*last_mv)[2], int ref_mv_scale,
                           int size, int h)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
 //FIXME convert other functions in the same way if faster
     if(c->flags==0 && h==16 && size==0){
         return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
@@ -995,7 +995,7 @@ static int epzs_motion_search2(MPVEncContext *const s,
                              int src_index, int ref_index, const int16_t (*last_mv)[2],
                              int ref_mv_scale, const int size)
 {
-    MotionEstContext * const c= &s->c.me;
+    MotionEstContext *const c = &s->me;
     int best[2]={0, 0};
     int d, dmin;
     unsigned map_generation;
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 584573b466..e4ac256538 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1112,7 +1112,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     m->encode_picture_header = mpeg1_encode_picture_header;
     s->encode_mb             = mpeg12_encode_mb;
 
-    s->c.me.mv_penalty = mv_penalty;
+    s->me.mv_penalty = mv_penalty;
     m->fcode_tab     = fcode_tab + MAX_MV;
     if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
         s->min_qcoeff = -255;
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index a65125cc13..efc9ee24d6 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -406,7 +406,6 @@ static av_cold void free_duplicate_context(MpegEncContext *s)
 
     av_freep(&s->sc.edge_emu_buffer);
     av_freep(&s->sc.scratchpad_buf);
-    s->me.temp = s->me.scratchpad =
     s->sc.obmc_scratchpad = NULL;
     s->sc.linesize = 0;
 
@@ -428,13 +427,10 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
 {
 #define COPY(a) bak->a = src->a
     COPY(sc);
-    COPY(me.map);
-    COPY(me.score_map);
     COPY(blocks);
     COPY(block);
     COPY(start_mb_y);
     COPY(end_mb_y);
-    COPY(me.map_generation);
     COPY(ac_val_base);
     COPY(ac_val[0]);
     COPY(ac_val[1]);
@@ -636,8 +632,6 @@ static void clear_context(MpegEncContext *s)
     s->ac_val[0] =
     s->ac_val[1] =
     s->ac_val[2] =NULL;
-    s->me.scratchpad = NULL;
-    s->me.temp = NULL;
     memset(&s->sc, 0, sizeof(s->sc));
 
 
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 5301338188..1dcfca6b03 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -35,7 +35,6 @@
 #include "h263dsp.h"
 #include "hpeldsp.h"
 #include "idctdsp.h"
-#include "motion_est.h"
 #include "mpegpicture.h"
 #include "qpeldsp.h"
 #include "videodsp.h"
@@ -205,8 +204,6 @@ typedef struct MpegEncContext {
     int last_mv[2][2][2];             ///< last MV, used for MV prediction in MPEG-1 & B-frame MPEG-4
     int16_t direct_scale_mv[2][64];   ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv
 
-    MotionEstContext me;
-
     int no_rounding;  /**< apply no rounding to motion compensation (MPEG-4, msmpeg4, ...)
                         for B-frames rounding mode is always 0 */
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 7492a9fdbd..116ca007ba 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -318,7 +318,7 @@ static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx
     int ret;
 
     ff_me_cmp_init(&mecc, avctx);
-    ret = ff_me_init(&s->c.me, avctx, &mecc, 1);
+    ret = ff_me_init(&s->me, avctx, &mecc, 1);
     if (ret < 0)
         return ret;
     ret = ff_set_cmp(&mecc, me_cmp, m->frame_skip_cmp, 1);
@@ -432,7 +432,7 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
 #else
         ALIGN = 128,
 #endif
-        ME_MAP_ALLOC_SIZE = FFALIGN(2 * ME_MAP_SIZE * sizeof(*s->c.me.map), ALIGN),
+        ME_MAP_ALLOC_SIZE = FFALIGN(2 * ME_MAP_SIZE * sizeof(*s->me.map), ALIGN),
         DCT_ERROR_SIZE    = FFALIGN(2 * sizeof(*s->dct_error_sum), ALIGN),
     };
     static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
@@ -495,8 +495,8 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
         s2->mb_mean      = (uint8_t*)(s2->mb_var + mb_array_size);
         s2->lambda_table = s->lambda_table;
 
-        s2->c.me.map     = (uint32_t*)me_map;
-        s2->c.me.score_map = s2->c.me.map + ME_MAP_SIZE;
+        s2->me.map       = (uint32_t*)me_map;
+        s2->me.score_map = s2->me.map + ME_MAP_SIZE;
         me_map          += ME_MAP_ALLOC_SIZE;
 
         s2->p_mv_table            = tmp_mv_table;
@@ -2791,8 +2791,8 @@ static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){
     MPVEncContext *const s = *(void**)arg;
 
 
-    s->c.me.pre_pass = 1;
-    s->c.me.dia_size = s->c.avctx->pre_dia_size;
+    s->me.pre_pass = 1;
+    s->me.dia_size = s->c.avctx->pre_dia_size;
     s->c.first_slice_line = 1;
     for (s->c.mb_y = s->c.end_mb_y - 1; s->c.mb_y >= s->c.start_mb_y; s->c.mb_y--) {
         for (s->c.mb_x = s->c.mb_width - 1; s->c.mb_x >=0 ; s->c.mb_x--)
@@ -2800,7 +2800,7 @@ static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){
         s->c.first_slice_line = 0;
     }
 
-    s->c.me.pre_pass = 0;
+    s->me.pre_pass = 0;
 
     return 0;
 }
@@ -2808,7 +2808,7 @@ static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){
 static int estimate_motion_thread(AVCodecContext *c, void *arg){
     MPVEncContext *const s = *(void**)arg;
 
-    s->c.me.dia_size= s->c.avctx->dia_size;
+    s->me.dia_size = s->c.avctx->dia_size;
     s->c.first_slice_line=1;
     for (s->c.mb_y = s->c.start_mb_y; s->c.mb_y < s->c.end_mb_y; s->c.mb_y++) {
         s->c.mb_x=0; //for block init below
@@ -2846,7 +2846,7 @@ static int mb_var_thread(AVCodecContext *c, void *arg){
 
             s->mb_var [s->c.mb_stride * mb_y + mb_x] = varc;
             s->mb_mean[s->c.mb_stride * mb_y + mb_x] = (sum+128)>>8;
-            s->c.me.mb_var_sum_temp    += varc;
+            s->me.mb_var_sum_temp    += varc;
         }
     }
     return 0;
@@ -3589,9 +3589,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
 #define MERGE(field) dst->field += src->field; src->field=0
 static void merge_context_after_me(MPVEncContext *const dst, MPVEncContext *const src)
 {
-    MERGE(c.me.scene_change_score);
-    MERGE(c.me.mc_mb_var_sum_temp);
-    MERGE(c.me.mb_var_sum_temp);
+    MERGE(me.scene_change_score);
+    MERGE(me.mc_mb_var_sum_temp);
+    MERGE(me.mb_var_sum_temp);
 }
 
 static void merge_context_after_encode(MPVEncContext *const dst, MPVEncContext *const src)
@@ -3684,8 +3684,8 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     int context_count = s->c.slice_context_count;
 
     /* Reset the average MB variance */
-    s->c.me.mb_var_sum_temp    =
-    s->c.me.mc_mb_var_sum_temp = 0;
+    s->me.mb_var_sum_temp    =
+    s->me.mc_mb_var_sum_temp = 0;
 
     /* we need to initialize some time vars before we can encode B-frames */
     // RAL: Condition added for MPEG1VIDEO
@@ -3694,7 +3694,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     if (CONFIG_MPEG4_ENCODER && s->c.codec_id == AV_CODEC_ID_MPEG4)
         ff_set_mpeg4_time(s);
 
-    s->c.me.scene_change_score=0;
+    s->me.scene_change_score=0;
 
 //    s->lambda = s->c.cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
 
@@ -3717,8 +3717,6 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         update_qscale(m);
     }
 
-    ff_me_init_pic(s);
-
     s->c.mb_intra = 0; //for the rate distortion & bit compare functions
     for (int i = 0; i < context_count; i++) {
         MPVEncContext *const slice = s->c.enc_contexts[i];
@@ -3732,7 +3730,8 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
             slice->lambda  = s->lambda;
             slice->lambda2 = s->lambda2;
         }
-        slice->c.me.temp = slice->c.me.scratchpad = slice->c.sc.scratchpad_buf;
+        slice->me.temp = slice->me.scratchpad = slice->c.sc.scratchpad_buf;
+        ff_me_init_pic(slice);
 
         h     = s->c.mb_height;
         start = pkt->data + (size_t)(((int64_t) pkt->size) * slice->c.start_mb_y / h);
@@ -3770,11 +3769,11 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     for(i=1; i<context_count; i++){
         merge_context_after_me(s, s->c.enc_contexts[i]);
     }
-    m->mc_mb_var_sum = s->c.me.mc_mb_var_sum_temp;
-    m->mb_var_sum    = s->c.me.   mb_var_sum_temp;
+    m->mc_mb_var_sum = s->me.mc_mb_var_sum_temp;
+    m->mb_var_sum    = s->me.   mb_var_sum_temp;
     emms_c();
 
-    if (s->c.me.scene_change_score > m->scenechange_threshold &&
+    if (s->me.scene_change_score > m->scenechange_threshold &&
         s->c.pict_type == AV_PICTURE_TYPE_P) {
         s->c.pict_type = AV_PICTURE_TYPE_I;
         for (int i = 0; i < s->c.mb_stride * s->c.mb_height; i++)
diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h
index 6985c41955..34438714e0 100644
--- a/libavcodec/mpegvideoenc.h
+++ b/libavcodec/mpegvideoenc.h
@@ -33,6 +33,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "fdctdsp.h"
+#include "motion_est.h"
 #include "mpegvideo.h"
 #include "mpegvideoencdsp.h"
 #include "pixblockdsp.h"
@@ -65,6 +66,7 @@ typedef struct MPVEncContext {
     FDCTDSPContext fdsp;
     MpegvideoEncDSPContext mpvencdsp;
     PixblockDSPContext pdsp;
+    MotionEstContext me;
 
     int16_t (*p_mv_table)[2];            ///< MV table (1MV per MB) P-frame
     int16_t (*b_forw_mv_table)[2];       ///< MV table (1MV per MB) forward mode B-frame
@@ -348,7 +350,7 @@ FF_MPV_OPT_CMP_FUNC, \
 
 #define FF_MPV_COMMON_MOTION_EST_OPTS \
 { "mv0",            "always try a mb with mv=<0,0>",                     0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 },    0, 0, FF_MPV_OPT_FLAGS, .unit = "mpv_flags" },\
-{"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(c.me.motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
+{"motion_est", "motion estimation algorithm",                       FF_MPV_OFFSET(me.motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, .unit = "motion_est" },   \
 { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
 { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion_est" }, \
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 269fc8a599..0c99b20379 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -217,7 +217,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     mcf(12,12)
 
     ff_me_cmp_init(&enc->mecc, avctx);
-    ret = ff_me_init(&mpv->c.me, avctx, &enc->mecc, 0);
+    ret = ff_me_init(&mpv->me, avctx, &enc->mecc, 0);
     if (ret < 0)
         return ret;
     ff_mpegvideoencdsp_init(&enc->mpvencdsp, avctx);
@@ -232,15 +232,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
     enc->m.lmax  = avctx->mb_lmax;
     mpv->c.mb_num  = (avctx->width * avctx->height + 255) / 256; // For ratecontrol
 
-    mpv->c.me.temp      =
-    mpv->c.me.scratchpad = av_calloc(avctx->width + 64, 2*16*2*sizeof(uint8_t));
+    mpv->me.temp      =
+    mpv->me.scratchpad = av_calloc(avctx->width + 64, 2*16*2*sizeof(uint8_t));
     mpv->c.sc.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
-    mpv->c.me.map       = av_mallocz(2 * ME_MAP_SIZE * sizeof(*mpv->c.me.map));
-    if (!mpv->c.me.scratchpad || !mpv->c.me.map || !mpv->c.sc.obmc_scratchpad)
+    mpv->me.map       = av_mallocz(2 * ME_MAP_SIZE * sizeof(*mpv->me.map));
+    if (!mpv->me.scratchpad || !mpv->me.map || !mpv->c.sc.obmc_scratchpad)
         return AVERROR(ENOMEM);
-    mpv->c.me.score_map = mpv->c.me.map + ME_MAP_SIZE;
+    mpv->me.score_map = mpv->me.map + ME_MAP_SIZE;
 
-    mpv->c.me.mv_penalty = ff_h263_get_mv_penalty();
+    mpv->me.mv_penalty = ff_h263_get_mv_penalty();
 
     s->max_ref_frames = av_clip(avctx->refs, 1, MAX_REF_FRAMES);
 
@@ -369,7 +369,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
 static int encode_q_branch(SnowEncContext *enc, int level, int x, int y)
 {
     SnowContext      *const s = &enc->com;
-    MotionEstContext *const c = &enc->m.s.c.me;
+    MotionEstContext *const c = &enc->m.s.me;
     uint8_t p_buffer[1024];
     uint8_t i_buffer[1024];
     uint8_t p_state[sizeof(s->block_state)];
@@ -840,12 +840,12 @@ static int get_block_rd(SnowEncContext *enc, int mb_x, int mb_y,
             distortion = 0;
             for(i=0; i<4; i++){
                 int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
-                distortion += enc->m.s.c.me.me_cmp[0](&enc->m.s, src + off, dst + off, ref_stride, 16);
+                distortion += enc->m.s.me.me_cmp[0](&enc->m.s, src + off, dst + off, ref_stride, 16);
             }
         }
     }else{
         av_assert2(block_w==8);
-        distortion = enc->m.s.c.me.me_cmp[0](&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
+        distortion = enc->m.s.me.me_cmp[0](&enc->m.s, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
     }
 
     if(plane_index==0){
@@ -911,7 +911,7 @@ static int get_4block_rd(SnowEncContext *enc, int mb_x, int mb_y, int plane_inde
         }
 
         av_assert1(block_w== 8 || block_w==16);
-        distortion += enc->m.s.c.me.me_cmp[block_w==8](&enc->m.s, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
+        distortion += enc->m.s.me.me_cmp[block_w==8](&enc->m.s, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
     }
 
     if(plane_index==0){
@@ -1866,9 +1866,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         mpv->c.b8_stride  = 2 * mpv->c.mb_width + 1;
         mpv->c.f_code     = 1;
         mpv->c.pict_type  = pic->pict_type;
-        mpv->c.me.motion_est = enc->motion_est;
-        mpv->c.me.scene_change_score = 0;
-        mpv->c.me.dia_size = avctx->dia_size;
+        mpv->me.motion_est = enc->motion_est;
+        mpv->me.scene_change_score = 0;
+        mpv->me.dia_size = avctx->dia_size;
         mpv->c.quarter_sample  = (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0;
         mpv->c.out_format      = FMT_H263;
         mpv->c.unrestricted_mv = 1;
@@ -1937,7 +1937,7 @@ redo_frame:
             if(   plane_index==0
                && pic->pict_type == AV_PICTURE_TYPE_P
                && !(avctx->flags&AV_CODEC_FLAG_PASS2)
-               && mpv->c.me.scene_change_score > enc->scenechange_threshold) {
+               && mpv->me.scene_change_score > enc->scenechange_threshold) {
                 ff_init_range_encoder(c, pkt->data, pkt->size);
                 ff_build_rac_states(c, (1LL<<32)/20, 256-8);
                 pic->pict_type= AV_PICTURE_TYPE_I;
@@ -2092,9 +2092,9 @@ static av_cold int encode_end(AVCodecContext *avctx)
         av_freep(&s->ref_scores[i]);
     }
 
-    enc->m.s.c.me.temp = NULL;
-    av_freep(&enc->m.s.c.me.scratchpad);
-    av_freep(&enc->m.s.c.me.map);
+    enc->m.s.me.temp = NULL;
+    av_freep(&enc->m.s.me.scratchpad);
+    av_freep(&enc->m.s.me.map);
     av_freep(&enc->m.s.c.sc.obmc_scratchpad);
 
     av_freep(&avctx->stats_out);
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 6e5146d6a5..13f86a76db 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -339,7 +339,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
         s2->b8_stride                     = 2 * s2->mb_width + 1;
         s2->f_code                        = 1;
         s2->pict_type                     = s->pict_type;
-        s2->me.scene_change_score         = 0;
+        s->m.me.scene_change_score        = 0;
         // s2->out_format                    = FMT_H263;
         // s2->unrestricted_mv               = 1;
         s->m.lambda                       = s->quality;
@@ -374,7 +374,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
                                              s2->mb_stride + 1;
         ff_me_init_pic(&s->m);
 
-        s2->me.dia_size      = s->avctx->dia_size;
+        s->m.me.dia_size     = s->avctx->dia_size;
         s2->first_slice_line = 1;
         for (y = 0; y < block_height; y++) {
             s->m.new_pic->data[0]  = src - y * 16 * stride; // ugly
@@ -539,8 +539,8 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx)
                s->rd_total / (double)(avctx->width * avctx->height *
                                       avctx->frame_num));
 
-    av_freep(&s->m.c.me.scratchpad);
-    av_freep(&s->m.c.me.map);
+    av_freep(&s->m.me.scratchpad);
+    av_freep(&s->m.me.map);
     av_freep(&s->mb_type);
     av_freep(&s->dummy);
     av_freep(&s->scratchbuf);
@@ -585,7 +585,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
 
     ff_hpeldsp_init(&s->hdsp, avctx->flags);
     ff_me_cmp_init(&s->mecc, avctx);
-    ret = ff_me_init(&s->m.c.me, avctx, &s->mecc, 0);
+    ret = ff_me_init(&s->m.me, avctx, &s->mecc, 0);
     if (ret < 0)
         return ret;
     ff_mpegvideoencdsp_init(&s->m.mpvencdsp, avctx);
@@ -613,24 +613,24 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
         return ret;
 
     s->m.c.picture_structure = PICT_FRAME;
-    s->m.c.me.temp           =
-    s->m.c.me.scratchpad     = av_mallocz((avctx->width + 64) *
+    s->m.me.temp           =
+    s->m.me.scratchpad     = av_mallocz((avctx->width + 64) *
                                         2 * 16 * 2 * sizeof(uint8_t));
     s->mb_type             = av_mallocz((s->y_block_width + 1) *
                                         s->y_block_height * sizeof(int16_t));
     s->dummy               = av_mallocz((s->y_block_width + 1) *
                                         s->y_block_height * sizeof(int32_t));
-    s->m.c.me.map            = av_mallocz(2 * ME_MAP_SIZE * sizeof(*s->m.c.me.map));
+    s->m.me.map            = av_mallocz(2 * ME_MAP_SIZE * sizeof(*s->m.me.map));
     s->m.new_pic       = av_frame_alloc();
 
-    if (!s->m.c.me.scratchpad || !s->m.c.me.map ||
+    if (!s->m.me.scratchpad || !s->m.me.map ||
         !s->mb_type || !s->dummy || !s->m.new_pic)
         return AVERROR(ENOMEM);
-    s->m.c.me.score_map = s->m.c.me.map + ME_MAP_SIZE;
+    s->m.me.score_map = s->m.me.map + ME_MAP_SIZE;
 
     ff_svq1enc_init(&s->svq1encdsp);
 
-    s->m.c.me.mv_penalty = ff_h263_get_mv_penalty();
+    s->m.me.mv_penalty = ff_h263_get_mv_penalty();
 
     return write_ident(avctx, s->avctx->flags & AV_CODEC_FLAG_BITEXACT ? "Lavc" : LIBAVCODEC_IDENT);
 }
@@ -718,7 +718,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 #define OFFSET(x) offsetof(struct SVQ1EncContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "motion-est", "Motion estimation algorithm", OFFSET(m.c.me.motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, .unit = "motion-est"},
+    { "motion-est", "Motion estimation algorithm", OFFSET(m.me.motion_est), AV_OPT_TYPE_INT, { .i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, VE, .unit = "motion-est"},
         { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
         { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
         { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, .unit = "motion-est" },
-- 
2.45.2


[-- Attachment #9: 0070-avcodec-mpegvideo_enc-Move-code-to-initialize-variab.patch --]
[-- Type: text/x-patch, Size: 1972 bytes --]

From df3ea2c7516e6cdbb3c5c4befb80744d7a291099 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 14:47:00 +0100
Subject: [PATCH 70/77] avcodec/mpegvideo_enc: Move code to initialize
 variables immediately

Also avoid casts and parentheses.
(This is only possible now because ff_update_duplicate_context()
no longer touches the PutBitContext.)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 116ca007ba..62e3e5a22f 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3720,8 +3720,11 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     s->c.mb_intra = 0; //for the rate distortion & bit compare functions
     for (int i = 0; i < context_count; i++) {
         MPVEncContext *const slice = s->c.enc_contexts[i];
-        uint8_t *start, *end;
-        int h;
+        int h = s->c.mb_height;
+        uint8_t *start = pkt->data + (int64_t)pkt->size * slice->c.start_mb_y / h;
+        uint8_t *end   = pkt->data + (int64_t)pkt->size * slice->c.  end_mb_y / h;
+
+        init_put_bits(&slice->pb, start, end - start);
 
         if (i) {
             ret = ff_update_duplicate_context(&slice->c, &s->c);
@@ -3732,12 +3735,6 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
         }
         slice->me.temp = slice->me.scratchpad = slice->c.sc.scratchpad_buf;
         ff_me_init_pic(slice);
-
-        h     = s->c.mb_height;
-        start = pkt->data + (size_t)(((int64_t) pkt->size) * slice->c.start_mb_y / h);
-        end   = pkt->data + (size_t)(((int64_t) pkt->size) * slice->c.  end_mb_y / h);
-
-        init_put_bits(&s->c.enc_contexts[i]->pb, start, end - start);
     }
 
     /* Estimate motion for every MB */
-- 
2.45.2


[-- Attachment #10: 0071-avcodec-motion_est-Reset-scene_change-score-MB-varia.patch --]
[-- Type: text/x-patch, Size: 3428 bytes --]

From 3ab911f2164b4c98d27a2f5945720e1ee511c933 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 15:18:17 +0100
Subject: [PATCH 71/77] avcodec/motion_est: Reset scene_change score, MB
 variance stats

Reset them in ff_me_init_pic(). It is the appropriate place for it
and allows to remove resetting code from multiple places
(e.g. mpegvideo_enc.c resetted it in two different places
(one for the main slice context, one for all the others)).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/motion_est.c    |  4 ++++
 libavcodec/mpegvideo_enc.c | 12 +++---------
 libavcodec/snowenc.c       |  1 -
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index af06acd9b2..35f853bc61 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -397,6 +397,10 @@ void ff_me_init_pic(MPVEncContext *const s)
         c->hpel_put[2][0]= c->hpel_put[2][1]=
         c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
     }
+    /* Reset the average MB variance and scene change stats */
+    c->scene_change_score = 0;
+    c->mb_var_sum_temp    =
+    c->mc_mb_var_sum_temp = 0;
 }
 
 #define CHECK_SAD_HALF_MV(suffix, x, y) \
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 62e3e5a22f..e84f1dd467 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3589,9 +3589,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
 #define MERGE(field) dst->field += src->field; src->field=0
 static void merge_context_after_me(MPVEncContext *const dst, MPVEncContext *const src)
 {
-    MERGE(me.scene_change_score);
-    MERGE(me.mc_mb_var_sum_temp);
-    MERGE(me.mb_var_sum_temp);
+    ADD(me.scene_change_score);
+    ADD(me.mc_mb_var_sum_temp);
+    ADD(me.mb_var_sum_temp);
 }
 
 static void merge_context_after_encode(MPVEncContext *const dst, MPVEncContext *const src)
@@ -3683,10 +3683,6 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     int bits;
     int context_count = s->c.slice_context_count;
 
-    /* Reset the average MB variance */
-    s->me.mb_var_sum_temp    =
-    s->me.mc_mb_var_sum_temp = 0;
-
     /* we need to initialize some time vars before we can encode B-frames */
     // RAL: Condition added for MPEG1VIDEO
     if (s->c.out_format == FMT_MPEG1 || (s->c.h263_pred && s->c.msmpeg4_version == MSMP4_UNUSED))
@@ -3694,8 +3690,6 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
     if (CONFIG_MPEG4_ENCODER && s->c.codec_id == AV_CODEC_ID_MPEG4)
         ff_set_mpeg4_time(s);
 
-    s->me.scene_change_score=0;
-
 //    s->lambda = s->c.cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
 
     if (s->c.pict_type == AV_PICTURE_TYPE_I) {
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 0c99b20379..fe71048a45 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1867,7 +1867,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         mpv->c.f_code     = 1;
         mpv->c.pict_type  = pic->pict_type;
         mpv->me.motion_est = enc->motion_est;
-        mpv->me.scene_change_score = 0;
         mpv->me.dia_size = avctx->dia_size;
         mpv->c.quarter_sample  = (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0;
         mpv->c.out_format      = FMT_H263;
-- 
2.45.2


[-- Attachment #11: 0072-avcodec-mpegvideo_enc-Defer-initialization-of-mb-pos.patch --]
[-- Type: text/x-patch, Size: 1866 bytes --]

From 6d2d34ec3b27c315938826233946d2105e3037f3 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 21:28:00 +0100
Subject: [PATCH 72/77] avcodec/mpegvideo_enc: Defer initialization of mb-pos
 dependent vars

Only set them after mb_x and mb_y are known which happens
only after the call to ff_h261_reorder_mb_index().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index e84f1dd467..dc165d92d2 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3024,8 +3024,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
         ff_init_block_index(&s->c);
 
         for (int mb_x = 0; mb_x < s->c.mb_width; mb_x++) {
-            int xy = mb_y*s->c.mb_stride + mb_x; // removed const, H261 needs to adjust this
-            int mb_type= s->mb_type[xy];
+            int mb_type, xy;
 //            int d;
             int dmin= INT_MAX;
             int dir;
@@ -3049,11 +3048,10 @@ static int encode_thread(AVCodecContext *c, void *arg){
             s->c.mb_y = mb_y;  // moved into loop, can get changed by H.261
             ff_update_block_index(&s->c, 8, 0, s->c.chroma_x_shift);
 
-            if(CONFIG_H261_ENCODER && s->c.codec_id == AV_CODEC_ID_H261){
+            if (CONFIG_H261_ENCODER && s->c.codec_id == AV_CODEC_ID_H261)
                 ff_h261_reorder_mb_index(s);
-                xy = s->c.mb_y*s->c.mb_stride + s->c.mb_x;
-                mb_type= s->mb_type[xy];
-            }
+            xy      = s->c.mb_y * s->c.mb_stride + s->c.mb_x;
+            mb_type = s->mb_type[xy];
 
             /* write gob / video packet header  */
             if(s->rtp_mode){
-- 
2.45.2


[-- Attachment #12: 0073-avcodec-mpegvideo_enc-Use-better-variable-name.patch --]
[-- Type: text/x-patch, Size: 1419 bytes --]

From 1ab3662fea849f911618fe9d7276bf49ebbbffd9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 21:55:34 +0100
Subject: [PATCH 73/77] avcodec/mpegvideo_enc: Use better variable name

Also fixes shadowing.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/mpegvideo_enc.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index dc165d92d2..95d774155a 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -534,7 +534,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     MPVMainEncContext *const m = avctx->priv_data;
     MPVEncContext    *const s = &m->s;
     AVCPBProperties *cpb_props;
-    int i, ret;
+    int gcd, ret;
 
     mpv_encode_defaults(m);
 
@@ -818,11 +818,11 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         m->b_frame_strategy = 0;
     }
 
-    i = av_gcd(avctx->time_base.den, avctx->time_base.num);
-    if (i > 1) {
+    gcd = av_gcd(avctx->time_base.den, avctx->time_base.num);
+    if (gcd > 1) {
         av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n");
-        avctx->time_base.den /= i;
-        avctx->time_base.num /= i;
+        avctx->time_base.den /= gcd;
+        avctx->time_base.num /= gcd;
         //return -1;
     }
 
-- 
2.45.2


[-- Attachment #13: 0074-avcodec-h261dec-Set-FF_CODEC_CAP_SKIP_FRAME_FILL_PAR.patch --]
[-- Type: text/x-patch, Size: 841 bytes --]

From 8bf165cbab2064129a3d38ca70b7dd70997978a2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 16:55:22 +0100
Subject: [PATCH 74/77] avcodec/h261dec: Set FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM

This decoder sets the AVCodecContext fields even when a frame
is skipped.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/h261dec.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index c32ddd2ddf..1f57c9f8fe 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -617,4 +617,5 @@ const FFCodec ff_h261_decoder = {
     .close          = ff_mpv_decode_close,
     .p.capabilities = AV_CODEC_CAP_DR1,
     .p.max_lowres   = 3,
+    .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
 };
-- 
2.45.2


[-- Attachment #14: 0075-avcodec-error_resilience-Avoid-me_cmp.h-inclusion.patch --]
[-- Type: text/x-patch, Size: 1441 bytes --]

From 1f32ad151711b371cb1a7a50c138868f3d94e73c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 17:03:31 +0100
Subject: [PATCH 75/77] avcodec/error_resilience: Avoid me_cmp.h inclusion

Use spell out what me_cmp_func means.
Avoids inclusions in the H.264 decoder as well as all
mpegvideo decoders.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/error_resilience.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
index 4005018676..8e43219b09 100644
--- a/libavcodec/error_resilience.h
+++ b/libavcodec/error_resilience.h
@@ -23,7 +23,6 @@
 #include <stdatomic.h>
 
 #include "avcodec.h"
-#include "me_cmp.h"
 
 /// current MB is the first after a resync marker
 #define VP_START               1
@@ -37,6 +36,8 @@
 #define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
 #define ER_MB_END   (ER_AC_END|ER_DC_END|ER_MV_END)
 
+typedef struct MPVEncContext MPVEncContext;
+
 typedef struct ERPicture {
     AVFrame *f;
     const struct ThreadFrame *tf;
@@ -53,7 +54,8 @@ typedef struct ERPicture {
 typedef struct ERContext {
     AVCodecContext *avctx;
 
-    me_cmp_func sad;
+    int (*sad)(MPVEncContext *unused, const uint8_t *blk1,
+               const uint8_t *blk2, ptrdiff_t stride, int h);
     int mecc_inited;
 
     int *mb_index2xy;
-- 
2.45.2


[-- Attachment #15: 0076-avcodec-mpegvideo-Move-unquantize-functions-into-a-f.patch --]
[-- Type: text/x-patch, Size: 22498 bytes --]

From 3df77991b9c503b5c5607f641ca8f7534397e1ca Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sun, 2 Mar 2025 05:44:09 +0100
Subject: [PATCH 76/77] avcodec/mpegvideo: Move unquantize functions into a
 file of their own

This is in preparation for only keeping the actually used
unquantize functions in MpegEncContext.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/Makefile                   |   1 +
 libavcodec/arm/mpegvideo_arm.c        |   1 +
 libavcodec/mips/mpegvideo_init_mips.c |   1 +
 libavcodec/mpegvideo.c                | 237 +---------------------
 libavcodec/mpegvideo.h                |   5 -
 libavcodec/mpegvideo_unquantize.c     | 273 ++++++++++++++++++++++++++
 libavcodec/mpegvideo_unquantize.h     |  37 ++++
 libavcodec/neon/mpegvideo.c           |   1 +
 libavcodec/ppc/mpegvideo_altivec.c    |   1 +
 libavcodec/x86/mpegvideo.c            |   1 +
 10 files changed, 318 insertions(+), 240 deletions(-)
 create mode 100644 libavcodec/mpegvideo_unquantize.c
 create mode 100644 libavcodec/mpegvideo_unquantize.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 37b201ec4a..b2abb3b863 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -147,6 +147,7 @@ OBJS-$(CONFIG_MPEGAUDIOHEADER)         += mpegaudiodecheader.o mpegaudiotabs.o
 OBJS-$(CONFIG_MPEG4AUDIO)              += mpeg4audio.o mpeg4audio_sample_rates.o
 OBJS-$(CONFIG_MPEGVIDEO)               += mpegvideo.o rl.o \
                                           mpegvideo_motion.o \
+                                          mpegvideo_unquantize.o \
                                           mpegvideodata.o mpegpicture.o  \
                                           to_upper4.o
 OBJS-$(CONFIG_MPEGVIDEODEC)            += mpegvideo_dec.o mpegutils.o
diff --git a/libavcodec/arm/mpegvideo_arm.c b/libavcodec/arm/mpegvideo_arm.c
index 28a3f2cdd9..e32451b554 100644
--- a/libavcodec/arm/mpegvideo_arm.c
+++ b/libavcodec/arm/mpegvideo_arm.c
@@ -24,6 +24,7 @@
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideo_unquantize.h"
 #include "mpegvideo_arm.h"
 #include "asm-offsets.h"
 
diff --git a/libavcodec/mips/mpegvideo_init_mips.c b/libavcodec/mips/mpegvideo_init_mips.c
index 1d02b0c937..a9acae94ce 100644
--- a/libavcodec/mips/mpegvideo_init_mips.c
+++ b/libavcodec/mips/mpegvideo_init_mips.c
@@ -20,6 +20,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/mips/cpu.h"
+#include "libavcodec/mpegvideo_unquantize.h"
 #include "h263dsp_mips.h"
 #include "mpegvideo_mips.h"
 
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index efc9ee24d6..9a40937bbd 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -41,221 +41,9 @@
 #include "mpegutils.h"
 #include "mpegvideo.h"
 #include "mpegvideodata.h"
+#include "mpegvideo_unquantize.h"
 #include "libavutil/refstruct.h"
 
-static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
-                                   int16_t *block, int n, int qscale)
-{
-    int i, level, nCoeffs;
-    const uint16_t *quant_matrix;
-
-    nCoeffs= s->block_last_index[n];
-
-    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
-    /* XXX: only MPEG-1 */
-    quant_matrix = s->intra_matrix;
-    for(i=1;i<=nCoeffs;i++) {
-        int j= s->intra_scantable.permutated[i];
-        level = block[j];
-        if (level) {
-            if (level < 0) {
-                level = -level;
-                level = (int)(level * qscale * quant_matrix[j]) >> 3;
-                level = (level - 1) | 1;
-                level = -level;
-            } else {
-                level = (int)(level * qscale * quant_matrix[j]) >> 3;
-                level = (level - 1) | 1;
-            }
-            block[j] = level;
-        }
-    }
-}
-
-static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
-                                   int16_t *block, int n, int qscale)
-{
-    int i, level, nCoeffs;
-    const uint16_t *quant_matrix;
-
-    nCoeffs= s->block_last_index[n];
-
-    quant_matrix = s->inter_matrix;
-    for(i=0; i<=nCoeffs; i++) {
-        int j= s->intra_scantable.permutated[i];
-        level = block[j];
-        if (level) {
-            if (level < 0) {
-                level = -level;
-                level = (((level << 1) + 1) * qscale *
-                         ((int) (quant_matrix[j]))) >> 4;
-                level = (level - 1) | 1;
-                level = -level;
-            } else {
-                level = (((level << 1) + 1) * qscale *
-                         ((int) (quant_matrix[j]))) >> 4;
-                level = (level - 1) | 1;
-            }
-            block[j] = level;
-        }
-    }
-}
-
-static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
-                                   int16_t *block, int n, int qscale)
-{
-    int i, level, nCoeffs;
-    const uint16_t *quant_matrix;
-
-    if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
-    else                 qscale <<= 1;
-
-    nCoeffs= s->block_last_index[n];
-
-    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
-    quant_matrix = s->intra_matrix;
-    for(i=1;i<=nCoeffs;i++) {
-        int j= s->intra_scantable.permutated[i];
-        level = block[j];
-        if (level) {
-            if (level < 0) {
-                level = -level;
-                level = (int)(level * qscale * quant_matrix[j]) >> 4;
-                level = -level;
-            } else {
-                level = (int)(level * qscale * quant_matrix[j]) >> 4;
-            }
-            block[j] = level;
-        }
-    }
-}
-
-static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
-                                   int16_t *block, int n, int qscale)
-{
-    int i, level, nCoeffs;
-    const uint16_t *quant_matrix;
-    int sum=-1;
-
-    if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
-    else                 qscale <<= 1;
-
-    nCoeffs= s->block_last_index[n];
-
-    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
-    sum += block[0];
-    quant_matrix = s->intra_matrix;
-    for(i=1;i<=nCoeffs;i++) {
-        int j= s->intra_scantable.permutated[i];
-        level = block[j];
-        if (level) {
-            if (level < 0) {
-                level = -level;
-                level = (int)(level * qscale * quant_matrix[j]) >> 4;
-                level = -level;
-            } else {
-                level = (int)(level * qscale * quant_matrix[j]) >> 4;
-            }
-            block[j] = level;
-            sum+=level;
-        }
-    }
-    block[63]^=sum&1;
-}
-
-static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
-                                   int16_t *block, int n, int qscale)
-{
-    int i, level, nCoeffs;
-    const uint16_t *quant_matrix;
-    int sum=-1;
-
-    if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
-    else                 qscale <<= 1;
-
-    nCoeffs= s->block_last_index[n];
-
-    quant_matrix = s->inter_matrix;
-    for(i=0; i<=nCoeffs; i++) {
-        int j= s->intra_scantable.permutated[i];
-        level = block[j];
-        if (level) {
-            if (level < 0) {
-                level = -level;
-                level = (((level << 1) + 1) * qscale *
-                         ((int) (quant_matrix[j]))) >> 5;
-                level = -level;
-            } else {
-                level = (((level << 1) + 1) * qscale *
-                         ((int) (quant_matrix[j]))) >> 5;
-            }
-            block[j] = level;
-            sum+=level;
-        }
-    }
-    block[63]^=sum&1;
-}
-
-static void dct_unquantize_h263_intra_c(MpegEncContext *s,
-                                  int16_t *block, int n, int qscale)
-{
-    int i, level, qmul, qadd;
-    int nCoeffs;
-
-    av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
-
-    qmul = qscale << 1;
-
-    if (!s->h263_aic) {
-        block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
-        qadd = (qscale - 1) | 1;
-    }else{
-        qadd = 0;
-    }
-    if(s->ac_pred)
-        nCoeffs=63;
-    else
-        nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
-
-    for(i=1; i<=nCoeffs; i++) {
-        level = block[i];
-        if (level) {
-            if (level < 0) {
-                level = level * qmul - qadd;
-            } else {
-                level = level * qmul + qadd;
-            }
-            block[i] = level;
-        }
-    }
-}
-
-static void dct_unquantize_h263_inter_c(MpegEncContext *s,
-                                  int16_t *block, int n, int qscale)
-{
-    int i, level, qmul, qadd;
-    int nCoeffs;
-
-    av_assert2(s->block_last_index[n]>=0);
-
-    qadd = (qscale - 1) | 1;
-    qmul = qscale << 1;
-
-    nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
-
-    for(i=0; i<=nCoeffs; i++) {
-        level = block[i];
-        if (level) {
-            if (level < 0) {
-                level = level * qmul - qadd;
-            } else {
-                level = level * qmul + qadd;
-            }
-            block[i] = level;
-        }
-    }
-}
-
 
 static void gray16(uint8_t *dst, const uint8_t *src, ptrdiff_t linesize, int h)
 {
@@ -325,28 +113,7 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
     ff_permute_scantable(s->permutated_intra_v_scantable, ff_alternate_vertical_scan,
                          s->idsp.idct_permutation);
 
-    s->dct_unquantize_h263_intra  = dct_unquantize_h263_intra_c;
-    s->dct_unquantize_h263_inter  = dct_unquantize_h263_inter_c;
-    s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
-    s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
-    s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
-    if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT)
-        s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
-    s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
-
-#if HAVE_INTRINSICS_NEON
-    ff_mpv_common_init_neon(s);
-#endif
-
-#if ARCH_ARM
-    ff_mpv_common_init_arm(s);
-#elif ARCH_PPC
-    ff_mpv_common_init_ppc(s);
-#elif ARCH_X86
-    ff_mpv_common_init_x86(s);
-#elif ARCH_MIPS
-    ff_mpv_common_init_mips(s);
-#endif
+    ff_mpv_unquantize_init(s);
 }
 
 static av_cold int init_duplicate_context(MpegEncContext *s)
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 1dcfca6b03..7379160159 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -362,11 +362,6 @@ typedef struct MpegEncContext {
 void ff_mpv_common_defaults(MpegEncContext *s);
 
 int ff_mpv_common_init(MpegEncContext *s);
-void ff_mpv_common_init_arm(MpegEncContext *s);
-void ff_mpv_common_init_neon(MpegEncContext *s);
-void ff_mpv_common_init_ppc(MpegEncContext *s);
-void ff_mpv_common_init_x86(MpegEncContext *s);
-void ff_mpv_common_init_mips(MpegEncContext *s);
 /**
  * Initialize an MpegEncContext's thread contexts. Presumes that
  * slice_context_count is already set and that all the fields
diff --git a/libavcodec/mpegvideo_unquantize.c b/libavcodec/mpegvideo_unquantize.c
new file mode 100644
index 0000000000..12bacdf424
--- /dev/null
+++ b/libavcodec/mpegvideo_unquantize.c
@@ -0,0 +1,273 @@
+/*
+ * Unquantize functions for mpegvideo
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "config.h"
+
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "mpegvideodata.h"
+#include "mpegvideo_unquantize.h"
+
+static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
+                                   int16_t *block, int n, int qscale)
+{
+    int i, level, nCoeffs;
+    const uint16_t *quant_matrix;
+
+    nCoeffs= s->block_last_index[n];
+
+    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+    /* XXX: only MPEG-1 */
+    quant_matrix = s->intra_matrix;
+    for(i=1;i<=nCoeffs;i++) {
+        int j= s->intra_scantable.permutated[i];
+        level = block[j];
+        if (level) {
+            if (level < 0) {
+                level = -level;
+                level = (int)(level * qscale * quant_matrix[j]) >> 3;
+                level = (level - 1) | 1;
+                level = -level;
+            } else {
+                level = (int)(level * qscale * quant_matrix[j]) >> 3;
+                level = (level - 1) | 1;
+            }
+            block[j] = level;
+        }
+    }
+}
+
+static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
+                                   int16_t *block, int n, int qscale)
+{
+    int i, level, nCoeffs;
+    const uint16_t *quant_matrix;
+
+    nCoeffs= s->block_last_index[n];
+
+    quant_matrix = s->inter_matrix;
+    for(i=0; i<=nCoeffs; i++) {
+        int j= s->intra_scantable.permutated[i];
+        level = block[j];
+        if (level) {
+            if (level < 0) {
+                level = -level;
+                level = (((level << 1) + 1) * qscale *
+                         ((int) (quant_matrix[j]))) >> 4;
+                level = (level - 1) | 1;
+                level = -level;
+            } else {
+                level = (((level << 1) + 1) * qscale *
+                         ((int) (quant_matrix[j]))) >> 4;
+                level = (level - 1) | 1;
+            }
+            block[j] = level;
+        }
+    }
+}
+
+static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
+                                   int16_t *block, int n, int qscale)
+{
+    int i, level, nCoeffs;
+    const uint16_t *quant_matrix;
+
+    if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
+    else                 qscale <<= 1;
+
+    nCoeffs= s->block_last_index[n];
+
+    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+    quant_matrix = s->intra_matrix;
+    for(i=1;i<=nCoeffs;i++) {
+        int j= s->intra_scantable.permutated[i];
+        level = block[j];
+        if (level) {
+            if (level < 0) {
+                level = -level;
+                level = (int)(level * qscale * quant_matrix[j]) >> 4;
+                level = -level;
+            } else {
+                level = (int)(level * qscale * quant_matrix[j]) >> 4;
+            }
+            block[j] = level;
+        }
+    }
+}
+
+static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
+                                   int16_t *block, int n, int qscale)
+{
+    int i, level, nCoeffs;
+    const uint16_t *quant_matrix;
+    int sum=-1;
+
+    if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
+    else                 qscale <<= 1;
+
+    nCoeffs= s->block_last_index[n];
+
+    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+    sum += block[0];
+    quant_matrix = s->intra_matrix;
+    for(i=1;i<=nCoeffs;i++) {
+        int j= s->intra_scantable.permutated[i];
+        level = block[j];
+        if (level) {
+            if (level < 0) {
+                level = -level;
+                level = (int)(level * qscale * quant_matrix[j]) >> 4;
+                level = -level;
+            } else {
+                level = (int)(level * qscale * quant_matrix[j]) >> 4;
+            }
+            block[j] = level;
+            sum+=level;
+        }
+    }
+    block[63]^=sum&1;
+}
+
+static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
+                                   int16_t *block, int n, int qscale)
+{
+    int i, level, nCoeffs;
+    const uint16_t *quant_matrix;
+    int sum=-1;
+
+    if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
+    else                 qscale <<= 1;
+
+    nCoeffs= s->block_last_index[n];
+
+    quant_matrix = s->inter_matrix;
+    for(i=0; i<=nCoeffs; i++) {
+        int j= s->intra_scantable.permutated[i];
+        level = block[j];
+        if (level) {
+            if (level < 0) {
+                level = -level;
+                level = (((level << 1) + 1) * qscale *
+                         ((int) (quant_matrix[j]))) >> 5;
+                level = -level;
+            } else {
+                level = (((level << 1) + 1) * qscale *
+                         ((int) (quant_matrix[j]))) >> 5;
+            }
+            block[j] = level;
+            sum+=level;
+        }
+    }
+    block[63]^=sum&1;
+}
+
+static void dct_unquantize_h263_intra_c(MpegEncContext *s,
+                                  int16_t *block, int n, int qscale)
+{
+    int i, level, qmul, qadd;
+    int nCoeffs;
+
+    av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
+
+    qmul = qscale << 1;
+
+    if (!s->h263_aic) {
+        block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+        qadd = (qscale - 1) | 1;
+    }else{
+        qadd = 0;
+    }
+    if(s->ac_pred)
+        nCoeffs=63;
+    else
+        nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
+
+    for(i=1; i<=nCoeffs; i++) {
+        level = block[i];
+        if (level) {
+            if (level < 0) {
+                level = level * qmul - qadd;
+            } else {
+                level = level * qmul + qadd;
+            }
+            block[i] = level;
+        }
+    }
+}
+
+static void dct_unquantize_h263_inter_c(MpegEncContext *s,
+                                  int16_t *block, int n, int qscale)
+{
+    int i, level, qmul, qadd;
+    int nCoeffs;
+
+    av_assert2(s->block_last_index[n]>=0);
+
+    qadd = (qscale - 1) | 1;
+    qmul = qscale << 1;
+
+    nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
+
+    for(i=0; i<=nCoeffs; i++) {
+        level = block[i];
+        if (level) {
+            if (level < 0) {
+                level = level * qmul - qadd;
+            } else {
+                level = level * qmul + qadd;
+            }
+            block[i] = level;
+        }
+    }
+}
+
+av_cold void ff_mpv_unquantize_init(MpegEncContext *s)
+{
+    s->dct_unquantize_h263_intra  = dct_unquantize_h263_intra_c;
+    s->dct_unquantize_h263_inter  = dct_unquantize_h263_inter_c;
+    s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
+    s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
+    s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
+    if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT)
+        s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
+    s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
+
+#if HAVE_INTRINSICS_NEON
+    ff_mpv_common_init_neon(s);
+#endif
+
+#if ARCH_ARM
+    ff_mpv_common_init_arm(s);
+#elif ARCH_PPC
+    ff_mpv_common_init_ppc(s);
+#elif ARCH_X86
+    ff_mpv_common_init_x86(s);
+#elif ARCH_MIPS
+    ff_mpv_common_init_mips(s);
+#endif
+}
diff --git a/libavcodec/mpegvideo_unquantize.h b/libavcodec/mpegvideo_unquantize.h
new file mode 100644
index 0000000000..1e7590561c
--- /dev/null
+++ b/libavcodec/mpegvideo_unquantize.h
@@ -0,0 +1,37 @@
+/*
+ * Unquantize functions for mpegvideo
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_MPEGVIDEO_UNQUANTIZE_H
+#define AVCODEC_MPEGVIDEO_UNQUANTIZE_H
+
+typedef struct MpegEncContext MpegEncContext;
+
+void ff_mpv_unquantize_init(MpegEncContext *s);
+void ff_mpv_common_init_arm(MpegEncContext *s);
+void ff_mpv_common_init_neon(MpegEncContext *s);
+void ff_mpv_common_init_ppc(MpegEncContext *s);
+void ff_mpv_common_init_x86(MpegEncContext *s);
+void ff_mpv_common_init_mips(MpegEncContext *s);
+
+#endif /* AVCODEC_MPEGVIDEO_UNQUANTIZE_H */
diff --git a/libavcodec/neon/mpegvideo.c b/libavcodec/neon/mpegvideo.c
index 8f05d77a65..a8b2a0606d 100644
--- a/libavcodec/neon/mpegvideo.c
+++ b/libavcodec/neon/mpegvideo.c
@@ -32,6 +32,7 @@
 #endif
 
 #include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideo_unquantize.h"
 
 static void inline ff_dct_unquantize_h263_neon(int qscale, int qadd, int nCoeffs,
                                                int16_t *block)
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index bcb59ba845..c361ca7857 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -33,6 +33,7 @@
 #include "libavutil/ppc/util_altivec.h"
 
 #include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideo_unquantize.h"
 
 #if HAVE_ALTIVEC
 
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 9878607a81..11a5ee474b 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -26,6 +26,7 @@
 #include "libavcodec/avcodec.h"
 #include "libavcodec/mpegvideo.h"
 #include "libavcodec/mpegvideodata.h"
+#include "libavcodec/mpegvideo_unquantize.h"
 
 #if HAVE_MMX_INLINE
 
-- 
2.45.2


[-- Attachment #16: 0077-avcodec-mpegvideo-Only-keep-the-actually-used-unquan.patch --]
[-- Type: text/x-patch, Size: 21057 bytes --]

From 3d1656ba8bae3fb1820bca9b929aeb41b2d28b8f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 19 Mar 2025 15:24:57 +0100
Subject: [PATCH 77/77] avcodec/mpegvideo: Only keep the actually used
 unquantize funcs

For all encoders and all decoders except MPEG-4 the unquantize
functions to use don't change at all and therefore needn't be
kept in the context. So discard them after setting them;
for MPEG-4, the functions get assigned on a per-frame basis.

Decoders not using any unquantize functions (H.261, MPEG-1/2)
as well as decoders that only call ff_mpv_reconstruct_mb()
through error resilience (RV30/40, the VC-1 family) don't have
the remaining pointers set at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/arm/mpegvideo_arm.c        |  5 ++--
 libavcodec/arm/mpegvideo_arm.h        |  4 +--
 libavcodec/arm/mpegvideo_armv5te.c    |  2 +-
 libavcodec/h263dec.c                  | 15 ++++-------
 libavcodec/mips/mpegvideo_init_mips.c |  9 ++++---
 libavcodec/mpeg4videodec.c            | 13 +++++++++
 libavcodec/mpeg4videodec.h            |  5 ++++
 libavcodec/mpegvideo.c                |  2 --
 libavcodec/mpegvideo.h                | 12 ---------
 libavcodec/mpegvideo_enc.c            | 34 +++++++++++++++++-------
 libavcodec/mpegvideo_unquantize.c     | 15 ++++++-----
 libavcodec/mpegvideo_unquantize.h     | 38 ++++++++++++++++++++++-----
 libavcodec/neon/mpegvideo.c           |  3 ++-
 libavcodec/ppc/mpegvideo_altivec.c    |  7 ++---
 libavcodec/x86/mpegvideo.c            |  5 ++--
 15 files changed, 108 insertions(+), 61 deletions(-)

diff --git a/libavcodec/arm/mpegvideo_arm.c b/libavcodec/arm/mpegvideo_arm.c
index e32451b554..e5e418b6c4 100644
--- a/libavcodec/arm/mpegvideo_arm.c
+++ b/libavcodec/arm/mpegvideo_arm.c
@@ -46,12 +46,13 @@ void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, int16_t *block,
 void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block,
                                        int n, int qscale);
 
-av_cold void ff_mpv_common_init_arm(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init_arm(MPVUnquantDSPContext *s,
+                                        AVCodecContext *avctx)
 {
     int cpu_flags = av_get_cpu_flags();
 
     if (have_armv5te(cpu_flags))
-        ff_mpv_common_init_armv5te(s);
+        ff_mpv_unquantize_init_armv5te(s);
 
     if (have_neon(cpu_flags)) {
         s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_neon;
diff --git a/libavcodec/arm/mpegvideo_arm.h b/libavcodec/arm/mpegvideo_arm.h
index 709ae6b247..93da7a5664 100644
--- a/libavcodec/arm/mpegvideo_arm.h
+++ b/libavcodec/arm/mpegvideo_arm.h
@@ -19,8 +19,8 @@
 #ifndef AVCODEC_ARM_MPEGVIDEO_ARM_H
 #define AVCODEC_ARM_MPEGVIDEO_ARM_H
 
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/mpegvideo_unquantize.h"
 
-void ff_mpv_common_init_armv5te(MpegEncContext *s);
+void ff_mpv_unquantize_init_armv5te(MPVUnquantDSPContext *s);
 
 #endif /* AVCODEC_ARM_MPEGVIDEO_ARM_H */
diff --git a/libavcodec/arm/mpegvideo_armv5te.c b/libavcodec/arm/mpegvideo_armv5te.c
index e20bb4c645..2737f68643 100644
--- a/libavcodec/arm/mpegvideo_armv5te.c
+++ b/libavcodec/arm/mpegvideo_armv5te.c
@@ -95,7 +95,7 @@ static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s,
     ff_dct_unquantize_h263_armv5te(block, qmul, qadd, nCoeffs + 1);
 }
 
-av_cold void ff_mpv_common_init_armv5te(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init_armv5te(MPVUnquantDSPContext *s)
 {
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te;
     s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te;
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 8434f6e7cf..8d00e5bf3d 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -44,6 +44,7 @@
 #include "mpegvideo.h"
 #include "mpegvideodata.h"
 #include "mpegvideodec.h"
+#include "mpegvideo_unquantize.h"
 #include "msmpeg4dec.h"
 #include "thread.h"
 #include "wmv2dec.h"
@@ -90,6 +91,7 @@ static enum AVPixelFormat h263_get_format(AVCodecContext *avctx)
 av_cold int ff_h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
+    MPVUnquantDSPContext unquant_dsp_ctx;
     int ret;
 
     s->out_format      = FMT_H263;
@@ -105,10 +107,11 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
     s->y_dc_scale_table =
     s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
 
+    ff_mpv_unquantize_init(&unquant_dsp_ctx, avctx, 0);
     // dct_unquantize defaults for H.263;
     // they might change on a per-frame basis for MPEG-4.
-    s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
-    s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
+    s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_h263_intra;
+    s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_h263_inter;
 
     /* select sub codec */
     switch (avctx->codec->id) {
@@ -117,9 +120,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
         avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
         break;
     case AV_CODEC_ID_MPEG4:
-        // dct_unquantize_inter is only used with MPEG-2 quantizers,
-        // so we can already set dct_unquantize_inter here once and for all.
-        s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
         break;
     case AV_CODEC_ID_MSMPEG4V1:
         s->h263_pred       = 1;
@@ -508,11 +508,6 @@ retry:
             goto retry;
         if (s->studio_profile != (s->idsp.idct == NULL))
             ff_mpv_idct_init(s);
-        if (s->mpeg_quant) {
-            s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
-        } else {
-            s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
-        }
     }
 
     /* After H.263 & MPEG-4 header decode we have the height, width,
diff --git a/libavcodec/mips/mpegvideo_init_mips.c b/libavcodec/mips/mpegvideo_init_mips.c
index a9acae94ce..0de8245460 100644
--- a/libavcodec/mips/mpegvideo_init_mips.c
+++ b/libavcodec/mips/mpegvideo_init_mips.c
@@ -24,7 +24,8 @@
 #include "h263dsp_mips.h"
 #include "mpegvideo_mips.h"
 
-av_cold void ff_mpv_common_init_mips(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init_mips(MPVUnquantDSPContext *s,
+                                         AVCodecContext *avctx, int q_scale_type)
 {
     int cpu_flags = av_get_cpu_flags();
 
@@ -34,15 +35,15 @@ av_cold void ff_mpv_common_init_mips(MpegEncContext *s)
         s->dct_unquantize_mpeg1_intra = ff_dct_unquantize_mpeg1_intra_mmi;
         s->dct_unquantize_mpeg1_inter = ff_dct_unquantize_mpeg1_inter_mmi;
 
-        if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT))
-            if (!s->q_scale_type)
+        if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT))
+            if (!q_scale_type)
                 s->dct_unquantize_mpeg2_intra = ff_dct_unquantize_mpeg2_intra_mmi;
     }
 
     if (have_msa(cpu_flags)) {
         s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_msa;
         s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_msa;
-        if (!s->q_scale_type)
+        if (!q_scale_type)
             s->dct_unquantize_mpeg2_inter = ff_dct_unquantize_mpeg2_inter_msa;
     }
 }
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 139b6d4b08..8803801b63 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -35,6 +35,7 @@
 #include "mpegvideo.h"
 #include "mpegvideodata.h"
 #include "mpegvideodec.h"
+#include "mpegvideo_unquantize.h"
 #include "mpeg4video.h"
 #include "mpeg4videodata.h"
 #include "mpeg4videodec.h"
@@ -3390,6 +3391,9 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
         }
     }
 
+    s->dct_unquantize_intra = s->mpeg_quant ? ctx->dct_unquantize_mpeg2_intra
+                                            : ctx->dct_unquantize_h263_intra;
+
 end:
     /* detect buggy encoders which don't set the low_delay flag
      * (divx4/xvid/opendivx). Note we cannot detect divx5 without B-frames
@@ -3862,6 +3866,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     static AVOnce init_static_once = AV_ONCE_INIT;
     Mpeg4DecContext *ctx = avctx->priv_data;
     MpegEncContext *s = &ctx->m;
+    MPVUnquantDSPContext unquant_dsp_ctx;
     int ret;
 
     ctx->divx_version =
@@ -3872,6 +3877,14 @@ static av_cold int decode_init(AVCodecContext *avctx)
     if ((ret = ff_h263_decode_init(avctx)) < 0)
         return ret;
 
+    ff_mpv_unquantize_init(&unquant_dsp_ctx, avctx, 0);
+
+    ctx->dct_unquantize_h263_intra  = unquant_dsp_ctx.dct_unquantize_h263_intra;
+    ctx->dct_unquantize_mpeg2_intra = unquant_dsp_ctx.dct_unquantize_mpeg2_intra;
+    // dct_unquantize_inter is only used with MPEG-2 quantizers,
+    // so we can already set dct_unquantize_inter here once and for all.
+    s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_mpeg2_inter;
+
     s->h263_pred = 1;
     s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */
     s->decode_mb = mpeg4_decode_mb;
diff --git a/libavcodec/mpeg4videodec.h b/libavcodec/mpeg4videodec.h
index bb14d24c88..3a254f2838 100644
--- a/libavcodec/mpeg4videodec.h
+++ b/libavcodec/mpeg4videodec.h
@@ -88,6 +88,11 @@ typedef struct Mpeg4DecContext {
 
     Mpeg4VideoDSPContext mdsp;
 
+    void (*dct_unquantize_mpeg2_intra)(MpegEncContext *s,
+                                       int16_t *block/*align 16*/, int n, int qscale);
+    void (*dct_unquantize_h263_intra)(MpegEncContext *s,
+                                      int16_t *block/*align 16*/, int n, int qscale);
+
     DECLARE_ALIGNED(8, int32_t, block32)[12][64];
     // 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan
     int dpcm_direction;
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 9a40937bbd..794b2d0f66 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -112,8 +112,6 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
                          s->idsp.idct_permutation);
     ff_permute_scantable(s->permutated_intra_v_scantable, ff_alternate_vertical_scan,
                          s->idsp.idct_permutation);
-
-    ff_mpv_unquantize_init(s);
 }
 
 static av_cold int init_duplicate_context(MpegEncContext *s)
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 7379160159..2d60c9ddf0 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -326,18 +326,6 @@ typedef struct MpegEncContext {
 #define SLICE_END       -2 ///<end marker found
 #define SLICE_NOEND     -3 ///<no end marker or error found but mb count exceeded
 
-    void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
-                           int16_t *block/*align 16*/, int n, int qscale);
-    void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
-                           int16_t *block/*align 16*/, int n, int qscale);
-    void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
-                           int16_t *block/*align 16*/, int n, int qscale);
-    void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
-                           int16_t *block/*align 16*/, int n, int qscale);
-    void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
-                           int16_t *block/*align 16*/, int n, int qscale);
-    void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
-                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)
                            int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 95d774155a..7be485bcad 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -60,6 +60,7 @@
 #include "mjpegenc_common.h"
 #include "mathops.h"
 #include "mpegutils.h"
+#include "mpegvideo_unquantize.h"
 #include "mjpegenc.h"
 #include "speedhqenc.h"
 #include "msmpeg4enc.h"
@@ -310,6 +311,24 @@ av_cold void ff_dct_encode_init(MPVEncContext *const s)
         s->dct_quantize  = dct_quantize_trellis_c;
 }
 
+static av_cold void init_unquantize(MpegEncContext *const s, AVCodecContext *avctx)
+{
+    MPVUnquantDSPContext unquant_dsp_ctx;
+
+    ff_mpv_unquantize_init(&unquant_dsp_ctx, avctx, s->q_scale_type);
+
+    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+        s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_mpeg2_intra;
+        s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_mpeg2_inter;
+    } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
+        s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_h263_intra;
+        s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_h263_inter;
+    } else {
+        s->dct_unquantize_intra = unquant_dsp_ctx.dct_unquantize_mpeg1_intra;
+        s->dct_unquantize_inter = unquant_dsp_ctx.dct_unquantize_mpeg1_inter;
+    }
+}
+
 static av_cold int me_cmp_init(MPVMainEncContext *const m, AVCodecContext *avctx)
 {
     MPVEncContext *const s = &m->s;
@@ -1013,6 +1032,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
      * to the slice contexts, so we initialize various fields of it
      * before calling ff_mpv_common_init(). */
     ff_mpv_idct_init(&s->c);
+    init_unquantize(&s->c, avctx);
     ff_fdctdsp_init(&s->fdsp, avctx);
     ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
     ff_pixblockdsp_init(&s->pdsp, avctx);
@@ -1031,15 +1051,11 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
 
     ff_dct_encode_init(s);
 
-    if (s->c.mpeg_quant || s->c.codec_id == AV_CODEC_ID_MPEG2VIDEO) {
-        s->c.dct_unquantize_intra = s->c.dct_unquantize_mpeg2_intra;
-        s->c.dct_unquantize_inter = s->c.dct_unquantize_mpeg2_inter;
-    } else if (s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) {
-        s->c.dct_unquantize_intra = s->c.dct_unquantize_h263_intra;
-        s->c.dct_unquantize_inter = s->c.dct_unquantize_h263_inter;
-    } else {
-        s->c.dct_unquantize_intra = s->c.dct_unquantize_mpeg1_intra;
-        s->c.dct_unquantize_inter = s->c.dct_unquantize_mpeg1_inter;
+    if (s->c.slice_context_count > 1) {
+        s->rtp_mode = 1;
+
+        if (avctx->codec_id == AV_CODEC_ID_H263P)
+            s->c.h263_slice_structured = 1;
     }
 
     if (CONFIG_H263_ENCODER && s->c.out_format == FMT_H263) {
diff --git a/libavcodec/mpegvideo_unquantize.c b/libavcodec/mpegvideo_unquantize.c
index 12bacdf424..fe45f350d7 100644
--- a/libavcodec/mpegvideo_unquantize.c
+++ b/libavcodec/mpegvideo_unquantize.c
@@ -246,28 +246,29 @@ static void dct_unquantize_h263_inter_c(MpegEncContext *s,
     }
 }
 
-av_cold void ff_mpv_unquantize_init(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init(MPVUnquantDSPContext *s,
+                                    AVCodecContext *avctx, int q_scale_type)
 {
     s->dct_unquantize_h263_intra  = dct_unquantize_h263_intra_c;
     s->dct_unquantize_h263_inter  = dct_unquantize_h263_inter_c;
     s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
     s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
     s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
-    if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT)
+    if (avctx->flags & AV_CODEC_FLAG_BITEXACT)
         s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
     s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
 
 #if HAVE_INTRINSICS_NEON
-    ff_mpv_common_init_neon(s);
+    ff_mpv_unquantize_init_neon(s, avctx);
 #endif
 
 #if ARCH_ARM
-    ff_mpv_common_init_arm(s);
+    ff_mpv_unquantize_init_arm(s, avctx);
 #elif ARCH_PPC
-    ff_mpv_common_init_ppc(s);
+    ff_mpv_unquantize_init_ppc(s, avctx);
 #elif ARCH_X86
-    ff_mpv_common_init_x86(s);
+    ff_mpv_unquantize_init_x86(s, avctx);
 #elif ARCH_MIPS
-    ff_mpv_common_init_mips(s);
+    ff_mpv_unquantize_init_mips(s. avctx, q_scale_type);
 #endif
 }
diff --git a/libavcodec/mpegvideo_unquantize.h b/libavcodec/mpegvideo_unquantize.h
index 1e7590561c..cfa349cccd 100644
--- a/libavcodec/mpegvideo_unquantize.h
+++ b/libavcodec/mpegvideo_unquantize.h
@@ -25,13 +25,39 @@
 #ifndef AVCODEC_MPEGVIDEO_UNQUANTIZE_H
 #define AVCODEC_MPEGVIDEO_UNQUANTIZE_H
 
+#include <stdint.h>
+
+#include "config.h"
+
+typedef struct AVCodecContext AVCodecContext;
 typedef struct MpegEncContext MpegEncContext;
 
-void ff_mpv_unquantize_init(MpegEncContext *s);
-void ff_mpv_common_init_arm(MpegEncContext *s);
-void ff_mpv_common_init_neon(MpegEncContext *s);
-void ff_mpv_common_init_ppc(MpegEncContext *s);
-void ff_mpv_common_init_x86(MpegEncContext *s);
-void ff_mpv_common_init_mips(MpegEncContext *s);
+typedef struct MPVUnquantDSPContext {
+    void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
+                           int16_t *block/*align 16*/, int n, int qscale);
+    void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
+                           int16_t *block/*align 16*/, int n, int qscale);
+    void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
+                           int16_t *block/*align 16*/, int n, int qscale);
+    void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
+                           int16_t *block/*align 16*/, int n, int qscale);
+    void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
+                           int16_t *block/*align 16*/, int n, int qscale);
+    void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
+                           int16_t *block/*align 16*/, int n, int qscale);
+} MPVUnquantDSPContext;
+
+#if !ARCH_MIPS
+#define ff_mpv_unquantize_init(s, avctx, q_scale_type) ff_mpv_unquantize_init(s, avctx)
+#endif
+
+void ff_mpv_unquantize_init(MPVUnquantDSPContext *s,
+                            AVCodecContext *avctx, int q_scale_type);
+void ff_mpv_unquantize_init_arm(MPVUnquantDSPContext *s, AVCodecContext *avctx);
+void ff_mpv_unquantize_init_neon(MPVUnquantDSPContext *s, AVCodecContext *avctx);
+void ff_mpv_unquantize_init_ppc(MPVUnquantDSPContext *s, AVCodecContext *avctx);
+void ff_mpv_unquantize_init_x86(MPVUnquantDSPContext *s, AVCodecContext *avctx);
+void ff_mpv_unquantize_init_mips(MPVUnquantDSPContext *s, AVCodecContext *avctx,
+                                 int q_scale_type);
 
 #endif /* AVCODEC_MPEGVIDEO_UNQUANTIZE_H */
diff --git a/libavcodec/neon/mpegvideo.c b/libavcodec/neon/mpegvideo.c
index a8b2a0606d..24cf8fe9b2 100644
--- a/libavcodec/neon/mpegvideo.c
+++ b/libavcodec/neon/mpegvideo.c
@@ -125,7 +125,8 @@ static void dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block,
 }
 
 
-av_cold void ff_mpv_common_init_neon(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init_neon(MPVUnquantDSPContext *s,
+                                         AVCodecContext *avctx)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index c361ca7857..f2801fdd50 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -117,14 +117,15 @@ static void dct_unquantize_h263_altivec(MpegEncContext *s,
 
 #endif /* HAVE_ALTIVEC */
 
-av_cold void ff_mpv_common_init_ppc(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init_ppc(MPVUnquantDSPContext *s,
+                                        AVCodecContext *avctx)
 {
 #if HAVE_ALTIVEC
     if (!PPC_ALTIVEC(av_get_cpu_flags()))
         return;
 
-    if ((s->avctx->dct_algo == FF_DCT_AUTO) ||
-        (s->avctx->dct_algo == FF_DCT_ALTIVEC)) {
+    if ((avctx->dct_algo == FF_DCT_AUTO) ||
+        (avctx->dct_algo == FF_DCT_ALTIVEC)) {
         s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec;
         s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec;
     }
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 11a5ee474b..2d026afc41 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -450,7 +450,8 @@ __asm__ volatile(
 
 #endif /* HAVE_MMX_INLINE */
 
-av_cold void ff_mpv_common_init_x86(MpegEncContext *s)
+av_cold void ff_mpv_unquantize_init_x86(MPVUnquantDSPContext *s,
+                                        AVCodecContext *avctx)
 {
 #if HAVE_MMX_INLINE
     int cpu_flags = av_get_cpu_flags();
@@ -460,7 +461,7 @@ av_cold void ff_mpv_common_init_x86(MpegEncContext *s)
         s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx;
         s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx;
         s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_mmx;
-        if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT))
+        if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT))
             s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx;
         s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx;
     }
-- 
2.45.2


[-- Attachment #17: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-03-19 21:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-19 21:18 [FFmpeg-devel] [PATCH 01/77] avcodec/mpegvideo(_enc)?: Mark init, close functions as, av_cold Andreas Rheinhardt
2025-03-19 21:20 ` Andreas Rheinhardt

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git