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

📄 slice.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 4 页
字号:
    EPZSSliceInit(params, img, EPZSCo_located, listX);

  if ((*currSlice)->symbol_mode == CAVLC)
  {
    writeMB_typeInfo       = writeSE_UVLC;
    writeIntraPredMode     = writeIntraPredMode_CAVLC;
    writeB8_typeInfo       = writeSE_UVLC;
    for (i=0; i<6; i++)
    {
      switch (listXsize[i])
      {
      case 0:
        writeRefFrame[i]   = NULL;
        break;
      case 1:
        writeRefFrame[i]   = writeSE_Dummy;
        break;
      case 2:
        writeRefFrame[i]   = writeSE_invFlag;
        break;
      default:
        writeRefFrame[i]   = writeSE_UVLC;
        break;
      }
    }

    writeMVD               = writeSE_SVLC;
    writeCBP               = writeCBP_VLC;
    writeDquant            = writeSE_SVLC;
    writeCIPredMode        = writeSE_UVLC;
    writeFieldModeInfo     = writeSE_Flag;
    writeMB_transform_size = writeSE_Flag;
  }
  else
  {
    writeMB_typeInfo       = writeMB_typeInfo_CABAC;
    writeIntraPredMode     = writeIntraPredMode_CABAC;
    writeB8_typeInfo       = writeB8_typeInfo_CABAC;
    for (i=0; i<6; i++)
    {
      switch (listXsize[i])
      {
      case 0:
        writeRefFrame[i]   = NULL;
      case 1:
        writeRefFrame[i]   = writeSE_Dummy;
        break;
      default:
        writeRefFrame[i]   = writeRefFrame_CABAC;
      }
    }
    writeMVD               = writeMVD_CABAC;
    writeCBP               = writeCBP_CABAC;
    writeDquant            = writeDquant_CABAC;
    writeCIPredMode        = writeCIPredMode_CABAC;
    writeFieldModeInfo     = writeFieldModeInfo_CABAC;
    writeMB_transform_size = writeMB_transform_size_CABAC;
  }

  // assign luma common reference picture pointers to be used for ME/sub-pel interpolation

  for(i = 0; i < active_ref_lists; i++)
  {
    for(j = 0; j < listXsize[i]; j++)
    {
      if( listX[i][j] )
      {
        listX[i][j]->p_curr_img     = listX[i][j]->p_img    [img->colour_plane_id];
        listX[i][j]->p_curr_img_sub = listX[i][j]->p_img_sub[img->colour_plane_id];
      }
    }
  }
  if (params->UseRDOQuant)
    init_rdoq_slice(img->type, (*currSlice)->symbol_mode);
}


/*!
 ************************************************************************
 * \brief
 *    Allocates a slice structure along with its dependent data structures
 * \return
 *    Pointer to a Slice
 ************************************************************************
 */
static Slice *malloc_slice()
{
  int i;
  DataPartition *dataPart;
  Slice *slice;
  int cr_size = IS_INDEPENDENT( params ) ? 0 : 512;

//  const int buffer_size = (img->size * 4); // AH 190202: There can be data expansion with
                                                          // low QP values. So, we make sure that buffer
                                                          // does not overflow. 4 is probably safe multiplier.
  int buffer_size;
  switch (params->slice_mode)
  {
  case 2:
    //buffer_size = imax(2 * params->slice_argument, 500 + (128 + 256 * img->bitdepth_luma + 512 * img->bitdepth_chroma));
    buffer_size = imax(2 * params->slice_argument, 764);
    break;
  case 1:
    buffer_size = 500 + params->slice_argument * (128 + 256 * img->bitdepth_luma + cr_size * img->bitdepth_chroma);
    break;
  default:
    buffer_size = 500 + img->FrameSizeInMbs * (128 + 256 * img->bitdepth_luma + cr_size * img->bitdepth_chroma);
    break;
  }

  // KS: this is approx. max. allowed code picture size
  if ((slice = (Slice *) calloc(1, sizeof(Slice))) == NULL) no_mem_exit ("malloc_slice: slice structure");

  slice->symbol_mode  = params->symbol_mode;
  cs_mb->symbol_mode  = params->symbol_mode;
  cs_b8->symbol_mode  = params->symbol_mode;
  cs_cm->symbol_mode  = params->symbol_mode;
  cs_ib8->symbol_mode = params->symbol_mode;
  cs_ib4->symbol_mode = params->symbol_mode;

  if (slice->symbol_mode == CABAC)
  {
    // create all context models
    slice->mot_ctx = create_contexts_MotionInfo();
    slice->tex_ctx = create_contexts_TextureInfo();
  }

  slice->max_part_nr = params->partition_mode==0?1:3;

  //for IDR img there should be only one partition
  if(img->currentPicture->idr_flag)
    slice->max_part_nr = 1;

  assignSE2partition[0] = assignSE2partition_NoDP;
  //ZL
  //for IDR img all the syntax element should be mapped to one partition
  if(!img->currentPicture->idr_flag && params->partition_mode == 1)
    assignSE2partition[1] =  assignSE2partition_DP;
  else
    assignSE2partition[1] =  assignSE2partition_NoDP;

  slice->num_mb = 0;          // no coded MBs so far

  if ((slice->partArr = (DataPartition *) calloc(slice->max_part_nr, sizeof(DataPartition))) == NULL) 
    no_mem_exit ("malloc_slice: partArr");
  for (i=0; i<slice->max_part_nr; i++) // loop over all data partitions
  {
    dataPart = &(slice->partArr[i]);
    if ((dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream))) == NULL) 
      no_mem_exit ("malloc_slice: Bitstream");
    if ((dataPart->bitstream->streamBuffer = (byte *) calloc(buffer_size, sizeof(byte))) == NULL) 
      no_mem_exit ("malloc_slice: StreamBuffer");
    // Initialize storage of bitstream parameters
  }

  return slice;
}


