⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 countbit.c

📁 encoder 视频会议 视频编码算法 源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ *编码数据流生成  *   ************************************************************************/#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: * *	Date: 941129	Author: Karl.Lillevold@nta.no * ***********************************************************************/void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits){  int cbpy, cbpcm, length;  /* COD */  if (trace) {    fprintf(tf,"MB-nr: %d",pic->MB);    if (pic->picture_coding_type == PCT_INTER)      fprintf(tf,"  COD: %d\n",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 (trace) {    fprintf(tf,"CBPCM (CBP=%d) (cbpcm=%d): ",CBP,cbpcm);  }  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;    }    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 */    cbpy = cbpy^15;  if (trace) {    fprintf(tf,"CBPY (CBP=%d) (cbpy=%d): ",CBP,cbpy);  }  length = put_cbpy (CBP, Mode);  bits->CBPY += length;    /* DQUANT */  if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)) {    if (trace) {      fprintf(tf,"DQUANT: ");    }    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;}/********************************************************************** * *      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",pic->MB);    if (pic->picture_coding_type == PCT_INTER)      fprintf(tf,"  COD: %d ",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 (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    length = AR_Encode(indexfn(cbpcm,mcbpctab,21),cumf_MCBPC);   bits->CBPCM += length;   /* MODB & CBPB */   if (pic->PB) {     switch (pic->MODB) {     case PBMODE_NORMAL:       bits->MODB += AR_Encode(0, cumf_MODB);       break;     case PBMODE_MVDB:       bits->MODB += AR_Encode(1, cumf_MODB);       break;     case PBMODE_CBPB_MVDB:       bits->MODB += AR_Encode(2, cumf_MODB);       /* 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);   }  /* 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)) {    if (trace) {      fprintf(tf,"DQUANT: ");    }    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 * *	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) {    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;    if (trace) {    fprintf(tf,"Coeffs block %d:\n",block);  }  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 (trace) {        fprintf(tf,"DC: ");      }      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 (trace) {              fprintf(tf,"Escape code: ");            }            if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}            putbits(7,3);	/* Escape code */            if (trace)              fprintf(tf,"last: ");            putbits(1,0);            if (trace)              fprintf(tf,"run: ");            putbits(6,prev_run);            if (trace)              fprintf(tf,"level: ");            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 (trace) {      fprintf(tf,"Last coeff: ");    }    if (prev_level  < 13 && prev_run < 64)       length = put_coeff (prev_run, prev_level, 1);       else      length = 0;    if (length == 0) {  /* Escape coding */      if (trace) {        fprintf(tf,"Escape code: ");      }      if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}      putbits (7,3);	/* Escape code */      if (trace)        fprintf(tf,"last: ");      putbits(1,1);      if (trace)        fprintf(tf,"run: ");      putbits(6,prev_run);      if (trace)        fprintf(tf,"level: ");      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: * *      Author:        pmulroy@visual.bt.co.uk * ***********************************************************************/ 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 (trace) {        fprintf(tf,"DC: ");      }      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 (trace) {              fprintf(tf,"Escape coding:\n");            }             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) {    if (trace) {      fprintf(tf,"Last coeff: ");    }    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 (trace) {        fprintf(tf,"Escape coding:\n");      }      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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -