Unified · Split
| @@ -63,8 +63,8 @@ OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \ · 62 unmodified lines | ||
| 63 | 63 | mpegaudiodsp_data.o \ |
| 64 | 64 | mpegaudiodsp_fixed.o \ |
| 65 | 65 | mpegaudiodsp_float.o |
| 66 | −OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideo_motion.o \ | |
| 67 | − mpegutils.o | |
| 66 | +OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o \ | |
| 67 | + mpegvideo_motion.o mpegutils.o | |
| 68 | 68 | OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ |
| 69 | 69 | motion_est.o ratecontrol.o |
| 70 | 70 | OBJS-$(CONFIG_QPELDSP) += qpeldsp.o |
| @@ -3,8 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | * Copyright (c) 2000, 2001 Fabrice Bellard |
| 4 | 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 | 6 | * This file is part of Libav. |
| 9 | 7 | * |
| 10 | 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 | 350 | #define avg2(a, b) ((a + b + 1) >> 1) |
| 353 | 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 | 353 | static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, |
| 442 | 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 | 1259 | c->sum_abs_dctelem = sum_abs_dctelem_c; |
| 1348 | 1260 | |
| 1349 | − c->gmc1 = gmc1_c; | |
| 1350 | − c->gmc = ff_gmc_c; | |
| 1351 | − | |
| 1352 | 1261 | c->pix_sum = pix_sum_c; |
| 1353 | 1262 | c->pix_norm1 = pix_norm1_c; |
| 1354 | 1263 | |
| @@ -34,10 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 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 | 37 | struct MpegEncContext; |
| 42 | 38 | /* Motion estimation: |
| 43 | 39 | * h is limited to { width / 2, width, 2 * width }, |
| @@ -84,18 +80,6 @@ typedef struct DSPContext { · 40 unmodified lines | ||
| 84 | 80 | uint8_t *pixels /* align 8 */, |
| 85 | 81 | int line_size); |
| 86 | 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 | 84 | int (*pix_sum)(uint8_t *pix, int line_size); |
| 101 | 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 | 380 | ff_blockdsp_init(&s->bdsp, s->avctx); |
| 381 | 381 | ff_dsputil_init(&s->dsp, s->avctx); |
| 382 | 382 | ff_hpeldsp_init(&s->hdsp, s->avctx->flags); |
| 383 | + ff_mpegvideodsp_init(&s->mdsp); | |
| 383 | 384 | ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample); |
| 384 | 385 | |
| 385 | 386 | s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include "get_bits.h" |
| 36 | 36 | #include "h263dsp.h" |
| 37 | 37 | #include "hpeldsp.h" |
| 38 | +#include "mpegvideodsp.h" | |
| 38 | 39 | #include "put_bits.h" |
| 39 | 40 | #include "ratecontrol.h" |
| 40 | 41 | #include "parser.h" |
| @@ -351,6 +352,7 @@ typedef struct MpegEncContext { · 310 unmodified lines | ||
| 351 | 352 | BlockDSPContext bdsp; |
| 352 | 353 | DSPContext dsp; ///< pointers for accelerated dsp functions |
| 353 | 354 | HpelDSPContext hdsp; |
| 355 | + MpegVideoDSPContext mdsp; | |
| 354 | 356 | QpelDSPContext qdsp; |
| 355 | 357 | VideoDSPContext vdsp; |
| 356 | 358 | H263DSPContext h263dsp; |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "libavutil/internal.h" |
| 27 | 27 | #include "avcodec.h" |
| 28 | −#include "dsputil.h" | |
| 29 | 28 | #include "h261.h" |
| 30 | 29 | #include "mpegutils.h" |
| 31 | 30 | #include "mpegvideo.h" |
| @@ -72,10 +71,10 @@ static void gmc1_motion(MpegEncContext *s, · 40 unmodified lines | ||
| 72 | 71 | } |
| 73 | 72 | |
| 74 | 73 | if ((motion_x | motion_y) & 7) { |
| 75 | − s->dsp.gmc1(dest_y, ptr, linesize, 16, | |
| 76 | − motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 77 | − s->dsp.gmc1(dest_y + 8, ptr + 8, linesize, 16, | |
| 78 | − motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 74 | + s->mdsp.gmc1(dest_y, ptr, linesize, 16, | |
| 75 | + motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 76 | + s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16, | |
| 77 | + motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 79 | 78 | } else { |
| 80 | 79 | int dxy; |
| 81 | 80 | |
| @@ -115,8 +114,8 @@ static void gmc1_motion(MpegEncContext *s, · 33 unmodified lines | ||
| 115 | 114 | ptr = s->edge_emu_buffer; |
| 116 | 115 | emu = 1; |
| 117 | 116 | } |
| 118 | − s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, | |
| 119 | − motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 117 | + s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8, | |
| 118 | + motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 120 | 119 | |
| 121 | 120 | ptr = ref_picture[2] + offset; |
| 122 | 121 | if (emu) { |
| @@ -127,8 +126,8 @@ static void gmc1_motion(MpegEncContext *s, · 4 unmodified lines | ||
| 127 | 126 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); |
| 128 | 127 | ptr = s->edge_emu_buffer; |
| 129 | 128 | } |
| 130 | − s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, | |
| 131 | − motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 129 | + s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8, | |
| 130 | + motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
| 132 | 131 | } |
| 133 | 132 | |
| 134 | 133 | static void gmc_motion(MpegEncContext *s, |
| @@ -150,19 +149,19 @@ static void gmc_motion(MpegEncContext *s, · 15 unmodified lines | ||
| 150 | 149 | oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 + |
| 151 | 150 | s->sprite_delta[1][1] * s->mb_y * 16; |
| 152 | 151 | |
| 153 | − s->dsp.gmc(dest_y, ptr, linesize, 16, | |
| 154 | − ox, oy, | |
| 155 | − s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 156 | − s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 157 | − a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 158 | − s->h_edge_pos, s->v_edge_pos); | |
| 159 | − s->dsp.gmc(dest_y + 8, ptr, linesize, 16, | |
| 160 | − ox + s->sprite_delta[0][0] * 8, | |
| 161 | − oy + s->sprite_delta[1][0] * 8, | |
| 162 | − s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 163 | − s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 164 | − a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 165 | − s->h_edge_pos, s->v_edge_pos); | |
| 152 | + s->mdsp.gmc(dest_y, ptr, linesize, 16, | |
| 153 | + ox, oy, | |
| 154 | + s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 155 | + s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 156 | + a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 157 | + s->h_edge_pos, s->v_edge_pos); | |
| 158 | + s->mdsp.gmc(dest_y + 8, ptr, linesize, 16, | |
| 159 | + ox + s->sprite_delta[0][0] * 8, | |
| 160 | + oy + s->sprite_delta[1][0] * 8, | |
| 161 | + s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 162 | + s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 163 | + a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 164 | + s->h_edge_pos, s->v_edge_pos); | |
| 166 | 165 | |
| 167 | 166 | if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY) |
| 168 | 167 | return; |
| @@ -173,20 +172,20 @@ static void gmc_motion(MpegEncContext *s, · 4 unmodified lines | ||
| 173 | 172 | s->sprite_delta[1][1] * s->mb_y * 8; |
| 174 | 173 | |
| 175 | 174 | ptr = ref_picture[1]; |
| 176 | − s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, | |
| 177 | − ox, oy, | |
| 178 | − s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 179 | − s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 180 | − a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 181 | − s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
| 175 | + s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8, | |
| 176 | + ox, oy, | |
| 177 | + s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 178 | + s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 179 | + a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 180 | + s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
| 182 | 181 | |
| 183 | 182 | ptr = ref_picture[2]; |
| 184 | − s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, | |
| 185 | − ox, oy, | |
| 186 | − s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 187 | − s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 188 | − a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 189 | − s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
| 183 | + s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8, | |
| 184 | + ox, oy, | |
| 185 | + s->sprite_delta[0][0], s->sprite_delta[0][1], | |
| 186 | + s->sprite_delta[1][0], s->sprite_delta[1][1], | |
| 187 | + a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
| 188 | + s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
| 190 | 189 | } |
| 191 | 190 | |
| 192 | 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 | 10 | OBJS-$(CONFIG_HPELDSP) += ppc/hpeldsp_altivec.o |
| 11 | 11 | OBJS-$(CONFIG_HUFFYUVDSP) += ppc/huffyuvdsp_altivec.o |
| 12 | 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 | 15 | OBJS-$(CONFIG_VIDEODSP) += ppc/videodsp_ppc.o |
| 15 | 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 | 25 | ALTIVEC-OBJS-$(CONFIG_DSPUTIL) += ppc/dsputil_altivec.o \ |
| 25 | 26 | ppc/fdct_altivec.o \ |
| 26 | − ppc/gmc_altivec.o \ | |
| 27 | 27 | ppc/idct_altivec.o \ |
| 28 | 28 | |
| 29 | 29 | FFT-OBJS-$(HAVE_GNU_AS) += ppc/fft_altivec_s.o |
| @@ -28,8 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "libavcodec/dsputil.h" |
| 29 | 29 | |
| 30 | 30 | void ff_fdct_altivec(int16_t *block); |
| 31 | −void ff_gmc1_altivec(uint8_t *dst, uint8_t *src, int stride, int h, | |
| 32 | − int x16, int y16, int rounder); | |
| 31 | + | |
| 33 | 32 | void ff_idct_put_altivec(uint8_t *dest, int line_size, int16_t *block); |
| 34 | 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 | 35 | if (PPC_ALTIVEC(av_get_cpu_flags())) { |
| 36 | 36 | ff_dsputil_init_altivec(c, avctx, high_bit_depth); |
| 37 | 37 | |
| 38 | − c->gmc1 = ff_gmc1_altivec; | |
| 39 | − | |
| 40 | 38 | if (!high_bit_depth) { |
| 41 | 39 | #if CONFIG_ENCODERS |
| 42 | 40 | if (avctx->dct_algo == FF_DCT_AUTO || |
| @@ -23,12 +23,13 @@ · 22 unmodified lines | ||
| 23 | 23 | #include "libavutil/mem.h" |
| 24 | 24 | #include "libavutil/ppc/types_altivec.h" |
| 25 | 25 | #include "libavutil/ppc/util_altivec.h" |
| 26 | −#include "dsputil_altivec.h" | |
| 26 | +#include "libavcodec/mpegvideodsp.h" | |
| 27 | 27 | |
| 28 | +#if HAVE_ALTIVEC | |
| 28 | 29 | /* AltiVec-enhanced gmc1. ATM this code assumes stride is a multiple of 8 |
| 29 | 30 | * to preserve proper dst alignment. */ |
| 30 | −void ff_gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, | |
| 31 | − int stride, int h, int x16, int y16, int rounder) | |
| 31 | +static void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, | |
| 32 | + int stride, int h, int x16, int y16, int rounder) | |
| 32 | 33 | { |
| 33 | 34 | int i; |
| 34 | 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 | 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 | 20 | OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp_mmx.o |
| 21 | 21 | OBJS-$(CONFIG_LPC) += x86/lpc.o |
| 22 | 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 | 25 | OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoenc.o |
| 25 | 26 | OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp_init.o |
| 26 | 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 | 52 | break; |
| 53 | 53 | } |
| 54 | 54 | } |
| 55 | − | |
| 56 | − c->gmc = ff_gmc_mmx; | |
| 57 | 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 | 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 | 41 | void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, |
| 42 | 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 | 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 | + | |