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

📄 image.c

📁 包含了从MPEG4的视频解码到H.264的视频编码部分的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
  }
  
  // do reference frame buffer reordering
  reorder_mref(img);
  if ( (img->weighted_bipred_idc > 0  && (img->type == B_SLICE)) || (img->weighted_pred_flag && img->type !=I_SLICE))
    fill_wp_params(img);
  

  if (current_header == SOP)
  {
    if (img->number == 0) 
      ercInit(img->width, 2*img->height, 1);
    // reset all variables of the error concealmnet instance before decoding of every frame.
    // here the third parameter should, if perfectly, be equal to the number of slices per frame.
    // using little value is ok, the code will alloc more memory if the slice number is larger
    ercReset(erc_errorVar, img->max_mb_nr, img->max_mb_nr, img->width);
    erc_mvperMB = 0;
  }
  
  // decode main slice information
  if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
    decode_one_slice(img,inp);
  
  // setMB-Nr in case this slice was lost
//  if(currSlice->ei_flag)  
//    img->current_mb_nr = currSlice->last_mb_nr + 1;

//! This code doesn't work with FMO or a slice lossy environment or out-of-order slices
  if(currSlice->next_eiflag && img->current_mb_nr != img->max_mb_nr)
    currSlice->next_header = SOS;
}

/*!
 ************************************************************************
 * \brief
 *    Initializes the parameters for a new field
 ************************************************************************
 */
void init_top(struct img_par *img, struct inp_par *inp)
{
  static int first_P = TRUE;
  int i,j;

  img->buf_cycle *= 2;
  img->number *= 2;
//  img->current_mb_nr=-4714;   // impossible value, StW
  img->current_slice_nr=0;

  img->mb_y = img->mb_x = 0;
  img->block_y = img->pix_y = img->pix_c_y = 0; // define vertical positions
  img->block_x = img->pix_x = img->pix_c_x = 0; // define horizontal positions

  last_P_no = last_P_no_fld;
  nextP_tr = nextP_tr_fld;

  //WYK: When entire non-B frames are lost, adjust the reference buffers
  //! TO 4.11.2001 Yes, but only for Bitstream mode! We do not loose anything in bitstream mode!
  //! Should remove this one time!
/* !KS removed refPicID from Header
#ifndef AFF //to be fixed
  if(inp->FileFormat == PAR_OF_ANNEXB) //! TO 4.11.2001 just to make sure that this piece of code 
  {                              //! does not affect any other input mode where this refPicID is not supported
    j = img->refPicID-img->refPicID_old;
    if(j<0) j += 16;    // img->refPicID is 4 bit, wrapps at 15
    if(j > 1) //at least one non-B frame has been lost  
    {
      for(i=1; i<j; i++)  // j-1 non-B frames are lost
      {
        img->number++;
        copy2fb(img);
      }
    }
  }
#endif
*/
  if (img->number == 0) // first picture
  {
    nextP_tr=prevP_tr=img->tr;
  }
  else if(img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)  // I or P pictures
  {
#ifdef _ADAPT_LAST_GROUP_

    for (i = img->buf_cycle; i > 0; i--)
      last_P_no[i] = last_P_no[i-1];
    last_P_no[0] = nextP_tr;
#endif
    nextP_tr=img->tr;

    if(first_P) // first P picture
    {
      first_P = FALSE;
      P_interval=nextP_tr-prevP_tr; //! TO 4.11.2001 we get problems here in case the first P-Frame was lost
    }
    write_prev_Pframe(img, p_out);  // imgY_prev, imgUV_prev -> file
  }
  
  if (img->type > SI_SLICE)
  {
    set_ec_flag(SE_PTYPE);
    img->type = P_SLICE;  // concealed element
  }

  img->max_mb_nr = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE);

  // allocate memory for frame buffers
  if (img->number == 0) 
  {
    init_frame_buffers(inp, img); 
    init_global_buffers(inp, img); 
    img->buf_cycle *= 2;
  }

  for(i=0;i<img->width/BLOCK_SIZE+1;i++)          // set edge to -1, indicate nothing to predict from
  {
    img->ipredmode[i+1][0]=-1;
    img->ipredmode[i+1][img->height/BLOCK_SIZE+1]=-1;
  }
  for(j=0;j<img->height/BLOCK_SIZE+1;j++)
  {
    img->ipredmode[0][j+1]=-1;
    img->ipredmode[img->width/BLOCK_SIZE+1][j+1]=-1;
  }
  img->ipredmode[0][0] = -1;

  if(img->constrained_intra_pred_flag)
  {
    for (i=0; i<img->width/MB_BLOCK_SIZE*img->height/MB_BLOCK_SIZE; i++)
    {
      img->intra_block[i][0] =img->intra_block[i][1] = img->intra_block[i][2] = img->intra_block[i][3] = 1;
    }
  }

  // WYK: Oct. 8, 2001. Set the slice_nr member of each MB to -1, to ensure correct when packet loss occurs
  for(i=0; i<img->max_mb_nr; i++)
    img->mb_data[i].slice_nr = -1;

  fb = fld;

  imgY = imgY_top;
  imgUV = imgUV_top;

  mref = mref_fld;
  mcef = mcef_fld;

  img->mv = img->mv_top;
  refFrArr = refFrArr_top;

  moving_block = moving_block_top;

  img->fw_refFrArr = img->fw_refFrArr_top;
  img->bw_refFrArr = img->bw_refFrArr_top;

}

/*!
 ************************************************************************
 * \brief
 *    Initializes the parameters for a new field
 ************************************************************************
 */
void init_bottom(struct img_par *img, struct inp_par *inp)
{
  static int first_P = TRUE;
  int i,j;

  img->number++;
//  img->current_mb_nr=-4715;   // impossible value, StW
  img->current_slice_nr=0;
  img->buf_cycle *= 2;

  img->mb_y = img->mb_x = 0;
  img->block_y = img->pix_y = img->pix_c_y = 0; // define vertical positions
  img->block_x = img->pix_x = img->pix_c_x = 0; // define horizontal positions

  last_P_no = last_P_no_fld;

  //WYK: When entire non-B frames are lost, adjust the reference buffers
  //! TO 4.11.2001 Yes, but only for Bitstream mode! We do not loose anything in bitstream mode!
  //! Should remove this one time!
/* !KS removed refPicID from Header  
#ifndef AFF //to be fixed
  if(inp->FileFormat == PAR_OF_ANNEXB) //! TO 4.11.2001 just to make sure that this piece of code 
  {                              //! does not affect any other input mode where this refPicID is not supported
    j = img->refPicID-img->refPicID_old;
    if(j<0) j += 16;    // img->refPicID is 4 bit, wrapps at 15
    if(j > 1) //at least one non-B frame has been lost  
    {
      for(i=1; i<j; i++)  // j-1 non-B frames are lost
      {
        img->number++;
        copy2fb(img);
      }
    }
  }
#endif
*/

  img->structure = TOP_FIELD;	//for set parity
  if(img->type==I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)
    copy2fb(img);       // trying to match exit_frame() in frame mode
  img->structure = BOTTOM_FIELD; //for set parity

  if (!img->mb_frame_field_flag)
  {
    if((img->type==B_SLICE) && !img->disposable_flag)
    {
      // copy motion information of stored B-picture for direct mode 
      for (i=0 ; i<img->width/4+4 ; i++)
      {
        for (j=0 ; j<img->height/4 ; j++)
        {
          img->mv_top[i][j][0] = img->fw_mv[i][j][0];
          img->mv_top[i][j][1] = img->fw_mv[i][j][1];        
          if (i<img->width/4)
          {
            refFrArr_top[j][i] = img->fw_refFrArr[j][i];
          }
        }
      }
    }
  }

  if (img->number == 0) // first picture
  {
    nextP_tr=prevP_tr=img->tr;
  }
  else if (img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)  // I or P pictures
  {
#ifdef _ADAPT_LAST_GROUP_
    if (img->number==1)
    {
      for (i = img->buf_cycle; i > 0; i--)
        last_P_no[i] = last_P_no[i-1];
      last_P_no[0] = nextP_tr;
    }
#endif
    nextP_tr=img->tr;
    
    if(first_P) // first P picture
    {
      first_P = FALSE;
      P_interval=nextP_tr-prevP_tr; //! TO 4.11.2001 we get problems here in case the first P-Frame was lost
    }
  }

  if (img->type > SI_SLICE)
  {
    set_ec_flag(SE_PTYPE);
    img->type = P_SLICE;  // concealed element
  }

  img->max_mb_nr = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE);

  for(i=0;i<img->width/BLOCK_SIZE+1;i++)          // set edge to -1, indicate nothing to predict from
  {
    img->ipredmode[i+1][0]=-1;
    img->ipredmode[i+1][img->height/BLOCK_SIZE+1]=-1;
  }
  for(j=0;j<img->height/BLOCK_SIZE+1;j++)
  {
    img->ipredmode[0][j+1]=-1;
    img->ipredmode[img->width/BLOCK_SIZE+1][j+1]=-1;
  }
  img->ipredmode[0][0] = -1;

  if(img->constrained_intra_pred_flag)
  {
    for (i=0; i<img->width/MB_BLOCK_SIZE*img->height/MB_BLOCK_SIZE; i++)
    {
      img->intra_block[i][0] =img->intra_block[i][1] = img->intra_block[i][2] = img->intra_block[i][3] = 1;
    }
  }

  // WYK: Oct. 8, 2001. Set the slice_nr member of each MB to -1, to ensure correct when packet loss occurs
  for(i=0; i<img->max_mb_nr; i++)
    img->mb_data[i].slice_nr = -1;

  imgY = imgY_bot;
  imgUV = imgUV_bot;

  img->mv = img->mv_bot;
  moving_block = moving_block_bot;
  refFrArr = refFrArr_bot;
  mref = mref_fld;
  mcef = mcef_fld;

  img->fw_refFrArr = img->fw_refFrArr_bot;
  img->bw_refFrArr = img->bw_refFrArr_bot;

}

/*!
 ************************************************************************
 * \brief
 *    Prepare field and frame buffer after frame decoding
 ************************************************************************
 */
void frame_postprocessing(struct img_par *img, struct inp_par *inp)
{
  int i;

  img->height = img->height/2;
  img->height_cr = img->height_cr/2;
  img->number *= 2;
  img->buf_cycle *= 2;

  fb = fld;
  mref = mref_fld;
  mcef = mcef_fld;
  imgY = imgY_top;
  imgUV = imgUV_top;
  img->structure = TOP_FIELD;//for set parity
  if (img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)  // I or P pictures
  {
    split_field_top(img);
    copy2fb(img);
  }

  img->number++;
  imgY = imgY_bot;
  imgUV = imgUV_bot;
  img->structure = BOTTOM_FIELD;//for set parity
  if (img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)  // I or P pictures
  {
    split_field_bot(img);
    copy2fb(img);
  }

  fb = frm;
  mref = mref_frm;
  mcef = mcef_frm;
  imgY = imgY_frm;
  imgUV = imgUV_frm;
  img->structure = FRAME;
  
  img->height *= 2;
  img->height_cr *= 2;
  img->buf_cycle /= 2;
  img->number /= 2;

  if((img->number)&&(img->type==I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag))
  {
    for (i = img->buf_cycle; i > 2; i--)
    {
      last_P_no_fld[i] = last_P_no_fld[i-2];
      last_P_no_fld[i-1] = last_P_no_fld[i-3];
    }
    last_P_no_fld[0] = nextP_tr_fld+1;
    last_P_no_fld[1] = nextP_tr_fld;

    nextP_tr_fld = nextP_tr * 2;
    nextP_tr_frm = nextP_tr;
  }
}

/*!
 ************************************************************************
 * \brief
 *    Extract top field from a frame
 ************************************************************************
 */
void split_field_top(struct img_par *img)
{
  int i;

  for (i=0; i<img->height; i++)
  {
    memcpy(imgY[i], imgY_frm[i*2], img->width);
  }

  for (i=0; i<img->height_cr; i++)
  {
    memcpy(imgUV[0][i], imgUV_frm[0][i*2], img->width_cr);
    memcpy(imgUV[1][i], imgUV_frm[1][i*2], img->width_cr);
  }
}

/*!

⌨️ 快捷键说明

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