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