📄 countbit.c
字号:
#include"sim.h"#include "putvlc.h" int arith_used = 0;void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits){ int cbpy, cbpcm, length; /* 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 (pic->picture_coding_type == PCT_INTRA) length = put_cbpcm_intra (CBP, Mode); else length = put_cbpcm_inter (CBP, Mode); bits->CBPCM += length; /* MODB & CBPB */ /* CBPY */ cbpy = CBP>>2; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */ cbpy = cbpy^15; length = put_cbpy (CBP, Mode); bits->CBPY += length; /* DQUANT */ if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q))
{ 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;}
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 */ putbits(PSC_LENGTH,PSC); /* PSC */ bits += PSC_LENGTH; /* Group Number */ putbits(5,slice); bits += 5; /* GOB Sub Bitstream Indicator */ /* if CPM == 1: read 2 bits GSBI */ /* not supported in this version */ /* GOB Frame ID */ 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 */ putbits(5,quant); bits += 5; return bits;}int FindCBP(short int *qcoeff, int Mode, int ncoeffs){ int i,j; int CBP = 0; int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q); /* Set CBP for this Macroblock */ for (i = 0; i < 6; i++)
{ for (j = i*ncoeffs + intra; j < (i+1)*ncoeffs; j++)
{ if (qcoeff[j])
{ if (i == 0) {CBP |= 32;} else if (i == 1) {CBP |= 16;} else if (i == 2) {CBP |= 8;} else if (i == 3) {CBP |= 4;} else if (i == 4) {CBP |= 2;} else if (i == 5) {CBP |= 1;} else
{ fprintf(stderr,"Error in CBP assignment\n"); exit(-1); } break; } } } return CBP;}void CountBitsVectors(MotionVector *MV[6][MBR+1][MBC+2], Bits *bits, int x, int y, int Mode, int newgob, Pict *pic){ int y_vec, x_vec; int pmv0, pmv1; int start,stop,block; x++;y++; if (Mode == MODE_INTER4V)
{ start = 1; stop = 4; } else
{ start = 0; stop = 0; } for (block = start; block <= stop; block++)
{ FindPMV(MV,x,y,&pmv0,&pmv1, block, newgob, 1); x_vec = (2*MV[block][y][x]->x + MV[block][y][x]->x_half) - pmv0; y_vec = (2*MV[block][y][x]->y + MV[block][y][x]->y_half) - pmv1; if (!long_vectors)
{ if (x_vec < -32) x_vec += 64; else if (x_vec > 31) x_vec -= 64; if (y_vec < -32) y_vec += 64; else if (y_vec > 31) y_vec -= 64; } else
{ if (pmv0 < -31 && x_vec < -63) x_vec += 64; else if (pmv0 > 32 && x_vec > 63) x_vec -= 64; if (pmv1 < -31 && y_vec < -63) y_vec += 64; else if (pmv1 > 32 && y_vec > 63) y_vec -= 64; } if (x_vec < 0) x_vec += 64; if (y_vec < 0) y_vec += 64; bits->vec += put_mv (x_vec); bits->vec += put_mv (y_vec); } return;}void FindPMV(MotionVector *MV[6][MBR+1][MBC+2], int x, int y, int *pmv0, int *pmv1, int block, int newgob, int half_pel){ int p1,p2,p3; int xin1=0,xin2=0,xin3=0; int yin1=0,yin2=0,yin3=0; int vec1=0,vec2=0,vec3=0; int l8,o8,or8; l8 = o8 = or8 = 0; if (MV[0][y][x-1]->Mode == MODE_INTER4V) l8 = 1; if (MV[0][y-1][x]->Mode == MODE_INTER4V) o8 = 1; if (MV[0][y-1][x+1]->Mode == MODE_INTER4V) or8 = 1; switch (block)
{ case 0: vec1 = (l8 ? 2 : 0) ; yin1 = y ; xin1 = x-1; vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x; vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1; break; case 1: vec1 = (l8 ? 2 : 0) ; yin1 = y ; xin1 = x-1; vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x; vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1; break; case 2: vec1 = 1 ; yin1 = y ; xin1 = x; vec2 = (o8 ? 4 : 0) ; yin2 = y-1; xin2 = x; vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1; break; case 3: vec1 = (l8 ? 4 : 0) ; yin1 = y ; xin1 = x-1; vec2 = 1 ; yin2 = y ; xin2 = x; vec3 = 2 ; yin3 = y ; xin3 = x; break; case 4: vec1 = 3 ; yin1 = y ; xin1 = x; vec2 = 1 ; yin2 = y ; xin2 = x; vec3 = 2 ; yin3 = y ; xin3 = x; break; default: fprintf(stderr,"Illegal block number in FindPMV (countbit.c)\n"); exit(-1); break; } if (half_pel)
{ p1 = 2*MV[vec1][yin1][xin1]->x + MV[vec1][yin1][xin1]->x_half; p2 = 2*MV[vec2][yin2][xin2]->x + MV[vec2][yin2][xin2]->x_half; p3 = 2*MV[vec3][yin3][xin3]->x + MV[vec3][yin3][xin3]->x_half; } else
{ p1 = 2*MV[vec1][yin1][xin1]->x; p2 = 2*MV[vec2][yin2][xin2]->x; p3 = 2*MV[vec3][yin3][xin3]->x; } if (newgob && (block == 0 || block == 1 || block == 2)) p2 = 2*NO_VEC; if (p2 == 2*NO_VEC) { p2 = p3 = p1; } *pmv0 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3)); if (half_pel)
{ p1 = 2*MV[vec1][yin1][xin1]->y + MV[vec1][yin1][xin1]->y_half; p2 = 2*MV[vec2][yin2][xin2]->y + MV[vec2][yin2][xin2]->y_half; p3 = 2*MV[vec3][yin3][xin3]->y + MV[vec3][yin3][xin3]->y_half; } else
{ p1 = 2*MV[vec1][yin1][xin1]->y; p2 = 2*MV[vec2][yin2][xin2]->y; p3 = 2*MV[vec3][yin3][xin3]->y; } if (newgob && (block == 0 || block == 1 || block == 2)) p2 = 2*NO_VEC; if (p2 == 2*NO_VEC) { p2 = p3 = p1; } *pmv1 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3)); return;}void ZeroBits(Bits *bits){ bits->Y = 0; bits->C = 0; bits->vec = 0; bits->CBPY = 0; bits->CBPCM = 0; bits->MODB = 0; bits->CBPB = 0; bits->COD = 0; bits->DQUANT = 0; bits->header = 0; bits->total = 0; bits->no_inter = 0; bits->no_inter4v = 0; bits->no_intra = 0; return;}
void ZeroRes(Results *res){ res->SNR_l = (float)0; res->SNR_Cr = (float)0; res->SNR_Cb = (float)0; res->QP_mean = (float)0;}
void AddBits(Bits *total, Bits *bits){ total->Y += bits->Y; total->C += bits->C; total->vec += bits->vec; total->CBPY += bits->CBPY; total->CBPCM += bits->CBPCM; total->MODB += bits->MODB; total->CBPB += bits->CBPB; total->COD += bits->COD; total->DQUANT += bits->DQUANT; total->header += bits->header; total->total += bits->total; total->no_inter += bits->no_inter; total->no_inter4v += bits->no_inter4v; total->no_intra += bits->no_intra; return;}
void AddRes(Results *total, Results *res, Pict *pic){ total->SNR_l += res->SNR_l; total->SNR_Cr += res->SNR_Cr; total->SNR_Cb += res->SNR_Cb; total->QP_mean += pic->QP_mean; return;}void AddBitsPicture(Bits *bits){ bits->total = bits->Y + bits->C + bits->vec + bits->CBPY + bits->CBPCM + bits->MODB + bits->CBPB + bits->COD + bits->DQUANT + bits->header ;}
void ZeroVec(MotionVector *MV){ MV->x = 0; MV->y = 0; MV->x_half = 0; MV->y_half = 0; return;}
void MarkVec(MotionVector *MV){ MV->x = NO_VEC; MV->y = NO_VEC; MV->x_half = 0; MV->y_half = 0; return;}void CopyVec(MotionVector *MV2, MotionVector *MV1){ MV2->x = MV1->x; MV2->x_half = MV1->x_half; MV2->y = MV1->y; MV2->y_half = MV1->y_half; return;}int EqualVec(MotionVector *MV2, MotionVector *MV1){ if (MV1->x != MV2->x) return 0; if (MV1->y != MV2->y) return 0; if (MV1->x_half != MV2->x_half) return 0; if (MV1->y_half != MV2->y_half) return 0; return 1;}int CountBitsPicture(Pict *pic){ int bits = 0; /* in case of arithmetic coding, encoder_flush() has been called before zeroflush() in main.c */ /* Picture start code */ putbits(PSC_LENGTH,PSC); bits += PSC_LENGTH; /* Group number */ putbits(5,0); bits += 5; /* Time reference */ putbits(8,pic->TR); bits += 8; /* bit 1 */ pic->spare = 1; /* always 1 to avoid start code emulation */ putbits(1,pic->spare); bits += 1; /* bit 2 */ putbits(1,0); bits += 1; /* bit 3 */ putbits(1,0); /* no support for split-screen in this software */ bits += 1; /* bit 4 */ putbits(1,0); bits += 1; /* bit 5 */ putbits(1,0); bits += 1; /* bit 6-8 */ putbits(3,pic->source_format); bits += 3; /* bit 9 */ putbits(1,pic->picture_coding_type); bits += 1; /* bit 10 */ putbits(1,pic->unrestricted_mv_mode); /* Unrestricted Motion Vector mode */ bits += 1; /* bit 11 */ putbits(1,syntax_arith_coding); /* Syntax-based Arithmetic Coding mode */ bits += 1; /* bit 12 */ putbits(1,advanced); /* Advanced Prediction mode */ bits += 1; /* bit 13 */ putbits(1,pic->PB); bits += 1; /* QUANT */ putbits(5,pic->QUANT); bits += 5; /* Continuous Presence Multipoint (CPM) */ putbits(1,0); /* CPM is not supported in this software */ bits += 1; /* Picture Sub Bitstream Indicator (PSBI) */ /* if CPM == 1: 2 bits PSBI */ /* not supported */ /* extra information for PB-frames */ /* PEI (extra information) */ /* "Encoders shall not insert PSPARE until specified by the ITU" */ putbits(1,0); bits += 1; /* PSPARE */ /* if PEI == 1: 8 bits PSPARE + another PEI bit */ /* not supported */ return bits;}void CountBitsCoeff_MY(short int *qcoeff, int Mode, int CBP, Bits *bits, int ncoeffs)
{
int i;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
bits->Y += CodeCoeff_MY(Mode, qcoeff,0,ncoeffs);
bits->Y += CodeCoeff_MY(Mode, qcoeff,1,ncoeffs);
bits->Y += CodeCoeff_MY(Mode, qcoeff,2,ncoeffs);
bits->Y += CodeCoeff_MY(Mode, qcoeff,3,ncoeffs);
bits->C += CodeCoeff_MY(Mode, qcoeff,4,ncoeffs);
bits->C += CodeCoeff_MY(Mode, qcoeff,5,ncoeffs);
}
else
{
if( CBP&32 )
bits->Y += CodeCoeff_MY(Mode, qcoeff, 0, ncoeffs);
if( CBP&16 )
bits->Y += CodeCoeff_MY(Mode, qcoeff, 1, ncoeffs);
if( CBP&8 )
bits->Y += CodeCoeff_MY(Mode, qcoeff, 2, ncoeffs);
if( CBP&4 )
bits->Y += CodeCoeff_MY(Mode, qcoeff, 3, ncoeffs);
if( CBP&2 )
bits->C += CodeCoeff_MY(Mode, qcoeff, 4, ncoeffs);
if( CBP&1 )
bits->C += CodeCoeff_MY(Mode, qcoeff, 5, ncoeffs);
}
return;
}
int CodeCoeff_MY(int Mode, short int *qcoeff, int block, int ncoeffs)
{
register int j, bits;
register int prev_run, run, prev_level, level, first;
register int prev_s, s, length;
int *p1;
register int temp0, temp1;
run = bits = 0;
first = 1;
prev_run = prev_level = level = s = prev_s = 0;
p1 = (int *)(qcoeff+block*ncoeffs);
temp0 = p1[0] & 0x0000ffff;
temp1 = p1[0] >> 16;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
/* DC coeff */
if ( temp0 != 128 )
putbits(8,temp0);
else
putbits(8,255);
bits += 8;
}
else
{
/* AC coeff */
s = 0;
/* Increment run if coeff is zero */
if ((level = temp0) == 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 (prev_s == 1)
{prev_level = -prev_level;}
putbits(7,3); /* Escape code */
putbits(1,0);
putbits(6,prev_run);
putbits(8,prev_level);
bits += 22;
}
else
{
putbits(1,prev_s);
bits += length + 1;
}
}
else
{
first = 0;
}
prev_run = run;
prev_s = s;
prev_level = level;
run = 0;
}
}
s = 0;
if ((level = temp1) == 0)
{
run++;
}
else
{
if (level < 0)
{
s = 1;
level = -level;
}
if (!first)
{
if (prev_level<13 && prev_run<64)
length = put_coeff(prev_run, prev_level, 0);
else
length = 0;
if (length == 0)
{
if (prev_s == 1)
{prev_level = -prev_level;}
putbits(7,3);
putbits(1,0);
putbits(6,prev_run);
putbits(8,prev_level);
bits += 22;
}
else
{
putbits(1,prev_s);
bits += length + 1;
}
}
else
{
first = 0;
}
prev_run = run;
prev_s = s;
prev_level = level;
run = 0;
}
for (j=1; j<ncoeffs>>1; j++)
{
temp0 = p1[j] & 0x0000ffff;
temp1 = p1[j] >> 16;
s = 0;
if ((level = temp0) == 0)
{
run++;
}
else
{
if (level < 0)
{
s = 1;
level = -level;
}
if (!first)
{
if (prev_level<13 && prev_run<64)
length = put_coeff(prev_run, prev_level, 0);
else
length = 0;
if (length == 0)
{
if (prev_s == 1)
{prev_level = -prev_level;}
putbits(7,3);
putbits(1,0);
putbits(6,prev_run);
putbits(8,prev_level);
bits += 22;
}
else
{
putbits(1,prev_s);
bits += length + 1;
}
}
else
{
first = 0;
}
prev_run = run;
prev_s = s;
prev_level = level;
run = 0;
}
s = 0;
if ((level = temp1) == 0)
{
run++;
}
else
{
if (level < 0)
{
s = 1;
level = -level;
}
if (!first)
{
if (prev_level<13 && prev_run<64)
length = put_coeff(prev_run, prev_level, 0);
else
length = 0;
if (length == 0)
{
if (prev_s == 1)
{prev_level = -prev_level;}
putbits(7,3);
putbits(1,0);
putbits(6,prev_run);
putbits(8,prev_level);
bits += 22;
}
else
{
putbits(1,prev_s);
bits += length + 1;
}
}
else
{
first = 0;
}
prev_run = run; prev_s = s;
prev_level = level;
run = 0;
}
}
/* Encode the last coeff */
if (!first)
{
if (prev_level < 13 && prev_run < 64)
length = put_coeff(prev_run, prev_level, 1);
else
length = 0;
if (length == 0)
{ /* Escape coding */
if (prev_s == 1)
{prev_level = -prev_level;}
putbits (7,3); /* Escape code */
putbits(1,1);
putbits(6,prev_run);
putbits(8,prev_level);
bits += 22;
}
else
{
putbits(1,prev_s);
bits += length+1;
}
}
return bits;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -