[FFmpeg-devel] [PATCH 26/28] avcodec/mpegvideoencdsp: Factor draw_edges out in its own context

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Tue May 7 00:52:25 EEST 2024


This allows to remove a dependency of the dirac decoder (!)
on mpegvideoenc.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 configure                             |   7 +-
 libavcodec/Makefile                   |   1 +
 libavcodec/diracdec.c                 |  14 +--
 libavcodec/drawedgesdsp.c             |  61 ++++++++++
 libavcodec/drawedgesdsp.h             |  35 ++++++
 libavcodec/mpegvideo.h                |   2 +
 libavcodec/mpegvideo_enc.c            |   9 +-
 libavcodec/mpegvideoencdsp.c          |  32 ------
 libavcodec/mpegvideoencdsp.h          |   6 -
 libavcodec/snowenc.c                  |  13 ++-
 libavcodec/x86/Makefile               |   1 +
 libavcodec/x86/drawedgesdsp.c         | 157 ++++++++++++++++++++++++++
 libavcodec/x86/mpegvideo.c            |   2 +-
 libavcodec/x86/mpegvideoencdsp_init.c | 118 -------------------
 14 files changed, 281 insertions(+), 177 deletions(-)
 create mode 100644 libavcodec/drawedgesdsp.c
 create mode 100644 libavcodec/drawedgesdsp.h
 create mode 100644 libavcodec/x86/drawedgesdsp.c

diff --git a/configure b/configure
index bea4547e20..edb1ddca33 100755
--- a/configure
+++ b/configure
@@ -2552,6 +2552,7 @@ CONFIG_EXTRA="
     dnn
     dovi_rpudec
     dovi_rpuenc
+    drawedgesdsp
     dvprofile
     evcparse
     exif
@@ -2868,7 +2869,7 @@ mpeg_er_select="error_resilience"
 mpegaudio_select="mpegaudiodsp mpegaudioheader"
 mpegvideo_select="blockdsp hpeldsp idctdsp videodsp"
 mpegvideodec_select="h264chroma mpegvideo mpeg_er"
-mpegvideoenc_select="aandcttables fdctdsp me_cmp mpegvideo pixblockdsp"
+mpegvideoenc_select="aandcttables drawedgesdsp fdctdsp me_cmp mpegvideo pixblockdsp"
 msmpeg4dec_select="h263_decoder"
 msmpeg4enc_select="h263_encoder"
 vc1dsp_select="h264chroma qpeldsp startcode"
@@ -2918,7 +2919,7 @@ cook_decoder_select="audiodsp sinewin"
 cri_decoder_select="mjpeg_decoder"
 cscd_decoder_suggest="zlib"
 dds_decoder_select="texturedsp"
-dirac_decoder_select="dirac_parse dwt golomb mpegvideoenc qpeldsp videodsp"
+dirac_decoder_select="dirac_parse drawedgesdsp dwt golomb qpeldsp videodsp"
 dnxhd_decoder_select="blockdsp idctdsp"
 dnxhd_encoder_select="blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp videodsp"
 dvvideo_decoder_select="dvprofile idctdsp"
@@ -3060,7 +3061,7 @@ shorten_decoder_select="bswapdsp"
 sipr_decoder_select="lsp"
 smvjpeg_decoder_select="mjpeg_decoder"
 snow_decoder_select="dwt h264qpel rangecoder videodsp"
-snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder videodsp"
+snow_encoder_select="drawedgesdsp dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder videodsp"
 sonic_decoder_select="golomb rangecoder"
 sonic_encoder_select="golomb rangecoder"
 sonic_ls_encoder_select="golomb rangecoder"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3e8a44e89c..dff6193bc2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -89,6 +89,7 @@ OBJS-$(CONFIG_CBS_VP9)                 += cbs_vp9.o
 OBJS-$(CONFIG_DEFLATE_WRAPPER)         += zlib_wrapper.o
 OBJS-$(CONFIG_DOVI_RPUDEC)             += dovi_rpu.o dovi_rpudec.o
 OBJS-$(CONFIG_DOVI_RPUENC)             += dovi_rpu.o dovi_rpuenc.o
+OBJS-$(CONFIG_DRAWEDGESDSP)            += drawedgesdsp.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)        += error_resilience.o
 OBJS-$(CONFIG_EVCPARSE)                += evc_parse.o evc_ps.o
 OBJS-$(CONFIG_EXIF)                    += exif.o tiff_common.o
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index f1fde0b339..f0df74e131 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -34,11 +34,11 @@
 #include "get_bits.h"
 #include "codec_internal.h"
 #include "decode.h"
+#include "drawedgesdsp.h"
 #include "golomb.h"
 #include "dirac_arith.h"
 #include "dirac_vlc.h"
 #include "mpegpicture.h"
-#include "mpegvideoencdsp.h"
 #include "dirac_dwt.h"
 #include "dirac.h"
 #include "diractab.h"
@@ -135,7 +135,7 @@ typedef struct DiracSlice {
 
 typedef struct DiracContext {
     AVCodecContext *avctx;
-    MpegvideoEncDSPContext mpvencdsp;
+    DrawEdgesDSPContext drawedges;
     VideoDSPContext vdsp;
     DiracDSPContext diracdsp;
     DiracVersionInfo version;
@@ -397,7 +397,7 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx)
     s->thread_buf_size = -1;
 
     ff_diracdsp_init(&s->diracdsp);
-    ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
+    ff_drawedgesdsp_init(&s->drawedges);
     ff_videodsp_init(&s->vdsp, 8);
 
     for (i = 0; i < MAX_FRAMES; i++) {
@@ -1836,7 +1836,7 @@ static int interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int
     int i, edge = EDGE_WIDTH/2;
 
     ref->hpel[plane][0] = ref->avframe->data[plane];
-    s->mpvencdsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
+    s->drawedges.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
 
     /* no need for hpel if we only have fpel vectors */
     if (!s->mv_precision)
@@ -1856,9 +1856,9 @@ static int interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int
         s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2],
                                       ref->hpel[plane][3], ref->hpel[plane][0],
                                       ref->avframe->linesize[plane], width, height);
-        s->mpvencdsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
-        s->mpvencdsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
-        s->mpvencdsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+        s->drawedges.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+        s->drawedges.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+        s->drawedges.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
     }
     ref->interpolated[plane] = 1;
 
diff --git a/libavcodec/drawedgesdsp.c b/libavcodec/drawedgesdsp.c
new file mode 100644
index 0000000000..3306bb9f6d
--- /dev/null
+++ b/libavcodec/drawedgesdsp.c
@@ -0,0 +1,61 @@
+/*
+ * 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 <stdint.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "drawedgesdsp.h"
+#include "libavutil/attributes.h"
+
+/* draw the edges of width 'w' of an image of size width, height */
+// FIXME: Check that this is OK for MPEG-4 interlaced.
+static void draw_edges_c(uint8_t *buf, int wrap, int width, int height,
+                         int w, int h, int sides)
+{
+    uint8_t *ptr = buf, *last_line;
+
+    /* left and right */
+    for (int i = 0; i < height; i++) {
+        memset(ptr - w, ptr[0], w);
+        memset(ptr + width, ptr[width - 1], w);
+        ptr += wrap;
+    }
+
+    /* top and bottom + corners */
+    buf -= w;
+    last_line = buf + (height - 1) * wrap;
+    if (sides & EDGE_TOP)
+        for (int i = 0; i < h; i++)
+            // top
+            memcpy(buf - (i + 1) * wrap, buf, width + w + w);
+    if (sides & EDGE_BOTTOM)
+        for (int i = 0; i < h; i++)
+            // bottom
+            memcpy(last_line + (i + 1) * wrap, last_line, width + w + w);
+}
+
+av_cold void ff_drawedgesdsp_init(DrawEdgesDSPContext *c)
+{
+    c->draw_edges = draw_edges_c;
+
+#if ARCH_X86
+    ff_drawedgesdsp_init_x86(c);
+#endif
+}
diff --git a/libavcodec/drawedgesdsp.h b/libavcodec/drawedgesdsp.h
new file mode 100644
index 0000000000..a57275809c
--- /dev/null
+++ b/libavcodec/drawedgesdsp.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+ */
+
+#ifndef AVCODEC_DRAWEDGESDSP_H
+#define AVCODEC_DRAWEDGESDSP_H
+
+#include <stdint.h>
+
+#define EDGE_TOP    1
+#define EDGE_BOTTOM 2
+
+typedef struct DrawEdgesDSPContext {
+    void (*draw_edges)(uint8_t *buf, int wrap, int width, int height,
+                       int w, int h, int sides);
+} DrawEdgesDSPContext;
+
+void ff_drawedgesdsp_init(DrawEdgesDSPContext *c);
+void ff_drawedgesdsp_init_x86(DrawEdgesDSPContext *c);
+
+#endif /* AVCODEC_DRAWEDGESDSP_H */
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 215df0fd5b..4635172732 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -29,6 +29,7 @@
 #define AVCODEC_MPEGVIDEO_H
 
 #include "blockdsp.h"
+#include "drawedgesdsp.h"
 #include "error_resilience.h"
 #include "fdctdsp.h"
 #include "get_bits.h"
@@ -222,6 +223,7 @@ typedef struct MpegEncContext {
     HpelDSPContext hdsp;
     IDCTDSPContext idsp;
     MECmpContext mecc;
+    DrawEdgesDSPContext drawedges;
     MpegvideoEncDSPContext mpvencdsp;
     PixblockDSPContext pdsp;
     QpelDSPContext qdsp;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 2a75973ac4..ab14538b33 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -810,6 +810,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
     ff_fdctdsp_init(&s->fdsp, avctx);
     ff_me_cmp_init(&s->mecc, avctx);
     ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
+    ff_drawedgesdsp_init(&s->drawedges);
     ff_pixblockdsp_init(&s->pdsp, avctx);
 
     if (!(avctx->stats_out = av_mallocz(256))               ||
@@ -1224,7 +1225,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
                     }
                 }
                 if ((s->width & 15) || (s->height & (vpad-1))) {
-                    s->mpvencdsp.draw_edges(dst, dst_stride,
+                    s->drawedges.draw_edges(dst, dst_stride,
                                             w, h,
                                             16 >> h_shift,
                                             vpad >> v_shift,
@@ -1655,19 +1656,19 @@ static void frame_end(MpegEncContext *s)
         !s->intra_only) {
         int hshift = s->chroma_x_shift;
         int vshift = s->chroma_y_shift;
-        s->mpvencdsp.draw_edges(s->current_picture.f->data[0],
+        s->drawedges.draw_edges(s->current_picture.f->data[0],
                                 s->current_picture.f->linesize[0],
                                 s->h_edge_pos, s->v_edge_pos,
                                 EDGE_WIDTH, EDGE_WIDTH,
                                 EDGE_TOP | EDGE_BOTTOM);
-        s->mpvencdsp.draw_edges(s->current_picture.f->data[1],
+        s->drawedges.draw_edges(s->current_picture.f->data[1],
                                 s->current_picture.f->linesize[1],
                                 s->h_edge_pos >> hshift,
                                 s->v_edge_pos >> vshift,
                                 EDGE_WIDTH >> hshift,
                                 EDGE_WIDTH >> vshift,
                                 EDGE_TOP | EDGE_BOTTOM);
-        s->mpvencdsp.draw_edges(s->current_picture.f->data[2],
+        s->drawedges.draw_edges(s->current_picture.f->data[2],
                                 s->current_picture.f->linesize[2],
                                 s->h_edge_pos >> hshift,
                                 s->v_edge_pos >> vshift,
diff --git a/libavcodec/mpegvideoencdsp.c b/libavcodec/mpegvideoencdsp.c
index 997d048663..a6de93456d 100644
--- a/libavcodec/mpegvideoencdsp.c
+++ b/libavcodec/mpegvideoencdsp.c
@@ -16,9 +16,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <assert.h>
 #include <stdint.h>
-#include <string.h>
 
 #include "config.h"
 #include "libavutil/avassert.h"
@@ -114,34 +112,6 @@ static int pix_norm1_c(const uint8_t *pix, int line_size)
     return s;
 }
 
-/* draw the edges of width 'w' of an image of size width, height */
-// FIXME: Check that this is OK for MPEG-4 interlaced.
-static void draw_edges_8_c(uint8_t *buf, int wrap, int width, int height,
-                           int w, int h, int sides)
-{
-    uint8_t *ptr = buf, *last_line;
-    int i;
-
-    /* left and right */
-    for (i = 0; i < height; i++) {
-        memset(ptr - w, ptr[0], w);
-        memset(ptr + width, ptr[width - 1], w);
-        ptr += wrap;
-    }
-
-    /* top and bottom + corners */
-    buf -= w;
-    last_line = buf + (height - 1) * wrap;
-    if (sides & EDGE_TOP)
-        for (i = 0; i < h; i++)
-            // top
-            memcpy(buf - (i + 1) * wrap, buf, width + w + w);
-    if (sides & EDGE_BOTTOM)
-        for (i = 0; i < h; i++)
-            // bottom
-            memcpy(last_line + (i + 1) * wrap, last_line, width + w + w);
-}
-
 /* 2x2 -> 1x1 */
 static void shrink22(uint8_t *dst, int dst_wrap,
                      const uint8_t *src, int src_wrap,
@@ -243,8 +213,6 @@ av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c,
     c->pix_sum   = pix_sum_c;
     c->pix_norm1 = pix_norm1_c;
 
-    c->draw_edges = draw_edges_8_c;
-
 #if ARCH_ARM
     ff_mpegvideoencdsp_init_arm(c, avctx);
 #elif ARCH_PPC
diff --git a/libavcodec/mpegvideoencdsp.h b/libavcodec/mpegvideoencdsp.h
index 95084679d9..46b40cf30e 100644
--- a/libavcodec/mpegvideoencdsp.h
+++ b/libavcodec/mpegvideoencdsp.h
@@ -26,9 +26,6 @@
 #define BASIS_SHIFT 16
 #define RECON_SHIFT 6
 
-#define EDGE_TOP    1
-#define EDGE_BOTTOM 2
-
 typedef struct MpegvideoEncDSPContext {
     int (*try_8x8basis)(const int16_t rem[64], const int16_t weight[64],
                         const int16_t basis[64], int scale);
@@ -39,9 +36,6 @@ typedef struct MpegvideoEncDSPContext {
 
     void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src,
                       int src_wrap, int width, int height);
-
-    void (*draw_edges)(uint8_t *buf, int wrap, int width, int height,
-                       int w, int h, int sides);
 } MpegvideoEncDSPContext;
 
 void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c,
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 43ca602762..ec708cebcc 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -27,6 +27,7 @@
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "codec_internal.h"
+#include "drawedgesdsp.h"
 #include "encode.h"
 #include "internal.h" //For AVCodecInternal.recon_frame
 #include "me_cmp.h"
@@ -46,7 +47,7 @@
 typedef struct SnowEncContext {
     SnowContext com;
     QpelDSPContext qdsp;
-    MpegvideoEncDSPContext mpvencdsp;
+    DrawEdgesDSPContext drawedges;
 
     int lambda;
     int lambda2;
@@ -216,7 +217,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     mcf(12,12)
 
     ff_me_cmp_init(&enc->mecc, avctx);
-    ff_mpegvideoencdsp_init(&enc->mpvencdsp, avctx);
+    ff_drawedgesdsp_init(&enc->drawedges);
 
     ff_snow_alloc_blocks(s);
 
@@ -1775,7 +1776,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
             memcpy(&s->input_picture->data[i][y * s->input_picture->linesize[i]],
                    &pict->data[i][y * pict->linesize[i]],
                    AV_CEIL_RSHIFT(width, hshift));
-        enc->mpvencdsp.draw_edges(s->input_picture->data[i], s->input_picture->linesize[i],
+        enc->drawedges.draw_edges(s->input_picture->data[i], s->input_picture->linesize[i],
                                 AV_CEIL_RSHIFT(width, hshift), AV_CEIL_RSHIFT(height, vshift),
                                 EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
                                 EDGE_TOP | EDGE_BOTTOM);
@@ -1815,14 +1816,14 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         int w = s->avctx->width;
         int h = s->avctx->height;
 
-        enc->mpvencdsp.draw_edges(s->current_picture->data[0],
+        enc->drawedges.draw_edges(s->current_picture->data[0],
                                   s->current_picture->linesize[0], w   , h   ,
                                   EDGE_WIDTH  , EDGE_WIDTH  , EDGE_TOP | EDGE_BOTTOM);
         if (s->current_picture->data[2]) {
-            enc->mpvencdsp.draw_edges(s->current_picture->data[1],
+            enc->drawedges.draw_edges(s->current_picture->data[1],
                                       s->current_picture->linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
                                       EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
-            enc->mpvencdsp.draw_edges(s->current_picture->data[2],
+            enc->drawedges.draw_edges(s->current_picture->data[2],
                                       s->current_picture->linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
                                       EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
         }
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index 331183f450..2b6c6659fd 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -7,6 +7,7 @@ OBJS-$(CONFIG_BLOCKDSP)                += x86/blockdsp_init.o
 OBJS-$(CONFIG_BSWAPDSP)                += x86/bswapdsp_init.o
 OBJS-$(CONFIG_DIRAC_DECODER)           += x86/diracdsp_init.o           \
                                           x86/dirac_dwt_init.o
+OBJS-$(CONFIG_DRAWEDGESDSP)            += x86/drawedgesdsp.o
 OBJS-$(CONFIG_FDCTDSP)                 += x86/fdctdsp_init.o
 OBJS-$(CONFIG_FMTCONVERT)              += x86/fmtconvert_init.o
 OBJS-$(CONFIG_H263DSP)                 += x86/h263dsp_init.o
diff --git a/libavcodec/x86/drawedgesdsp.c b/libavcodec/x86/drawedgesdsp.c
new file mode 100644
index 0000000000..1d059b3806
--- /dev/null
+++ b/libavcodec/x86/drawedgesdsp.c
@@ -0,0 +1,157 @@
+/*
+ * draw_edges by Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 <stdint.h>
+
+#include "config.h"
+
+#include "libavcodec/drawedgesdsp.h"
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+
+#if HAVE_INLINE_ASM
+
+/* Draw the edges of width 'w' of an image of size width, height
+ * this MMX version can only handle w == 8 || w == 16. */
+static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
+                           int w, int h, int sides)
+{
+    uint8_t *ptr, *last_line;
+
+    last_line = buf + (height - 1) * wrap;
+    /* left and right */
+    ptr = buf;
+    if (w == 8) {
+        __asm__ volatile (
+            "1:                             \n\t"
+            "movd            (%0), %%mm0    \n\t"
+            "punpcklbw      %%mm0, %%mm0    \n\t"
+            "punpcklwd      %%mm0, %%mm0    \n\t"
+            "punpckldq      %%mm0, %%mm0    \n\t"
+            "movq           %%mm0, -8(%0)   \n\t"
+            "movq      -8(%0, %2), %%mm1    \n\t"
+            "punpckhbw      %%mm1, %%mm1    \n\t"
+            "punpckhwd      %%mm1, %%mm1    \n\t"
+            "punpckhdq      %%mm1, %%mm1    \n\t"
+            "movq           %%mm1, (%0, %2) \n\t"
+            "add               %1, %0       \n\t"
+            "cmp               %3, %0       \n\t"
+            "jb                1b           \n\t"
+            : "+r" (ptr)
+            : "r" ((x86_reg) wrap), "r" ((x86_reg) width),
+              "r" (ptr + wrap * height));
+    } else if (w == 16) {
+        __asm__ volatile (
+            "1:                                 \n\t"
+            "movd            (%0), %%mm0        \n\t"
+            "punpcklbw      %%mm0, %%mm0        \n\t"
+            "punpcklwd      %%mm0, %%mm0        \n\t"
+            "punpckldq      %%mm0, %%mm0        \n\t"
+            "movq           %%mm0, -8(%0)       \n\t"
+            "movq           %%mm0, -16(%0)      \n\t"
+            "movq      -8(%0, %2), %%mm1        \n\t"
+            "punpckhbw      %%mm1, %%mm1        \n\t"
+            "punpckhwd      %%mm1, %%mm1        \n\t"
+            "punpckhdq      %%mm1, %%mm1        \n\t"
+            "movq           %%mm1,  (%0, %2)    \n\t"
+            "movq           %%mm1, 8(%0, %2)    \n\t"
+            "add               %1, %0           \n\t"
+            "cmp               %3, %0           \n\t"
+            "jb                1b               \n\t"
+            : "+r"(ptr)
+            : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
+            );
+    } else {
+        av_assert1(w == 4);
+        __asm__ volatile (
+            "1:                             \n\t"
+            "movd            (%0), %%mm0    \n\t"
+            "punpcklbw      %%mm0, %%mm0    \n\t"
+            "punpcklwd      %%mm0, %%mm0    \n\t"
+            "movd           %%mm0, -4(%0)   \n\t"
+            "movd      -4(%0, %2), %%mm1    \n\t"
+            "punpcklbw      %%mm1, %%mm1    \n\t"
+            "punpckhwd      %%mm1, %%mm1    \n\t"
+            "punpckhdq      %%mm1, %%mm1    \n\t"
+            "movd           %%mm1, (%0, %2) \n\t"
+            "add               %1, %0       \n\t"
+            "cmp               %3, %0       \n\t"
+            "jb                1b           \n\t"
+            : "+r" (ptr)
+            : "r" ((x86_reg) wrap), "r" ((x86_reg) width),
+              "r" (ptr + wrap * height));
+    }
+
+    /* top and bottom (and hopefully also the corners) */
+    if (sides & EDGE_TOP) {
+        for (int i = 0; i < h; i += 4) {
+            ptr = buf - (i + 1) * wrap - w;
+            __asm__ volatile (
+                "1:                             \n\t"
+                "movq (%1, %0), %%mm0           \n\t"
+                "movq    %%mm0, (%0)            \n\t"
+                "movq    %%mm0, (%0, %2)        \n\t"
+                "movq    %%mm0, (%0, %2, 2)     \n\t"
+                "movq    %%mm0, (%0, %3)        \n\t"
+                "add        $8, %0              \n\t"
+                "cmp        %4, %0              \n\t"
+                "jb         1b                  \n\t"
+                : "+r" (ptr)
+                : "r" ((x86_reg) buf - (x86_reg) ptr - w),
+                  "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3),
+                  "r" (ptr + width + 2 * w));
+        }
+    }
+
+    if (sides & EDGE_BOTTOM) {
+        for (int i = 0; i < h; i += 4) {
+            ptr = last_line + (i + 1) * wrap - w;
+            __asm__ volatile (
+                "1:                             \n\t"
+                "movq (%1, %0), %%mm0           \n\t"
+                "movq    %%mm0, (%0)            \n\t"
+                "movq    %%mm0, (%0, %2)        \n\t"
+                "movq    %%mm0, (%0, %2, 2)     \n\t"
+                "movq    %%mm0, (%0, %3)        \n\t"
+                "add        $8, %0              \n\t"
+                "cmp        %4, %0              \n\t"
+                "jb         1b                  \n\t"
+                : "+r" (ptr)
+                : "r" ((x86_reg) last_line - (x86_reg) ptr - w),
+                  "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3),
+                  "r" (ptr + width + 2 * w));
+        }
+    }
+}
+
+#endif
+
+av_cold void ff_drawedgesdsp_init_x86(DrawEdgesDSPContext *c)
+{
+#if HAVE_INLINE_ASM
+    int cpu_flags = av_get_cpu_flags();
+
+    if (INLINE_MMX(cpu_flags))
+        c->draw_edges = draw_edges_mmx;
+#endif
+}
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 73967cafda..a4ab2bb308 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -1,6 +1,6 @@
 /*
  * Optimized for ia32 CPUs by Nick Kurshev <nickols_k at mail.ru>
- * H.263, MPEG-1, MPEG-2 dequantizer & draw_edges by Michael Niedermayer <michaelni at gmx.at>
+ * H.263, MPEG-1, MPEG-2 dequantizer by Michael Niedermayer <michaelni at gmx.at>
  *
  * This file is part of FFmpeg.
  *
diff --git a/libavcodec/x86/mpegvideoencdsp_init.c b/libavcodec/x86/mpegvideoencdsp_init.c
index 9fa7ee4824..c816ca2ee7 100644
--- a/libavcodec/x86/mpegvideoencdsp_init.c
+++ b/libavcodec/x86/mpegvideoencdsp_init.c
@@ -17,7 +17,6 @@
  */
 
 #include "libavutil/attributes.h"
-#include "libavutil/avassert.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/avcodec.h"
@@ -94,121 +93,6 @@ int ff_pix_norm1_sse2(const uint8_t *pix, int line_size);
 #undef PMULHRW
 #undef PHADDD
 #endif /* HAVE_SSSE3_INLINE */
-
-/* Draw the edges of width 'w' of an image of size width, height
- * this MMX version can only handle w == 8 || w == 16. */
-static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
-                           int w, int h, int sides)
-{
-    uint8_t *ptr, *last_line;
-    int i;
-
-    last_line = buf + (height - 1) * wrap;
-    /* left and right */
-    ptr = buf;
-    if (w == 8) {
-        __asm__ volatile (
-            "1:                             \n\t"
-            "movd            (%0), %%mm0    \n\t"
-            "punpcklbw      %%mm0, %%mm0    \n\t"
-            "punpcklwd      %%mm0, %%mm0    \n\t"
-            "punpckldq      %%mm0, %%mm0    \n\t"
-            "movq           %%mm0, -8(%0)   \n\t"
-            "movq      -8(%0, %2), %%mm1    \n\t"
-            "punpckhbw      %%mm1, %%mm1    \n\t"
-            "punpckhwd      %%mm1, %%mm1    \n\t"
-            "punpckhdq      %%mm1, %%mm1    \n\t"
-            "movq           %%mm1, (%0, %2) \n\t"
-            "add               %1, %0       \n\t"
-            "cmp               %3, %0       \n\t"
-            "jb                1b           \n\t"
-            : "+r" (ptr)
-            : "r" ((x86_reg) wrap), "r" ((x86_reg) width),
-              "r" (ptr + wrap * height));
-    } else if (w == 16) {
-        __asm__ volatile (
-            "1:                                 \n\t"
-            "movd            (%0), %%mm0        \n\t"
-            "punpcklbw      %%mm0, %%mm0        \n\t"
-            "punpcklwd      %%mm0, %%mm0        \n\t"
-            "punpckldq      %%mm0, %%mm0        \n\t"
-            "movq           %%mm0, -8(%0)       \n\t"
-            "movq           %%mm0, -16(%0)      \n\t"
-            "movq      -8(%0, %2), %%mm1        \n\t"
-            "punpckhbw      %%mm1, %%mm1        \n\t"
-            "punpckhwd      %%mm1, %%mm1        \n\t"
-            "punpckhdq      %%mm1, %%mm1        \n\t"
-            "movq           %%mm1,  (%0, %2)    \n\t"
-            "movq           %%mm1, 8(%0, %2)    \n\t"
-            "add               %1, %0           \n\t"
-            "cmp               %3, %0           \n\t"
-            "jb                1b               \n\t"
-            : "+r"(ptr)
-            : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
-            );
-    } else {
-        av_assert1(w == 4);
-        __asm__ volatile (
-            "1:                             \n\t"
-            "movd            (%0), %%mm0    \n\t"
-            "punpcklbw      %%mm0, %%mm0    \n\t"
-            "punpcklwd      %%mm0, %%mm0    \n\t"
-            "movd           %%mm0, -4(%0)   \n\t"
-            "movd      -4(%0, %2), %%mm1    \n\t"
-            "punpcklbw      %%mm1, %%mm1    \n\t"
-            "punpckhwd      %%mm1, %%mm1    \n\t"
-            "punpckhdq      %%mm1, %%mm1    \n\t"
-            "movd           %%mm1, (%0, %2) \n\t"
-            "add               %1, %0       \n\t"
-            "cmp               %3, %0       \n\t"
-            "jb                1b           \n\t"
-            : "+r" (ptr)
-            : "r" ((x86_reg) wrap), "r" ((x86_reg) width),
-              "r" (ptr + wrap * height));
-    }
-
-    /* top and bottom (and hopefully also the corners) */
-    if (sides & EDGE_TOP) {
-        for (i = 0; i < h; i += 4) {
-            ptr = buf - (i + 1) * wrap - w;
-            __asm__ volatile (
-                "1:                             \n\t"
-                "movq (%1, %0), %%mm0           \n\t"
-                "movq    %%mm0, (%0)            \n\t"
-                "movq    %%mm0, (%0, %2)        \n\t"
-                "movq    %%mm0, (%0, %2, 2)     \n\t"
-                "movq    %%mm0, (%0, %3)        \n\t"
-                "add        $8, %0              \n\t"
-                "cmp        %4, %0              \n\t"
-                "jb         1b                  \n\t"
-                : "+r" (ptr)
-                : "r" ((x86_reg) buf - (x86_reg) ptr - w),
-                  "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3),
-                  "r" (ptr + width + 2 * w));
-        }
-    }
-
-    if (sides & EDGE_BOTTOM) {
-        for (i = 0; i < h; i += 4) {
-            ptr = last_line + (i + 1) * wrap - w;
-            __asm__ volatile (
-                "1:                             \n\t"
-                "movq (%1, %0), %%mm0           \n\t"
-                "movq    %%mm0, (%0)            \n\t"
-                "movq    %%mm0, (%0, %2)        \n\t"
-                "movq    %%mm0, (%0, %2, 2)     \n\t"
-                "movq    %%mm0, (%0, %3)        \n\t"
-                "add        $8, %0              \n\t"
-                "cmp        %4, %0              \n\t"
-                "jb         1b                  \n\t"
-                : "+r" (ptr)
-                : "r" ((x86_reg) last_line - (x86_reg) ptr - w),
-                  "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3),
-                  "r" (ptr + width + 2 * w));
-        }
-    }
-}
-
 #endif /* HAVE_INLINE_ASM */
 
 av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c,
@@ -232,8 +116,6 @@ av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c,
             c->try_8x8basis = try_8x8basis_mmx;
         }
         c->add_8x8basis = add_8x8basis_mmx;
-
-        c->draw_edges = draw_edges_mmx;
     }
 
     if (INLINE_AMD3DNOW(cpu_flags)) {
-- 
2.40.1



More information about the ffmpeg-devel mailing list