?? text_code_mb.c
字號:
/**************************************************************************
該文件包含了宏塊紋理編碼的函數(shù)代碼
***************************************************************************/
#include "text_code.h"
#include "text_dct.h"
#define BLOCK_SIZE 8
Void BlockPredict (SInt *curr, /*SInt *rec_curr,*/
Int x_pos, Int y_pos, UInt width, Int fblock[][8]);
Void BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);
Void BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,
Int *qcoeff, Int maxDC, Int image_type);
Void BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,
Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);
/***********************************************************CommentBegin******
函數(shù)功能:
編碼、解碼重建的視頻宏塊
函數(shù)輸入:
Int x_pos 宏塊的x軸方向坐標
Int y_pos 宏塊的y軸方向坐標
UInt width Vop邊界會的寬度
Int QP 量化參數(shù)
Int Mode 宏塊編碼模式
函數(shù)輸入/輸出:
Vop *curr 當前未編碼的視頻對象平面
Vop *rec_curr 當前解碼并重建的視頻對象平面
Vop *comp 當前已經(jīng)過運動補償后的視頻對象平面
Int *qcoeff 系數(shù)塊(384 * sizeof(Int))
*
Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,
Int QP, Int Mode, Int *qcoeff)
{
Int k;
Int fblock[6][8][8];
Int coeff[384];
Int *coeff_ind;
Int *qcoeff_ind;
Int* rcoeff_ind;
Int x, y;
SInt *current, *recon, *compensated = NULL;
UInt xwidth;
Int iblock[6][8][8];
Int rcoeff[6*64];
Int i, j;
Int type; /* luma = 1, chroma = 2 */
// Int *qmat;
SInt tmp[64];
Int s;
int operation = curr->prediction_type;
/* This variable is for combined operation.
If it is an I_VOP, then MB in curr is reconstruct into rec_curr,
and comp is not used at all (i.e., it can be set to NULL).
If it is a P_VOP, then MB in curr is reconstructed, and the result
added with MB_comp is written into rec_curr.
- adamli 11/19/2000 */
Int max = GetVopBrightWhite(curr);
/* This variable is the max value for the clipping of the reconstructed image. */
coeff_ind = coeff;
qcoeff_ind = qcoeff;
rcoeff_ind = rcoeff;
for (k = 0; k < 6; k++)
{
switch (k)
{
case 0:
x = x_pos;
y = y_pos;
xwidth = width;
current = (SInt *) GetImageData (GetVopY (curr));
break;
case 1:
y = y_pos;
xwidth = width;
current = (SInt *) GetImageData (GetVopY (curr));
break;
case 2:
x = x_pos;
y = y_pos + 8;
xwidth = width;
current = (SInt *) GetImageData (GetVopY (curr));
break;
case 3:
x = x_pos + 8;
y = y_pos + 8;
xwidth = width;
current = (SInt *) GetImageData (GetVopY (curr));
break;
case 4:
x = x_pos / 2;
y = y_pos / 2;
xwidth = width / 2;
current = (SInt *) GetImageData (GetVopU (curr));
break;
case 5:
x = x_pos / 2;
y = y_pos / 2;
xwidth = width / 2;
current = (SInt *) GetImageData (GetVopV (curr));
break;
default:
break;
}
BlockPredict (current, x, y, xwidth, fblock[k]);
}
for (k = 0; k < 6; k++)
{
s = 0;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
tmp[s++] = (SInt) fblock[k][i][j];
#ifndef _MMX_
fdct_enc(tmp);
#else
fdct_mm32(tmp);
#endif
for (s = 0; s < 64; s++)
coeff_ind[s] = (Int) tmp[s];
if (k < 4) type = 1;
else type = 2;
/* For this release, only H263 quantization is supported. - adamli */
BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,
GetVopBrightWhite(curr),1);
BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));
for (s = 0; s < 64; s++)
tmp[s] = (SInt) rcoeff_ind[s];
#ifndef _MMX_
idct_enc(tmp);
#else
Fast_IDCT(tmp);
#endif
s = 0;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
iblock[k][i][j] = (Int)tmp[s++];
coeff_ind += 64;
qcoeff_ind += 64;
rcoeff_ind += 64;
if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j ++)
iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));
switch (k)
{
case 0:
case 1:
case 2:
continue;
case 3:
recon = (SInt *) GetImageData (GetVopY (rec_curr));
if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));
BlockRebuild (recon, compensated, operation, max, x_pos, y_pos, width, 16, iblock[0]);
BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos, width, 16, iblock[1]);
BlockRebuild (recon, compensated, operation, max, x_pos, y_pos + 8, width, 16, iblock[2]);
BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);
continue;
case 4:
recon = (SInt *) GetImageData (GetVopU (rec_curr));
if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));
BlockRebuild (recon, compensated, operation, max,
x_pos/2, y_pos/2, width/2, 8, iblock[4]);
continue;
case 5:
recon = (SInt *) GetImageData (GetVopV (rec_curr));
if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));
BlockRebuild (recon, compensated, operation, max,
x_pos/2, y_pos/2, width/2, 8, iblock[5]);
continue;
}
}
return;
}
/***********************************************************CommentBegin******
函數(shù)功能:
對一個幀內宏塊進行預測,并得到它的預測結果。
函數(shù)輸入:
1) nt x_pos:宏塊的x方向的空間位置;
2) nt y_pos:宏塊的y方向的空間位置;
3) Int width:宏塊所在視頻對象平面的邊界框的寬度。
函數(shù)輸出:
Int fblock[][8]:將要進行編碼的預測宏塊,輸出到數(shù)據(jù)流中。
函數(shù)輸入/輸出:
1)SInt* curr :當前未編碼的視頻對象平面數(shù)據(jù);
2)SInt* rec_curr:重建視頻對象平面數(shù)據(jù)的區(qū)域
*
***********************************************************CommentEnd********/
Void
BlockPredict (SInt *curr, /*SInt *rec_curr,*/ Int x_pos, Int y_pos,
UInt width, Int fblock[][8])
{
Int i, j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];
}
}
}
/***********************************************************CommentBegin******
函數(shù)功能:
在視頻對象平面數(shù)據(jù)區(qū)域中重建一個宏塊。
函數(shù)輸入:
1) nt x_pos:宏塊的x方向的空間位置;
2) Int y_pos:宏塊的y方向的空間位置;
3)UInt width:宏塊所在視頻對象平面的邊界框的寬度。
函數(shù)輸出:
SInt* rec_curr:當前將要重建的視頻對象平面數(shù)據(jù)區(qū)域。
函數(shù)描述:
對幀內的預測塊也進行重建。
***********************************************************CommentEnd********/
Void BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8])
{
/* 本函數(shù)將同時重建塊和產(chǎn)生新的誤差*/
Int i, j;
SInt *rec;
Int padded_width;
padded_width = width + 2 * edge;
rec = rec_curr + edge * padded_width + edge;
if (pred_type == I_VOP)
{
SInt *p;
p = rec + y_pos * padded_width + x_pos;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
SInt temp = fblock[i][j];
*(p++) = CLIP(temp, 0, max);
}
p += padded_width - 8;
}
}
else if (pred_type == P_VOP)
{
SInt *p, *pc;
p = rec + y_pos * padded_width + x_pos;
pc = comp + y_pos * width + x_pos;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
SInt temp = *(pc++) + fblock[i][j];
*(p++) = CLIP(temp, 0, max);
}
p += padded_width - 8;
pc += width - 8;
}
}
}
/***********************************************************CommentBegin******
函數(shù)功能:
* 8x8宏塊量化
函數(shù)輸入:
Int *coeff 未量化系數(shù)
Int QP 量化參數(shù)
Int Mode 宏塊編碼模式
函數(shù)輸出:
Int *qcoeff 已量化系數(shù)
***********************************************************CommentEnd********/
Void
BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type, Int *qcoeff, Int maxDC, Int image_type)
{
Int i;
Int level, result;
Int step, offset;
Int dc_scaler;
if (!(QP > 0 && (QP < 32*image_type))) return;
if (!(type == 1 || type == 2)) return;
if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
{ /* Intra */
dc_scaler = cal_dc_scaler(QP,type);
qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));
step = 2 * QP;
for (i = 1; i < 64; i++)
{
level = (abs(coeff[i])) / step;
result = (coeff[i] >= 0) ? level : -level;
qcoeff[i] = MIN(2047, MAX(-2048, result));
}
}
else
{ /* non Intra */
step = 2 * QP;
offset = QP / 2;
for (i = 0; i < 64; i++)
{
level = (abs(coeff[i]) - offset) / step;
result = (coeff[i] >= 0) ? level : -level;
qcoeff[i] = MIN(2047, MAX(-2048, result));
}
}
return;
}
/***********************************************************CommentBegin******
*
* -- BlockDequantH263 -- 8x8 block dequantization
*
* Purpose :
* 8x8 block dequantization
*
* Arguments in :
* Int *qcoeff quantized coefficients
* Int QP quantization parameter
* Int mode Macroblock coding mode
* Int short_video_header Flag to signal short video header bitstreams (H.263)
*
* Arguments out :
* Int *rcoeff reconstructed (dequantized) coefficients
*
***********************************************************CommentEnd********/
Void
BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,
Int image_type, Int short_video_header, Int bits_per_pixel)
{
Int i;
Int dc_scaler;
Int lim;
lim = (1 << (bits_per_pixel + 3));
if (QP)
{
for (i = 0; i < 64; i++)
{
if (qcoeff[i])
{
/* 16.11.98 Sven Brandau: "correct saturation" due to N2470, Clause 2.1.6 */
qcoeff[i] = MIN(2047, MAX(-2048, qcoeff[i] ));
if ((QP % 2) == 1)
rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
else
rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
}
else
rcoeff[i] = 0;
}
if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
{ /* Intra */
MOMCHECK(QP > 0 && (QP < 32*image_type));
MOMCHECK(type == 1 || type == 2);
if (short_video_header)
dc_scaler = 8;
else
dc_scaler = cal_dc_scaler(QP,type);
rcoeff[0] = qcoeff[0] * dc_scaler;
}
}
else
{
/* No quantizing at all */
for (i = 0; i < 64; i++)
{
rcoeff[i] = qcoeff[i];
}
if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
{ /* Intra */
rcoeff[0] = qcoeff[0]*8;
}
}
for (i=0;i<64;i++)
if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -