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

📄 cabac.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 4 页
字号:
}

/*!
***************************************************************************
* \brief
*    This function is used to arithmetically decode the macroblock
*    intra_pred_size flag info of a given MB.
***************************************************************************
*/

void readMB_transform_size_flag_CABAC( SyntaxElement *se,
                                  ImageParameters *img,
                                  DecodingEnvironmentPtr dep_dp)
{
  MotionInfoContexts *ctx    = (img->currentSlice)->mot_ctx;
  Macroblock         *currMB = &img->mb_data[img->current_mb_nr];

  int b = (currMB->mb_available_up   == NULL) ? 0 : currMB->mb_available_up->luma_transform_size_8x8_flag;
  int a = (currMB->mb_available_left == NULL) ? 0 : currMB->mb_available_left->luma_transform_size_8x8_flag;

  int act_ctx = a + b;
  int act_sym = biari_decode_symbol(dep_dp, ctx->transform_size_contexts + act_ctx );

  se->value1 = act_sym;

#if TRACE
  fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
  fflush(p_trace);
#endif

}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the macroblock
 *    type info of a given MB.
 ************************************************************************
 */
void readMB_typeInfo_CABAC( SyntaxElement *se,
                            ImageParameters *img,
                            DecodingEnvironmentPtr dep_dp)
{
  MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];

  int a = 0, b = 0;
  int act_ctx;
  int act_sym;
  int bframe=(img->type==B_SLICE);
  int mode_sym;
  int curr_mb_type;


  if(img->type == I_SLICE)  // INTRA-frame
  {
    if (currMB->mb_available_up != NULL)
      b = (((currMB->mb_available_up)->mb_type != I4MB && currMB->mb_available_up->mb_type != I8MB) ? 1 : 0 );

    if (currMB->mb_available_left != NULL)
      a = (((currMB->mb_available_left)->mb_type != I4MB && currMB->mb_available_left->mb_type != I8MB) ? 1 : 0 );

    act_ctx = a + b;
    act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx);
    se->context = act_ctx; // store context

    if (act_sym==0) // 4x4 Intra
    {
      curr_mb_type = act_sym;
    }
    else // 16x16 Intra
    {
      mode_sym = biari_decode_final(dep_dp);
      if(mode_sym == 1)
      {
        curr_mb_type = 25;
      }
      else
      {
        act_sym = 1;
        act_ctx = 4;
        mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); // decoding of AC/no AC
        act_sym += mode_sym*12;
        act_ctx = 5;
        // decoding of cbp: 0,1,2
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
        if (mode_sym!=0)
        {
          act_ctx=6;
          mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
          act_sym+=4;
          if (mode_sym!=0)
              act_sym+=4;
            }
          // decoding of I pred-mode: 0,1,2,3
          act_ctx = 7;
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
          act_sym += mode_sym*2;
          act_ctx = 8;
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
          act_sym += mode_sym;
          curr_mb_type = act_sym;
      }
    }
  }
  else if(img->type == SI_SLICE)  // SI-frame
  {
    // special ctx's for SI4MB
    if (currMB->mb_available_up != NULL)
      b = (( (currMB->mb_available_up)->mb_type != SI4MB) ? 1 : 0 );

    if (currMB->mb_available_left != NULL)
      a = (( (currMB->mb_available_left)->mb_type != SI4MB) ? 1 : 0 );

    act_ctx = a + b;
    act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx);
    se->context = act_ctx; // store context

    if (act_sym==0) //  SI 4x4 Intra
    {
      curr_mb_type = 0;
    }
    else // analog INTRA_IMG
    {
      if (currMB->mb_available_up != NULL)
        b = (( (currMB->mb_available_up)->mb_type != I4MB) ? 1 : 0 );

      if (currMB->mb_available_left != NULL)
        a = (( (currMB->mb_available_left)->mb_type != I4MB) ? 1 : 0 );

      act_ctx = a + b;
      act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx);
      se->context = act_ctx; // store context

      if (act_sym==0) // 4x4 Intra
      {
        curr_mb_type = 1;
      }
      else // 16x16 Intra
      {
        mode_sym = biari_decode_final(dep_dp);
        if( mode_sym==1 )
        {
          curr_mb_type = 26;
        }
        else
        {
          act_sym = 2;
          act_ctx = 4;
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); // decoding of AC/no AC
          act_sym += mode_sym*12;
          act_ctx = 5;
          // decoding of cbp: 0,1,2
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
          if (mode_sym!=0)
          {
            act_ctx=6;
            mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
            act_sym+=4;
            if (mode_sym!=0)
              act_sym+=4;
          }
          // decoding of I pred-mode: 0,1,2,3
          act_ctx = 7;
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
          act_sym += mode_sym*2;
          act_ctx = 8;
          mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
          act_sym += mode_sym;
          curr_mb_type = act_sym;
        }
      }
    }
  }
  else
  {
    if (bframe)
    {
      if (currMB->mb_available_up != NULL)
        b = (( (currMB->mb_available_up)->mb_type != 0) ? 1 : 0 );

      if (currMB->mb_available_left != NULL)
        a = (( (currMB->mb_available_left)->mb_type != 0) ? 1 : 0 );

      act_ctx = a + b;

      if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx]))
      {
        if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][4]))
        {
          if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][5]))
          {
            act_sym=12;
            if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=8;
            if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=4;
            if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=2;

            if      (act_sym==24)  act_sym=11;
            else if (act_sym==26)  act_sym=22;
            else
            {
              if (act_sym==22)     act_sym=23;
              if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=1;
            }
          }
          else
          {
            act_sym=3;
            if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=4;
            if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=2;
            if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=1;
          }
        }
        else
        {
          if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym=2;
          else                                                            act_sym=1;
        }
      }
      else
      {
        act_sym = 0;
      }
    }
    else // P-frame
    {
      {
        if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][4] ))
        {
          if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] ))   act_sym = 7;
          else                                                              act_sym = 6;
        }
        else
        {
          if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][5] ))
          {
            if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] )) act_sym = 2;
            else                                                            act_sym = 3;
          }
          else
          {
            if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][6] )) act_sym = 4;
            else                                                            act_sym = 1;
          }
        }
      }
    }

    if (act_sym<=6 || (((img->type == B_SLICE)?1:0) && act_sym<=23))
    {
      curr_mb_type = act_sym;
    }
    else  // additional info for 16x16 Intra-mode
    {
      mode_sym = biari_decode_final(dep_dp);
      if( mode_sym==1 )
      {
        if(bframe)  // B frame
          curr_mb_type = 48;
        else      // P frame
          curr_mb_type = 31;
      }
      else
      {
        act_ctx = 8;
        mode_sym =  biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); // decoding of AC/no AC
        act_sym += mode_sym*12;

        // decoding of cbp: 0,1,2
        act_ctx = 9;
        mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
        if (mode_sym != 0)
        {
          act_sym+=4;
          mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
          if (mode_sym != 0)
            act_sym+=4;
        }

        // decoding of I pred-mode: 0,1,2,3
        act_ctx = 10;
        mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
        act_sym += mode_sym*2;
        mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
        act_sym += mode_sym;
        curr_mb_type = act_sym;
      }
    }
  }
  se->value1 = curr_mb_type;

//  if (curr_mb_type >= 23)       printf(" stopx");
#if TRACE
  fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
  fflush(p_trace);
#endif
}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode a pair of
 *    intra prediction modes of a given MB.
 ************************************************************************
 */
void readIntraPredMode_CABAC( SyntaxElement *se,
                              ImageParameters *img,
                              DecodingEnvironmentPtr dep_dp)
{
  TextureInfoContexts *ctx     = img->currentSlice->tex_ctx;
  int act_sym;

  // use_most_probable_mode
  act_sym = biari_decode_symbol(dep_dp, ctx->ipr_contexts);

  // remaining_mode_selector
  if (act_sym == 1)
    se->value1 = -1;
  else
  {
    se->value1  = 0;
    se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1)     );
    se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 1);
    se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 2);
  }

#if TRACE
  fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
  fflush(p_trace);
#endif
}
/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the reference
 *    parameter of a given MB.
 ************************************************************************
 */
void readRefFrame_CABAC( SyntaxElement *se,
                         ImageParameters *img,
                         DecodingEnvironmentPtr dep_dp)
{
  MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  Macroblock *neighborMB = NULL;

  int   addctx  = 0;
  int   a = 0, b = 0;
  int   act_ctx;
  int   act_sym;
  char** refframe_array = dec_picture->motion.ref_idx[se->value2];
  int   b8a, b8b;

  PixelPos block_a, block_b;

  get4x4Neighbour(currMB, (img->subblock_x<<2) - 1, (img->subblock_y<<2)    , img->mb_size[IS_LUMA], &block_a);
  get4x4Neighbour(currMB, (img->subblock_x<<2),     (img->subblock_y<<2) - 1, img->mb_size[IS_LUMA], &block_b);

  b8a=((block_a.x>>1)&0x01)+2*((block_a.y>>1)&0x01);
  b8b=((block_b.x>>1)&0x01)+2*((block_b.y>>1)&0x01);

  if (block_b.available)
  {
    neighborMB = &img->mb_data[block_b.mb_addr];
    if (!( (neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8b]==0 && neighborMB->b8pdir[b8b]==2)))
    {
      if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (neighborMB->mb_field == 1))
        b = (refframe_array[block_b.pos_y][block_b.pos_x] > 1 ? 2 : 0);
      else
        b = (refframe_array[block_b.pos_y][block_b.pos_x] > 0 ? 2 : 0);
    }
  }

  if (block_a.available)
  {
    neighborMB = &img->mb_data[block_a.mb_addr];
    if (!((neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8a]==0 && neighborMB->b8pdir[b8a]==2)))
    {
      if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (neighborMB->mb_field == 1))
        a = (refframe_array[block_a.pos_y][block_a.pos_x] > 1 ? 1 : 0);
      else
        a = (refframe_array[block_a.pos_y][block_a.pos_x] > 0 ? 1 : 0);
    }
  }

  act_ctx = a + b;
  se->context = act_ctx; // store context

  act_sym = biari_decode_symbol(dep_dp,ctx->ref_no_contexts[addctx] + act_ctx );

  if (act_sym != 0)
  {
    act_ctx = 4;
    act_sym = unary_bin_decode(dep_dp,ctx->ref_no_contexts[addctx] + act_ctx,1);
    act_sym++;
  }
  se->value1 = act_sym;

#if TRACE
  fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
//  fprintf(p_trace," c: %d :%d \n",ctx->ref_no_contexts[addctx][act_ctx].cum_freq[0],ctx->ref_no_contexts[addctx][act_ctx].cum_freq[1]);
  fflush(p_trace);
#endif
}


/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the delta qp
 *     of a given MB.
 ************************************************************************
 */
void readDquant_CABAC( SyntaxElement *se,
                       ImageParameters *img,
                       DecodingEnvironmentPtr dep_dp)
{
  MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
  int *dquant = &se->value1;
  int act_ctx = ((last_dquant != 0) ? 1 : 0);
  int act_sym = biari_decode_symbol(dep_dp,ctx->delta_qp_contexts + act_ctx );

  if (act_sym != 0)
  {
    act_ctx = 2;
    act_sym = unary_bin_decode(dep_dp,ctx->delta_qp_contexts + act_ctx,1);
    act_sym++;
  }

  *dquant = (act_sym + 1) >> 1;
  if((act_sym & 0x01)==0)                           // lsb is signed bit
    *dquant = -*dquant;

  last_dquant = *dquant;

#if TRACE
  fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
  fflush(p_trace);
#endif
}
/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the coded
 *    block pattern of a given MB.
 ************************************************************************
 */
void readCBP_CABAC(SyntaxElement *se,
                   ImageParameters *img,
                   DecodingEnvironmentPtr dep_dp)
{
  TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  Macroblock *neighborMB = NULL;

  int mb_x, mb_y;
  int a, b;
  int curr_cbp_ctx;

⌨️ 快捷键说明

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