📄 coder.c
字号:
/************************************************* * libr263: fast H.263 encoder library * * Copyright (C) 1996, Roalt Aalmoes, Twente University * SPA multimedia group * * Based on Telenor TMN 1.6 encoder (Copyright (C) 1995, Telenor R&D) * created by Karl Lillevold * * Author encoder: Roalt Aalmoes, <aalmoes@huygens.nl> * * Date: 31-07-96 **************************************************/ /* Modyfied by Roalt Aalmoes with better algorithms and performance * objectives * * Warning: Although I tried to remove all advanced options code, * there might still be some artifacts in the code. Please do not * blame me for not removing all of it. * Removing all advanced and alternating quantization code was done * for performance reasons. I'm sorry these options are not * implemented here, but see the tmn1.7 code for a slow functioning * advanced H.263 compression algorithm. *****************************************************************//* Notes for clear code: *//* var. j is used for row indexing of MB in frame *//* var. i is used for column indexing of MB in frame *//* pic is declared global *//* MV is changed: it is now a real array of MV instead of array of pointers to MV. Its range is also equal to MVs encoded, without border MVs Advantages: No more mallocs and frees in the code, disadvantages: ?? *//* PictImage structure is replaced by int pointer. Drawback: not flexible for other format. */#include"sim.h"/********************************************************************** * * Name: Clip * Description: clips recontructed data 0-255 * * Input: pointer to recon. data structure * Side effects: data structure clipped * * Date: 960715 Author: Roalt Aalmoes * ***********************************************************************/__inline__ void Clip(MB_Structure *data) { int n; int *mb_ptr = (int *) data; for (n = 0; n < 256 + 64 + 64; n++) { *mb_ptr = mmin(255,mmax(0,*mb_ptr)); mb_ptr++; }}/* Encodes one frame intra using params */void CodeIntraH263(CParam *params, Bits *bits){ unsigned int *new_recon; MB_Structure *data = (MB_Structure *)malloc(sizeof(MB_Structure)); int *qcoeff; int Mode = MODE_INTRA; int CBP; int i,j; new_recon = params->recon; ZeroBits(bits); pic->QUANT = params->Q_intra; pic->picture_coding_type = PCT_INTRA; bits->header += CountBitsPicture(pic); for ( j = 0; j < mbr; j++) { /* insert sync in *every* slice if use_gobsync is chosen */ if (pic->use_gobsync && j != 0) bits->header += CountBitsSlice(j,params->Q_intra); for ( i = 0; i < mbc; i++) { pic->MB = i + j * mbc; bits->no_intra++; FillLumBlock(i*MB_SIZE, j*MB_SIZE, params->data, data); FillChromBlock(i*MB_SIZE, j*MB_SIZE, params->data, data); qcoeff = MB_EncodeAndFindCBP(data, params->Q_intra, Mode, &CBP); /* Do standard VLC encoding */ /* COD = 0 ,Every block is coded as Intra frame */ CountBitsMB(Mode,0,CBP,0,pic,bits); CountBitsCoeff(qcoeff, Mode, CBP,bits,64); MB_Decode(qcoeff, data, params->Q_intra, Mode); Clip(data); ReconImage(i,j,data,new_recon); free(qcoeff); } } pic->QP_mean = params->Q_intra; params->recon = new_recon; AddBitsPicture(bits); free(data); return;}/********************************************************************** * * 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: * * Date: 930128 Author: Robert.Danielsen@nta.no * **********************************************************************//* If you compare original quant with FindCBP, you see they both act on the same range of coefficients in the cases INTRA (1..63) or INTER (0..63) */int *MB_EncodeAndFindCBP(MB_Structure *mb_orig, int QP, int I, int *CBP){ int i, j, k, l, row, col; int fblock[64]; int coeff[384]; int *coeff_ind; int *qcoeff; int *qcoeff_ind; int CBP_Mask = 32; *CBP = 0; /* CBP gives bit pattern of lowest 6 bits that specify which coordinates are not zero. Bits 6 (32) to 2 (4) repr. four 8x8 Y parts of macroblock, while bits 1 (2) and 0 (1) repr. resp. the U and V component */ if ((qcoeff=(int *)malloc(sizeof(int)*384)) == 0) { fprintf(stderr,"mb_encode(): Couldn't allocate qcoeff.\n"); exit(0); } 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) {#if LONGISDOUBLEINT for (j=l,col=0;col<8;j += 2,col +=2 ) { *(long *) (fblock+row+col) = * (long *) &(mb_orig->lum[i][j]); }#else for (j=l,col=0;col<8;j++ , col++ ) { *(int *) (fblock+row+col) = * (int *) &(mb_orig->lum[i][j]); }#endif } Dct(fblock,coeff_ind); *CBP |= QuantAndFindCBP(coeff_ind,qcoeff_ind,QP,I,CBP_Mask); coeff_ind += 64; qcoeff_ind += 64; CBP_Mask = CBP_Mask>>1; } /* end l */ } /* End k */ for (i=0;i<8;i++) {#ifdef LONGISDOUBLEINT for (j=0;j<8;j += 2) { *(long *) (fblock+i*8+j) = *(long *) &(mb_orig->Cb[i][j]); }#else for (j=0;j<8;j++) { *(int *) (fblock+i*8+j) = *(int *) &(mb_orig->Cb[i][j]); } #endif } Dct(fblock,coeff_ind); *CBP |= QuantAndFindCBP(coeff_ind,qcoeff_ind,QP,I,CBP_Mask /* i == 4 */); coeff_ind += 64; qcoeff_ind += 64; CBP_Mask = CBP_Mask>>1; for (i=0;i<8;i++) {#ifdef LONGISDOUBLEINT for (j=0;j<8;j += 2) { * (long *) (fblock+i*8+j) = *(long *) &(mb_orig->Cr[i][j]); }#else for (j=0;j<8;j ++) { * (int *) (fblock+i*8+j) = *(int *) &(mb_orig->Cr[i][j]); }#endif } Dct(fblock,coeff_ind); *CBP |= QuantAndFindCBP(coeff_ind,qcoeff_ind,QP,I, CBP_Mask /* i == 5 */); 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: * * Date: 930128 Author: Robert.Danielsen@nta.no * **********************************************************************/ 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++)#ifdef LONGISDOUBLEINT for (j = 0; j < 8; j+=2) *(long *) &(mb_recon->lum[i][j]) = 0L;#else for (j = 0; j < 8; j++) *(int *) &(mb_recon->lum[i][j]) = 0;#endif for (i = 0; i < 8; i++) #ifdef LONGISDOUBLEINT for (j = 0; j < 8; j += 2) { *(long *) &(mb_recon->Cb[i][j]) = 0L; *(long *) &(mb_recon->Cr[i][j]) = 0L; }#else for (j = 0; j < 8; j ++) { *(int *) &(mb_recon->Cb[i][j]) = 0; *(int *) &(mb_recon->Cr[i][j]) = 0; }#endif 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);#ifdef STANDARDIDCT 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) {#ifdef LONGISDOUBLEINT for (j=l,col=0;col<8;j += 2,col += 2) { *(long *) &(mb_recon->lum[i][j]) = * (long *) (iblock+row+col); }#else for (j=l,col=0;col<8; j++, col++) { *(int *) &(mb_recon->lum[i][j]) = * (int *) (iblock+row+col); }#endif } } } Dequant(qcoeff_ind,rcoeff_ind,QP,I);#ifdef STANDARDIDCT idctref(rcoeff_ind,iblock); #else idct(rcoeff_ind,iblock); #endif qcoeff_ind += 64; rcoeff_ind += 64; for (i=0;i<8;i++) {#ifdef LONGISDOUBLEINT for (j=0;j<8;j +=2 ) { *(long *) &(mb_recon->Cb[i][j]) = *(long *) (iblock+i*8+j); }#else for (j=0;j<8;j++ ) { *(int *) &(mb_recon->Cb[i][j]) = *(int *) (iblock+i*8+j); }#endif } Dequant(qcoeff_ind,rcoeff_ind,QP,I);#ifdef STANDARDIDCT idctref(rcoeff_ind,iblock); #else idct(rcoeff_ind,iblock); #endif for (i=0;i<8;i++) {#ifdef LONGISDOUBLEINT for (j=0;j<8;j += 2) { *(long *) &(mb_recon->Cr[i][j]) = *(long *) (iblock+i*8+j); }#else for (j=0;j<8;j++) { *(int *) &(mb_recon->Cr[i][j]) = *(int *) (iblock+i*8+j); }#endif } free(iblock); free(rcoeff); return 0;}/********************************************************************** * * Name: FillLumBlock * Description: Fills the luminance of one block of lines*pels * * Input: Position, pointer to qcif, array to fill * Returns: * Side effects: fills array * * Date: 930129 Author: Karl.Lillevold@nta.no * ***********************************************************************/void FillLumBlock( int x, int y, unsigned int *image, MB_Structure *data){ int n, m; /* OPTIMIZE HERE */ /* m -> int conversion is done here, so no long optimiz. possible */ for (n = 0; n < MB_SIZE; n++) for (m = 0; m < MB_SIZE; m++) data->lum[n][m] = (int) (*(image + x+m + (y+n)*pels)); return;}/********************************************************************** * * Name: FillChromBlock * Description: Fills the chrominance of one block of qcif * * Input: Position, pointer to qcif, array to fill * Returns: * Side effects: fills array * 128 subtracted from each * * Date: 930129 Author: Karl.Lillevold@nta.no * ***********************************************************************/void FillChromBlock(int x_curr, int y_curr, unsigned int *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 + vskip + x+m + (y+n)*cpels)); data->Cb[n][m] = (int) (*(image + uskip + x+m + (y+n)*cpels)); } return;}/********************************************************************** * * Name: ZeroMBlock * Description: Fills one MB with Zeros * * Input: MB_Structure to zero out * Returns: * Side effects: * * Date: 940829 Author: Karl.Lillevold@nta.no * ***********************************************************************/void ZeroMBlock(MB_Structure *data){ int n; register int m; /* ALPHA optimization */#ifdef LONGISDOUBLEINT for (n = 0; n < MB_SIZE; n++) for (m = 0; m < MB_SIZE; m +=2 ) *(long *) &(data->lum[n][m]) = 0L; for (n = 0; n < (MB_SIZE>>1); n++) for (m = 0; m < (MB_SIZE>>1); m +=2 ) { *(long *) &(data->Cr[n][m]) = 0L; *(long *) &(data->Cb[n][m]) = 0L; }#else for (n = 0; n < MB_SIZE; n++) for (m = 0; m < MB_SIZE; m++ ) *(int *) &(data->lum[n][m]) = 0; for (n = 0; n < (MB_SIZE>>1); n++) for (m = 0; m < (MB_SIZE>>1); m++ ) { *(int *) &(data->Cr[n][m]) = 0; *(int *) &(data->Cb[n][m]) = 0; }#endif return;}/********************************************************************** * * Name: ReconImage * Description: Puts together reconstructed image * * Input: position of curr block, reconstructed * macroblock, pointer to recontructed image * Returns: * Side effects: * * Date: 930123 Author: Karl.Lillevold@nta.no * ***********************************************************************/void ReconImage (int i, int j, MB_Structure *data, unsigned int *recon){ int n; int x_curr, y_curr; int *lum_ptr, *Cb_ptr, *Cr_ptr; unsigned int *recon_ptr, *recon_Cb_ptr, *recon_Cr_ptr; x_curr = i * MB_SIZE; y_curr = j * MB_SIZE; lum_ptr = &(data->lum[0][0]); recon_ptr = recon + x_curr + y_curr*pels; /* Fill in luminance data */ for (n = 0; n < MB_SIZE; n++) {#ifdef LONGISDOUBLEINT * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += 2; lum_ptr += 2; * (long *) recon_ptr = * (long *) lum_ptr; recon_ptr += pels - 14; lum_ptr += 2; /* Was: for every m = 0..15 : *(recon->lum + x_curr+m + (y_curr+n)*pels) = *(lum_ptr++); */#else * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr++; lum_ptr++; * (int *) recon_ptr = * (int *) lum_ptr; recon_ptr += pels - 15; lum_ptr++;#endif } recon_Cb_ptr = recon+uskip+ (x_curr>>1) + (y_curr>>1)*cpels; recon_Cr_ptr = recon+vskip+ (x_curr>>1) + (y_curr>>1)*cpels; Cb_ptr = &(data->Cb[0][0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -