PR #22780 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22780
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22780.patch


>From f3f1945eb6dae7cfb8f62081eb68e996f395122b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Tue, 7 Apr 2026 23:50:43 +0200
Subject: [PATCH 01/13] avcodec/snowdata: Don't use 8 bits for six bits data

This has been done in 561a18d3ba07382dffdf583dda13f6954109b116
in order to avoid shifts, yet this rationale no longer applies
since d593e329832a432777218eb92469bad10594a3c5. So shift them back;
this is in preparation for using these coefficients together with
pmaddubsw.

Hint: 561a18d3ba07382dffdf583dda13f6954109b116 also added a block
guarded by "if(LOG2_OBMC_MAX == 8". I changed the condition to remove
this check (i.e. kept the block) which should not change the output
at all. Yet all FATE tests pass if the block is completely
removed. I don't know if this block is necessary at all.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snow.c        |   9 +--
 libavcodec/snow.h        |   2 +-
 libavcodec/snowdata.h    | 120 +++++++++++++++++++--------------------
 libavcodec/snowenc.c     |   7 +--
 libavcodec/x86/snowdsp.c |   8 +--
 5 files changed, 73 insertions(+), 73 deletions(-)

diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index b2850356ef..fa191c08c0 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -131,10 +131,11 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const 
int obmc_stride, uint8_
                     +obmc3[x] * block[1][x + y*src_stride]
                     +obmc4[x] * block[0][x + y*src_stride];
 
-            v <<= 8 - LOG2_OBMC_MAX;
-            if(FRAC_BITS != 8){
-                v >>= 8 - FRAC_BITS;
-            }
+#if FRAC_BITS > LOG2_OBMC_MAX
+            v <<= FRAC_BITS - LOG2_OBMC_MAX;
+#elif FRAC_BITS < LOG2_OBMC_MAX
+            v >>= LOG2_OBMC_MAX - FRAC_BITS;
+#endif
             if(add){
                 v += dst[x + src_x];
                 v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
index f8f45b8763..fa351bd53c 100644
--- a/libavcodec/snow.h
+++ b/libavcodec/snow.h
@@ -45,7 +45,7 @@
 #define FRAC_BITS 4
 #define MAX_REF_FRAMES 8
 
-#define LOG2_OBMC_MAX 8
+#define LOG2_OBMC_MAX 6
 #define OBMC_MAX (1<<(LOG2_OBMC_MAX))
 typedef struct BlockNode{
     int16_t mx;                 ///< Motion vector component X, see mv_scale
diff --git a/libavcodec/snowdata.h b/libavcodec/snowdata.h
index ca0c1e3f7a..87ab354385 100644
--- a/libavcodec/snowdata.h
+++ b/libavcodec/snowdata.h
@@ -25,79 +25,79 @@
 #include "snow.h"
 
 static const uint8_t obmc32[1024]={
-  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  
8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,
-  0,  4,  4,  4,  8,  8,  8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 
20, 16, 16, 16, 12, 12,  8,  8,  8,  4,  4,  4,  0,
-  0,  4,  8,  8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 
32, 28, 28, 24, 20, 20, 16, 12, 12,  8,  8,  4,  0,
-  0,  4,  8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 
44, 40, 36, 32, 28, 28, 24, 20, 16, 12,  8,  4,  0,
-  4,  8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 
56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12,  8,  4,
-  4,  8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 
68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12,  8,  4,
-  4,  8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 
80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16,  8,  4,
-  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 
92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12,  4,
-  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 
96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 
 4,
-  4, 16, 24, 32, 44, 52, 60, 72, 80, 
92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 
24, 16,  4,
-  4, 16, 28, 36, 48, 56, 68, 80, 
88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 
36, 28, 16,  4,
-  4, 16, 28, 40, 52, 64, 76, 88, 
96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 
40, 28, 16,  4,
-  8, 20, 32, 44, 56, 68, 80, 
92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 
56, 44, 32, 20,  8,
-  8, 20, 32, 48, 60, 76, 
88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 
76, 60, 48, 32, 20,  8,
-  8, 20, 36, 52, 64, 80, 
96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 
80, 64, 52, 36, 20,  8,
-  8, 24, 40, 56, 68, 
84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100,
 84, 68, 56, 40, 24,  8,
-  8, 24, 40, 56, 68, 
84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100,
 84, 68, 56, 40, 24,  8,
-  8, 20, 36, 52, 64, 80, 
96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 
80, 64, 52, 36, 20,  8,
-  8, 20, 32, 48, 60, 76, 
88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 
76, 60, 48, 32, 20,  8,
-  8, 20, 32, 44, 56, 68, 80, 
92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 
56, 44, 32, 20,  8,
-  4, 16, 28, 40, 52, 64, 76, 88, 
96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 
40, 28, 16,  4,
-  4, 16, 28, 36, 48, 56, 68, 80, 
88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 
36, 28, 16,  4,
-  4, 16, 24, 32, 44, 52, 60, 72, 80, 
92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 
24, 16,  4,
-  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 
96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 
 4,
-  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 
92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12,  4,
-  4,  8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 
80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16,  8,  4,
-  4,  8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 
68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12,  8,  4,
-  4,  8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 
56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12,  8,  4,
-  0,  4,  8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 
44, 40, 36, 32, 28, 28, 24, 20, 16, 12,  8,  4,  0,
-  0,  4,  8,  8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 
32, 28, 28, 24, 20, 20, 16, 12, 12,  8,  8,  4,  0,
-  0,  4,  4,  4,  8,  8,  8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 
20, 16, 16, 16, 12, 12,  8,  8,  8,  4,  4,  4,  0,
-  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  
8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,
+  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  
2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,
+  0,  1,  1,  1,  2,  2,  2,  3,  3,  4,  4,  4,  5,  5,  5,  6,  6,  5,  5,  
5,  4,  4,  4,  3,  3,  2,  2,  2,  1,  1,  1,  0,
+  0,  1,  2,  2,  3,  3,  4,  5,  5,  6,  7,  7,  8,  8,  9, 10, 10,  9,  8,  
8,  7,  7,  6,  5,  5,  4,  3,  3,  2,  2,  1,  0,
+  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  9, 10, 11, 12, 13, 14, 14, 13, 12, 
11, 10,  9,  8,  7,  7,  6,  5,  4,  3,  2,  1,  0,
+  1,  2,  3,  4,  5,  6,  7,  8, 10, 11, 12, 13, 14, 15, 16, 17, 17, 16, 15, 
14, 13, 12, 11, 10,  8,  7,  6,  5,  4,  3,  2,  1,
+  1,  2,  3,  5,  6,  8,  9, 10, 12, 13, 14, 16, 17, 19, 20, 21, 21, 20, 19, 
17, 16, 14, 13, 12, 10,  9,  8,  6,  5,  3,  2,  1,
+  1,  2,  4,  6,  7,  9, 11, 12, 14, 15, 17, 19, 20, 22, 24, 25, 25, 24, 22, 
20, 19, 17, 15, 14, 12, 11,  9,  7,  6,  4,  2,  1,
+  1,  3,  5,  7,  8, 10, 12, 14, 16, 18, 20, 22, 23, 25, 27, 29, 29, 27, 25, 
23, 22, 20, 18, 16, 14, 12, 10,  8,  7,  5,  3,  1,
+  1,  3,  5,  7, 10, 12, 14, 16, 18, 20, 22, 24, 27, 29, 31, 33, 33, 31, 29, 
27, 24, 22, 20, 18, 16, 14, 12, 10,  7,  5,  3,  1,
+  1,  4,  6,  8, 11, 13, 15, 18, 20, 23, 25, 27, 30, 32, 34, 37, 37, 34, 32, 
30, 27, 25, 23, 20, 18, 15, 13, 11,  8,  6,  4,  1,
+  1,  4,  7,  9, 12, 14, 17, 20, 22, 25, 28, 30, 33, 35, 38, 41, 41, 38, 35, 
33, 30, 28, 25, 22, 20, 17, 14, 12,  9,  7,  4,  1,
+  1,  4,  7, 10, 13, 16, 19, 22, 24, 27, 30, 33, 36, 39, 42, 45, 45, 42, 39, 
36, 33, 30, 27, 24, 22, 19, 16, 13, 10,  7,  4,  1,
+  2,  5,  8, 11, 14, 17, 20, 23, 27, 30, 33, 36, 39, 42, 45, 48, 48, 45, 42, 
39, 36, 33, 30, 27, 23, 20, 17, 14, 11,  8,  5,  2,
+  2,  5,  8, 12, 15, 19, 22, 25, 29, 32, 35, 39, 42, 46, 49, 52, 52, 49, 46, 
42, 39, 35, 32, 29, 25, 22, 19, 15, 12,  8,  5,  2,
+  2,  5,  9, 13, 16, 20, 24, 27, 31, 34, 38, 42, 45, 49, 53, 56, 56, 53, 49, 
45, 42, 38, 34, 31, 27, 24, 20, 16, 13,  9,  5,  2,
+  2,  6, 10, 14, 17, 21, 25, 29, 33, 37, 41, 45, 48, 52, 56, 60, 60, 56, 52, 
48, 45, 41, 37, 33, 29, 25, 21, 17, 14, 10,  6,  2,
+  2,  6, 10, 14, 17, 21, 25, 29, 33, 37, 41, 45, 48, 52, 56, 60, 60, 56, 52, 
48, 45, 41, 37, 33, 29, 25, 21, 17, 14, 10,  6,  2,
+  2,  5,  9, 13, 16, 20, 24, 27, 31, 34, 38, 42, 45, 49, 53, 56, 56, 53, 49, 
45, 42, 38, 34, 31, 27, 24, 20, 16, 13,  9,  5,  2,
+  2,  5,  8, 12, 15, 19, 22, 25, 29, 32, 35, 39, 42, 46, 49, 52, 52, 49, 46, 
42, 39, 35, 32, 29, 25, 22, 19, 15, 12,  8,  5,  2,
+  2,  5,  8, 11, 14, 17, 20, 23, 27, 30, 33, 36, 39, 42, 45, 48, 48, 45, 42, 
39, 36, 33, 30, 27, 23, 20, 17, 14, 11,  8,  5,  2,
+  1,  4,  7, 10, 13, 16, 19, 22, 24, 27, 30, 33, 36, 39, 42, 45, 45, 42, 39, 
36, 33, 30, 27, 24, 22, 19, 16, 13, 10,  7,  4,  1,
+  1,  4,  7,  9, 12, 14, 17, 20, 22, 25, 28, 30, 33, 35, 38, 41, 41, 38, 35, 
33, 30, 28, 25, 22, 20, 17, 14, 12,  9,  7,  4,  1,
+  1,  4,  6,  8, 11, 13, 15, 18, 20, 23, 25, 27, 30, 32, 34, 37, 37, 34, 32, 
30, 27, 25, 23, 20, 18, 15, 13, 11,  8,  6,  4,  1,
+  1,  3,  5,  7, 10, 12, 14, 16, 18, 20, 22, 24, 27, 29, 31, 33, 33, 31, 29, 
27, 24, 22, 20, 18, 16, 14, 12, 10,  7,  5,  3,  1,
+  1,  3,  5,  7,  8, 10, 12, 14, 16, 18, 20, 22, 23, 25, 27, 29, 29, 27, 25, 
23, 22, 20, 18, 16, 14, 12, 10,  8,  7,  5,  3,  1,
+  1,  2,  4,  6,  7,  9, 11, 12, 14, 15, 17, 19, 20, 22, 24, 25, 25, 24, 22, 
20, 19, 17, 15, 14, 12, 11,  9,  7,  6,  4,  2,  1,
+  1,  2,  3,  5,  6,  8,  9, 10, 12, 13, 14, 16, 17, 19, 20, 21, 21, 20, 19, 
17, 16, 14, 13, 12, 10,  9,  8,  6,  5,  3,  2,  1,
+  1,  2,  3,  4,  5,  6,  7,  8, 10, 11, 12, 13, 14, 15, 16, 17, 17, 16, 15, 
14, 13, 12, 11, 10,  8,  7,  6,  5,  4,  3,  2,  1,
+  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  9, 10, 11, 12, 13, 14, 14, 13, 12, 
11, 10,  9,  8,  7,  7,  6,  5,  4,  3,  2,  1,  0,
+  0,  1,  2,  2,  3,  3,  4,  5,  5,  6,  7,  7,  8,  8,  9, 10, 10,  9,  8,  
8,  7,  7,  6,  5,  5,  4,  3,  3,  2,  2,  1,  0,
+  0,  1,  1,  1,  2,  2,  2,  3,  3,  4,  4,  4,  5,  5,  5,  6,  6,  5,  5,  
5,  4,  4,  4,  3,  3,  2,  2,  2,  1,  1,  1,  0,
+  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  
2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,
  //error:0.000020
 };
 static const uint8_t obmc16[256]={
-  0,  4,  4,  8,  8, 12, 12, 16, 16, 12, 12,  8,  8,  4,  4,  0,
-  4,  8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16,  8,  4,
-  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16,  4,
-  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20,  8,
-  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28,  8,
- 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
- 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
- 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
- 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
- 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
- 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
-  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28,  8,
-  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20,  8,
-  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16,  4,
-  4,  8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16,  8,  4,
-  0,  4,  4,  8,  8, 12, 12, 16, 16, 12, 12,  8,  8,  4,  4,  0,
+  0,  1,  1,  2,  2,  3,  3,  4,  4,  3,  3,  2,  2,  1,  1,  0,
+  1,  2,  4,  5,  7,  8, 10, 11, 11, 10,  8,  7,  5,  4,  2,  1,
+  1,  4,  6,  9, 11, 14, 16, 19, 19, 16, 14, 11,  9,  6,  4,  1,
+  2,  5,  9, 12, 16, 19, 23, 26, 26, 23, 19, 16, 12,  9,  5,  2,
+  2,  7, 11, 16, 20, 25, 29, 34, 34, 29, 25, 20, 16, 11,  7,  2,
+  3,  8, 14, 19, 25, 30, 36, 41, 41, 36, 30, 25, 19, 14,  8,  3,
+  3, 10, 16, 23, 29, 36, 42, 49, 49, 42, 36, 29, 23, 16, 10,  3,
+  4, 11, 19, 26, 34, 41, 49, 56, 56, 49, 41, 34, 26, 19, 11,  4,
+  4, 11, 19, 26, 34, 41, 49, 56, 56, 49, 41, 34, 26, 19, 11,  4,
+  3, 10, 16, 23, 29, 36, 42, 49, 49, 42, 36, 29, 23, 16, 10,  3,
+  3,  8, 14, 19, 25, 30, 36, 41, 41, 36, 30, 25, 19, 14,  8,  3,
+  2,  7, 11, 16, 20, 25, 29, 34, 34, 29, 25, 20, 16, 11,  7,  2,
+  2,  5,  9, 12, 16, 19, 23, 26, 26, 23, 19, 16, 12,  9,  5,  2,
+  1,  4,  6,  9, 11, 14, 16, 19, 19, 16, 14, 11,  9,  6,  4,  1,
+  1,  2,  4,  5,  7,  8, 10, 11, 11, 10,  8,  7,  5,  4,  2,  1,
+  0,  1,  1,  2,  2,  3,  3,  4,  4,  3,  3,  2,  2,  1,  1,  0,
 //error:0.000015
 };
 
 //linear *64
 static const uint8_t obmc8[64]={
-  4, 12, 20, 28, 28, 20, 12,  4,
- 12, 36, 60, 84, 84, 60, 36, 12,
- 20, 60,100,140,140,100, 60, 20,
- 28, 84,140,196,196,140, 84, 28,
- 28, 84,140,196,196,140, 84, 28,
- 20, 60,100,140,140,100, 60, 20,
- 12, 36, 60, 84, 84, 60, 36, 12,
-  4, 12, 20, 28, 28, 20, 12,  4,
+  1,  3,  5,  7,  7,  5,  3,  1,
+  3,  9, 15, 21, 21, 15,  9,  3,
+  5, 15, 25, 35, 35, 25, 15,  5,
+  7, 21, 35, 49, 49, 35, 21,  7,
+  7, 21, 35, 49, 49, 35, 21,  7,
+  5, 15, 25, 35, 35, 25, 15,  5,
+  3,  9, 15, 21, 21, 15,  9,  3,
+  1,  3,  5,  7,  7,  5,  3,  1,
 //error:0.000000
 };
 
 //linear *64
 static const uint8_t obmc4[16]={
- 16, 48, 48, 16,
- 48,144,144, 48,
- 48,144,144, 48,
- 16, 48, 48, 16,
+  4, 12, 12,  4,
+ 12, 36, 36, 12,
+ 12, 36, 36, 12,
+  4, 12, 12,  4,
 //error:0.000000
 };
 
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 5312d48e99..29a1f114c3 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -815,10 +815,9 @@ static int get_block_rd(SnowEncContext *enc, int mb_x, int 
mb_y,
         }
     }
 
-    /* copy the regions where obmc[] = (uint8_t)256 */
-    if(LOG2_OBMC_MAX == 8
-        && (mb_x == 0 || mb_x == b_stride-1)
-        && (mb_y == 0 || mb_y == b_height-1)){
+    /* copy the regions where obmc[] = (uint8_t)(1<<LOG2_OBMC_MAX) */
+    if ((mb_x == 0 || mb_x == b_stride-1) &&
+        (mb_y == 0 || mb_y == b_height-1)){
         if(mb_x == 0)
             x1 = block_w;
         else
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp.c
index bd0aa766e5..78a71f4aa5 100644
--- a/libavcodec/x86/snowdsp.c
+++ b/libavcodec/x86/snowdsp.c
@@ -746,8 +746,8 @@ snow_inner_add_yblock_sse2_accum_16("1", "512")
 snow_inner_add_yblock_sse2_accum_16("0", "528")
 
              "mov %0, %%"FF_REG_d"           \n\t"
-             "psrlw $4, %%xmm1               \n\t"
-             "psrlw $4, %%xmm5               \n\t"
+             "psrlw $2, %%xmm1               \n\t"
+             "psrlw $2, %%xmm5               \n\t"
              "paddw   (%%"FF_REG_D"), %%xmm1 \n\t"
              "paddw 16(%%"FF_REG_D"), %%xmm5 \n\t"
              "paddw %%xmm3, %%xmm1           \n\t"
@@ -797,8 +797,8 @@ snow_inner_add_yblock_sse2_end_16
 
 #define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\
              "mov %0, %%"FF_REG_d"           \n\t"\
-             "psrlw $4, %%mm1                \n\t"\
-             "psrlw $4, %%mm5                \n\t"\
+             "psrlw $2, %%mm1                \n\t"\
+             "psrlw $2, %%mm5                \n\t"\
              "paddw "read_offset"(%%"FF_REG_D"), %%mm1   \n\t"\
              "paddw "read_offset"+8(%%"FF_REG_D"), %%mm5 \n\t"\
              "paddw %%mm3, %%mm1             \n\t"\
-- 
2.52.0


>From 5a9bb23452fbbc8f81d74239be4761fa2eccc23b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 09:20:25 +0200
Subject: [PATCH 02/13] avcodec/snow: Disable dead code in
 ff_snow_inner_add_yblock()

It is only used with add != 0 (and the assembly functions
only support this case).

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snow.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index fa191c08c0..b6aa94e1ce 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -20,6 +20,7 @@
 
 #include <assert.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/log.h"
 #include "libavutil/mem.h"
 #include "libavutil/thread.h"
@@ -118,6 +119,9 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const 
int obmc_stride, uint8_
                               int src_x, int src_y, int src_stride, 
slice_buffer * sb, int add, uint8_t * dst8){
     int y, x;
     IDWTELEM * dst;
+
+    av_assume(add); // add == 0 is currently unused
+
     for(y=0; y<b_h; y++){
         //FIXME ugly misuse of obmc_stride
         const uint8_t *obmc1= obmc + y*obmc_stride;
-- 
2.52.0


>From 42f80b10f4b1b7fe1332c664fc6787228cd3b56a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 09:29:33 +0200
Subject: [PATCH 03/13] avcodec/snow: Avoid always-true branch

The input lines used in ff_snow_inner_add_yblock()
must always be set (because their values are used).
The MMX assembly always relied on this.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snow.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index b6aa94e1ce..76dcdd5488 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -118,7 +118,6 @@ static av_cold void init_qpel(SnowContext *const s)
 void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, 
uint8_t * * block, int b_w, int b_h,
                               int src_x, int src_y, int src_stride, 
slice_buffer * sb, int add, uint8_t * dst8){
     int y, x;
-    IDWTELEM * dst;
 
     av_assume(add); // add == 0 is currently unused
 
@@ -128,7 +127,9 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const 
int obmc_stride, uint8_
         const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
         const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
         const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
-        dst = slice_buffer_get_line(sb, src_y + y);
+        IDWTELEM *dst = sb->line[src_y+y];
+        av_assert2(dst);
+
         for(x=0; x<b_w; x++){
             int v=   obmc1[x] * block[3][x + y*src_stride]
                     +obmc2[x] * block[2][x + y*src_stride]
-- 
2.52.0


>From a028877e45ef561cbe9a7cfc9bc74029941e9f97 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 10:39:04 +0200
Subject: [PATCH 04/13] avcodec/x86/snow_dwt: Avoid slice_buffer in
 inner_add_yblock

It is unnecessary and avoids the src_y parameter;
it also makes this function more ASM-friendly.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snow.c        |  5 +++--
 libavcodec/snow.h        |  2 +-
 libavcodec/snow_dwt.h    |  4 ++--
 libavcodec/x86/snowdsp.c | 39 +++++++++++++++++++++------------------
 4 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 76dcdd5488..e61f4f726a 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -116,7 +116,8 @@ static av_cold void init_qpel(SnowContext *const s)
 }
 
 void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, 
uint8_t * * block, int b_w, int b_h,
-                              int src_x, int src_y, int src_stride, 
slice_buffer * sb, int add, uint8_t * dst8){
+                              int src_x, int src_stride, IDWTELEM *const 
*lines, int add, uint8_t *dst8)
+{
     int y, x;
 
     av_assume(add); // add == 0 is currently unused
@@ -127,7 +128,7 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const 
int obmc_stride, uint8_
         const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
         const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
         const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
-        IDWTELEM *dst = sb->line[src_y+y];
+        IDWTELEM *dst = lines[y];
         av_assert2(dst);
 
         for(x=0; x<b_w; x++){
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
index fa351bd53c..7a38fa057f 100644
--- a/libavcodec/snow.h
+++ b/libavcodec/snow.h
@@ -313,7 +313,7 @@ static av_always_inline void add_yblock(SnowContext *s, int 
sliced, slice_buffer
         ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, 
b_h, rb, plane_index, w, h);
     }
     if(sliced){
-        s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, 
src_x,src_y, src_stride, sb, add, dst8);
+        s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, sb->line + src_y, add, dst8);
     }else{
         for(y=0; y<b_h; y++){
             //FIXME ugly misuse of obmc_stride
diff --git a/libavcodec/snow_dwt.h b/libavcodec/snow_dwt.h
index b5803bc99a..d2ebb79328 100644
--- a/libavcodec/snow_dwt.h
+++ b/libavcodec/snow_dwt.h
@@ -62,7 +62,7 @@ typedef struct SnowDWTContext {
     void (*horizontal_compose97i)(IDWTELEM *b, IDWTELEM *temp, int width);
     void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride,
                              uint8_t **block, int b_w, int b_h, int src_x,
-                             int src_y, int src_stride, slice_buffer *sb,
+                             int src_stride, IDWTELEM * const *lines,
                              int add, uint8_t *dst8);
 } SnowDWTContext;
 
@@ -141,7 +141,7 @@ IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int 
line);
 
 void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
                               uint8_t **block, int b_w, int b_h, int src_x,
-                              int src_y, int src_stride, slice_buffer *sb,
+                              int src_stride, IDWTELEM *const *lines,
                               int add, uint8_t *dst8);
 
 int ff_w53_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, 
ptrdiff_t line_size, int h);
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp.c
index 78a71f4aa5..7cd3fd5415 100644
--- a/libavcodec/x86/snowdsp.c
+++ b/libavcodec/x86/snowdsp.c
@@ -608,7 +608,6 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, 
IDWTELEM *b1, IDWTELEM
 
 #if HAVE_6REGS
 #define snow_inner_add_yblock_sse2_header \
-    IDWTELEM * * dst_array = sb->line + src_y;\
     x86_reg tmp;\
     __asm__ volatile(\
              "mov  %7, %%"FF_REG_c"          \n\t"\
@@ -669,7 +668,7 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, 
IDWTELEM *b1, IDWTELEM
 
 #define snow_inner_add_yblock_sse2_end_common2\
              "jnz 1b                         \n\t"\
-             :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\
+             :"+m"(dst8),"+m"(lines),"=&r"(tmp)\
              :\
              
"rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\
              XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", 
"%xmm5", "%xmm6", "%xmm7", )\
@@ -690,7 +689,8 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, 
IDWTELEM *b1, IDWTELEM
              snow_inner_add_yblock_sse2_end_common2
 
 static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(const uint8_t *obmc, 
const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * 
sb, int add, uint8_t * dst8){
+                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
+{
 snow_inner_add_yblock_sse2_header
 snow_inner_add_yblock_sse2_start_8("xmm1", "xmm5", "3", "0")
 snow_inner_add_yblock_sse2_accum_8("2", "8")
@@ -738,7 +738,8 @@ snow_inner_add_yblock_sse2_end_8
 }
 
 static void inner_add_yblock_bw_16_obmc_32_sse2(const uint8_t *obmc, const 
x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * 
sb, int add, uint8_t * dst8){
+                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
+{
 snow_inner_add_yblock_sse2_header
 snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0")
 snow_inner_add_yblock_sse2_accum_16("2", "16")
@@ -762,7 +763,6 @@ snow_inner_add_yblock_sse2_end_16
 }
 
 #define snow_inner_add_yblock_mmx_header \
-    IDWTELEM * * dst_array = sb->line + src_y;\
     x86_reg tmp;\
     __asm__ volatile(\
              "mov  %7, %%"FF_REG_c"          \n\t"\
@@ -818,13 +818,14 @@ snow_inner_add_yblock_sse2_end_16
              "add %%"FF_REG_c", %0                             \n\t"\
              "dec %2                         \n\t"\
              "jnz 1b                         \n\t"\
-             :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\
+             :"+m"(dst8),"+m"(lines),"=&r"(tmp)\
              :\
              
"rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\
              "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d"");
 
 static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const 
x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * 
sb, int add, uint8_t * dst8){
+                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
+{
 snow_inner_add_yblock_mmx_header
 snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0")
 snow_inner_add_yblock_mmx_accum("2", "8", "0")
@@ -835,7 +836,8 @@ snow_inner_add_yblock_mmx_end("16")
 }
 
 static void inner_add_yblock_bw_16_obmc_32_mmx(const uint8_t *obmc, const 
x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * 
sb, int add, uint8_t * dst8){
+                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
+{
 snow_inner_add_yblock_mmx_header
 snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0")
 snow_inner_add_yblock_mmx_accum("2", "16", "0")
@@ -852,27 +854,28 @@ snow_inner_add_yblock_mmx_end("32")
 }
 
 static void ff_snow_inner_add_yblock_sse2(const uint8_t *obmc, const int 
obmc_stride, uint8_t * * block, int b_w, int b_h,
-                           int src_x, int src_y, int src_stride, slice_buffer 
* sb, int add, uint8_t * dst8){
-
+                           int src_x, int src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
+{
     if (b_w == 16)
-        inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, 
b_h, src_x,src_y, src_stride, sb, add, dst8);
+        inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, 
b_h, src_x, src_stride, lines, add, dst8);
     else if (b_w == 8 && obmc_stride == 16) {
         if (!(b_h & 1))
-            inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, 
block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
+            inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, 
block, b_w, b_h, src_x, src_stride, lines, add, dst8);
         else
-            inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, 
b_h, src_x,src_y, src_stride, sb, add, dst8);
+            inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, 
b_h, src_x, src_stride, lines, add, dst8);
     } else
-         ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, 
src_x,src_y, src_stride, sb, add, dst8);
+         ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
 }
 
 static void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int 
obmc_stride, uint8_t * * block, int b_w, int b_h,
-                          int src_x, int src_y, int src_stride, slice_buffer * 
sb, int add, uint8_t * dst8){
+                          int src_x, int src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
+{
     if (b_w == 16)
-        inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x,src_y, src_stride, sb, add, dst8);
+        inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x, src_stride, lines, add, dst8);
     else if (b_w == 8 && obmc_stride == 16)
-        inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x,src_y, src_stride, sb, add, dst8);
+        inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x, src_stride, lines, add, dst8);
     else
-        ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, 
src_x,src_y, src_stride, sb, add, dst8);
+        ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
 }
 #endif /* HAVE_6REGS */
 
-- 
2.52.0


>From 8a55e7690be335285d20d5901e1062d673b85719 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 10:41:28 +0200
Subject: [PATCH 05/13] avcodec/snow_dwt: Remove pointless forward declaration

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snow_dwt.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libavcodec/snow_dwt.h b/libavcodec/snow_dwt.h
index d2ebb79328..a26db62d6d 100644
--- a/libavcodec/snow_dwt.h
+++ b/libavcodec/snow_dwt.h
@@ -53,8 +53,6 @@ typedef struct slice_buffer_s {
     IDWTELEM *base_buffer;  ///< Buffer that this structure is caching.
 } slice_buffer;
 
-struct SnowDWTContext;
-
 typedef struct SnowDWTContext {
     void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
                                 IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
-- 
2.52.0


>From 1cf18360c74d7c58218ab78cf7b5ce0ffad1a45a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 18:20:33 +0200
Subject: [PATCH 06/13] avcodec/snowdata: Add explicit alignment for obmc
 tables

This is in preparation for adding SSSE3 assembly.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snowdata.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavcodec/snowdata.h b/libavcodec/snowdata.h
index 87ab354385..fa31ae72c2 100644
--- a/libavcodec/snowdata.h
+++ b/libavcodec/snowdata.h
@@ -23,8 +23,9 @@
 #define AVCODEC_SNOWDATA_H
 
 #include "snow.h"
+#include "libavutil/mem_internal.h"
 
-static const uint8_t obmc32[1024]={
+DECLARE_ALIGNED(16, static const uint8_t, obmc32)[1024]={
   0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  
2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,
   0,  1,  1,  1,  2,  2,  2,  3,  3,  4,  4,  4,  5,  5,  5,  6,  6,  5,  5,  
5,  4,  4,  4,  3,  3,  2,  2,  2,  1,  1,  1,  0,
   0,  1,  2,  2,  3,  3,  4,  5,  5,  6,  7,  7,  8,  8,  9, 10, 10,  9,  8,  
8,  7,  7,  6,  5,  5,  4,  3,  3,  2,  2,  1,  0,
@@ -59,7 +60,7 @@ static const uint8_t obmc32[1024]={
   0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  
2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,
  //error:0.000020
 };
-static const uint8_t obmc16[256]={
+DECLARE_ALIGNED(16, static const uint8_t, obmc16)[256]={
   0,  1,  1,  2,  2,  3,  3,  4,  4,  3,  3,  2,  2,  1,  1,  0,
   1,  2,  4,  5,  7,  8, 10, 11, 11, 10,  8,  7,  5,  4,  2,  1,
   1,  4,  6,  9, 11, 14, 16, 19, 19, 16, 14, 11,  9,  6,  4,  1,
-- 
2.52.0


>From c289e3547e4ff8b1be23ab4a3044b8d7ae622961 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Fri, 10 Apr 2026 10:25:22 +0200
Subject: [PATCH 07/13] tests/checkasm: Add snowdsp test

Only inner_add_yblock for now.
Hint: Said function uses a pointer to an array of pointers as parameter.
The MMX version clobbers the array in such a way that calling the
function repeatedly with the same arguments (as happens inside bench_new())
leads to buffer overflows and segfaults. Therefore CALL4 had to be
overridden to restore the original pointers. This workaround will be
removed soon when the MMX version is removed.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 tests/checkasm/Makefile   |   1 +
 tests/checkasm/checkasm.c |   3 +
 tests/checkasm/checkasm.h |   1 +
 tests/checkasm/snowdsp.c  | 159 ++++++++++++++++++++++++++++++++++++++
 tests/fate/checkasm.mak   |   1 +
 5 files changed, 165 insertions(+)
 create mode 100644 tests/checkasm/snowdsp.c

diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile
index bf2d6b7ec2..55d2527047 100644
--- a/tests/checkasm/Makefile
+++ b/tests/checkasm/Makefile
@@ -50,6 +50,7 @@ AVCODECOBJS-$(CONFIG_PNG_DECODER)       += png.o
 AVCODECOBJS-$(CONFIG_RV34DSP)           += rv34dsp.o
 AVCODECOBJS-$(CONFIG_RV40_DECODER)      += rv40dsp.o
 AVCODECOBJS-$(CONFIG_SBC_ENCODER)       += sbcdsp.o
+AVCODECOBJS-$(CONFIG_SNOW_DECODER)      += snowdsp.o
 AVCODECOBJS-$(CONFIG_SVQ1_ENCODER)      += svq1enc.o
 AVCODECOBJS-$(CONFIG_TAK_DECODER)       += takdsp.o
 AVCODECOBJS-$(CONFIG_UTVIDEO_DECODER)   += utvideodsp.o
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 8629f26788..e863ff6eed 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -253,6 +253,9 @@ static const struct {
     #if CONFIG_SBC_ENCODER
         { "sbcdsp", checkasm_check_sbcdsp },
     #endif
+    #if CONFIG_SNOW_DECODER
+        { "snowdsp", checkasm_check_snowdsp },
+    #endif
     #if CONFIG_SVQ1_ENCODER
         { "svq1enc", checkasm_check_svq1enc },
     #endif
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index 43c158e97b..72a1404163 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -141,6 +141,7 @@ void checkasm_check_sbrdsp(void);
 void checkasm_check_rv34dsp(void);
 void checkasm_check_rv40dsp(void);
 void checkasm_check_scene_sad(void);
+void checkasm_check_snowdsp(void);
 void checkasm_check_svq1enc(void);
 void checkasm_check_synth_filter(void);
 void checkasm_check_sw_gbrp(void);
diff --git a/tests/checkasm/snowdsp.c b/tests/checkasm/snowdsp.c
new file mode 100644
index 0000000000..2edad643ad
--- /dev/null
+++ b/tests/checkasm/snowdsp.c
@@ -0,0 +1,159 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/macros.h"
+#include "libavutil/mem_internal.h"
+
+#include "libavcodec/snow.h"
+#include "libavcodec/snow_dwt.h"
+
+#include "checkasm.h"
+
+#define randomize_buffer(buf)                                 \
+do {                                                          \
+    for (size_t k = 0; k < (sizeof(buf) & ~3); k += 4)        \
+        AV_WN32A((char*)buf + k, rnd());                      \
+    for (size_t k = sizeof(buf) & ~3; k < sizeof(buf); ++k)   \
+        ((char*)buf)[k] = rnd();                              \
+} while (0)
+
+static void checkasm_check_inner_add_yblock(const SnowDWTContext *const 
snowdsp)
+{
+    enum {
+        LOG2_MAX_BLOCKSIZE = 4,
+        MAX_BLOCKSIZE      = 1 << LOG2_MAX_BLOCKSIZE,
+        LOG2_MIN_BLOCKSIZE = 1,
+        MAX_STRIDE         = 256,
+    };
+    declare_func_emms(AV_CPU_FLAG_MMX, void, const uint8_t *obmc, const int 
obmc_stride,
+                       uint8_t **block, int b_w, int b_h, int src_x,
+                       int src_stride, IDWTELEM * const *lines,
+                       int add, uint8_t *dst8);
+    DECLARE_ALIGNED(16, uint8_t, dst8_ref)[MAX_STRIDE * MAX_BLOCKSIZE];
+    DECLARE_ALIGNED(16, uint8_t, dst8_new)[MAX_STRIDE * MAX_BLOCKSIZE];
+    DECLARE_ALIGNED(16, uint8_t, block)[4][MAX_STRIDE * (MAX_BLOCKSIZE - 1) + 
MAX_BLOCKSIZE];
+    DECLARE_ALIGNED(16, IDWTELEM, linebuf)[MAX_BLOCKSIZE][MAX_STRIDE];
+    int inited = 0;
+
+    for (int i = 0; i < 2; ++i) {
+        for (int j = LOG2_MIN_BLOCKSIZE; j <= LOG2_MAX_BLOCKSIZE; ++j) {
+            int b_w = 1 << j;
+
+            if (!check_func(snowdsp->inner_add_yblock, 
"inner_add_yblock_%d%s", b_w, i ? "_border" : ""))
+                continue;
+
+            const uint8_t *obmc = ff_obmc_tab[LOG2_MAX_BLOCKSIZE - j];
+            int obmc_stride = 2 << j;
+            int b_h = b_w, mb_x;
+            int width = 1 + rnd() % MAX_STRIDE;
+
+            if (!i) {
+                // Test the ordinary case of a complete block.
+                width = FFMAX(width, 2 * b_w);
+                int nb_complete_blocks = (width - b_w / 2) / b_w;
+                mb_x = 1 + rnd() % nb_complete_blocks;
+            } else {
+                // Test a boundary block. If width == b_w/2 mod b_w,
+                // there is no right boundary block, so use the left one.
+                mb_x = (width + b_w/2) % b_w && rnd() & 1 ? (width + b_w/2) / 
b_w : 0;
+            }
+            ptrdiff_t src_stride = FFALIGN(width + rnd() % (MAX_STRIDE - width 
+ 1), 16);
+            int src_x = b_w*mb_x - b_w/2;
+
+            if (src_x < 0) {
+                obmc -= src_x;
+                b_w  += src_x;
+                src_x = 0;
+            }
+            if (src_x + b_w > width) {
+                b_w = width - src_x;
+            }
+
+            uint8_t *dst8p_ref = dst8_ref + src_x;
+            uint8_t *dst8p_new = dst8_new + src_x;
+            unsigned rand = rnd();
+            uint8_t *blocks[4] = { block[rand % 4],      block[rand / 4  % 4],
+                                   block[rand / 16 % 4], block[rand / 64 % 4] 
};
+            if (rnd() & 1) { // negate stride
+                dst8p_ref += (b_h - 1) * src_stride;
+                dst8p_new += (b_h - 1) * src_stride;
+                blocks[0] += (b_h - 1) * src_stride;
+                blocks[1] += (b_h - 1) * src_stride;
+                blocks[2] += (b_h - 1) * src_stride;
+                blocks[3] += (b_h - 1) * src_stride;
+                src_stride = -src_stride;
+            }
+            uint8_t *blocks_backup[4] = { blocks[0], blocks[1],
+                                          blocks[2], blocks[3] };
+            IDWTELEM *lines[MAX_BLOCKSIZE];
+
+            for (int k = 0; k < b_h; ++k)
+                lines[k] = linebuf[rnd() % MAX_BLOCKSIZE];
+
+            if (!inited) {
+                inited = 1;
+                randomize_buffer(block);
+                randomize_buffer(dst8_ref);
+                for (size_t k = 0; k < FF_ARRAY_ELEMS(linebuf); ++k) {
+                    for (size_t l = 0; l < FF_ARRAY_ELEMS(linebuf[0]); ++l)
+                        linebuf[k][l] = sign_extend(rnd(), 15);
+                }
+            }
+
+            memcpy(dst8_new, dst8_ref, sizeof(dst8_new));
+
+            call_ref(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, 
lines, 1, dst8p_ref);
+            memcpy(blocks, blocks_backup, sizeof(blocks));\
+            call_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, 
lines, 1, dst8p_new);
+
+            if (memcmp(dst8_ref, dst8_new, sizeof(dst8_new)))
+                fail();
+
+#undef CALL4
+#define CALL4(...)\
+    do {\
+        memcpy(blocks, blocks_backup, sizeof(blocks));\
+        tfunc(__VA_ARGS__); \
+        memcpy(blocks, blocks_backup, sizeof(blocks));\
+        tfunc(__VA_ARGS__); \
+        memcpy(blocks, blocks_backup, sizeof(blocks));\
+        tfunc(__VA_ARGS__); \
+        memcpy(blocks, blocks_backup, sizeof(blocks));\
+        tfunc(__VA_ARGS__); \
+    } while (0)
+
+            bench_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, 
lines, 1, dst8p_new);
+        }
+    }
+    report("inner_add_yblock");
+}
+
+void checkasm_check_snowdsp(void)
+{
+    SnowDWTContext snowdsp;
+
+    ff_dwt_init(&snowdsp);
+
+    checkasm_check_inner_add_yblock(&snowdsp);
+}
diff --git a/tests/fate/checkasm.mak b/tests/fate/checkasm.mak
index 2fb1f693b8..b7392fa745 100644
--- a/tests/fate/checkasm.mak
+++ b/tests/fate/checkasm.mak
@@ -56,6 +56,7 @@ FATE_CHECKASM = fate-checkasm-aacencdsp                       
          \
                 fate-checkasm-rv40dsp                                   \
                 fate-checkasm-sbcdsp                                    \
                 fate-checkasm-scene_sad                                 \
+                fate-checkasm-snowdsp                                   \
                 fate-checkasm-svq1enc                                   \
                 fate-checkasm-synth_filter                              \
                 fate-checkasm-sw_gbrp                                   \
-- 
2.52.0


>From 7aee8017b6f366fde85844beb1378847dfee06d5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Fri, 10 Apr 2026 10:57:45 +0200
Subject: [PATCH 08/13] tests/checkasm/llvidencdsp: Fix nonsense randomization

The first loop was never entered due to a precedence problem;
the second loop initialized everything, although it was not intended
that way.
This has been added in 56b8769a1c26dac8fe51319f0c2b94de67a64217.
Sorry for this.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 tests/checkasm/llvidencdsp.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/checkasm/llvidencdsp.c b/tests/checkasm/llvidencdsp.c
index 785553f70a..d8ee673e0f 100644
--- a/tests/checkasm/llvidencdsp.c
+++ b/tests/checkasm/llvidencdsp.c
@@ -28,12 +28,12 @@
 
 #include "checkasm.h"
 
-#define randomize_buffers(buf, size)              \
-    do {                                          \
-        for (size_t j = 0; j < size & ~3; j += 4) \
-            AV_WN32(buf + j, rnd());              \
-        for (size_t j = 0; j < size; ++j)         \
-            buf[j] = rnd();                       \
+#define randomize_buffers(buf, size)                \
+    do {                                            \
+        for (size_t j = 0; j < (size & ~3); j += 4) \
+            AV_WN32(buf + j, rnd());                \
+        for (size_t j = size & ~3; j < size; ++j)   \
+            buf[j] = rnd();                         \
     } while (0)
 
 static const struct {uint8_t w, h, s;} planes[] = {
-- 
2.52.0


>From 855e6c3976f03370a5df4dcea9637f4eb7bdc7f8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Fri, 10 Apr 2026 11:08:48 +0200
Subject: [PATCH 09/13] tests/checkasm/mpegvideo_unquantize: Fix precedence
 problem

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 tests/checkasm/mpegvideo_unquantize.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/checkasm/mpegvideo_unquantize.c 
b/tests/checkasm/mpegvideo_unquantize.c
index 0430e20354..9de0bb4284 100644
--- a/tests/checkasm/mpegvideo_unquantize.c
+++ b/tests/checkasm/mpegvideo_unquantize.c
@@ -36,7 +36,7 @@
     static_assert(!(_Alignof(TYPE) % 4),                  \
                   "can't use aligned stores");            \
     unsigned char *ptr = (unsigned char*)s;               \
-    for (size_t i = 0; i < sizeof(*s) & ~3; i += 4)       \
+    for (size_t i = 0; i < (sizeof(*s) & ~3); i += 4)     \
         AV_WN32A(ptr + i, rnd());                         \
     for (size_t i = sizeof(*s) & ~3; i < sizeof(*s); ++i) \
         ptr[i] = rnd();                                   \
-- 
2.52.0


>From d7869eb9c531c88ed7f4139efeaca54d0b08f7c7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 18:43:54 +0200
Subject: [PATCH 10/13] avcodec/x86/snowdsp: Add SSSE3 inner_add_yblock

Compared to the MMX version, this version benefits from wider
registers and pmaddubsw. It also has fewer unnecessary loads
and stores: On x64, the MMX version has 12 unnecessary GPR loads
and 6 stores in each line when width is eight; for width 16,
there are 17 unnecessary GPR loads and six stores per line.
Even the 32bit SSSE3 version only has six loads and zero stores
per line more than the x64 version. Furthermore, in contrast
to the MMX version, the SSSE3 version also does not clobber
the array of block pointers given to it.

Benchmarks:
inner_add_yblock_2_c:                                   29.2 ( 1.00x)
inner_add_yblock_2_mmx:                                 32.5 ( 0.90x)
inner_add_yblock_2_ssse3:                               28.6 ( 1.02x)
inner_add_yblock_4_c:                                   85.2 ( 1.00x)
inner_add_yblock_4_mmx:                                 89.2 ( 0.96x)
inner_add_yblock_4_ssse3:                               84.5 ( 1.01x)
inner_add_yblock_8_c:                                  302.0 ( 1.00x)
inner_add_yblock_8_mmx:                                 77.0 ( 3.92x)
inner_add_yblock_8_ssse3:                               30.6 ( 9.85x)
inner_add_yblock_16_c:                                1164.7 ( 1.00x)
inner_add_yblock_16_mmx:                               260.4 ( 4.47x)
inner_add_yblock_16_ssse3:                              82.3 (14.15x)

Both the MMX and SSSE3 versions leave the size 2 and 4 cases
to ff_snow_inner_add_yblock_c() (but the MMX version has
a prologue at the beginning that it needs to undo before
the call, leading to the higher overhead for these sizes).
I don't know why the SSSE3 version is marginally faster than
the C version in these cases.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/snow.c                            |   4 +-
 libavcodec/snow_dwt.c                        |   2 +-
 libavcodec/snow_dwt.h                        |   8 +-
 libavcodec/x86/Makefile                      |   6 +-
 libavcodec/x86/snowdsp.asm                   | 191 +++++++++++++++++++
 libavcodec/x86/{snowdsp.c => snowdsp_init.c} |  17 +-
 6 files changed, 216 insertions(+), 12 deletions(-)
 create mode 100644 libavcodec/x86/snowdsp.asm
 rename libavcodec/x86/{snowdsp.c => snowdsp_init.c} (98%)

diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index e61f4f726a..5c13709b5c 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -115,8 +115,8 @@ static av_cold void init_qpel(SnowContext *const s)
     s->put_snow_qpel_pixels_tab[3][15] = put_snow_qpel2_mc33_8_c;
 }
 
-void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, 
uint8_t * * block, int b_w, int b_h,
-                              int src_x, int src_stride, IDWTELEM *const 
*lines, int add, uint8_t *dst8)
+void ff_snow_inner_add_yblock_c(const uint8_t *obmc, const int obmc_stride, 
uint8_t **block, int b_w, int b_h,
+                                int src_x, int src_stride, IDWTELEM *const 
*lines, int add, uint8_t *dst8)
 {
     int y, x;
 
diff --git a/libavcodec/snow_dwt.c b/libavcodec/snow_dwt.c
index eb4d1e4d36..28fbebbe4d 100644
--- a/libavcodec/snow_dwt.c
+++ b/libavcodec/snow_dwt.c
@@ -852,7 +852,7 @@ av_cold void ff_dwt_init(SnowDWTContext *c)
 {
     c->vertical_compose97i   = snow_vertical_compose97i;
     c->horizontal_compose97i = snow_horizontal_compose97i;
-    c->inner_add_yblock      = ff_snow_inner_add_yblock;
+    c->inner_add_yblock      = ff_snow_inner_add_yblock_c;
 
 #if ARCH_X86 && HAVE_MMX
     ff_dwt_init_x86(c);
diff --git a/libavcodec/snow_dwt.h b/libavcodec/snow_dwt.h
index a26db62d6d..d4a384b267 100644
--- a/libavcodec/snow_dwt.h
+++ b/libavcodec/snow_dwt.h
@@ -137,10 +137,10 @@ void ff_slice_buffer_flush(slice_buffer *buf);
 void ff_slice_buffer_destroy(slice_buffer *buf);
 IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line);
 
-void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
-                              uint8_t **block, int b_w, int b_h, int src_x,
-                              int src_stride, IDWTELEM *const *lines,
-                              int add, uint8_t *dst8);
+void ff_snow_inner_add_yblock_c(const uint8_t *obmc, const int obmc_stride,
+                                uint8_t **block, int b_w, int b_h, int src_x,
+                                int src_stride, IDWTELEM *const *lines,
+                                int add, uint8_t *dst8);
 
 int ff_w53_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, 
ptrdiff_t line_size, int h);
 int ff_w97_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, 
ptrdiff_t line_size, int h);
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index bf723ed1a6..e87cb750f4 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -65,8 +65,10 @@ X86ASM-OBJS-$(CONFIG_PRORES_DECODER)   += 
x86/proresdsp_init.o
 X86ASM-OBJS-$(CONFIG_PRORES_RAW_DECODER) += x86/proresdsp_init.o
 X86ASM-OBJS-$(CONFIG_RV40_DECODER)     += x86/rv40dsp_init.o
 X86ASM-OBJS-$(CONFIG_SBC_ENCODER)      += x86/sbcdsp_init.o
-OBJS-$(CONFIG_SNOW_DECODER)            += x86/snowdsp.o
-OBJS-$(CONFIG_SNOW_ENCODER)            += x86/snowdsp.o
+OBJS-$(CONFIG_SNOW_DECODER)            += x86/snowdsp_init.o
+X86ASM-OBJS-$(CONFIG_SNOW_DECODER)     += x86/snowdsp.o
+OBJS-$(CONFIG_SNOW_ENCODER)            += x86/snowdsp_init.o
+X86ASM-OBJS-$(CONFIG_SNOW_ENCODER)     += x86/snowdsp.o
 X86ASM-OBJS-$(CONFIG_SVQ1_ENCODER)     += x86/svq1enc_init.o
 X86ASM-OBJS-$(CONFIG_TAK_DECODER)      += x86/takdsp_init.o
 OBJS-$(CONFIG_TRUEHD_DECODER)          += x86/mlpdsp_init.o
diff --git a/libavcodec/x86/snowdsp.asm b/libavcodec/x86/snowdsp.asm
new file mode 100644
index 0000000000..bde9054731
--- /dev/null
+++ b/libavcodec/x86/snowdsp.asm
@@ -0,0 +1,191 @@
+;*
+;* ASM optimized Snow DSP functions
+;*
+;* This file is part of FFmpeg.
+;*
+;* FFmpeg is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* FFmpeg is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with FFmpeg; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+cextern snow_inner_add_yblock_c
+
+SECTION .text
+
+%assign FRAC_BITS     4
+%assign LOG2_OBMC_MAX 6
+
+%macro ADD_YBLOCK_PROLOGUE 1
+%assign stack_offset 0
+%if ARCH_X86_32
+    PROLOGUE 1, 7, 7+(%1>>4), obmc, offset, dst8, lines, b_h, src_x, dst
+    ; copy all four block pointers to the stack to be able to load
+    ; them via esp
+    mov             r2, r2m
+    mov           b_hd, b_hm
+    mov         src_xd, src_xm
+    movups          m1, [r2]
+    mov         linesq, r7m
+    shl         src_xd, 1              ; convert src_x from IDWTELEM to bytes
+    mov          dst8q, r9m
+    mov         src_xm, src_xd
+    ; Just reuse the space for the arguments to store the block pointers.
+%if HAVE_ALIGNED_STACK
+    movaps         r0m, m1
+%else
+    movups         r0m, m1
+%endif
+    %define src_strideq r6m
+%else ; X64
+    PROLOGUE 1, 12, 7+(%1>>4), obmc, offset, dst8, lines, b_h, src_x, 
src_stride, dst, block0, block1, block2, block3
+    mov        block0q, [r2q]
+    mov        block1q, [r2q +   gprsize]
+    mov        block2q, [r2q + 2*gprsize]
+    mov        block3q, [r2q + 3*gprsize]
+    movifnidn     b_hd, b_hm
+    movifnidn   src_xd, src_xm
+    shl         src_xd, 1              ; convert src_x from IDWTELEM to bytes 
and zero-extend it
+    movsxd src_strideq, src_stridem
+    mov         linesq, r7mp
+    mov          dst8q, r9mp
+%endif
+    xor        offsetd, offsetd
+    psllw           m0, FRAC_BITS - 1  ; pw_m8
+%endmacro
+
+%macro LOAD_BLOCKPOINTER_FOR_X86_32 2
+%if ARCH_X86_32
+    ; we put block #i into the spot of register r#i
+    mov             r5, r %+ %1 %+ m
+    mov             r6, r %+ %2 %+ m
+    %xdefine block%1q r5
+    %xdefine block%2q r6
+%endif
+%endmacro
+
+INIT_XMM ssse3
+; void ff_snow_inner_add_yblock_ssse3(const uint8_t *obmc, const int 
obmc_stride,
+;                                     uint8_t **block, int b_w, int b_h, int 
src_x,
+;                                     int src_stride, IDWTELEM *const *lines,
+;                                     int add, uint8_t *dst8);
+; Don't use cglobal to load args, as we may want to perform
+; a tail call to ff_snow_inner_add_yblock.
+cglobal snow_inner_add_yblock
+    pcmpeqw         m0, m0
+%if ARCH_X86_32
+    mov            r0d, r3m     ; block width
+    cmp            r0d, 16
+    je            .w16
+    cmp            r0d, 8
+    jne snow_inner_add_yblock_c
+    cmp           r1mp, 16
+    jne snow_inner_add_yblock_c
+%else
+    ; all arguments used to check for support are already in registers
+    cmp            r3d, 16
+    je            .w16
+    cmp            r3d, 8
+    jne snow_inner_add_yblock_c
+    cmp            r1d, 16
+    jne snow_inner_add_yblock_c
+%endif
+    ADD_YBLOCK_PROLOGUE 8
+    .loop8:
+        LOAD_BLOCKPOINTER_FOR_X86_32 1, 3
+        movq            m3, [block3q+offsetq]
+        movq            m4, [block1q+offsetq]
+        mova            m1, [obmcq]
+        mova            m2, [obmcq+16*8]
+%if ARCH_X86_64
+        mov           dstq, [linesq]
+%endif
+        LOAD_BLOCKPOINTER_FOR_X86_32 0, 2
+        movq            m5, [block2q+offsetq]
+        movq            m6, [block0q+offsetq]
+        punpcklbw       m3, m4
+%if ARCH_X86_32
+        mov           dstq, [linesq]
+        add           dstq, src_xm
+%endif
+        SBUTTERFLY      bw, 1, 2, 4
+%if ARCH_X86_64
+        movu            m4, [dstq+src_xq]
+%else
+        movu            m4, [dstq]
+%endif
+        pmaddubsw       m3, m1
+        add          obmcq, 16
+        punpcklbw       m5, m6
+        pmaddubsw       m5, m2
+        add         linesq, gprsize
+        paddw           m3, m5
+        psubw           m4, m0         ; + 1<<(FRAC_BITS-1)
+        psrlw           m3, LOG2_OBMC_MAX - FRAC_BITS
+        paddw           m3, m4
+        psraw           m3, FRAC_BITS
+        packuswb        m3, m3
+        movq [dst8q+offsetq], m3
+        add        offsetq, src_strideq
+        dec           b_hd
+        jnz         .loop8
+    RET
+    .w16:
+    ADD_YBLOCK_PROLOGUE 16
+    .loop16:
+        LOAD_BLOCKPOINTER_FOR_X86_32 2, 3
+        mova            m3, [block3q+offsetq]
+        mova            m4, [block2q+offsetq]
+        mova            m1, [obmcq]
+        mova            m2, [obmcq+16]
+        LOAD_BLOCKPOINTER_FOR_X86_32 0, 1
+        SBUTTERFLY      bw, 3, 4, 7
+        mova            m5, [block1q+offsetq]
+        mova            m6, [block0q+offsetq]
+        SBUTTERFLY      bw, 1, 2, 7
+        mov           dstq, [linesq]
+        pmaddubsw       m3, m1
+        mova            m1, [obmcq+32*16]
+        pmaddubsw       m4, m2
+        mova            m2, [obmcq+32*16+16]
+%if ARCH_X86_32
+        add           dstq, src_xm
+%endif
+        SBUTTERFLY      bw, 5, 6, 7
+        SBUTTERFLY      bw, 1, 2, 7
+        pmaddubsw       m5, m1
+        add         linesq, gprsize
+        pmaddubsw       m6, m2
+        paddw           m3, m5
+        paddw           m4, m6
+        psrlw           m3, LOG2_OBMC_MAX - FRAC_BITS
+        psrlw           m4, LOG2_OBMC_MAX - FRAC_BITS
+        add          obmcq, 32
+%if ARCH_X86_32
+        paddw           m3, [dstq]
+        paddw           m4, [dstq+16]
+%else
+        paddw           m3, [dstq+src_xq]
+        paddw           m4, [dstq+src_xq+16]
+%endif
+        psubw           m3, m0         ; + 1<<(FRAC_BITS-1)
+        psubw           m4, m0         ; + 1<<(FRAC_BITS-1)
+        psraw           m3, FRAC_BITS
+        psraw           m4, FRAC_BITS
+        packuswb        m3, m4
+        movu [dst8q+offsetq], m3
+        add        offsetq, src_strideq
+        dec           b_hd
+        jnz        .loop16
+    RET
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp_init.c
similarity index 98%
rename from libavcodec/x86/snowdsp.c
rename to libavcodec/x86/snowdsp_init.c
index 7cd3fd5415..2a120cd0e0 100644
--- a/libavcodec/x86/snowdsp.c
+++ b/libavcodec/x86/snowdsp_init.c
@@ -24,8 +24,14 @@
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/snow_dwt.h"
 
+void ff_snow_inner_add_yblock_ssse3(const uint8_t *obmc, const int obmc_stride,
+                                    uint8_t **block, int b_w, int b_h, int 
src_x,
+                                    int src_stride, IDWTELEM *const *lines,
+                                    int add, uint8_t *dst8);
+
 #if HAVE_INLINE_ASM
 
 static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, IDWTELEM *temp, 
int width){
@@ -864,7 +870,7 @@ static void ff_snow_inner_add_yblock_sse2(const uint8_t 
*obmc, const int obmc_st
         else
             inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, 
b_h, src_x, src_stride, lines, add, dst8);
     } else
-         ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
+         ff_snow_inner_add_yblock_c(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
 }
 
 static void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int 
obmc_stride, uint8_t * * block, int b_w, int b_h,
@@ -875,7 +881,7 @@ static void ff_snow_inner_add_yblock_mmx(const uint8_t 
*obmc, const int obmc_str
     else if (b_w == 8 && obmc_stride == 16)
         inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x, src_stride, lines, add, dst8);
     else
-        ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
+        ff_snow_inner_add_yblock_c(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
 }
 #endif /* HAVE_6REGS */
 
@@ -883,9 +889,9 @@ static void ff_snow_inner_add_yblock_mmx(const uint8_t 
*obmc, const int obmc_str
 
 av_cold void ff_dwt_init_x86(SnowDWTContext *c)
 {
-#if HAVE_INLINE_ASM
     int mm_flags = av_get_cpu_flags();
 
+#if HAVE_INLINE_ASM
     if (mm_flags & AV_CPU_FLAG_MMX) {
         if(mm_flags & AV_CPU_FLAG_SSE2 & 0){
             c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;
@@ -909,4 +915,9 @@ av_cold void ff_dwt_init_x86(SnowDWTContext *c)
         }
     }
 #endif /* HAVE_INLINE_ASM */
+#if HAVE_SSSE3_EXTERNAL
+    if (EXTERNAL_SSSE3(mm_flags)) {
+        c->inner_add_yblock = ff_snow_inner_add_yblock_ssse3;
+    }
+#endif
 }
-- 
2.52.0


>From 9303de3d4681250333a702c84c3cce4b860c4e6e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 20:35:06 +0200
Subject: [PATCH 11/13] avcodec/x86/snowdsp_init: Remove MMXEXT, SSE2
 inner_add_yblock versions

They have been superseded by SSSE3; the SSE2 version was even disabled
(and segfaults if enabled).

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/snowdsp_init.c | 281 ----------------------------------
 tests/checkasm/snowdsp.c      |  18 +--
 2 files changed, 1 insertion(+), 298 deletions(-)

diff --git a/libavcodec/x86/snowdsp_init.c b/libavcodec/x86/snowdsp_init.c
index 2a120cd0e0..18c7cfd364 100644
--- a/libavcodec/x86/snowdsp_init.c
+++ b/libavcodec/x86/snowdsp_init.c
@@ -612,279 +612,6 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, 
IDWTELEM *b1, IDWTELEM
 }
 #endif //HAVE_7REGS
 
-#if HAVE_6REGS
-#define snow_inner_add_yblock_sse2_header \
-    x86_reg tmp;\
-    __asm__ volatile(\
-             "mov  %7, %%"FF_REG_c"          \n\t"\
-             "mov  %6, %2                    \n\t"\
-             "mov  %4, %%"FF_REG_S"          \n\t"\
-             "pxor %%xmm7, %%xmm7            \n\t" /* 0 */\
-             "pcmpeqd %%xmm3, %%xmm3         \n\t"\
-             "psllw $15, %%xmm3              \n\t"\
-             "psrlw $12, %%xmm3              \n\t" /* FRAC_BITS >> 1 */\
-             "1:                             \n\t"\
-             "mov %1, %%"FF_REG_D"           \n\t"\
-             "mov (%%"FF_REG_D"), %%"FF_REG_D" \n\t"\
-             "add %3, %%"FF_REG_D"           \n\t"
-
-#define snow_inner_add_yblock_sse2_start_8(out_reg1, out_reg2, ptr_offset, 
s_offset)\
-             "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; 
\n\t"\
-             "movq (%%"FF_REG_d"), %%"out_reg1"                           
\n\t"\
-             "movq (%%"FF_REG_d", %%"FF_REG_c"), %%"out_reg2"             
\n\t"\
-             "punpcklbw %%xmm7, %%"out_reg1" \n\t"\
-             "punpcklbw %%xmm7, %%"out_reg2" \n\t"\
-             "movq "s_offset"(%%"FF_REG_S"), %%xmm0    \n\t"\
-             "movq "s_offset"+16(%%"FF_REG_S"), %%xmm4 \n\t"\
-             "punpcklbw %%xmm7, %%xmm0       \n\t"\
-             "punpcklbw %%xmm7, %%xmm4       \n\t"\
-             "pmullw %%xmm0, %%"out_reg1"    \n\t"\
-             "pmullw %%xmm4, %%"out_reg2"    \n\t"
-
-#define snow_inner_add_yblock_sse2_start_16(out_reg1, out_reg2, ptr_offset, 
s_offset)\
-             "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; 
\n\t"\
-             "movq (%%"FF_REG_d"), %%"out_reg1"                           
\n\t"\
-             "movq 8(%%"FF_REG_d"), %%"out_reg2"                          
\n\t"\
-             "punpcklbw %%xmm7, %%"out_reg1" \n\t"\
-             "punpcklbw %%xmm7, %%"out_reg2" \n\t"\
-             "movq "s_offset"(%%"FF_REG_S"), %%xmm0   \n\t"\
-             "movq "s_offset"+8(%%"FF_REG_S"), %%xmm4 \n\t"\
-             "punpcklbw %%xmm7, %%xmm0       \n\t"\
-             "punpcklbw %%xmm7, %%xmm4       \n\t"\
-             "pmullw %%xmm0, %%"out_reg1"    \n\t"\
-             "pmullw %%xmm4, %%"out_reg2"    \n\t"
-
-#define snow_inner_add_yblock_sse2_accum_8(ptr_offset, s_offset) \
-             snow_inner_add_yblock_sse2_start_8("xmm2", "xmm6", ptr_offset, 
s_offset)\
-             "paddusw %%xmm2, %%xmm1         \n\t"\
-             "paddusw %%xmm6, %%xmm5         \n\t"
-
-#define snow_inner_add_yblock_sse2_accum_16(ptr_offset, s_offset) \
-             snow_inner_add_yblock_sse2_start_16("xmm2", "xmm6", ptr_offset, 
s_offset)\
-             "paddusw %%xmm2, %%xmm1         \n\t"\
-             "paddusw %%xmm6, %%xmm5         \n\t"
-
-#define snow_inner_add_yblock_sse2_end_common1\
-             "add $32, %%"FF_REG_S"                            \n\t"\
-             "add %%"FF_REG_c", %0                             \n\t"\
-             "add %%"FF_REG_c", "FF_PTR_SIZE"*3(%%"FF_REG_a"); \n\t"\
-             "add %%"FF_REG_c", "FF_PTR_SIZE"*2(%%"FF_REG_a"); \n\t"\
-             "add %%"FF_REG_c", "FF_PTR_SIZE"*1(%%"FF_REG_a"); \n\t"\
-             "add %%"FF_REG_c", (%%"FF_REG_a")                 \n\t"
-
-#define snow_inner_add_yblock_sse2_end_common2\
-             "jnz 1b                         \n\t"\
-             :"+m"(dst8),"+m"(lines),"=&r"(tmp)\
-             :\
-             
"rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\
-             XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", 
"%xmm5", "%xmm6", "%xmm7", )\
-             "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d"");
-
-#define snow_inner_add_yblock_sse2_end_8\
-             "sal $1, %%"FF_REG_c"                \n\t"\
-             "add"FF_OPSIZE" $"FF_PTR_SIZE"*2, %1 \n\t"\
-             snow_inner_add_yblock_sse2_end_common1\
-             "sar $1, %%"FF_REG_c"           \n\t"\
-             "sub $2, %2                     \n\t"\
-             snow_inner_add_yblock_sse2_end_common2
-
-#define snow_inner_add_yblock_sse2_end_16\
-             "add"FF_OPSIZE" $"FF_PTR_SIZE"*1, %1 \n\t"\
-             snow_inner_add_yblock_sse2_end_common1\
-             "dec %2                         \n\t"\
-             snow_inner_add_yblock_sse2_end_common2
-
-static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(const uint8_t *obmc, 
const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
-{
-snow_inner_add_yblock_sse2_header
-snow_inner_add_yblock_sse2_start_8("xmm1", "xmm5", "3", "0")
-snow_inner_add_yblock_sse2_accum_8("2", "8")
-snow_inner_add_yblock_sse2_accum_8("1", "128")
-snow_inner_add_yblock_sse2_accum_8("0", "136")
-
-             "mov %0, %%"FF_REG_d"           \n\t"
-             "movdqa (%%"FF_REG_D"), %%xmm0  \n\t"
-             "movdqa %%xmm1, %%xmm2          \n\t"
-
-             "punpckhwd %%xmm7, %%xmm1       \n\t"
-             "punpcklwd %%xmm7, %%xmm2       \n\t"
-             "paddd %%xmm2, %%xmm0           \n\t"
-             "movdqa 16(%%"FF_REG_D"), %%xmm2\n\t"
-             "paddd %%xmm1, %%xmm2           \n\t"
-             "paddd %%xmm3, %%xmm0           \n\t"
-             "paddd %%xmm3, %%xmm2           \n\t"
-
-             "mov %1, %%"FF_REG_D"           \n\t"
-             "mov "FF_PTR_SIZE"(%%"FF_REG_D"), %%"FF_REG_D"; \n\t"
-             "add %3, %%"FF_REG_D"           \n\t"
-
-             "movdqa (%%"FF_REG_D"), %%xmm4  \n\t"
-             "movdqa %%xmm5, %%xmm6          \n\t"
-             "punpckhwd %%xmm7, %%xmm5       \n\t"
-             "punpcklwd %%xmm7, %%xmm6       \n\t"
-             "paddd %%xmm6, %%xmm4           \n\t"
-             "movdqa 16(%%"FF_REG_D"), %%xmm6\n\t"
-             "paddd %%xmm5, %%xmm6           \n\t"
-             "paddd %%xmm3, %%xmm4           \n\t"
-             "paddd %%xmm3, %%xmm6           \n\t"
-
-             "psrad $8, %%xmm0               \n\t" /* FRAC_BITS. */
-             "psrad $8, %%xmm2               \n\t" /* FRAC_BITS. */
-             "packssdw %%xmm2, %%xmm0        \n\t"
-             "packuswb %%xmm7, %%xmm0        \n\t"
-             "movq %%xmm0, (%%"FF_REG_d")    \n\t"
-
-             "psrad $8, %%xmm4               \n\t" /* FRAC_BITS. */
-             "psrad $8, %%xmm6               \n\t" /* FRAC_BITS. */
-             "packssdw %%xmm6, %%xmm4        \n\t"
-             "packuswb %%xmm7, %%xmm4        \n\t"
-             "movq %%xmm4, (%%"FF_REG_d",%%"FF_REG_c"); \n\t"
-snow_inner_add_yblock_sse2_end_8
-}
-
-static void inner_add_yblock_bw_16_obmc_32_sse2(const uint8_t *obmc, const 
x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
-{
-snow_inner_add_yblock_sse2_header
-snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0")
-snow_inner_add_yblock_sse2_accum_16("2", "16")
-snow_inner_add_yblock_sse2_accum_16("1", "512")
-snow_inner_add_yblock_sse2_accum_16("0", "528")
-
-             "mov %0, %%"FF_REG_d"           \n\t"
-             "psrlw $2, %%xmm1               \n\t"
-             "psrlw $2, %%xmm5               \n\t"
-             "paddw   (%%"FF_REG_D"), %%xmm1 \n\t"
-             "paddw 16(%%"FF_REG_D"), %%xmm5 \n\t"
-             "paddw %%xmm3, %%xmm1           \n\t"
-             "paddw %%xmm3, %%xmm5           \n\t"
-             "psraw $4, %%xmm1               \n\t" /* FRAC_BITS. */
-             "psraw $4, %%xmm5               \n\t" /* FRAC_BITS. */
-             "packuswb %%xmm5, %%xmm1        \n\t"
-
-             "movdqu %%xmm1, (%%"FF_REG_d")  \n\t"
-
-snow_inner_add_yblock_sse2_end_16
-}
-
-#define snow_inner_add_yblock_mmx_header \
-    x86_reg tmp;\
-    __asm__ volatile(\
-             "mov  %7, %%"FF_REG_c"          \n\t"\
-             "mov  %6, %2                    \n\t"\
-             "mov  %4, %%"FF_REG_S"          \n\t"\
-             "pxor %%mm7, %%mm7              \n\t" /* 0 */\
-             "pcmpeqd %%mm3, %%mm3           \n\t"\
-             "psllw $15, %%mm3               \n\t"\
-             "psrlw $12, %%mm3               \n\t" /* FRAC_BITS >> 1 */\
-             "1:                             \n\t"\
-             "mov %1, %%"FF_REG_D"           \n\t"\
-             "mov (%%"FF_REG_D"), %%"FF_REG_D" \n\t"\
-             "add %3, %%"FF_REG_D"           \n\t"
-
-#define snow_inner_add_yblock_mmx_start(out_reg1, out_reg2, ptr_offset, 
s_offset, d_offset)\
-             "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; 
\n\t"\
-             "movd "d_offset"(%%"FF_REG_d"), %%"out_reg1"                 
\n\t"\
-             "movd "d_offset"+4(%%"FF_REG_d"), %%"out_reg2"               
\n\t"\
-             "punpcklbw %%mm7, %%"out_reg1" \n\t"\
-             "punpcklbw %%mm7, %%"out_reg2" \n\t"\
-             "movd "s_offset"(%%"FF_REG_S"), %%mm0   \n\t"\
-             "movd "s_offset"+4(%%"FF_REG_S"), %%mm4 \n\t"\
-             "punpcklbw %%mm7, %%mm0       \n\t"\
-             "punpcklbw %%mm7, %%mm4       \n\t"\
-             "pmullw %%mm0, %%"out_reg1"   \n\t"\
-             "pmullw %%mm4, %%"out_reg2"   \n\t"
-
-#define snow_inner_add_yblock_mmx_accum(ptr_offset, s_offset, d_offset) \
-             snow_inner_add_yblock_mmx_start("mm2", "mm6", ptr_offset, 
s_offset, d_offset)\
-             "paddusw %%mm2, %%mm1         \n\t"\
-             "paddusw %%mm6, %%mm5         \n\t"
-
-#define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\
-             "mov %0, %%"FF_REG_d"           \n\t"\
-             "psrlw $2, %%mm1                \n\t"\
-             "psrlw $2, %%mm5                \n\t"\
-             "paddw "read_offset"(%%"FF_REG_D"), %%mm1   \n\t"\
-             "paddw "read_offset"+8(%%"FF_REG_D"), %%mm5 \n\t"\
-             "paddw %%mm3, %%mm1             \n\t"\
-             "paddw %%mm3, %%mm5             \n\t"\
-             "psraw $4, %%mm1                \n\t"\
-             "psraw $4, %%mm5                \n\t"\
-             "packuswb %%mm5, %%mm1          \n\t"\
-             "movq %%mm1, "write_offset"(%%"FF_REG_d") \n\t"
-
-#define snow_inner_add_yblock_mmx_end(s_step)\
-             "add $"s_step", %%"FF_REG_S"                      \n\t"\
-             "add %%"FF_REG_c", "FF_PTR_SIZE"*3(%%"FF_REG_a"); \n\t"\
-             "add %%"FF_REG_c", "FF_PTR_SIZE"*2(%%"FF_REG_a"); \n\t"\
-             "add %%"FF_REG_c", "FF_PTR_SIZE"*1(%%"FF_REG_a"); \n\t"\
-             "add %%"FF_REG_c", (%%"FF_REG_a")                 \n\t"\
-             "add"FF_OPSIZE " $"FF_PTR_SIZE"*1, %1             \n\t"\
-             "add %%"FF_REG_c", %0                             \n\t"\
-             "dec %2                         \n\t"\
-             "jnz 1b                         \n\t"\
-             :"+m"(dst8),"+m"(lines),"=&r"(tmp)\
-             :\
-             
"rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\
-             "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d"");
-
-static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const 
x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
-{
-snow_inner_add_yblock_mmx_header
-snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0")
-snow_inner_add_yblock_mmx_accum("2", "8", "0")
-snow_inner_add_yblock_mmx_accum("1", "128", "0")
-snow_inner_add_yblock_mmx_accum("0", "136", "0")
-snow_inner_add_yblock_mmx_mix("0", "0")
-snow_inner_add_yblock_mmx_end("16")
-}
-
-static void inner_add_yblock_bw_16_obmc_32_mmx(const uint8_t *obmc, const 
x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, x86_reg src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
-{
-snow_inner_add_yblock_mmx_header
-snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0")
-snow_inner_add_yblock_mmx_accum("2", "16", "0")
-snow_inner_add_yblock_mmx_accum("1", "512", "0")
-snow_inner_add_yblock_mmx_accum("0", "528", "0")
-snow_inner_add_yblock_mmx_mix("0", "0")
-
-snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "8", "8")
-snow_inner_add_yblock_mmx_accum("2", "24", "8")
-snow_inner_add_yblock_mmx_accum("1", "520", "8")
-snow_inner_add_yblock_mmx_accum("0", "536", "8")
-snow_inner_add_yblock_mmx_mix("16", "8")
-snow_inner_add_yblock_mmx_end("32")
-}
-
-static void ff_snow_inner_add_yblock_sse2(const uint8_t *obmc, const int 
obmc_stride, uint8_t * * block, int b_w, int b_h,
-                           int src_x, int src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
-{
-    if (b_w == 16)
-        inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, 
b_h, src_x, src_stride, lines, add, dst8);
-    else if (b_w == 8 && obmc_stride == 16) {
-        if (!(b_h & 1))
-            inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, 
block, b_w, b_h, src_x, src_stride, lines, add, dst8);
-        else
-            inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, 
b_h, src_x, src_stride, lines, add, dst8);
-    } else
-         ff_snow_inner_add_yblock_c(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
-}
-
-static void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int 
obmc_stride, uint8_t * * block, int b_w, int b_h,
-                          int src_x, int src_stride, IDWTELEM *const *lines, 
int add, uint8_t * dst8)
-{
-    if (b_w == 16)
-        inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x, src_stride, lines, add, dst8);
-    else if (b_w == 8 && obmc_stride == 16)
-        inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, 
src_x, src_stride, lines, add, dst8);
-    else
-        ff_snow_inner_add_yblock_c(obmc, obmc_stride, block, b_w, b_h, src_x, 
src_stride, lines, add, dst8);
-}
-#endif /* HAVE_6REGS */
-
 #endif /* HAVE_INLINE_ASM */
 
 av_cold void ff_dwt_init_x86(SnowDWTContext *c)
@@ -892,14 +619,10 @@ av_cold void ff_dwt_init_x86(SnowDWTContext *c)
     int mm_flags = av_get_cpu_flags();
 
 #if HAVE_INLINE_ASM
-    if (mm_flags & AV_CPU_FLAG_MMX) {
         if(mm_flags & AV_CPU_FLAG_SSE2 & 0){
             c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;
 #if HAVE_7REGS
             c->vertical_compose97i = ff_snow_vertical_compose97i_sse2;
-#endif
-#if HAVE_6REGS
-            c->inner_add_yblock = ff_snow_inner_add_yblock_sse2;
 #endif
         }
         else{
@@ -909,11 +632,7 @@ av_cold void ff_dwt_init_x86(SnowDWTContext *c)
             c->vertical_compose97i = ff_snow_vertical_compose97i_mmx;
 #endif
             }
-#if HAVE_6REGS
-            c->inner_add_yblock = ff_snow_inner_add_yblock_mmx;
-#endif
         }
-    }
 #endif /* HAVE_INLINE_ASM */
 #if HAVE_SSSE3_EXTERNAL
     if (EXTERNAL_SSSE3(mm_flags)) {
diff --git a/tests/checkasm/snowdsp.c b/tests/checkasm/snowdsp.c
index 2edad643ad..99cfae679e 100644
--- a/tests/checkasm/snowdsp.c
+++ b/tests/checkasm/snowdsp.c
@@ -46,7 +46,7 @@ static void checkasm_check_inner_add_yblock(const 
SnowDWTContext *const snowdsp)
         LOG2_MIN_BLOCKSIZE = 1,
         MAX_STRIDE         = 256,
     };
-    declare_func_emms(AV_CPU_FLAG_MMX, void, const uint8_t *obmc, const int 
obmc_stride,
+    declare_func(void, const uint8_t *obmc, const int obmc_stride,
                        uint8_t **block, int b_w, int b_h, int src_x,
                        int src_stride, IDWTELEM * const *lines,
                        int add, uint8_t *dst8);
@@ -104,8 +104,6 @@ static void checkasm_check_inner_add_yblock(const 
SnowDWTContext *const snowdsp)
                 blocks[3] += (b_h - 1) * src_stride;
                 src_stride = -src_stride;
             }
-            uint8_t *blocks_backup[4] = { blocks[0], blocks[1],
-                                          blocks[2], blocks[3] };
             IDWTELEM *lines[MAX_BLOCKSIZE];
 
             for (int k = 0; k < b_h; ++k)
@@ -124,25 +122,11 @@ static void checkasm_check_inner_add_yblock(const 
SnowDWTContext *const snowdsp)
             memcpy(dst8_new, dst8_ref, sizeof(dst8_new));
 
             call_ref(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, 
lines, 1, dst8p_ref);
-            memcpy(blocks, blocks_backup, sizeof(blocks));\
             call_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, 
lines, 1, dst8p_new);
 
             if (memcmp(dst8_ref, dst8_new, sizeof(dst8_new)))
                 fail();
 
-#undef CALL4
-#define CALL4(...)\
-    do {\
-        memcpy(blocks, blocks_backup, sizeof(blocks));\
-        tfunc(__VA_ARGS__); \
-        memcpy(blocks, blocks_backup, sizeof(blocks));\
-        tfunc(__VA_ARGS__); \
-        memcpy(blocks, blocks_backup, sizeof(blocks));\
-        tfunc(__VA_ARGS__); \
-        memcpy(blocks, blocks_backup, sizeof(blocks));\
-        tfunc(__VA_ARGS__); \
-    } while (0)
-
             bench_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, 
lines, 1, dst8p_new);
         }
     }
-- 
2.52.0


>From 9de8fb46d2b9e5c365f5da90ab58cec39a12689d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 20:47:11 +0200
Subject: [PATCH 12/13] avcodec/x86/snowdsp_init: Use standard init pattern

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/snowdsp_init.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/libavcodec/x86/snowdsp_init.c b/libavcodec/x86/snowdsp_init.c
index 18c7cfd364..1d51901f33 100644
--- a/libavcodec/x86/snowdsp_init.c
+++ b/libavcodec/x86/snowdsp_init.c
@@ -616,26 +616,24 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, 
IDWTELEM *b1, IDWTELEM
 
 av_cold void ff_dwt_init_x86(SnowDWTContext *c)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpuflags = av_get_cpu_flags();
 
 #if HAVE_INLINE_ASM
-        if(mm_flags & AV_CPU_FLAG_SSE2 & 0){
-            c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;
+    if (INLINE_MMXEXT(cpuflags)) {
+        c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx;
 #if HAVE_7REGS
-            c->vertical_compose97i = ff_snow_vertical_compose97i_sse2;
+        c->vertical_compose97i   = ff_snow_vertical_compose97i_mmx;
 #endif
-        }
-        else{
-            if (mm_flags & AV_CPU_FLAG_MMXEXT) {
-            c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx;
+    }
+    if (INLINE_SSE2(cpuflags) && 0) {
+        c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;
 #if HAVE_7REGS
-            c->vertical_compose97i = ff_snow_vertical_compose97i_mmx;
+        c->vertical_compose97i   = ff_snow_vertical_compose97i_sse2;
 #endif
-            }
-        }
+    }
 #endif /* HAVE_INLINE_ASM */
 #if HAVE_SSSE3_EXTERNAL
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpuflags)) {
         c->inner_add_yblock = ff_snow_inner_add_yblock_ssse3;
     }
 #endif
-- 
2.52.0


>From 0b3fbdaf89a2ecb0783837a0058bfc2c6cf9bd20 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Apr 2026 23:23:30 +0200
Subject: [PATCH 13/13] avcodec/x86/snowdsp_init: Remove disabled SSE2
 functions

Disabled in 3e0f7126b53b395d9e79df57b2e626eb99ad846b
(almost 20 years ago) and no one fixed them, so remove them.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/snowdsp_init.c | 293 +---------------------------------
 1 file changed, 1 insertion(+), 292 deletions(-)

diff --git a/libavcodec/x86/snowdsp_init.c b/libavcodec/x86/snowdsp_init.c
index 1d51901f33..34f91c1ee7 100644
--- a/libavcodec/x86/snowdsp_init.c
+++ b/libavcodec/x86/snowdsp_init.c
@@ -1,5 +1,5 @@
 /*
- * MMX and SSE2 optimized snow DSP utils
+ * ASM optimized Snow DSP utils
  * Copyright (c) 2005-2006 Robert Edele <[email protected]>
  *
  * This file is part of FFmpeg.
@@ -34,194 +34,6 @@ void ff_snow_inner_add_yblock_ssse3(const uint8_t *obmc, 
const int obmc_stride,
 
 #if HAVE_INLINE_ASM
 
-static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, IDWTELEM *temp, 
int width){
-    const int w2= (width+1)>>1;
-    const int w_l= (width>>1);
-    const int w_r= w2 - 1;
-    int i;
-
-    { // Lift 0
-        IDWTELEM * const ref = b + w2 - 1;
-        IDWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be 
calculated twice
-        // (the first time erroneously), we allow the SSE2 code to run an 
extra pass.
-        // The savings in code and time are well worth having to store this 
value and
-        // calculate b[0] correctly afterwards.
-
-        i = 0;
-        __asm__ volatile(
-            "pcmpeqd   %%xmm7, %%xmm7         \n\t"
-            "pcmpeqd   %%xmm3, %%xmm3         \n\t"
-            "psllw         $1, %%xmm3         \n\t"
-            "paddw     %%xmm7, %%xmm3         \n\t"
-            "psllw        $13, %%xmm3         \n\t"
-        ::);
-        for(; i<w_l-15; i+=16){
-            __asm__ volatile(
-                "movdqu   (%1), %%xmm1        \n\t"
-                "movdqu 16(%1), %%xmm5        \n\t"
-                "movdqu  2(%1), %%xmm2        \n\t"
-                "movdqu 18(%1), %%xmm6        \n\t"
-                "paddw  %%xmm1, %%xmm2        \n\t"
-                "paddw  %%xmm5, %%xmm6        \n\t"
-                "paddw  %%xmm7, %%xmm2        \n\t"
-                "paddw  %%xmm7, %%xmm6        \n\t"
-                "pmulhw %%xmm3, %%xmm2        \n\t"
-                "pmulhw %%xmm3, %%xmm6        \n\t"
-                "paddw    (%0), %%xmm2        \n\t"
-                "paddw  16(%0), %%xmm6        \n\t"
-                "movdqa %%xmm2, (%0)          \n\t"
-                "movdqa %%xmm6, 16(%0)        \n\t"
-                :: "r"(&b[i]), "r"(&ref[i])
-                : "memory"
-            );
-        }
-        snow_horizontal_compose_lift_lead_out(i, b, b, ref, width, w_l, 0, 
W_DM, W_DO, W_DS);
-        b[0] = b_0 - ((W_DM * 2 * ref[1]+W_DO)>>W_DS);
-    }
-
-    { // Lift 1
-        IDWTELEM * const dst = b+w2;
-
-        i = 0;
-        for(; (((x86_reg)&dst[i]) & 0x1F) && i<w_r; i++){
-            dst[i] = dst[i] - (b[i] + b[i + 1]);
-        }
-        for(; i<w_r-15; i+=16){
-            __asm__ volatile(
-                "movdqu   (%1), %%xmm1        \n\t"
-                "movdqu 16(%1), %%xmm5        \n\t"
-                "movdqu  2(%1), %%xmm2        \n\t"
-                "movdqu 18(%1), %%xmm6        \n\t"
-                "paddw  %%xmm1, %%xmm2        \n\t"
-                "paddw  %%xmm5, %%xmm6        \n\t"
-                "movdqa   (%0), %%xmm0        \n\t"
-                "movdqa 16(%0), %%xmm4        \n\t"
-                "psubw  %%xmm2, %%xmm0        \n\t"
-                "psubw  %%xmm6, %%xmm4        \n\t"
-                "movdqa %%xmm0, (%0)          \n\t"
-                "movdqa %%xmm4, 16(%0)        \n\t"
-                :: "r"(&dst[i]), "r"(&b[i])
-                : "memory"
-            );
-        }
-        snow_horizontal_compose_lift_lead_out(i, dst, dst, b, width, w_r, 1, 
W_CM, W_CO, W_CS);
-    }
-
-    { // Lift 2
-        IDWTELEM * const ref = b+w2 - 1;
-        IDWTELEM b_0 = b[0];
-
-        i = 0;
-        __asm__ volatile(
-            "psllw         $15, %%xmm7        \n\t"
-            "pcmpeqw    %%xmm6, %%xmm6        \n\t"
-            "psrlw         $13, %%xmm6        \n\t"
-            "paddw      %%xmm7, %%xmm6        \n\t"
-        ::);
-        for(; i<w_l-15; i+=16){
-            __asm__ volatile(
-                "movdqu   (%1), %%xmm0        \n\t"
-                "movdqu 16(%1), %%xmm4        \n\t"
-                "movdqu  2(%1), %%xmm1        \n\t"
-                "movdqu 18(%1), %%xmm5        \n\t" //FIXME try aligned reads 
and shifts
-                "paddw  %%xmm6, %%xmm0        \n\t"
-                "paddw  %%xmm6, %%xmm4        \n\t"
-                "paddw  %%xmm7, %%xmm1        \n\t"
-                "paddw  %%xmm7, %%xmm5        \n\t"
-                "pavgw  %%xmm1, %%xmm0        \n\t"
-                "pavgw  %%xmm5, %%xmm4        \n\t"
-                "psubw  %%xmm7, %%xmm0        \n\t"
-                "psubw  %%xmm7, %%xmm4        \n\t"
-                "psraw      $1, %%xmm0        \n\t"
-                "psraw      $1, %%xmm4        \n\t"
-                "movdqa   (%0), %%xmm1        \n\t"
-                "movdqa 16(%0), %%xmm5        \n\t"
-                "paddw  %%xmm1, %%xmm0        \n\t"
-                "paddw  %%xmm5, %%xmm4        \n\t"
-                "psraw      $2, %%xmm0        \n\t"
-                "psraw      $2, %%xmm4        \n\t"
-                "paddw  %%xmm1, %%xmm0        \n\t"
-                "paddw  %%xmm5, %%xmm4        \n\t"
-                "movdqa %%xmm0, (%0)          \n\t"
-                "movdqa %%xmm4, 16(%0)        \n\t"
-                :: "r"(&b[i]), "r"(&ref[i])
-                : "memory"
-            );
-        }
-        snow_horizontal_compose_liftS_lead_out(i, b, b, ref, width, w_l);
-        b[0] = b_0 + ((2 * ref[1] + W_BO-1 + 4 * b_0) >> W_BS);
-    }
-
-    { // Lift 3
-        IDWTELEM * const src = b+w2;
-
-        i = 0;
-        for(; (((x86_reg)&temp[i]) & 0x1F) && i<w_r; i++){
-            temp[i] = src[i] - ((-W_AM*(b[i] + b[i+1]))>>W_AS);
-        }
-        for(; i<w_r-7; i+=8){
-            __asm__ volatile(
-                "movdqu  2(%1), %%xmm2        \n\t"
-                "movdqu 18(%1), %%xmm6        \n\t"
-                "paddw    (%1), %%xmm2        \n\t"
-                "paddw  16(%1), %%xmm6        \n\t"
-                "movdqu   (%0), %%xmm0        \n\t"
-                "movdqu 16(%0), %%xmm4        \n\t"
-                "paddw  %%xmm2, %%xmm0        \n\t"
-                "paddw  %%xmm6, %%xmm4        \n\t"
-                "psraw      $1, %%xmm2        \n\t"
-                "psraw      $1, %%xmm6        \n\t"
-                "paddw  %%xmm0, %%xmm2        \n\t"
-                "paddw  %%xmm4, %%xmm6        \n\t"
-                "movdqa %%xmm2, (%2)          \n\t"
-                "movdqa %%xmm6, 16(%2)        \n\t"
-                :: "r"(&src[i]), "r"(&b[i]), "r"(&temp[i])
-                 : "memory"
-               );
-        }
-        snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, 
-W_AM, W_AO+1, W_AS);
-    }
-
-    {
-        snow_interleave_line_header(&i, width, b, temp);
-
-        for (; (i & 0x3E) != 0x3E; i-=2){
-            b[i+1] = temp[i>>1];
-            b[i] = b[i>>1];
-        }
-        for (i-=62; i>=0; i-=64){
-            __asm__ volatile(
-                "movdqa      (%1), %%xmm0       \n\t"
-                "movdqa    16(%1), %%xmm2       \n\t"
-                "movdqa    32(%1), %%xmm4       \n\t"
-                "movdqa    48(%1), %%xmm6       \n\t"
-                "movdqa      (%1), %%xmm1       \n\t"
-                "movdqa    16(%1), %%xmm3       \n\t"
-                "movdqa    32(%1), %%xmm5       \n\t"
-                "movdqa    48(%1), %%xmm7       \n\t"
-                "punpcklwd   (%2), %%xmm0       \n\t"
-                "punpcklwd 16(%2), %%xmm2       \n\t"
-                "punpcklwd 32(%2), %%xmm4       \n\t"
-                "punpcklwd 48(%2), %%xmm6       \n\t"
-                "movdqa    %%xmm0, (%0)         \n\t"
-                "movdqa    %%xmm2, 32(%0)       \n\t"
-                "movdqa    %%xmm4, 64(%0)       \n\t"
-                "movdqa    %%xmm6, 96(%0)       \n\t"
-                "punpckhwd   (%2), %%xmm1       \n\t"
-                "punpckhwd 16(%2), %%xmm3       \n\t"
-                "punpckhwd 32(%2), %%xmm5       \n\t"
-                "punpckhwd 48(%2), %%xmm7       \n\t"
-                "movdqa    %%xmm1, 16(%0)       \n\t"
-                "movdqa    %%xmm3, 48(%0)       \n\t"
-                "movdqa    %%xmm5, 80(%0)       \n\t"
-                "movdqa    %%xmm7, 112(%0)      \n\t"
-                :: "r"(&(b)[i]), "r"(&(b)[i>>1]), "r"(&(temp)[i>>1])
-                 : "memory"
-               );
-        }
-    }
-}
-
 static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, IDWTELEM *temp, int 
width){
     const int w2= (width+1)>>1;
     const int w_l= (width>>1);
@@ -396,30 +208,12 @@ static void ff_snow_horizontal_compose97i_mmx(IDWTELEM 
*b, IDWTELEM *temp, int w
 }
 
 #if HAVE_7REGS
-#define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\
-        ""op" ("r",%%"FF_REG_d"), %%"t0"      \n\t"\
-        ""op" 16("r",%%"FF_REG_d"), %%"t1"    \n\t"\
-        ""op" 32("r",%%"FF_REG_d"), %%"t2"    \n\t"\
-        ""op" 48("r",%%"FF_REG_d"), %%"t3"    \n\t"
-
-#define snow_vertical_compose_sse2_load(r,t0,t1,t2,t3)\
-        snow_vertical_compose_sse2_load_add("movdqa",r,t0,t1,t2,t3)
-
-#define snow_vertical_compose_sse2_add(r,t0,t1,t2,t3)\
-        snow_vertical_compose_sse2_load_add("paddw",r,t0,t1,t2,t3)
-
 #define snow_vertical_compose_r2r_sub(s0,s1,s2,s3,t0,t1,t2,t3)\
         "psubw %%"s0", %%"t0" \n\t"\
         "psubw %%"s1", %%"t1" \n\t"\
         "psubw %%"s2", %%"t2" \n\t"\
         "psubw %%"s3", %%"t3" \n\t"
 
-#define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\
-        "movdqa %%"s0", ("w",%%"FF_REG_d")    \n\t"\
-        "movdqa %%"s1", 16("w",%%"FF_REG_d")  \n\t"\
-        "movdqa %%"s2", 32("w",%%"FF_REG_d")  \n\t"\
-        "movdqa %%"s3", 48("w",%%"FF_REG_d")  \n\t"
-
 #define snow_vertical_compose_sra(n,t0,t1,t2,t3)\
         "psraw $"n", %%"t0" \n\t"\
         "psraw $"n", %%"t1" \n\t"\
@@ -438,85 +232,6 @@ static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, 
IDWTELEM *temp, int w
         "pmulhw %%"s2", %%"t2" \n\t"\
         "pmulhw %%"s3", %%"t3" \n\t"
 
-#define snow_vertical_compose_sse2_move(s0,s1,s2,s3,t0,t1,t2,t3)\
-        "movdqa %%"s0", %%"t0" \n\t"\
-        "movdqa %%"s1", %%"t1" \n\t"\
-        "movdqa %%"s2", %%"t2" \n\t"\
-        "movdqa %%"s3", %%"t3" \n\t"
-
-static void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, 
IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){
-    x86_reg i = width;
-
-    while(i & 0x1F)
-    {
-        i--;
-        b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
-        b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
-        b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
-        b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
-    }
-    i+=i;
-
-         __asm__ volatile (
-        "jmp 2f                                      \n\t"
-        "1:                                          \n\t"
-        snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%6","xmm0","xmm2","xmm4","xmm6")
-
-
-        "pcmpeqw    %%xmm0, %%xmm0                   \n\t"
-        "pcmpeqw    %%xmm2, %%xmm2                   \n\t"
-        "paddw      %%xmm2, %%xmm2                   \n\t"
-        "paddw      %%xmm0, %%xmm2                   \n\t"
-        "psllw         $13, %%xmm2                   \n\t"
-        
snow_vertical_compose_r2r_add("xmm0","xmm0","xmm0","xmm0","xmm1","xmm3","xmm5","xmm7")
-        
snow_vertical_compose_r2r_pmulhw("xmm2","xmm2","xmm2","xmm2","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sse2_add("%5","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sse2_store("%5","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%3","xmm1","xmm3","xmm5","xmm7")
-        
snow_vertical_compose_r2r_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_store("%4","xmm0","xmm2","xmm4","xmm6")
-
-        "pcmpeqw %%xmm7, %%xmm7                      \n\t"
-        "pcmpeqw %%xmm5, %%xmm5                      \n\t"
-        "psllw $15, %%xmm7                           \n\t"
-        "psrlw $13, %%xmm5                           \n\t"
-        "paddw %%xmm7, %%xmm5                        \n\t"
-        
snow_vertical_compose_r2r_add("xmm5","xmm5","xmm5","xmm5","xmm0","xmm2","xmm4","xmm6")
-        "movq   (%2,%%"FF_REG_d"), %%xmm1            \n\t"
-        "movq  8(%2,%%"FF_REG_d"), %%xmm3            \n\t"
-        "paddw %%xmm7, %%xmm1                        \n\t"
-        "paddw %%xmm7, %%xmm3                        \n\t"
-        "pavgw %%xmm1, %%xmm0                        \n\t"
-        "pavgw %%xmm3, %%xmm2                        \n\t"
-        "movq 16(%2,%%"FF_REG_d"), %%xmm1            \n\t"
-        "movq 24(%2,%%"FF_REG_d"), %%xmm3            \n\t"
-        "paddw %%xmm7, %%xmm1                        \n\t"
-        "paddw %%xmm7, %%xmm3                        \n\t"
-        "pavgw %%xmm1, %%xmm4                        \n\t"
-        "pavgw %%xmm3, %%xmm6                        \n\t"
-        
snow_vertical_compose_r2r_sub("xmm7","xmm7","xmm7","xmm7","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6")
-
-        snow_vertical_compose_sra("2","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_store("%3","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%1","xmm0","xmm2","xmm4","xmm6")
-        
snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6")
-        
snow_vertical_compose_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%2","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_store("%2","xmm0","xmm2","xmm4","xmm6")
-
-        "2:                                          \n\t"
-        "sub $64, %%"FF_REG_d"                       \n\t"
-        "jge 1b                                      \n\t"
-        :"+d"(i)
-        :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5));
-}
-
 #define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\
         ""op" ("r",%%"FF_REG_d"), %%"t0"   \n\t"\
         ""op" 8("r",%%"FF_REG_d"), %%"t1"  \n\t"\
@@ -623,12 +338,6 @@ av_cold void ff_dwt_init_x86(SnowDWTContext *c)
         c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx;
 #if HAVE_7REGS
         c->vertical_compose97i   = ff_snow_vertical_compose97i_mmx;
-#endif
-    }
-    if (INLINE_SSE2(cpuflags) && 0) {
-        c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;
-#if HAVE_7REGS
-        c->vertical_compose97i   = ff_snow_vertical_compose97i_sse2;
 #endif
     }
 #endif /* HAVE_INLINE_ASM */
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to