📄 countbit.cpp
字号:
#include"stdafx.h"
#include"Global.h"
#include"indices.h"
#include "OutputVlc.h"
int arith_used = 0;
int syntax_arith_coding;
int advanced;
/************************************************************************/
int CountBitsPicture(Pict *pic)
{
int bits = 0;
/* 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 */
putbits(1,1);
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;
if (pic->PB) {
putbits(3,pic->TRB);
bits += 3;
putbits(2,pic->BQUANT);
bits += 2;
}
putbits(1,0);
bits += 1;
return bits;
}
/************************************************************************/
void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits)
{
int cbpy, cbpcm, length;
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 */
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;
}
}
/* 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;
/* Picture Start Code */
putbits(PSC_LENGTH,PSC); /* PSC */
bits += PSC_LENGTH;
/* Group Number */
putbits(5,slice);
bits += 5;
/* GOB Frame ID */
putbits(2, 0);
bits += 2;
/* Gquant */
putbits(5,quant);
bits += 5;
return bits;
}
/*************************************************************************/
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;
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 (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 (0,prev_run, prev_level);
else
length = 0;
if (length == 0) { /* Escape coding */
if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
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;
}
}
prev_run = run; prev_s = s;
prev_level = level;
run = first = 0;
}
}
}
/* Encode the last coeff */
if (!first) {
if (prev_level < 13 && prev_run < 64)
length = put_coeff (1,prev_run, prev_level);
else
length = 0;
if (length == 0) { /* Escape coding */
if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
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;
}
/*************************************************************************/
int FindCBP(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 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 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 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 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,xin2,xin3;
int yin1,yin2,yin3;
int vec1,vec2,vec3;
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 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);
}
/* PB帧的偏差矢量 */
if (pic->PB)
if (pic->MODB == PBMODE_MVDB || pic->MODB == PBMODE_CBPB_MVDB) {
x_vec = MV[5][y][x]->x;
y_vec = MV[5][y][x]->y;
/* x_vec和y_vec是PB帧的偏差矢量 */
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -