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

📄 cabac.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 4 页
字号:

  //===== WRITE BIT =====
  biari_encode_symbol (eep_dp, (unsigned char) bit,
                       img->currentSlice->tex_ctx->cbp_contexts[inter][0] + a+2*b);
}

/*!
 ****************************************************************************
 * \brief
 *    This function is used to arithmetically encode the coded
 *    block pattern of a macroblock
 ****************************************************************************
 */
void writeCBP2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
  TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];

  int a, b;
  int curr_cbp_ctx, curr_cbp_idx;
  int cbp = se->value1; // symbol to encode
  int cbp_bit;
  int b8;

  for (b8=0; b8<4; b8++)
  {
    curr_cbp_idx = (currMB->b8mode[b8] == IBLOCK ? 0 : 1);
    writeCBP_BIT_CABAC (b8, cbp&(1<<b8), cbp, currMB, curr_cbp_idx, eep_dp);
  }

  if ( se->type == SE_CBP_INTRA )
    curr_cbp_idx = 0;
  else
    curr_cbp_idx = 1;

  // coding of chroma part
  b = 0;
  if (currMB->mb_available[0][1] != NULL)
    b = ((currMB->mb_available[0][1])->cbp > 15) ? 1 : 0;

  a = 0;
  if (currMB->mb_available[1][0] != NULL)
    a = ((currMB->mb_available[1][0])->cbp > 15) ? 1 : 0;

  curr_cbp_ctx = a+2*b;
  cbp_bit = (cbp > 15 ) ? 1 : 0;
  biari_encode_symbol(eep_dp, (unsigned char) cbp_bit, ctx->cbp_contexts[curr_cbp_idx][1] + curr_cbp_ctx );

  if (cbp > 15)
  {
    b = 0;
    if (currMB->mb_available[0][1] != NULL)
      if ((currMB->mb_available[0][1])->cbp > 15)
        b = (( ((currMB->mb_available[0][1])->cbp >> 4) == 2) ? 1 : 0);

    a = 0;
    if (currMB->mb_available[1][0] != NULL)
      if ((currMB->mb_available[1][0])->cbp > 15)
        a = (( ((currMB->mb_available[1][0])->cbp >> 4) == 2) ? 1 : 0);

    curr_cbp_ctx = a+2*b;
    cbp_bit = ((cbp>>4) == 2) ? 1 : 0;
    biari_encode_symbol(eep_dp, (unsigned char) cbp_bit, ctx->cbp_contexts[curr_cbp_idx][2] + curr_cbp_ctx );
  }
}


/*!
 ****************************************************************************
 * \brief
 *    This function is used to arithmetically encode coeff_count, level and
 *    run of a given MB.
 ****************************************************************************
 */
