|
|
|
@ -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, |
|
|
|
|