[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