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