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

📄 countbit.cpp

📁 H.263编码与解码程序,能将YUV文件压缩成H.263格式的视频文件
💻 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 + -