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 + -
显示快捷键?