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