📄 coder.c
字号:
#include"sim.h"#include "global_e.h"
#include "TMConfig.h"
void CodeOneOrTwo(PictImage *curr, PictImage *B_image, PictImage *prev, PictImage *pr, int QP, int frameskip, Bits *bits, Pict *pic, PictImage *B_recon, PictImage *recon){ unsigned char *prev_ipol,*pi_edge=NULL,*pi,*orig_lum; PictImage *prev_recon=NULL, *pr_edge=NULL; MotionVector *MV[6][MBR+1][MBC+2]; MotionVector ZERO = {0,0,0,0,0}; MB_Structure *recon_data_P; MB_Structure *recon_data_B=NULL; MB_Structure *diff; short int *qcoeff_P; short int *qcoeff_B=NULL; int Mode,B; int CBP, CBPB=0; int bquant[] = {5,6,7,8}; int QP_B; int newgob; int i,j,k; /* buffer control vars */ float QP_cumulative = (float)0.0; int abs_mb_num = 0, QuantChangePostponed = 0; int QP_new, QP_prev, dquant, QP_xmitted=QP; ZeroBits(bits); /* interpolate image */ pi = InterpolateImage_MY(pr->lum,pels,lines); prev_ipol = pi; prev_recon = pr; orig_lum = prev->lum;
/* mark PMV's outside the frame */ for (i = 1; i < (pels>>4)+1; i++)
{ for (k = 0; k < 6; k++)
{ MV[k][0][i] = (MotionVector *)malloc(sizeof(MotionVector)); MarkVec(MV[k][0][i]); } MV[0][0][i]->Mode = MODE_INTRA; } /* zero out PMV's outside the frame */ for (i = 0; i < (lines>>4)+1; i++)
{ for (k = 0; k < 6; k++)
{ MV[k][i][0] = (MotionVector *)malloc(sizeof(MotionVector)); ZeroVec(MV[k][i][0]); MV[k][i][(pels>>4)+1] = (MotionVector *)malloc(sizeof(MotionVector)); ZeroVec(MV[k][i][(pels>>4)+1]); } MV[0][i][0]->Mode = MODE_INTRA; MV[0][i][(pels>>4)+1]->Mode = MODE_INTRA; } MotionEstimatePicture(curr->lum,prev_recon->lum,prev_ipol,pic->seek_dist,MV, pic->use_gobsync);
#ifndef OFFLINE_RATE_CONTROL if (pic->bit_rate != 0)
{ /* Initialization routine for Rate Control */ QP_new = InitializeQuantizer(PCT_INTER, (float)pic->bit_rate, (pic->PB ? pic->target_frame_rate/2 : pic->target_frame_rate), pic->QP_mean); QP_xmitted = QP_prev = QP_new; } else
{ QP_new = QP_xmitted = QP_prev = QP; /* Copy the passed value of QP */ }#else QP_new = QP_xmitted = QP_prev = QP; /* Copy the passed value of QP */#endif dquant = 0; for ( j = 0; j < lines/MB_SIZE; j++)
{#ifndef OFFLINE_RATE_CONTROL if (pic->bit_rate != 0)
{ /* QP updated at the beginning of each row */ AddBitsPicture(bits); QP_new = UpdateQuantizer(abs_mb_num, pic->QP_mean, PCT_INTER, (float)pic->bit_rate, pels/MB_SIZE, lines/MB_SIZE, bits->total); }#endif newgob = 0;
if (j == 0)
{ pic->QUANT = QP_new; bits->header += CountBitsPicture(pic); QP_xmitted = QP_prev = QP_new; } else if (pic->use_gobsync && j%pic->use_gobsync == 0)
{ bits->header += CountBitsSlice(j,QP_new); /* insert gob sync */ QP_xmitted = QP_prev = QP_new; newgob = 1; }
for ( i = 0; i < pels/MB_SIZE; i++)
{ /* Update of dquant, check and correct its limit */ dquant = QP_new - QP_prev; if (dquant != 0 && i != 0 && MV[0][j+1][i+1]->Mode == MODE_INTER4V)
{ dquant = 0; QP_xmitted = QP_prev; QuantChangePostponed = 1; } else
{ QP_xmitted = QP_new; QuantChangePostponed = 0; } if (dquant > 2) { dquant = 2; QP_xmitted = QP_prev + dquant;} if (dquant < -2) { dquant = -2; QP_xmitted = QP_prev + dquant;} pic->DQUANT = dquant; /* modify mode if dquant != 0 (e.g. MODE_INTER -> MODE_INTER_Q) */ Mode = ModifyMode(MV[0][j+1][i+1]->Mode,pic->DQUANT); MV[0][j+1][i+1]->Mode = Mode; pic->MB = i + j * (pels/MB_SIZE);
if (Mode == MODE_INTER || Mode == MODE_INTER_Q || Mode==MODE_INTER4V)
{ /* Predict P-MB */ diff = Predict_P(curr, prev_recon, prev_ipol, i*MB_SIZE, j*MB_SIZE, MV, pic->PB); } else
{ diff = (MB_Structure *)malloc(sizeof(MB_Structure)); FillLumBlock_MY(i*MB_SIZE, j*MB_SIZE, curr, diff); FillChromBlock_MY(i*MB_SIZE, j*MB_SIZE, curr, diff); } /* P or INTRA Macroblock */ qcoeff_P = MB_Encode(diff, QP_xmitted, Mode); CBP = FindCBP(qcoeff_P, Mode, 64); if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q)) ZeroMBlock(diff); else MB_Decode(qcoeff_P, diff, QP_xmitted, Mode);
recon_data_P = MB_Recon_P(prev_recon, prev_ipol,diff, i*MB_SIZE,j*MB_SIZE,MV,pic->PB);
Clip_MY(recon_data_P); free(diff); ZeroVec(MV[5][j+1][i+1]); /* Zero out PB deltas */
if ((CBP==0) && (CBPB==0) && (EqualVec(MV[0][j+1][i+1],&ZERO)) && (EqualVec(MV[5][j+1][i+1],&ZERO)) && (Mode == MODE_INTER || Mode == MODE_INTER_Q))
{ /* Skipped MB : both CBP and CBPB are zero, 16x16 vector is zero, PB delta vector is zero and Mode = MODE_INTER */ if (Mode == MODE_INTER_Q)
{ /* DQUANT != 0 but not coded anyway */ QP_xmitted = QP_prev; pic->DQUANT = 0; Mode = MODE_INTER; } CountBitsMB(Mode,1,CBP,CBPB,pic,bits); } else { /* Normal MB */ /* VLC */ CountBitsMB(Mode,0,CBP,CBPB,pic,bits); if (Mode == MODE_INTER || Mode == MODE_INTER_Q)
{ bits->no_inter++; CountBitsVectors(MV, bits, i, j, Mode, newgob, pic); } else if (Mode == MODE_INTER4V)
{ bits->no_inter4v++; CountBitsVectors(MV, bits, i, j, Mode, newgob, pic); } else
{ /* MODE_INTRA or MODE_INTRA_Q */ bits->no_intra++; if (pic->PB) CountBitsVectors(MV, bits, i, j, Mode, newgob, pic); } if (CBP || Mode == MODE_INTRA || Mode == MODE_INTRA_Q) CountBitsCoeff_MY(qcoeff_P, Mode, CBP, bits, 64); if (CBPB) CountBitsCoeff_MY(qcoeff_B, MODE_INTER, CBPB, bits, 64); QP_prev = QP_xmitted; }
abs_mb_num++; QP_cumulative += QP_xmitted; #ifdef PRINTQ /* most useful when quantizer changes within a picture */ if (QuantChangePostponed) fprintf(stdout,"@%2d",QP_xmitted); else fprintf(stdout," %2d",QP_xmitted);#endif
ReconImage_MY(i,j,recon_data_P,recon); free(recon_data_P); free(qcoeff_P);
}#ifdef PRINTQ fprintf(stdout,"\n");#endif } pic->QP_mean = QP_cumulative/(float)abs_mb_num; /* Free memory */ free(pi); 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;}PictImage *CodeOneIntra(PictImage *curr, int QP, Bits *bits, Pict *pic){ PictImage *recon; MB_Structure *data = (MB_Structure *)malloc(sizeof(MB_Structure)); short 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_MY(i*MB_SIZE, j*MB_SIZE, curr, data); FillChromBlock_MY(i*MB_SIZE, j*MB_SIZE, curr, data); qcoeff = MB_Encode(data, QP, Mode); CBP = FindCBP(qcoeff,Mode,64);
CountBitsMB(Mode,COD,CBP,0,pic,bits); CountBitsCoeff_MY(qcoeff, Mode, CBP,bits,64); MB_Decode(qcoeff, data, QP, Mode);/* Clip(data);*//* ReconImage(i,j,data,recon);*/
Clip_MY(data);
ReconImage_MY(i,j,data,recon); free(qcoeff); } } pic->QP_mean = (float)QP; free(data); return recon;}short int *MB_Encode(MB_Structure *mb_orig, int QP, int I){ int i, j, k, l, row, col; short int fblock[64]; short int coeff[384]; short int *coeff_ind; short int *qcoeff; short int *qcoeff_ind;
int *pp1, *pp2; if ((qcoeff=(short int *)malloc(sizeof(short 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)
{
pp1 = (int *)(&(mb_orig->lum[k][l]));
pp2 = (int *)fblock;
for( i=0; i<8; i++ )
{
pp2[0] = pp1[0];
pp2[1] = pp1[1];
pp2[2] = pp1[2];
pp2[3] = pp1[3];
pp1 += 8;
pp2 += 4;
}
Dct(fblock,coeff_ind); Quant_MY(coeff_ind,qcoeff_ind,QP,I); coeff_ind += 64; qcoeff_ind += 64; } }
pp1 = (int *)(mb_orig->Cb[0]);
pp2 = (int *)fblock;
for( i=0; i<8; i++ )
{
pp2[0] = pp1[0];
pp2[1] = pp1[1];
pp2[2] = pp1[2];
pp2[3] = pp1[3];
pp1 += 4;
pp2 += 4;
}
Dct(fblock,coeff_ind);
Quant_MY(coeff_ind,qcoeff_ind,QP,I); coeff_ind += 64; qcoeff_ind += 64;
pp1 = (int *)(mb_orig->Cr[0]);
pp2 = (int *)fblock;
for( i=0; i<8; i++ )
{
pp2[0] = pp1[0];
pp2[1] = pp1[1];
pp2[2] = pp1[2];
pp2[3] = pp1[3];
pp1 += 4;
pp2 += 4;
}
Dct(fblock,coeff_ind);
Quant_MY(coeff_ind,qcoeff_ind,QP,I); return qcoeff;} int MB_Decode(short int *qcoeff, MB_Structure *mb_recon, int QP, int I){ int i, j, k, l, row, col; short int *iblock; short int *qcoeff_ind; short int *rcoeff, *rcoeff_ind;
int *pp1, *pp2; if ((iblock = (short int *)malloc(sizeof(short int)*64)) == NULL)
{ fprintf(stderr,"MB_Coder: Could not allocate space for iblock\n"); exit(-1); } if ((rcoeff = (short int *)malloc(sizeof(short int)*384)) == NULL)
{ fprintf(stderr,"MB_Coder: Could not allocate space for rcoeff\n"); exit(-1); }
pp1 = (int *)(mb_recon->lum[0]);
for( i=0; i<8; i++ )
{
pp1[0] = 0;
pp1[1] = 0;
pp1[2] = 0;
pp1[3] = 0;
pp1[4] = 0;
pp1[5] = 0;
pp1[6] = 0;
pp1[7] = 0;
pp1 += 8;
}
pp1 = (int *)(mb_recon->Cb[0]);
pp2 = (int *)(mb_recon->Cr[0]);
for( i=0; i<4; i++ )
{
pp1[0] = 0;
pp1[1] = 0;
pp1[2] = 0;
pp1[3] = 0;
pp2[0] = 0;
pp2[1] = 0;
pp2[2] = 0;
pp2[3] = 0;
pp1 += 4;
pp2 += 4;
}
qcoeff_ind = qcoeff; rcoeff_ind = rcoeff; for (k=0;k<16;k+=8)
{ for (l=0;l<16;l+=8)
{
Dequant_MY(qcoeff_ind,rcoeff_ind,QP,I); idct(rcoeff_ind,iblock);
/* Idct_MY(rcoeff_ind,iblock);*/ qcoeff_ind += 64; rcoeff_ind += 64;
pp1 = (int *)(&(mb_recon->lum[k][l]));
pp2 = (int *)iblock;
for( i=0; i<8; i++ )
{
pp1[0] = pp2[0];
pp1[1] = pp2[1];
pp1[2] = pp2[2];
pp1[3] = pp2[3];
pp1 += 8;
pp2 += 4;
}
} }
Dequant_MY(qcoeff_ind,rcoeff_ind,QP,I); idct(rcoeff_ind,iblock);
/* Idct_MY(rcoeff_ind,iblock); */ qcoeff_ind += 64; rcoeff_ind += 64;
pp1 = (int *)(mb_recon->Cb[0]);
pp2 = (int *)iblock;
for( i=0; i<8; i++ )
{
pp1[0] = pp2[0];
pp1[1] = pp2[1];
pp1[2] = pp2[2];
pp1[3] = pp2[3];
pp1 += 4;
pp2 += 4;
}
Dequant_MY(qcoeff_ind,rcoeff_ind,QP,I); idct(rcoeff_ind,iblock);
/* Idct_MY(rcoeff_ind,iblock);*/
pp1 = (int *)(mb_recon->Cr[0]);
pp2 = (int *)iblock;
for( i=0; i<8; i++ )
{
pp1[0] = pp2[0];
pp1[1] = pp2[1];
pp1[2] = pp2[2];
pp1[3] = pp2[3];
pp1 += 4;
pp2 += 4;
}
free(iblock); free(rcoeff); return 0;}void ZeroMBlock(MB_Structure *data){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -