Unified · Split
| @@ -63,8 +63,8 @@ OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \ · 62 unmodified lines | |||
| 63 | mpegaudiodsp_data.o \ | 63 | mpegaudiodsp_data.o \ |
| 64 | mpegaudiodsp_fixed.o \ | 64 | mpegaudiodsp_fixed.o \ |
| 65 | mpegaudiodsp_float.o | 65 | mpegaudiodsp_float.o |
| 66 | OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideo_motion.o \ | 66 | OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o \ |
| 67 | mpegutils.o | 67 | mpegvideo_motion.o mpegutils.o |
| 68 | OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ | 68 | OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ |
| 69 | motion_est.o ratecontrol.o | 69 | motion_est.o ratecontrol.o |
| 70 | OBJS-$(CONFIG_QPELDSP) += qpeldsp.o | 70 | OBJS-$(CONFIG_QPELDSP) += qpeldsp.o |
| @@ -3,8 +3,6 @@ · 2 unmodified lines | |||
| 3 | * Copyright (c) 2000, 2001 Fabrice Bellard | 3 | * Copyright (c) 2000, 2001 Fabrice Bellard |
| 4 | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> | 4 | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> |
| 5 | * | 5 | * |
| 6 | * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> | ||
| 7 | * | ||
| 8 | * This file is part of Libav. | 6 | * This file is part of Libav. |
| 9 | * | 7 | * |
| 10 | * Libav is free software; you can redistribute it and/or | 8 | * Libav is free software; you can redistribute it and/or |
| @@ -352,92 +350,6 @@ static int sum_abs_dctelem_c(int16_t *block) · 341 unmodified lines | |||
| 352 | #define avg2(a, b) ((a + b + 1) >> 1) | 350 | #define avg2(a, b) ((a + b + 1) >> 1) |
| 353 | #define avg4(a, b, c, d) ((a + b + c + d + 2) >> 2) | 351 | #define avg4(a, b, c, d) ((a + b + c + d + 2) >> 2) |
| 354 | 352 | ||
| 355 | static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, | ||
| 356 | int x16, int y16, int rounder) | ||
| 357 | { | ||
| 358 | const int A = (16 - x16) * (16 - y16); | ||
| 359 | const int B = (x16) * (16 - y16); | ||
| 360 | const int C = (16 - x16) * (y16); | ||
| 361 | const int D = (x16) * (y16); | ||
| 362 | int i; | ||
| 363 | |||
| 364 | for (i = 0; i < h; i++) { | ||
| 365 | dst[0] = (A * src[0] + B * src[1] + C * src[stride + 0] + D * src[stride + 1] + rounder) >> 8; | ||
| 366 | dst[1] = (A * src[1] + B * src[2] + C * src[stride + 1] + D * src[stride + 2] + rounder) >> 8; | ||
| 367 | dst[2] = (A * src[2] + B * src[3] + C * src[stride + 2] + D * src[stride + 3] + rounder) >> 8; | ||
| 368 | dst[3] = (A * src[3] + B * src[4] + C * src[stride + 3] + D * src[stride + 4] + rounder) >> 8; | ||
| 369 | dst[4] = (A * src[4] + B * src[5] + C * src[stride + 4] + D * src[stride + 5] + rounder) >> 8; | ||
| 370 | dst[5] = (A * src[5] + B * src[6] + C * src[stride + 5] + D * src[stride + 6] + rounder) >> 8; | ||
| 371 | dst[6] = (A * src[6] + B * src[7] + C * src[stride + 6] + D * src[stride + 7] + rounder) >> 8; | ||
| 372 | dst[7] = (A * src[7] + B * src[8] + C * src[stride + 7] + D * src[stride + 8] + rounder) >> 8; | ||
| 373 | dst += stride; | ||
| 374 | src += stride; | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, | ||
| 379 | int dxx, int dxy, int dyx, int dyy, int shift, int r, | ||
| 380 | int width, int height) | ||
| 381 | { | ||
| 382 | int y, vx, vy; | ||
| 383 | const int s = 1 << shift; | ||
| 384 | |||
| 385 | width--; | ||
| 386 | height--; | ||
| 387 | |||
| 388 | for (y = 0; y < h; y++) { | ||
| 389 | int x; | ||
| 390 | |||
| 391 | vx = ox; | ||
| 392 | vy = oy; | ||
| 393 | for (x = 0; x < 8; x++) { // FIXME: optimize | ||
| 394 | int index; | ||
| 395 | int src_x = vx >> 16; | ||
| 396 | int src_y = vy >> 16; | ||
| 397 | int frac_x = src_x & (s - 1); | ||
| 398 | int frac_y = src_y & (s - 1); | ||
| 399 | |||
| 400 | src_x >>= shift; | ||
| 401 | src_y >>= shift; | ||
| 402 | |||
| 403 | if ((unsigned) src_x < width) { | ||
| 404 | if ((unsigned) src_y < height) { | ||
| 405 | index = src_x + src_y * stride; | ||
| 406 | dst[y * stride + x] = | ||
| 407 | ((src[index] * (s - frac_x) + | ||
| 408 | src[index + 1] * frac_x) * (s - frac_y) + | ||
| 409 | (src[index + stride] * (s - frac_x) + | ||
| 410 | src[index + stride + 1] * frac_x) * frac_y + | ||
| 411 | r) >> (shift * 2); | ||
| 412 | } else { | ||
| 413 | index = src_x + av_clip(src_y, 0, height) * stride; | ||
| 414 | dst[y * stride + x] = | ||
| 415 | ((src[index] * (s - frac_x) + | ||
| 416 | src[index + 1] * frac_x) * s + | ||
| 417 | r) >> (shift * 2); | ||
| 418 | } | ||
| 419 | } else { | ||
| 420 | if ((unsigned) src_y < height) { | ||
| 421 | index = av_clip(src_x, 0, width) + src_y * stride; | ||
| 422 | dst[y * stride + x] = | ||
| 423 | ((src[index] * (s - frac_y) + | ||
| 424 | src[index + stride] * frac_y) * s + | ||
| 425 | r) >> (shift * 2); | ||
| 426 | } else { | ||
| 427 | index = av_clip(src_x, 0, width) + | ||
| 428 | av_clip(src_y, 0, height) * stride; | ||
| 429 | dst[y * stride + x] = src[index]; | ||
| 430 | } | ||
| 431 | } | ||
| 432 | |||
| 433 | vx += dxx; | ||
| 434 | vy += dyx; | ||
| 435 | } | ||
| 436 | ox += dxy; | ||
| 437 | oy += dyy; | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, | 353 | static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, |
| 442 | int line_size, int h) | 354 | int line_size, int h) |
| 443 | { | 355 | { |
| @@ -1346,9 +1258,6 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) · 902 unmodified lines | |||
| 1346 | 1258 | ||
| 1347 | c->sum_abs_dctelem = sum_abs_dctelem_c; | 1259 | c->sum_abs_dctelem = sum_abs_dctelem_c; |
| 1348 | 1260 | ||
| 1349 | c->gmc1 = gmc1_c; | ||
| 1350 | c->gmc = ff_gmc_c; | ||
| 1351 | |||
| 1352 | c->pix_sum = pix_sum_c; | 1261 | c->pix_sum = pix_sum_c; |
| 1353 | c->pix_norm1 = pix_norm1_c; | 1262 | c->pix_norm1 = pix_norm1_c; |
| 1354 | 1263 | ||
| @@ -34,10 +34,6 @@ · 33 unmodified lines | |||
| 34 | 34 | ||
| 35 | extern uint32_t ff_square_tab[512]; | 35 | extern uint32_t ff_square_tab[512]; |
| 36 | 36 | ||
| 37 | void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, | ||
| 38 | int dxx, int dxy, int dyx, int dyy, int shift, int r, | ||
| 39 | int width, int height); | ||
| 40 | |||
| 41 | struct MpegEncContext; | 37 | struct MpegEncContext; |
| 42 | /* Motion estimation: | 38 | /* Motion estimation: |
| 43 | * h is limited to { width / 2, width, 2 * width }, | 39 | * h is limited to { width / 2, width, 2 * width }, |
| @@ -84,18 +80,6 @@ typedef struct DSPContext { · 40 unmodified lines | |||
| 84 | uint8_t *pixels /* align 8 */, | 80 | uint8_t *pixels /* align 8 */, |
| 85 | int line_size); | 81 | int line_size); |
| 86 | int (*sum_abs_dctelem)(int16_t *block /* align 16 */); | 82 | int (*sum_abs_dctelem)(int16_t *block /* align 16 */); |
| 87 | /** | ||
| 88 | * translational global motion compensation. | ||
| 89 | */ | ||
| 90 | void (*gmc1)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, | ||
| 91 | int srcStride, int h, int x16, int y16, int rounder); | ||
| 92 | /** | ||
| 93 | * global motion compensation. | ||
| 94 | */ | ||
| 95 | void (*gmc)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, | ||
| 96 | int stride, int h, int ox, int oy, | ||
| 97 | int dxx, int dxy, int dyx, int dyy, | ||
| 98 | int shift, int r, int width, int height); | ||
| 99 | 83 | ||
| 100 | int (*pix_sum)(uint8_t *pix, int line_size); | 84 | int (*pix_sum)(uint8_t *pix, int line_size); |
| 101 | int (*pix_norm1)(uint8_t *pix, int line_size); | 85 | int (*pix_norm1)(uint8_t *pix, int line_size); |
| @@ -380,6 +380,7 @@ av_cold int ff_dct_common_init(MpegEncContext *s) · 379 unmodified lines | |||
| 380 | ff_blockdsp_init(&s->bdsp, s->avctx); | 380 | ff_blockdsp_init(&s->bdsp, s->avctx); |
| 381 | ff_dsputil_init(&s->dsp, s->avctx); | 381 | ff_dsputil_init(&s->dsp, s->avctx); |
| 382 | ff_hpeldsp_init(&s->hdsp, s->avctx->flags); | 382 | ff_hpeldsp_init(&s->hdsp, s->avctx->flags); |
| 383 | ff_mpegvideodsp_init(&s->mdsp); | ||
| 383 | ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample); | 384 | ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample); |
| 384 | 385 | ||
| 385 | s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; | 386 | s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include "get_bits.h" | 35 | #include "get_bits.h" |
| 36 | #include "h263dsp.h" | 36 | #include "h263dsp.h" |
| 37 | #include "hpeldsp.h" | 37 | #include "hpeldsp.h" |
| 38 | #include "mpegvideodsp.h" | ||
| 38 | #include "put_bits.h" | 39 | #include "put_bits.h" |
| 39 | #include "ratecontrol.h" | 40 | #include "ratecontrol.h" |
| 40 | #include "parser.h" | 41 | #include "parser.h" |
| @@ -351,6 +352,7 @@ typedef struct MpegEncContext { · 310 unmodified lines | |||
| 351 | BlockDSPContext bdsp; | 352 | BlockDSPContext bdsp; |
| 352 | DSPContext dsp; ///< pointers for accelerated dsp functions | 353 | DSPContext dsp; ///< pointers for accelerated dsp functions |
| 353 | HpelDSPContext hdsp; | 354 | HpelDSPContext hdsp; |
| 355 | MpegVideoDSPContext mdsp; | ||
| 354 | QpelDSPContext qdsp; | 356 | QpelDSPContext qdsp; |
| 355 | VideoDSPContext vdsp; | 357 | VideoDSPContext vdsp; |
| 356 | H263DSPContext h263dsp; | 358 | H263DSPContext h263dsp; |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | #include "libavutil/internal.h" | 26 | #include "libavutil/internal.h" |
| 27 | #include "avcodec.h" | 27 | #include "avcodec.h" |
| 28 | #include "dsputil.h" | ||
| 29 | #include "h261.h" | 28 | #include "h261.h" |
| 30 | #include "mpegutils.h" | 29 | #include "mpegutils.h" |
| 31 | #include "mpegvideo.h" | 30 | #include "mpegvideo.h" |
| @@ -72,10 +71,10 @@ static void gmc1_motion(MpegEncContext *s, · 40 unmodified lines | |||
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | if ((motion_x | motion_y) & 7) { | 73 | if ((motion_x | motion_y) & 7) { |
| 75 | s->dsp.gmc1(dest_y, ptr, linesize, 16, | 74 | s->mdsp.gmc1(dest_y, ptr, linesize, 16, |
| 76 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | 75 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); |
| 77 | s->dsp.gmc1(dest_y + 8, ptr + 8, linesize, 16, | 76 | s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16, |
| 78 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | 77 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); |
| 79 | } else { | 78 | } else { |
| 80 | int dxy; | 79 | int dxy; |
| 81 | 80 | ||
| @@ -115,8 +114,8 @@ static void gmc1_motion(MpegEncContext *s, · 33 unmodified lines | |||
| 115 | ptr = s->edge_emu_buffer; | 114 | ptr = s->edge_emu_buffer; |
| 116 | emu = 1; | 115 | emu = 1; |
| 117 | } | 116 | } |
| 118 | s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, | 117 | s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8, |
| 119 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | 118 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); |
| 120 | 119 | ||
| 121 | ptr = ref_picture[2] + offset; | 120 | ptr = ref_picture[2] + offset; |
| 122 | if (emu) { | 121 | if (emu) { |
| @@ -127,8 +126,8 @@ static void gmc1_motion(MpegEncContext *s, · 4 unmodified lines | |||
| 127 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | 126 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); |
| 128 | ptr = s->edge_emu_buffer; | 127 | ptr = s->edge_emu_buffer; |
| 129 | } | 128 | } |
| 130 | s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, | 129 | s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8, |
| 131 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | 130 | motion_x & 15, motion_y & 15, 128 - s->no_rounding); |
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | static void gmc_motion(MpegEncContext *s, | 133 | static void gmc_motion(MpegEncContext *s, |
| @@ -150,19 +149,19 @@ static void gmc_motion(MpegEncContext *s, · 15 unmodified lines | |||
| 150 | oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 + | 149 | oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 + |
| 151 | s->sprite_delta[1][1] * s->mb_y * 16; | 150 | s->sprite_delta[1][1] * s->mb_y * 16; |
| 152 | 151 | ||
| 153 | s->dsp.gmc(dest_y, ptr, linesize, 16, | 152 | s->mdsp.gmc(dest_y, ptr, linesize, 16, |
| 154 | ox, oy, | 153 | ox, oy, |
| 155 | s->sprite_delta[0][0], s->sprite_delta[0][1], | 154 | s->sprite_delta[0][0], s->sprite_delta[0][1], |
| 156 | s->sprite_delta[1][0], s->sprite_delta[1][1], | 155 | s->sprite_delta[1][0], s->sprite_delta[1][1], |
| 157 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | 156 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, |
| 158 | s->h_edge_pos, s->v_edge_pos); | 157 | s->h_edge_pos, s->v_edge_pos); |
| 159 | s->dsp.gmc(dest_y + 8, ptr, linesize, 16, | 158 | s->mdsp.gmc(dest_y + 8, ptr, linesize, 16, |
| 160 | ox + s->sprite_delta[0][0] * 8, | 159 | ox + s->sprite_delta[0][0] * 8, |
| 161 | oy + s->sprite_delta[1][0] * 8, | 160 | oy + s->sprite_delta[1][0] * 8, |
| 162 | s->sprite_delta[0][0], s->sprite_delta[0][1], | 161 | s->sprite_delta[0][0], s->sprite_delta[0][1], |
| 163 | s->sprite_delta[1][0], s->sprite_delta[1][1], | 162 | s->sprite_delta[1][0], s->sprite_delta[1][1], |
| 164 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | 163 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, |
| 165 | s->h_edge_pos, s->v_edge_pos); | 164 | s->h_edge_pos, s->v_edge_pos); |
| 166 | 165 | ||
| 167 | if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY) | 166 | if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY) |
| 168 | return; | 167 | return; |
| @@ -173,20 +172,20 @@ static void gmc_motion(MpegEncContext *s, · 4 unmodified lines | |||
| 173 | s->sprite_delta[1][1] * s->mb_y * 8; | 172 | s->sprite_delta[1][1] * s->mb_y * 8; |
| 174 | 173 | ||
| 175 | ptr = ref_picture[1]; | 174 | ptr = ref_picture[1]; |
| 176 | s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, | 175 | s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8, |
| 177 | ox, oy, | 176 | ox, oy, |
| 178 | s->sprite_delta[0][0], s->sprite_delta[0][1], | 177 | s->sprite_delta[0][0], s->sprite_delta[0][1], |
| 179 | s->sprite_delta[1][0], s->sprite_delta[1][1], | 178 | s->sprite_delta[1][0], s->sprite_delta[1][1], |
| 180 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | 179 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, |
| 181 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | 180 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); |
| 182 | 181 | ||
| 183 | ptr = ref_picture[2]; | 182 | ptr = ref_picture[2]; |
| 184 | s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, | 183 | s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8, |
| 185 | ox, oy, | 184 | ox, oy, |
| 186 | s->sprite_delta[0][0], s->sprite_delta[0][1], | 185 | s->sprite_delta[0][0], s->sprite_delta[0][1], |
| 187 | s->sprite_delta[1][0], s->sprite_delta[1][1], | 186 | s->sprite_delta[1][0], s->sprite_delta[1][1], |
| 188 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | 187 | a + 1, (1 << (2 * a + 1)) - s->no_rounding, |
| 189 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | 188 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); |
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | static inline int hpel_motion(MpegEncContext *s, | 191 | static inline int hpel_motion(MpegEncContext *s, |
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | * This file is part of Libav. | ||
| 3 | * | ||
| 4 | * Libav is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * Libav is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with Libav; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "config.h" | ||
| 20 | #include "libavutil/attributes.h" | ||
| 21 | #include "libavutil/common.h" | ||
| 22 | #include "mpegvideodsp.h" | ||
| 23 | |||
| 24 | static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, | ||
| 25 | int x16, int y16, int rounder) | ||
| 26 | { | ||
| 27 | const int A = (16 - x16) * (16 - y16); | ||
| 28 | const int B = (x16) * (16 - y16); | ||
| 29 | const int C = (16 - x16) * (y16); | ||
| 30 | const int D = (x16) * (y16); | ||
| 31 | int i; | ||
| 32 | |||
| 33 | for (i = 0; i < h; i++) { | ||
| 34 | dst[0] = (A * src[0] + B * src[1] + C * src[stride + 0] + D * src[stride + 1] + rounder) >> 8; | ||
| 35 | dst[1] = (A * src[1] + B * src[2] + C * src[stride + 1] + D * src[stride + 2] + rounder) >> 8; | ||
| 36 | dst[2] = (A * src[2] + B * src[3] + C * src[stride + 2] + D * src[stride + 3] + rounder) >> 8; | ||
| 37 | dst[3] = (A * src[3] + B * src[4] + C * src[stride + 3] + D * src[stride + 4] + rounder) >> 8; | ||
| 38 | dst[4] = (A * src[4] + B * src[5] + C * src[stride + 4] + D * src[stride + 5] + rounder) >> 8; | ||
| 39 | dst[5] = (A * src[5] + B * src[6] + C * src[stride + 5] + D * src[stride + 6] + rounder) >> 8; | ||
| 40 | dst[6] = (A * src[6] + B * src[7] + C * src[stride + 6] + D * src[stride + 7] + rounder) >> 8; | ||
| 41 | dst[7] = (A * src[7] + B * src[8] + C * src[stride + 7] + D * src[stride + 8] + rounder) >> 8; | ||
| 42 | dst += stride; | ||
| 43 | src += stride; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, | ||
| 48 | int dxx, int dxy, int dyx, int dyy, int shift, int r, | ||
| 49 | int width, int height) | ||
| 50 | { | ||
| 51 | int y, vx, vy; | ||
| 52 | const int s = 1 << shift; | ||
| 53 | |||
| 54 | width--; | ||
| 55 | height--; | ||
| 56 | |||
| 57 | for (y = 0; y < h; y++) { | ||
| 58 | int x; | ||
| 59 | |||
| 60 | vx = ox; | ||
| 61 | vy = oy; | ||
| 62 | for (x = 0; x < 8; x++) { // FIXME: optimize | ||
| 63 | int index; | ||
| 64 | int src_x = vx >> 16; | ||
| 65 | int src_y = vy >> 16; | ||
| 66 | int frac_x = src_x & (s - 1); | ||
| 67 | int frac_y = src_y & (s - 1); | ||
| 68 | |||
| 69 | src_x >>= shift; | ||
| 70 | src_y >>= shift; | ||
| 71 | |||
| 72 | if ((unsigned) src_x < width) { | ||
| 73 | if ((unsigned) src_y < height) { | ||
| 74 | index = src_x + src_y * stride; | ||
| 75 | dst[y * stride + x] = | ||
| 76 | ((src[index] * (s - frac_x) + | ||
| 77 | src[index + 1] * frac_x) * (s - frac_y) + | ||
| 78 | (src[index + stride] * (s - frac_x) + | ||
| 79 | src[index + stride + 1] * frac_x) * frac_y + | ||
| 80 | r) >> (shift * 2); | ||
| 81 | } else { | ||
| 82 | index = src_x + av_clip(src_y, 0, height) * stride; | ||
| 83 | dst[y * stride + x] = | ||
| 84 | ((src[index] * (s - frac_x) + | ||
| 85 | src[index + 1] * frac_x) * s + | ||
| 86 | r) >> (shift * 2); | ||
| 87 | } | ||
| 88 | } else { | ||
| 89 | if ((unsigned) src_y < height) { | ||
| 90 | index = av_clip(src_x, 0, width) + src_y * stride; | ||
| 91 | dst[y * stride + x] = | ||
| 92 | ((src[index] * (s - frac_y) + | ||
| 93 | src[index + stride] * frac_y) * s + | ||
| 94 | r) >> (shift * 2); | ||
| 95 | } else { | ||
| 96 | index = av_clip(src_x, 0, width) + | ||
| 97 | av_clip(src_y, 0, height) * stride; | ||
| 98 | dst[y * stride + x] = src[index]; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | vx += dxx; | ||
| 103 | vy += dyx; | ||
| 104 | } | ||
| 105 | ox += dxy; | ||
| 106 | oy += dyy; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | av_cold void ff_mpegvideodsp_init(MpegVideoDSPContext *c) | ||
| 111 | { | ||
| 112 | c->gmc1 = gmc1_c; | ||
| 113 | c->gmc = ff_gmc_c; | ||
| 114 | |||
| 115 | if (ARCH_PPC) | ||
| 116 | ff_mpegvideodsp_init_ppc(c); | ||
| 117 | if (ARCH_X86) | ||
| 118 | ff_mpegvideodsp_init_x86(c); | ||
| 119 | } | ||
| @@ -0,0 +1,47 @@ | |||
| 1 | /* | ||
| 2 | * This file is part of Libav. | ||
| 3 | * | ||
| 4 | * Libav is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * Libav is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with Libav; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef AVCODEC_MPEGVIDEODSP_H | ||
| 20 | #define AVCODEC_MPEGVIDEODSP_H | ||
| 21 | |||
| 22 | #include <stdint.h> | ||
| 23 | |||
| 24 | void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, | ||
| 25 | int dxx, int dxy, int dyx, int dyy, int shift, int r, | ||
| 26 | int width, int height); | ||
| 27 | |||
| 28 | typedef struct MpegVideoDSPContext { | ||
| 29 | /** | ||
| 30 | * translational global motion compensation. | ||
| 31 | */ | ||
| 32 | void (*gmc1)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, | ||
| 33 | int srcStride, int h, int x16, int y16, int rounder); | ||
| 34 | /** | ||
| 35 | * global motion compensation. | ||
| 36 | */ | ||
| 37 | void (*gmc)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, | ||
| 38 | int stride, int h, int ox, int oy, | ||
| 39 | int dxx, int dxy, int dyx, int dyy, | ||
| 40 | int shift, int r, int width, int height); | ||
| 41 | } MpegVideoDSPContext; | ||
| 42 | |||
| 43 | void ff_mpegvideodsp_init(MpegVideoDSPContext *c); | ||
| 44 | void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c); | ||
| 45 | void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c); | ||
| 46 | |||
| 47 | #endif /* AVCODEC_MPEGVIDEODSP_H */ | ||
| @@ -10,7 +10,8 @@ OBJS-$(CONFIG_H264QPEL) += ppc/h264qpel.o · 9 unmodified lines | |||
| 10 | OBJS-$(CONFIG_HPELDSP) += ppc/hpeldsp_altivec.o | 10 | OBJS-$(CONFIG_HPELDSP) += ppc/hpeldsp_altivec.o |
| 11 | OBJS-$(CONFIG_HUFFYUVDSP) += ppc/huffyuvdsp_altivec.o | 11 | OBJS-$(CONFIG_HUFFYUVDSP) += ppc/huffyuvdsp_altivec.o |
| 12 | OBJS-$(CONFIG_MPEGAUDIODSP) += ppc/mpegaudiodsp_altivec.o | 12 | OBJS-$(CONFIG_MPEGAUDIODSP) += ppc/mpegaudiodsp_altivec.o |
| 13 | OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o | 13 | OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o \ |
| 14 | ppc/mpegvideodsp.o | ||
| 14 | OBJS-$(CONFIG_VIDEODSP) += ppc/videodsp_ppc.o | 15 | OBJS-$(CONFIG_VIDEODSP) += ppc/videodsp_ppc.o |
| 15 | OBJS-$(CONFIG_VP3DSP) += ppc/vp3dsp_altivec.o | 16 | OBJS-$(CONFIG_VP3DSP) += ppc/vp3dsp_altivec.o |
| 16 | 17 | ||
| @@ -23,7 +24,6 @@ OBJS-$(CONFIG_VP8_DECODER) += ppc/vp8dsp_altivec.o · 6 unmodified lines | |||
| 23 | 24 | ||
| 24 | ALTIVEC-OBJS-$(CONFIG_DSPUTIL) += ppc/dsputil_altivec.o \ | 25 | ALTIVEC-OBJS-$(CONFIG_DSPUTIL) += ppc/dsputil_altivec.o \ |
| 25 | ppc/fdct_altivec.o \ | 26 | ppc/fdct_altivec.o \ |
| 26 | ppc/gmc_altivec.o \ | ||
| 27 | ppc/idct_altivec.o \ | 27 | ppc/idct_altivec.o \ |
| 28 | 28 | ||
| 29 | FFT-OBJS-$(HAVE_GNU_AS) += ppc/fft_altivec_s.o | 29 | FFT-OBJS-$(HAVE_GNU_AS) += ppc/fft_altivec_s.o |
| @@ -28,8 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include "libavcodec/dsputil.h" | 28 | #include "libavcodec/dsputil.h" |
| 29 | 29 | ||
| 30 | void ff_fdct_altivec(int16_t *block); | 30 | void ff_fdct_altivec(int16_t *block); |
| 31 | void ff_gmc1_altivec(uint8_t *dst, uint8_t *src, int stride, int h, | 31 | |
| 32 | int x16, int y16, int rounder); | ||
| 33 | void ff_idct_put_altivec(uint8_t *dest, int line_size, int16_t *block); | 32 | void ff_idct_put_altivec(uint8_t *dest, int line_size, int16_t *block); |
| 34 | void ff_idct_add_altivec(uint8_t *dest, int line_size, int16_t *block); | 33 | void ff_idct_add_altivec(uint8_t *dest, int line_size, int16_t *block); |
| 35 | 34 | ||
| @@ -35,8 +35,6 @@ av_cold void ff_dsputil_init_ppc(DSPContext *c, AVCodecContext *avctx, · 34 unmodified lines | |||
| 35 | if (PPC_ALTIVEC(av_get_cpu_flags())) { | 35 | if (PPC_ALTIVEC(av_get_cpu_flags())) { |
| 36 | ff_dsputil_init_altivec(c, avctx, high_bit_depth); | 36 | ff_dsputil_init_altivec(c, avctx, high_bit_depth); |
| 37 | 37 | ||
| 38 | c->gmc1 = ff_gmc1_altivec; | ||
| 39 | |||
| 40 | if (!high_bit_depth) { | 38 | if (!high_bit_depth) { |
| 41 | #if CONFIG_ENCODERS | 39 | #if CONFIG_ENCODERS |
| 42 | if (avctx->dct_algo == FF_DCT_AUTO || | 40 | if (avctx->dct_algo == FF_DCT_AUTO || |
| @@ -23,12 +23,13 @@ · 22 unmodified lines | |||
| 23 | #include "libavutil/mem.h" | 23 | #include "libavutil/mem.h" |
| 24 | #include "libavutil/ppc/types_altivec.h" | 24 | #include "libavutil/ppc/types_altivec.h" |
| 25 | #include "libavutil/ppc/util_altivec.h" | 25 | #include "libavutil/ppc/util_altivec.h" |
| 26 | #include "dsputil_altivec.h" | 26 | #include "libavcodec/mpegvideodsp.h" |
| 27 | 27 | ||
| 28 | #if HAVE_ALTIVEC | ||
| 28 | /* AltiVec-enhanced gmc1. ATM this code assumes stride is a multiple of 8 | 29 | /* AltiVec-enhanced gmc1. ATM this code assumes stride is a multiple of 8 |
| 29 | * to preserve proper dst alignment. */ | 30 | * to preserve proper dst alignment. */ |
| 30 | void ff_gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, | 31 | static void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, |
| 31 | int stride, int h, int x16, int y16, int rounder) | 32 | int stride, int h, int x16, int y16, int rounder) |
| 32 | { | 33 | { |
| 33 | int i; | 34 | int i; |
| 34 | const DECLARE_ALIGNED(16, unsigned short, rounder_a) = rounder; | 35 | const DECLARE_ALIGNED(16, unsigned short, rounder_a) = rounder; |
| @@ -122,3 +123,11 @@ void ff_gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, · 87 unmodified lines | |||
| 122 | src += stride; | 123 | src += stride; |
| 123 | } | 124 | } |
| 124 | } | 125 | } |
| 126 | #endif /* HAVE_ALTIVEC */ | ||
| 127 | |||
| 128 | av_cold void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c) | ||
| 129 | { | ||
| 130 | #if HAVE_ALTIVEC | ||
| 131 | c->gmc1 = gmc1_altivec; | ||
| 132 | #endif /* HAVE_ALTIVEC */ | ||
| 133 | } | ||
| @@ -20,7 +20,8 @@ OBJS-$(CONFIG_HUFFYUVDSP) += x86/huffyuvdsp_init.o · 19 unmodified lines | |||
| 20 | OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp_mmx.o | 20 | OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp_mmx.o |
| 21 | OBJS-$(CONFIG_LPC) += x86/lpc.o | 21 | OBJS-$(CONFIG_LPC) += x86/lpc.o |
| 22 | OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodsp.o | 22 | OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodsp.o |
| 23 | OBJS-$(CONFIG_MPEGVIDEO) += x86/mpegvideo.o | 23 | OBJS-$(CONFIG_MPEGVIDEO) += x86/mpegvideo.o \ |
| 24 | x86/mpegvideodsp.o | ||
| 24 | OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoenc.o | 25 | OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoenc.o |
| 25 | OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp_init.o | 26 | OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp_init.o |
| 26 | OBJS-$(CONFIG_VIDEODSP) += x86/videodsp_init.o | 27 | OBJS-$(CONFIG_VIDEODSP) += x86/videodsp_init.o |
| @@ -52,8 +52,6 @@ static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx, · 51 unmodified lines | |||
| 52 | break; | 52 | break; |
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| 55 | |||
| 56 | c->gmc = ff_gmc_mmx; | ||
| 57 | #endif /* HAVE_MMX_INLINE */ | 55 | #endif /* HAVE_MMX_INLINE */ |
| 58 | } | 56 | } |
| 59 | 57 | ||
| @@ -260,118 +260,4 @@ void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, · 259 unmodified lines | |||
| 260 | } | 260 | } |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | void ff_gmc_mmx(uint8_t *dst, uint8_t *src, | ||
| 264 | int stride, int h, int ox, int oy, | ||
| 265 | int dxx, int dxy, int dyx, int dyy, | ||
| 266 | int shift, int r, int width, int height) | ||
| 267 | { | ||
| 268 | const int w = 8; | ||
| 269 | const int ix = ox >> (16 + shift); | ||
| 270 | const int iy = oy >> (16 + shift); | ||
| 271 | const int oxs = ox >> 4; | ||
| 272 | const int oys = oy >> 4; | ||
| 273 | const int dxxs = dxx >> 4; | ||
| 274 | const int dxys = dxy >> 4; | ||
| 275 | const int dyxs = dyx >> 4; | ||
| 276 | const int dyys = dyy >> 4; | ||
| 277 | const uint16_t r4[4] = { r, r, r, r }; | ||
| 278 | const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys }; | ||
| 279 | const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys }; | ||
| 280 | const uint64_t shift2 = 2 * shift; | ||
| 281 | int x, y; | ||
| 282 | |||
| 283 | const int dxw = (dxx - (1 << (16 + shift))) * (w - 1); | ||
| 284 | const int dyh = (dyy - (1 << (16 + shift))) * (h - 1); | ||
| 285 | const int dxh = dxy * (h - 1); | ||
| 286 | const int dyw = dyx * (w - 1); | ||
| 287 | |||
| 288 | if ( // non-constant fullpel offset (3% of blocks) | ||
| 289 | ((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) | | ||
| 290 | (oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift) || | ||
| 291 | // uses more than 16 bits of subpel mv (only at huge resolution) | ||
| 292 | (dxx | dxy | dyx | dyy) & 15 || | ||
| 293 | (unsigned) ix >= width - w || | ||
| 294 | (unsigned) iy >= height - h) { | ||
| 295 | // FIXME could still use mmx for some of the rows | ||
| 296 | ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, | ||
| 297 | shift, r, width, height); | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | |||
| 301 | src += ix + iy * stride; | ||
| 302 | |||
| 303 | __asm__ volatile ( | ||
| 304 | "movd %0, %%mm6 \n\t" | ||
| 305 | "pxor %%mm7, %%mm7 \n\t" | ||
| 306 | "punpcklwd %%mm6, %%mm6 \n\t" | ||
| 307 | "punpcklwd %%mm6, %%mm6 \n\t" | ||
| 308 | :: "r" (1 << shift)); | ||
| 309 | |||
| 310 | for (x = 0; x < w; x += 4) { | ||
| 311 | uint16_t dx4[4] = { oxs - dxys + dxxs * (x + 0), | ||
| 312 | oxs - dxys + dxxs * (x + 1), | ||
| 313 | oxs - dxys + dxxs * (x + 2), | ||
| 314 | oxs - dxys + dxxs * (x + 3) }; | ||
| 315 | uint16_t dy4[4] = { oys - dyys + dyxs * (x + 0), | ||
| 316 | oys - dyys + dyxs * (x + 1), | ||
| 317 | oys - dyys + dyxs * (x + 2), | ||
| 318 | oys - dyys + dyxs * (x + 3) }; | ||
| 319 | |||
| 320 | for (y = 0; y < h; y++) { | ||
| 321 | __asm__ volatile ( | ||
| 322 | "movq %0, %%mm4 \n\t" | ||
| 323 | "movq %1, %%mm5 \n\t" | ||
| 324 | "paddw %2, %%mm4 \n\t" | ||
| 325 | "paddw %3, %%mm5 \n\t" | ||
| 326 | "movq %%mm4, %0 \n\t" | ||
| 327 | "movq %%mm5, %1 \n\t" | ||
| 328 | "psrlw $12, %%mm4 \n\t" | ||
| 329 | "psrlw $12, %%mm5 \n\t" | ||
| 330 | : "+m" (*dx4), "+m" (*dy4) | ||
| 331 | : "m" (*dxy4), "m" (*dyy4)); | ||
| 332 | |||
| 333 | __asm__ volatile ( | ||
| 334 | "movq %%mm6, %%mm2 \n\t" | ||
| 335 | "movq %%mm6, %%mm1 \n\t" | ||
| 336 | "psubw %%mm4, %%mm2 \n\t" | ||
| 337 | "psubw %%mm5, %%mm1 \n\t" | ||
| 338 | "movq %%mm2, %%mm0 \n\t" | ||
| 339 | "movq %%mm4, %%mm3 \n\t" | ||
| 340 | "pmullw %%mm1, %%mm0 \n\t" // (s - dx) * (s - dy) | ||
| 341 | "pmullw %%mm5, %%mm3 \n\t" // dx * dy | ||
| 342 | "pmullw %%mm5, %%mm2 \n\t" // (s - dx) * dy | ||
| 343 | "pmullw %%mm4, %%mm1 \n\t" // dx * (s - dy) | ||
| 344 | |||
| 345 | "movd %4, %%mm5 \n\t" | ||
| 346 | "movd %3, %%mm4 \n\t" | ||
| 347 | "punpcklbw %%mm7, %%mm5 \n\t" | ||
| 348 | "punpcklbw %%mm7, %%mm4 \n\t" | ||
| 349 | "pmullw %%mm5, %%mm3 \n\t" // src[1, 1] * dx * dy | ||
| 350 | "pmullw %%mm4, %%mm2 \n\t" // src[0, 1] * (s - dx) * dy | ||
| 351 | |||
| 352 | "movd %2, %%mm5 \n\t" | ||
| 353 | "movd %1, %%mm4 \n\t" | ||
| 354 | "punpcklbw %%mm7, %%mm5 \n\t" | ||
| 355 | "punpcklbw %%mm7, %%mm4 \n\t" | ||
| 356 | "pmullw %%mm5, %%mm1 \n\t" // src[1, 0] * dx * (s - dy) | ||
| 357 | "pmullw %%mm4, %%mm0 \n\t" // src[0, 0] * (s - dx) * (s - dy) | ||
| 358 | "paddw %5, %%mm1 \n\t" | ||
| 359 | "paddw %%mm3, %%mm2 \n\t" | ||
| 360 | "paddw %%mm1, %%mm0 \n\t" | ||
| 361 | "paddw %%mm2, %%mm0 \n\t" | ||
| 362 | |||
| 363 | "psrlw %6, %%mm0 \n\t" | ||
| 364 | "packuswb %%mm0, %%mm0 \n\t" | ||
| 365 | "movd %%mm0, %0 \n\t" | ||
| 366 | |||
| 367 | : "=m" (dst[x + y * stride]) | ||
| 368 | : "m" (src[0]), "m" (src[1]), | ||
| 369 | "m" (src[stride]), "m" (src[stride + 1]), | ||
| 370 | "m" (*r4), "m" (shift2)); | ||
| 371 | src += stride; | ||
| 372 | } | ||
| 373 | src += 4 - h * stride; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | #endif /* HAVE_INLINE_ASM */ | 263 | #endif /* HAVE_INLINE_ASM */ |
| @@ -41,9 +41,4 @@ void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, · 40 unmodified lines | |||
| 41 | void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, | 41 | void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, |
| 42 | int w, int h, int sides); | 42 | int w, int h, int sides); |
| 43 | 43 | ||
| 44 | void ff_gmc_mmx(uint8_t *dst, uint8_t *src, | ||
| 45 | int stride, int h, int ox, int oy, | ||
| 46 | int dxx, int dxy, int dyx, int dyy, | ||
| 47 | int shift, int r, int width, int height); | ||
| 48 | |||
| 49 | #endif /* AVCODEC_X86_DSPUTIL_X86_H */ | 44 | #endif /* AVCODEC_X86_DSPUTIL_X86_H */ |
| @@ -0,0 +1,153 @@ | |||
| 1 | /* | ||
| 2 | * This file is part of Libav. | ||
| 3 | * | ||
| 4 | * Libav is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * Libav is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with Libav; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "config.h" | ||
| 20 | #include "libavutil/attributes.h" | ||
| 21 | #include "libavutil/cpu.h" | ||
| 22 | #include "libavutil/x86/asm.h" | ||
| 23 | #include "libavutil/x86/cpu.h" | ||
| 24 | #include "libavcodec/mpegvideodsp.h" | ||
| 25 | |||
| 26 | #if HAVE_INLINE_ASM | ||
| 27 | |||
| 28 | static void gmc_mmx(uint8_t *dst, uint8_t *src, | ||
| 29 | int stride, int h, int ox, int oy, | ||
| 30 | int dxx, int dxy, int dyx, int dyy, | ||
| 31 | int shift, int r, int width, int height) | ||
| 32 | { | ||
| 33 | const int w = 8; | ||
| 34 | const int ix = ox >> (16 + shift); | ||
| 35 | const int iy = oy >> (16 + shift); | ||
| 36 | const int oxs = ox >> 4; | ||
| 37 | const int oys = oy >> 4; | ||
| 38 | const int dxxs = dxx >> 4; | ||
| 39 | const int dxys = dxy >> 4; | ||
| 40 | const int dyxs = dyx >> 4; | ||
| 41 | const int dyys = dyy >> 4; | ||
| 42 | const uint16_t r4[4] = { r, r, r, r }; | ||
| 43 | const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys }; | ||
| 44 | const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys }; | ||
| 45 | const uint64_t shift2 = 2 * shift; | ||
| 46 | int x, y; | ||
| 47 | |||
| 48 | const int dxw = (dxx - (1 << (16 + shift))) * (w - 1); | ||
| 49 | const int dyh = (dyy - (1 << (16 + shift))) * (h - 1); | ||
| 50 | const int dxh = dxy * (h - 1); | ||
| 51 | const int dyw = dyx * (w - 1); | ||
| 52 | |||
| 53 | if ( // non-constant fullpel offset (3% of blocks) | ||
| 54 | ((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) | | ||
| 55 | (oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift) || | ||
| 56 | // uses more than 16 bits of subpel mv (only at huge resolution) | ||
| 57 | (dxx | dxy | dyx | dyy) & 15 || | ||
| 58 | (unsigned) ix >= width - w || | ||
| 59 | (unsigned) iy >= height - h) { | ||
| 60 | // FIXME could still use mmx for some of the rows | ||
| 61 | ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, | ||
| 62 | shift, r, width, height); | ||
| 63 | return; | ||
| 64 | } | ||
| 65 | |||
| 66 | src += ix + iy * stride; | ||
| 67 | |||
| 68 | __asm__ volatile ( | ||
| 69 | "movd %0, %%mm6 \n\t" | ||
| 70 | "pxor %%mm7, %%mm7 \n\t" | ||
| 71 | "punpcklwd %%mm6, %%mm6 \n\t" | ||
| 72 | "punpcklwd %%mm6, %%mm6 \n\t" | ||
| 73 | :: "r" (1 << shift)); | ||
| 74 | |||
| 75 | for (x = 0; x < w; x += 4) { | ||
| 76 | uint16_t dx4[4] = { oxs - dxys + dxxs * (x + 0), | ||
| 77 | oxs - dxys + dxxs * (x + 1), | ||
| 78 | oxs - dxys + dxxs * (x + 2), | ||
| 79 | oxs - dxys + dxxs * (x + 3) }; | ||
| 80 | uint16_t dy4[4] = { oys - dyys + dyxs * (x + 0), | ||
| 81 | oys - dyys + dyxs * (x + 1), | ||
| 82 | oys - dyys + dyxs * (x + 2), | ||
| 83 | oys - dyys + dyxs * (x + 3) }; | ||
| 84 | |||
| 85 | for (y = 0; y < h; y++) { | ||
| 86 | __asm__ volatile ( | ||
| 87 | "movq %0, %%mm4 \n\t" | ||
| 88 | "movq %1, %%mm5 \n\t" | ||
| 89 | "paddw %2, %%mm4 \n\t" | ||
| 90 | "paddw %3, %%mm5 \n\t" | ||
| 91 | "movq %%mm4, %0 \n\t" | ||
| 92 | "movq %%mm5, %1 \n\t" | ||
| 93 | "psrlw $12, %%mm4 \n\t" | ||
| 94 | "psrlw $12, %%mm5 \n\t" | ||
| 95 | : "+m" (*dx4), "+m" (*dy4) | ||
| 96 | : "m" (*dxy4), "m" (*dyy4)); | ||
| 97 | |||
| 98 | __asm__ volatile ( | ||
| 99 | "movq %%mm6, %%mm2 \n\t" | ||
| 100 | "movq %%mm6, %%mm1 \n\t" | ||
| 101 | "psubw %%mm4, %%mm2 \n\t" | ||
| 102 | "psubw %%mm5, %%mm1 \n\t" | ||
| 103 | "movq %%mm2, %%mm0 \n\t" | ||
| 104 | "movq %%mm4, %%mm3 \n\t" | ||
| 105 | "pmullw %%mm1, %%mm0 \n\t" // (s - dx) * (s - dy) | ||
| 106 | "pmullw %%mm5, %%mm3 \n\t" // dx * dy | ||
| 107 | "pmullw %%mm5, %%mm2 \n\t" // (s - dx) * dy | ||
| 108 | "pmullw %%mm4, %%mm1 \n\t" // dx * (s - dy) | ||
| 109 | |||
| 110 | "movd %4, %%mm5 \n\t" | ||
| 111 | "movd %3, %%mm4 \n\t" | ||
| 112 | "punpcklbw %%mm7, %%mm5 \n\t" | ||
| 113 | "punpcklbw %%mm7, %%mm4 \n\t" | ||
| 114 | "pmullw %%mm5, %%mm3 \n\t" // src[1, 1] * dx * dy | ||
| 115 | "pmullw %%mm4, %%mm2 \n\t" // src[0, 1] * (s - dx) * dy | ||
| 116 | |||
| 117 | "movd %2, %%mm5 \n\t" | ||
| 118 | "movd %1, %%mm4 \n\t" | ||
| 119 | "punpcklbw %%mm7, %%mm5 \n\t" | ||
| 120 | "punpcklbw %%mm7, %%mm4 \n\t" | ||
| 121 | "pmullw %%mm5, %%mm1 \n\t" // src[1, 0] * dx * (s - dy) | ||
| 122 | "pmullw %%mm4, %%mm0 \n\t" // src[0, 0] * (s - dx) * (s - dy) | ||
| 123 | "paddw %5, %%mm1 \n\t" | ||
| 124 | "paddw %%mm3, %%mm2 \n\t" | ||
| 125 | "paddw %%mm1, %%mm0 \n\t" | ||
| 126 | "paddw %%mm2, %%mm0 \n\t" | ||
| 127 | |||
| 128 | "psrlw %6, %%mm0 \n\t" | ||
| 129 | "packuswb %%mm0, %%mm0 \n\t" | ||
| 130 | "movd %%mm0, %0 \n\t" | ||
| 131 | |||
| 132 | : "=m" (dst[x + y * stride]) | ||
| 133 | : "m" (src[0]), "m" (src[1]), | ||
| 134 | "m" (src[stride]), "m" (src[stride + 1]), | ||
| 135 | "m" (*r4), "m" (shift2)); | ||
| 136 | src += stride; | ||
| 137 | } | ||
| 138 | src += 4 - h * stride; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | #endif /* HAVE_INLINE_ASM */ | ||
| 143 | |||
| 144 | av_cold void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c) | ||
| 145 | { | ||
| 146 | #if HAVE_INLINE_ASM | ||
| 147 | int cpu_flags = av_get_cpu_flags(); | ||
| 148 | |||
| 149 | if (INLINE_MMX(cpu_flags)) | ||
| 150 | c->gmc = gmc_mmx; | ||
| 151 | #endif /* HAVE_INLINE_ASM */ | ||
| 152 | } | ||
| 153 | |||