www.pudn.com > wm2.5.zip > block.c
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2004, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder 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 is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/
#include "global.h"
#include "block.h"
#include "vlc.h"
//#define AVS_1_0
#define clip(a,b,c) ( (a)<(b) ? (b) : ((a)>(c)?(c):(a)) ) //!< clamp a to the range of [b;c]
extern MacroblockHeader MbHeader;
extern MacroblockData MbData ;
extern int sign(int a,int b);
#define Q_BITS 15 //qwang 2004-3-8
#define DQ_BITS 6 //qwang 2004-3-8
#define DQ_ROUND (1<<(DQ_BITS-1)) //qwang 2004-3-8
const short 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,
};
static const int quant_coef[6][2][2] = { //qwang 2004-4-4
{ {8192, 6205}, {6205, 4964} },
{ {7282, 5761}, {5761, 4512} },
{ {6554, 5041}, {5041, 3818} },
{ {5699, 4481}, {4481, 3545} },
{ {5041, 4033}, {4033, 3102} },
{ {4520, 3507}, {3507, 2758} }
};
static const int dequant_coef[6][2][2] = { //qwang 2004-4-4
{ {16, 13}, {13, 10} },
{ {18, 14}, {14, 11} },
{ {20, 16}, {16, 13} },
{ {23, 18}, {18, 14} },
{ {26, 20}, {20, 16} },
{ {29, 23}, {23, 18} }
};
#ifndef AVS_1_0
int ScaleM[4][4] ={
{32768,26214,32768,26214},
{26214,20972,26214,20972},
{32768,26214,32768,26214},
{26214,20972,26214,20972}
};
int ABTScaleM[4][4] ={
{32768,37958,36158,37958},
{37958,43969,41884,43969},
{36158,41884,39898,41884},
{37958,43969,41884,43969}
};
#else
int ScaleM[4][4] ={
{32768,36158,32768,36158},
{36158,39898,36158,39898},
{32768,36158,32768,36158},
{36158,39898,36158,39898}
};
#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] = {
14,14,14,14,14,14,14,14,
13,13,13,13,13,13,13,13,
13,12,12,12,12,12,12,12,
11,11,11,11,11,11,11,11,
11,10,10,10,10,10,10,10,
10,9,9,9,9,9,9,9,
9,8,8,8,8,8,8,8,
7,7,7,7,7,7,7,7
};
#ifndef AVS_1_0
void Transform_B4(int blk, int subblk) // block to be transformed. //qwang 2004-4-4
{
int tmp[4];
int i,j,i1,j1;
// Horizontal transform
for (j=0; j<4; j++)
{
for (i=0; i<2; i++)
{
i1=3-i;
tmp[i]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j][i1];
tmp[i1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j][i1];
}
MbHeader.pred_residual[blk][subblk][j][0] = (tmp[0]+tmp[1])<<1;
MbHeader.pred_residual[blk][subblk][j][2] = (tmp[0]-tmp[1])<<1;
MbHeader.pred_residual[blk][subblk][j][1] = (tmp[3]*3)+tmp[2];
MbHeader.pred_residual[blk][subblk][j][3] = tmp[3]-(tmp[2]*3);
}
// Vertical transform
for (i=0; i < 4; i++)
{
for (j=0; j < 2; j++)//zhangnan change
{
j1=3-j;
tmp[j]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j1][i];
tmp[j1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j1][i];
}
MbHeader.pred_residual[blk][subblk][0][i] = (tmp[0]+tmp[1])<<1;
MbHeader.pred_residual[blk][subblk][2][i] = (tmp[0]-tmp[1])<<1;
MbHeader.pred_residual[blk][subblk][1][i] = (tmp[3]*3)+tmp[2];
MbHeader.pred_residual[blk][subblk][3][i] = tmp[3]-(tmp[2]*3);
}
}
#else
void Transform_B4(int blk, int subblk) // block to be transformed. //qwang 2004-4-4
{
int tmp[4];
int i,j,i1,j1;
// Horizontal transform
for (j=0; j<4; j++)
{
for (i=0; i<2; i++)
{
i1=3-i;
tmp[i]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j][i1];
tmp[i1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j][i1];
}
MbHeader.pred_residual[blk][subblk][j][0] = (tmp[0]+tmp[1])<<2;
MbHeader.pred_residual[blk][subblk][j][2] = (tmp[0]-tmp[1])<<2;
MbHeader.pred_residual[blk][subblk][j][1] = (tmp[3]*5)+tmp[2]*2;
MbHeader.pred_residual[blk][subblk][j][3] = tmp[3]*2-(tmp[2]*5);
}
// Vertical transform
for (i=0; i < 4; i++)
{
for (j=0; j < 2; j++)//zhangnan change
{
j1=3-j;
tmp[j]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j1][i];
tmp[j1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j1][i];
}
MbHeader.pred_residual[blk][subblk][0][i] = (((tmp[0]+tmp[1])<<2) + 2)>>2;
MbHeader.pred_residual[blk][subblk][2][i] = (((tmp[0]-tmp[1])<<2) + 2)>>2;
MbHeader.pred_residual[blk][subblk][1][i] = (tmp[3]*5 + tmp[2]*2 + 2)>>2;
MbHeader.pred_residual[blk][subblk][3][i] = (tmp[3]*2 - tmp[2]*5 + 2)>>2;
}
}
#endif
#ifndef AVS_1_0
void Quant_B4(int qp, int blk, int subblk, int* coeff_cost) // Quantization parameter //qwang 2004-3-7
{
int i, j;
int val, temp;
int qp_const, qp_const1;
if(blk>=4)
qp = QP_SCALE_CR[qp];
if (pgImage->picture_code_type == INTRA_IMG) //need modification if intra is used in P frame ??
{
qp_const = (1<<15)/3; // intra
qp_const1 = (1<<16)/3;
}
else
{
qp_const = (1<<15)/6; // inter
qp_const1 = (1<<16)/6;
}
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
val = MbHeader.pred_residual[blk][subblk][j][i];
temp = absm(MbHeader.pred_residual[blk][subblk][j][i]);
//sw Chroma DC
if ((blk==4 || blk==5) && (i==0 && j==0))
//MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const1)>>16;
MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const)>>15;//zcx
else
MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const)>>15;
if (temp!=val)
MbHeader.pred_residual[blk][subblk][j][i] = -1*MbHeader.pred_residual[blk][subblk][j][i];
}
}
//zigza scan for vlx out
if (zigzag_scan_B4(blk, subblk, coeff_cost)>0) // there are coefficients
{
// removed by dongjie (pgMbHeader->cbp) |= (1<cbp_4x4[blk]) |= (1<cbp_4x4[blk]) &= (~(1<=4)
qp = QP_SCALE_CR[qp];
if (pgImage->picture_code_type == INTRA_IMG) //need modification if intra is used in P frame ??
{
qp_const = (1<<15)/3; // intra
qp_const1 = (1<<16)/3;
}
else
{
qp_const = (1<<15)/6; // inter
qp_const1 = (1<<16)/6;
}
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
val = MbHeader.pred_residual[blk][subblk][j][i];
temp = absm(MbHeader.pred_residual[blk][subblk][j][i]);
//sw Chroma DC
if ((blk==4 || blk==5) && (i==0 && j==0))
MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const1)>>16;
else
MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const)>>15;
if (temp!=val)
MbHeader.pred_residual[blk][subblk][j][i] = -1*MbHeader.pred_residual[blk][subblk][j][i];
}
}
//zigza scan for vlx out
if (zigzag_scan_B4(blk, subblk, coeff_cost)>0) // there are coefficients
(pgMbHeader->cbp) |= (1<=4)
qp = QP_SCALE_CR[qp];
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
val = MbHeader.pred_residual[blk][subblk][j][i];
shift = IQ_SHIFT[qp];
QPI = IQ_TAB[qp];
MbData.recon_residual[blk][subblk][j][i] = (val*QPI+(1<<(shift-1)))>>shift;
}
}
/*
*************************************************************************
* Function:
Inverse transform of a 4x4 block.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
#ifndef AVS_1_0
void Inv_Transform_B4(int blk, int subblk) //qwang 2004-3-7
{
int tmp[4];
int i,j,i1,j1;
//horizontal
for (j=0; j<4; j++)
{
tmp[0]=(MbData.recon_residual[blk][subblk][j][0]+MbData.recon_residual[blk][subblk][j][2])<<1; //zzy
tmp[1]=(MbData.recon_residual[blk][subblk][j][0]-MbData.recon_residual[blk][subblk][j][2])<<1; //zzy
tmp[3]= (MbData.recon_residual[blk][subblk][j][1]*3)+MbData.recon_residual[blk][subblk][j][3]; //zzy
tmp[2]= MbData.recon_residual[blk][subblk][j][1]-(MbData.recon_residual[blk][subblk][j][3]*3);
for (i=0; i<2; i++)
{
i1=3-i;
MbData.recon_residual[blk][subblk][j][i]=tmp[i]+tmp[i1];
MbData.recon_residual[blk][subblk][j][i1]=tmp[i]-tmp[i1];
}
}
//vertical
for (i=0; i<4; i++)
{
tmp[0]= (MbData.recon_residual[blk][subblk][0][i]+MbData.recon_residual[blk][subblk][2][i])<<1; //zzy
tmp[1]= (MbData.recon_residual[blk][subblk][0][i]-MbData.recon_residual[blk][subblk][2][i])<<1; //zzy
tmp[3]= (MbData.recon_residual[blk][subblk][1][i]*3)+MbData.recon_residual[blk][subblk][3][i];
tmp[2]= MbData.recon_residual[blk][subblk][1][i]-(MbData.recon_residual[blk][subblk][3][i]*3);
for (j=0; j<2; j++)
{
j1=3-j;
MbData.recon_residual[blk][subblk][j][i] =(tmp[j]+tmp[j1]+16)>>5;
MbData.recon_residual[blk][subblk][j1][i]=(tmp[j]-tmp[j1]+16)>>5;
}
}
}
#else
void Inv_Transform_B4(int blk, int subblk) //qwang 2004-3-7
{
int tmp[4];
int i,j,i1,j1;
//horizontal
for (j=0; j<4; j++)
{
tmp[0]=(MbData.recon_residual[blk][subblk][j][0]+MbData.recon_residual[blk][subblk][j][2])<<2; //zzy
tmp[1]=(MbData.recon_residual[blk][subblk][j][0]-MbData.recon_residual[blk][subblk][j][2])<<2; //zzy
tmp[3]= (MbData.recon_residual[blk][subblk][j][1]*5)+MbData.recon_residual[blk][subblk][j][3]*2; //zzy
tmp[2]= MbData.recon_residual[blk][subblk][j][1]*2-(MbData.recon_residual[blk][subblk][j][3]*5);
for (i=0; i<2; i++)
{
i1=3-i;
MbData.recon_residual[blk][subblk][j][i]= (tmp[i]+tmp[i1] + 2)>>2;
MbData.recon_residual[blk][subblk][j][i1]= (tmp[i]-tmp[i1] +2 )>>2;
}
}
//vertical
for (i=0; i<4; i++)
{
tmp[0]= (MbData.recon_residual[blk][subblk][0][i]+MbData.recon_residual[blk][subblk][2][i])<<2; //zzy
tmp[1]= (MbData.recon_residual[blk][subblk][0][i]-MbData.recon_residual[blk][subblk][2][i])<<2; //zzy
tmp[3]= (MbData.recon_residual[blk][subblk][1][i]*5)+MbData.recon_residual[blk][subblk][3][i]*2;
tmp[2]= MbData.recon_residual[blk][subblk][1][i]*2-(MbData.recon_residual[blk][subblk][3][i]*5);
for (j=0; j<2; j++)
{
j1=3-j;
MbData.recon_residual[blk][subblk][j][i] =(tmp[j]+tmp[j1]+16)>>5;
MbData.recon_residual[blk][subblk][j1][i]=(tmp[j]-tmp[j1]+16)>>5;
}
}
}
#endif
/********************************************************************
Function:
Reconstruction of a 4x4 block
Created: 13:2:2004
Author :
Input :
Output :
Function:
*********************************************************************/
void Recon_B4(int blk, int subblk, int Update_Flag_Inter) //zhangnan
{
int left_offset = 0;
int pic_x = (MbData.mb_x<<4)+((blk&1)<<3)+((subblk &1)<<2);//zhangnan
int pic_x_c = (MbData.mb_x<<3)+((subblk &1)<<2);
int i,j;
short temp;
for(j=0; j<4; j++)
{
for(i=0; i<4; i++)
{
temp = (short) (MbData.pred_sample[blk][subblk][j][i] + MbData.recon_residual[blk][subblk][j][i]);
MbData.pred_sample[blk][subblk][j][i] = clip(temp,0,255);
}
}
if (blk<4)
{
for(j=0; j<4; j++)
for(i=0; i<4; i++)
{
imgY1[j][i] = MbData.pred_sample[blk][subblk][j][i]; //zhangnan
}
}else
{
for(j=0; j<4; j++)
for(i=0; i<4; i++)
{
imgUV1[blk-4][j][i] = MbData.pred_sample[blk][subblk][j][i];
}
}
}
/*
*************************************************************************
* Function:
Transfromation of a 2x2 Chroma DC block.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
void TranformChromaDC(int blk)
{
int m1[4];
int i;
m1[0] = (MbHeader.pred_residual[blk][0][0][0] + MbHeader.pred_residual[blk][1][0][0]
+ MbHeader.pred_residual[blk][2][0][0] + MbHeader.pred_residual[blk][3][0][0]);
m1[1] = (MbHeader.pred_residual[blk][0][0][0] - MbHeader.pred_residual[blk][1][0][0]
+ MbHeader.pred_residual[blk][2][0][0] - MbHeader.pred_residual[blk][3][0][0]);
m1[2] = (MbHeader.pred_residual[blk][0][0][0] + MbHeader.pred_residual[blk][1][0][0]
- MbHeader.pred_residual[blk][2][0][0] - MbHeader.pred_residual[blk][3][0][0]);
m1[3] = (MbHeader.pred_residual[blk][0][0][0] - MbHeader.pred_residual[blk][1][0][0]
- MbHeader.pred_residual[blk][2][0][0] + MbHeader.pred_residual[blk][3][0][0]);
for(i=0; i<4; i++)
//MbHeader.pred_residual[blk][i][0][0] = m1[i];
MbHeader.pred_residual[blk][i][0][0] = m1[i]>>1;//zcx
}
*/
/*
*************************************************************************
* Function:
Inverse Transfrom of a 2x2 Chroma DC block.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
void InvTransformChromaDC(int blk)
{
int m1[4];
int i;
m1[0] = (MbData.recon_residual[blk][0][0][0] + MbData.recon_residual[blk][1][0][0]
+ MbData.recon_residual[blk][2][0][0] + MbData.recon_residual[blk][3][0][0])>>1;
m1[1] = (MbData.recon_residual[blk][0][0][0] - MbData.recon_residual[blk][1][0][0]
+ MbData.recon_residual[blk][2][0][0] - MbData.recon_residual[blk][3][0][0])>>1;
m1[2] = (MbData.recon_residual[blk][0][0][0] + MbData.recon_residual[blk][1][0][0]
- MbData.recon_residual[blk][2][0][0] - MbData.recon_residual[blk][3][0][0])>>1;
m1[3] = (MbData.recon_residual[blk][0][0][0] - MbData.recon_residual[blk][1][0][0]
- MbData.recon_residual[blk][2][0][0] + MbData.recon_residual[blk][3][0][0])>>1;
for(i=0; i<4; i++)
MbData.recon_residual[blk][i][0][0] = m1[i];
}
*/
//#ifdef AVS_ABT
/*************************************************************************
* Function: Transfromation of a 8x8 block for ABT.
* Input:
* Output:
* Return:
* Attention: used by 16x16 16x8 8x16 8x8
*************************************************************************/
void abt_transform_B8(int blk) // for abt 8x8 and up transform
{
int xx, yy;
int b[8];
int tmp[8];
int curr_blk[8][8];
int subblk;
for(yy=0; yy<8; yy++)
for(xx=0; xx<8; xx++)
{
subblk=((yy>>2)<<1)+(xx>>2);
curr_blk[yy][xx]=MbHeader.pred_residual[blk][subblk][yy&3][xx&3];
}
// 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] = (b[0]+(1<<4))>>5;
curr_blk[1][xx] = (b[4]+(1<<4))>>5;
curr_blk[2][xx] = (b[2]+(1<<4))>>5;
curr_blk[3][xx] = (b[5]+(1<<4))>>5;
curr_blk[4][xx] = (b[1]+(1<<4))>>5;
curr_blk[5][xx] = (b[6]+(1<<4))>>5;
curr_blk[6][xx] = (b[3]+(1<<4))>>5;
curr_blk[7][xx] = (b[7]+(1<<4))>>5;
}
for(yy=0; yy<8; yy++)
for(xx=0; xx<8; xx++)
{
subblk=((yy>>2)<<1)+(xx>>2);
MbHeader.pred_residual[blk][subblk][yy&3][xx&3]=curr_blk[yy][xx];
}
}
/*************************************************************************
* Function:
for abt 8x8 quantization.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************/
void abt_quant_B8(int qp, int blk, int *coeff_cost)
{
int xx, yy;
int val, temp;
int qp_const;
int intra = 0;
int divfac;
short int curr_blk[8][8];
int subblk;
for(yy=0; yy<8; yy++)
for(xx=0; xx<8; xx++)
{
subblk=((yy>>2)<<1)+(xx>>2);
curr_blk[yy][xx] =MbHeader.pred_residual[blk][subblk][yy&3][xx&3];
}
divfac=( intra ? 3:6 );
qp_const = (1<<15)/divfac;
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 * ABTScaleM[yy&3][xx&3] + (1<<18)) >> 19)*Q_TAB[qp]+qp_const)>>15), val);
}
for(yy=0; yy<8; yy++)
for(xx=0; xx<8; xx++)
{
subblk=((yy>>2)<<1)+(xx>>2);
MbHeader.pred_residual[blk][subblk][yy&3][xx&3] =curr_blk[yy][xx];
}
if(abt_zigzag_B8(blk, coeff_cost)>0) // there are coefficients
(pgMbHeader->cbp)|= (1<>2)<<1)+(xx>>2);
val =MbHeader.pred_residual[blk][subblk][yy&3][xx&3];
MbHeader.pred_residual[blk][subblk][yy&3][xx&3]= (val*QPI+(1<<(shift-1)) )>>(shift);
}
}
/********************************************************************
Function:
for abt inverse transform 8x8
Created:
Author :
Input :
Output :
Function:
*********************************************************************/
void abt_Itransform_B8(int blk)
{
short int xx, yy;
short int tmp[8];
short int t;
short int b[8];
int curr_blk[8][8];
int subblk;
for(yy=0; yy<8; yy++)
for(xx=0; xx<8; xx++)
{
subblk=((yy>>2)<<1)+(xx>>2);
curr_blk[yy][xx] = MbHeader.pred_residual[blk][subblk][yy&3][xx&3];
}
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]=((b[0]+b[4])+(1<<2))>>3;
curr_blk[yy][1]=((b[1]+b[5])+(1<<2))>>3;
curr_blk[yy][2]=((b[2]+b[6])+(1<<2))>>3;
curr_blk[yy][3]=((b[3]+b[7])+(1<<2))>>3;
curr_blk[yy][7]=((b[0]-b[4])+(1<<2))>>3;
curr_blk[yy][6]=((b[1]-b[5])+(1<<2))>>3;
curr_blk[yy][5]=((b[2]-b[6])+(1<<2))>>3;
curr_blk[yy][4]=((b[3]-b[7])+(1<<2))>>3;
/*Lou End*/
}
// 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;
curr_blk[1][xx]=(b[1]+b[5]+64)>>7;
curr_blk[2][xx]=(b[2]+b[6]+64)>>7;
curr_blk[3][xx]=(b[3]+b[7]+64)>>7;
curr_blk[7][xx]=(b[0]-b[4]+64)>>7;
curr_blk[6][xx]=(b[1]-b[5]+64)>>7;
curr_blk[5][xx]=(b[2]-b[6]+64)>>7;
curr_blk[4][xx]=(b[3]-b[7]+64)>>7;
}
for(yy=0; yy<8; yy++)
for(xx=0; xx<8; xx++)
{
subblk=((yy>>2)<<1)+(xx>>2);
MbData.recon_residual[blk][subblk][yy&3][xx&3] = curr_blk[yy][xx];
}
}
//for sign qhg for abt
int sign(int a,int b)
{
int x;
x=absm(a);
if (b >= 0)
return x;
else
return -x;
}
//#endif