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

📄 mv_competition.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    }
    
    return rate;
  }
  
  /*! 
  *************************************************************************************
  * \brief
  *    
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  
  int writeMotionVectorPredictorSKIP (int predictor)
  {
    int            rate       = 0;
    Macroblock*    currMB     = &img->mb_data[img->current_mb_nr];
    SyntaxElement* currSE     = &img->MB_SyntaxElements[currMB->currSEnr];
    int*           bitCount   = currMB->bitcounter;
    Slice*         currSlice  = img->currentSlice;
    const int*     partMap    = assignSE2partition[input->partition_mode];
    DataPartition* dataPart;
    
    currSE->value1 = predictor;
    currSE->type = SE_MV_PREDICTOR;
    currSE->value2 = (mv_comp.nb_mode_for_skip / 2) + (mv_comp.nb_mode_for_skip % 2);     
    
    if (input->symbol_mode == UVLC)
    {
      dataPart = &(currSlice->partArr[partMap[currSE->type]]);
      currSE->len = u_v(currSE->value2, "predictor for the SKIP mode", currSE->value1,dataPart->bitstream);
    }
    else
    {
      currSE->writing = writeMB_Motion_predictor_CABAC;
      dataPart = &(currSlice->partArr[partMap[currSE->type]]);
      dataPart->writeSyntaxElement (currSE, dataPart);
    }
    
    bitCount[BITS_SKIP_PRED] += currSE->len;
    rate                     += currSE->len;
    currSE++;  
    currMB->currSEnr++;
    
    return rate;
  }
  
  
  /*! 
  *************************************************************************************
  * \brief
  *    
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  int writeIndexForMotionVectorPrediction (int  refframe,  int  list_idx,
    int  mv_mode,
    int i,
    int j)
  {
    int            rate       = 0;
    
    Macroblock*    currMB     = &img->mb_data[img->current_mb_nr];
    int*           bitCount   = currMB->bitcounter;
    SyntaxElement* currSE     = &img->MB_SyntaxElements[currMB->currSEnr];
    Slice*         currSlice  = img->currentSlice;
    const int*     partMap    = assignSE2partition[input->partition_mode];
    DataPartition* dataPart;
    
    int maxmode = 0;
    
    if (img->type == I_SLICE) 
      maxmode = 1;
    else if (img->type == P_SLICE)
      maxmode = mv_comp.nb_mode_for_mvp;
    else if (img->type == B_SLICE)
      maxmode = mv_comp.nb_mode_for_mvb;
    
    currSE->value1 = predModeMV[mv_mode][refframe][list_idx][j][i];  
    currSE->type = SE_MV_PREDICTOR;
    currSE->value2 = (maxmode / 2) + (maxmode % 2);     
    
    if (maxmode > 1)
    {
      if (input->symbol_mode == UVLC)
      {
        dataPart = &(currSlice->partArr[partMap[currSE->type]]);
        currSE->len = u_v(currSE->value2, "predictor of MV", currSE->value1,dataPart->bitstream);
      }
      else
      {
        currSE->writing = writeMB_Motion_predictor_CABAC;
        dataPart = &(currSlice->partArr[partMap[currSE->type]]);
        dataPart->writeSyntaxElement (currSE, dataPart);
      }
    }
    
    bitCount[BITS_MV_PRED] += currSE->len;
    rate                   += currSE->len;
    currSE++;  
    currMB->currSEnr++;
    
    return rate;
  }
  
  /*! 
  *************************************************************************************
  * \brief
  *    This function is used to arithmetically encode the Motion vector 
  *   predictor
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  
  void writeMB_Motion_predictor_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
  {
    Macroblock          *currMB = &img->mb_data[img->current_mb_nr];
    int act_ctx = 0;
    MotionInfoContexts *ctx  = (img->currentSlice)->mot_ctx;
    int nb_symbol;
    int curr_symbol;
    
    if(se->value2 != 0)
    {
      nb_symbol = se->value2;
      curr_symbol = se->value1;
      
      while(nb_symbol!=0)
      {
        if(currMB->mb_type == 0)
          biari_encode_symbol(eep_dp, (signed short) (curr_symbol % 2), &ctx->mv_predictor_skip_contexts[act_ctx]);
        else 
          if(img->type == P_SLICE)
            biari_encode_symbol(eep_dp, (signed short) (curr_symbol % 2), &ctx->mv_predictor_mvp_contexts[act_ctx]);
          else if(img->type == B_SLICE)
            biari_encode_symbol(eep_dp, (signed short) (curr_symbol % 2), &ctx->mv_predictor_mvb_contexts[act_ctx]);
          
          nb_symbol--;
          curr_symbol = curr_symbol / 2;
      }
    }
  }
  
  
  /*! 
  *************************************************************************************
  * \brief
  *    Returns 0 if no motion vector is available for the previous frame
  * at macrobloc position (pos_j, pos_i), 1 otherwise
  * because of INTRA_MODE or out of frame (checked here)Writes motion vectors predictor for SKIP
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  short collocated_mv_available(int pos_y, int pos_x, int list)
  {
    short return_val = TRUE;
    
    if (listX[list][0]->ref_idx[0][pos_y*4][pos_x*4] == -1)  // Collocated block in INTRA
    {
      return_val = FALSE;
    }
    
    return (return_val);
  }
  
  /*! 
  *************************************************************************************
  * \brief
  *    Writes motion vectors predictor for SKIP
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  short collocated_mv_available_previous_B_frame(int pos_y, int pos_x, int list)
  {
    short return_val = TRUE;
    
    if (ref_idx_previous_B_frame[list][pos_y*4][pos_x*4] == -1)  // Collocated block in INTRA
      return_val = FALSE;
    
    return (return_val);
  }
  
  /*! 
  *************************************************************************************
  * \brief
  *    
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  short send_index_for_skip_prediction(int best_mode_skip)
  {
    short mv_x_ref, mv_y_ref;
    short i;
    short return_val = FALSE;      // Assumes it can be guessed
    short nb_of_available = 0;        // Number of modes available
    
    mv_x_ref = mv_comp.mv_pred_skip[best_mode_skip][0];
    mv_y_ref = mv_comp.mv_pred_skip[best_mode_skip][1];
    
    for (i=0; i<mv_comp.nb_mode_for_skip; i++)
    {
      //Check if among all modes enabled, one single is AVAILABLE (all others are NOT_AVAILABLE)
      if (mv_comp.mv_pred_skip[i][0] != NOT_AVAILABLE) 
        nb_of_available++;
    }
    
    if (nb_of_available > 1)  //Otherwise does not need to be sent: only one is available
    {
      for (i=0; i<mv_comp.nb_mode_for_skip; i++)
      {
        if ((mv_comp.mv_pred_skip[i][0] != mv_x_ref) 
          || (mv_comp.mv_pred_skip[i][1] != mv_y_ref))
          
          return_val = TRUE;    // One of the component for one prediction is different
        // We can return 0, the mode cannot be guessed
      }
    }
    
    return (return_val);
  }
  
  /*! 
  *************************************************************************************
  * \brief
  *    Set motion vector predictor
  *
  * \param 
  *    
  *
  * \return
  *    
  *************************************************************************************
  */
  void SetMotionVectorPredictor_Competition (short  pmv[2],
    char   **refPic,
    short  ***tmp_mv,
    short  ref_frame,
    int    list,
    int    block_x,
    int    block_y,
    int    blockshape_x,
    int    blockshape_y)
  {
    
    int mb_x                 = 4*block_x;
    int mb_y                 = 4*block_y;
    short  pmv2[2];
    short predictor;
    
    int maxmode=0;
    int modeblock;
    int prediction_mode;
    int *predictors=NULL;
    
    modeblock = determine_mode_block(blockshape_x,blockshape_y);
    
    if (img->type == I_SLICE) 
      maxmode = 1;
    else if (img->type == P_SLICE)
    {
      maxmode = mv_comp.nb_mode_for_mvp;
      predictors = mv_comp.predictor_for_mvp;
    }
    else if (img->type == B_SLICE)
    {
      maxmode = mv_comp.nb_mode_for_mvb;
      predictors = mv_comp.predictor_for_mvb;
    }
    
    predictor = 0;
    
    for (prediction_mode = 0; prediction_mode<maxmode; prediction_mode++)
    {
      if (predictors[prediction_mode] == PRED_H264_MEDIAN)  
      {
        SetMotionVectorPredictor(pmv2,refPic,tmp_mv,ref_frame,list,block_x,block_y,blockshape_x,blockshape_y);
        
        if (predictor == 0 )
        { 
          pmv[0]=pmv2[0];
          pmv[1]=pmv2[1];
        }
      }
      else if (predictors[prediction_mode] == PRED_ZERO)
      {
        pmv2[0] = 0;
        pmv2[1] = 0;
      }
      else if (predictors[prediction_mode] == PRED_A)  
      {  
        PixelPos block_a;
        getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y,           -1,  0, &block_a);
        pmv2[0] = block_a.available  ? tmp_mv[block_a.pos_y][block_a.pos_x][0] : 0;
        pmv2[1] = block_a.available  ? tmp_mv[block_a.pos_y][block_a.pos_x][1] : 0;  
      }
      else if (predictors[prediction_mode] == PRED_B)  
      {
        PixelPos  block_b;
        
        getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y,            0, -1, &block_b);
        pmv2[0] = block_b.available  ? tmp_mv[block_b.pos_y][block_b.pos_x][0] : 0;
        pmv2[1] = block_b.available  ? tmp_mv[block_b.pos_y][block_b.pos_x][1] : 0;
      }
      else if (predictors[prediction_mode] == PRED_C)
      {
        PixelPos block_c, block_d;
        
        getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
        getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y,           -1, -1, &block_d);
        
        if (mb_y > 0)
        {
          if (mb_x < 8)  // first column of 8x8 blocks
          {
            if (mb_y==8)
            {
              if (blockshape_x == 16)      block_c.available  = 0;
              else                         block_c.available &= 1;
            }
            else
            {
              if (mb_x+blockshape_x != 8)  block_c.available &= 1;
              else                         block_c.available  = 0;
            }
          }
          else
          {
            if (mb_x+blockshape_x != 16)   block_c.available &= 1;
            else                           block_c.available  = 0;
          }
        }
        
        if (!block_c.available)
        {
          block_c=block_d;
        }
        
        pmv2[0] = block_c.available  ? tmp_mv[block_c.pos_y][block_c.pos_x][0] : 0;
        pmv2[1] = block_c.available  ? tmp_mv[block_c.pos_y][block_c.pos_x][1] : 0;
      }
      else if (predictors[prediction_mode] == 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 (img->type == P_SLICE)
        {
          
          if (collocated_mv_available(y, x, LIST_0) == TRUE)
          {
            // The collocated is the top left MV of the macroblock, whatever the subpartition...
            // To be improved.
            pmv2[0] = listX[0][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] * (ref_frame+1) / (listX[0][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
            pmv2[1] = listX[0][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] * (ref_frame+1) / (listX[0][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
          }
          else
          {
            pmv2[0] = 0;//NOT_AVAILABLE;
            pmv2[1] = 0;//NOT_AVAILABLE;
          }
        } 
        else if (img->type == B_SLICE)
        {
          // <FTRD : Compatibility with hierarchical B slices
          //  if(input->HierarchicalCoding == 0)
          //    {
          //    SetMotionVectorPredictor_collocated_B_SLICE(pmv2, y, x, list, ref_frame, block_y, block_x);
          //    }
          //    else
          //    {
          SetMotionVectorPredictor_collocated_HB_SLICE(pmv2, y, x, list, ref_frame, block_y, block_x);
          //    }
          // FTRD>
        }
      }
      mv_predictors[block_x][block_y][modeblock][ref_frame][list][prediction_mode][0] = pmv2[0];
      mv_predictors[block_x][block_y][modeblock][ref_frame][list][prediction_mode][1] = pmv2[1];
  }
  
  // Check if the index for the motion vector prediction needs to be sent or not
  // Stored in predModeMV2
  send_index_for_mv_prediction(block_x, block_y, modeblock, ref_frame, list, maxmode);
}

/*! 
*************************************************************************************
* \brief
*    
*
* \param 
*    
*
* \return
*    
*************************************************************************************
*/

void send_index_for_mv_prediction(int block_x, int block_y, int modeblock, short ref_frame, int list, int maxmode) 
{
  short egality_of_predictors = 0;
  short current_predictor_index;
  short nb_of_available = 0;
  short i;
  
  
  int pred0_x, pred0_y, current_pred_x, current_pred_y; 
  
  pred0_x = mv_predictors[block_x][block_y][modeblock][ref_frame][list][0][0];
  pred0_y = mv_predictors[block_x][block_y][modeblock][ref_frame][list][0][1];
  
  for (i=0; i<maxmode; i++)
  {
    //Check if among all modes enabled, one single is AVAILABLE (all others are NOT_AVAILABLE)
    if (mv_predictors[block_x][block_y][modeblock][ref_frame][list][i][0] != NOT_AVAILABLE) 
      nb_of_available++;
  }
  
  //  if (nb_of_available > 1)  //Otherwise does not need to be sent: only one is available
  {
    for(current_predictor_index=1;current_predictor_index<maxmode ;current_predictor_index++)
    {
      current_pred_x = mv_predictors[block_x][block_y][modeblock][ref_frame][list][current_predictor_index][0];
      current_pred_y = mv_predictors[block_x][block_y][modeblock][ref_frame][list][current_predictor_index][1];
      
      if ((current_pred_x == pred0_x) && (current_pred_y == pred0_y))
        egality_of_predictors++;  
    }
  }
  
  if(egality_of_predictors == maxmode-1)
    send_index_mv_prediction[modeblock][ref_frame][list][block_y][block_x][maxmode]=1;
  else 
    send_index_mv_prediction[modeblock][ref_frame][list][block_y][block_x][maxmode]=0;
}

/*! 
*************************************************************************************
* \brief
*    return le mode associ

⌨️ 快捷键说明

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