[FFmpeg-devel] [PATCH 1/6] avcodec/mpegvideo_motion: Move mspel/gmc motion to mpeg4videodec.c

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Wed Oct 12 21:03:25 EEST 2022


It is the only codec for which mcsel is ever set.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavcodec/mpeg4videodec.c    | 168 ++++++++++++++++++++++++++++++++++
 libavcodec/mpeg4videodec.h    |   3 +
 libavcodec/mpegvideo_motion.c | 166 +--------------------------------
 3 files changed, 174 insertions(+), 163 deletions(-)

diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 4dbf37afe5..58a8ac9027 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -72,6 +72,174 @@ static const int mb_type_b_map[4] = {
     MB_TYPE_L0      | MB_TYPE_16x16,
 };
 
+static void gmc1_motion(MpegEncContext *s,
+                        uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                        uint8_t *const *ref_picture)
+{
+    const uint8_t *ptr;
+    int src_x, src_y, motion_x, motion_y;
+    ptrdiff_t offset, linesize, uvlinesize;
+    int emu = 0;
+
+    motion_x   = s->sprite_offset[0][0];
+    motion_y   = s->sprite_offset[0][1];
+    src_x      = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
+    src_y      = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
+    motion_x *= 1 << (3 - s->sprite_warping_accuracy);
+    motion_y *= 1 << (3 - s->sprite_warping_accuracy);
+    src_x      = av_clip(src_x, -16, s->width);
+    if (src_x == s->width)
+        motion_x = 0;
+    src_y = av_clip(src_y, -16, s->height);
+    if (src_y == s->height)
+        motion_y = 0;
+
+    linesize   = s->linesize;
+    uvlinesize = s->uvlinesize;
+
+    ptr = ref_picture[0] + src_y * linesize + src_x;
+
+    if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
+        (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
+        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+                                 linesize, linesize,
+                                 17, 17,
+                                 src_x, src_y,
+                                 s->h_edge_pos, s->v_edge_pos);
+        ptr = s->sc.edge_emu_buffer;
+    }
+
+    if ((motion_x | motion_y) & 7) {
+        s->mdsp.gmc1(dest_y, ptr, linesize, 16,
+                     motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+        s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
+                     motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+    } else {
+        int dxy;
+
+        dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
+        if (s->no_rounding) {
+            s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
+        } else {
+            s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
+        }
+    }
+
+    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
+        return;
+
+    motion_x   = s->sprite_offset[1][0];
+    motion_y   = s->sprite_offset[1][1];
+    src_x      = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
+    src_y      = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
+    motion_x  *= 1 << (3 - s->sprite_warping_accuracy);
+    motion_y  *= 1 << (3 - s->sprite_warping_accuracy);
+    src_x      = av_clip(src_x, -8, s->width >> 1);
+    if (src_x == s->width >> 1)
+        motion_x = 0;
+    src_y = av_clip(src_y, -8, s->height >> 1);
+    if (src_y == s->height >> 1)
+        motion_y = 0;
+
+    offset = (src_y * uvlinesize) + src_x;
+    ptr    = ref_picture[1] + offset;
+    if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
+        (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
+        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+                                 uvlinesize, uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ptr = s->sc.edge_emu_buffer;
+        emu = 1;
+    }
+    s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,
+                 motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+
+    ptr = ref_picture[2] + offset;
+    if (emu) {
+        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+                                 uvlinesize, uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ptr = s->sc.edge_emu_buffer;
+    }
+    s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,
+                 motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+}
+
+static void gmc_motion(MpegEncContext *s,
+                       uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                       uint8_t *const *ref_picture)
+{
+    const uint8_t *ptr;
+    int linesize, uvlinesize;
+    const int a = s->sprite_warping_accuracy;
+    int ox, oy;
+
+    linesize   = s->linesize;
+    uvlinesize = s->uvlinesize;
+
+    ptr = ref_picture[0];
+
+    ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
+         s->sprite_delta[0][1] * s->mb_y * 16;
+    oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
+         s->sprite_delta[1][1] * s->mb_y * 16;
+
+    s->mdsp.gmc(dest_y, ptr, linesize, 16,
+                ox, oy,
+                s->sprite_delta[0][0], s->sprite_delta[0][1],
+                s->sprite_delta[1][0], s->sprite_delta[1][1],
+                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+                s->h_edge_pos, s->v_edge_pos);
+    s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,
+                ox + s->sprite_delta[0][0] * 8,
+                oy + s->sprite_delta[1][0] * 8,
+                s->sprite_delta[0][0], s->sprite_delta[0][1],
+                s->sprite_delta[1][0], s->sprite_delta[1][1],
+                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+                s->h_edge_pos, s->v_edge_pos);
+
+    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
+        return;
+
+    ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
+         s->sprite_delta[0][1] * s->mb_y * 8;
+    oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
+         s->sprite_delta[1][1] * s->mb_y * 8;
+
+    ptr = ref_picture[1];
+    s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,
+                ox, oy,
+                s->sprite_delta[0][0], s->sprite_delta[0][1],
+                s->sprite_delta[1][0], s->sprite_delta[1][1],
+                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+                (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
+
+    ptr = ref_picture[2];
+    s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,
+                ox, oy,
+                s->sprite_delta[0][0], s->sprite_delta[0][1],
+                s->sprite_delta[1][0], s->sprite_delta[1][1],
+                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+                (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
+}
+
+void ff_mpeg4_mcsel_motion(MpegEncContext *s,
+                           uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                           uint8_t *const *ref_picture)
+{
+    if (s->real_sprite_warping_points == 1) {
+        gmc1_motion(s, dest_y, dest_cb, dest_cr,
+                    ref_picture);
+    } else {
+        gmc_motion(s, dest_y, dest_cb, dest_cr,
+                    ref_picture);
+    }
+}
+
 void ff_mpeg4_decode_studio(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
                             uint8_t *dest_cr, int block_size, int uvlinesize,
                             int dct_linesize, int dct_offset)
diff --git a/libavcodec/mpeg4videodec.h b/libavcodec/mpeg4videodec.h
index 65d846aed0..8d1e121b67 100644
--- a/libavcodec/mpeg4videodec.h
+++ b/libavcodec/mpeg4videodec.h
@@ -87,6 +87,9 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb,
 void ff_mpeg4_decode_studio(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
                             uint8_t *dest_cr, int block_size, int uvlinesize,
                             int dct_linesize, int dct_offset);
+void ff_mpeg4_mcsel_motion(MpegEncContext *s,
+                           uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+                           uint8_t *const *ref_picture);
 int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx);
 int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx);
 int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx);
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index fe3bfc4454..8922f5b1a5 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -31,164 +31,10 @@
 #include "h261.h"
 #include "mpegutils.h"
 #include "mpegvideo.h"
+#include "mpeg4videodec.h"
 #include "qpeldsp.h"
 #include "wmv2.h"
 
-static void gmc1_motion(MpegEncContext *s,
-                        uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
-                        uint8_t *const *ref_picture)
-{
-    const uint8_t *ptr;
-    int src_x, src_y, motion_x, motion_y;
-    ptrdiff_t offset, linesize, uvlinesize;
-    int emu = 0;
-
-    motion_x   = s->sprite_offset[0][0];
-    motion_y   = s->sprite_offset[0][1];
-    src_x      = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
-    src_y      = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
-    motion_x *= 1 << (3 - s->sprite_warping_accuracy);
-    motion_y *= 1 << (3 - s->sprite_warping_accuracy);
-    src_x      = av_clip(src_x, -16, s->width);
-    if (src_x == s->width)
-        motion_x = 0;
-    src_y = av_clip(src_y, -16, s->height);
-    if (src_y == s->height)
-        motion_y = 0;
-
-    linesize   = s->linesize;
-    uvlinesize = s->uvlinesize;
-
-    ptr = ref_picture[0] + src_y * linesize + src_x;
-
-    if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
-        (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
-                                 linesize, linesize,
-                                 17, 17,
-                                 src_x, src_y,
-                                 s->h_edge_pos, s->v_edge_pos);
-        ptr = s->sc.edge_emu_buffer;
-    }
-
-    if ((motion_x | motion_y) & 7) {
-        s->mdsp.gmc1(dest_y, ptr, linesize, 16,
-                     motion_x & 15, motion_y & 15, 128 - s->no_rounding);
-        s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
-                     motion_x & 15, motion_y & 15, 128 - s->no_rounding);
-    } else {
-        int dxy;
-
-        dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
-        if (s->no_rounding) {
-            s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
-        } else {
-            s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
-        }
-    }
-
-    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
-        return;
-
-    motion_x   = s->sprite_offset[1][0];
-    motion_y   = s->sprite_offset[1][1];
-    src_x      = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
-    src_y      = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
-    motion_x  *= 1 << (3 - s->sprite_warping_accuracy);
-    motion_y  *= 1 << (3 - s->sprite_warping_accuracy);
-    src_x      = av_clip(src_x, -8, s->width >> 1);
-    if (src_x == s->width >> 1)
-        motion_x = 0;
-    src_y = av_clip(src_y, -8, s->height >> 1);
-    if (src_y == s->height >> 1)
-        motion_y = 0;
-
-    offset = (src_y * uvlinesize) + src_x;
-    ptr    = ref_picture[1] + offset;
-    if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
-        (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
-                                 uvlinesize, uvlinesize,
-                                 9, 9,
-                                 src_x, src_y,
-                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
-        ptr = s->sc.edge_emu_buffer;
-        emu = 1;
-    }
-    s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,
-                 motion_x & 15, motion_y & 15, 128 - s->no_rounding);
-
-    ptr = ref_picture[2] + offset;
-    if (emu) {
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
-                                 uvlinesize, uvlinesize,
-                                 9, 9,
-                                 src_x, src_y,
-                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
-        ptr = s->sc.edge_emu_buffer;
-    }
-    s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,
-                 motion_x & 15, motion_y & 15, 128 - s->no_rounding);
-}
-
-static void gmc_motion(MpegEncContext *s,
-                       uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
-                       uint8_t *const *ref_picture)
-{
-    const uint8_t *ptr;
-    int linesize, uvlinesize;
-    const int a = s->sprite_warping_accuracy;
-    int ox, oy;
-
-    linesize   = s->linesize;
-    uvlinesize = s->uvlinesize;
-
-    ptr = ref_picture[0];
-
-    ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
-         s->sprite_delta[0][1] * s->mb_y * 16;
-    oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
-         s->sprite_delta[1][1] * s->mb_y * 16;
-
-    s->mdsp.gmc(dest_y, ptr, linesize, 16,
-                ox, oy,
-                s->sprite_delta[0][0], s->sprite_delta[0][1],
-                s->sprite_delta[1][0], s->sprite_delta[1][1],
-                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
-                s->h_edge_pos, s->v_edge_pos);
-    s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,
-                ox + s->sprite_delta[0][0] * 8,
-                oy + s->sprite_delta[1][0] * 8,
-                s->sprite_delta[0][0], s->sprite_delta[0][1],
-                s->sprite_delta[1][0], s->sprite_delta[1][1],
-                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
-                s->h_edge_pos, s->v_edge_pos);
-
-    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
-        return;
-
-    ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
-         s->sprite_delta[0][1] * s->mb_y * 8;
-    oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
-         s->sprite_delta[1][1] * s->mb_y * 8;
-
-    ptr = ref_picture[1];
-    s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,
-                ox, oy,
-                s->sprite_delta[0][0], s->sprite_delta[0][1],
-                s->sprite_delta[1][0], s->sprite_delta[1][1],
-                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
-                (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
-
-    ptr = ref_picture[2];
-    s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,
-                ox, oy,
-                s->sprite_delta[0][0], s->sprite_delta[0][1],
-                s->sprite_delta[1][0], s->sprite_delta[1][1],
-                a + 1, (1 << (2 * a + 1)) - s->no_rounding,
-                (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
-}
-
 static inline int hpel_motion(MpegEncContext *s,
                               uint8_t *dest, uint8_t *src,
                               int src_x, int src_y,
@@ -849,14 +695,8 @@ static av_always_inline void mpv_motion_internal(MpegEncContext *s,
 
     switch (s->mv_type) {
     case MV_TYPE_16X16:
-        if (!is_mpeg12 && s->mcsel) {
-            if (s->real_sprite_warping_points == 1) {
-                gmc1_motion(s, dest_y, dest_cb, dest_cr,
-                            ref_picture);
-            } else {
-                gmc_motion(s, dest_y, dest_cb, dest_cr,
-                           ref_picture);
-            }
+        if (CONFIG_MPEG4_DECODER && !is_mpeg12 && s->mcsel) {
+            ff_mpeg4_mcsel_motion(s, dest_y, dest_cb, dest_cr, ref_picture);
         } else if (!is_mpeg12 && s->quarter_sample) {
             qpel_motion(s, dest_y, dest_cb, dest_cr,
                         0, 0, 0,
-- 
2.34.1



More information about the ffmpeg-devel mailing list