📄 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:
*
***********************************************************************/
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)) {
if( pic->DQUANT <-2 ) pic->DQUANT =-2 ;
if(pic->DQUANT >2 )pic->DQUANT=2 ;
if(pic->DQUANT==0)pic->DQUANT=1 ;
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:
break ;
}
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.
*
***********************************************************************/
void Count_sac_BitsMB(int Mode,int COD,int CBP,int CBPB,Pict *pic,Bits *bits)
{
int cbpy, cbpcm, length;
arith_used = 1;
/* 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 (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 */
/* 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);
}
bits->CBPY += length;
/* DQUANT */
if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)) {
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
*
***********************************************************************/
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;
}
/**********************************************************************
*
* 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:
*
***********************************************************************/
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 (prev_run, prev_level, 0);
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 (prev_run, prev_level, 1);
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;
}
/**********************************************************************
*
* 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:
*
***********************************************************************/
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 (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 (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) {
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 (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.
*
* Side Effects: None
*
*********************************************************************/
int CodeTCoef(int mod_index, int position, int intra)
{
int length;
switch (position) {
case 1:
{
if (intra)
length = AR_Encode(mod_index, cumf_TCOEF1_intra);
else
length = AR_Encode(mod_index, cumf_TCOEF1);
break;
}
case 2:
{
if (intra)
length = AR_Encode(mod_index, cumf_TCOEF2_intra);
else
length = AR_Encode(mod_index, cumf_TCOEF2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -