📄 coder.c
字号:
else
fprintf(stdout," %2d",QP_xmitted);
#endif
if (pic->PB)
ReconImage(i,j,recon_data_B,B_recon);
ReconImage(i,j,recon_data_P,recon);
free(recon_data_P);
free(qcoeff_P);
if (pic->PB) {
free(qcoeff_B);
free(recon_data_B);
}
}
#ifdef PRINTQ
fprintf(stdout,"\n");
#endif
}
pic->QP_mean = QP_cumulative/(float)abs_mb_num;
/* Free memory */
free(pi);
if (mv_outside_frame) {
free(prev_recon);
FreeImage(pr_edge);
}
for (j = 0; j < (lines>>4)+1; j++)
for (i = 0; i < (pels>>4)+2; i++)
for (k = 0; k < 6; k++)
free(MV[k][j][i]);
return;
}
/**********************************************************************
*
* Name: CodeOneIntra
* Description: codes one image intra
*
* Input: pointer to image, QP
*
* Returns: pointer to reconstructed image
* Side effects: memory is allocated to recon image
*
***********************************************************************/
PictImage *CodeOneIntra(PictImage *curr, int QP, Bits *bits, Pict *pic)
{
PictImage *recon;
MB_Structure *data = (MB_Structure *)malloc(sizeof(MB_Structure));
int *qcoeff;
int Mode = MODE_INTRA;
int CBP,COD;
int i,j;
recon = InitImage(pels*lines);
ZeroBits(bits);
pic->QUANT = QP;
bits->header += CountBitsPicture(pic);
COD = 0; /* Every block is coded in Intra frame */
for ( j = 0; j < lines/MB_SIZE; j++) {
/* insert sync in *every* slice if use_gobsync is chosen */
if (pic->use_gobsync && j != 0)
bits->header += CountBitsSlice(j,QP);
for ( i = 0; i < pels/MB_SIZE; i++) {
pic->MB = i + j * (pels/MB_SIZE);
bits->no_intra++;
FillLumBlock(i*MB_SIZE, j*MB_SIZE, curr, data);
FillChromBlock(i*MB_SIZE, j*MB_SIZE, curr, data);
qcoeff = MB_Encode(data, QP, Mode);
CBP = FindCBP(qcoeff,Mode,64);
if (!syntax_arith_coding) {
CountBitsMB(Mode,COD,CBP,0,pic,bits);
CountBitsCoeff(qcoeff, Mode, CBP,bits,64);
} else {
Count_sac_BitsMB(Mode,COD,CBP,0,pic,bits);
Count_sac_BitsCoeff(qcoeff, Mode, CBP,bits,64);
}
MB_Decode(qcoeff, data, QP, Mode);
Clip(data);
ReconImage(i,j,data,recon);
free(qcoeff);
}
}
pic->QP_mean = (float)QP;
free(data);
return recon;
}
/**********************************************************************
*
* Name: MB_Encode
* Description: DCT and quantization of Macroblocks
*
* Input: MB data struct, mquant (1-31, 0 = no quant),
* MB info struct
* Returns: Pointer to quantized coefficients
* Side effects:
*
**********************************************************************/
int *MB_Encode(MB_Structure *mb_orig, int QP, int I)
{
int i, j, k, l, row, col;
int fblock[64];
int coeff[384];
int *coeff_ind;
int *qcoeff;
int *qcoeff_ind;
if ((qcoeff=(int *)malloc(sizeof(int)*384)) == 0) {
fprintf(stderr,"mb_encode(): Couldn't allocate qcoeff.\n");
exit(-1);
}
coeff_ind = coeff;
qcoeff_ind = qcoeff;
for (k=0;k<16;k+=8) {
for (l=0;l<16;l+=8) {
for (i=k,row=0;row<64;i++,row+=8) {
for (j=l,col=0;col<8;j++,col++) {
*(fblock+row+col) = mb_orig->lum[i][j];
}
}
Dct(fblock,coeff_ind);
Quant(coeff_ind,qcoeff_ind,QP,I);
coeff_ind += 64;
qcoeff_ind += 64;
}
}
for (i=0;i<8;i++) {
for (j=0;j<8;j++) {
*(fblock+i*8+j) = mb_orig->Cb[i][j];
}
}
Dct(fblock,coeff_ind);
Quant(coeff_ind,qcoeff_ind,QP,I);
coeff_ind += 64;
qcoeff_ind += 64;
for (i=0;i<8;i++) {
for (j=0;j<8;j++) {
*(fblock+i*8+j) = mb_orig->Cr[i][j];
}
}
Dct(fblock,coeff_ind);
Quant(coeff_ind,qcoeff_ind,QP,I);
return qcoeff;
}
/**********************************************************************
*
* Name: MB_Decode
* Description: Reconstruction of quantized DCT-coded Macroblocks
*
* Input: Quantized coefficients, MB data
* QP (1-31, 0 = no quant), MB info block
* Returns: int (just 0)
* Side effects:
*
**********************************************************************/
int MB_Decode(int *qcoeff, MB_Structure *mb_recon, int QP, int I)
{
int i, j, k, l, row, col;
int *iblock;
int *qcoeff_ind;
int *rcoeff, *rcoeff_ind;
if ((iblock = (int *)malloc(sizeof(int)*64)) == NULL) {
fprintf(stderr,"MB_Coder: Could not allocate space for iblock\n");
exit(-1);
}
if ((rcoeff = (int *)malloc(sizeof(int)*384)) == NULL) {
fprintf(stderr,"MB_Coder: Could not allocate space for rcoeff\n");
exit(-1);
}
/* For control purposes */
/* Zero data */
for (i = 0; i < 16; i++)
for (j = 0; j < 16; j++)
mb_recon->lum[j][i] = 0;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++) {
mb_recon->Cb[j][i] = 0;
mb_recon->Cr[j][i] = 0;
}
qcoeff_ind = qcoeff;
rcoeff_ind = rcoeff;
for (k=0;k<16;k+=8) {
for (l=0;l<16;l+=8) {
Dequant(qcoeff_ind,rcoeff_ind,QP,I);
#ifndef FASTIDCT
idctref(rcoeff_ind,iblock);
#else
idct(rcoeff_ind,iblock);
#endif
qcoeff_ind += 64;
rcoeff_ind += 64;
for (i=k,row=0;row<64;i++,row+=8) {
for (j=l,col=0;col<8;j++,col++) {
mb_recon->lum[i][j] = *(iblock+row+col);
}
}
}
}
Dequant(qcoeff_ind,rcoeff_ind,QP,I);
#ifndef FASTIDCT
idctref(rcoeff_ind,iblock);
#else
idct(rcoeff_ind,iblock);
#endif
qcoeff_ind += 64;
rcoeff_ind += 64;
for (i=0;i<8;i++) {
for (j=0;j<8;j++) {
mb_recon->Cb[i][j] = *(iblock+i*8+j);
}
}
Dequant(qcoeff_ind,rcoeff_ind,QP,I);
#ifndef FASTIDCT
idctref(rcoeff_ind,iblock);
#else
idct(rcoeff_ind,iblock);
#endif
for (i=0;i<8;i++) {
for (j=0;j<8;j++) {
mb_recon->Cr[i][j] = *(iblock+i*8+j);
}
}
free(iblock);
free(rcoeff);
return 0;
}
/**********************************************************************
*
* Name: FillLumBlock
* Description: Fills the luminance of one block of PictImage
*
* Input: Position, pointer to PictImage, array to fill
* Returns:
* Side effects: fills array
*
***********************************************************************/
void FillLumBlock( int x, int y, PictImage *image, MB_Structure *data)
{
int n;
register int m;
for (n = 0; n < MB_SIZE; n++)
for (m = 0; m < MB_SIZE; m++)
data->lum[n][m] =
(int)(*(image->lum + x+m + (y+n)*pels));
return;
}
/**********************************************************************
*
* Name: FillChromBlock
* Description: Fills the chrominance of one block of PictImage
*
* Input: Position, pointer to PictImage, array to fill
* Returns:
* Side effects: fills array
* 128 subtracted from each
*
***********************************************************************/
void FillChromBlock(int x_curr, int y_curr, PictImage *image,
MB_Structure *data)
{
int n;
register int m;
int x, y;
x = x_curr>>1;
y = y_curr>>1;
for (n = 0; n < (MB_SIZE>>1); n++)
for (m = 0; m < (MB_SIZE>>1); m++) {
data->Cr[n][m] =
(int)(*(image->Cr +x+m + (y+n)*cpels));
data->Cb[n][m] =
(int)(*(image->Cb +x+m + (y+n)*cpels));
}
return;
}
/**********************************************************************
*
* Name: ZeroMBlock
* Description: Fills one MB with Zeros
*
* Input: MB_Structure to zero out
* Returns:
* Side effects:
*
***********************************************************************/
void ZeroMBlock(MB_Structure *data)
{
int n;
register int m;
for (n = 0; n < MB_SIZE; n++)
for (m = 0; m < MB_SIZE; m++)
data->lum[n][m] = 0;
for (n = 0; n < (MB_SIZE>>1); n++)
for (m = 0; m < (MB_SIZE>>1); m++) {
data->Cr[n][m] = 0;
data->Cb[n][m] = 0;
}
return;
}
/**********************************************************************
*
* Name: ReconImage
* Description: Puts together reconstructed image
*
* Input: position of curr block, reconstructed
* macroblock, pointer to recontructed image
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -