📄 countbit.c
字号:
} } 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\n", pic->MB); if (pic->picture_coding_type == PCT_INTER || pic->picture_coding_type == PCT_IPB || pic->picture_coding_type == PCT_PB) fprintf (tf, " COD: %d ", COD); } if (pic->picture_coding_type == PCT_INTER || pic->picture_coding_type == PCT_IPB || pic->picture_coding_type == PCT_PB) 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 if (EPTYPE) length = AR_Encode (indexfn (cbpcm, mcbpctab_4mvq, 25), cumf_MCBPC_4MVQ); else length = AR_Encode (indexfn (cbpcm, mcbpctab, 21), cumf_MCBPC_no4MVQ); bits->CBPCM += length; /* INTRA_MODE when advanced intra coding mode is used */ if (advanced_intra_coding && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) { if (trace) fprintf (tf, "INTRA_MODE: "); switch (pic->Intra_Mode) { case INTRA_MODE_DC: bits->INTRA_MODE += AR_Encode (0, cumf_INTRA_AC_DC); break; case INTRA_MODE_VERT_AC: bits->INTRA_MODE += AR_Encode (1, cumf_INTRA_AC_DC); break; case INTRA_MODE_HORI_AC: bits->INTRA_MODE += AR_Encode (2, cumf_INTRA_AC_DC); } } /* MODB & CBPB */ if (pic->PB == PB_FRAMES) { switch (pic->MODB) { case PBMODE_NORMAL: bits->MODB += AR_Encode (0, cumf_MODB_G); break; case PBMODE_MVDB: bits->MODB += AR_Encode (1, cumf_MODB_G); break; case PBMODE_CBPB_MVDB: bits->MODB += AR_Encode (2, cumf_MODB_G); /* 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); } if (pic->PB == IM_PB_FRAMES) { switch (pic->MODB) { case PBMODE_BIDIR_PRED: bits->MODB += AR_Encode (0, cumf_MODB_M); break; case PBMODE_CBPB_BIDIR_PRED: bits->MODB += AR_Encode (1, cumf_MODB_M); break; case PBMODE_FRW_PRED: bits->MODB += AR_Encode (2, cumf_MODB_M); break; case PBMODE_CBPB_FRW_PRED: bits->MODB += AR_Encode (3, cumf_MODB_M); break; case PBMODE_BCKW_PRED: bits->MODB += AR_Encode (4, cumf_MODB_M); break; case PBMODE_CBPB_BCKW_PRED: bits->MODB += AR_Encode (5, cumf_MODB_M); break; } if (pic->MODB==PBMODE_CBPB_BIDIR_PRED || pic->MODB==PBMODE_CBPB_FRW_PRED ||pic->MODB==PBMODE_CBPB_BCKW_PRED) { /* 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); } 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) || (Mode == MODE_INTER4V_Q)) { if (trace) { fprintf (tf, "DQUANT: %d\n ",pic->DQUANT); } bits->DQUANT += AR_Encode (indexfn (pic->DQUANT + 2, dquanttab, 4), cumf_DQUANT); } return;}/********************************************************************** * * Name: CountBitsGOB * Description: counts bits used for GOB info including Annex N * (Reference Picture Selection mode) syntax. * * Input: gob number (GN), quantizer, picture structure * * Date: 980624 Author: guyc@ece.ubc.ca * ***********************************************************************/int CountBitsGOB (int gob, int quant, Pict *pic){ int bits = 0; if (arith_used) { bits += encoder_flush (); /* Need to call before fixed length string * output */ arith_used = 0; } /* GOB are byte aligned for easier packetization at GOB boundaries */ if (trace) fprintf (tf, "Stuffing (GSTUF): "); bits += alignbits (); /* 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, gob); 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, pic->GFID); /* GFID is not allowed to change unless PTYPE changes */ /* GFID will change if PTYPE changes from INTRA -> INTER -> INTRA */ /* not yet implemented for different picture types */ bits += 2; /* Gquant */ if (trace) fprintf (tf, "GQUANT: "); putbits(5,quant); bits += 5; if (pic->reference_picture_selection) { /* Annex N GOB syntax */ /* Temporal reference indication(1 bit) */ if (trace) { fprintf (tf, "temporal reference indication: "); } putbits (1, pic->TRI); bits += 1; if (pic->TRI) { /* Temporal reference of GOB */ if (trace) { fprintf (tf, "temporal reference: "); } if (pic->PCF) { putbits (10, pic->TR); bits += 10; } else { putbits (8, pic->TR); bits += 8; } } /* Temporal reference for prediction indication(1 bit) */ if (trace) { fprintf (tf, "temporal reference for prediction indication: "); } if (pic->picture_coding_type == PCT_INTRA || pic->picture_coding_type == PCT_EI) { pic->TRPI = 0; } putbits (1, pic->TRPI); bits += 1; if (pic->TRPI) { /* Temporal reference for prediction */ if (trace) { fprintf (tf, "temporal reference for prediction: "); } if (pic->PCF) { putbits (10, pic->TRP); bits += 10; } else { putbits (10, ((pic->TRP) & 0x00FF)); bits += 10; } } /* Back Channel message Indication (BCI) */ if (trace) { fprintf (tf, "back channel message indication: "); } if (pic->BCM->present) { putbits (1, pic->BCI); bits += 1; } else { putbits (2, pic->BCI); bits += 2; } if (pic->BCM->present) { /* Back Channel Message (BCM) */ /* not implemented, back channel must use external means */ fprintf(stderr,"BCM not implemented \n"); exit (-1); /* CountBitsBCM(pic); */ } } return bits;}/********************************************************************** * * Name: CountBitsSlice * Description: counts 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) && !(advanced_intra_coding)) { 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, use_extended_escape; /* Annex S variables */ int code_intra, code_inter, length_intra = 0, length_inter = 0, run_inter; int total_length_inter, total_length_intra; int use_intra = 0; if (trace) { fprintf (tf, "Coeffs block %d:\n", block); } /* Annex S */ if (alternative_inter_vlc && !(Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) { /* choose the table to use in alternative * inter VLC mode */ run = bits = 0; first = 1; prev_run = prev_level = level = s = prev_s = 0; use_intra = 0; run_inter = 0; total_length_inter = total_length_intra = 0; for (j = block * ncoeffs; j < (block + 1) * ncoeffs; j++) { /* Increment run if coeff is zero */ if ((level = qcoeff[j]) == 0) { run++; } else { if (-127 <= level && level < 0) level = -level; if (!first) { if (prev_level >= 0 && prev_level < 26 && prev_run < 64) { if (prev_level < 13) { show_inter_coeff (prev_run, prev_level, 0, &length_inter, &code_inter); if (!(length_inter)) length_inter = 22; } else length_inter = 22; show_intra_coeff (prev_run, prev_level, 0, &length_intra, &code_intra); if (!(length_intra)) length_intra = 22; } else length_intra = 22; if (modified_quantization && (prev_level < -127 || prev_level > 127)) { length_inter += 11; length_intra += 11; } if (length_intra < 22) { run_inter += show_inter_run (length_intra, code_intra) + 1; } else { run_inter += prev_run + 1; } total_length_inter += length_inter;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -