| @@ -921,34 +921,6 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c) | |||||
| WRAPPER8_16_SQ(rd8x8_c, rd16_c) | WRAPPER8_16_SQ(rd8x8_c, rd16_c) | ||||
| WRAPPER8_16_SQ(bit8x8_c, bit16_c) | WRAPPER8_16_SQ(bit8x8_c, bit16_c) | ||||
| /* draw the edges of width 'w' of an image of size width, height */ | |||||
| // FIXME: Check that this is OK for MPEG-4 interlaced. | |||||
| static void draw_edges_8_c(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides) | |||||
| { | |||||
| uint8_t *ptr = buf, *last_line; | |||||
| int i; | |||||
| /* left and right */ | |||||
| for (i = 0; i < height; i++) { | |||||
| memset(ptr - w, ptr[0], w); | |||||
| memset(ptr + width, ptr[width - 1], w); | |||||
| ptr += wrap; | |||||
| } | |||||
| /* top and bottom + corners */ | |||||
| buf -= w; | |||||
| last_line = buf + (height - 1) * wrap; | |||||
| if (sides & EDGE_TOP) | |||||
| for (i = 0; i < h; i++) | |||||
| // top | |||||
| memcpy(buf - (i + 1) * wrap, buf, width + w + w); | |||||
| if (sides & EDGE_BOTTOM) | |||||
| for (i = 0; i < h; i++) | |||||
| // bottom | |||||
| memcpy(last_line + (i + 1) * wrap, last_line, width + w + w); | |||||
| } | |||||
| /* init static data */ | /* init static data */ | ||||
| av_cold void ff_dsputil_static_init(void) | av_cold void ff_dsputil_static_init(void) | ||||
| { | { | ||||
| @@ -1023,8 +995,6 @@ av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx) | |||||
| c->nsse[0] = nsse16_c; | c->nsse[0] = nsse16_c; | ||||
| c->nsse[1] = nsse8_c; | c->nsse[1] = nsse8_c; | ||||
| c->draw_edges = draw_edges_8_c; | |||||
| switch (avctx->bits_per_raw_sample) { | switch (avctx->bits_per_raw_sample) { | ||||
| case 9: | case 9: | ||||
| case 10: | case 10: | ||||
| @@ -83,12 +83,6 @@ typedef struct DSPContext { | |||||
| /* (I)DCT */ | /* (I)DCT */ | ||||
| void (*fdct)(int16_t *block /* align 16 */); | void (*fdct)(int16_t *block /* align 16 */); | ||||
| void (*fdct248)(int16_t *block /* align 16 */); | void (*fdct248)(int16_t *block /* align 16 */); | ||||
| void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides); | |||||
| #define EDGE_WIDTH 16 | |||||
| #define EDGE_TOP 1 | |||||
| #define EDGE_BOTTOM 2 | |||||
| } DSPContext; | } DSPContext; | ||||
| void ff_dsputil_static_init(void); | void ff_dsputil_static_init(void); | ||||
| @@ -80,6 +80,8 @@ enum OutputFormat { | |||||
| #define INPLACE_OFFSET 16 | #define INPLACE_OFFSET 16 | ||||
| #define EDGE_WIDTH 16 | |||||
| /* Start codes. */ | /* Start codes. */ | ||||
| #define SEQ_END_CODE 0x000001b7 | #define SEQ_END_CODE 0x000001b7 | ||||
| #define SEQ_START_CODE 0x000001b3 | #define SEQ_START_CODE 0x000001b3 | ||||
| @@ -1391,18 +1391,22 @@ static void frame_end(MpegEncContext *s) | |||||
| const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); | ||||
| int hshift = desc->log2_chroma_w; | int hshift = desc->log2_chroma_w; | ||||
| int vshift = desc->log2_chroma_h; | int vshift = desc->log2_chroma_h; | ||||
| s->dsp.draw_edges(s->current_picture.f->data[0], s->linesize, | |||||
| s->h_edge_pos, s->v_edge_pos, | |||||
| EDGE_WIDTH, EDGE_WIDTH, | |||||
| EDGE_TOP | EDGE_BOTTOM); | |||||
| s->dsp.draw_edges(s->current_picture.f->data[1], s->uvlinesize, | |||||
| s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, | |||||
| EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, | |||||
| EDGE_TOP | EDGE_BOTTOM); | |||||
| s->dsp.draw_edges(s->current_picture.f->data[2], s->uvlinesize, | |||||
| s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, | |||||
| EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, | |||||
| EDGE_TOP | EDGE_BOTTOM); | |||||
| s->mpvencdsp.draw_edges(s->current_picture.f->data[0], s->linesize, | |||||
| s->h_edge_pos, s->v_edge_pos, | |||||
| EDGE_WIDTH, EDGE_WIDTH, | |||||
| EDGE_TOP | EDGE_BOTTOM); | |||||
| s->mpvencdsp.draw_edges(s->current_picture.f->data[1], s->uvlinesize, | |||||
| s->h_edge_pos >> hshift, | |||||
| s->v_edge_pos >> vshift, | |||||
| EDGE_WIDTH >> hshift, | |||||
| EDGE_WIDTH >> vshift, | |||||
| EDGE_TOP | EDGE_BOTTOM); | |||||
| s->mpvencdsp.draw_edges(s->current_picture.f->data[2], s->uvlinesize, | |||||
| s->h_edge_pos >> hshift, | |||||
| s->v_edge_pos >> vshift, | |||||
| EDGE_WIDTH >> hshift, | |||||
| EDGE_WIDTH >> vshift, | |||||
| EDGE_TOP | EDGE_BOTTOM); | |||||
| } | } | ||||
| emms_c(); | emms_c(); | ||||
| @@ -18,6 +18,7 @@ | |||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <string.h> | |||||
| #include "config.h" | #include "config.h" | ||||
| #include "libavutil/attributes.h" | #include "libavutil/attributes.h" | ||||
| @@ -124,6 +125,34 @@ static int pix_norm1_c(uint8_t *pix, int line_size) | |||||
| return s; | return s; | ||||
| } | } | ||||
| /* draw the edges of width 'w' of an image of size width, height */ | |||||
| // FIXME: Check that this is OK for MPEG-4 interlaced. | |||||
| static void draw_edges_8_c(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides) | |||||
| { | |||||
| uint8_t *ptr = buf, *last_line; | |||||
| int i; | |||||
| /* left and right */ | |||||
| for (i = 0; i < height; i++) { | |||||
| memset(ptr - w, ptr[0], w); | |||||
| memset(ptr + width, ptr[width - 1], w); | |||||
| ptr += wrap; | |||||
| } | |||||
| /* top and bottom + corners */ | |||||
| buf -= w; | |||||
| last_line = buf + (height - 1) * wrap; | |||||
| if (sides & EDGE_TOP) | |||||
| for (i = 0; i < h; i++) | |||||
| // top | |||||
| memcpy(buf - (i + 1) * wrap, buf, width + w + w); | |||||
| if (sides & EDGE_BOTTOM) | |||||
| for (i = 0; i < h; i++) | |||||
| // bottom | |||||
| memcpy(last_line + (i + 1) * wrap, last_line, width + w + w); | |||||
| } | |||||
| av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, | av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, | ||||
| AVCodecContext *avctx) | AVCodecContext *avctx) | ||||
| { | { | ||||
| @@ -138,6 +167,8 @@ av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, | |||||
| c->pix_sum = pix_sum_c; | c->pix_sum = pix_sum_c; | ||||
| c->pix_norm1 = pix_norm1_c; | c->pix_norm1 = pix_norm1_c; | ||||
| c->draw_edges = draw_edges_8_c; | |||||
| if (ARCH_ARM) | if (ARCH_ARM) | ||||
| ff_mpegvideoencdsp_init_arm(c, avctx); | ff_mpegvideoencdsp_init_arm(c, avctx); | ||||
| if (ARCH_PPC) | if (ARCH_PPC) | ||||
| @@ -26,6 +26,9 @@ | |||||
| #define BASIS_SHIFT 16 | #define BASIS_SHIFT 16 | ||||
| #define RECON_SHIFT 6 | #define RECON_SHIFT 6 | ||||
| #define EDGE_TOP 1 | |||||
| #define EDGE_BOTTOM 2 | |||||
| typedef struct MpegvideoEncDSPContext { | typedef struct MpegvideoEncDSPContext { | ||||
| int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], | int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], | ||||
| int16_t basis[64], int scale); | int16_t basis[64], int scale); | ||||
| @@ -36,6 +39,9 @@ typedef struct MpegvideoEncDSPContext { | |||||
| void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, | void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, | ||||
| int src_wrap, int width, int height); | int src_wrap, int width, int height); | ||||
| void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides); | |||||
| } MpegvideoEncDSPContext; | } MpegvideoEncDSPContext; | ||||
| void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, | void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, | ||||
| @@ -41,6 +41,7 @@ | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "dsputil.h" | #include "dsputil.h" | ||||
| #include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
| #include "mpegvideo.h" | |||||
| #include "thread.h" | #include "thread.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "bytestream.h" | #include "bytestream.h" | ||||
| @@ -51,7 +51,6 @@ OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp_init.o | |||||
| OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o | OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o | ||||
| MMX-OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp_mmx.o | MMX-OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp_mmx.o | ||||
| MMX-OBJS-$(CONFIG_DSPUTIL) += x86/dsputil_mmx.o | |||||
| MMX-OBJS-$(CONFIG_ENCODERS) += x86/fdct.o | MMX-OBJS-$(CONFIG_ENCODERS) += x86/fdct.o | ||||
| MMX-OBJS-$(CONFIG_HPELDSP) += x86/fpel_mmx.o \ | MMX-OBJS-$(CONFIG_HPELDSP) += x86/fpel_mmx.o \ | ||||
| x86/hpeldsp_mmx.o | x86/hpeldsp_mmx.o | ||||
| @@ -24,24 +24,9 @@ | |||||
| #include "libavcodec/dsputil.h" | #include "libavcodec/dsputil.h" | ||||
| #include "dsputil_x86.h" | #include "dsputil_x86.h" | ||||
| static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx, | |||||
| int cpu_flags, unsigned high_bit_depth) | |||||
| { | |||||
| #if HAVE_MMX_INLINE | |||||
| if (!high_bit_depth) { | |||||
| c->draw_edges = ff_draw_edges_mmx; | |||||
| } | |||||
| #endif /* HAVE_MMX_INLINE */ | |||||
| } | |||||
| av_cold void ff_dsputil_init_x86(DSPContext *c, AVCodecContext *avctx, | av_cold void ff_dsputil_init_x86(DSPContext *c, AVCodecContext *avctx, | ||||
| unsigned high_bit_depth) | unsigned high_bit_depth) | ||||
| { | { | ||||
| int cpu_flags = av_get_cpu_flags(); | |||||
| if (X86_MMX(cpu_flags)) | |||||
| dsputil_init_mmx(c, avctx, cpu_flags, high_bit_depth); | |||||
| if (CONFIG_ENCODERS) | if (CONFIG_ENCODERS) | ||||
| ff_dsputilenc_init_mmx(c, avctx, high_bit_depth); | ff_dsputilenc_init_mmx(c, avctx, high_bit_depth); | ||||
| } | } | ||||
| @@ -1,128 +0,0 @@ | |||||
| /* | |||||
| * MMX optimized DSP utils | |||||
| * Copyright (c) 2000, 2001 Fabrice Bellard | |||||
| * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> | |||||
| * | |||||
| * MMX optimization by Nick Kurshev <nickols_k@mail.ru> | |||||
| * | |||||
| * This file is part of Libav. | |||||
| * | |||||
| * Libav is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * | |||||
| * Libav is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with Libav; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #include "config.h" | |||||
| #include "libavutil/cpu.h" | |||||
| #include "libavutil/x86/asm.h" | |||||
| #include "dsputil_x86.h" | |||||
| #include "inline_asm.h" | |||||
| #if HAVE_INLINE_ASM | |||||
| /* Draw the edges of width 'w' of an image of size width, height | |||||
| * this MMX version can only handle w == 8 || w == 16. */ | |||||
| void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides) | |||||
| { | |||||
| uint8_t *ptr, *last_line; | |||||
| int i; | |||||
| last_line = buf + (height - 1) * wrap; | |||||
| /* left and right */ | |||||
| ptr = buf; | |||||
| if (w == 8) { | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movd (%0), %%mm0 \n\t" | |||||
| "punpcklbw %%mm0, %%mm0 \n\t" | |||||
| "punpcklwd %%mm0, %%mm0 \n\t" | |||||
| "punpckldq %%mm0, %%mm0 \n\t" | |||||
| "movq %%mm0, -8(%0) \n\t" | |||||
| "movq -8(%0, %2), %%mm1 \n\t" | |||||
| "punpckhbw %%mm1, %%mm1 \n\t" | |||||
| "punpckhwd %%mm1, %%mm1 \n\t" | |||||
| "punpckhdq %%mm1, %%mm1 \n\t" | |||||
| "movq %%mm1, (%0, %2) \n\t" | |||||
| "add %1, %0 \n\t" | |||||
| "cmp %3, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) wrap), "r" ((x86_reg) width), | |||||
| "r" (ptr + wrap * height)); | |||||
| } else { | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movd (%0), %%mm0 \n\t" | |||||
| "punpcklbw %%mm0, %%mm0 \n\t" | |||||
| "punpcklwd %%mm0, %%mm0 \n\t" | |||||
| "punpckldq %%mm0, %%mm0 \n\t" | |||||
| "movq %%mm0, -8(%0) \n\t" | |||||
| "movq %%mm0, -16(%0) \n\t" | |||||
| "movq -8(%0, %2), %%mm1 \n\t" | |||||
| "punpckhbw %%mm1, %%mm1 \n\t" | |||||
| "punpckhwd %%mm1, %%mm1 \n\t" | |||||
| "punpckhdq %%mm1, %%mm1 \n\t" | |||||
| "movq %%mm1, (%0, %2) \n\t" | |||||
| "movq %%mm1, 8(%0, %2) \n\t" | |||||
| "add %1, %0 \n\t" | |||||
| "cmp %3, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) wrap), "r" ((x86_reg) width), | |||||
| "r" (ptr + wrap * height)); | |||||
| } | |||||
| /* top and bottom (and hopefully also the corners) */ | |||||
| if (sides & EDGE_TOP) { | |||||
| for (i = 0; i < h; i += 4) { | |||||
| ptr = buf - (i + 1) * wrap - w; | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movq (%1, %0), %%mm0 \n\t" | |||||
| "movq %%mm0, (%0) \n\t" | |||||
| "movq %%mm0, (%0, %2) \n\t" | |||||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||||
| "movq %%mm0, (%0, %3) \n\t" | |||||
| "add $8, %0 \n\t" | |||||
| "cmp %4, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) buf - (x86_reg) ptr - w), | |||||
| "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3), | |||||
| "r" (ptr + width + 2 * w)); | |||||
| } | |||||
| } | |||||
| if (sides & EDGE_BOTTOM) { | |||||
| for (i = 0; i < h; i += 4) { | |||||
| ptr = last_line + (i + 1) * wrap - w; | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movq (%1, %0), %%mm0 \n\t" | |||||
| "movq %%mm0, (%0) \n\t" | |||||
| "movq %%mm0, (%0, %2) \n\t" | |||||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||||
| "movq %%mm0, (%0, %3) \n\t" | |||||
| "add $8, %0 \n\t" | |||||
| "cmp %4, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) last_line - (x86_reg) ptr - w), | |||||
| "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3), | |||||
| "r" (ptr + width + 2 * w)); | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif /* HAVE_INLINE_ASM */ | |||||
| @@ -31,7 +31,4 @@ void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx, | |||||
| unsigned high_bit_depth); | unsigned high_bit_depth); | ||||
| void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx); | void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx); | ||||
| void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides); | |||||
| #endif /* AVCODEC_X86_DSPUTIL_X86_H */ | #endif /* AVCODEC_X86_DSPUTIL_X86_H */ | ||||
| @@ -93,6 +93,101 @@ int ff_pix_norm1_mmx(uint8_t *pix, int line_size); | |||||
| #undef PHADDD | #undef PHADDD | ||||
| #endif /* HAVE_SSSE3_INLINE */ | #endif /* HAVE_SSSE3_INLINE */ | ||||
| /* Draw the edges of width 'w' of an image of size width, height | |||||
| * this MMX version can only handle w == 8 || w == 16. */ | |||||
| static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, | |||||
| int w, int h, int sides) | |||||
| { | |||||
| uint8_t *ptr, *last_line; | |||||
| int i; | |||||
| last_line = buf + (height - 1) * wrap; | |||||
| /* left and right */ | |||||
| ptr = buf; | |||||
| if (w == 8) { | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movd (%0), %%mm0 \n\t" | |||||
| "punpcklbw %%mm0, %%mm0 \n\t" | |||||
| "punpcklwd %%mm0, %%mm0 \n\t" | |||||
| "punpckldq %%mm0, %%mm0 \n\t" | |||||
| "movq %%mm0, -8(%0) \n\t" | |||||
| "movq -8(%0, %2), %%mm1 \n\t" | |||||
| "punpckhbw %%mm1, %%mm1 \n\t" | |||||
| "punpckhwd %%mm1, %%mm1 \n\t" | |||||
| "punpckhdq %%mm1, %%mm1 \n\t" | |||||
| "movq %%mm1, (%0, %2) \n\t" | |||||
| "add %1, %0 \n\t" | |||||
| "cmp %3, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) wrap), "r" ((x86_reg) width), | |||||
| "r" (ptr + wrap * height)); | |||||
| } else { | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movd (%0), %%mm0 \n\t" | |||||
| "punpcklbw %%mm0, %%mm0 \n\t" | |||||
| "punpcklwd %%mm0, %%mm0 \n\t" | |||||
| "punpckldq %%mm0, %%mm0 \n\t" | |||||
| "movq %%mm0, -8(%0) \n\t" | |||||
| "movq %%mm0, -16(%0) \n\t" | |||||
| "movq -8(%0, %2), %%mm1 \n\t" | |||||
| "punpckhbw %%mm1, %%mm1 \n\t" | |||||
| "punpckhwd %%mm1, %%mm1 \n\t" | |||||
| "punpckhdq %%mm1, %%mm1 \n\t" | |||||
| "movq %%mm1, (%0, %2) \n\t" | |||||
| "movq %%mm1, 8(%0, %2) \n\t" | |||||
| "add %1, %0 \n\t" | |||||
| "cmp %3, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) wrap), "r" ((x86_reg) width), | |||||
| "r" (ptr + wrap * height)); | |||||
| } | |||||
| /* top and bottom (and hopefully also the corners) */ | |||||
| if (sides & EDGE_TOP) { | |||||
| for (i = 0; i < h; i += 4) { | |||||
| ptr = buf - (i + 1) * wrap - w; | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movq (%1, %0), %%mm0 \n\t" | |||||
| "movq %%mm0, (%0) \n\t" | |||||
| "movq %%mm0, (%0, %2) \n\t" | |||||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||||
| "movq %%mm0, (%0, %3) \n\t" | |||||
| "add $8, %0 \n\t" | |||||
| "cmp %4, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) buf - (x86_reg) ptr - w), | |||||
| "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3), | |||||
| "r" (ptr + width + 2 * w)); | |||||
| } | |||||
| } | |||||
| if (sides & EDGE_BOTTOM) { | |||||
| for (i = 0; i < h; i += 4) { | |||||
| ptr = last_line + (i + 1) * wrap - w; | |||||
| __asm__ volatile ( | |||||
| "1: \n\t" | |||||
| "movq (%1, %0), %%mm0 \n\t" | |||||
| "movq %%mm0, (%0) \n\t" | |||||
| "movq %%mm0, (%0, %2) \n\t" | |||||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||||
| "movq %%mm0, (%0, %3) \n\t" | |||||
| "add $8, %0 \n\t" | |||||
| "cmp %4, %0 \n\t" | |||||
| "jb 1b \n\t" | |||||
| : "+r" (ptr) | |||||
| : "r" ((x86_reg) last_line - (x86_reg) ptr - w), | |||||
| "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3), | |||||
| "r" (ptr + width + 2 * w)); | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif /* HAVE_INLINE_ASM */ | #endif /* HAVE_INLINE_ASM */ | ||||
| av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, | av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, | ||||
| @@ -112,6 +207,10 @@ av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, | |||||
| c->try_8x8basis = try_8x8basis_mmx; | c->try_8x8basis = try_8x8basis_mmx; | ||||
| } | } | ||||
| c->add_8x8basis = add_8x8basis_mmx; | c->add_8x8basis = add_8x8basis_mmx; | ||||
| if (avctx->bits_per_raw_sample <= 8) { | |||||
| c->draw_edges = draw_edges_mmx; | |||||
| } | |||||
| } | } | ||||
| if (INLINE_AMD3DNOW(cpu_flags)) { | if (INLINE_AMD3DNOW(cpu_flags)) { | ||||