📄 block.c
字号:
/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy for standardization procedure is available at
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Original Code is Reference Software for China National Standard
* GB/T 20090.2-2006 (short for AVS-P2 or AVS Video) at version RM52J.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup (Audio and Video coding Standard Working Group of China).
* Contributors: Guoping Li, Siwei Ma, Jian Lou, Qiang Wang ,
* Jianwen Chen,Haiwu Zhao, Xiaozhen Zheng, Junhao Zheng, Zhiming Wang
*
******************************************************************************
*/
/*
*************************************************************************************
* File name:
* Function:
*
*************************************************************************************
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <memory.h>
#include "defines.h"
#include "global.h"
#include "rdopt_coding_state.h"
#include "vlc.h"
#include "block.h"
#include "golomb.h"
#define Q_BITS 21
#define EP (edgepixels+20)
#ifdef WIN32
#define int16 __int16
#else
#define int16 int16_t
#endif
//////////////////////////////////////////////////////////////////////////
unsigned short Q_TAB[64] = {
32768,29775,27554,25268,23170,21247,19369,17770,
16302,15024,13777,12634,11626,10624,9742,8958,
8192,7512,6889,6305,5793,5303,4878,4467,
4091,3756,3444,3161,2894,2654,2435,2235,
2048,1878,1722,1579,1449,1329,1218,1117,
1024,939,861,790,724,664,609,558,
512,470,430,395,362,332,304,279,
256,235,215,197,181,166,152,140
};
unsigned short IQ_TAB[64] = {
32768,36061,38968,42495,46341,50535,55437,60424,
32932,35734,38968,42495,46177,50535,55109,59933,
65535,35734,38968,42577,46341,50617,55027,60097,
32809,35734,38968,42454,46382,50576,55109,60056,
65535,35734,38968,42495,46320,50515,55109,60076,
65535,35744,38968,42495,46341,50535,55099,60087,
65535,35734,38973,42500,46341,50535,55109,60097,
32771,35734,38965,42497,46341,50535,55109,60099
};
short IQ_SHIFT[64] = {
15,15,15,15,15,15,15,15,
14,14,14,14,14,14,14,14,
14,13,13,13,13,13,13,13,
12,12,12,12,12,12,12,12,
12,11,11,11,11,11,11,11,
11,10,10,10,10,10,10,10,
10,9,9,9,9,9,9,9,
8,8,8,8,8,8,8,8
};
const byte QP_SCALE_CR[64]=
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,42,43,43,44,44,45,45,
46,46,47,47,48,48,48,49,49,49,
50,50,50,51,
};//Lou 1014
#define absm(A) ((A)<(0) ? (-(A)):(A))
const int ZD_MAT[8][8] = {
{8,8,8,8,8,8,8,8},
{10,9,6,2,-2,-6,-9,-10},
{10,4,-4,-10,-10,-4,4,10},
{9,-2,-10,-6,6,10,2,-9},
{8,-8,-8,8,8,-8,-8,8},
{6,-10,2,9,-9,-2,10,-6},
{4,-10,10,-4,-4,10,-10,4},
{2,-6,9,-10,10,-9,6,-2}
};
/*Lou End*/
int ScaleM[4][4] ={
{32768,37958,36158,37958},
{37958,43969,41884,43969},
{36158,41884,39898,41884},
{37958,43969,41884,43969}
};
extern const int AVS_SCAN[2][64][2];
#define B8_SIZE 8
void transform_B8(short curr_blk[B8_SIZE][B8_SIZE]) // block to be transformed.
{
int xx, yy;
int b[8];
int tmp[8];
// Horizontal Transform
for(yy=0; yy<8; yy++)
{
// First Butterfly
b[0]=curr_blk[yy][0] + curr_blk[yy][7];
b[1]=curr_blk[yy][1] + curr_blk[yy][6];
b[2]=curr_blk[yy][2] + curr_blk[yy][5];
b[3]=curr_blk[yy][3] + curr_blk[yy][4];
b[4]=curr_blk[yy][0] - curr_blk[yy][7];
b[5]=curr_blk[yy][1] - curr_blk[yy][6];
b[6]=curr_blk[yy][2] - curr_blk[yy][5];
b[7]=curr_blk[yy][3] - curr_blk[yy][4];
// Upright Butterfly
tmp[0]=b[0] + b[3];
tmp[1]=b[1] + b[2];
tmp[2]=b[0] - b[3];
tmp[3]=b[1] - b[2];
b[0]=(tmp[0] + tmp[1])<<3;
b[1]=(tmp[0] - tmp[1])<<3;
/*Lou Change*/
b[2]=((tmp[2]*10)+(tmp[3]<<2));
b[3]=((tmp[2]<<2)-(tmp[3]*10));
/*Lou End*/
// Downright Butterfly
tmp[4]=b[4];
tmp[5]=b[5];
tmp[6]=b[6];
tmp[7]=b[7];
/*Lou Change*/
tmp[0]=(((tmp[4] - tmp[7])<<1) + tmp[4]);
tmp[1]=(((tmp[5] + tmp[6])<<1) + tmp[5]);
tmp[2]=(((tmp[5] - tmp[6])<<1) - tmp[6]);
tmp[3]=(((tmp[4] + tmp[7])<<1) + tmp[7]);
b[4]=(((tmp[0] + tmp[1] + tmp[3])<<1) + tmp[1]);// 10*tmp[4] +9*tmp[5] +6*tmp[6] +2*tmp[7];
b[5]=(((tmp[0] - tmp[1] + tmp[2])<<1) + tmp[0]);// 9*tmp[4] -2*tmp[5] -10*tmp[6] -6*tmp[7];
b[6]=(((-tmp[1] - tmp[2] + tmp[3])<<1) + tmp[3]);// 6*tmp[4] -10*tmp[5] -2*tmp[6] +9*tmp[7];
b[7]=(((tmp[0] - tmp[2] - tmp[3])<<1) - tmp[2]);// 2*tmp[4] -6*tmp[5] +9*tmp[6] -10*tmp[7];
/*Lou End*/
// Output
curr_blk[yy][0]=b[0];
curr_blk[yy][1]=b[4];
curr_blk[yy][2]=b[2];
curr_blk[yy][3]=b[5];
curr_blk[yy][4]=b[1];
curr_blk[yy][5]=b[6];
curr_blk[yy][6]=b[3];
curr_blk[yy][7]=b[7];
}
// Vertical transform
for(xx=0; xx<8; xx++)
{
// First Butterfly
b[0]=curr_blk[0][xx] + curr_blk[7][xx];
b[1]=curr_blk[1][xx] + curr_blk[6][xx];
b[2]=curr_blk[2][xx] + curr_blk[5][xx];
b[3]=curr_blk[3][xx] + curr_blk[4][xx];
b[4]=curr_blk[0][xx] - curr_blk[7][xx];
b[5]=curr_blk[1][xx] - curr_blk[6][xx];
b[6]=curr_blk[2][xx] - curr_blk[5][xx];
b[7]=curr_blk[3][xx] - curr_blk[4][xx];
// Upright Butterfly
tmp[0]=b[0] + b[3];
tmp[1]=b[1] + b[2];
tmp[2]=b[0] - b[3];
tmp[3]=b[1] - b[2];
b[0]=(tmp[0] + tmp[1])<<3;
b[1]=(tmp[0] - tmp[1])<<3;
/*Lou Change*/
b[2]=((tmp[2]*10)+(tmp[3]<<2));
b[3]=((tmp[2]<<2)-(tmp[3]*10));
/*Lou End*/
// Downright Butterfly
tmp[4]=b[4];
tmp[5]=b[5];
tmp[6]=b[6];
tmp[7]=b[7];
/*Lou Change*/
tmp[0]=(((tmp[4] - tmp[7])<<1) + tmp[4]);
tmp[1]=(((tmp[5] + tmp[6])<<1) + tmp[5]);
tmp[2]=(((tmp[5] - tmp[6])<<1) - tmp[6]);
tmp[3]=(((tmp[4] + tmp[7])<<1) + tmp[7]);
b[4]=(((tmp[0] + tmp[1] + tmp[3])<<1) + tmp[1]);// 10*tmp[4] +9*tmp[5] +6*tmp[6] +2*tmp[7];
b[5]=(((tmp[0] - tmp[1] + tmp[2])<<1) + tmp[0]);// 9*tmp[4] -2*tmp[5] -10*tmp[6] -6*tmp[7];
b[6]=(((-tmp[1] - tmp[2] + tmp[3])<<1) + tmp[3]);// 6*tmp[4] -10*tmp[5] -2*tmp[6] +9*tmp[7];
b[7]=(((tmp[0] - tmp[2] - tmp[3])<<1) - tmp[2]);// 2*tmp[4] -6*tmp[5] +9*tmp[6] -10*tmp[7];
/*Lou End*/
// Output
curr_blk[0][xx] = (short)((b[0]+(1<<4))>>5);
curr_blk[1][xx] = (short)((b[4]+(1<<4))>>5);
curr_blk[2][xx] = (short)((b[2]+(1<<4))>>5);
curr_blk[3][xx] = (short)((b[5]+(1<<4))>>5);
curr_blk[4][xx] = (short)((b[1]+(1<<4))>>5);
curr_blk[5][xx] = (short)((b[6]+(1<<4))>>5);
curr_blk[6][xx] = (short)((b[3]+(1<<4))>>5);
curr_blk[7][xx] = (short)((b[7]+(1<<4))>>5);
}
}
void quant_B8(int qp, // Quantization parameter
int mode, // block tiling mode used for AVS. USED ALSO FOR SIGNALING INTRA (AVS_mode+4)
short curr_blk[B8_SIZE][B8_SIZE]
) {
int xx, yy;
int val, temp;
int qp_const;
int intra = 0;
if (mode>3) // mode 0..inter, mode 4.. intra
{
intra = 1;
}
if(intra)
qp_const = (1<<15)*10/31;
else
qp_const = (1<<15)*10/62;
for (yy=0; yy<8; yy++)
for (xx=0; xx<8; xx++)
{
val = curr_blk[yy][xx];
temp = absm(val);
curr_blk[yy][xx] = sign(((((temp * ScaleM[yy&3][xx&3] + (1<<18)) >> 19)*Q_TAB[qp]+qp_const)>>15), val);
}
}
void inv_transform_B8(short curr_blk[B8_SIZE][B8_SIZE] // block to be inverse transformed.
)
{
int xx, yy;
int tmp[8];
int t;
int b[8];
for(yy=0; yy<8; yy++)
{
// Horizontal inverse transform
// Reorder
tmp[0]=curr_blk[yy][0];
tmp[1]=curr_blk[yy][4];
tmp[2]=curr_blk[yy][2];
tmp[3]=curr_blk[yy][6];
tmp[4]=curr_blk[yy][1];
tmp[5]=curr_blk[yy][3];
tmp[6]=curr_blk[yy][5];
tmp[7]=curr_blk[yy][7];
// Downleft Butterfly
/*Lou Change*/
b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4];
b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5];
b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6];
b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7];
b[4] = ((b[0] + b[1] + b[3])<<1) + b[1];
b[5] = ((b[0] - b[1] + b[2])<<1) + b[0];
b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3];
b[7] = ((b[0] - b[2] - b[3])<<1) - b[2];
/*Lou End*/
// Upleft Butterfly
/*Lou Change*/
t=((tmp[2]*10)+(tmp[3]<<2));
tmp[3]=((tmp[2]<<2)-(tmp[3]*10));
tmp[2]=t;
t=(tmp[0]+tmp[1])<<3;
tmp[1]=(tmp[0]-tmp[1])<<3;
tmp[0]=t;
/*Lou End*/
b[0]=tmp[0]+tmp[2];
b[1]=tmp[1]+tmp[3];
b[2]=tmp[1]-tmp[3];
b[3]=tmp[0]-tmp[2];
// Last Butterfly
/*Lou Change*/
//curr_blk[yy][0]=(short)(((b[0]+b[4])+(1<<2))>>3);
//curr_blk[yy][1]=(short)(((b[1]+b[5])+(1<<2))>>3);
//curr_blk[yy][2]=(short)(((b[2]+b[6])+(1<<2))>>3);
//curr_blk[yy][3]=(short)(((b[3]+b[7])+(1<<2))>>3);
//curr_blk[yy][7]=(short)(((b[0]-b[4])+(1<<2))>>3);
//curr_blk[yy][6]=(short)(((b[1]-b[5])+(1<<2))>>3);
//curr_blk[yy][5]=(short)(((b[2]-b[6])+(1<<2))>>3);
//curr_blk[yy][4]=(short)(((b[3]-b[7])+(1<<2))>>3);
/*Lou End*/
/*WANGJP CHANGE 20061226*/
/* Commented by cjw, 20070327
curr_blk[yy][0]=((int16)((int16)(b[0]+b[4])+4))>>3;
curr_blk[yy][1]=((int16)((int16)(b[1]+b[5])+4))>>3;
curr_blk[yy][2]=((int16)((int16)(b[2]+b[6])+4))>>3;
curr_blk[yy][3]=((int16)((int16)(b[3]+b[7])+4))>>3;
curr_blk[yy][7]=((int16)((int16)(b[0]-b[4])+4))>>3;
curr_blk[yy][6]=((int16)((int16)(b[1]-b[5])+4))>>3;
curr_blk[yy][5]=((int16)((int16)(b[2]-b[6])+4))>>3;
curr_blk[yy][4]=((int16)((int16)(b[3]-b[7])+4))>>3;
*/
/*WANGJP END*/
//070305 dingdandan
curr_blk[yy][0]=(short)((Clip3(-32768,32767,((b[0]+b[4])+(1<<2))))>>3);
curr_blk[yy][1]=(short)((Clip3(-32768,32767,((b[1]+b[5])+(1<<2))))>>3);
curr_blk[yy][2]=(short)((Clip3(-32768,32767,((b[2]+b[6])+(1<<2))))>>3);
curr_blk[yy][3]=(short)((Clip3(-32768,32767,((b[3]+b[7])+(1<<2))))>>3);
curr_blk[yy][7]=(short)((Clip3(-32768,32767,((b[0]-b[4])+(1<<2))))>>3);
curr_blk[yy][6]=(short)((Clip3(-32768,32767,((b[1]-b[5])+(1<<2))))>>3);
curr_blk[yy][5]=(short)((Clip3(-32768,32767,((b[2]-b[6])+(1<<2))))>>3);
curr_blk[yy][4]=(short)((Clip3(-32768,32767,((b[3]-b[7])+(1<<2))))>>3);
//070305 dingdandan
}
// Vertical inverse transform
for(xx=0; xx<8; xx++)
{
// Reorder
tmp[0]=curr_blk[0][xx];
tmp[1]=curr_blk[4][xx];
tmp[2]=curr_blk[2][xx];
tmp[3]=curr_blk[6][xx];
tmp[4]=curr_blk[1][xx];
tmp[5]=curr_blk[3][xx];
tmp[6]=curr_blk[5][xx];
tmp[7]=curr_blk[7][xx];
// Downleft Butterfly
/*Lou Change*/
b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4];
b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5];
b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6];
b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7];
b[4] = ((b[0] + b[1] + b[3])<<1) + b[1];
b[5] = ((b[0] - b[1] + b[2])<<1) + b[0];
b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3];
b[7] = ((b[0] - b[2] - b[3])<<1) - b[2];
/*Lou End*/
// Upleft Butterfly
/*Lou Change*/
t=((tmp[2]*10)+(tmp[3]<<2));
tmp[3]=((tmp[2]<<2)-(tmp[3]*10));
tmp[2]=t;
t=(tmp[0]+tmp[1])<<3;
tmp[1]=(tmp[0]-tmp[1])<<3;
tmp[0]=t;
/*Lou End*/
b[0]=tmp[0]+tmp[2];
b[1]=tmp[1]+tmp[3];
b[2]=tmp[1]-tmp[3];
b[3]=tmp[0]-tmp[2];
// Last Butterfly
//curr_blk[0][xx]=(b[0]+b[4]+64)>>7;/*(Clip3(-32768,32703,b[0]+b[4])+64)>>7;*/
//curr_blk[1][xx]=(b[1]+b[5]+64)>>7;/*(Clip3(-32768,32703,b[1]+b[5])+64)>>7;*/
//curr_blk[2][xx]=(b[2]+b[6]+64)>>7;/*(Clip3(-32768,32703,b[2]+b[6])+64)>>7;*/
//curr_blk[3][xx]=(b[3]+b[7]+64)>>7;/*(Clip3(-32768,32703,b[3]+b[7])+64)>>7;*/
//curr_blk[7][xx]=(b[0]-b[4]+64)>>7;/*(Clip3(-32768,32703,b[0]-b[4])+64)>>7;*/
//curr_blk[6][xx]=(b[1]-b[5]+64)>>7;/*(Clip3(-32768,32703,b[1]-b[5])+64)>>7;*/
//curr_blk[5][xx]=(b[2]-b[6]+64)>>7;/*(Clip3(-32768,32703,b[2]-b[6])+64)>>7;*/
//curr_blk[4][xx]=(b[3]-b[7]+64)>>7;/*(Clip3(-32768,32703,b[3]-b[7])+64)>>7;*/
/*WANGJP CHANGE 20061226*/
/* Commented by cjw, 20070327
curr_blk[0][xx]=((int16)((int16)(b[0]+b[4])+64))>>7;
curr_blk[1][xx]=((int16)((int16)(b[1]+b[5])+64))>>7;
curr_blk[2][xx]=((int16)((int16)(b[2]+b[6])+64))>>7;
curr_blk[3][xx]=((int16)((int16)(b[3]+b[7])+64))>>7;
curr_blk[7][xx]=((int16)((int16)(b[0]-b[4])+64))>>7;
curr_blk[6][xx]=((int16)((int16)(b[1]-b[5])+64))>>7;
curr_blk[5][xx]=((int16)((int16)(b[2]-b[6])+64))>>7;
curr_blk[4][xx]=((int16)((int16)(b[3]-b[7])+64))>>7;
*/
/*WANGJP END*/
//070305 dingdandan
curr_blk[0][xx]=(Clip3(-32768,32767,(b[0]+b[4])+64))>>7;
curr_blk[1][xx]=(Clip3(-32768,32767,(b[1]+b[5])+64))>>7;
curr_blk[2][xx]=(Clip3(-32768,32767,(b[2]+b[6])+64))>>7;
curr_blk[3][xx]=(Clip3(-32768,32767,(b[3]+b[7])+64))>>7;
curr_blk[7][xx]=(Clip3(-32768,32767,(b[0]-b[4])+64))>>7;
curr_blk[6][xx]=(Clip3(-32768,32767,(b[1]-b[5])+64))>>7;
curr_blk[5][xx]=(Clip3(-32768,32767,(b[2]-b[6])+64))>>7;
curr_blk[4][xx]=(Clip3(-32768,32767,(b[3]-b[7])+64))>>7;
//070305 dingdandan
//it is uncessary to check range with clip operation
// //range checking
// if((b[0]+b[4])<=-32768 || (b[0]+b[4])>=(32768-65 ))
// printf("error\n");
// if((b[1]+b[5])<=-32768 || (b[1]+b[5])>=(32768-65 ))
// printf("error\n");
// if((b[2]+b[6])<=-32768 || (b[2]+b[6])>=(32768-65 ))
// printf("error\n");
// if((b[3]+b[7])<=-32768 || (b[3]+b[7])>=(32768-65 ))
// printf("error\n");
// if((b[0]-b[4])<=-32768 || (b[0]-b[4])>=(32768-65 ))
// printf("error\n");
// if((b[1]-b[5])<=-32768 || (b[1]-b[5])>=(32768-65 ))
// printf("error\n");
// if((b[2]-b[6])<=-32768 || (b[2]-b[6])>=(32768-65 ))
// printf("error\n");
// if((b[3]-b[7])<=-32768 || (b[3]-b[7])>=(32768-65 ))
// printf("error\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -