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/11] avcodec/mpeg4videodec: Actually check, av_buffer_replace()
@ 2025-03-26  8:40 Andreas Rheinhardt
  2025-03-28  5:17 ` Andreas Rheinhardt
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-26  8:40 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

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

Patches attached, two of which fix regressions. I will apply these two
tonight unless there are objections.

- Andreas

[-- Attachment #2: 0001-avcodec-mpeg4videodec-Actually-check-av_buffer_repla.patch --]
[-- Type: text/x-patch, Size: 1206 bytes --]

From a167afe702eec2bceb76dbc13ada7398a75a5f81 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 02:20:51 +0100
Subject: [PATCH 01/11] avcodec/mpeg4videodec: Actually check
 av_buffer_replace()

Forgotten in 4f2becc2dc4668f837b5ba96c11c3426bc120ac0.

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

diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 7d5af9b877..cb32f0e300 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3795,12 +3795,10 @@ static int mpeg4_update_thread_context(AVCodecContext *dst,
     memcpy(s->sprite_shift, s1->sprite_shift, sizeof(s1->sprite_shift));
     memcpy(s->sprite_traj,  s1->sprite_traj,  sizeof(s1->sprite_traj));
 
-    ret = av_buffer_replace(&s->bitstream_buffer, s1->bitstream_buffer);
-
     if (!init && s1->xvid_build >= 0)
         ff_xvid_idct_init(&s->m.idsp, dst);
 
-    return 0;
+    return av_buffer_replace(&s->bitstream_buffer, s1->bitstream_buffer);
 }
 
 static int mpeg4_update_thread_context_for_user(AVCodecContext *dst,
-- 
2.45.2


[-- Attachment #3: 0002-avcodec-x86-mpegvideoenc_template-Remove-remnants-of.patch --]
[-- Type: text/x-patch, Size: 11054 bytes --]

From f039f3651a86f133c406f3d393d892f8daa31918 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 03:07:55 +0100
Subject: [PATCH 02/11] avcodec/x86/mpegvideoenc_template: Remove remnants of
 MMX

Forgotten in 7284ab789d5fe271b9d6a1666ab5ea6be8724cca.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/x86/mpegvideoenc.c          |  10 --
 libavcodec/x86/mpegvideoenc_template.c | 135 ++++++++++---------------
 2 files changed, 53 insertions(+), 92 deletions(-)

diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index f3c8756d76..d81a8ef14d 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -43,26 +43,16 @@ DECLARE_ALIGNED(16, static const uint16_t, inv_zigzag_direct16)[64] = {
 #if HAVE_6REGS
 
 #if HAVE_SSE2_INLINE
-#undef COMPILE_TEMPLATE_SSE2
-#undef COMPILE_TEMPLATE_SSSE3
-#define COMPILE_TEMPLATE_SSE2   1
 #define COMPILE_TEMPLATE_SSSE3  0
-#undef RENAME
-#undef RENAME_FDCT
 #define RENAME(a)      a ## _sse2
-#define RENAME_FDCT(a) a ## _sse2
 #include "mpegvideoenc_template.c"
 #endif /* HAVE_SSE2_INLINE */
 
 #if HAVE_SSSE3_INLINE
-#undef COMPILE_TEMPLATE_SSE2
 #undef COMPILE_TEMPLATE_SSSE3
-#define COMPILE_TEMPLATE_SSE2   1
 #define COMPILE_TEMPLATE_SSSE3  1
 #undef RENAME
-#undef RENAME_FDCT
 #define RENAME(a)      a ## _ssse3
-#define RENAME_FDCT(a) a ## _sse2
 #include "mpegvideoenc_template.c"
 #endif /* HAVE_SSSE3_INLINE */
 
diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c
index c5418a1b04..85e9159f91 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -29,49 +29,22 @@
 #include "libavcodec/mpegvideoenc.h"
 #include "fdct.h"
 
-#undef MMREG_WIDTH
-#undef MM
-#undef MOVQ
 #undef SPREADW
 #undef PMAXW
 #undef PMAX
 #undef SAVE_SIGN
 #undef RESTORE_SIGN
 
-#if COMPILE_TEMPLATE_SSE2
-#define MMREG_WIDTH "16"
-#define MM "%%xmm"
-#define MOVQ "movdqa"
 #define SPREADW(a) \
             "pshuflw $0, "a", "a"       \n\t"\
             "punpcklwd "a", "a"         \n\t"
-#define PMAXW(a,b) "pmaxsw "a", "b"     \n\t"
 #define PMAX(a,b) \
             "movhlps "a", "b"           \n\t"\
-            PMAXW(b, a)\
+            "pmaxsw "b", "a"            \n\t"\
             "pshuflw $0x0E, "a", "b"    \n\t"\
-            PMAXW(b, a)\
+            "pmaxsw "b", "a"            \n\t"\
             "pshuflw $0x01, "a", "b"    \n\t"\
-            PMAXW(b, a)
-#else
-#define MMREG_WIDTH "8"
-#define MM "%%mm"
-#define MOVQ "movq"
-#define SPREADW(a) \
-            "punpcklwd "a", "a"         \n\t"\
-            "punpcklwd "a", "a"         \n\t"
-#define PMAXW(a,b) \
-            "psubusw "a", "b"           \n\t"\
-            "paddw "a", "b"             \n\t"
-#define PMAX(a,b)  \
-            "movq "a", "b"              \n\t"\
-            "psrlq $32, "a"             \n\t"\
-            PMAXW(b, a)\
-            "movq "a", "b"              \n\t"\
-            "psrlq $16, "a"             \n\t"\
-            PMAXW(b, a)
-
-#endif
+            "pmaxsw "b", "a"            \n\t"
 
 #if COMPILE_TEMPLATE_SSSE3
 #define SAVE_SIGN(a,b) \
@@ -100,7 +73,7 @@ static int RENAME(dct_quantize)(MPVEncContext *const s,
     LOCAL_ALIGNED_16(int16_t, temp_block, [64]);
 
     //s->fdct (block);
-    RENAME_FDCT(ff_fdct)(block); // cannot be anything else ...
+    ff_fdct_sse2(block); // cannot be anything else ...
 
     if(s->dct_error_sum)
         s->denoise_dct(s, block);
@@ -138,32 +111,32 @@ static int RENAME(dct_quantize)(MPVEncContext *const s,
 
     if ((s->c.out_format == FMT_H263 || s->c.out_format == FMT_H261) && !s->c.mpeg_quant) {
         __asm__ volatile(
-            "movd %%"FF_REG_a", "MM"3           \n\t" // last_non_zero_p1
-            SPREADW(MM"3")
-            "pxor "MM"7, "MM"7                  \n\t" // 0
-            "pxor "MM"4, "MM"4                  \n\t" // 0
-            MOVQ" (%2), "MM"5                   \n\t" // qmat[0]
-            "pxor "MM"6, "MM"6                  \n\t"
-            "psubw (%3), "MM"6                  \n\t" // -bias[0]
+            "movd %%"FF_REG_a", %%xmm3          \n\t" // last_non_zero_p1
+            SPREADW("%%xmm3")
+            "pxor  %%xmm7, %%xmm7               \n\t" // 0
+            "pxor  %%xmm4, %%xmm4               \n\t" // 0
+            "movdqa  (%2), %%xmm5               \n\t" // qmat[0]
+            "pxor  %%xmm6, %%xmm6               \n\t"
+            "psubw   (%3), %%xmm6               \n\t" // -bias[0]
             "mov $-128, %%"FF_REG_a"            \n\t"
             ".p2align 4                         \n\t"
             "1:                                 \n\t"
-            MOVQ" (%1, %%"FF_REG_a"), "MM"0     \n\t" // block[i]
-            SAVE_SIGN(MM"1", MM"0")                   // ABS(block[i])
-            "psubusw "MM"6, "MM"0               \n\t" // ABS(block[i]) + bias[0]
-            "pmulhw "MM"5, "MM"0                \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16
-            "por "MM"0, "MM"4                   \n\t"
-            RESTORE_SIGN(MM"1", MM"0")                // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])
-            MOVQ" "MM"0, (%5, %%"FF_REG_a")     \n\t"
-            "pcmpeqw "MM"7, "MM"0               \n\t" // out==0 ? 0xFF : 0x00
-            MOVQ" (%4, %%"FF_REG_a"), "MM"1     \n\t"
-            MOVQ" "MM"7, (%1, %%"FF_REG_a")     \n\t" // 0
-            "pandn "MM"1, "MM"0                 \n\t"
-            PMAXW(MM"0", MM"3")
-            "add $"MMREG_WIDTH", %%"FF_REG_a"   \n\t"
+            "movdqa  (%1, %%"FF_REG_a"), %%xmm0 \n\t" // block[i]
+            SAVE_SIGN("%%xmm1", "%%xmm0")             // ABS(block[i])
+            "psubusw %%xmm6, %%xmm0             \n\t" // ABS(block[i]) + bias[0]
+            "pmulhw  %%xmm5, %%xmm0             \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16
+            "por     %%xmm0, %%xmm4             \n\t"
+            RESTORE_SIGN("%%xmm1", "%%xmm0")          // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])
+            "movdqa  %%xmm0, (%5, %%"FF_REG_a") \n\t"
+            "pcmpeqw %%xmm7, %%xmm0             \n\t" // out==0 ? 0xFF : 0x00
+            "movdqa  (%4, %%"FF_REG_a"), %%xmm1 \n\t"
+            "movdqa  %%xmm7, (%1, %%"FF_REG_a") \n\t" // 0
+            "pandn   %%xmm1, %%xmm0             \n\t"
+            "pmaxsw  %%xmm0, %%xmm3             \n\t"
+            "add        $16, %%"FF_REG_a"       \n\t"
             " js 1b                             \n\t"
-            PMAX(MM"3", MM"0")
-            "movd "MM"3, %%"FF_REG_a"           \n\t"
+            PMAX("%%xmm3", "%%xmm0")
+            "movd %%xmm3, %%"FF_REG_a"          \n\t"
             "movzbl %%al, %%eax                 \n\t" // last_non_zero_p1
             : "+a" (last_non_zero_p1)
             : "r" (block+64), "r" (qmat), "r" (bias),
@@ -173,31 +146,31 @@ static int RENAME(dct_quantize)(MPVEncContext *const s,
         );
     }else{ // FMT_H263
         __asm__ volatile(
-            "movd %%"FF_REG_a", "MM"3           \n\t" // last_non_zero_p1
-            SPREADW(MM"3")
-            "pxor "MM"7, "MM"7                  \n\t" // 0
-            "pxor "MM"4, "MM"4                  \n\t" // 0
+            "movd %%"FF_REG_a", %%xmm3          \n\t" // last_non_zero_p1
+            SPREADW("%%xmm3")
+            "pxor %%xmm7, %%xmm7                \n\t" // 0
+            "pxor %%xmm4, %%xmm4                \n\t" // 0
             "mov $-128, %%"FF_REG_a"            \n\t"
             ".p2align 4                         \n\t"
             "1:                                 \n\t"
-            MOVQ" (%1, %%"FF_REG_a"), "MM"0     \n\t" // block[i]
-            SAVE_SIGN(MM"1", MM"0")                   // ABS(block[i])
-            MOVQ" (%3, %%"FF_REG_a"), "MM"6     \n\t" // bias[0]
-            "paddusw "MM"6, "MM"0               \n\t" // ABS(block[i]) + bias[0]
-            MOVQ" (%2, %%"FF_REG_a"), "MM"5     \n\t" // qmat[i]
-            "pmulhw "MM"5, "MM"0                \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16
-            "por "MM"0, "MM"4                   \n\t"
-            RESTORE_SIGN(MM"1", MM"0")                // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])
-            MOVQ" "MM"0, (%5, %%"FF_REG_a")     \n\t"
-            "pcmpeqw "MM"7, "MM"0               \n\t" // out==0 ? 0xFF : 0x00
-            MOVQ" (%4, %%"FF_REG_a"), "MM"1     \n\t"
-            MOVQ" "MM"7, (%1, %%"FF_REG_a")     \n\t" // 0
-            "pandn "MM"1, "MM"0                 \n\t"
-            PMAXW(MM"0", MM"3")
-            "add $"MMREG_WIDTH", %%"FF_REG_a"   \n\t"
+            "movdqa  (%1, %%"FF_REG_a"), %%xmm0 \n\t" // block[i]
+            SAVE_SIGN("%%xmm1", "%%xmm0")             // ABS(block[i])
+            "movdqa  (%3, %%"FF_REG_a"), %%xmm6 \n\t" // bias[0]
+            "paddusw %%xmm6, %%xmm0             \n\t" // ABS(block[i]) + bias[0]
+            "movdqa  (%2, %%"FF_REG_a"), %%xmm5 \n\t" // qmat[i]
+            "pmulhw  %%xmm5, %%xmm0             \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16
+            "por     %%xmm0, %%xmm4             \n\t"
+            RESTORE_SIGN("%%xmm1", "%%xmm0")          // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i])
+            "movdqa  %%xmm0, (%5, %%"FF_REG_a") \n\t"
+            "pcmpeqw %%xmm7, %%xmm0             \n\t" // out==0 ? 0xFF : 0x00
+            "movdqa  (%4, %%"FF_REG_a"), %%xmm1 \n\t"
+            "movdqa  %%xmm7, (%1, %%"FF_REG_a") \n\t" // 0
+            "pandn   %%xmm1, %%xmm0             \n\t"
+            "pmaxsw  %%xmm0, %%xmm3             \n\t"
+            "add        $16, %%"FF_REG_a"       \n\t"
             " js 1b                             \n\t"
-            PMAX(MM"3", MM"0")
-            "movd "MM"3, %%"FF_REG_a"           \n\t"
+            PMAX("%%xmm3", "%%xmm0")
+            "movd %%xmm3, %%"FF_REG_a"          \n\t"
             "movzbl %%al, %%eax                 \n\t" // last_non_zero_p1
             : "+a" (last_non_zero_p1)
             : "r" (block+64), "r" (qmat+64), "r" (bias+64),
@@ -207,14 +180,12 @@ static int RENAME(dct_quantize)(MPVEncContext *const s,
         );
     }
     __asm__ volatile(
-        "movd %1, "MM"1                     \n\t" // max_qcoeff
-        SPREADW(MM"1")
-        "psubusw "MM"1, "MM"4               \n\t"
-        "packuswb "MM"4, "MM"4              \n\t"
-#if COMPILE_TEMPLATE_SSE2
-        "packsswb "MM"4, "MM"4              \n\t"
-#endif
-        "movd "MM"4, %0                     \n\t" // *overflow
+        "movd         %1, %%xmm1             \n\t" // max_qcoeff
+        SPREADW("%%xmm1")
+        "psubusw  %%xmm1, %%xmm4             \n\t"
+        "packuswb %%xmm4, %%xmm4             \n\t"
+        "packsswb %%xmm4, %%xmm4             \n\t"
+        "movd     %%xmm4, %0                 \n\t" // *overflow
         : "=g" (*overflow)
         : "g" (s->max_qcoeff)
     );
-- 
2.45.2


[-- Attachment #4: 0003-avcodec-mpegvideo_enc-Pass-data_partitioning-directl.patch --]
[-- Type: text/x-patch, Size: 2463 bytes --]

From 9901b63fc2ad7b09e9c9cd5a4776f07026ab08a2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 16:03:38 +0100
Subject: [PATCH 03/11] avcodec/mpegvideo_enc: Pass data_partitioning directly

This avoids having to store it in the backup MPVEncContext.

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

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index ea3bc4ee55..16086bf067 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -2659,7 +2659,8 @@ static inline void copy_context_before_encode(MPVEncContext *const d,
 }
 
 static inline void copy_context_after_encode(MPVEncContext *const d,
-                                             const MPVEncContext *const s)
+                                             const MPVEncContext *const s,
+                                             int data_partitioning)
 {
     int i;
 
@@ -2683,7 +2684,7 @@ static inline void copy_context_after_encode(MPVEncContext *const d,
     d->c.mv_type    = s->c.mv_type;
     d->c.mv_dir     = s->c.mv_dir;
     d->pb= s->pb;
-    if (s->c.data_partitioning) {
+    if (data_partitioning) {
         d->pb2= s->pb2;
         d->tex_pb= s->tex_pb;
     }
@@ -2743,7 +2744,7 @@ static void encode_mb_hq(MPVEncContext *const s, MPVEncContext *const backup, MP
         *dmin= score;
         *next_block^=1;
 
-        copy_context_after_encode(best, s);
+        copy_context_after_encode(best, s, s->c.data_partitioning);
     }
 }
 
@@ -3164,8 +3165,6 @@ static int encode_thread(AVCodecContext *c, void *arg){
 
                 copy_context_before_encode(&backup_s, s);
                 backup_s.pb= s->pb;
-                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;
@@ -3389,7 +3388,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     }
                 }
 
-                copy_context_after_encode(s, &best_s);
+                copy_context_after_encode(s, &best_s, s->c.data_partitioning);
 
                 pb_bits_count= put_bits_count(&s->pb);
                 flush_put_bits(&s->pb);
-- 
2.45.2


[-- Attachment #5: 0004-avcodec-mpegvideo_enc-Don-t-use-unnecessarily-much-s.patch --]
[-- Type: text/x-patch, Size: 10912 bytes --]

From 3c0df27067d0e0758fc72bbe31c5cab7eb2c8ed2 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 18:00:25 +0100
Subject: [PATCH 04/11] avcodec/mpegvideo_enc: Don't use unnecessarily much
 stack

encode_thread() puts two MPVEncContexts (2*6516B here)
on the stack and zeroes one of them in order to
temporarily store the variables that get changed
during encoding a macroblock (when there is more than
one candidate type for a macroblock). This is wasteful
and therefore this commit adds a small (328B here) structure
to store exactly the fields that actually need to be backed
up. Then one can extend MPVEncContext without fearing
too use up to much stack.

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

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 16086bf067..fb3ad2e25c 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -2631,80 +2631,100 @@ static void encode_mb(MPVEncContext *const s, int motion_x, int motion_y)
         encode_mb_internal(s, motion_x, motion_y, 16, 16, 12, 0, 0, CHROMA_444);
 }
 
-static inline void copy_context_before_encode(MPVEncContext *const d,
-                                              const MPVEncContext *const s)
-{
-    int i;
-
-    memcpy(d->c.last_mv, s->c.last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
-
-    /* MPEG-1 */
-    d->c.mb_skip_run = s->c.mb_skip_run;
-    for(i=0; i<3; i++)
-        d->c.last_dc[i] = s->c.last_dc[i];
-
-    /* statistics */
-    d->mv_bits= s->mv_bits;
-    d->i_tex_bits= s->i_tex_bits;
-    d->p_tex_bits= s->p_tex_bits;
-    d->i_count= s->i_count;
-    d->misc_bits= s->misc_bits;
-    d->last_bits= 0;
-
-    d->c.mb_skipped = 0;
-    d->c.qscale = s->c.qscale;
-    d->dquant= s->dquant;
-
-    d->esc3_level_length= s->esc3_level_length;
+typedef struct MBBackup {
+    struct {
+        int mv[2][4][2];
+        int last_mv[2][2][2];
+        int mv_type, mv_dir;
+        int last_dc[3];
+        int mb_intra, mb_skipped, mb_skip_run;
+        int qscale;
+        int block_last_index[8];
+        int interlaced_dct;
+        int16_t (*block)[64];
+    } c;
+    int mv_bits, i_tex_bits, p_tex_bits, i_count, misc_bits, last_bits;
+    int dquant;
+    int esc3_level_length;
+    PutBitContext pb, pb2, tex_pb;
+} MBBackup;
+
+#define COPY_CONTEXT(BEFORE, AFTER, DST_TYPE, SRC_TYPE)                     \
+static inline void BEFORE ##_context_before_encode(DST_TYPE *const d,       \
+                                                   const SRC_TYPE *const s) \
+{                                                                           \
+    /* FIXME is memcpy faster than a loop? */                               \
+    memcpy(d->c.last_mv, s->c.last_mv, 2*2*2*sizeof(int));                  \
+                                                                            \
+    /* MPEG-1 */                                                            \
+    d->c.mb_skip_run = s->c.mb_skip_run;                                    \
+    for (int i = 0; i < 3; i++)                                             \
+        d->c.last_dc[i] = s->c.last_dc[i];                                  \
+                                                                            \
+    /* statistics */                                                        \
+    d->mv_bits    = s->mv_bits;                                             \
+    d->i_tex_bits = s->i_tex_bits;                                          \
+    d->p_tex_bits = s->p_tex_bits;                                          \
+    d->i_count    = s->i_count;                                             \
+    d->misc_bits  = s->misc_bits;                                           \
+    d->last_bits  = 0;                                                      \
+                                                                            \
+    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 AFTER ## _context_after_encode(DST_TYPE *const d,        \
+                                                  const SRC_TYPE *const s,  \
+                                                  int data_partitioning)    \
+{                                                                           \
+    /* 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));                  \
+                                                                            \
+    /* MPEG-1 */                                                            \
+    d->c.mb_skip_run = s->c.mb_skip_run;                                    \
+    for (int i = 0; i < 3; i++)                                             \
+        d->c.last_dc[i] = s->c.last_dc[i];                                  \
+                                                                            \
+    /* statistics */                                                        \
+    d->mv_bits    = s->mv_bits;                                             \
+    d->i_tex_bits = s->i_tex_bits;                                          \
+    d->p_tex_bits = s->p_tex_bits;                                          \
+    d->i_count    = s->i_count;                                             \
+    d->misc_bits  = s->misc_bits;                                           \
+                                                                            \
+    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 (data_partitioning) {                                                \
+        d->pb2    = s->pb2;                                                 \
+        d->tex_pb = s->tex_pb;                                              \
+    }                                                                       \
+    d->c.block = s->c.block;                                                \
+    for (int i = 0; i < 8; i++)                                             \
+        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 inline void copy_context_after_encode(MPVEncContext *const d,
-                                             const MPVEncContext *const s,
-                                             int data_partitioning)
-{
-    int i;
-
-    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->c.mb_skip_run = s->c.mb_skip_run;
-    for(i=0; i<3; i++)
-        d->c.last_dc[i] = s->c.last_dc[i];
-
-    /* statistics */
-    d->mv_bits= s->mv_bits;
-    d->i_tex_bits= s->i_tex_bits;
-    d->p_tex_bits= s->p_tex_bits;
-    d->i_count= s->i_count;
-    d->misc_bits= s->misc_bits;
-
-    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 (data_partitioning) {
-        d->pb2= s->pb2;
-        d->tex_pb= s->tex_pb;
-    }
-    d->c.block = s->c.block;
-    for(i=0; i<8; i++)
-        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;
-}
+COPY_CONTEXT(backup, save, MBBackup, MPVEncContext)
+COPY_CONTEXT(reset, store, MPVEncContext, MBBackup)
 
-static void encode_mb_hq(MPVEncContext *const s, MPVEncContext *const backup, MPVEncContext *const best,
+static void encode_mb_hq(MPVEncContext *const s, MBBackup *const backup, MBBackup *const best,
                          PutBitContext pb[2], PutBitContext pb2[2], PutBitContext tex_pb[2],
                          int *dmin, int *next_block, int motion_x, int motion_y)
 {
     int score;
     uint8_t *dest_backup[3];
 
-    copy_context_before_encode(s, backup);
+    reset_context_before_encode(s, backup);
 
     s->c.block = s->c.blocks[*next_block];
     s->pb      = pb[*next_block];
@@ -2744,7 +2764,7 @@ static void encode_mb_hq(MPVEncContext *const s, MPVEncContext *const backup, MP
         *dmin= score;
         *next_block^=1;
 
-        copy_context_after_encode(best, s, s->c.data_partitioning);
+        save_context_after_encode(best, s, s->c.data_partitioning);
     }
 }
 
@@ -2962,7 +2982,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
     MPVEncContext *const s = *(void**)arg;
     int chr_h = 16 >> s->c.chroma_y_shift;
     int i;
-    MPVEncContext best_s = { 0 }, backup_s;
+    MBBackup 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];
@@ -3163,7 +3183,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                 int next_block=0;
                 int pb_bits_count, pb2_bits_count, tex_pb_bits_count;
 
-                copy_context_before_encode(&backup_s, s);
+                backup_context_before_encode(&backup_s, s);
                 backup_s.pb= s->pb;
                 if (s->c.data_partitioning) {
                     backup_s.pb2= s->pb2;
@@ -3388,7 +3408,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     }
                 }
 
-                copy_context_after_encode(s, &best_s, s->c.data_partitioning);
+                store_context_after_encode(s, &best_s, s->c.data_partitioning);
 
                 pb_bits_count= put_bits_count(&s->pb);
                 flush_put_bits(&s->pb);
-- 
2.45.2


[-- Attachment #6: 0005-avcodec-mpegvideo_enc-Set-b-frame-chain-length-prope.patch --]
[-- Type: text/x-patch, Size: 1295 bytes --]

From 3b229dc34e11826e18f42c228b77596ff30c8776 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 26 Mar 2025 08:38:58 +0100
Subject: [PATCH 05/11] avcodec/mpegvideo_enc: Set b-frame chain length
 properly

Fixes a regression caused by my desire to use loop-scope
for iterators in 72bf3d3c12ae562fd408603483bc59058757b1a1.

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

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index fb3ad2e25c..febe50930b 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1726,8 +1726,9 @@ static int set_bframe_chain_length(MPVMainEncContext *const m)
                                         s->c.linesize) + 1;
                 }
             }
-            for (int i = 0; i < m->max_b_frames + 1; i++) {
-                if (!m->input_picture[i] ||
+            for (int i = 0;; i++) {
+                if (i >= m->max_b_frames + 1 ||
+                    !m->input_picture[i] ||
                     m->input_picture[i]->b_frame_score - 1 >
                         s->c.mb_num / m->b_sensitivity) {
                     b_frames = FFMAX(0, i - 1);
-- 
2.45.2


[-- Attachment #7: 0006-fate-vcodec-Test-non-default-b_strategy.patch --]
[-- Type: text/x-patch, Size: 2985 bytes --]

From 483932d3eac7a4ab9f2fb9cca214ace1c44e01cf Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Wed, 26 Mar 2025 09:05:38 +0100
Subject: [PATCH 06/11] fate/vcodec: Test non-default b_strategy

With this modification the test would have caught the regression
introduced in 72bf3d3c12ae562fd408603483bc59058757b1a1.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 tests/fate/vcodec.mak               | 3 ++-
 tests/ref/vsynth/vsynth1-mpeg4-adap | 8 ++++----
 tests/ref/vsynth/vsynth3-mpeg4-adap | 8 ++++----
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
index 8a9083d4ed..f433feac69 100644
--- a/tests/fate/vcodec.mak
+++ b/tests/fate/vcodec.mak
@@ -306,7 +306,8 @@ fate-vsynth%-mpeg4:              FMT     = mp4
 fate-vsynth%-mpeg4-adap:         ENCOPTS = -b 550k -bf 2 -flags +mv4     \
                                            -trellis 1 -cmp 1 -subcmp 2   \
                                            -mbd rd -scplx_mask 0.3       \
-                                           -mpv_flags +mv0
+                                           -mpv_flags +mv0               \
+                                           -b_strategy 1 -b_sensitivity 5
 
 fate-vsynth%-mpeg4-adv:          ENCOPTS = -qscale 9 -flags +mv4+aic       \
                                            -data_partitioning 1 -trellis 1 \
diff --git a/tests/ref/vsynth/vsynth1-mpeg4-adap b/tests/ref/vsynth/vsynth1-mpeg4-adap
index d3ad12e921..8fd0384f31 100644
--- a/tests/ref/vsynth/vsynth1-mpeg4-adap
+++ b/tests/ref/vsynth/vsynth1-mpeg4-adap
@@ -1,4 +1,4 @@
-3b4fe7ad106cb112364d062b20ad80a8 *tests/data/fate/vsynth1-mpeg4-adap.avi
-325594 tests/data/fate/vsynth1-mpeg4-adap.avi
-96c5a7759413ab24afaa926abb3c5fe0 *tests/data/fate/vsynth1-mpeg4-adap.out.rawvideo
-stddev:   14.11 PSNR: 25.13 MAXDIFF:  184 bytes:  7603200/  7603200
+3a889f498a36c3bce59924887e73990f *tests/data/fate/vsynth1-mpeg4-adap.avi
+264468 tests/data/fate/vsynth1-mpeg4-adap.avi
+8333845e5dfdb913d08570b7edf8682f *tests/data/fate/vsynth1-mpeg4-adap.out.rawvideo
+stddev:   13.94 PSNR: 25.24 MAXDIFF:  165 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth3-mpeg4-adap b/tests/ref/vsynth/vsynth3-mpeg4-adap
index 70a25831d9..d85d648729 100644
--- a/tests/ref/vsynth/vsynth3-mpeg4-adap
+++ b/tests/ref/vsynth/vsynth3-mpeg4-adap
@@ -1,4 +1,4 @@
-10512ee1a666ed95643557e1cf699363 *tests/data/fate/vsynth3-mpeg4-adap.avi
-41100 tests/data/fate/vsynth3-mpeg4-adap.avi
-9ba2c3cab3f08d2a345b849d0b30e3e1 *tests/data/fate/vsynth3-mpeg4-adap.out.rawvideo
-stddev:    5.79 PSNR: 32.88 MAXDIFF:   49 bytes:    86700/    86700
+974af2dfb1f81c8030d813617f989b9d *tests/data/fate/vsynth3-mpeg4-adap.avi
+42096 tests/data/fate/vsynth3-mpeg4-adap.avi
+96839ddca31edf7c9d392c358262a6d4 *tests/data/fate/vsynth3-mpeg4-adap.out.rawvideo
+stddev:    4.94 PSNR: 34.25 MAXDIFF:   49 bytes:    86700/    86700
-- 
2.45.2


[-- Attachment #8: 0007-avcodec-motion_est-Put-map-me_map-into-MotionEstCont.patch --]
[-- Type: text/x-patch, Size: 6253 bytes --]

From c0215651a2b84f8f5faf56ebab4b86643b571402 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 03:23:13 +0100
Subject: [PATCH 07/11] avcodec/motion_est: Put map, me_map into
 MotionEstContext

They have a fixed size and given that nowadays
MotionEstContext is no longer in any decoder's private context,
it is not wasteful to just put it into there.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/motion_est.h    |  5 +++--
 libavcodec/mpegvideo_enc.c | 15 ++-------------
 libavcodec/snowenc.c       |  5 +----
 libavcodec/svq1enc.c       |  5 +----
 4 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h
index fe3d61fafb..89a2f41b75 100644
--- a/libavcodec/motion_est.h
+++ b/libavcodec/motion_est.h
@@ -55,8 +55,6 @@ typedef struct MotionEstContext {
     uint8_t *scratchpad;            /**< data area for the ME algo, so that
                                      * the ME does not need to malloc/free. */
     uint8_t *temp;
-    uint32_t *map;                  ///< map to avoid duplicate evaluations
-    uint32_t *score_map;            ///< map to store the scores
     unsigned map_generation;
     int pre_penalty_factor;
     int penalty_factor;             /**< an estimate of the bits required to
@@ -104,6 +102,9 @@ typedef struct MotionEstContext {
                              int *mx_ptr, int *my_ptr, int dmin,
                              int src_index, int ref_index,
                              int size, int h);
+
+    uint32_t map[ME_MAP_SIZE];      ///< map to avoid duplicate evaluations
+    uint32_t score_map[ME_MAP_SIZE];///< map to store the scores
 } MotionEstContext;
 
 /**
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index febe50930b..3d67df8d73 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -451,13 +451,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),
         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,
+    static_assert(DCT_ERROR_SIZE * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
                   "Need checks for potential overflow.");
     unsigned nb_slices = s->c.slice_context_count, mv_table_size, mb_array_size;
-    char *dct_error = NULL, *me_map;
+    char *dct_error = NULL;
     int has_b_frames = !!m->max_b_frames, nb_mv_tables = 1 + 5 * has_b_frames;
     int16_t (*mv_table)[2];
 
@@ -470,11 +469,6 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
         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;
 
     /* Allocate MB type table */
     mb_array_size = s->c.mb_stride * s->c.mb_height;
@@ -514,10 +508,6 @@ 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;
-        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;
@@ -1132,7 +1122,6 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
     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);
 
     av_freep(&s->mb_type);
     av_freep(&s->lambda_table);
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index a15960e4a3..7818c79fa6 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -235,10 +235,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
     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->me.map       = av_mallocz(2 * ME_MAP_SIZE * sizeof(*mpv->me.map));
-    if (!mpv->me.scratchpad || !mpv->me.map || !mpv->c.sc.obmc_scratchpad)
+    if (!mpv->me.scratchpad || !mpv->c.sc.obmc_scratchpad)
         return AVERROR(ENOMEM);
-    mpv->me.score_map = mpv->me.map + ME_MAP_SIZE;
 
     mpv->me.mv_penalty = ff_h263_get_mv_penalty();
 
@@ -2093,7 +2091,6 @@ static av_cold int encode_end(AVCodecContext *avctx)
 
     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 9d8b0d496f..0a92c5607c 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -540,7 +540,6 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx)
                                       avctx->frame_num));
 
     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);
@@ -620,13 +619,11 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
                                         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.new_pic       = av_frame_alloc();
 
-    if (!s->m.me.scratchpad || !s->m.me.map ||
+    if (!s->m.me.scratchpad ||
         !s->mb_type || !s->dummy || !s->m.new_pic)
         return AVERROR(ENOMEM);
-    s->m.me.score_map = s->m.me.map + ME_MAP_SIZE;
 
     ff_svq1enc_init(&s->svq1encdsp);
 
-- 
2.45.2


[-- Attachment #9: 0008-avcodec-snowenc-Don-t-allocate-obmc_scratchpad-separ.patch --]
[-- Type: text/x-patch, Size: 3084 bytes --]

From 1c444bb0559b412dbd9ccc54ae56a96b51e0f14c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 03:35:09 +0100
Subject: [PATCH 08/11] avcodec/snowenc: Don't allocate obmc_scratchpad
 separately

Put it into SnowEncContext instead. Also use the proper type
(it is only used as IDWTELEM aka short).

(The allocation code allocated it in units of uint32_t,
yet it was never used in this way. I made the array so big
that the size (in bytes) does not change.)

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

diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 7818c79fa6..8e7712fe5f 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -68,6 +68,8 @@ typedef struct SnowEncContext {
     unsigned me_cache_generation;
 
     uint64_t encoding_error[SNOW_MAX_PLANES];
+
+    IDWTELEM obmc_scratchpad[MB_SIZE * MB_SIZE * 12 * 2];
 } SnowEncContext;
 
 static void init_ref(MotionEstContext *c, const uint8_t *const src[3],
@@ -234,8 +236,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
 
     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));
-    if (!mpv->me.scratchpad || !mpv->c.sc.obmc_scratchpad)
+    if (!mpv->me.scratchpad)
         return AVERROR(ENOMEM);
 
     mpv->me.mv_penalty = ff_h263_get_mv_penalty();
@@ -670,7 +671,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.c.sc.obmc_scratchpad + plane_index * block_size * block_size * 4; //FIXME change to unsigned
+    IDWTELEM *dst = enc->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 +769,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.c.sc.obmc_scratchpad + plane_index * block_size * block_size * 4;
+    IDWTELEM *pred = enc->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;
@@ -2091,7 +2092,6 @@ static av_cold int encode_end(AVCodecContext *avctx)
 
     enc->m.s.me.temp = NULL;
     av_freep(&enc->m.s.me.scratchpad);
-    av_freep(&enc->m.s.c.sc.obmc_scratchpad);
 
     av_freep(&avctx->stats_out);
 
-- 
2.45.2


[-- Attachment #10: 0009-avcodec-mpegvideo-Don-t-set-bf-_code-for-non-MPEG-4-.patch --]
[-- Type: text/x-patch, Size: 4741 bytes --]

From ffead361c6bcdf574f45dfeff8a06b51b35b74e9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 04:22:27 +0100
Subject: [PATCH 09/11] avcodec/mpegvideo: Don't set [bf]_code for non-MPEG-4
 decoders

It is only used by encoders and the MPEG-4 decoder.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/flvdec.c        | 2 --
 libavcodec/intelh263dec.c  | 1 -
 libavcodec/ituh263dec.c    | 1 -
 libavcodec/mpeg4videodec.c | 8 ++++----
 libavcodec/mpegvideo.c     | 3 ---
 libavcodec/mpegvideo_enc.c | 3 +++
 libavcodec/rv10.c          | 2 --
 7 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index f4bfd99417..627538ef83 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -97,8 +97,6 @@ int ff_flv_decode_picture_header(MpegEncContext *s)
     if (skip_1stop_8data_bits(&s->gb) < 0)
         return AVERROR_INVALIDDATA;
 
-    s->f_code = 1;
-
     if (s->ehc_mode)
         s->avctx->sample_aspect_ratio= (AVRational){1,2};
 
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index 4efae7938c..374dfdc0de 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -118,7 +118,6 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s)
     /* PEI */
     if (skip_1stop_8data_bits(&s->gb) < 0)
         return AVERROR_INVALIDDATA;
-    s->f_code = 1;
 
     ff_h263_show_pict_info(s);
 
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index d451a35da8..6c9c2583e3 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -1353,7 +1353,6 @@ int ff_h263_decode_picture_header(MpegEncContext *s)
             return -1;
         }
     }
-    s->f_code = 1;
 
     if (s->pict_type == AV_PICTURE_TYPE_B)
         s->low_delay = 0;
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index cb32f0e300..e21f1d24a2 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3329,6 +3329,8 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
         }
     }
 
+    s->f_code = 1;
+    s->b_code = 1;
     if (ctx->shape != BIN_ONLY_SHAPE) {
         s->chroma_qscale = s->qscale = get_bits(gb, ctx->quant_precision);
         if (s->qscale == 0) {
@@ -3345,8 +3347,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
                 s->f_code = 1;
                 return AVERROR_INVALIDDATA;  // makes no sense to continue, as there is nothing left from the image then
             }
-        } else
-            s->f_code = 1;
+        }
 
         if (s->pict_type == AV_PICTURE_TYPE_B) {
             s->b_code = get_bits(gb, 3);
@@ -3356,8 +3357,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb,
                 s->b_code=1;
                 return AVERROR_INVALIDDATA; // makes no sense to continue, as the MV decoding will break very quickly
             }
-        } else
-            s->b_code = 1;
+        }
 
         if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
             av_log(s->avctx, AV_LOG_DEBUG,
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 794b2d0f66..d09eb1211d 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -236,9 +236,6 @@ av_cold void ff_mpv_common_defaults(MpegEncContext *s)
 
     s->picture_number        = 0;
 
-    s->f_code                = 1;
-    s->b_code                = 1;
-
     s->slice_context_count   = 1;
 }
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 3d67df8d73..02255fdaed 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -285,6 +285,9 @@ static av_cold void mpv_encode_defaults(MPVMainEncContext *const m)
 
     ff_mpv_common_defaults(&s->c);
 
+    s->c.f_code = 1;
+    s->c.b_code = 1;
+
     if (!m->fcode_tab) {
         m->fcode_tab = default_fcode_tab + MAX_MV;
         ff_thread_once(&init_static_once, mpv_encode_init_static);
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 753c6c6cb3..d8df7e8612 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -150,7 +150,6 @@ static int rv10_decode_picture_header(MpegEncContext *s)
         mb_count = s->mb_width * s->mb_height;
     }
     skip_bits(&s->gb, 3);   /* ignored */
-    s->f_code          = 1;
 
     return mb_count;
 }
@@ -284,7 +283,6 @@ static int rv20_decode_picture_header(RVDecContext *rv, int whole_size)
         // binary decoder reads 3+2 bits here but they don't seem to be used
         skip_bits(&s->gb, 5);
 
-    s->f_code          = 1;
     s->h263_aic        = s->pict_type == AV_PICTURE_TYPE_I;
     s->modified_quant  = 1;
     if (!s->avctx->lowres)
-- 
2.45.2


[-- Attachment #11: 0010-avcodec-rv10-Remove-pointless-casts.patch --]
[-- Type: text/x-patch, Size: 1546 bytes --]

From a968f6580f49ec6dd33bc6d7aadf08f51dbec703 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 05:27:11 +0100
Subject: [PATCH 10/11] avcodec/rv10: Remove pointless casts

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

diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index d8df7e8612..4df545aec0 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -206,8 +206,8 @@ static int rv20_decode_picture_header(RVDecContext *rv, int whole_size)
                 return AVERROR_INVALIDDATA;
             }
 
-            new_w = 4 * ((uint8_t *) s->avctx->extradata)[6 + 2 * f];
-            new_h = 4 * ((uint8_t *) s->avctx->extradata)[7 + 2 * f];
+            new_w = 4 * s->avctx->extradata[6 + 2 * f];
+            new_h = 4 * s->avctx->extradata[7 + 2 * f];
         } else {
             new_w = rv->orig_width;
             new_h = rv->orig_height;
@@ -368,8 +368,8 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
     rv->orig_width  = avctx->coded_width;
     rv->orig_height = avctx->coded_height;
 
-    s->h263_long_vectors = ((uint8_t *) avctx->extradata)[3] & 1;
-    rv->sub_id           = AV_RB32((uint8_t *) avctx->extradata + 4);
+    s->h263_long_vectors = avctx->extradata[3] & 1;
+    rv->sub_id           = AV_RB32A(avctx->extradata + 4);
 
     major_ver = RV_GET_MAJOR_VER(rv->sub_id);
     minor_ver = RV_GET_MINOR_VER(rv->sub_id);
-- 
2.45.2


[-- Attachment #12: 0011-avcodec-rv10-Make-logmessage-endian-independent.patch --]
[-- Type: text/x-patch, Size: 918 bytes --]

From 82f5465a9890751a9272d68f4299d3cdbb344493 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 25 Mar 2025 05:30:13 +0100
Subject: [PATCH 11/11] avcodec/rv10: Make logmessage endian-independent

Also fix a potential effective-type violation.

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

diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 4df545aec0..482af8e52a 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -394,7 +394,7 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
 
     if (avctx->debug & FF_DEBUG_PICT_INFO) {
         av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%"PRIX32"\n", rv->sub_id,
-               ((uint32_t *) avctx->extradata)[0]);
+               AV_RL32A(avctx->extradata));
     }
 
     /* init static VLCs */
-- 
2.45.2


[-- Attachment #13: 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/11] avcodec/mpeg4videodec: Actually check, av_buffer_replace()
  2025-03-26  8:40 [FFmpeg-devel] [PATCH 01/11] avcodec/mpeg4videodec: Actually check, av_buffer_replace() Andreas Rheinhardt
@ 2025-03-28  5:17 ` Andreas Rheinhardt
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-28  5:17 UTC (permalink / raw)
  To: ffmpeg-devel

Andreas Rheinhardt:
> Patches attached, two of which fix regressions. I will apply these two
> tonight unless there are objections.
> 
> - Andreas
> 
Will apply the remaining patches of this patch tomorrow unless there are
objections.

- Andreas

_______________________________________________
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-28  5:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-26  8:40 [FFmpeg-devel] [PATCH 01/11] avcodec/mpeg4videodec: Actually check, av_buffer_replace() Andreas Rheinhardt
2025-03-28  5:17 ` 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