mpegvideo_mmx.c
资源名称:tcpmp.rar [点击查看]
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:22k
源码类别:
Windows CE
开发平台:
C/C++
- /*
- * The simplest mpeg encoder (well, it was the simplest!)
- * Copyright (c) 2000,2001 Fabrice Bellard.
- *
- * This library 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 of the License, or (at your option) any later version.
- *
- * This library 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 this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Optimized for ia32 cpus by Nick Kurshev <nickols_k@mail.ru>
- * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer <michaelni@gmx.at>
- */
- #include "../dsputil.h"
- #include "../mpegvideo.h"
- #include "../avcodec.h"
- #include "mmx.h"
- extern uint8_t zigzag_direct_noperm[64];
- extern uint16_t inv_zigzag_direct16[64];
- static const unsigned long long int mm_wabs __attribute__ ((aligned(8))) = 0xffffffffffffffffULL;
- static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001ULL;
- static void dct_unquantize_h263_intra_mmx(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
- {
- long level, qmul, qadd, nCoeffs;
- qmul = qscale << 1;
- assert(s->block_last_index[n]>=0 || s->h263_aic);
- if (!s->h263_aic) {
- if (n < 4)
- level = block[0] * s->y_dc_scale;
- else
- level = block[0] * s->c_dc_scale;
- qadd = (qscale - 1) | 1;
- }else{
- qadd = 0;
- level= block[0];
- }
- if(s->ac_pred)
- nCoeffs=63;
- else
- nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
- //printf("%d %d ", qmul, qadd);
- asm volatile(
- "movd %1, %%mm6 nt" //qmul
- "packssdw %%mm6, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "movd %2, %%mm5 nt" //qadd
- "pxor %%mm7, %%mm7 nt"
- "packssdw %%mm5, %%mm5 nt"
- "packssdw %%mm5, %%mm5 nt"
- "psubw %%mm5, %%mm7 nt"
- "pxor %%mm4, %%mm4 nt"
- ".balign 16nt"
- "1: nt"
- "movq (%0, %3), %%mm0 nt"
- "movq 8(%0, %3), %%mm1 nt"
- "pmullw %%mm6, %%mm0 nt"
- "pmullw %%mm6, %%mm1 nt"
- "movq (%0, %3), %%mm2 nt"
- "movq 8(%0, %3), %%mm3 nt"
- "pcmpgtw %%mm4, %%mm2 nt" // block[i] < 0 ? -1 : 0
- "pcmpgtw %%mm4, %%mm3 nt" // block[i] < 0 ? -1 : 0
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "paddw %%mm7, %%mm0 nt"
- "paddw %%mm7, %%mm1 nt"
- "pxor %%mm0, %%mm2 nt"
- "pxor %%mm1, %%mm3 nt"
- "pcmpeqw %%mm7, %%mm0 nt" // block[i] == 0 ? -1 : 0
- "pcmpeqw %%mm7, %%mm1 nt" // block[i] == 0 ? -1 : 0
- "pandn %%mm2, %%mm0 nt"
- "pandn %%mm3, %%mm1 nt"
- "movq %%mm0, (%0, %3) nt"
- "movq %%mm1, 8(%0, %3) nt"
- "add $16, %3 nt"
- "jng 1b nt"
- ::"r" (block+nCoeffs), "g"(qmul), "g" (qadd), "r" (2*(-nCoeffs))
- : "memory"
- );
- block[0]= level;
- }
- static void dct_unquantize_h263_inter_mmx(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
- {
- long qmul, qadd, nCoeffs;
- qmul = qscale << 1;
- qadd = (qscale - 1) | 1;
- assert(s->block_last_index[n]>=0 || s->h263_aic);
- nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
- //printf("%d %d ", qmul, qadd);
- asm volatile(
- "movd %1, %%mm6 nt" //qmul
- "packssdw %%mm6, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "movd %2, %%mm5 nt" //qadd
- "pxor %%mm7, %%mm7 nt"
- "packssdw %%mm5, %%mm5 nt"
- "packssdw %%mm5, %%mm5 nt"
- "psubw %%mm5, %%mm7 nt"
- "pxor %%mm4, %%mm4 nt"
- ".balign 16nt"
- "1: nt"
- "movq (%0, %3), %%mm0 nt"
- "movq 8(%0, %3), %%mm1 nt"
- "pmullw %%mm6, %%mm0 nt"
- "pmullw %%mm6, %%mm1 nt"
- "movq (%0, %3), %%mm2 nt"
- "movq 8(%0, %3), %%mm3 nt"
- "pcmpgtw %%mm4, %%mm2 nt" // block[i] < 0 ? -1 : 0
- "pcmpgtw %%mm4, %%mm3 nt" // block[i] < 0 ? -1 : 0
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "paddw %%mm7, %%mm0 nt"
- "paddw %%mm7, %%mm1 nt"
- "pxor %%mm0, %%mm2 nt"
- "pxor %%mm1, %%mm3 nt"
- "pcmpeqw %%mm7, %%mm0 nt" // block[i] == 0 ? -1 : 0
- "pcmpeqw %%mm7, %%mm1 nt" // block[i] == 0 ? -1 : 0
- "pandn %%mm2, %%mm0 nt"
- "pandn %%mm3, %%mm1 nt"
- "movq %%mm0, (%0, %3) nt"
- "movq %%mm1, 8(%0, %3) nt"
- "add $16, %3 nt"
- "jng 1b nt"
- ::"r" (block+nCoeffs), "g"(qmul), "g" (qadd), "r" (2*(-nCoeffs))
- : "memory"
- );
- }
- /*
- NK:
- Note: looking at PARANOID:
- "enable all paranoid tests for rounding, overflows, etc..."
- #ifdef PARANOID
- if (level < -2048 || level > 2047)
- fprintf(stderr, "unquant error %d %dn", i, level);
- #endif
- We can suppose that result of two multiplications can't be greate of 0xFFFF
- i.e. is 16-bit, so we use here only PMULLW instruction and can avoid
- a complex multiplication.
- =====================================================
- Full formula for multiplication of 2 integer numbers
- which are represent as high:low words:
- input: value1 = high1:low1
- value2 = high2:low2
- output: value3 = value1*value2
- value3=high3:low3 (on overflow: modulus 2^32 wrap-around)
- this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4
- but this algorithm will compute only 0x66cb0ce4
- this limited by 16-bit size of operands
- ---------------------------------
- tlow1 = high1*low2
- tlow2 = high2*low1
- tlow1 = tlow1 + tlow2
- high3:low3 = low1*low2
- high3 += tlow1
- */
- static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
- {
- long nCoeffs;
- const uint16_t *quant_matrix;
- int block0;
- assert(s->block_last_index[n]>=0);
- nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1;
- if (n < 4)
- block0 = block[0] * s->y_dc_scale;
- else
- block0 = block[0] * s->c_dc_scale;
- /* XXX: only mpeg1 */
- quant_matrix = s->intra_matrix;
- asm volatile(
- "pcmpeqw %%mm7, %%mm7 nt"
- "psrlw $15, %%mm7 nt"
- "movd %2, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "mov %3, %%"REG_a" nt"
- ".balign 16nt"
- "1: nt"
- "movq (%0, %%"REG_a"), %%mm0 nt"
- "movq 8(%0, %%"REG_a"), %%mm1 nt"
- "movq (%1, %%"REG_a"), %%mm4 nt"
- "movq 8(%1, %%"REG_a"), %%mm5 nt"
- "pmullw %%mm6, %%mm4 nt" // q=qscale*quant_matrix[i]
- "pmullw %%mm6, %%mm5 nt" // q=qscale*quant_matrix[i]
- "pxor %%mm2, %%mm2 nt"
- "pxor %%mm3, %%mm3 nt"
- "pcmpgtw %%mm0, %%mm2 nt" // block[i] < 0 ? -1 : 0
- "pcmpgtw %%mm1, %%mm3 nt" // block[i] < 0 ? -1 : 0
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt" // abs(block[i])
- "psubw %%mm3, %%mm1 nt" // abs(block[i])
- "pmullw %%mm4, %%mm0 nt" // abs(block[i])*q
- "pmullw %%mm5, %%mm1 nt" // abs(block[i])*q
- "pxor %%mm4, %%mm4 nt"
- "pxor %%mm5, %%mm5 nt" // FIXME slow
- "pcmpeqw (%0, %%"REG_a"), %%mm4 nt" // block[i] == 0 ? -1 : 0
- "pcmpeqw 8(%0, %%"REG_a"), %%mm5nt" // block[i] == 0 ? -1 : 0
- "psraw $3, %%mm0 nt"
- "psraw $3, %%mm1 nt"
- "psubw %%mm7, %%mm0 nt"
- "psubw %%mm7, %%mm1 nt"
- "por %%mm7, %%mm0 nt"
- "por %%mm7, %%mm1 nt"
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt"
- "psubw %%mm3, %%mm1 nt"
- "pandn %%mm0, %%mm4 nt"
- "pandn %%mm1, %%mm5 nt"
- "movq %%mm4, (%0, %%"REG_a") nt"
- "movq %%mm5, 8(%0, %%"REG_a") nt"
- "add $16, %%"REG_a" nt"
- "js 1b nt"
- ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)
- : "%"REG_a, "memory"
- );
- block[0]= block0;
- }
- static void dct_unquantize_mpeg1_inter_mmx(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
- {
- long nCoeffs;
- const uint16_t *quant_matrix;
- assert(s->block_last_index[n]>=0);
- nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1;
- quant_matrix = s->inter_matrix;
- asm volatile(
- "pcmpeqw %%mm7, %%mm7 nt"
- "psrlw $15, %%mm7 nt"
- "movd %2, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "mov %3, %%"REG_a" nt"
- ".balign 16nt"
- "1: nt"
- "movq (%0, %%"REG_a"), %%mm0 nt"
- "movq 8(%0, %%"REG_a"), %%mm1 nt"
- "movq (%1, %%"REG_a"), %%mm4 nt"
- "movq 8(%1, %%"REG_a"), %%mm5 nt"
- "pmullw %%mm6, %%mm4 nt" // q=qscale*quant_matrix[i]
- "pmullw %%mm6, %%mm5 nt" // q=qscale*quant_matrix[i]
- "pxor %%mm2, %%mm2 nt"
- "pxor %%mm3, %%mm3 nt"
- "pcmpgtw %%mm0, %%mm2 nt" // block[i] < 0 ? -1 : 0
- "pcmpgtw %%mm1, %%mm3 nt" // block[i] < 0 ? -1 : 0
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt" // abs(block[i])
- "psubw %%mm3, %%mm1 nt" // abs(block[i])
- "paddw %%mm0, %%mm0 nt" // abs(block[i])*2
- "paddw %%mm1, %%mm1 nt" // abs(block[i])*2
- "paddw %%mm7, %%mm0 nt" // abs(block[i])*2 + 1
- "paddw %%mm7, %%mm1 nt" // abs(block[i])*2 + 1
- "pmullw %%mm4, %%mm0 nt" // (abs(block[i])*2 + 1)*q
- "pmullw %%mm5, %%mm1 nt" // (abs(block[i])*2 + 1)*q
- "pxor %%mm4, %%mm4 nt"
- "pxor %%mm5, %%mm5 nt" // FIXME slow
- "pcmpeqw (%0, %%"REG_a"), %%mm4 nt" // block[i] == 0 ? -1 : 0
- "pcmpeqw 8(%0, %%"REG_a"), %%mm5nt" // block[i] == 0 ? -1 : 0
- "psraw $4, %%mm0 nt"
- "psraw $4, %%mm1 nt"
- "psubw %%mm7, %%mm0 nt"
- "psubw %%mm7, %%mm1 nt"
- "por %%mm7, %%mm0 nt"
- "por %%mm7, %%mm1 nt"
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt"
- "psubw %%mm3, %%mm1 nt"
- "pandn %%mm0, %%mm4 nt"
- "pandn %%mm1, %%mm5 nt"
- "movq %%mm4, (%0, %%"REG_a") nt"
- "movq %%mm5, 8(%0, %%"REG_a") nt"
- "add $16, %%"REG_a" nt"
- "js 1b nt"
- ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)
- : "%"REG_a, "memory"
- );
- }
- static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
- {
- long nCoeffs;
- const uint16_t *quant_matrix;
- int block0;
- assert(s->block_last_index[n]>=0);
- if(s->alternate_scan) nCoeffs= 63; //FIXME
- else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
- if (n < 4)
- block0 = block[0] * s->y_dc_scale;
- else
- block0 = block[0] * s->c_dc_scale;
- quant_matrix = s->intra_matrix;
- asm volatile(
- "pcmpeqw %%mm7, %%mm7 nt"
- "psrlw $15, %%mm7 nt"
- "movd %2, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "mov %3, %%"REG_a" nt"
- ".balign 16nt"
- "1: nt"
- "movq (%0, %%"REG_a"), %%mm0 nt"
- "movq 8(%0, %%"REG_a"), %%mm1 nt"
- "movq (%1, %%"REG_a"), %%mm4 nt"
- "movq 8(%1, %%"REG_a"), %%mm5 nt"
- "pmullw %%mm6, %%mm4 nt" // q=qscale*quant_matrix[i]
- "pmullw %%mm6, %%mm5 nt" // q=qscale*quant_matrix[i]
- "pxor %%mm2, %%mm2 nt"
- "pxor %%mm3, %%mm3 nt"
- "pcmpgtw %%mm0, %%mm2 nt" // block[i] < 0 ? -1 : 0
- "pcmpgtw %%mm1, %%mm3 nt" // block[i] < 0 ? -1 : 0
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt" // abs(block[i])
- "psubw %%mm3, %%mm1 nt" // abs(block[i])
- "pmullw %%mm4, %%mm0 nt" // abs(block[i])*q
- "pmullw %%mm5, %%mm1 nt" // abs(block[i])*q
- "pxor %%mm4, %%mm4 nt"
- "pxor %%mm5, %%mm5 nt" // FIXME slow
- "pcmpeqw (%0, %%"REG_a"), %%mm4 nt" // block[i] == 0 ? -1 : 0
- "pcmpeqw 8(%0, %%"REG_a"), %%mm5nt" // block[i] == 0 ? -1 : 0
- "psraw $3, %%mm0 nt"
- "psraw $3, %%mm1 nt"
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt"
- "psubw %%mm3, %%mm1 nt"
- "pandn %%mm0, %%mm4 nt"
- "pandn %%mm1, %%mm5 nt"
- "movq %%mm4, (%0, %%"REG_a") nt"
- "movq %%mm5, 8(%0, %%"REG_a") nt"
- "add $16, %%"REG_a" nt"
- "jng 1b nt"
- ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)
- : "%"REG_a, "memory"
- );
- block[0]= block0;
- //Note, we dont do mismatch control for intra as errors cannot accumulate
- }
- static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
- {
- long nCoeffs;
- const uint16_t *quant_matrix;
- assert(s->block_last_index[n]>=0);
- if(s->alternate_scan) nCoeffs= 63; //FIXME
- else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
- quant_matrix = s->inter_matrix;
- asm volatile(
- "pcmpeqw %%mm7, %%mm7 nt"
- "psrlq $48, %%mm7 nt"
- "movd %2, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "packssdw %%mm6, %%mm6 nt"
- "mov %3, %%"REG_a" nt"
- ".balign 16nt"
- "1: nt"
- "movq (%0, %%"REG_a"), %%mm0 nt"
- "movq 8(%0, %%"REG_a"), %%mm1 nt"
- "movq (%1, %%"REG_a"), %%mm4 nt"
- "movq 8(%1, %%"REG_a"), %%mm5 nt"
- "pmullw %%mm6, %%mm4 nt" // q=qscale*quant_matrix[i]
- "pmullw %%mm6, %%mm5 nt" // q=qscale*quant_matrix[i]
- "pxor %%mm2, %%mm2 nt"
- "pxor %%mm3, %%mm3 nt"
- "pcmpgtw %%mm0, %%mm2 nt" // block[i] < 0 ? -1 : 0
- "pcmpgtw %%mm1, %%mm3 nt" // block[i] < 0 ? -1 : 0
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt" // abs(block[i])
- "psubw %%mm3, %%mm1 nt" // abs(block[i])
- "paddw %%mm0, %%mm0 nt" // abs(block[i])*2
- "paddw %%mm1, %%mm1 nt" // abs(block[i])*2
- "pmullw %%mm4, %%mm0 nt" // abs(block[i])*2*q
- "pmullw %%mm5, %%mm1 nt" // abs(block[i])*2*q
- "paddw %%mm4, %%mm0 nt" // (abs(block[i])*2 + 1)*q
- "paddw %%mm5, %%mm1 nt" // (abs(block[i])*2 + 1)*q
- "pxor %%mm4, %%mm4 nt"
- "pxor %%mm5, %%mm5 nt" // FIXME slow
- "pcmpeqw (%0, %%"REG_a"), %%mm4 nt" // block[i] == 0 ? -1 : 0
- "pcmpeqw 8(%0, %%"REG_a"), %%mm5nt" // block[i] == 0 ? -1 : 0
- "psrlw $4, %%mm0 nt"
- "psrlw $4, %%mm1 nt"
- "pxor %%mm2, %%mm0 nt"
- "pxor %%mm3, %%mm1 nt"
- "psubw %%mm2, %%mm0 nt"
- "psubw %%mm3, %%mm1 nt"
- "pandn %%mm0, %%mm4 nt"
- "pandn %%mm1, %%mm5 nt"
- "pxor %%mm4, %%mm7 nt"
- "pxor %%mm5, %%mm7 nt"
- "movq %%mm4, (%0, %%"REG_a") nt"
- "movq %%mm5, 8(%0, %%"REG_a") nt"
- "add $16, %%"REG_a" nt"
- "jng 1b nt"
- "movd 124(%0, %3), %%mm0 nt"
- "movq %%mm7, %%mm6 nt"
- "psrlq $32, %%mm7 nt"
- "pxor %%mm6, %%mm7 nt"
- "movq %%mm7, %%mm6 nt"
- "psrlq $16, %%mm7 nt"
- "pxor %%mm6, %%mm7 nt"
- "pslld $31, %%mm7 nt"
- "psrlq $15, %%mm7 nt"
- "pxor %%mm7, %%mm0 nt"
- "movd %%mm0, 124(%0, %3) nt"
- ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "r" (-2*nCoeffs)
- : "%"REG_a, "memory"
- );
- }
- /* 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)
- {
- uint8_t *ptr, *last_line;
- int i;
- last_line = buf + (height - 1) * wrap;
- /* left and right */
- ptr = buf;
- if(w==8)
- {
- asm volatile(
- "1: nt"
- "movd (%0), %%mm0 nt"
- "punpcklbw %%mm0, %%mm0 nt"
- "punpcklwd %%mm0, %%mm0 nt"
- "punpckldq %%mm0, %%mm0 nt"
- "movq %%mm0, -8(%0) nt"
- "movq -8(%0, %2), %%mm1 nt"
- "punpckhbw %%mm1, %%mm1 nt"
- "punpckhwd %%mm1, %%mm1 nt"
- "punpckhdq %%mm1, %%mm1 nt"
- "movq %%mm1, (%0, %2) nt"
- "add %1, %0 nt"
- "cmp %3, %0 nt"
- " jb 1b nt"
- : "+r" (ptr)
- : "r" ((long)wrap), "r" ((long)width), "r" (ptr + wrap*height)
- );
- }
- else
- {
- asm volatile(
- "1: nt"
- "movd (%0), %%mm0 nt"
- "punpcklbw %%mm0, %%mm0 nt"
- "punpcklwd %%mm0, %%mm0 nt"
- "punpckldq %%mm0, %%mm0 nt"
- "movq %%mm0, -8(%0) nt"
- "movq %%mm0, -16(%0) nt"
- "movq -8(%0, %2), %%mm1 nt"
- "punpckhbw %%mm1, %%mm1 nt"
- "punpckhwd %%mm1, %%mm1 nt"
- "punpckhdq %%mm1, %%mm1 nt"
- "movq %%mm1, (%0, %2) nt"
- "movq %%mm1, 8(%0, %2) nt"
- "add %1, %0 nt"
- "cmp %3, %0 nt"
- " jb 1b nt"
- : "+r" (ptr)
- : "r" ((long)wrap), "r" ((long)width), "r" (ptr + wrap*height)
- );
- }
- for(i=0;i<w;i+=4) {
- /* top and bottom (and hopefully also the corners) */
- ptr= buf - (i + 1) * wrap - w;
- asm volatile(
- "1: nt"
- "movq (%1, %0), %%mm0 nt"
- "movq %%mm0, (%0) nt"
- "movq %%mm0, (%0, %2) nt"
- "movq %%mm0, (%0, %2, 2) nt"
- "movq %%mm0, (%0, %3) nt"
- "add $8, %0 nt"
- "cmp %4, %0 nt"
- " jb 1b nt"
- : "+r" (ptr)
- : "r" ((long)buf - (long)ptr - w), "r" ((long)-wrap), "r" ((long)-wrap*3), "r" (ptr+width+2*w)
- );
- ptr= last_line + (i + 1) * wrap - w;
- asm volatile(
- "1: nt"
- "movq (%1, %0), %%mm0 nt"
- "movq %%mm0, (%0) nt"
- "movq %%mm0, (%0, %2) nt"
- "movq %%mm0, (%0, %2, 2) nt"
- "movq %%mm0, (%0, %3) nt"
- "add $8, %0 nt"
- "cmp %4, %0 nt"
- " jb 1b nt"
- : "+r" (ptr)
- : "r" ((long)last_line - (long)ptr - w), "r" ((long)wrap), "r" ((long)wrap*3), "r" (ptr+width+2*w)
- );
- }
- }
- static void denoise_dct_mmx(MpegEncContext *s, DCTELEM *block){
- const int intra= s->mb_intra;
- int *sum= s->dct_error_sum[intra];
- uint16_t *offset= s->dct_offset[intra];
- s->dct_count[intra]++;
- asm volatile(
- "pxor %%mm7, %%mm7 nt"
- "1: nt"
- "pxor %%mm0, %%mm0 nt"
- "pxor %%mm1, %%mm1 nt"
- "movq (%0), %%mm2 nt"
- "movq 8(%0), %%mm3 nt"
- "pcmpgtw %%mm2, %%mm0 nt"
- "pcmpgtw %%mm3, %%mm1 nt"
- "pxor %%mm0, %%mm2 nt"
- "pxor %%mm1, %%mm3 nt"
- "psubw %%mm0, %%mm2 nt"
- "psubw %%mm1, %%mm3 nt"
- "movq %%mm2, %%mm4 nt"
- "movq %%mm3, %%mm5 nt"
- "psubusw (%2), %%mm2 nt"
- "psubusw 8(%2), %%mm3 nt"
- "pxor %%mm0, %%mm2 nt"
- "pxor %%mm1, %%mm3 nt"
- "psubw %%mm0, %%mm2 nt"
- "psubw %%mm1, %%mm3 nt"
- "movq %%mm2, (%0) nt"
- "movq %%mm3, 8(%0) nt"
- "movq %%mm4, %%mm2 nt"
- "movq %%mm5, %%mm3 nt"
- "punpcklwd %%mm7, %%mm4 nt"
- "punpckhwd %%mm7, %%mm2 nt"
- "punpcklwd %%mm7, %%mm5 nt"
- "punpckhwd %%mm7, %%mm3 nt"
- "paddd (%1), %%mm4 nt"
- "paddd 8(%1), %%mm2 nt"
- "paddd 16(%1), %%mm5 nt"
- "paddd 24(%1), %%mm3 nt"
- "movq %%mm4, (%1) nt"
- "movq %%mm2, 8(%1) nt"
- "movq %%mm5, 16(%1) nt"
- "movq %%mm3, 24(%1) nt"
- "add $16, %0 nt"
- "add $32, %1 nt"
- "add $16, %2 nt"
- "cmp %3, %0 nt"
- " jb 1b nt"
- : "+r" (block), "+r" (sum), "+r" (offset)
- : "r"(block+64)
- );
- }
- static void denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){
- const int intra= s->mb_intra;
- int *sum= s->dct_error_sum[intra];
- uint16_t *offset= s->dct_offset[intra];
- s->dct_count[intra]++;
- asm volatile(
- "pxor %%xmm7, %%xmm7 nt"
- "1: nt"
- "pxor %%xmm0, %%xmm0 nt"
- "pxor %%xmm1, %%xmm1 nt"
- "movdqa (%0), %%xmm2 nt"
- "movdqa 16(%0), %%xmm3 nt"
- "pcmpgtw %%xmm2, %%xmm0 nt"
- "pcmpgtw %%xmm3, %%xmm1 nt"
- "pxor %%xmm0, %%xmm2 nt"
- "pxor %%xmm1, %%xmm3 nt"
- "psubw %%xmm0, %%xmm2 nt"
- "psubw %%xmm1, %%xmm3 nt"
- "movdqa %%xmm2, %%xmm4 nt"
- "movdqa %%xmm3, %%xmm5 nt"
- "psubusw (%2), %%xmm2 nt"
- "psubusw 16(%2), %%xmm3 nt"
- "pxor %%xmm0, %%xmm2 nt"
- "pxor %%xmm1, %%xmm3 nt"
- "psubw %%xmm0, %%xmm2 nt"
- "psubw %%xmm1, %%xmm3 nt"
- "movdqa %%xmm2, (%0) nt"
- "movdqa %%xmm3, 16(%0) nt"
- "movdqa %%xmm4, %%xmm6 nt"
- "movdqa %%xmm5, %%xmm0 nt"
- "punpcklwd %%xmm7, %%xmm4 nt"
- "punpckhwd %%xmm7, %%xmm6 nt"
- "punpcklwd %%xmm7, %%xmm5 nt"
- "punpckhwd %%xmm7, %%xmm0 nt"
- "paddd (%1), %%xmm4 nt"
- "paddd 16(%1), %%xmm6 nt"
- "paddd 32(%1), %%xmm5 nt"
- "paddd 48(%1), %%xmm0 nt"
- "movdqa %%xmm4, (%1) nt"
- "movdqa %%xmm6, 16(%1) nt"
- "movdqa %%xmm5, 32(%1) nt"
- "movdqa %%xmm0, 48(%1) nt"
- "add $32, %0 nt"
- "add $64, %1 nt"
- "add $32, %2 nt"
- "cmp %3, %0 nt"
- " jb 1b nt"
- : "+r" (block), "+r" (sum), "+r" (offset)
- : "r"(block+64)
- );
- }
- #undef HAVE_MMX2
- #define RENAME(a) a ## _MMX
- #define RENAMEl(a) a ## _mmx
- #include "mpegvideo_mmx_template.c"
- #define HAVE_MMX2
- #undef RENAME
- #undef RENAMEl
- #define RENAME(a) a ## _MMX2
- #define RENAMEl(a) a ## _mmx2
- #include "mpegvideo_mmx_template.c"
- #undef RENAME
- #undef RENAMEl
- #define RENAME(a) a ## _SSE2
- #define RENAMEl(a) a ## _sse2
- #include "mpegvideo_mmx_template.c"
- void MPV_common_init_mmx(MpegEncContext *s)
- {
- if (mm_flags & MM_MMX) {
- const int dct_algo = s->avctx->dct_algo;
- s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx;
- s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx;
- s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx;
- s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_mmx;
- s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx;
- s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx;
- draw_edges = draw_edges_mmx;
- if (mm_flags & MM_SSE2) {
- s->denoise_dct= denoise_dct_sse2;
- } else {
- s->denoise_dct= denoise_dct_mmx;
- }
- if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){
- if(mm_flags & MM_SSE2){
- s->dct_quantize= dct_quantize_SSE2;
- } else if(mm_flags & MM_MMXEXT){
- s->dct_quantize= dct_quantize_MMX2;
- } else {
- s->dct_quantize= dct_quantize_MMX;
- }
- }
- }
- }