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

📄 mv_competition.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
        colocated_MV_y = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][1];
        
        *pmv_x = -((b_frame_to_code + 1))*colocated_MV_x / (successive_Bframe+1-((b_frame_to_code + 1)-1));
        *pmv_y = -((b_frame_to_code + 1))*colocated_MV_y / (successive_Bframe+1-((b_frame_to_code + 1)-1));
        
        if ((collocated_mv_available(y, x, LIST_1) == TRUE) && (ref_frame != 0))
        {
          *pmv_x = *pmv_x  + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
          *pmv_y = *pmv_y  + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
        }
      }
      else 
      {
        if (collocated_mv_available_previous_B_frame(y, x, LIST_0) == TRUE)
        {
          colocated_MV_x = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][0] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
          colocated_MV_y = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][1] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
          
          *pmv_x = ((b_frame_to_code + 1))*colocated_MV_x / ((b_frame_to_code + 1)-1);  
          *pmv_y = ((b_frame_to_code + 1))*colocated_MV_y / ((b_frame_to_code + 1)-1);
          
          if ((collocated_mv_available(y, x, LIST_1) == TRUE) && (ref_frame != 0))
          {
            *pmv_x = *pmv_x + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
            *pmv_y = *pmv_y + (ref_frame*listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1));
          }
        }
        else
        {
          *pmv_x = 0;
          *pmv_y = 0;
        }
      }
    }
    
  }
  else
  {//LIST_1
    if((b_frame_to_code)==0)//if this B_frame is the first B_frame of the GOP
    {
      if (collocated_mv_available(y, x, LIST_1) == TRUE)
      { 
        colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] * (ref_frame+1) / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
        colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] * (ref_frame+1) / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
        
        *pmv_x = -successive_Bframe*colocated_MV_x/(successive_Bframe+1);
        *pmv_y = -successive_Bframe*colocated_MV_y/(successive_Bframe+1);
      }
      else
      {
        *pmv_x = 0;
        *pmv_y = 0;
      }
    }
    else
    {
      if (collocated_mv_available_previous_B_frame(y, x, LIST_1) == TRUE)
      {
        colocated_MV_x = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][0];
        colocated_MV_y = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][1];
        
        *pmv_x = (successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_x / (successive_Bframe+1-((b_frame_to_code + 1)-1));
        *pmv_y = (successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_y / (successive_Bframe+1-((b_frame_to_code + 1)-1));
        
      }
      else
      {
        if (collocated_mv_available_previous_B_frame(y, x, LIST_0) == TRUE)
        {
          colocated_MV_x = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][0] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
          colocated_MV_y = ((b_frame_to_code + 1)-1) * mv_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x][1] / (ref_idx_previous_B_frame[LIST_0][y*4+block_y][x*4+block_x] * (successive_Bframe+1) + ((b_frame_to_code + 1)-1));
          
          *pmv_x = -(successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_x / ((b_frame_to_code + 1)-1);
          *pmv_y = -(successive_Bframe+1-(b_frame_to_code + 1))*colocated_MV_y / ((b_frame_to_code + 1)-1);            
        }
        else
        {
          *pmv_x = 0;
          *pmv_y = 0;
        }
      }
    }
  }
  
}

void Copy_MV_B_frame(short ****  mv, char  ***   ref_idx)
{ 
  int i, j;
  
  for(i=0;i<img->height/4;i+=1)
  {
    for(j=0;j<img->width/4;j+=1)
    {
      mv_previous_B_frame[LIST_0][i][j][0] = mv[LIST_0][i][j][0];
      mv_previous_B_frame[LIST_0][i][j][1] = mv[LIST_0][i][j][1];
      ref_idx_previous_B_frame[LIST_0][i][j] = ref_idx[LIST_0][i][j];
      
      mv_previous_B_frame[LIST_1][i][j][0] = mv[LIST_1][i][j][0];
      mv_previous_B_frame[LIST_1][i][j][1] = mv[LIST_1][i][j][1];
      ref_idx_previous_B_frame[LIST_1][i][j] = ref_idx[LIST_1][i][j];
    }
  }
  
}

/*!
************************************************************************
* \brief
*    Set motion vector predictor
************************************************************************
*/

void SetMotionVectorPredictor_Skip (short  *pmv_x, short *pmv_y, char   ***refPic, short  ****tmp_mv, short  ref_frame,
                                    int    list, int    block_x, int    block_y, int    blockshape_x, int    blockshape_y,
                                    short mode_skip)
{ 
  int zeroMotionAbove;
  int zeroMotionLeft;
  //PixelPos mb_a, mb_b;
  int      a_mv_y = 0;
  int      a_ref_idx = 0;
  int      b_mv_y = 0;
  int      b_ref_idx = 0;
  //  int i=(int)img->current_mb_nr/(img->width/16);
  //  int j=(int)img->current_mb_nr%(img->width/16);
  
  
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  
  PixelPos block_a, block_b, block_c, block_d;
  int mb_nr = img->current_mb_nr;
  
  getLuma4x4Neighbour(mb_nr, block_x, block_y,           -1,  0, &block_a);
  getLuma4x4Neighbour(mb_nr, block_x, block_y,            0, -1, &block_b);
  getLuma4x4Neighbour(mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
  getLuma4x4Neighbour(mb_nr, block_x, block_y,           -1, -1, &block_d);
  
  //  Same as in the original JM... might not be optimal
  if (mv_comp.predictor_for_skip[mode_skip] == PRED_H264_MEDIAN)
  {
    if (block_a.available)
    {
      a_mv_y    = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
      a_ref_idx = dec_picture->ref_idx[LIST_0][block_a.pos_y][block_a.pos_x];
      
      if (currMB->mb_field && !img->mb_data[block_a.mb_addr].mb_field)
      {
        a_mv_y    /=2;
        a_ref_idx *=2;
      }
      if (!currMB->mb_field && img->mb_data[block_a.mb_addr].mb_field)
      {
        a_mv_y    *=2;
        a_ref_idx >>=1;
      }
    }
    
    if (block_b.available)
    {
      b_mv_y    = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
      b_ref_idx = dec_picture->ref_idx[LIST_0][block_b.pos_y][block_b.pos_x];
      
      if (currMB->mb_field && !img->mb_data[block_b.mb_addr].mb_field)
      {
        b_mv_y    /=2;
        b_ref_idx *=2;
      }
      if (!currMB->mb_field && img->mb_data[block_b.mb_addr].mb_field)
      {
        b_mv_y    *=2;
        b_ref_idx >>=1;
      }
    }
    
    zeroMotionLeft  = !block_a.available ? 1 : a_ref_idx==0 && dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
    zeroMotionAbove = !block_b.available ? 1 : b_ref_idx==0 && dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
    
    if (zeroMotionAbove || zeroMotionLeft)
    {
      
      *pmv_x = 0;
      *pmv_y = 0;
    }
    else
    {
      SetMotionVectorPredictor (img, pmv_x, pmv_y, 0, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
    }    
  }
  
  else if (mv_comp.predictor_for_skip[mode_skip] == PRED_A)
  {  
    if (block_a.available) /*&& (img->mb_data[img->current_mb_nr-1].mb_type<9))*/ 
    {
      *pmv_x = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0];
      *pmv_y = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
    }
    else 
    {
      *pmv_x = NOT_AVAILABLE;
      *pmv_y = NOT_AVAILABLE;
    }
  }
  else if (mv_comp.predictor_for_skip[mode_skip] == PRED_B)
  {  
    if (block_b.available) /*&& (img->mb_data[img->current_mb_nr-1].mb_type<9))*/ 
    {
      *pmv_x = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0];
      *pmv_y = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
    }
    else 
    {
      *pmv_x = NOT_AVAILABLE;
      *pmv_y = NOT_AVAILABLE;
    }
  }
  else if (mv_comp.predictor_for_skip[mode_skip] == PRED_C)
  {  
    if (block_c.available) /*&& (img->mb_data[img->current_mb_nr-1].mb_type<9))*/ 
    {
      *pmv_x = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][0];
      *pmv_y = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][1];
    }
    else 
    {
      *pmv_x = NOT_AVAILABLE;
      *pmv_y = NOT_AVAILABLE;
    }
  }
  else if (mv_comp.predictor_for_skip[mode_skip] == PRED_ZERO)
  {  
    *pmv_x = 0;
    *pmv_y = 0;
  }
  else if (mv_comp.predictor_for_skip[mode_skip] == PRED_COLOCATED)
  {
    int y=(int)img->current_mb_nr/(img->width/16);  // Vertical
    int x=(int)img->current_mb_nr%(img->width/16);  // Horizontal
    
    if (collocated_mv_available(y, x, LIST_0) == TRUE)
    {
      
      *pmv_x = listX[0][0]->mv[LIST_0][y*4][x*4][0] / (listX[0][0]->ref_idx[0][y*4][x*4] + 1);
      *pmv_y = listX[0][0]->mv[LIST_0][y*4][x*4][1] / (listX[0][0]->ref_idx[0][y*4][x*4] + 1);
    }
    else
    {
      *pmv_x = NOT_AVAILABLE;
      *pmv_y = NOT_AVAILABLE;
    }
  }
  else if (mv_comp.predictor_for_skip[mode_skip] == PRED_EXTENDEDSPATIAL)  
  {
    int mv_a, mv_b, mv_c;
    
    if ((block_a.available) && (block_b.available) && (block_c.available))  
    {
      mv_a = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0];
      mv_b = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0];
      mv_c = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][0];      
      *pmv_x = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
      
      mv_a = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];
      mv_b = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
      mv_c = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][1];      
      *pmv_y = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
    }
    else if (block_a.available) 
    {
      *pmv_x = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][0];        
      *pmv_y = dec_picture->mv[LIST_0][block_a.pos_y][block_a.pos_x][1];        
      
    }
    else if (block_b.available)  
    {
      *pmv_x = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][0];
      *pmv_y = dec_picture->mv[LIST_0][block_b.pos_y][block_b.pos_x][1];
      
    }
    else if (block_c.available)  
    {
      *pmv_x = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][0];
      *pmv_y = dec_picture->mv[LIST_0][block_c.pos_y][block_c.pos_x][1];
      
    }
    else
    {
      *pmv_x = 0;
      *pmv_y = 0;
    }
  }
  
  
}

// <FTRD : Compatibility with hierarchical B frames
void init_mvscale_hb()
{
  int i, j, k, l;
  int iTRb = 0 ; int iTRp = 0;
  int prescale = 0;
  int num_ref_max = 0;
  
  //printf("Encoding picture : %d\n",dec_picture->poc/2);
  //printf("[point_list_cur_B] [ref_num_B] [point_list_coloc] [ref_num_coloc] [mv_scale]\n");
  
  // Mv in current B frame points to LIST_0 or LIST_1
  for(i = 0 ; i < 2 ; i++)
  {
    for(k = 0 ; k <listXsize[i] ; k++)
    {
      iTRb = Clip3(-128, 127, dec_picture->poc - listX[i][k]->poc);
      
      // The colocated vector points to LIST_0 or LIST_1
      for(j=0;j<2;j++)
      {
        if(listX[LIST_1][0]->slice_type == B_SLICE) 
        {
          if(j==0) num_ref_max = img->num_ref_idx_l0_active;  
          if(j==1) num_ref_max = img->num_ref_idx_l0_active;  
        }
        if(listX[LIST_1][0]->slice_type == P_SLICE) 
        {
          num_ref_max = dpb.num_ref_frames;
        }
        
        for(l = 0 ; l < num_ref_max ; l++)
        {
          iTRp = (int)Clip3(-128, 127, listX[LIST_1][0]->poc - (listX[LIST_1][0]->ref_pic_num[0][j][l]/2));
          
          if(iTRp==0) img->mvscale_hb[i][j][k][l]=9999;
          else 
          {
            prescale=(16384 + absm(iTRp/2))/iTRp;
            //printf("B = %d , ref_B = %d , colc = %d , ref_col = %d\n",enc_picture->poc/2,
            img->mvscale_hb[i][j][k][l] = Clip3(-2048, 2047,(iTRb*prescale + 32) >> 6);
            //printf("LIST_%d   %d   LIST_%d   %d   %f\n",i,k,j,l,(float)iTRb/(float)iTRp);
          }
        }
      }
    }
  }
}
// FTRD>

// <FTRD : Compatibility with hierarchical B frames
void SetMotionVectorPredictor_collocated_HB_SLICE (short *pmv_x,short *pmv_y,int y,int x,int list,int ref_frame,int block_y,int block_x)
{
  int colocated_MV_x = 0, colocated_MV_y = 0;
  int ref_frame_coloc = 0;
  *pmv_x = 0;
  *pmv_y = 0;
  
  // printf("%d, %d\n",listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x],listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x]);
  
  // B frame mv points to LIST_0
  if(list == LIST_0)
  {
    // If colocated mv points to LIST_0
    if(listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x] != -1)
    {
      colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0];
      colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1];
      
      ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x];
      
      // Scaling
      *pmv_x = (img->mvscale_hb[LIST_0][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
      *pmv_y = (img->mvscale_hb[LIST_0][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
    }
    
    else
    {
      // If colocated mv points to LIST_1
      if(listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x] != -1)
      {
        colocated_MV_x = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][0];
        colocated_MV_y = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][1];
        
        ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x];
        
        // Scaling
        *pmv_x = (img->mvscale_hb[LIST_0][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
        *pmv_y = (img->mvscale_hb[LIST_0][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
      }
      
      // No colocated mv is available.
      else
      {
        *pmv_x = 0;
        *pmv_y = 0;
      }
    }
  }
  
  // B frame mv points to LIST_1
  else
  {
    // If colocated mv points to LIST_0
    if(listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x] != -1)
    {
      colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0];
      colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1];
      
      ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_0][y*4+block_y][x*4+block_x];
      
      // Scaling
      *pmv_x = (img->mvscale_hb[LIST_1][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
      *pmv_y = (img->mvscale_hb[LIST_1][LIST_0][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
    }
    
    else
    {
      // If colocated mv points to LIST_1
      if(listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x] != -1)
      {
        colocated_MV_x = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][0];
        colocated_MV_y = listX[LIST_1][0]->mv[LIST_1][y*4+block_y][x*4+block_x][1];
        
        ref_frame_coloc = listX[LIST_1][0]->ref_idx[LIST_1][y*4+block_y][x*4+block_x];
        
        // Scaling
        *pmv_x = (img->mvscale_hb[LIST_1][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_x + 128) >> 8;
        *pmv_y = (img->mvscale_hb[LIST_1][LIST_1][ref_frame][ref_frame_coloc] * colocated_MV_y + 128) >> 8;
      }
      
      // No colocated mv is available.
      else
      {
        *pmv_x = 0;
        *pmv_y = 0;
      }
    }
  } 
}
// FTRD>
#endif

⌨️ 快捷键说明

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