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

📄 image.c

📁 the newest JM software by h.264 JVT official reference model.
💻 C
📖 第 1 页 / 共 5 页
字号:
    case SI_SLICE:
      ReportIntra(tmp_time,me_time);
      break;
    case B_SLICE:
      ReportB(tmp_time,me_time);
      break;
    default:      // P
      ReportP(tmp_time,me_time);
    }
  }

  if (params->Verbose == 0)
  {
    //for (i = 0; i <= (img->number & 0x0F); i++)
    //printf(".");
    //printf("                              \r");
    printf("Completed Encoding Frame %05d.\r", img->frame_no);
  }
  // Flush output statistics
  fflush(stdout);

  //Rate control
  if(params->RCEnable)
    rc_update_picture_ptr( bits );

  stats->bit_ctr_n = stats->bit_ctr;

  stats->bit_ctr_parametersets_n = 0;

  if ( img->type == I_SLICE && img->nal_reference_idc)
  {
    //img->lastINTRA = img->frame_no;
    // Lets also handle the possibility of backward GOPs and hierarchical structures 
    if ( !(img->b_frame_to_code) )
    {
      img->lastINTRA       = imax(img->lastINTRA, img->frame_no);
      img->lastIntraNumber = img->frm_number;
    }
    if ( img->currentPicture->idr_flag )
    {
      img->lastIDRnumber = img->frm_number;
    }
  }

  return ((img->gop_number == 0)? 0 : 1);
}


/*!
 ************************************************************************
 * \brief
 *    This function write out a picture
 * \return
 *    0 if OK,                                                         \n
 *    1 in case of error
 *
 ************************************************************************
 */
static void writeout_picture(Picture *pic)
{
  int partition, slice;
  Slice  *currSlice;

  img->currentPicture = pic;

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

    // loop over the partitions
    for (partition=0; partition < currSlice->max_part_nr; partition++)
    {
      // write only if the partition has content
      if (currSlice->partArr[partition].bitstream->write_flag )
      {
        stats->bit_ctr += WriteNALU (currSlice->partArr[partition].nal_unit);
      }
    }
  }
}


void copy_params(StorablePicture *enc_picture, seq_parameter_set_rbsp_t *active_sps)
{
  enc_picture->frame_mbs_only_flag = active_sps->frame_mbs_only_flag;
  enc_picture->frame_cropping_flag = active_sps->frame_cropping_flag;
  enc_picture->chroma_format_idc   = active_sps->chroma_format_idc;

  if (active_sps->frame_cropping_flag)
  {
    enc_picture->frame_cropping_rect_left_offset   = active_sps->frame_cropping_rect_left_offset;
    enc_picture->frame_cropping_rect_right_offset  = active_sps->frame_cropping_rect_right_offset;
    enc_picture->frame_cropping_rect_top_offset    = active_sps->frame_cropping_rect_top_offset;
    enc_picture->frame_cropping_rect_bottom_offset = active_sps->frame_cropping_rect_bottom_offset;
  }
  else
  {
    enc_picture->frame_cropping_rect_left_offset   = 0;
    enc_picture->frame_cropping_rect_right_offset  = 0;
    enc_picture->frame_cropping_rect_top_offset    = 0;
    enc_picture->frame_cropping_rect_bottom_offset = 0;
  }
}

/*!
 ************************************************************************
 * \brief
 *    Prepare and allocate an encoded frame picture structure
 ************************************************************************
 */
static void prepare_enc_frame_picture (StorablePicture **stored_pic)
{
  (*stored_pic)              = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr);
  
  img->ThisPOC               = img->framepoc;
  (*stored_pic)->poc         = img->framepoc;
  (*stored_pic)->top_poc     = img->toppoc;
  (*stored_pic)->bottom_poc  = img->bottompoc;
  (*stored_pic)->frame_poc   = img->framepoc;
  (*stored_pic)->pic_num     = img->frame_num;
  (*stored_pic)->frame_num   = img->frame_num;
  (*stored_pic)->coded_frame = 1;
  (*stored_pic)->MbaffFrameFlag = img->MbaffFrameFlag = (params->MbInterlace != FRAME_CODING);
  
  get_mb_block_pos           = img->MbaffFrameFlag ? get_mb_block_pos_mbaff : get_mb_block_pos_normal;
  getNeighbour               = img->MbaffFrameFlag ? getAffNeighbour : getNonAffNeighbour;
  enc_picture                = *stored_pic;

  copy_params(enc_picture, active_sps);
}

static void calc_picture_bits(Picture *frame)
{
  int i, j;
  Slice *thisSlice = NULL;

  frame->bits_per_picture = 0;

  for ( i = 0; i < frame->no_slices; i++ )
  {
    thisSlice = frame->slices[i];

    for ( j = 0; j < thisSlice->max_part_nr; j++ )
      frame->bits_per_picture += 8 * ((thisSlice->partArr[j]).bitstream)->byte_pos;
  }
}
/*!
 ************************************************************************
 * \brief
 *    Encodes a frame picture
 ************************************************************************
 */
void frame_picture (Picture *frame, ImageData *imgData, int rd_pass)
{
  int nplane;
  img->SumFrameQP = 0;
  img->structure = FRAME;
  img->PicSizeInMbs = img->FrameSizeInMbs;
  //set mv limits to frame type
  update_mv_limits(img, FALSE);


  if( IS_INDEPENDENT(params) )
  {
    for( nplane=0; nplane<MAX_PLANE; nplane++ )
    {
      prepare_enc_frame_picture( &enc_frame_picture_JV[nplane] );      
    }
  }
  else
  {
    prepare_enc_frame_picture( &enc_frame_picture[rd_pass] );
  }


  img->fld_flag = FALSE;
  code_a_picture(frame);

  if( IS_INDEPENDENT(params) )
  {
    make_frame_picture_JV();
  }

  calc_picture_bits(frame);

  if (img->structure==FRAME)
  {
    find_distortion (imgData);
    frame->distortion = dist->metric[SSE];
  }
}


/*!
 ************************************************************************
 * \brief
 *    Encodes a field picture, consisting of top and bottom field
 ************************************************************************
 */
static void field_picture (Picture *top, Picture *bottom)
{
  //Rate control
  int old_pic_type;              // picture type of top field used for rate control
  int TopFieldBits;
  img->SumFrameQP = 0;
  //set mv limits to field type
  update_mv_limits(img, TRUE);

  //Rate control
  old_pic_type = img->type;

  img->number *= 2;
  img->gop_number = (img->number - img->start_frame_no);
  img->buf_cycle *= 2;
  img->height    = (params->output.height + img->auto_crop_bottom) / 2;
  img->height_cr = img->height_cr_frame / 2;
  img->fld_flag  = TRUE;
  img->PicSizeInMbs = img->FrameSizeInMbs/2;
  // Top field

  enc_field_picture[0]              = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr);
  enc_field_picture[0]->poc         = img->toppoc;
  enc_field_picture[0]->frame_poc   = img->toppoc;
  enc_field_picture[0]->pic_num     = img->frame_num;
  enc_field_picture[0]->frame_num   = img->frame_num;
  enc_field_picture[0]->coded_frame = 0;
  enc_field_picture[0]->MbaffFrameFlag = img->MbaffFrameFlag = FALSE;
  get_mb_block_pos = get_mb_block_pos_normal;
  getNeighbour = getNonAffNeighbour;
  img->ThisPOC = img->toppoc;

  img->structure = TOP_FIELD;
  enc_picture = enc_field_picture[0];
  copy_params(enc_picture, active_sps);

  put_buffer_top (img);
  init_field (img);

  img->fld_flag = TRUE;

  //Rate control
  if(params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE)
    rc_init_top_field();

  code_a_picture(field_pic[0]);
  enc_picture->structure = TOP_FIELD;

  store_picture_in_dpb(enc_field_picture[0]);

  calc_picture_bits(top);

  //Rate control
  TopFieldBits=top->bits_per_picture;

  //  Bottom field
  enc_field_picture[1]  = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr);
  enc_field_picture[1]->poc=img->bottompoc;
  enc_field_picture[1]->frame_poc = img->bottompoc;
  enc_field_picture[1]->pic_num = img->frame_num;
  enc_field_picture[1]->frame_num = img->frame_num;
  enc_field_picture[1]->coded_frame = 0;
  enc_field_picture[1]->MbaffFrameFlag = img->MbaffFrameFlag = FALSE;
  get_mb_block_pos = get_mb_block_pos_normal;
  getNeighbour = getNonAffNeighbour;

  img->ThisPOC = img->bottompoc;
  img->structure = BOTTOM_FIELD;
  enc_picture = enc_field_picture[1];
  copy_params(enc_picture, active_sps);
  put_buffer_bot (img);
  img->number++;
  img->gop_number = (img->number - img->start_frame_no);

  init_field (img);

 if (img->type == I_SLICE && params->IntraBottom!=1)
   set_slice_type(img, (params->BRefPictures == 2) ? B_SLICE : P_SLICE);

  img->fld_flag = TRUE;

  //Rate control
  if(params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE)
    rc_init_bottom_field( TopFieldBits );

  enc_picture->structure = BOTTOM_FIELD;
  code_a_picture(field_pic[1]);

  calc_picture_bits(bottom);

  // the distortion for a field coded frame (consisting of top and bottom field)
  // lives in the top->distortion variables, the bottom-> are dummies
  distortion_fld (top, &imgData);
}

/*!
 ************************************************************************
 * \brief
 *    form frame picture from two field pictures
 ************************************************************************
 */
static void combine_field(void)
{
  int i, k;

  for (i = 0; i < (img->height >> 1); i++)
  {
    memcpy(imgY_com[i*2],     enc_field_picture[0]->imgY[i], img->width*sizeof(imgpel));     // top field
    memcpy(imgY_com[i*2 + 1], enc_field_picture[1]->imgY[i], img->width*sizeof(imgpel)); // bottom field
  }

  if (img->yuv_format != YUV400)
  {
    for (k = 0; k < 2; k++)
    {
      for (i = 0; i < (img->height_cr >> 1); i++)
      {
        memcpy(imgUV_com[k][i*2],     enc_field_picture[0]->imgUV[k][i], img->width_cr*sizeof(imgpel));
        memcpy(imgUV_com[k][i*2 + 1], enc_field_picture[1]->imgUV[k][i], img->width_cr*sizeof(imgpel));
      }
    }
  }
}

/*!
 ************************************************************************
 * \brief
 *    Distortion Field
 ************************************************************************
 */
static void distortion_fld (Picture *field_pic, ImageData *imgData)
{

  img->number /= 2;
  img->gop_number = (img->number - img->start_frame_no);
  img->buf_cycle /= 2;
  img->height    = (params->output.height + img->auto_crop_bottom);
  img->height_cr = img->height_cr_frame;

  combine_field ();

  pCurImg   = imgData->frm_data[0];
  pImgOrg[0] = imgData->frm_data[0];

  if (params->output.yuv_format != YUV400)
  {
    pImgOrg[1] = imgData->frm_data[1];
    pImgOrg[2] = imgData->frm_data[2];
  }

  find_distortion (imgData);   // find snr from original frame picture
  field_pic->distortion = dist->metric[SSE];
}


/*!
 ************************************************************************
 * \brief
 *    RD decision of frame and field coding
 ************************************************************************
 */
static byte decide_fld_frame(float snr_frame_Y, float snr_field_Y, int bit_field, int bit_frame, double lambda_picture)
{
  double cost_frame, cost_field;

  cost_frame = bit_frame * lambda_picture + snr_frame_Y;
  cost_field = bit_field * lambda_picture + snr_field_Y;

  if (cost_field > cost_frame)
    return FALSE;
  else
    return TRUE;
}

/*!
 ************************************************************************
 * \brief
 *    Picture Structure Decision
 ************************************************************************
 */
static byte picture_structure_decision (Picture *frame, Picture *top, Picture *bot)
{
  double lambda_picture;
  int bframe = (img->type == B_SLICE);
  float sse_frame, sse_field;
  int bit_frame, bit_field;

  lambda_picture = 0.68 * pow (2, img->bitdepth_lambda_scale + ((img->qp - SHIFT_QP) / 3.0)) * (bframe ? 1 : 1);

⌨️ 快捷键说明

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