/*!
 ************************************************************************
 * \brief
 *    This function frees nal units
 *
 ************************************************************************
 */
static void free_nal_unit(Picture *pic)
{
  int partition, slice;
  Slice  *currSlice;

  // loop over all slices of the picture
  for (slice=0; slice < pic->no_slices; slice++)
  {
    currSlice = pic->slices[slice];

    // loop over the partitions
    if (currSlice != NULL)
    {
      for (partition=0; partition < currSlice->max_part_nr; partition++)
      {
        // free only if the partition has content
        if (currSlice->partArr[partition].bitstream->write_flag )
        {
          if (currSlice->partArr[partition].nal_unit != NULL)
          {
            FreeNALU(currSlice->partArr[partition].nal_unit);
            currSlice->partArr[partition].nal_unit = NULL;
          }
        }
      }
    }
  }
}

/*!
 ************************************************************************
 * \brief
 *    Memory frees of all Slice structures and of its dependent
 *    data structures
 * \par Input:
 *    Image Parameters struct struct img_par *img
 ************************************************************************
 */
void free_slice_list(Picture *currPic)
{
  int i;

  free_nal_unit(currPic);

  for (i = 0; i < currPic->no_slices; i++)
  {
    free_slice (currPic->slices[i]);
    currPic->slices[i]=NULL;
  }
}


/*!
 ************************************************************************
 * \brief
 *    Memory frees of the Slice structure and of its dependent
 *    data structures
 * \param slice:
 *    Slice to be freed
 ************************************************************************
 */
static void free_slice(Slice *slice)
{
  int i;
  DataPartition *dataPart;

  if (slice != NULL)
  {
    for (i=0; i<slice->max_part_nr; i++) // loop over all data partitions
    {
      dataPart = &(slice->partArr[i]);
      if (dataPart != NULL)
      {
         if (dataPart->bitstream != NULL)
         {
           if (dataPart->bitstream->streamBuffer != NULL)
             free(dataPart->bitstream->streamBuffer);       
           free(dataPart->bitstream);
         }
      }
    }
    if (slice->partArr != NULL)
      free(slice->partArr);
    
    if (slice->symbol_mode == CABAC)
    {
      delete_contexts_MotionInfo(slice->mot_ctx);
      delete_contexts_TextureInfo(slice->tex_ctx);
    }

    free(slice);
  }
}

static void set_ref_pic_num()
{
  int i,j;
  StorablePicture *this_ref;

  //! need to add field ref_pic_num that handles field pair.

  for (i=0;i<listXsize[LIST_0];i++)
  {
    this_ref = listX[LIST_0][i];
    enc_picture->ref_pic_num        [LIST_0][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0) ;
    enc_picture->frm_ref_pic_num    [LIST_0][i] = this_ref->frame_poc * 2;
    enc_picture->top_ref_pic_num    [LIST_0][i] = this_ref->top_poc * 2;
    enc_picture->bottom_ref_pic_num [LIST_0][i] = this_ref->bottom_poc * 2 + 1;
  }

  for (i=0;i<listXsize[LIST_1];i++)
  {
    this_ref = listX[LIST_1][i];
    enc_picture->ref_pic_num        [LIST_1][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0);
    enc_picture->frm_ref_pic_num    [LIST_1][i] = this_ref->frame_poc * 2;
    enc_picture->top_ref_pic_num    [LIST_1][i] = this_ref->top_poc * 2;
    enc_picture->bottom_ref_pic_num [LIST_1][i] = this_ref->bottom_poc * 2 + 1;
  }

  if (!active_sps->frame_mbs_only_flag && img->structure==FRAME)
  {
    for (j=2;j<6;j++)
      for (i=0;i<listXsize[j];i++)
      {
        this_ref = listX[j][i];
        enc_picture->ref_pic_num[j][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0);
        enc_picture->frm_ref_pic_num[j][i] = this_ref->frame_poc * 2 ;
        enc_picture->top_ref_pic_num[j][i] = this_ref->top_poc * 2 ;
        enc_picture->bottom_ref_pic_num[j][i] = this_ref->bottom_poc * 2 + 1;
      }
  }
}

/*!
************************************************************************
* \brief
*    decide reference picture reordering, Frame only
************************************************************************
*/
void poc_ref_pic_reorder_frame(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
{
  unsigned int i,j,k;

  int currPicNum, picNumLXPred;

  int default_order[32];
  int re_order[32];
  int tmp_reorder[32];
  int list_sign[32];
  int reorder_stop, no_reorder;
  int poc_diff[32];
  int tmp_value, diff;

  int abs_poc_dist;
  int maxPicNum;
  unsigned int numRefs;

  maxPicNum  = max_frame_num;
  currPicNum = img->frame_num;

  picNumLXPred = currPicNum;

  // First assign default list order.
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    default_order[i] = list[i]->pic_num;
  }

  // Now access all references in buffer and assign them
  // to a potential reordering list. For each one of these
  // references compute the poc distance compared to current
  // frame.
  numRefs = dpb.ref_frames_in_buffer;
  for (i=0; i<dpb.ref_frames_in_buffer; i++)
  {
    poc_diff[i] = 0xFFFF;
    re_order[i] = dpb.fs_ref[i]->frame->pic_num;

    if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
    {
      abs_poc_dist = iabs(dpb.fs_ref[i]->frame->poc - enc_picture->poc) ;
      poc_diff[i] = abs_poc_dist;
      if (list_no == LIST_0)
      {
        list_sign[i] = (enc_picture->poc < dpb.fs_ref[i]->frame->poc) ? +1 : -1;
      }
      else
      {
        list_sign[i] = (enc_picture->poc > dpb.fs_ref[i]->frame->poc) ? +1 : -1;
      }
    }
  }

  // now sort these references based on poc (temporal) distance
  for (i = 0; i< numRefs - 1; i++)
  {
    for (j = i + 1; j < numRefs; j++)
    {
      if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
      {

        tmp_value = poc_diff[i];
        poc_diff[i] = poc_diff[j];
        poc_diff[j] = tmp_value;
        tmp_value  = re_order[i];
        re_order[i] = re_order[j];
        re_order[j] = tmp_value ;
        tmp_value  = list_sign[i];
        list_sign[i] = list_sign[j];
        list_sign[j] = tmp_value ;
      }
    }
  }
  // populate list with selections from the pre-analysis stage
  if ( params->WPMCPrecision 
    && pWPX->curr_wp_rd_pass->algorithm != WP_REGULAR
    && pWPX->num_wp_ref_list[list_no] )
  {
    for (i=0; i<num_ref_idx_lX_active; i++)
    {
      re_order[i] = pWPX->wp_ref_list[list_no][i].PicNum;
    }
  }

  // Check versus default list to see if any
  // change has happened
  no_reorder = 1;
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    if (default_order[i] != re_order[i])
    {
      no_reorder = 0;
    }
  }

  // If different, then signal reordering
  if (no_reorder==0)
  {
    for (i=0; i<num_ref_idx_lX_active; i++)
    {
      diff = re_order[i]-picNumLXPred;
      if (diff <= 0)
      {
        reordering_of_pic_nums_idc[i] = 0;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
        if (abs_diff_pic_num_minus1[i] < 0)
          abs_diff_pic_num_minus1[i] = maxPicNum -1;
      }
      else
      {
        reordering_of_pic_nums_idc[i] = 1;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
      }
      picNumLXPred = re_order[i];

      tmp_reorder[i] = re_order[i];

      k = i;
      for (j=i; j<num_ref_idx_lX_active; j++)
      {
        if (default_order[j] != re_order[i])
        {
          ++k;
          tmp_reorder[k] = default_order[j];
        }
      }
      reorder_stop = 1;
      for(j=i+1; j<num_ref_idx_lX_active; j++)
      {
        if (tmp_reorder[j] != re_order[j])
        {
          reorder_stop = 0;
          break;
        }
      }

      if (reorder_stop==1)
      {

⌨️ 快捷键说明

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