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

📄 h.264

📁 H.264编码解码器源码(c语言版本)
💻 264
📖 第 1 页 / 共 5 页
字号:
  //===== INTER PREDICTION =====
  if (fw_mode || (direct && (!input->direct_type || fw_ref_frame!=-1)) || skipped)
  {
    OneComponentChromaPrediction4x4 (fw_pred, pic_pix_x, pic_pix_y, fmv_array , fw_ref_frame, fw_mode, uv);
  }
  if (bw_mode || (direct && (!input->direct_type || bw_ref_frame!=-1)))
  {
    //if (img->type == BS_IMG)
		if (img->type == B_SLICE && img->nal_reference_idc>0)
      OneComponentChromaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, bmv_array, bw_ref_frame, bw_mode, uv);
    else
      OneComponentChromaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, bmv_array,           -1, bw_mode, uv);
  }

  if (apply_weights)
  {
    if (direct || (fw_mode && bw_mode))
    {
      if (direct && input->direct_type)
      {
        for (j=block_y; j<block_y4; j++)
        for (i=block_x; i<block_x4; i++)  
          if (fw_ref_frame==-1)
            img->mpr[i][j] = clip1a(((wp_weight[1][bw_ref_idx][uv+1] * *bpred++  + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[1][bw_ref_idx][uv+1]);
          else if (bw_ref_frame==-1)
            img->mpr[i][j] =  clip1a(((wp_weight[0][fw_ref_idx][uv+1] * *fpred++  + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[0][fw_ref_idx][uv+1]);
          else
            img->mpr[i][j] =  clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++ 
                  + 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1) );
      }
      else
        for (j=block_y; j<block_y4; j++)
          for (i=block_x; i<block_x4; i++)  
            img->mpr[i][j] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++ 
                    + 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1));
 
    }
		else if (img->type == B_SLICE && img->nal_reference_idc>0)
    {
      for (j=block_y; j<block_y4; j++)
        for (i=block_x; i<block_x4; i++)  
          img->mpr[i][j] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++ 
                     + 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1));
    }
    else if (fw_mode || skipped)
    {
      for (j=block_y; j<block_y4; j++)
      for (i=block_x; i<block_x4; i++)  
           img->mpr[i][j] = clip1a(((wp_weight[0][fw_ref_idx][uv+1] * *fpred++ + wp_chroma_round) >> chroma_log_weight_denom) +  wp_offset[0][fw_ref_idx][uv+1]);
    }
    else
    {
      for (j=block_y; j<block_y4; j++)
      for (i=block_x; i<block_x4; i++)  
            img->mpr[i][j] = clip1a(((wp_weight[1][bw_ref_idx][uv+1] * *bpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[1][bw_ref_idx][uv+1]);

    }       
  }
  else
  {
    if (direct || (fw_mode && bw_mode))
    {
      if (direct && input->direct_type)
      {
        for (j=block_y; j<block_y4; j++)
          for (i=block_x; i<block_x4; i++)  
            if (fw_ref_frame==-1)
              img->mpr[i][j] = *bpred++;
            else if (bw_ref_frame==-1)
              img->mpr[i][j] = *fpred++;
            else
              img->mpr[i][j] = (*fpred++ + *bpred++ + 1) / 2; 
      }
      else
        for (j=block_y; j<block_y4; j++)
          for (i=block_x; i<block_x4; i++)  
            img->mpr[i][j] = (*fpred++ + *bpred++ + 1) / 2; 
     }
		 else if (img->type == B_SLICE && img->nal_reference_idc>0)
     {
       for (j=block_y; j<block_y4; j++)
         for (i=block_x; i<block_x4; i++)  
           img->mpr[i][j] = (*fpred++ + *bpred++ + 1) / 2; 
     }
     else if (fw_mode || skipped)
     {
       for (j=block_y; j<block_y4; j++)
         for (i=block_x; i<block_x4; i++)  img->mpr[i][j] = *fpred++;
     }
     else
     {
       for (j=block_y; j<block_y4; j++)
         for (i=block_x; i<block_x4; i++)  img->mpr[i][j] = *bpred++;
     }
  }
}




/*!
 ************************************************************************
 * \brief
 *    Chroma residual coding for an macroblock
 ************************************************************************
 */
void ChromaResidualCoding (int* cr_cbp)
{
  int   uv, block8, block_y, block_x, j, i;
  int   fw_mode, bw_mode, refframe;
  int   skipped = (img->mb_data[img->current_mb_nr].mb_type == 0 && (img->type == P_SLICE || img->type == SP_SLICE));
  int   incr = 1, offset = 0; // For MB level field/frame coding 
  int   bw_ref;


  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    incr = 2;   // increment every other field  
    if(!img->top_field)
      offset = -7;
  }

  for (*cr_cbp=0, uv=0; uv<2; uv++)
  {
    //===== prediction of chrominance blocks ===d==
    block8 = 0;
    for (block_y=0; block_y<8; block_y+=4)
    for (block_x=0; block_x<8; block_x+=4, block8++)
    {
      SetModesAndRefframe (block8, &fw_mode, &bw_mode, &refframe, &bw_ref);

      ChromaPrediction4x4 (uv, block_x, block_y, fw_mode, bw_mode, refframe, bw_ref);
    }

        // ==== set chroma residue to zero for skip Mode in SP frames 
    if (img->NoResidueDirect)
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
        }
        else
    if (skipped && img->type==SP_SLICE)
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          img->m7[i][j] = 0;
        }
    else
    if (skipped)
    {
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
        }
    }
    else
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          img->m7[i][j] = imgUV_org[uv][img->pix_c_y+(j*incr)+offset][img->pix_c_x+i] - img->mpr[i][j];
        }

    //===== DCT, Quantization, inverse Quantization, IDCT, and Reconstruction =====
    //===== Call function for skip mode in SP frames to properly process frame ====
    
    if (skipped && img->type==SP_SLICE)
    {
        *cr_cbp=dct_chroma_sp(uv,*cr_cbp);
    }
    else
    if (!img->NoResidueDirect && !skipped)
    {
      if (img->type!=SP_SLICE || IS_INTRA (&img->mb_data[img->current_mb_nr]))
        *cr_cbp=dct_chroma   (uv,*cr_cbp);
      else
        *cr_cbp=dct_chroma_sp(uv,*cr_cbp);
    }
  }

  //===== update currMB->cbp =====
  img->mb_data[img->current_mb_nr].cbp += ((*cr_cbp)<<4);  
}


/*!
 ************************************************************************
 * \brief
 *    Predict an intra chroma 8x8 block
 ************************************************************************
 */
void IntraChromaPrediction8x8 (int *mb_up, int *mb_left, int*mb_up_left)
{
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  int     s, s0, s1, s2, s3, i, j, k;
  pel_t** image;
  int     block_x, block_y, b4;
  int     img_cx            = img->pix_c_x;
  int     img_cy            = img->pix_c_y;
  int     img_cx_1          = img->pix_c_x-1;
  int     img_cx_4          = img->pix_c_x+4;
  int     img_cy_1          = img->pix_c_y-1;
  int     img_cy_4          = img->pix_c_y+4;
  int     mb_nr             = img->current_mb_nr;
  int     mb_width          = img->width/16;
  int     mb_available_up   = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
  int     mb_available_left = (img_cx/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-1]       .slice_nr);
  int     mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
  int     ih,iv;
  int     ib,ic,iaa;
  int     uv;
  int     hline[8], vline[8];
  int     mode;
  int     best_mode = DC_PRED_8;         //just an initilaization here, should always be overwritten
  int     cost;
  int     min_cost;
  int     diff[16];
	int     left_avail;
	PixelPos up;       //!< pixel position p(0,-1)
  PixelPos left[9];  //!< pixel positions p(-1, -1..8)


	for (i=0;i<9;i++)
  {
    getNeighbour(mb_nr, -1 ,  i-1 , 0, &left[i]);
  }
  
  getNeighbour(mb_nr, 0     ,  -1 , 0, &up);

  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    img_cy   = img->field_pix_c_y;
    img_cy_1 = img->field_pix_c_y-1;
    img_cy_4 = img->field_pix_c_y+4;
    mb_available_up = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
    mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
  }

  if(input->UseConstrainedIntraPred)
  {
		mb_available_up      = up.available ? img->intra_block[up.mb_addr] : 0;
    for (i=1, left_avail=1; i<9;i++)
      mb_available_left  &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
    mb_available_up_left = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
  }

  if (mb_up)
    *mb_up = mb_available_up;
  if (mb_left)
    *mb_left = mb_available_left;
  if( mb_up_left )
    *mb_up_left = mb_available_up_left;

  // compute all chroma intra prediction modes for both U and V
  for (uv=0; uv<2; uv++)
  {
/*    if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
    {
      if(img->top_field)
        image = imgUV_top[uv];
      else
        image = imgUV_bot[uv];
    }
    else
*/
    image = enc_picture->imgUV[uv];

    // DC prediction
    for (block_y=0; block_y<8; block_y+=4)
    for (block_x=0; block_x<8; block_x+=4)
    {
      s=128;
      s0=s1=s2=s3=0;
      //===== get prediction value =====
      switch ((block_y>>1) + (block_x>>2))
      {
      case 0:  //===== TOP LEFT =====
        if      (mb_available_up)    for (i=0;i<4;i++)  s0 += image[img_cy_1  ][img_cx  +i];
        if      (mb_available_left)  for (i=0;i<4;i++)  s2 += image[img_cy  +i][img_cx_1  ];
        if      (mb_available_up && mb_available_left)  s  = (s0+s2+4) >> 3;
        else if (mb_available_up)                       s  = (s0   +2) >> 2;
        else if (mb_available_left)                     s  = (s2   +2) >> 2;
        break;
      case 1: //===== TOP RIGHT =====
        if      (mb_available_up)    for (i=0;i<4;i++)  s1 += image[img_cy_1  ][img_cx_4+i];
        else if (mb_available_left)  for (i=0;i<4;i++)  s2 += image[img_cy  +i][img_cx_1  ];
        if      (mb_available_up)                       s  = (s1   +2) >> 2;
        else if (mb_available_left)                     s  = (s2   +2) >> 2;
        break;
      case 2: //===== BOTTOM LEFT =====
        if      (mb_available_left)  for (i=0;i<4;i++)  s3 += image[img_cy_4+i][img_cx_1  ];
        else if (mb_available_up)    for (i=0;i<4;i++)  s0 += image[img_cy_1  ][img_cx  +i];
        if      (mb_available_left)                     s  = (s3   +2) >> 2;
        else if (mb_available_up)                       s  = (s0   +2) >> 2;
        break;
      case 3: //===== BOTTOM RIGHT =====
        if      (mb_available_up)    for (i=0;i<4;i++)  s1 += image[img_cy_1  ][img_cx_4+i];
        if      (mb_available_left)  for (i=0;i<4;i++)  s3 += image[img_cy_4+i][img_cx_1  ];
        if      (mb_available_up && mb_available_left)  s  = (s1+s3+4) >> 3;
        else if (mb_available_up)                       s  = (s1   +2) >> 2;
        else if (mb_available_left)                     s  = (s3   +2) >> 2;
        break;
      }

      //===== prediction =====
      for (j=block_y; j<block_y+4; j++)
      for (i=block_x; i<block_x+4; i++)
      {
        img->mprr_c[uv][DC_PRED_8][i][j] = s;
      }
    }

    // vertical prediction
    if (mb_available_up)
    {
      for (i=0; i<8; i++)
        hline[i] = image[img_cy_1][img_cx+i];
      for (i=0; i<8; i++)
      for (j=0; j<8; j++)
        img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
    }

    // horizontal prediction
    if (mb_available_left)
    {
      for (i=0; i<8; i++)
        vline[i] = image[img_cy+i][img_cx_1];
      for (i=0; i<8; i++)
      for (j=0; j<8; j++)
        img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j];
    }

    // plane prediction
    if (mb_available_up_left)
    {
      ih = 4*(hline[7] - image[img_cy_1][img_cx_1]);
      iv = 4*(vline[7] - image[img_cy_1][img_cx_1]);
      for (i=1;i<4;i++)
      {
        ih += i*(hline[3+i] - hline[3-i]);
        iv += i*(vline[3+i] - vline[3-i]);
      }
      ib=(17*ih+16)>>5;
      ic=(17*iv+16)>>5;

      iaa=16*(hline[7]+vline[7]);
      for (j=0; j<8; j++)
      for (i=0; i<8; i++)
        img->mprr_c[uv][PLANE_8][i][j]=max(0,min(255,(iaa+(i-3)*ib +(j-3)*ic + 16)/32));// store plane prediction
    }
  }

  if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
  {                       // since ipredmodes could be overwritten => encoder-decoder-mismatches
    // pick lowest cost prediction mode
    min_cost = 1<<20;
    for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
    {
      if ((mode==VERT_PRED_8 && !mb_available_up) ||
          (mode==HOR_PRED_8 && !mb_available_left) ||
          (mode==PLANE_8 && (!mb_available_left || !mb_available_up || !mb_available_up_left)))
        continue;

      cost = 0;
      for (uv=0; uv<2; uv++

⌨️ 快捷键说明

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