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

📄 image.c

📁 本源码是H.26L标准的Visual C++源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }
    else {
      for (j = 0; j < BLOCK_SIZE; j++) {
        for (i = 0; i < BLOCK_SIZE; i++) {
          for (result = 0, x = -3; x < 5; x++)
            result += tmp[j][i+x+3]*COEF[dx/2][x+3];
          block2[i][j] = max(0, min(255, (result+32768)/65536));
        }
      }
    }

    average_block(block, block2);
  }
  else if ((dx == 1 || dx == 7) && (dy == 1 || dy == 7)) { /* Diagonal averaging */
    interp_block_X(ref_frame, pres_x, (y_pos+1)>>3, COEF[(dx+1)/4], max_x, max_y, block);
    interp_block_Y(ref_frame, (x_pos+1)>>3, pres_y, COEF[(dy+1)/4], max_x, max_y, block2);
    average_block(block, block2);
  }
  else if (dx == 1 || dx == 7 || dy == 1 || dy == 7) { /* Diagonal linear interpolation */

    interp_block_X(ref_frame, pres_x, (y_pos+3)>>3, COEF[1], max_x, max_y, block);
    interp_block_Y(ref_frame, (x_pos+3)>>3, pres_y, COEF[1], max_x, max_y, block2);

    if (dx == 1 || dx == 7)
      interp_block_3_1(block, block2, block);
    else
      interp_block_3_1(block, block, block2);
  }
  else { /* Diagonal interpolation using a full pixel and a center 1/2-pixel */

    for (j = -3; j < BLOCK_SIZE+5; j++) {
      for (i = 0; i < BLOCK_SIZE; i++) {
        for (tmp[i][j+3] = 0, x = -3; x < 5; x++)
          tmp[i][j+3] += mref[ref_frame][max(0,min(pres_y+j,max_y))][max(0,min(pres_x+i+x,max_x))]*COEF[1][x+3];
      }
    }

    for (j = 0; j < BLOCK_SIZE; j++) {
      for (i = 0; i < BLOCK_SIZE; i++) {
        for (result = 0, y = -3; y < 5; y++)
          result += tmp[i][j+y+3]*COEF[1][y+3];
        block[i][j] = max(0, min(255, (result+32768)/65536));
      }
    }

    get_fullpel_block(ref_frame, (x_pos+3)>>3, (y_pos+3)>>3, max_x, max_y, block2);
    interp_block_3_1(block, block, block2);
  }
}

/*!
 ************************************************************************
 * \brief
 *    Reads new slice (picture) from bit_stream
 ************************************************************************
 */
int read_new_slice(struct img_par *img, struct inp_par *inp)
{

    int current_header;
    Slice *currSlice = img->currentSlice;

    // read new slice
    current_header = currSlice->readSlice(img,inp);
    return  current_header;
}


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


  img->current_mb_nr=0;
  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

  //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!
  
  if(inp->of_mode == PAR_OF_26L) //! 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);
      }
    }
  }
  
  if (img->number == 0) // first picture
  {
    nextP_tr=prevP_tr=img->tr;
  }
  else if(img->type == INTRA_IMG || img->type == INTER_IMG_1 || img->type == INTER_IMG_MULT || img->type == SP_IMG_1 || img->type == SP_IMG_MULT)  // I or P pictures
  {
#ifdef _ADAPT_LAST_GROUP_
    for (i = img->buf_cycle-1; 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 > SP_IMG_MULT)
  {
    set_ec_flag(SE_PTYPE);
    img->type = INTER_IMG_1;  // 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); 
  }

  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;
  for(j=0;j<img->height/BLOCK_SIZE+1;j++)
    img->ipredmode[0][j+1]=-1;

  if(img->UseConstrainedIntraPred)
  {
    for (i=0; i<img->width/MB_BLOCK_SIZE*img->height/MB_BLOCK_SIZE; i++)
      img->intra_mb[i] = 1; // default 1 = intra mb
  }

  // 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; 

}

/*!
 ************************************************************************
 * \brief
 *    exit a frame
 ************************************************************************
 */
void exit_frame(struct img_par *img, struct inp_par *inp)
{
    if(img->type==INTRA_IMG || img->type == INTER_IMG_1 || img->type == INTER_IMG_MULT || img->type == SP_IMG_1 || img->type == SP_IMG_MULT)
        copy2fb(img);
}

/*!
 ************************************************************************
 * \brief
 *    write the encoding mode and motion vectors of current 
 *    MB to the buffer of the error concealment module.
 ************************************************************************
 */
#if _ERROR_CONCEALMENT_
void ercWriteMBMODEandMV(struct img_par *img,struct inp_par *inp)
{
  extern objectBuffer_t *erc_object_list;
  int i, ii, jj, currMBNum = img->current_mb_nr;
  int mbx = xPosMB(currMBNum,img->width), mby = yPosMB(currMBNum,img->width);
  objectBuffer_t *currRegion, *pRegion;
  Macroblock *currMB = &img->mb_data[currMBNum];

  currRegion = erc_object_list + (currMBNum<<2);

  if(img->type != B_IMG_1 && img->type != B_IMG_MULT) //non-B frame
  {
    if(currMB->intraOrInter == INTRA_MB_16x16)
    {
      for(i=0; i<4; i++)
      {
        pRegion = currRegion + i;
        pRegion->regionMode = REGMODE_INTRA;
        pRegion->mv[0] = 0;
        pRegion->mv[1] = 0;
        pRegion->mv[2] = currMB->ref_frame;
      }
    }
    else if(currMB->intraOrInter == INTRA_MB_4x4)
    {
      for(i=0; i<4; i++)
      {
        pRegion = currRegion + i;
        pRegion->regionMode = REGMODE_INTRA_8x8;
        pRegion->mv[0] = 0;
        pRegion->mv[1] = 0;
        pRegion->mv[2] = currMB->ref_frame;
      }
    }
    else //if(currMB->intraOrInter == INTER_MB)
    {
      switch(img->mb_mode)
      {
      case COPY_MB:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_COPY;
          pRegion->mv[0] = 0;
          pRegion->mv[1] = 0;
          pRegion->mv[2] = currMB->ref_frame;
        }
        break;
      case M16x16_MB:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_PRED;
          pRegion->mv[0] = img->mv[4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][0];
          pRegion->mv[1] = img->mv[4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][1];
          erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
          pRegion->mv[2] = currMB->ref_frame;
        }
        break;
      case M16x8_MB:
      case M8x16_MB:
      case M8x8_MB:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_PRED_8x8;
          pRegion->mv[0] = img->mv[4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][0];
          pRegion->mv[1] = img->mv[4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][1];
          erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
          pRegion->mv[2] = currMB->ref_frame;
        }
        break;
      case M8x4_MB:
      case M4x8_MB:
      case M4x4_MB:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_PRED_8x8;
          ii = 4*mbx + (i%2)*2 + BLOCK_SIZE; jj = 4*mby + (i/2)*2;
          pRegion->mv[0] = (img->mv[ii][jj][0] + img->mv[ii+1][jj][0] + img->mv[ii][jj+1][0] + img->mv[ii+1][jj+1][0] + 2)/4;
          pRegion->mv[1] = (img->mv[ii][jj][1] + img->mv[ii+1][jj][1] + img->mv[ii][jj+1][1] + img->mv[ii+1][jj+1][1] + 2)/4;
          erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
          pRegion->mv[2] = currMB->ref_frame;
        }
        break;
      default:
        snprintf(errortext, ET_SIZE, "INTER MB mode %i is not supported\n", img->mb_mode);
        error (errortext, 200);
      }
    }
  }
  else  //B-frame
  {
    if(currMB->intraOrInter == INTRA_MB_16x16)
    {
      for(i=0; i<4; i++)
      {
        pRegion = currRegion + i;
        pRegion->regionMode = REGMODE_INTRA;
        pRegion->mv[0] = 0;
        pRegion->mv[1] = 0;
        pRegion->mv[2] = currMB->ref_frame;
      }
    }
    else if(currMB->intraOrInter == INTRA_MB_4x4)
    {
      for(i=0; i<4; i++)
      {
        pRegion = currRegion + i;
        pRegion->regionMode = REGMODE_INTRA_8x8;
        pRegion->mv[0] = 0;
        pRegion->mv[1] = 0;
        pRegion->mv[2] = currMB->ref_frame;
      }
    }
    else //if(currMB->intraOrInter == INTER_MB)
    {
      switch(img->imod)
      {
      case B_Forward:
      case B_Bidirect:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_PRED_8x8;
          ii = 4*mbx + (i%2)*2 + BLOCK_SIZE; jj = 4*mby + (i/2)*2;
          pRegion->mv[0] = (img->fw_mv[ii][jj][0] + img->fw_mv[ii+1][jj][0] + img->fw_mv[ii][jj+1][0] + img->fw_mv[ii+1][jj+1][0] + 2)/4;
          pRegion->mv[1] = (img->fw_mv[ii][jj][1] + img->fw_mv[ii+1][jj][1] + img->fw_mv[ii][jj+1][1] + img->fw_mv[ii+1][jj+1][1] + 2)/4;
          erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
          pRegion->mv[2] = (currMB->ref_frame-1+img->buf_cycle) % img->buf_cycle; //ref_frame_fw
        }
        break;
      case B_Backward:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_PRED_8x8;
          ii = 4*mbx + (i%2)*2 + BLOCK_SIZE; jj = 4*mby + (i/2)*2;
          pRegion->mv[0] = (img->bw_mv[ii][jj][0] + img->bw_mv[ii+1][jj][0] + img->bw_mv[ii][jj+1][0] + img->bw_mv[ii+1][jj+1][0] + 2)/4;
          pRegion->mv[1] = (img->bw_mv[ii][jj][1] + img->bw_mv[ii+1][jj][1] + img->bw_mv[ii][jj+1][1] + img->bw_mv[ii+1][jj+1][1] + 2)/4;
          erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
          pRegion->mv[2] = 0; //ref_frame_bw
        }
        break;
      case B_Direct:
        for(i=0; i<4; i++)
        {
          pRegion = currRegion + i;
          pRegion->regionMode = REGMODE_INTER_PRED_8x8;
          ii = 4*mbx + (i%2)*2 + BLOCK_SIZE; jj = 4*mby + (i/2)*2;
          pRegion->mv[0] = (img->dbMV[ii][jj][0] + img->dbMV[ii+1][jj][0] + img->dbMV[ii][jj+1][0] + img->dbMV[ii+1][jj+1][0] + 2)/4;
          pRegion->mv[1] = (img->dbMV[ii][jj][1] + img->dbMV[ii+1][jj][1] + img->dbMV[ii][jj+1][1] + img->dbMV[ii+1][jj+1][1] + 2)/4;
          erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
          pRegion->mv[2] = 0; //ref_frame_bw
        }
        break;
      default:
        snprintf(errortext, ET_SIZE, "B-frame img->imod %i is not supported\n", img->imod);
        error (errortext, 200);
      }
    }

  }
}
#endif

/*!
 ************************************************************************
 * \brief
 *    decodes one slice
 ************************************************************************
 */
void decode_one_slice(struct img_par *img,struct inp_par *inp)
{

  Boolean end_of_slice = FALSE;
  int read_flag;

  img->cod_counter=-1;

  reset_ec_flags();

  while (end_of_slice == FALSE) // loop over macroblocks
  {

#if TRACE
    fprintf(p_trace,"\n*********** Pic: %i (I/P) MB: %i Slice: %i Type %d **********\n", img->tr, img->current_mb_nr, img->mb_data[img->current_mb_nr].slice_nr, img->type);
#endif

    // Initializes the current macroblock
    start_macroblock(img,inp);

    // Get the syntax elements from the NAL
    read_flag = read_one_macroblock(img,inp);

    // decode one macroblock
    switch(read_flag)
    {
    case DECODE_MB:
      decode_one_macroblock(img,inp);
      break;
    case DECODE_COPY_MB:
      decode_one_CopyMB(img,inp);
      break;
    case DECODE_MB_BFRAME:
      decode_one_macroblock_Bframe(img);
      break;
    default:
        printf("need to trigger error concealment or something here\n ");
    }

#if _ERROR_CONCEALMENT_
    ercWriteMBMODEandMV(img,inp);
#endif

    DeblockMb( img ) ;
    end_of_slice=exit_macroblock(img,inp);
  }
  reset_ec_flags();
}

⌨️ 快捷键说明

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