vf_spp.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 625 行 · 第 1/2 页

C
625
字号
/*    Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program 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 General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*//* * This implementation is based on an algorithm described in * "Aria Nosratinia Embedded Post-Processing for  * Enhancement of Compressed Images (1999)" * (http://citeseer.nj.nec.com/nosratinia99embedded.html) */ #include <uclib.h>#include <uclib.h>#include <uclib.h>#include <inttypes.h>#include <math.h>#include "config.h"#include "mp_msg.h"#include "cpudetect.h"#include "libavcodec/avcodec.h"#include "libavcodec/dsputil.h"#ifdef HAVE_MALLOC_H#include <uclib.h>#endif#include "img_format.h"#include "mp_image.h"#include "vf.h"#include "libvo/fastmemcpy.h"#define XMIN(a,b) ((a) < (b) ? (a) : (b))//===========================================================================//static const uint8_t  __attribute__((aligned(8))) dither[8][8]={{  0,  48,  12,  60,   3,  51,  15,  63, },{ 32,  16,  44,  28,  35,  19,  47,  31, },{  8,  56,   4,  52,  11,  59,   7,  55, },{ 40,  24,  36,  20,  43,  27,  39,  23, },{  2,  50,  14,  62,   1,  49,  13,  61, },{ 34,  18,  46,  30,  33,  17,  45,  29, },{ 10,  58,   6,  54,   9,  57,   5,  53, },{ 42,  26,  38,  22,  41,  25,  37,  21, },};static const uint8_t offset[127][2]= {{0,0},{0,0}, {4,4},{0,0}, {2,2}, {6,4}, {4,6},{0,0}, {5,1}, {2,2}, {7,3}, {4,4}, {1,5}, {6,6}, {3,7}, {0,0}, {4,0}, {1,1}, {5,1}, {3,2}, {7,2}, {2,3}, {6,3}, {0,4}, {4,4}, {1,5}, {5,5}, {3,6}, {7,6}, {2,7}, {6,7}, {0,0}, {0,2}, {0,4}, {0,6}, {1,1}, {1,3}, {1,5}, {1,7}, {2,0}, {2,2}, {2,4}, {2,6}, {3,1}, {3,3}, {3,5}, {3,7}, {4,0}, {4,2}, {4,4}, {4,6}, {5,1}, {5,3}, {5,5}, {5,7}, {6,0}, {6,2}, {6,4}, {6,6}, {7,1}, {7,3}, {7,5}, {7,7}, {0,0}, {4,4}, {0,4}, {4,0}, {2,2}, {6,6}, {2,6}, {6,2}, {0,2}, {4,6}, {0,6}, {4,2}, {2,0}, {6,4}, {2,4}, {6,0}, {1,1}, {5,5}, {1,5}, {5,1}, {3,3}, {7,7}, {3,7}, {7,3}, {1,3}, {5,7}, {1,7}, {5,3}, {3,1}, {7,5}, {3,5}, {7,1}, {0,1}, {4,5}, {0,5}, {4,1}, {2,3}, {6,7}, {2,7}, {6,3}, {0,3}, {4,7}, {0,7}, {4,3}, {2,1}, {6,5}, {2,5}, {6,1}, {1,0}, {5,4}, {1,4}, {5,0}, {3,2}, {7,6}, {3,6}, {7,2}, {1,2}, {5,6}, {1,6}, {5,2}, {3,0}, {7,4}, {3,4}, {7,0},};struct vf_priv_s {	int log2_count;	int qp;	int mode;	int mpeg2;	int temp_stride;	uint8_t *src;	int16_t *temp;	AVCodecContext *avctx;	DSPContext dsp;        char *non_b_qp;};#define SHIFT 22static void hardthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){	int i; 	int bias= 0; //FIXME	unsigned int threshold1, threshold2;		threshold1= qp*((1<<4) - bias) - 1;	threshold2= (threshold1<<1);        	memset(dst, 0, 64*sizeof(DCTELEM));	dst[0]= (src[0] + 4)>>3;        for(i=1; i<64; i++){		int level= src[i];		if(((unsigned)(level+threshold1))>threshold2){			const int j= permutation[i];			dst[j]= (level + 4)>>3;		}	}}static void softthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){	int i; 	int bias= 0; //FIXME	unsigned int threshold1, threshold2;		threshold1= qp*((1<<4) - bias) - 1;	threshold2= (threshold1<<1);        	memset(dst, 0, 64*sizeof(DCTELEM));	dst[0]= (src[0] + 4)>>3;        for(i=1; i<64; i++){		int level= src[i];		if(((unsigned)(level+threshold1))>threshold2){			const int j= permutation[i];			if(level>0)				dst[j]= (level - threshold1 + 4)>>3;			else				dst[j]= (level + threshold1 + 4)>>3;		}	}}#ifdef HAVE_MMXstatic void hardthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){	int bias= 0; //FIXME	unsigned int threshold1;		threshold1= qp*((1<<4) - bias) - 1;	        asm volatile(#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \		"movq " #src0 ", %%mm0	\n\t"\		"movq " #src1 ", %%mm1	\n\t"\		"movq " #src2 ", %%mm2	\n\t"\		"movq " #src3 ", %%mm3	\n\t"\		"psubw %%mm4, %%mm0	\n\t"\		"psubw %%mm4, %%mm1	\n\t"\		"psubw %%mm4, %%mm2	\n\t"\		"psubw %%mm4, %%mm3	\n\t"\		"paddusw %%mm5, %%mm0	\n\t"\		"paddusw %%mm5, %%mm1	\n\t"\		"paddusw %%mm5, %%mm2	\n\t"\		"paddusw %%mm5, %%mm3	\n\t"\		"paddw %%mm6, %%mm0	\n\t"\		"paddw %%mm6, %%mm1	\n\t"\		"paddw %%mm6, %%mm2	\n\t"\		"paddw %%mm6, %%mm3	\n\t"\		"psubusw %%mm6, %%mm0	\n\t"\		"psubusw %%mm6, %%mm1	\n\t"\		"psubusw %%mm6, %%mm2	\n\t"\		"psubusw %%mm6, %%mm3	\n\t"\		"psraw $3, %%mm0	\n\t"\		"psraw $3, %%mm1	\n\t"\		"psraw $3, %%mm2	\n\t"\		"psraw $3, %%mm3	\n\t"\\		"movq %%mm0, %%mm7	\n\t"\		"punpcklwd %%mm2, %%mm0	\n\t" /*A*/\		"punpckhwd %%mm2, %%mm7	\n\t" /*C*/\		"movq %%mm1, %%mm2	\n\t"\		"punpcklwd %%mm3, %%mm1	\n\t" /*B*/\		"punpckhwd %%mm3, %%mm2	\n\t" /*D*/\		"movq %%mm0, %%mm3	\n\t"\		"punpcklwd %%mm1, %%mm0	\n\t" /*A*/\		"punpckhwd %%mm7, %%mm3	\n\t" /*C*/\		"punpcklwd %%mm2, %%mm7	\n\t" /*B*/\		"punpckhwd %%mm2, %%mm1	\n\t" /*D*/\\		"movq %%mm0, " #dst0 "	\n\t"\		"movq %%mm7, " #dst1 "	\n\t"\		"movq %%mm3, " #dst2 "	\n\t"\		"movq %%mm1, " #dst3 "	\n\t"                		"movd %2, %%mm4		\n\t"		"movd %3, %%mm5		\n\t"		"movd %4, %%mm6		\n\t"		"packssdw %%mm4, %%mm4	\n\t"		"packssdw %%mm5, %%mm5	\n\t"		"packssdw %%mm6, %%mm6	\n\t"		"packssdw %%mm4, %%mm4	\n\t"		"packssdw %%mm5, %%mm5	\n\t"		"packssdw %%mm6, %%mm6	\n\t"		REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))		REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))		REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))		REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))		: : "r" (src), "r" (dst), "g" (threshold1+1), "g" (threshold1+5), "g" (threshold1-4) //FIXME maybe more accurate then needed?	);	dst[0]= (src[0] + 4)>>3;}static void softthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){	int bias= 0; //FIXME	unsigned int threshold1;	threshold1= qp*((1<<4) - bias) - 1;	        asm volatile(#undef REQUANT_CORE#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \		"movq " #src0 ", %%mm0	\n\t"\		"movq " #src1 ", %%mm1	\n\t"\		"pxor %%mm6, %%mm6	\n\t"\		"pxor %%mm7, %%mm7	\n\t"\		"pcmpgtw %%mm0, %%mm6	\n\t"\		"pcmpgtw %%mm1, %%mm7	\n\t"\		"pxor %%mm6, %%mm0	\n\t"\		"pxor %%mm7, %%mm1	\n\t"\		"psubusw %%mm4, %%mm0	\n\t"\		"psubusw %%mm4, %%mm1	\n\t"\		"pxor %%mm6, %%mm0	\n\t"\		"pxor %%mm7, %%mm1	\n\t"\		"movq " #src2 ", %%mm2	\n\t"\		"movq " #src3 ", %%mm3	\n\t"\		"pxor %%mm6, %%mm6	\n\t"\		"pxor %%mm7, %%mm7	\n\t"\		"pcmpgtw %%mm2, %%mm6	\n\t"\		"pcmpgtw %%mm3, %%mm7	\n\t"\		"pxor %%mm6, %%mm2	\n\t"\		"pxor %%mm7, %%mm3	\n\t"\		"psubusw %%mm4, %%mm2	\n\t"\		"psubusw %%mm4, %%mm3	\n\t"\		"pxor %%mm6, %%mm2	\n\t"\		"pxor %%mm7, %%mm3	\n\t"\\		"paddsw %%mm5, %%mm0	\n\t"\		"paddsw %%mm5, %%mm1	\n\t"\		"paddsw %%mm5, %%mm2	\n\t"\		"paddsw %%mm5, %%mm3	\n\t"\		"psraw $3, %%mm0	\n\t"\		"psraw $3, %%mm1	\n\t"\		"psraw $3, %%mm2	\n\t"\		"psraw $3, %%mm3	\n\t"\\		"movq %%mm0, %%mm7	\n\t"\		"punpcklwd %%mm2, %%mm0	\n\t" /*A*/\		"punpckhwd %%mm2, %%mm7	\n\t" /*C*/\		"movq %%mm1, %%mm2	\n\t"\		"punpcklwd %%mm3, %%mm1	\n\t" /*B*/\		"punpckhwd %%mm3, %%mm2	\n\t" /*D*/\		"movq %%mm0, %%mm3	\n\t"\		"punpcklwd %%mm1, %%mm0	\n\t" /*A*/\		"punpckhwd %%mm7, %%mm3	\n\t" /*C*/\		"punpcklwd %%mm2, %%mm7	\n\t" /*B*/\		"punpckhwd %%mm2, %%mm1	\n\t" /*D*/\\		"movq %%mm0, " #dst0 "	\n\t"\		"movq %%mm7, " #dst1 "	\n\t"\		"movq %%mm3, " #dst2 "	\n\t"\		"movq %%mm1, " #dst3 "	\n\t"                		"movd %2, %%mm4		\n\t"		"movd %3, %%mm5		\n\t"		"packssdw %%mm4, %%mm4	\n\t"		"packssdw %%mm5, %%mm5	\n\t"		"packssdw %%mm4, %%mm4	\n\t"		"packssdw %%mm5, %%mm5	\n\t"		REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))		REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))		REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))		REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))		: : "r" (src), "r" (dst), "g" (threshold1), "rm" (4) //FIXME maybe more accurate then needed?	);	dst[0]= (src[0] + 4)>>3;}#endifstatic inline void add_block(int16_t *dst, int stride, DCTELEM block[64]){	int y;		for(y=0; y<8; y++){		*(uint32_t*)&dst[0 + y*stride]+= *(uint32_t*)&block[0 + y*8];		*(uint32_t*)&dst[2 + y*stride]+= *(uint32_t*)&block[2 + y*8];		*(uint32_t*)&dst[4 + y*stride]+= *(uint32_t*)&block[4 + y*8];		*(uint32_t*)&dst[6 + y*stride]+= *(uint32_t*)&block[6 + y*8];	}}static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){	int y, x;#define STORE(pos) \	temp= ((src[x + y*src_stride + pos]<<log2_scale) + d[pos])>>6;\	if(temp & 0x100) temp= ~(temp>>31);\	dst[x + y*dst_stride + pos]= temp;	for(y=0; y<height; y++){		const uint8_t *d= dither[y];		for(x=0; x<width; x+=8){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?