📄 countbit.cpp
字号:
////////////////////////////////////////////////////////////////////////////
//
//
// Project : VideoNet version 1.1.
// Description : Peer to Peer Video Conferencing over the LAN.
// Author : Nagareshwar Y Talekar ( nsry2002@yahoo.co.in)
// Date : 15-6-2004.
//
// I have converted origional fast h.263 encoder library from C to C++
// so that it can be integrated into any windows application easily.
// I have removed some of unnecessary codes/files from the
// fast h263 library.Also moved definitions and declarations
// in their proper .h and .cpp files.
//
// File description :
// Name : countbit.cpp
//
//
/////////////////////////////////////////////////////////////////////////////
/************************************************* * libr263: fast H.263 encoder library * * Copyright (C) 1996, Roalt Aalmoes, Twente University * SPA multimedia group * * Based on Telenor TMN 1.6 encoder (Copyright (C) 1995, Telenor R&D) * created by Karl Lillevold * * Author encoder: Roalt Aalmoes, <aalmoes@huygens.nl> * * Date: 31-07-96 **************************************************/ /********************************************************************** * * 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 * ***********************************************************************/
#include "stdafx.h"
#include "countbit.h"
void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits){ extern EHUFF *vlc_cbpy, *vlc_cbpcm, *vlc_cbpcm_intra; int cbpy, cbpcm, length; /* COD */ if (Global::trace) { fprintf(Global::tf,"MB-nr: %d",pic->MB); if (pic->picture_coding_type == PCT_INTER) fprintf(Global::tf," COD: %d\n",COD); } if (pic->picture_coding_type == PCT_INTER) { mputv(1,COD); bits->COD++; } if (COD) return; /* not coded */ /* CBPCM */ cbpcm = Mode | ((CBP&3)<<4); if (Global::trace) { fprintf(Global::tf,"CBPCM (CBP=%d) (cbpcm=%d): ",CBP,cbpcm); } if (pic->picture_coding_type == PCT_INTRA) { length = Encode(cbpcm,vlc_cbpcm_intra); } else { length = Encode(cbpcm,vlc_cbpcm); } bits->CBPCM += length; /* CBPY */ cbpy = CBP>>2; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */ cbpy = cbpy^15; if (Global::trace) { fprintf(Global::tf,"CBPY (CBP=%d) (cbpy=%d): ",CBP,cbpy); } length = Encode(cbpy, vlc_cbpy); bits->CBPY += length; 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; /* Picture Start Code */ if (Global::trace) fprintf(Global::tf,"GOB sync (GBSC): "); mputv(PSC_LENGTH,PSC); /* PSC */ bits += PSC_LENGTH; /* Group Number */ if (Global::trace) fprintf(Global::tf,"GN: "); mputv(5,slice); bits += 5; /* GOB Sub Bitstream Indicator */ /* if CPM == 1: read 2 bits GSBI */ /* not supported in this version */ /* GOB Frame ID */ if (Global::trace) fprintf(Global::tf,"GFID: "); mputv(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 (Global::trace) fprintf(Global::tf,"GQUANT: "); mputv(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) { 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_ind, ind, prev_s, s, length; extern EHUFF *vlc_3d; run = bits = 0; first = 1; prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0; for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) { /* Do this block's DC-coefficient first */ if (!(j%ncoeffs) && (Mode == MODE_INTRA)) { /* DC coeff */ if (Global::trace) { fprintf(Global::tf,"DC: "); } if (qcoeff[block*ncoeffs] != 128) mputv(8,qcoeff[block*ncoeffs]); else mputv(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; } ind = level | run<<4; ind = ind | 0<<12; /* Not last coeff */ if (!first) { /* Encode the previous ind */ if (prev_level < 13 && prev_run < 64) { length = Encode(prev_ind,vlc_3d); } else length = 0; if (length == 0) { /* Escape coding */ if (Global::trace) { fprintf(Global::tf,"Escape coding:\n"); } if (prev_s == 1) {prev_level = (prev_level^0xff)+1;} Encode(ESCAPE,vlc_3d); mputv(1,0); mputv(6,prev_run); mputv(8,prev_level); bits += 22; } else { mputv(1,prev_s); bits += length + 1; } } prev_run = run; prev_s = s; prev_level = level; prev_ind = ind; run = first = 0; } } } /* Encode the last coeff */ if (!first) { if (Global::trace) { fprintf(Global::tf,"Last coeff: "); } prev_ind = prev_ind | 1<<12; /* last coeff */ if (prev_level < 13 && prev_run < 64) { length = Encode(prev_ind,vlc_3d); } else length = 0; if (length == 0) { /* Escape coding */ if (Global::trace) { fprintf(Global::tf,"Escape coding:\n"); } if (prev_s == 1) {prev_level = (prev_level^0xff)+1;} Encode(ESCAPE,vlc_3d); mputv(1,1); mputv(6,prev_run); mputv(8,prev_level); bits += 22; } else { mputv(1,prev_s); bits += length + 1; } } return bits;} /********************************************************************** * * Name: FindCBP * Description: Finds the CBP for a macroblock * * Input: qcoeff and mode * * Returns: CBP * Side effects: * * Date: 940829 Author: Karl.Lillevold@nta.no * ***********************************************************************/int FindCBP(int *qcoeff, int Mode, int ncoeffs){ int i,j; int CBP = 0; /* IF INTRABLOCK then intra =1 else 0 */ int intra = (Mode == MODE_INTRA); /* Set CBP for this Macroblock */ for (i = 0; i < 6; i++) { /* First time i = 0: j = 0 ..64-1 set bit 5 if coeff != 0 Sec. time i = 1; j = 64..128-1 set bit 4 if coeff != 0 */ /* OPTIMIZE: I think for i can be removed and only values i=0 must be proessed */ 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_ptr, Bits *bits, int x, int y, int Mode, int newgob, Pict *pic){ int y_vec, x_vec; extern EHUFF *vlc_mv; int pmv0, pmv1; int start,stop,block; MotionVector *MV_xy; start = 0; stop = 0; MV_xy = MV_ptr + y*Global::mbc + x; for (block = start; block <= stop; block++) { FindPMV(MV_ptr,x,y,&pmv0,&pmv1, block, newgob, 1); x_vec = (2*(*MV_xy).x + (*MV_xy).x_half) - pmv0; y_vec = (2*(*MV_xy).y + (*MV_xy).y_half) - pmv1; if (!Global::long_vectors) { if (x_vec < -32) x_vec += 64; else if (x_vec > 31) x_vec -= 64;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -