📄 cavsdsp.c.svn-base
字号:
/* * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * * DSP functions * * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * * This file is part of FFmpeg. * * FFmpeg 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. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include <stdio.h>#include "dsputil.h"/***************************************************************************** * * in-loop deblocking filter * ****************************************************************************/#define P2 p0_p[-3*stride]#define P1 p0_p[-2*stride]#define P0 p0_p[-1*stride]#define Q0 p0_p[ 0*stride]#define Q1 p0_p[ 1*stride]#define Q2 p0_p[ 2*stride]static inline void loop_filter_l2(uint8_t *p0_p,int stride,int alpha, int beta) { int p0 = P0; int q0 = Q0; if(abs(p0-q0)<alpha && abs(P1-p0)<beta && abs(Q1-q0)<beta) { int s = p0 + q0 + 2; alpha = (alpha>>2) + 2; if(abs(P2-p0) < beta && abs(p0-q0) < alpha) { P0 = (P1 + p0 + s) >> 2; P1 = (2*P1 + s) >> 2; } else P0 = (2*P1 + s) >> 2; if(abs(Q2-q0) < beta && abs(q0-p0) < alpha) { Q0 = (Q1 + q0 + s) >> 2; Q1 = (2*Q1 + s) >> 2; } else Q0 = (2*Q1 + s) >> 2; }}static inline void loop_filter_l1(uint8_t *p0_p, int stride, int alpha, int beta, int tc) { int p0 = P0; int q0 = Q0; if(abs(p0-q0)<alpha && abs(P1-p0)<beta && abs(Q1-q0)<beta) { int delta = av_clip(((q0-p0)*3+P1-Q1+4)>>3,-tc, tc); P0 = av_clip_uint8(p0+delta); Q0 = av_clip_uint8(q0-delta); if(abs(P2-p0)<beta) { delta = av_clip(((P0-P1)*3+P2-Q0+4)>>3, -tc, tc); P1 = av_clip_uint8(P1+delta); } if(abs(Q2-q0)<beta) { delta = av_clip(((Q1-Q0)*3+P0-Q2+4)>>3, -tc, tc); Q1 = av_clip_uint8(Q1-delta); } }}static inline void loop_filter_c2(uint8_t *p0_p,int stride,int alpha, int beta) { int p0 = P0; int q0 = Q0; if(abs(p0-q0)<alpha && abs(P1-p0)<beta && abs(Q1-q0)<beta) { int s = p0 + q0 + 2; alpha = (alpha>>2) + 2; if(abs(P2-p0) < beta && abs(p0-q0) < alpha) { P0 = (P1 + p0 + s) >> 2; } else P0 = (2*P1 + s) >> 2; if(abs(Q2-q0) < beta && abs(q0-p0) < alpha) { Q0 = (Q1 + q0 + s) >> 2; } else Q0 = (2*Q1 + s) >> 2; }}static inline void loop_filter_c1(uint8_t *p0_p,int stride,int alpha, int beta, int tc) { if(abs(P0-Q0)<alpha && abs(P1-P0)<beta && abs(Q1-Q0)<beta) { int delta = av_clip(((Q0-P0)*3+P1-Q1+4)>>3, -tc, tc); P0 = av_clip_uint8(P0+delta); Q0 = av_clip_uint8(Q0-delta); }}#undef P0#undef P1#undef P2#undef Q0#undef Q1#undef Q2static void cavs_filter_lv_c(uint8_t *d, int stride, int alpha, int beta, int tc, int bs1, int bs2) { int i; if(bs1==2) for(i=0;i<16;i++) loop_filter_l2(d + i*stride,1,alpha,beta); else { if(bs1) for(i=0;i<8;i++) loop_filter_l1(d + i*stride,1,alpha,beta,tc); if (bs2) for(i=8;i<16;i++) loop_filter_l1(d + i*stride,1,alpha,beta,tc); }}static void cavs_filter_lh_c(uint8_t *d, int stride, int alpha, int beta, int tc, int bs1, int bs2) { int i; if(bs1==2) for(i=0;i<16;i++) loop_filter_l2(d + i,stride,alpha,beta); else { if(bs1) for(i=0;i<8;i++) loop_filter_l1(d + i,stride,alpha,beta,tc); if (bs2) for(i=8;i<16;i++) loop_filter_l1(d + i,stride,alpha,beta,tc); }}static void cavs_filter_cv_c(uint8_t *d, int stride, int alpha, int beta, int tc, int bs1, int bs2) { int i; if(bs1==2) for(i=0;i<8;i++) loop_filter_c2(d + i*stride,1,alpha,beta); else { if(bs1) for(i=0;i<4;i++) loop_filter_c1(d + i*stride,1,alpha,beta,tc); if (bs2) for(i=4;i<8;i++) loop_filter_c1(d + i*stride,1,alpha,beta,tc); }}static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc, int bs1, int bs2) { int i; if(bs1==2) for(i=0;i<8;i++) loop_filter_c2(d + i,stride,alpha,beta); else { if(bs1) for(i=0;i<4;i++) loop_filter_c1(d + i,stride,alpha,beta,tc); if (bs2) for(i=4;i<8;i++) loop_filter_c1(d + i,stride,alpha,beta,tc); }}/***************************************************************************** * * inverse transform * ****************************************************************************/static void cavs_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride) { int i; DCTELEM (*src)[8] = (DCTELEM(*)[8])block; uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; src[0][0] += 8; for( i = 0; i < 8; i++ ) { const int a0 = 3*src[i][1] - (src[i][7]<<1); const int a1 = 3*src[i][3] + (src[i][5]<<1); const int a2 = (src[i][3]<<1) - 3*src[i][5]; const int a3 = (src[i][1]<<1) + 3*src[i][7]; const int b4 = ((a0 + a1 + a3)<<1) + a1; const int b5 = ((a0 - a1 + a2)<<1) + a0; const int b6 = ((a3 - a2 - a1)<<1) + a3; const int b7 = ((a0 - a2 - a3)<<1) - a2; const int a7 = (src[i][2]<<2) - 10*src[i][6]; const int a6 = (src[i][6]<<2) + 10*src[i][2]; const int a5 = ((src[i][0] - src[i][4]) << 3) + 4; const int a4 = ((src[i][0] + src[i][4]) << 3) + 4; const int b0 = a4 + a6; const int b1 = a5 + a7; const int b2 = a5 - a7; const int b3 = a4 - a6; src[i][0] = (b0 + b4) >> 3; src[i][1] = (b1 + b5) >> 3; src[i][2] = (b2 + b6) >> 3; src[i][3] = (b3 + b7) >> 3; src[i][4] = (b3 - b7) >> 3; src[i][5] = (b2 - b6) >> 3; src[i][6] = (b1 - b5) >> 3; src[i][7] = (b0 - b4) >> 3; } for( i = 0; i < 8; i++ ) { const int a0 = 3*src[1][i] - (src[7][i]<<1); const int a1 = 3*src[3][i] + (src[5][i]<<1); const int a2 = (src[3][i]<<1) - 3*src[5][i]; const int a3 = (src[1][i]<<1) + 3*src[7][i]; const int b4 = ((a0 + a1 + a3)<<1) + a1; const int b5 = ((a0 - a1 + a2)<<1) + a0; const int b6 = ((a3 - a2 - a1)<<1) + a3; const int b7 = ((a0 - a2 - a3)<<1) - a2; const int a7 = (src[2][i]<<2) - 10*src[6][i]; const int a6 = (src[6][i]<<2) + 10*src[2][i]; const int a5 = (src[0][i] - src[4][i]) << 3; const int a4 = (src[0][i] + src[4][i]) << 3; const int b0 = a4 + a6; const int b1 = a5 + a7; const int b2 = a5 - a7; const int b3 = a4 - a6; dst[i + 0*stride] = cm[ dst[i + 0*stride] + ((b0 + b4) >> 7)]; dst[i + 1*stride] = cm[ dst[i + 1*stride] + ((b1 + b5) >> 7)]; dst[i + 2*stride] = cm[ dst[i + 2*stride] + ((b2 + b6) >> 7)]; dst[i + 3*stride] = cm[ dst[i + 3*stride] + ((b3 + b7) >> 7)]; dst[i + 4*stride] = cm[ dst[i + 4*stride] + ((b3 - b7) >> 7)]; dst[i + 5*stride] = cm[ dst[i + 5*stride] + ((b2 - b6) >> 7)]; dst[i + 6*stride] = cm[ dst[i + 6*stride] + ((b1 - b5) >> 7)]; dst[i + 7*stride] = cm[ dst[i + 7*stride] + ((b0 - b4) >> 7)]; } memset(block,0,64*sizeof(DCTELEM));}/***************************************************************************** * * motion compensation * ****************************************************************************/#define CAVS_SUBPIX(OPNAME, OP, NAME, A, B, C, D, E, F) \static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int h=8;\ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ for(i=0; i<h; i++)\ {\ OP(dst[0], A*src[-2] + B*src[-1] + C*src[0] + D*src[1] + E*src[2] + F*src[3]);\ OP(dst[1], A*src[-1] + B*src[ 0] + C*src[1] + D*src[2] + E*src[3] + F*src[4]);\ OP(dst[2], A*src[ 0] + B*src[ 1] + C*src[2] + D*src[3] + E*src[4] + F*src[5]);\ OP(dst[3], A*src[ 1] + B*src[ 2] + C*src[3] + D*src[4] + E*src[5] + F*src[6]);\ OP(dst[4], A*src[ 2] + B*src[ 3] + C*src[4] + D*src[5] + E*src[6] + F*src[7]);\ OP(dst[5], A*src[ 3] + B*src[ 4] + C*src[5] + D*src[6] + E*src[7] + F*src[8]);\ OP(dst[6], A*src[ 4] + B*src[ 5] + C*src[6] + D*src[7] + E*src[8] + F*src[9]);\ OP(dst[7], A*src[ 5] + B*src[ 6] + C*src[7] + D*src[8] + E*src[9] + F*src[10]);\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -