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

📄 countbit.c

📁 H.263的压缩算法
💻 C
📖 第 1 页 / 共 5 页
字号:
    }  }  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 + -