[FFmpeg-devel] [PATCH 4/4] avcodec/me_cmp: Don't access AVCodecContext directly in ff_me_cmp_init()

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Tue Sep 20 00:28:39 EEST 2022


Instead, pass the used parameters directly. This has the advantage
that the user needn't have an AVCodecContext to call ff_me_cmp_init().

This in particular applies to the checkasm test for this. The calls
to avcodec_alloc_context3() and avcodec_free_context() made checkasm
pull most of libavcodec in (in particular, all the codecs).

This is bad in itself, but it also triggered an issue when using shared
builds with MSVC: Certain codecs use avpriv_(cga|vga16)_font and the
when using shared builds it is expected that these symbols are imported
from a different dll, but checkasm links statically to all libraries
to be able to access their internals, which causes link failures
with MSVC when any of these codecs are pulled in. See e.g.
https://fate.ffmpeg.org/log.cgi?time=20220919173112&slot=x86_32-msvc14-dll-md-windows-native&log=test
This commit ensures that these fonts are no longer pulled in by
checkasm and therefore fixes this issue.

(This is actually a regression since commit
c471cc74747461ca166559c7b7fdfe030c3e3712.)

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavcodec/aarch64/me_cmp_init_aarch64.c |  2 +-
 libavcodec/ac3enc.c                      |  2 +-
 libavcodec/alpha/me_cmp_alpha.c          |  2 +-
 libavcodec/arm/me_cmp_init_arm.c         |  2 +-
 libavcodec/dvenc.c                       |  2 +-
 libavcodec/error_resilience.c            |  2 +-
 libavcodec/me_cmp.c                      | 14 +++++++-------
 libavcodec/me_cmp.h                      | 17 +++++++++--------
 libavcodec/mips/me_cmp_init_mips.c       |  2 +-
 libavcodec/mpegvideo_enc.c               |  2 +-
 libavcodec/ppc/me_cmp.c                  |  2 +-
 libavcodec/snow.c                        |  2 +-
 libavcodec/svq1enc.c                     |  2 +-
 libavcodec/tests/motion.c                |  8 ++------
 libavcodec/x86/me_cmp_init.c             |  8 ++++----
 tests/checkasm/motion.c                  |  9 +--------
 16 files changed, 34 insertions(+), 44 deletions(-)

diff --git a/libavcodec/aarch64/me_cmp_init_aarch64.c b/libavcodec/aarch64/me_cmp_init_aarch64.c
index ade3e9a4c1..ff6b933635 100644
--- a/libavcodec/aarch64/me_cmp_init_aarch64.c
+++ b/libavcodec/aarch64/me_cmp_init_aarch64.c
@@ -54,7 +54,7 @@ int nsse16_neon(int multiplier, const uint8_t *s, const uint8_t *s2,
 int nsse16_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
                         ptrdiff_t stride, int h);
 
-av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init_aarch64(MECmpContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index a090576823..6599821cb8 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -2612,7 +2612,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
         return ret;
 
     ff_audiodsp_init(&s->adsp);
-    ff_me_cmp_init(&s->mecc, avctx);
+    ff_me_cmp_init(&s->mecc, avctx->flags & AV_CODEC_FLAG_BITEXACT, avctx->codec_id);
     ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
 
     dprint_options(s);
diff --git a/libavcodec/alpha/me_cmp_alpha.c b/libavcodec/alpha/me_cmp_alpha.c
index 0c1a4a62c5..2ef0703349 100644
--- a/libavcodec/alpha/me_cmp_alpha.c
+++ b/libavcodec/alpha/me_cmp_alpha.c
@@ -264,7 +264,7 @@ static int pix_abs16x16_xy2_mvi(struct MpegEncContext *v, const uint8_t *pix1, c
     return result;
 }
 
-av_cold void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init_alpha(MECmpContext *c)
 {
     /* amask clears all bits that correspond to present features.  */
     if (amask(AMASK_MVI) == 0) {
diff --git a/libavcodec/arm/me_cmp_init_arm.c b/libavcodec/arm/me_cmp_init_arm.c
index 8c556f1755..9f5843c486 100644
--- a/libavcodec/arm/me_cmp_init_arm.c
+++ b/libavcodec/arm/me_cmp_init_arm.c
@@ -38,7 +38,7 @@ int ff_pix_abs8_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk
 int ff_sse16_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
                    ptrdiff_t stride, int h);
 
-av_cold void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init_arm(MECmpContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
index 4c747ef71f..48d006c0f9 100644
--- a/libavcodec/dvenc.c
+++ b/libavcodec/dvenc.c
@@ -102,7 +102,7 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx)
     memset(&mecc,0, sizeof(mecc));
     memset(&pdsp,0, sizeof(pdsp));
     ff_fdctdsp_init(&fdsp, avctx);
-    ff_me_cmp_init(&mecc, avctx);
+    ff_me_cmp_init(&mecc, avctx->flags & AV_CODEC_FLAG_BITEXACT, AV_CODEC_ID_DVVIDEO);
     ff_pixblockdsp_init(&pdsp, avctx);
     ff_set_cmp(&mecc, mecc.ildct_cmp, avctx->ildct_cmp);
 
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 2aa6f1d864..e9aafa123e 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -791,7 +791,7 @@ void ff_er_frame_start(ERContext *s)
 
     if (!s->mecc_inited) {
         MECmpContext mecc;
-        ff_me_cmp_init(&mecc, s->avctx);
+        ff_me_cmp_init(&mecc, s->avctx->flags & AV_CODEC_FLAG_BITEXACT, s->avctx->codec_id);
         s->sad = mecc.sad[0];
         s->mecc_inited = 1;
     }
diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c
index 4242fbc6e4..e35c562afd 100644
--- a/libavcodec/me_cmp.c
+++ b/libavcodec/me_cmp.c
@@ -1000,7 +1000,7 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
 WRAPPER8_16_SQ(rd8x8_c, rd16_c)
 WRAPPER8_16_SQ(bit8x8_c, bit16_c)
 
-av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init(MECmpContext *c, int bitexact, enum AVCodecID codec_id)
 {
     c->sum_abs_dctelem = sum_abs_dctelem_c;
 
@@ -1049,17 +1049,17 @@ av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
 #endif
 
 #if ARCH_AARCH64
-    ff_me_cmp_init_aarch64(c, avctx);
+    ff_me_cmp_init_aarch64(c);
 #elif ARCH_ALPHA
-    ff_me_cmp_init_alpha(c, avctx);
+    ff_me_cmp_init_alpha(c);
 #elif ARCH_ARM
-    ff_me_cmp_init_arm(c, avctx);
+    ff_me_cmp_init_arm(c);
 #elif ARCH_PPC
-    ff_me_cmp_init_ppc(c, avctx);
+    ff_me_cmp_init_ppc(c);
 #elif ARCH_X86
-    ff_me_cmp_init_x86(c, avctx);
+    ff_me_cmp_init_x86(c, bitexact, codec_id);
 #elif ARCH_MIPS
-    ff_me_cmp_init_mips(c, avctx);
+    ff_me_cmp_init_mips(c);
 #endif
 
     c->median_sad[0] = pix_median_abs16_c;
diff --git a/libavcodec/me_cmp.h b/libavcodec/me_cmp.h
index c6de2d0061..e7f0d91ae4 100644
--- a/libavcodec/me_cmp.h
+++ b/libavcodec/me_cmp.h
@@ -19,9 +19,10 @@
 #ifndef AVCODEC_ME_CMP_H
 #define AVCODEC_ME_CMP_H
 
+#include <stddef.h>
 #include <stdint.h>
 
-#include "avcodec.h"
+#include "codec_id.h"
 
 extern const uint32_t ff_square_tab[512];
 
@@ -79,13 +80,13 @@ typedef struct MECmpContext {
     me_cmp_func median_sad[6];
 } MECmpContext;
 
-void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx);
-void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx);
+void ff_me_cmp_init(MECmpContext *c, int bitexact, enum AVCodecID codec_id);
+void ff_me_cmp_init_aarch64(MECmpContext *c);
+void ff_me_cmp_init_alpha(MECmpContext *c);
+void ff_me_cmp_init_arm(MECmpContext *c);
+void ff_me_cmp_init_ppc(MECmpContext *c);
+void ff_me_cmp_init_x86(MECmpContext *c, int bitexact, enum AVCodecID codec_id);
+void ff_me_cmp_init_mips(MECmpContext *c);
 
 void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type);
 
diff --git a/libavcodec/mips/me_cmp_init_mips.c b/libavcodec/mips/me_cmp_init_mips.c
index 90b8b91256..1135bfc310 100644
--- a/libavcodec/mips/me_cmp_init_mips.c
+++ b/libavcodec/mips/me_cmp_init_mips.c
@@ -22,7 +22,7 @@
 #include "libavutil/mips/cpu.h"
 #include "me_cmp_mips.h"
 
-av_cold void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init_mips(MECmpContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 0b398c56ab..e1206fa209 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -808,7 +808,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
         return ret;
 
     ff_fdctdsp_init(&s->fdsp, avctx);
-    ff_me_cmp_init(&s->mecc, avctx);
+    ff_me_cmp_init(&s->mecc, avctx->flags & AV_CODEC_FLAG_BITEXACT, avctx->codec_id);
     ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
     ff_pixblockdsp_init(&s->pdsp, avctx);
     ff_qpeldsp_init(&s->qdsp);
diff --git a/libavcodec/ppc/me_cmp.c b/libavcodec/ppc/me_cmp.c
index 90f21525d7..185a2c15d6 100644
--- a/libavcodec/ppc/me_cmp.c
+++ b/libavcodec/ppc/me_cmp.c
@@ -723,7 +723,7 @@ static int hadamard8_diff16_altivec(MpegEncContext *s, const uint8_t *dst,
 }
 #endif /* HAVE_ALTIVEC */
 
-av_cold void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init_ppc(MECmpContext *c)
 {
 #if HAVE_ALTIVEC
     if (!PPC_ALTIVEC(av_get_cpu_flags()))
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 85ad6d10a1..e9a4a62d62 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -401,7 +401,7 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){
     s->max_ref_frames=1; //just make sure it's not an invalid value in case of no initial keyframe
     s->spatial_decomposition_count = 1;
 
-    ff_me_cmp_init(&s->mecc, avctx);
+    ff_me_cmp_init(&s->mecc, avctx->flags & AV_CODEC_FLAG_BITEXACT, AV_CODEC_ID_SNOW);
     ff_hpeldsp_init(&s->hdsp, avctx->flags);
     ff_videodsp_init(&s->vdsp, 8);
     ff_dwt_init(&s->dwt);
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index ef6655c2f7..b3b7a28f05 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -526,7 +526,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx)
     }
 
     ff_hpeldsp_init(&s->hdsp, avctx->flags);
-    ff_me_cmp_init(&s->mecc, avctx);
+    ff_me_cmp_init(&s->mecc, avctx->flags & AV_CODEC_FLAG_BITEXACT, AV_CODEC_ID_SVQ1);
     ff_mpegvideoencdsp_init(&s->m.mpvencdsp, avctx);
 
     s->current_picture = av_frame_alloc();
diff --git a/libavcodec/tests/motion.c b/libavcodec/tests/motion.c
index ef6e1ff309..5f12e19849 100644
--- a/libavcodec/tests/motion.c
+++ b/libavcodec/tests/motion.c
@@ -114,7 +114,6 @@ static void test_motion(const char *name,
 
 int main(int argc, char **argv)
 {
-    AVCodecContext *ctx;
     int c;
     MECmpContext cctx, mmxctx;
     int flags[2] = { AV_CPU_FLAG_MMX, AV_CPU_FLAG_MMXEXT };
@@ -127,16 +126,14 @@ int main(int argc, char **argv)
 
     printf("ffmpeg motion test\n");
 
-    ctx = avcodec_alloc_context3(NULL);
-    ctx->flags |= AV_CODEC_FLAG_BITEXACT;
     av_force_cpu_flags(0);
     memset(&cctx, 0, sizeof(cctx));
-    ff_me_cmp_init(&cctx, ctx);
+    ff_me_cmp_init(&cctx, 1, AV_CODEC_ID_NONE);
     for (c = 0; c < flags_size; c++) {
         int x;
         av_force_cpu_flags(flags[c]);
         memset(&mmxctx, 0, sizeof(mmxctx));
-        ff_me_cmp_init(&mmxctx, ctx);
+        ff_me_cmp_init(&mmxctx, 1, AV_CODEC_ID_NONE);
 
         for (x = 0; x < 2; x++) {
             printf("%s for %dx%d pixels\n", c ? "mmx2" : "mmx",
@@ -147,7 +144,6 @@ int main(int argc, char **argv)
             test_motion("mmx_xy2", mmxctx.pix_abs[x][3], cctx.pix_abs[x][3]);
         }
     }
-    av_free(ctx);
 
     return 0;
 }
diff --git a/libavcodec/x86/me_cmp_init.c b/libavcodec/x86/me_cmp_init.c
index bc1051c27e..60fe3fd3d2 100644
--- a/libavcodec/x86/me_cmp_init.c
+++ b/libavcodec/x86/me_cmp_init.c
@@ -230,7 +230,7 @@ PIX_SADXY(mmx)
 
 #endif /* HAVE_INLINE_ASM */
 
-av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
+av_cold void ff_me_cmp_init_x86(MECmpContext *c, int bitexact, enum AVCodecID codec_id)
 {
     int cpu_flags = av_get_cpu_flags();
 
@@ -269,7 +269,7 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
         c->vsad[4] = ff_vsad_intra16_mmxext;
         c->vsad[5] = ff_vsad_intra8_mmxext;
 
-        if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
+        if (!bitexact) {
             c->pix_abs[0][3] = ff_sad16_approx_xy2_mmxext;
             c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext;
 
@@ -286,14 +286,14 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
         c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2;
         c->hadamard8_diff[1] = ff_hadamard8_diff_sse2;
 #endif
-        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && avctx->codec_id != AV_CODEC_ID_SNOW) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && codec_id != AV_CODEC_ID_SNOW) {
             c->sad[0]        = ff_sad16_sse2;
             c->pix_abs[0][0] = ff_sad16_sse2;
             c->pix_abs[0][1] = ff_sad16_x2_sse2;
             c->pix_abs[0][2] = ff_sad16_y2_sse2;
 
             c->vsad[4]       = ff_vsad_intra16_sse2;
-            if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
+            if (!bitexact) {
                 c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2;
                 c->vsad[0]       = ff_vsad16_approx_sse2;
             }
diff --git a/tests/checkasm/motion.c b/tests/checkasm/motion.c
index 87b20d1c10..77b4e1458a 100644
--- a/tests/checkasm/motion.c
+++ b/tests/checkasm/motion.c
@@ -118,16 +118,11 @@ static void test_motion(const char *name, me_cmp_func test_func)
 static void check_motion(void)
 {
     char buf[64];
-    AVCodecContext *av_ctx;
     MECmpContext me_ctx;
 
     memset(&me_ctx, 0, sizeof(me_ctx));
 
-    /* allocate AVCodecContext */
-    av_ctx = avcodec_alloc_context3(NULL);
-    av_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
-
-    ff_me_cmp_init(&me_ctx, av_ctx);
+    ff_me_cmp_init(&me_ctx, 1, AV_CODEC_ID_NONE);
 
     for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.pix_abs); i++) {
         for (int j = 0; j < FF_ARRAY_ELEMS(me_ctx.pix_abs[0]); j++) {
@@ -143,8 +138,6 @@ static void check_motion(void)
     }
     ME_CMP_1D_ARRAYS(XX)
 #undef XX
-
-    avcodec_free_context(&av_ctx);
 }
 
 void checkasm_check_motion(void)
-- 
2.34.1



More information about the ffmpeg-devel mailing list