void writeRunLevel2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
  const int level = se->value1;
  const int run = se->value2;
  int curr_ctx_idx = se->context;
  int sign_of_level;
  int max_run;
  static int coeff_can[2][17] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
  static int coeff_count=0;
  int i,j,a,b;
  int max_coeff[9] = {8,16,16,16,15,4,4,15,15};
  int curr_run_ctx, curr_level_ctx;
  int act_ctx=0;
  static int count[3] = {0,0,0};
  static int prev_sym[3] = {0,0,0};
  int prevLevel = 0;
  int absLevel;
  int changed_ctx_idx=curr_ctx_idx;

  TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];

  if (level != 0)
  {
    coeff_can[0][coeff_count] = level;
    coeff_can[1][coeff_count] = run;
    coeff_count++;
  }
  else
  {
    //send coeff_count
    switch(curr_ctx_idx)
    {
    case 0://max 8 coeffs, double_scan
    {
      //context determination
      act_ctx = (count[0] == 0) ? 0 : ((prev_sym[0] == 0) ? 1 : 2);
      prev_sym[0] = coeff_count;
      if(++count[0] == 2) count[0]=0;
      
      if (coeff_count == 0)
        biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
      else
      {
        biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
      }
      break;
    }
    case 1: //max 16 coeffs //single scan
    case 2:
    {
      //context termination
      j = img->subblock_y;
      i = img->subblock_x;
      if (j==0)
        b = (currMB->mb_available[0][1] == NULL)?0:(((currMB->mb_available[0][1])->coeffs_count[BLOCK_SIZE-1][i]==0)?0:1);
      else
        b = (currMB->coeffs_count[j-1][i]==0)?0:1;
          
      if (i==0)
        a = (currMB->mb_available[1][0] == NULL)?0:(((currMB->mb_available[1][0])->coeffs_count[j][BLOCK_SIZE-1]==0)?0:1);
      else
        a = (currMB->coeffs_count[j][i-1]==0)?0:1;

      act_ctx = a+2*b; 
      if (coeff_count == 0)
        biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
      else
      {
        biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
      }
      currMB->coeffs_count[j][i] = coeff_count; 
      break;
    }
    case 4://max 15 coeffs // 16x16 luma ac
    {
      //context determination
      act_ctx = (count[2] == 0) ? 0 : ((prev_sym[2] == 0) ? 1 : 2);
      prev_sym[2] = coeff_count;
      if(++count[2] == 16) count[2]=0;

      if (coeff_count == 0)
        biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
      else
      {
        biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
      }
      break;
    }
    case 5:
    case 6://max 4 coeffs, chroma dc different ctx uv for first bin
    {
      act_ctx = (se->k == 0)?0:1;
      if (coeff_count == 0)
        biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
      else
      {
        biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
      }
      break;
    }
    case 7:
    case 8://max 15 coeffs, chroma ac different ctx uv for first bin
    {
      act_ctx = (se->k < 4)?0:1;
      if (coeff_count == 0)
        biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
      else
      {
        biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
      }
      break;
    }
    case 3:  //max 16 coeffs // 16x16 luma dc
    {
      act_ctx = 0;
      if (coeff_count == 0)
        biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
      else
      {
        biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
      }
      break;
    }
    default: printf("ERROR");
    }
    prevLevel = 0;
    for(i=0; i<coeff_count;i++)
    {
      //determine run ctx
      switch (curr_ctx_idx)
      {
      case 1:
      case 2:
          curr_run_ctx = ((coeff_count) >= 4) ? 1 : 0;  
          break;                                        
      case 3:
          curr_run_ctx = ((coeff_count-i) >= 4) ? 1 : 0;
          break;
      case 4:
      case 7:
      case 8:
      case 0:
          curr_run_ctx = ((coeff_count-i) >= 3) ? 1 : 0;
          break;
      case 5:
      case 6:
          curr_run_ctx = ((coeff_count-i) >= 2) ? 1 : 0;
          break;
      }
      curr_run_ctx = 9*curr_run_ctx + curr_ctx_idx;
      //send run
      if (i==0)
        max_run = max_coeff[curr_ctx_idx]-coeff_count;
      if ((max_run != 0) )
        unary_bin_max_encode(eep_dp,(unsigned int) coeff_can[1][i],ctx->run_context[curr_run_ctx],1,max_run);
      max_run -= coeff_can[1][i];
      //determine level ctx
      changed_ctx_idx = curr_ctx_idx;
      absLevel    = absm(coeff_can[0][i]);
      changed_ctx_idx += 9*prevLevel;
      prevLevel     = absLevel > 3 ? 3 : absLevel;
      // send level
      unary_level_encode(eep_dp,(unsigned int) absm(coeff_can[0][i])-1,ctx->level_context[changed_ctx_idx]);
      sign_of_level = ((coeff_can[0][i] < 0) ? 1 : 0);
      curr_level_ctx = 3;
      biari_encode_symbol(eep_dp, (unsigned char) sign_of_level, ctx->level_context[curr_ctx_idx]+ curr_level_ctx );
    }
    coeff_count=0;
  }
}

/*!
 ************************************************************************
 * \brief
 *    Unary binarization and encoding of a symbol by using
 *    one or two distinct models for the first two and all
 *    remaining bins
*
************************************************************************/
void unary_bin_encode(EncodingEnvironmentPtr eep_dp,
                      unsigned int symbol,
                      BiContextTypePtr ctx,
                      int ctx_offset)
{
  unsigned int l;
  BiContextTypePtr ictx;

  if (symbol==0)
  {
    biari_encode_symbol(eep_dp, 0, ctx );
    return;
  }
  else
  {
    biari_encode_symbol(eep_dp, 1, ctx );
    l=symbol;
    ictx=ctx+ctx_offset;
    while ((--l)>0)
      biari_encode_symbol(eep_dp, 1, ictx);
    biari_encode_symbol(eep_dp, 0, ictx);
  }
  return;
}

/*!
 ************************************************************************
 * \brief
 *    Unary binarization and encoding of a symbol by using
 *    one or two distinct models for the first two and all
 *    remaining bins; no terminating "0" for max_symbol
 *    (finite symbol alphabet)
 ************************************************************************
 */
void unary_bin_max_encode(EncodingEnvironmentPtr eep_dp,
                          unsigned int symbol,
                          BiContextTypePtr ctx,
                          int ctx_offset,
                          unsigned int max_symbol)
{
  unsigned int l;
  BiContextTypePtr ictx;

  if (symbol==0)
  {
    biari_encode_symbol(eep_dp, 0, ctx );
    return;
  }
  else
  {
    biari_encode_symbol(eep_dp, 1, ctx );
    l=symbol;
    ictx=ctx+ctx_offset;
    while ((--l)>0)
      biari_encode_symbol(eep_dp, 1, ictx);
    if (symbol<max_symbol)
        biari_encode_symbol(eep_dp, 0, ictx);
  }
  return;
}

/*!
 ************************************************************************
 * \brief
 *    Unary binarization and encoding of a symbol by using
 *    three distinct models for the first, the second and all
 *    remaining bins
 ************************************************************************
 */
void unary_level_encode(EncodingEnvironmentPtr eep_dp,
                        unsigned int symbol,
                        BiContextTypePtr ctx)
{
  unsigned int l;
  int bin=1;
  BiContextTypePtr ictx=ctx;

  if (symbol==0)
  {
    biari_encode_symbol(eep_dp, 0, ictx );
    return;
  }
  else
  {
    biari_encode_symbol(eep_dp, 1, ictx );
    l=symbol;
    ictx++;
    while ((--l)>0)
    {
      biari_encode_symbol(eep_dp, 1, ictx  );
      if ((++bin)==2) ictx++;
    }
    biari_encode_symbol(eep_dp, 0, ictx  );
  }
  return;
}

/*!
 ************************************************************************
 * \brief
 *    Unary binarization and encoding of a symbol by using
 *    four distinct models for the first, the second, intermediate
 *    and all remaining bins
 ************************************************************************
 */
void unary_mv_encode(EncodingEnvironmentPtr eep_dp,
                        unsigned int symbol,
                        BiContextTypePtr ctx,
                        unsigned int max_bin)
{
  unsigned int l;
  unsigned int bin=1;
  BiContextTypePtr ictx=ctx;

  if (symbol==0)
  {
    biari_encode_symbol(eep_dp, 0, ictx );
    return;
  }
  else
  {
    biari_encode_symbol(eep_dp, 1, ictx );
    l=symbol;
    ictx++;
    while ((--l)>0)
    {
      biari_encode_symbol(eep_dp, 1, ictx  );
      if ((++bin)==2) ictx++;
      if (bin==max_bin) ictx++;
    }
    biari_encode_symbol(eep_dp, 0, ictx  );
  }
  return;
}

⌨️ 快捷键说明

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