📄 countbit.c
字号:
/************************************************************************ *编码数据流生成 * ************************************************************************/#include"sim.h"#include"sactbls.h"#include"indices.h"#include "putvlc.h" int arith_used = 0;/********************************************************************** * * Name: CountBitsMB * Description: counts bits used for MB info * * Input: Mode, COD, CBP, Picture and Bits structures * Returns: * Side effects: * * Date: 941129 Author: Karl.Lillevold@nta.no * ***********************************************************************/void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits){ int cbpy, cbpcm, length; /* COD */ if (trace) { fprintf(tf,"MB-nr: %d",pic->MB); if (pic->picture_coding_type == PCT_INTER) fprintf(tf," COD: %d\n",COD); } if (pic->picture_coding_type == PCT_INTER) { putbits(1,COD); bits->COD++; } if (COD) return; /* not coded */ /* CBPCM */ cbpcm = Mode | ((CBP&3)<<4); if (trace) { fprintf(tf,"CBPCM (CBP=%d) (cbpcm=%d): ",CBP,cbpcm); } if (pic->picture_coding_type == PCT_INTRA) length = put_cbpcm_intra (CBP, Mode); else length = put_cbpcm_inter (CBP, Mode); bits->CBPCM += length; /* MODB & CBPB */ if (pic->PB) { switch (pic->MODB) { case PBMODE_NORMAL: putbits(1,0); bits->MODB += 1; break; case PBMODE_MVDB: putbits(2,2); bits->MODB += 2; break; case PBMODE_CBPB_MVDB: putbits(2,3); bits->MODB += 2; /* CBPB */ putbits(6,CBPB); bits->CBPB += 6; break; } if (trace) fprintf(tf,"MODB: %d, CBPB: %d\n", pic->MODB, CBPB); } /* CBPY */ cbpy = CBP>>2; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */ cbpy = cbpy^15; if (trace) { fprintf(tf,"CBPY (CBP=%d) (cbpy=%d): ",CBP,cbpy); } length = put_cbpy (CBP, Mode); bits->CBPY += length; /* DQUANT */ if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)) { if (trace) { fprintf(tf,"DQUANT: "); } switch (pic->DQUANT) { case -1: putbits(2,0); break; case -2: putbits(2,1); break; case 1: putbits(2,2); break; case 2: putbits(2,3); break; default: fprintf(stderr,"Invalid DQUANT\n"); exit(-1); } bits->DQUANT += 2; } return;}/********************************************************************** * * Name: Count_sac_BitsMB * Description: counts bits used for MB info using SAC models * modified from CountBitsMB * * Input: Mode, COD, CBP, Picture and Bits structures * Returns: none * Side effects: Updates Bits structure. * * Author: pmulroy@visual.bt.co.uk * ***********************************************************************/ void Count_sac_BitsMB(int Mode,int COD,int CBP,int CBPB,Pict *pic,Bits *bits){ int cbpy, cbpcm, length, i; arith_used = 1; /* COD */ if (trace) { fprintf(tf,"MB-nr: %d",pic->MB); if (pic->picture_coding_type == PCT_INTER) fprintf(tf," COD: %d ",COD); } if (pic->picture_coding_type == PCT_INTER) bits->COD+=AR_Encode(COD, cumf_COD); if (COD) return; /* not coded */ /* CBPCM */ cbpcm = Mode | ((CBP&3)<<4); if (trace) { fprintf(tf,"CBPCM (CBP=%d) (cbpcm=%d): ",CBP,cbpcm); } if (pic->picture_coding_type == PCT_INTRA) length = AR_Encode(indexfn(cbpcm,mcbpc_intratab,9),cumf_MCBPC_intra); else length = AR_Encode(indexfn(cbpcm,mcbpctab,21),cumf_MCBPC); bits->CBPCM += length; /* MODB & CBPB */ if (pic->PB) { switch (pic->MODB) { case PBMODE_NORMAL: bits->MODB += AR_Encode(0, cumf_MODB); break; case PBMODE_MVDB: bits->MODB += AR_Encode(1, cumf_MODB); break; case PBMODE_CBPB_MVDB: bits->MODB += AR_Encode(2, cumf_MODB); /* CBPB */ for(i=5; i>1; i--) bits->CBPB += AR_Encode(((CBPB & 1<<i)>>i), cumf_YCBPB); for(i=1; i>-1; i--) bits->CBPB += AR_Encode(((CBPB & 1<<i)>>i), cumf_UVCBPB); break; } if (trace) fprintf(tf,"MODB: %d, CBPB: %d\n", pic->MODB, CBPB); } /* CBPY */ cbpy = CBP>>2; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { /* Intra */ length = AR_Encode(indexfn(cbpy,cbpy_intratab,16),cumf_CBPY_intra); } else { length = AR_Encode(indexfn(cbpy,cbpytab,16),cumf_CBPY); } if (trace) { fprintf(tf,"CBPY (CBP=%d) (cbpy=%d): ",CBP,cbpy); } bits->CBPY += length; /* DQUANT */ if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)) { if (trace) { fprintf(tf,"DQUANT: "); } bits->DQUANT += AR_Encode(indexfn(pic->DQUANT+2,dquanttab,4), cumf_DQUANT); } return;}/********************************************************************** * * Name: CountBitsSlice * Description: couonts bits used for slice (GOB) info * * Input: slice no., quantizer * * Date: 94???? Author: Karl.Lillevold@nta.no * ***********************************************************************/int CountBitsSlice(int slice, int quant){ int bits = 0; if (arith_used) { bits+=encoder_flush(); /* Need to call before fixed length string output */ arith_used = 0; } /* Picture Start Code */ if (trace) fprintf(tf,"GOB sync (GBSC): "); putbits(PSC_LENGTH,PSC); /* PSC */ bits += PSC_LENGTH; /* Group Number */ if (trace) fprintf(tf,"GN: "); putbits(5,slice); bits += 5; /* GOB Sub Bitstream Indicator */ /* if CPM == 1: read 2 bits GSBI */ /* not supported in this version */ /* GOB Frame ID */ if (trace) fprintf(tf,"GFID: "); putbits(2, 0); /* NB: in error-prone environments this value should change if PTYPE in picture header changes. In this version of the encoder PTYPE only changes when PB-frames are used in the following cases: (i) after the first intra frame (ii) if the distance between two P-frames is very large Therefore I haven't implemented this GFID change */ /* GFID is not allowed to change unless PTYPE changes */ bits += 2; /* Gquant */ if (trace) fprintf(tf,"GQUANT: "); putbits(5,quant); bits += 5; return bits;}/********************************************************************** * * Name: CountBitsCoeff * Description: counts bits used for coeffs * * Input: qcoeff, coding mode CBP, bits structure, no. of * coeffs * * Returns: struct with no. of bits used * Side effects: * * Date: 940111 Author: Karl.Lillevold@nta.no * ***********************************************************************/void CountBitsCoeff(int *qcoeff, int Mode, int CBP, Bits *bits, int ncoeffs){ int i; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { for (i = 0; i < 4; i++) { bits->Y += CodeCoeff(Mode, qcoeff,i,ncoeffs); } for (i = 4; i < 6; i++) { bits->C += CodeCoeff(Mode, qcoeff,i,ncoeffs); } } else { for (i = 0; i < 4; i++) { if ((i==0 && CBP&32) || (i==1 && CBP&16) || (i==2 && CBP&8) || (i==3 && CBP&4) || (i==4 && CBP&2) || (i==5 && CBP&1)) { bits->Y += CodeCoeff(Mode, qcoeff, i, ncoeffs); } } for (i = 4; i < 6; i++) { if ((i==0 && CBP&32) || (i==1 && CBP&16) || (i==2 && CBP&8) || (i==3 && CBP&4) || (i==4 && CBP&2) || (i==5 && CBP&1)) { bits->C += CodeCoeff(Mode, qcoeff, i, ncoeffs); } } } return;} int CodeCoeff(int Mode, int *qcoeff, int block, int ncoeffs){ int j, bits; int prev_run, run, prev_level, level, first; int prev_s, s, length; run = bits = 0; first = 1; prev_run = prev_level = level = s = prev_s = 0; if (trace) { fprintf(tf,"Coeffs block %d:\n",block); } for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) { /* Do this block's DC-coefficient first */ if (!(j%ncoeffs) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) { /* DC coeff */ if (trace) { fprintf(tf,"DC: "); } if (qcoeff[block*ncoeffs] != 128) putbits(8,qcoeff[block*ncoeffs]); else putbits(8,255); bits += 8; } else { /* AC coeff */ s = 0; /* Increment run if coeff is zero */ if ((level = qcoeff[j]) == 0) { run++; } else { /* code run & level and count bits */ if (level < 0) { s = 1; level = -level; } if (!first) { /* Encode the previous coefficient */ if (prev_level < 13 && prev_run < 64) length = put_coeff (prev_run, prev_level, 0); else length = 0; if (length == 0) { /* Escape coding */ if (trace) { fprintf(tf,"Escape code: "); } if (prev_s == 1) {prev_level = (prev_level^0xff)+1;} putbits(7,3); /* Escape code */ if (trace) fprintf(tf,"last: "); putbits(1,0); if (trace) fprintf(tf,"run: "); putbits(6,prev_run); if (trace) fprintf(tf,"level: "); putbits(8,prev_level); bits += 22; } else { putbits(1,prev_s); bits += length + 1; } } prev_run = run; prev_s = s; prev_level = level; run = first = 0; } } } /* Encode the last coeff */ if (!first) { if (trace) { fprintf(tf,"Last coeff: "); } if (prev_level < 13 && prev_run < 64) length = put_coeff (prev_run, prev_level, 1); else length = 0; if (length == 0) { /* Escape coding */ if (trace) { fprintf(tf,"Escape code: "); } if (prev_s == 1) {prev_level = (prev_level^0xff)+1;} putbits (7,3); /* Escape code */ if (trace) fprintf(tf,"last: "); putbits(1,1); if (trace) fprintf(tf,"run: "); putbits(6,prev_run); if (trace) fprintf(tf,"level: "); putbits(8,prev_level); bits += 22; } else { putbits(1,prev_s); bits += length + 1; } } return bits;}/********************************************************************** * * Name: Count_sac_BitsCoeff * counts bits using SAC models * * Input: qcoeff, coding mode CBP, bits structure, no. of * coeffs * * Returns: struct with no. of bits used * Side effects: * * Author: pmulroy@visual.bt.co.uk * ***********************************************************************/ void Count_sac_BitsCoeff(int *qcoeff,int Mode,int CBP,Bits *bits,int ncoeffs){ int i; arith_used = 1; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { for (i = 0; i < 4; i++) { bits->Y += Code_sac_Coeff(Mode, qcoeff,i,ncoeffs); } for (i = 4; i < 6; i++) { bits->C += Code_sac_Coeff(Mode, qcoeff,i,ncoeffs); } } else { for (i = 0; i < 4; i++) { if ((i==0 && CBP&32) || (i==1 && CBP&16) || (i==2 && CBP&8) || (i==3 && CBP&4) || (i==4 && CBP&2) || (i==5 && CBP&1)) { bits->Y += Code_sac_Coeff(Mode, qcoeff, i, ncoeffs); } } for (i = 4; i < 6; i++) { if ((i==0 && CBP&32) || (i==1 && CBP&16) || (i==2 && CBP&8) || (i==3 && CBP&4) || (i==4 && CBP&2) || (i==5 && CBP&1)) { bits->C += Code_sac_Coeff(Mode, qcoeff, i, ncoeffs); } } } return;} int Code_sac_Coeff(int Mode, int *qcoeff, int block, int ncoeffs){ int j, bits, mod_index, intra; int prev_run, run, prev_level, level, first, prev_position, position; int prev_ind, ind, prev_s, s, length; run = bits = 0; first = 1; position = 0; intra = 0; level = s = ind = 0; prev_run = prev_level = prev_ind = prev_s = prev_position = 0; intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q); for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) { if (!(j%ncoeffs) && intra) { if (trace) { fprintf(tf,"DC: "); } if (qcoeff[block*ncoeffs]!=128) mod_index = indexfn(qcoeff[block*ncoeffs],intradctab,254); else mod_index = indexfn(255,intradctab,254); bits += AR_Encode(mod_index, cumf_INTRADC); } else { s = 0; /* Increment run if coeff is zero */ if ((level = qcoeff[j]) == 0) { run++; } else { /* code run & level and count bits */ if (level < 0) { s = 1; level = -level; } ind = level | run<<4; ind = ind | 0<<12; /* Not last coeff */ position++; if (!first) { mod_index = indexfn(prev_ind, tcoeftab, 103); if (prev_level < 13 && prev_run < 64) length = CodeTCoef(mod_index, prev_position, intra); else length = -1; if (length == -1) { /* Escape coding */ if (trace) { fprintf(tf,"Escape coding:\n"); } if (prev_s == 1) {prev_level = (prev_level^0xff)+1;} mod_index = indexfn(ESCAPE, tcoeftab, 103); bits += CodeTCoef(mod_index, prev_position, intra); if (intra) bits += AR_Encode(indexfn(0, lasttab, 2), cumf_LAST_intra); else bits += AR_Encode(indexfn(0, lasttab, 2), cumf_LAST); if (intra) bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN_intra); else bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN); if (intra) bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL_intra); else bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL); } else { bits += AR_Encode(indexfn(prev_s, signtab, 2), cumf_SIGN); bits += length; } } prev_run = run; prev_s = s; prev_level = level; prev_ind = ind; prev_position = position; run = first = 0; } } } /* Encode Last Coefficient */ if (!first) { if (trace) { fprintf(tf,"Last coeff: "); } prev_ind = prev_ind | 1<<12; /* last coeff */ mod_index = indexfn(prev_ind, tcoeftab, 103); if (prev_level < 13 && prev_run < 64) length = CodeTCoef(mod_index, prev_position, intra); else length = -1; if (length == -1) { /* Escape coding */ if (trace) { fprintf(tf,"Escape coding:\n"); } if (prev_s == 1) {prev_level = (prev_level^0xff)+1;} mod_index = indexfn(ESCAPE, tcoeftab, 103); bits += CodeTCoef(mod_index, prev_position, intra); if (intra) bits += AR_Encode(indexfn(1, lasttab, 2), cumf_LAST_intra); else bits += AR_Encode(indexfn(1, lasttab, 2), cumf_LAST); if (intra) bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN_intra); else bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN); if (intra) bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL_intra); else bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL); } else { bits += AR_Encode(indexfn(prev_s, signtab, 2), cumf_SIGN); bits += length; } } /* last coeff */ return bits;} /********************************************************************* * * Name: CodeTCoef * * Description: Encodes an AC Coefficient using the * relevant SAC model. * * Input: Model index, position in DCT block and intra/ * inter flag. * * Returns: Number of bits used.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -