lencod.c

来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 2,070 行 · 第 1/5 页

C
2,070
字号
    if (params->HierarchicalCoding)
      set_slice_type( img, gop_structure[gop_frame_num - 1].slice_type);
    else
      set_slice_type( img, ( params->PReplaceBSlice ) ? P_SLICE : B_SLICE);
  }
}

static void set_poc(ImageParameters *img, double frame_to_code)
{
  img->toppoc = (int) (img->frame_interval * frame_to_code);
  if (img->gop_number && (img->gop_number <= params->intra_delay))
  {
    if(params->idr_period && ((!params->adaptive_idr_period && ( img->frm_number - img->lastIDRnumber ) % params->idr_period == 0)
      || (params->adaptive_idr_period == 1 && ( img->frm_number - imax(img->lastIntraNumber, img->lastIDRnumber) ) % params->idr_period == 0)) )
      img->toppoc = img->toppoc;
    else
    {
      img->toppoc += (-img->frm_number + img->lastIDRnumber) * img->base_dist;
      img->toppoc *= 2;
    }
  }
  else
  {
    if(params->idr_period && !params->adaptive_idr_period)
      img->toppoc += ((( img->frm_number - img->lastIDRnumber - params->intra_delay) % params->idr_period ) - 1) * img->base_dist;
    else
      img->toppoc += (( img->frm_number - img->lastIDRnumber - params->intra_delay - 1 ) * img->base_dist);
    img->toppoc *= 2;
  }
}

/*!
************************************************************************
* \brief
*    Prepare first coding layer.
************************************************************************
*/
static void prepare_first_layer(ImageParameters *p_img, int curr_frame_to_code)
{
  p_img->number ++;
  p_img->gop_number = (p_img->number - p_img->start_frame_no);
  p_img->frm_number = p_img->number;

  p_img->frm_no_in_file = CalculateFrameNumber(p_img);

  if (params->last_frame != 0 && (params->last_frame == p_img->frm_no_in_file) && params->HierarchicalCoding)
  { 
    int numberBFrames = params->NumberBFrames;
    params->HierarchicalCoding = imin( 2, params->HierarchicalCoding);    
    params->NumberBFrames = params->no_frames - curr_frame_to_code - 1;    

    clear_gop_structure();
    init_gop_structure(params);
    create_hierarchy(params);

    params->NumberBFrames = numberBFrames;
  }
  SetImgType(p_img, 0);

  init_frame_params(p_img);

  //Rate control
  if (params->RCEnable && p_img->type == I_SLICE)
    rc_init_gop_params();

  // which layer does the image belong to?
  p_img->layer = (p_img->gop_number % (params->NumFramesInELSubSeq + 1)) ? 0 : 1;
}

/*!
************************************************************************
* \brief
*    Prepare second coding layer.
************************************************************************
*/
static void prepare_second_layer(ImageParameters *p_img, int enh_frame_to_code)
{
  p_img->layer = (params->NumFramesInELSubSeq == 0) ? 0 : 1;      
  SetImgType(p_img, enh_frame_to_code);

  if ((p_img->gop_number > 0) && (params->EnableIDRGOP == 0 || p_img->idr_gop_number)) // B-frame(s) to encode
  {
    if (params->HierarchicalCoding)
    {
      p_img->nal_reference_idc = gop_structure[enh_frame_to_code - 1].reference_idc;
      set_poc(p_img, (double)(1 + gop_structure[enh_frame_to_code - 1].display_no));

      if (p_img->gop_number && (p_img->gop_number <= params->intra_delay))
      {
        if (enh_frame_to_code == 1)
          p_img->delta_pic_order_cnt[0] = p_img->toppoc - 2*(p_img->start_tr_gop  + (params->intra_delay - p_img->gop_number)*(p_img->base_dist));
        else
          p_img->delta_pic_order_cnt[0] = p_img->toppoc - 2*(p_img->start_tr_gop  + (params->intra_delay - p_img->gop_number)*(p_img->base_dist) 
          + (int) (2.0 * p_img->frame_interval * (double) (1 + gop_structure[enh_frame_to_code - 2].display_no)));
      }
      else
      {
        if (enh_frame_to_code == 1)
          p_img->delta_pic_order_cnt[0] = p_img->toppoc - 2*(p_img->start_tr_gop  + (p_img->frm_number - p_img->lastIDRnumber)*(p_img->base_dist));
        else
          p_img->delta_pic_order_cnt[0] = p_img->toppoc - 2*(p_img->start_tr_gop  + (p_img->frm_number - p_img->lastIDRnumber - 1)*(p_img->base_dist) 
          + (int) (2.0 * p_img->frame_interval * (double) (1+ gop_structure[enh_frame_to_code - 2].display_no)));
        }
    }
    else
    {
      p_img->nal_reference_idc = (params->BRefPictures == 1 ) ? NALU_PRIORITY_LOW : NALU_PRIORITY_DISPOSABLE;
      set_poc(p_img, (double)enh_frame_to_code);

      //the following is sent in the slice header
      if (params->BRefPictures != 1)
      {
        p_img->delta_pic_order_cnt[0]= 2 * (enh_frame_to_code - 1);
      }
      else
      {
        p_img->delta_pic_order_cnt[0]= -2;
      }
    }

    p_img->delta_pic_order_cnt[1]= 0;

    if ((params->PicInterlace==FRAME_CODING)&&(params->MbInterlace==FRAME_CODING))
      p_img->bottompoc = p_img->toppoc;
    else
      p_img->bottompoc = p_img->toppoc + 1;

    p_img->framepoc = imin (p_img->toppoc, p_img->bottompoc);
    p_img->frm_no_in_file = CalculateFrameNumber(p_img);
  }
}

/*!
 ***********************************************************************
 * \brief
 *    Encode a sequence
 ***********************************************************************
 */
static void encode_sequence(ImageParameters *img)
{
  int HierarchicalCoding = params->HierarchicalCoding;
  int NumberBFrames = params->NumberBFrames;
  int jumpd = params->jumpd;
  int curr_frame_to_code = 0;
  int enh_frame_to_code = 0;

  for (curr_frame_to_code = 0; curr_frame_to_code < params->no_frames; curr_frame_to_code++)
  {     
    // Update frame_num counter
    if (img->last_ref_idc == 1)
    {
      img->frame_num++;
      img->frame_num %= max_frame_num;
    }
   
    // Read explicit sequence coding information
    if (params->ExplicitSeqCoding)
    {
      ExpFrameInfo *info = &expSeq->info[curr_frame_to_code % expSeq->no_frames];
      ReadExplicitSeqFile(expSeq, curr_frame_to_code);
      ExplicitUpdateImgParams(info, img);
      img->b_frame_to_code = 0;
    }
    else
    {
      enh_frame_to_code = determine_coding_level(img, params, curr_frame_to_code);
      img->b_frame_to_code = enh_frame_to_code;

      if (enh_frame_to_code == 0) 
        prepare_first_layer(img, curr_frame_to_code);
      else 
      {
        prepare_second_layer(img, enh_frame_to_code);
      }
    }

    // redundant frame initialization and allocation
    if (params->redundant_pic_flag)
    {
      Init_redundant_frame();
      Set_redundant_frame();
    }

    encode_one_frame(img); // encode one frame;

    img->last_ref_idc = img->nal_reference_idc ? 1 : 0;

    // if key frame is encoded, encode one redundant frame
    if (params->redundant_pic_flag && key_frame)
    {
      encode_one_redundant_frame();
    }

    if (img->type == I_SLICE && params->EnableOpenGOP)
      img->last_valid_reference = img->ThisPOC;

    if (img->currentPicture->idr_flag)
    {
      img->idr_gop_number = 0;
    }
    else
      img->idr_gop_number ++;

    if (params->ReportFrameStats)
      report_frame_statistic();
  }

  params->HierarchicalCoding = HierarchicalCoding;
  params->NumberBFrames      = NumberBFrames;
  params->jumpd = jumpd;
}


/*!
 ***********************************************************************
 * \brief
 *    Free memory allocated for the encoder
 ***********************************************************************
 */

void free_encoder_memory(ImageParameters *img)
{
  int nplane;
  terminate_sequence();

  flush_dpb();

  CloseFiles(&params->input_file1);

  if (-1 != p_dec)
    close(p_dec);
  if (p_trace)
    fclose(p_trace);

  Clear_Motion_Search_Module ();

  RandomIntraUninit();
  FmoUninit();

  if (params->HierarchicalCoding)
    clear_gop_structure ();

  // free structure for rd-opt. mode decision
  clear_rdopt (params);

#ifdef _LEAKYBUCKET_
  calc_buffer();
#endif

  // report everything
  report(img, params, stats);

#ifdef _LEAKYBUCKET_
  if (Bit_Buffer != NULL)
  {
    free(Bit_Buffer);
    Bit_Buffer = NULL;
  }
#endif

  free_dpb();

  if( IS_INDEPENDENT(params) )
  {
    for( nplane=0; nplane<MAX_PLANE; nplane++ )
    {
      free_colocated(Co_located_JV[nplane]);
    }
  }
  else
  {
    free_colocated(Co_located);
  }

  uninit_out_buffer();

  free_global_buffers();

  // free image mem
  free_img ();
  free_context_memory ();
  FreeParameterSets();
   if (params->ExplicitSeqCoding)
     CloseExplicitSeqFile();
}

/*!
 ***********************************************************************
 * \brief
 *    Initializes the POC structure with appropriate parameters.
 *
 ***********************************************************************
 */
void init_poc()
{
  //the following should probably go in sequence parameters
  // frame poc's increase by 2, field poc's by 1

  img->pic_order_cnt_type=params->pic_order_cnt_type;

  img->delta_pic_order_always_zero_flag = FALSE;
  img->num_ref_frames_in_pic_order_cnt_cycle= 1;

  if (params->BRefPictures == 1)
  {
    img->offset_for_non_ref_pic  =  0;
    img->offset_for_ref_frame[0] =  2;
  }
  else
  {
    img->offset_for_non_ref_pic  = -2*(params->NumberBFrames);
    img->offset_for_ref_frame[0] =  2*(params->NumberBFrames + 1);
  }

  if ((params->PicInterlace==FRAME_CODING) && (params->MbInterlace==FRAME_CODING))
  {
    img->offset_for_top_to_bottom_field = 0;
    img->pic_order_present_flag = FALSE;
    img->delta_pic_order_cnt_bottom = 0;
  }
  else
  {
    img->offset_for_top_to_bottom_field = 1;
    img->pic_order_present_flag = TRUE;
    img->delta_pic_order_cnt_bottom = 1;
  }
}


static inline int alloc_rddata(ImageParameters *img, RD_DATA *rd_data)
{
  int alloc_size = 0;

  alloc_size += get_mem2Dpel(&(rd_data->rec_mbY), MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  alloc_size += get_mem3Dpel(&(rd_data->rec_mb_cr), 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);

  alloc_size += get_mem_ACcoeff (&(rd_data->cofAC));
  alloc_size += get_mem_DCcoeff (&(rd_data->cofDC));  

  if (!params->IntraProfile)
  {          
    alloc_size += get_mem_mv (&(rd_data->all_mv));
  }
  
  alloc_size += get_mem2D((byte***)&(rd_data->ipredmode), img->height_blk, img->width_blk);
  alloc_size += get_mem3D((byte****)&(rd_data->refar), 2, 4, 4);

  return alloc_size;
}

static inline void free_rddata(RD_DATA *rd_data)
{
  free_mem3D((byte***) rd_data->refar);
  free_mem2D((byte**) rd_data->ipredmode);

  if (!params->IntraProfile)
  {          
    free_mem_mv (rd_data->all_mv);
  }
  free_mem_DCcoeff (rd_data->cofDC);
  free_mem_ACcoeff (rd_data->cofAC);  

  free_mem3Dpel(rd_data->rec_mb_cr);
  free_mem2Dpel(rd_data->rec_mbY);
}

/*!
 ***********************************************************************
 * \brief
 *    Initializes the img->nz_coeff
 * \par Input:
 *    none
 * \par  Output:
 *    none
 * \ side effects
 *    sets omg->nz_coef[][][][] to -1
 ***********************************************************************
 */
void CAVLC_init(void)
{
  memset(&img->nz_coeff[0][0][0], 0, img->PicSizeInMbs * 4 * (4 + img->num_blk8x8_uv)* sizeof(int));
}


/*!
 ***********************************************************************
 * \brief
 *    Initializes the Image structure with appropriate parameters.
 * \par Input:
 *    Input Parameters struct inp_par *inp
 * \par  Output:
 *    Image Parameters ImageParameters *img
 ***********************************************************************
 */
static void init_img( ImageParameters *img, InputParameters *params)
{
  int i, j;
  int byte_abs_range;

  static int mb_width_cr[4] = {0,8, 8,16};
  static int mb_height_cr[4]= {0,8,16,16};

  img->number         = -1;
  img->start_frame_no = 0;
  img->gop_number     = (img->number - img->start_frame_no);
  img->start_tr_gop   = 0;

  img->last_idr_number = 0;
  // Color format
  img->yuv_format  = params->output.yuv_format;
  img->P444_joined = (img->yuv_format == YUV444 && !IS_INDEPENDENT(params));  

  //pel bitdepth init
  img->bitdepth_luma            = params->output.bit_depth[0];

⌨️ 快捷键说明

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