diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-10-12 12:59:25 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-10-20 07:56:17 +0200 |
commit | ac8afdb9b5228e79ab5582f932434b0dc0bbd186 (patch) | |
tree | 9ac18e6fc2bd4f6e8f899c89abd6657109d971ea /libavcodec/mpeg4videodec.c | |
parent | eb1ce6e3c73dbb59c3178d643eacc48bba824922 (diff) | |
download | ffmpeg-ac8afdb9b5228e79ab5582f932434b0dc0bbd186.tar.gz |
avcodec/mpegvideo_motion: Move mspel/gmc motion to mpeg4videodec.c
It is the only codec for which mcsel is ever set.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/mpeg4videodec.c')
-rw-r--r-- | libavcodec/mpeg4videodec.c | 168 |
1 files changed, 168 insertions, 0 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) |