diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-01-31 01:14:58 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-01-31 02:46:26 +0100 |
commit | 151ecc2aecd81718e2520936dd3c537d7e6fe2fc (patch) | |
tree | d30c9048773a1138a4567fead3fd2c440db745bc /libavcodec | |
parent | b8c16558828e73e933ae73b5888345d50e897dfc (diff) | |
parent | d7edd359ec28142120eb7fde77b775309b6038d8 (diff) | |
download | ffmpeg-151ecc2aecd81718e2520936dd3c537d7e6fe2fc.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (26 commits)
avconv: deprecate the -deinterlace option
doc: Fix the name of the new function
aacenc: make sure to encode enough frames to cover all input samples.
aacenc: only use the number of input samples provided by the user.
wmadec: Verify bitstream size makes sense before calling init_get_bits.
kmvc: Log into a context at a log level constant.
mpeg12: Pad framerate tab to 16 entries.
kgv1dec: Increase offsets array size so it is large enough.
kmvc: Check palsize.
nsvdec: Propagate errors
nsvdec: Be more careful with av_malloc().
nsvdec: Fix use of uninitialized streams.
movenc: cosmetics: Get rid of camelCase identifiers
swscale: more generic check for planar destination formats with alpha
doc: Document mov/mp4 fragmentation options
build: Use order-only prerequisites for creating FATE reference file dirs.
x86 dsputil: provide SSE2/SSSE3 versions of bswap_buf
rtsp: Remove some unused variables from ff_rtsp_connect().
avutil: make intfloat api public
avformat_write_header(): detail error message
...
Conflicts:
doc/APIchanges
doc/ffmpeg.texi
doc/muxers.texi
ffmpeg.c
libavcodec/kmvc.c
libavcodec/x86/Makefile
libavcodec/x86/dsputil_yasm.asm
libavcodec/x86/pngdsp-init.c
libavformat/movenc.c
libavformat/movenc.h
libavformat/mpegtsenc.c
libavformat/nsvdec.c
libavformat/utils.c
libavutil/avutil.h
libswscale/swscale.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/aacenc.c | 24 | ||||
-rw-r--r-- | libavcodec/kmvc.c | 12 | ||||
-rw-r--r-- | libavcodec/mpc7.c | 2 | ||||
-rw-r--r-- | libavcodec/mpeg12data.c | 2 | ||||
-rw-r--r-- | libavcodec/wmadec.c | 2 | ||||
-rw-r--r-- | libavcodec/x86/Makefile | 1 | ||||
-rw-r--r-- | libavcodec/x86/dsputil_mmx.c | 5 | ||||
-rw-r--r-- | libavcodec/x86/dsputil_yasm.asm | 124 | ||||
-rw-r--r-- | libavcodec/x86/pngdsp-init.c | 123 | ||||
-rw-r--r-- | libavcodec/x86/pngdsp.asm | 174 |
10 files changed, 347 insertions, 122 deletions
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 2ff6f9cc04..51c2fa8662 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -223,8 +223,9 @@ WINDOW_FUNC(eight_short) const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; const float *in = audio + 448; float *out = sce->ret; + int w; - for (int w = 0; w < 8; w++) { + for (w = 0; w < 8; w++) { dsp->vector_fmul (out, in, w ? pwindow : swindow, 128); out += 128; in += 128; @@ -476,7 +477,7 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, * Channels are reordered from Libav's default order to AAC order. */ static void deinterleave_input_samples(AACEncContext *s, - const float *samples) + const float *samples, int nb_samples) { int ch, i; const int sinc = s->channels; @@ -490,10 +491,12 @@ static void deinterleave_input_samples(AACEncContext *s, memcpy(&s->planar_samples[ch][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0])); /* deinterleave */ - for (i = 2048; i < 3072; i++) { + for (i = 2048; i < 2048 + nb_samples; i++) { s->planar_samples[ch][i] = *sptr; sptr += sinc; } + memset(&s->planar_samples[ch][i], 0, + (3072 - i) * sizeof(s->planar_samples[0][0])); } } @@ -507,14 +510,12 @@ static int aac_encode_frame(AVCodecContext *avctx, int chan_el_counter[4]; FFPsyWindowInfo windows[AAC_MAX_CHANNELS]; - if (s->last_frame) + if (s->last_frame == 2) return 0; - if (data) { - deinterleave_input_samples(s, data); - if (s->psypp) - ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); - } + deinterleave_input_samples(s, data, data ? avctx->frame_size : 0); + if (s->psypp) + ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); if (!avctx->frame_number) return 0; @@ -645,7 +646,7 @@ static int aac_encode_frame(AVCodecContext *avctx, } if (!data) - s->last_frame = 1; + s->last_frame++; return put_bits_count(&s->pb)>>3; } @@ -686,11 +687,12 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s) { + int ch; FF_ALLOCZ_OR_GOTO(avctx, s->buffer.samples, 3 * 1024 * s->channels * sizeof(s->buffer.samples[0]), alloc_fail); FF_ALLOCZ_OR_GOTO(avctx, s->cpe, sizeof(ChannelElement) * s->chan_map[0], alloc_fail); FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + FF_INPUT_BUFFER_PADDING_SIZE, alloc_fail); - for(int ch = 0; ch < s->channels; ch++) + for(ch = 0; ch < s->channels; ch++) s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch; return 0; diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 9c98badbde..6d5af5d657 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -33,6 +33,7 @@ #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 #define KMVC_METHOD 0x0F +#define MAX_PALSIZE 256 /* * Decoder context @@ -43,7 +44,7 @@ typedef struct KmvcContext { int setpal; int palsize; - uint32_t pal[256]; + uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; uint8_t *frm0, *frm1; GetByteContext g; @@ -376,14 +377,15 @@ static av_cold int decode_init(AVCodecContext * avctx) } if (avctx->extradata_size < 12) { - av_log(NULL, 0, "Extradata missing, decoding may not work properly...\n"); + av_log(avctx, AV_LOG_WARNING, + "Extradata missing, decoding may not work properly...\n"); c->palsize = 127; } else { c->palsize = AV_RL16(avctx->extradata + 10); - if (c->palsize > 255U) { + if (c->palsize >= (unsigned)MAX_PALSIZE) { c->palsize = 127; - av_log(NULL, AV_LOG_ERROR, "palsize too big\n"); - return -1; + av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n"); + return AVERROR_INVALIDDATA; } } diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 0bde329e08..c60a621c65 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -53,7 +53,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) int i, j; MPCContext *c = avctx->priv_data; GetBitContext gb; - uint8_t buf[16]; + LOCAL_ALIGNED_16(uint8_t, buf, [16]); static int vlc_initialized = 0; static VLC_TYPE scfi_table[1 << MPC7_SCFI_BITS][2]; diff --git a/libavcodec/mpeg12data.c b/libavcodec/mpeg12data.c index c40883692b..309ec4efd6 100644 --- a/libavcodec/mpeg12data.c +++ b/libavcodec/mpeg12data.c @@ -305,7 +305,7 @@ const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = { { 0xc, 10 }, }; -const AVRational avpriv_frame_rate_tab[] = { +const AVRational avpriv_frame_rate_tab[16] = { { 0, 0}, {24000, 1001}, { 24, 1}, diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 0b2e49981d..7d7cc7f7bf 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -891,6 +891,8 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, /* read each frame starting from bit_offset */ pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; + if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8) + return AVERROR_INVALIDDATA; init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); len = pos & 7; if (len > 0) diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 5ba3942933..282bc916bd 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -48,6 +48,7 @@ MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o YASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o MMX-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp-init.o +YASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o MMX-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp-init.o YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o MMX-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp-init.o diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index ad29029528..4402995da5 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -2392,6 +2392,9 @@ void ff_apply_window_int16_ssse3 (int16_t *output, const int16_t *input, void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, const int16_t *window, unsigned int len); +void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w); +void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w); + void ff_add_hfyu_median_prediction_mmx2(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, int w, int left); int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, int w, int left); @@ -2880,6 +2883,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->apply_window_int16 = ff_apply_window_int16_sse2; } } + c->bswap_buf = ff_bswap32_buf_sse2; #endif } if (mm_flags & AV_CPU_FLAG_SSSE3) { @@ -2892,6 +2896,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) if (!(mm_flags & (AV_CPU_FLAG_SSE42|AV_CPU_FLAG_3DNOW))) { // cachesplit c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3; } + c->bswap_buf = ff_bswap32_buf_ssse3; #endif } diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm index 6c52ac1ffb..ad9ec2c339 100644 --- a/libavcodec/x86/dsputil_yasm.asm +++ b/libavcodec/x86/dsputil_yasm.asm @@ -30,6 +30,7 @@ pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13 pb_revwords: db 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1 pd_16384: times 4 dd 16384 +pb_bswap32: db 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 SECTION_TEXT @@ -1180,3 +1181,126 @@ BUTTERFLIES_FLOAT_INTERLEAVE INIT_YMM avx BUTTERFLIES_FLOAT_INTERLEAVE %endif + +INIT_XMM sse2 +; %1 = aligned/unaligned +%macro BSWAP_LOOPS_SSE2 1 + mov r3, r2 + sar r2, 3 + jz .left4_%1 +.loop8_%1: + mov%1 m0, [r1 + 0] + mov%1 m1, [r1 + 16] + pshuflw m0, m0, 10110001b + pshuflw m1, m1, 10110001b + pshufhw m0, m0, 10110001b + pshufhw m1, m1, 10110001b + mova m2, m0 + mova m3, m1 + psllw m0, 8 + psllw m1, 8 + psrlw m2, 8 + psrlw m3, 8 + por m2, m0 + por m3, m1 + mova [r0 + 0], m2 + mova [r0 + 16], m3 + add r1, 32 + add r0, 32 + dec r2 + jnz .loop8_%1 +.left4_%1: + mov r2, r3 + and r3, 4 + jz .left + mov%1 m0, [r1] + pshuflw m0, m0, 10110001b + pshufhw m0, m0, 10110001b + mova m2, m0 + psllw m0, 8 + psrlw m2, 8 + por m2, m0 + mova [r0], m2 + add r1, 16 + add r0, 16 +%endmacro + +; void bswap_buf(uint32_t *dst, const uint32_t *src, int w); +cglobal bswap32_buf, 3,4,5 + mov r3, r1 + and r3, 15 + jz .start_align + BSWAP_LOOPS_SSE2 u + jmp .left +.start_align: + BSWAP_LOOPS_SSE2 a +.left: + and r2, 3 + jz .end +.loop2: + mov r3d, [r1] + bswap r3d + mov [r0], r3d + add r1, 4 + add r0, 4 + dec r2 + jnz .loop2 +.end + RET + +; %1 = aligned/unaligned +%macro BSWAP_LOOPS_SSSE3 1 + mov r3, r2 + sar r2, 3 + jz .left4_%1 +.loop8_%1: + mov%1 m0, [r1 + 0] + mov%1 m1, [r1 + 16] + pshufb m0, m2 + pshufb m1, m2 + mova [r0 + 0], m0 + mova [r0 + 16], m1 + add r0, 32 + add r1, 32 + dec r2 + jnz .loop8_%1 +.left4_%1: + mov r2, r3 + and r3, 4 + jz .left2 + mov%1 m0, [r1] + pshufb m0, m2 + mova [r0], m0 + add r1, 16 + add r0, 16 +%endmacro + +INIT_XMM ssse3 +; void bswap_buf(uint32_t *dst, const uint32_t *src, int w); +cglobal bswap32_buf, 3,4,3 + mov r3, r1 + mova m2, [pb_bswap32] + and r3, 15 + jz .start_align + BSWAP_LOOPS_SSSE3 u + jmp .left2 +.start_align: + BSWAP_LOOPS_SSSE3 a +.left2: + mov r3, r2 + and r2, 2 + jz .left1 + movq m0, [r1] + pshufb m0, m2 + movq [r0], m0 + add r1, 8 + add r0, 8 +.left1: + and r3, 1 + jz .end + mov r2d, [r1] + bswap r2d + mov [r0], r2d +.end: + RET + diff --git a/libavcodec/x86/pngdsp-init.c b/libavcodec/x86/pngdsp-init.c index 089147c9e4..f122b242fb 100644 --- a/libavcodec/x86/pngdsp-init.c +++ b/libavcodec/x86/pngdsp-init.c @@ -19,118 +19,33 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/common.h" #include "libavutil/cpu.h" -#include "libavutil/x86_cpu.h" #include "libavcodec/pngdsp.h" -#include "dsputil_mmx.h" -#define PAETH(cpu, abs3)\ -static void add_png_paeth_prediction_##cpu(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)\ -{\ - x86_reg i, end;\ - if(bpp>4) add_png_paeth_prediction_##cpu(dst+bpp/2, src+bpp/2, top+bpp/2, w-bpp/2, -bpp);\ - if(bpp<0) bpp=-bpp;\ - i= -bpp;\ - end = w-3;\ - __asm__ volatile(\ - "pxor %%mm7, %%mm7 \n"\ - "movd (%1,%0), %%mm0 \n"\ - "movd (%2,%0), %%mm1 \n"\ - "punpcklbw %%mm7, %%mm0 \n"\ - "punpcklbw %%mm7, %%mm1 \n"\ - "add %4, %0 \n"\ - "1: \n"\ - "movq %%mm1, %%mm2 \n"\ - "movd (%2,%0), %%mm1 \n"\ - "movq %%mm2, %%mm3 \n"\ - "punpcklbw %%mm7, %%mm1 \n"\ - "movq %%mm2, %%mm4 \n"\ - "psubw %%mm1, %%mm3 \n"\ - "psubw %%mm0, %%mm4 \n"\ - "movq %%mm3, %%mm5 \n"\ - "paddw %%mm4, %%mm5 \n"\ - abs3\ - "movq %%mm4, %%mm6 \n"\ - "pminsw %%mm5, %%mm6 \n"\ - "pcmpgtw %%mm6, %%mm3 \n"\ - "pcmpgtw %%mm5, %%mm4 \n"\ - "movq %%mm4, %%mm6 \n"\ - "pand %%mm3, %%mm4 \n"\ - "pandn %%mm3, %%mm6 \n"\ - "pandn %%mm0, %%mm3 \n"\ - "movd (%3,%0), %%mm0 \n"\ - "pand %%mm1, %%mm6 \n"\ - "pand %%mm4, %%mm2 \n"\ - "punpcklbw %%mm7, %%mm0 \n"\ - "paddw %%mm6, %%mm0 \n"\ - "paddw %%mm2, %%mm3 \n"\ - "paddw %%mm3, %%mm0 \n"\ - "pand %6 , %%mm0 \n"\ - "movq %%mm0, %%mm3 \n"\ - "packuswb %%mm3, %%mm3 \n"\ - "movd %%mm3, (%1,%0) \n"\ - "add %4, %0 \n"\ - "cmp %5, %0 \n"\ - "jle 1b \n"\ - :"+r"(i)\ - :"r"(dst), "r"(top), "r"(src), "r"((x86_reg)bpp), "g"(end),\ - "m"(ff_pw_255)\ - :"memory"\ - );\ -} - -#define ABS3_MMX2\ - "psubw %%mm5, %%mm7 \n"\ - "pmaxsw %%mm7, %%mm5 \n"\ - "pxor %%mm6, %%mm6 \n"\ - "pxor %%mm7, %%mm7 \n"\ - "psubw %%mm3, %%mm6 \n"\ - "psubw %%mm4, %%mm7 \n"\ - "pmaxsw %%mm6, %%mm3 \n"\ - "pmaxsw %%mm7, %%mm4 \n"\ - "pxor %%mm7, %%mm7 \n" - -#define ABS3_SSSE3\ - "pabsw %%mm3, %%mm3 \n"\ - "pabsw %%mm4, %%mm4 \n"\ - "pabsw %%mm5, %%mm5 \n" - -PAETH(mmx2, ABS3_MMX2) -#if HAVE_SSSE3 -PAETH(ssse3, ABS3_SSSE3) -#endif - -static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) -{ - x86_reg i=0; - __asm__ volatile( - "jmp 2f \n\t" - "1: \n\t" - "movq (%2, %0), %%mm0 \n\t" - "movq 8(%2, %0), %%mm1 \n\t" - "paddb (%3, %0), %%mm0 \n\t" - "paddb 8(%3, %0), %%mm1 \n\t" - "movq %%mm0, (%1, %0) \n\t" - "movq %%mm1, 8(%1, %0) \n\t" - "add $16, %0 \n\t" - "2: \n\t" - "cmp %4, %0 \n\t" - " js 1b \n\t" - : "+r" (i) - : "r"(dst), "r"(src1), "r"(src2), "r"((x86_reg) w - 15) - ); - for (; i < w; i++) - dst[i] = src1[i] + src2[i]; -} +void ff_add_png_paeth_prediction_mmx2 (uint8_t *dst, uint8_t *src, + uint8_t *top, int w, int bpp); +void ff_add_png_paeth_prediction_ssse3(uint8_t *dst, uint8_t *src, + uint8_t *top, int w, int bpp); +void ff_add_bytes_l2_mmx (uint8_t *dst, uint8_t *src1, + uint8_t *src2, int w); +void ff_add_bytes_l2_sse2(uint8_t *dst, uint8_t *src1, + uint8_t *src2, int w); void ff_pngdsp_init_x86(PNGDSPContext *dsp) { +#if HAVE_YASM int flags = av_get_cpu_flags(); +#if ARCH_X86_32 if (flags & AV_CPU_FLAG_MMX) - dsp->add_bytes_l2 = add_bytes_l2_mmx; + dsp->add_bytes_l2 = ff_add_bytes_l2_mmx; +#endif if (flags & AV_CPU_FLAG_MMX2) - dsp->add_paeth_prediction = add_png_paeth_prediction_mmx2; - if (HAVE_SSSE3 && flags & AV_CPU_FLAG_SSSE3) - dsp->add_paeth_prediction = add_png_paeth_prediction_ssse3; + dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmx2; + if (flags & AV_CPU_FLAG_SSE2) + dsp->add_bytes_l2 = ff_add_bytes_l2_sse2; + if (flags & AV_CPU_FLAG_SSSE3) + dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3; +#endif } diff --git a/libavcodec/x86/pngdsp.asm b/libavcodec/x86/pngdsp.asm new file mode 100644 index 0000000000..8c4cb19da0 --- /dev/null +++ b/libavcodec/x86/pngdsp.asm @@ -0,0 +1,174 @@ +;****************************************************************************** +;* x86 optimizations for PNG decoding +;* +;* Copyright (c) 2008 Loren Merritt <lorenm@u.washington.edu> +;* Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com> +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86inc.asm" +%include "x86util.asm" + +SECTION_RODATA + +cextern pw_255 + +section .text align=16 + +; %1 = nr. of xmm registers used +%macro ADD_BYTES_FN 1 +cglobal add_bytes_l2, 4, 6, %1, dst, src1, src2, wa, w, i +%if ARCH_X86_64 + movsxd waq, wad +%endif + xor iq, iq + + ; vector loop + mov wq, waq + and waq, ~(mmsize*2-1) + jmp .end_v +.loop_v: + mova m0, [src1q+iq] + mova m1, [src1q+iq+mmsize] + paddb m0, [src2q+iq] + paddb m1, [src2q+iq+mmsize] + mova [dstq+iq ], m0 + mova [dstq+iq+mmsize], m1 + add iq, mmsize*2 +.end_v: + cmp iq, waq + jl .loop_v + +%if mmsize == 16 + ; vector loop + mov wq, waq + and waq, ~7 + jmp .end_l +.loop_l: + movq mm0, [src1q+iq] + paddb mm0, [src2q+iq] + movq [dstq+iq ], mm0 + add iq, 8 +.end_l: + cmp iq, waq + jl .loop_l +%endif + + ; scalar loop for leftover + jmp .end_s +.loop_s: + mov wab, [src1q+iq] + add wab, [src2q+iq] + mov [dstq+iq], wab + inc iq +.end_s: + cmp iq, wq + jl .loop_s + REP_RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +ADD_BYTES_FN 0 +%endif + +INIT_XMM sse2 +ADD_BYTES_FN 2 + +%macro ADD_PAETH_PRED_FN 1 +cglobal add_png_paeth_prediction, 5, 7, %1, dst, src, top, w, bpp, end, cntr +%if ARCH_X86_64 + movsxd bppq, bppd + movsxd wq, wd +%endif + lea endq, [dstq+wq-(mmsize/2-1)] + sub topq, dstq + sub srcq, dstq + sub dstq, bppq + pxor m7, m7 + + PUSH dstq + lea cntrq, [bppq-1] + shr cntrq, 2 + mmsize/16 +.bpp_loop: + lea dstq, [dstq+cntrq*(mmsize/2)] + movh m0, [dstq] + movh m1, [topq+dstq] + punpcklbw m0, m7 + punpcklbw m1, m7 + add dstq, bppq +.loop: + mova m2, m1 + movh m1, [topq+dstq] + mova m3, m2 + punpcklbw m1, m7 + mova m4, m2 + psubw m3, m1 + psubw m4, m0 + mova m5, m3 + paddw m5, m4 +%if cpuflag(ssse3) + pabsw m3, m3 + pabsw m4, m4 + pabsw m5, m5 +%else ; !cpuflag(ssse3) + psubw m7, m5 + pmaxsw m5, m7 + pxor m6, m6 + pxor m7, m7 + psubw m6, m3 + psubw m7, m4 + pmaxsw m3, m6 + pmaxsw m4, m7 + pxor m7, m7 +%endif ; cpuflag(ssse3) + mova m6, m4 + pminsw m6, m5 + pcmpgtw m3, m6 + pcmpgtw m4, m5 + mova m6, m4 + pand m4, m3 + pandn m6, m3 + pandn m3, m0 + movh m0, [srcq+dstq] + pand m6, m1 + pand m2, m4 + punpcklbw m0, m7 + paddw m0, m6 + paddw m3, m2 + paddw m0, m3 + pand m0, [pw_255] + mova m3, m0 + packuswb m3, m3 + movh [dstq], m3 + add dstq, bppq + cmp dstq, endq + jle .loop + + mov dstq, [rsp] + dec cntrq + jge .bpp_loop + POP dstq + RET +%endmacro + +INIT_MMX mmx2 +ADD_PAETH_PRED_FN 0 + +INIT_MMX ssse3 +ADD_PAETH_PRED_FN 0 |