📄 mblockcode.c
字号:
#include "mblockcode.h"
#include "../mpeg4/mpeg4vlc.h"
#include "../mpeg4/mpeg4.h"
static const int iDQtab[5] = {1, 0, -1, 2, 3};
#define DQ_VALUE2INDEX(value) iDQtab[(value)+2]
static const short default_acdc_values[15] =
{ 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static int CalcAcdcCoeff(MacroBlock * pMB,
short block,
short qcoeff[64],
unsigned int iDcScaler,
short predictors[8])
{
short *pCurrent = pMB->PredictValue[block];
int i;
int S1 = 0, S2 = 0;
pCurrent[0] = qcoeff[0] * iDcScaler;
pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
for (i = 1; i < 8; i++)
{
pCurrent[i] = qcoeff[i];
pCurrent[i + 7] = qcoeff[i * 8];
}
qcoeff[0] = qcoeff[0] - predictors[0];
if( pMB->PredictDirection[block] == VERTICAL_DIRECTION)
{
/* VERTICAL_DIRECTION */
for (i = 1; i < 8; i++)
{
short level;
level = qcoeff[i];
S2 += abs(level);
level -= predictors[i];
S1 += abs(level);
predictors[i] = level;
}
}
else
{
for (i = 1; i < 8; i++)
{
short level;
level = qcoeff[i * 8];
S2 += abs(level);
level -= predictors[i];
S1 += abs(level);
predictors[i] = level;
}
}
return S2 - S1;
}
//***********************************************************************************************
//函 数 名:PredictIntraMB
//函数功能:宏块帧内预测
//形式参数:pMB 第一个宏块结构体指针
// iMBWidth 行宏块数目
// iQuant 量化系数
// x,y 当前宏块的行列标号
// data 系数块
//返 回 值:void
//***********************************************************************************************
static void PredictIntraMB(MacroBlock* pMB, short iMBWidth, short iQuant, short x, short y, short* data)
{
int iMBx = x; //当前宏块x值
short i, j;
int iMBNo = y * iMBWidth + x; //当前宏块号
short iDcScalar;
int iTotal = 0;
short iFlag;
short Predictors[6][8];
const short *pLeft = default_acdc_values;
const short *pTop = default_acdc_values;
const short *pDiag = default_acdc_values;
short *left, *top, *diag, *current;
int left_quant = iQuant;
int top_quant = iQuant;
pMB[iMBNo].pred_mode = INTRA_DCAC_PRED;
for (i = 0; i < 6; i++)
{
left = top = diag = current = NULL;
pLeft = default_acdc_values;
pTop = default_acdc_values;
pDiag = default_acdc_values;
//左
if ( iMBx && iMBNo >= 1 && (pMB[iMBNo-1].mb_type == MB_INTRA || pMB[iMBNo-1].mb_type == MB_INTRA_Q) )
{
left = pMB[iMBNo-1].PredictValue[0];
left_quant = pMB[iMBNo-1].quant;
}
//上
if ( iMBNo >= iMBWidth && (pMB[iMBNo-iMBWidth].mb_type == MB_INTRA || pMB[iMBNo-iMBWidth].mb_type == MB_INTRA_Q) )
{
top = pMB[iMBNo-iMBWidth].PredictValue[0];
top_quant = pMB[iMBNo-iMBWidth].quant;
}
//对角
if (iMBx && iMBNo >= iMBWidth + 1 && (pMB[iMBNo-iMBWidth-1].mb_type == MB_INTRA || pMB[iMBNo-iMBWidth-1].mb_type == MB_INTRA_Q))
{
diag = pMB[iMBNo-iMBWidth-1].PredictValue[0];
}
current = pMB[iMBNo].PredictValue[0];
iFlag = (i<4)? 1 : 0;
iDcScalar = GetDcScaler(iQuant, iFlag);
switch (i)
{
case 0:
if (left)
{
pLeft = left + MB_PREDICT;
}
if (top)
{
pTop = top + (MB_PREDICT << 1);
}
if (diag)
{
pDiag = diag + 3 * MB_PREDICT;
}
break;
case 1:
pLeft = current;
left_quant = iQuant;
if (top)
{
pTop = top + 3 * MB_PREDICT;
pDiag = top + (MB_PREDICT << 1);
}
break;
case 2:
if (left)
{
pLeft = left + 3 * MB_PREDICT;
pDiag = left + MB_PREDICT;
}
pTop = current;
top_quant = iQuant;
break;
case 3:
pLeft = current + (MB_PREDICT << 1);
left_quant = iQuant;
pTop = current + MB_PREDICT ;
top_quant = iQuant;
pDiag = current;
break;
case 4:
if (left)
{
pLeft = left + (MB_PREDICT << 2);
}
if (top)
{
pTop = top + (MB_PREDICT << 2);
}
if (diag)
{
pDiag = diag + (MB_PREDICT << 2);
}
break;
case 5:
if (left)
{
pLeft = left + 5 * MB_PREDICT;
}
if (top)
{
pTop = top + 5 * MB_PREDICT;
}
if (diag)
{
pDiag = diag + 5 * MB_PREDICT;
}
break;
default:
break;
}
/* get the predict direction */
if (ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0]))
{
pMB[iMBNo].PredictDirection[i] = VERTICAL_DIRECTION; /* vertical */
Predictors[i][0] = DIV_DIV(pTop[0], iDcScalar);
if (pMB[iMBNo].pred_mode == INTRA_DCAC_PRED)
{
/* INTRA_ACDC_PRED */
Predictors[i][1] = rescale(top_quant, iQuant, pTop[1]);
Predictors[i][2] = rescale(top_quant, iQuant, pTop[2]);
Predictors[i][3] = rescale(top_quant, iQuant, pTop[3]);
Predictors[i][4] = rescale(top_quant, iQuant, pTop[4]);
Predictors[i][5] = rescale(top_quant, iQuant, pTop[5]);
Predictors[i][6] = rescale(top_quant, iQuant, pTop[6]);
Predictors[i][7] = rescale(top_quant, iQuant, pTop[7]);
}
}
else
{
pMB[iMBNo].PredictDirection[i] = HORIZON_DIRECTION; /* horizontal */
Predictors[i][0] = DIV_DIV(pLeft[0], iDcScalar);
if (pMB[iMBNo].pred_mode == INTRA_DCAC_PRED)
{
/* INTRA_ACDC_PRED */
Predictors[i][1] = rescale(left_quant, iQuant, pLeft[8]);
Predictors[i][2] = rescale(left_quant, iQuant, pLeft[9]);
Predictors[i][3] = rescale(left_quant, iQuant, pLeft[10]);
Predictors[i][4] = rescale(left_quant, iQuant, pLeft[11]);
Predictors[i][5] = rescale(left_quant, iQuant, pLeft[12]);
Predictors[i][6] = rescale(left_quant, iQuant, pLeft[13]);
Predictors[i][7] = rescale(left_quant, iQuant, pLeft[14]);
}
}
/* rebuild the DC coeff and AC coeff */
iTotal += CalcAcdcCoeff(&pMB[iMBNo], i, data+i*64, iDcScalar, Predictors[i]);
}
//如果只有DC预测
if (iTotal <= 0)
{
pMB[iMBNo].pred_mode = INTRA_DC_PRED;
}
else
{
for (j = 0; j < 6; j++)
{
if (pMB[iMBNo].PredictDirection[j] == HORIZON_DIRECTION)
{
/* HORIZON_DIRECTION */
data[8] = Predictors[j][1];
data[16] = Predictors[j][2];
data[24] = Predictors[j][3];
data[32] = Predictors[j][4];
data[40] = Predictors[j][5];
data[48] = Predictors[j][6];
data[56] = Predictors[j][7];
}
else
{
data[1] = Predictors[j][1];
data[2] = Predictors[j][2];
data[3] = Predictors[j][3];
data[4] = Predictors[j][4];
data[5] = Predictors[j][5];
data[6] = Predictors[j][6];
data[7] = Predictors[j][7];
}
data += 64;
}
}
return;
}
//***********************************************************************************************
//函 数 名:PutIntraMBToBitstream()
//函数功能:将宏块写入码流
//形式参数: bs 比特流指针
// pEncoder 编码器结构体指针
// pCurMB 当前宏块指针
// iCbp 宏块编码类型
// data 系数矩阵
//返 回 值:void
//***********************************************************************************************
static short PutIntraMBToBitstream(Stream* bs, Encoder* pEncoder, MacroBlock* pCurMB, short iCbp, short* data)
{
short iMcbpc;
short i;
short iCbpy = iCbp>>2;
short iMBMode = pCurMB->mb_type;
unsigned int iBits;
iBits = GetStreamPosition(bs);
if (pEncoder->pCurFrameInfo->vop_coding_type == I_VOP)
{
iMcbpc = ((iMBMode >> 1) & 3) | ((iCbp & 3)<<2) ;
StreamPutBits(bs, IntraMBTypeTab[iMcbpc].code, IntraMBTypeTab[iMcbpc].len);
}
else
{
/* not_coded */
StreamPutBit(bs, 0);
iMcbpc = ( ((iCbp & 3)<<3) | (iMBMode & 7) );
StreamPutBits(bs, InterMBTypeTab[iMcbpc].code, InterMBTypeTab[iMcbpc].len);
}
iBits = GetStreamPosition(bs);
/* ac_pred_flag */
if (pCurMB->pred_mode == INTRA_DCAC_PRED)
{
StreamPutBit(bs, 1);
}
else
{
StreamPutBit(bs, 0);
}
/* cbpy */
StreamPutBits(bs, ChroTypeTab[iCbpy].code, ChroTypeTab[iCbpy].len);
/* dquant */
if (iMBMode == MB_INTRA_Q)
{
StreamPutBits(bs, DQ_VALUE2INDEX(pCurMB->dquant), 2);
}
/* code dct coeff */
for (i = 0; i < 6; i++)
{
if (i < 4)
{
/* dct_dc_size_luminance */
StreamPutBits(bs, LumTab[data[i * 64 + 0] + 255].code, LumTab[data[i * 64 + 0] + 255].len);
}
else
{
StreamPutBits(bs, chrotab[data[i * 64 + 0] + 255].code, chrotab[data[i * 64 + 0] + 255].len);
}
if (iCbp & (1<<(5-i)) )
{
int ScanMode;
if (pEncoder->pCurFrameInfo->alternate_vertical_scan_flag)
{
ScanMode = 2;
}
else if (pCurMB->pred_mode == INTRA_DCAC_PRED)
{
ScanMode = (pCurMB->PredictDirection[i] == VERTICAL_DIRECTION)? 1 : 2;
}
else
{
/* default: zizag */
ScanMode = 0;
}
CodeCoeffIntra(bs, data+i*64, Table[ScanMode]);
GetStreamPosition(bs);
}
}
return 1;
}
//***********************************************************************************************
//函 数 名:RecoverIntraMB()
//函数功能:预测恢复
//形式参数: pCurMB 当前宏块指针
// data 系数块
//返 回 值:void
//***********************************************************************************************
static short RecoverIntraMB(MacroBlock* pCurMB, short* data)
{
int i;
int iDcScaler;
short *Block, *Predictors;
short iFlag;
for (i = 0; i < 6; i++)
{
iFlag = (i < 4)? 1: 0;
iDcScaler = GetDcScaler(pCurMB->quant, iFlag);
Block = &data[i * 64];
Block[0] = DIV_DIV( pCurMB->PredictValue[i][0], iDcScaler );
Predictors = pCurMB->PredictValue[i];
if (pCurMB->pred_mode == INTRA_DCAC_PRED)
{
if (pCurMB->PredictDirection[i] == VERTICAL_DIRECTION)
{
Block[1] = Predictors[1];
Block[2] = Predictors[2];
Block[3] = Predictors[3];
Block[4] = Predictors[4];
Block[5] = Predictors[5];
Block[6] = Predictors[6];
Block[7] = Predictors[7];
}
else
{
Block[8] = Predictors[8];
Block[16] = Predictors[9];
Block[24] = Predictors[10];
Block[32] = Predictors[11];
Block[40] = Predictors[12];
Block[48] = Predictors[13];
Block[56] = Predictors[14];
}
}
}
return 0;
}
//***********************************************************************************************
//函 数 名:CodeIntraMB
//函数功能:
//形式参数:bs:
// :pEncoder:
// :
//
//
//
//返 回 值:void
//***********************************************************************************************
void CodeIntraMB(Stream* bs, Encoder* pEncoder, MacroBlock* pCurMB, short x, short y, short* data)
{
short iMBWidth = pEncoder->pCurFrameInfo->vop_width/16;
short iCBP;
MacroBlock* pMB = pEncoder->pCurFrameInfo->pMB;
/* intra predict */
PredictIntraMB(pMB, iMBWidth, pCurMB->quant, x, y, data);
/* coding macroblock DCT coeff and MV */
iCBP = GetMBlockCBP(data, pCurMB->mb_type);
PutIntraMBToBitstream(bs, pEncoder, pCurMB, iCBP, data);
/* recover intra predict */
RecoverIntraMB(pCurMB, data);
}
static void CodeVector(Stream * bs, int value, int f_code)
{
const int scale_factor = 1 << (f_code - 1);
const int cmp = scale_factor << 5;
if (value < (-1 * cmp))
{
value += 64 * scale_factor;
}
if (value > (cmp - 1))
{
value -= 64 * scale_factor;
}
if (value == 0)
{
StreamPutBits(bs, mb_motion_table[32].code, mb_motion_table[32].len);
}
else
{
unsigned short length, code, mv_res, sign;
length = 16 << f_code;
f_code--;
sign = (value < 0);
if (value >= length)
{
value -= 2 * length;
}
else if (value < -length)
{
value += 2 * length;
}
if (sign)
{
value = -value;
}
value--;
mv_res = value & ((1 << f_code) - 1);
code = ((value - mv_res) >> f_code) + 1;
if (sign)
{
code = -code;
}
code += 32;
StreamPutBits(bs, mb_motion_table[code].code,
mb_motion_table[code].len);
if (f_code)
{
StreamPutBits(bs, mv_res, f_code);
}
}
}
void CodeInterMB(Stream* bs, Encoder* pEncoder, MacroBlock* pCurMB, short x, short y, short* data)
{
int i;
unsigned int iMcbpc, iCbpy;
unsigned short *scan_table = pEncoder->pCurFrameInfo->alternate_vertical_scan_flag ? Table[2] : Table[0];
/* write the bitstream */
StreamPutBit(bs, 0);
iMcbpc = (pCurMB->mb_type & 7) | ((pCurMB->cbp & 3) << 3);
iCbpy = 15 - (pCurMB->cbp >> 2);
/* write mcbpc */
StreamPutBits(bs, InterMBTypeTab[iMcbpc].code,InterMBTypeTab[iMcbpc].len);
/* write cbpy */
StreamPutBits(bs, ChroTypeTab[iCbpy].code, ChroTypeTab[iCbpy].len);
/* write dquant */
if (pCurMB->mb_type == MB_INTER_Q)
{
StreamPutBits(bs, DQ_VALUE2INDEX(pCurMB->dquant), 2);
}
CodeVector(bs, pCurMB->PredMv[0].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
CodeVector(bs, pCurMB->PredMv[0].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
if (pCurMB->mb_type == MB_INTER_4V)
{
CodeVector(bs, pCurMB->PredMv[1].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
CodeVector(bs, pCurMB->PredMv[1].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
CodeVector(bs, pCurMB->PredMv[2].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
CodeVector(bs, pCurMB->PredMv[2].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
CodeVector(bs, pCurMB->PredMv[3].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
CodeVector(bs, pCurMB->PredMv[3].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
}
/* code block coeffs */
for (i = 0; i < 6; i++)
{
if (pCurMB->cbp & (1 << (5 - i)))
{
CodeCoeffInter(bs, &data[i * 64], scan_table);
}
}
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -