📄 image.c
字号:
for (i = 0; i < 6; i++)
enc_frame_picture[i] = NULL;
gettime(&start_time); // start time in ms
//Rate control
img->write_macroblock = FALSE;
/*
//Shankar Regunathan (Oct 2002)
//Prepare Panscanrect SEI payload
UpdatePanScanRectInfo ();
//Prepare Arbitrarydata SEI Payload
UpdateUser_data_unregistered ();
//Prepare Registered data SEI Payload
UpdateUser_data_registered_itu_t_t35 ();
//Prepare RandomAccess SEI Payload
UpdateRandomAccess ();
*/
put_buffer_frame (img); // sets the pointers to the frame structures
// (and not to one of the field structures)
init_frame (img);
if(params->WPIterMC)
img->frameOffsetAvail = 0;
ReadOneFrame (¶ms->input_file1, img->frm_no_in_file, params->infile_header, ¶ms->source, ¶ms->output, imgData1.frm_data);
PaddAutoCropBorders (params->output, img->width, img->height, img->width_cr, img->height_cr, imgData1.frm_data);
ProcessImage( params );
// set parameters for direct mode and deblocking filter
img->direct_spatial_mv_pred_flag = params->direct_spatial_mv_pred_flag;
img->DFDisableIdc = params->DFDisableIdc[img->nal_reference_idc > 0][img->type];
img->DFAlphaC0Offset = params->DFAlpha [img->nal_reference_idc > 0][img->type];
img->DFBetaOffset = params->DFBeta [img->nal_reference_idc > 0][img->type];
img->AdaptiveRounding = params->AdaptiveRounding;
// Following code should consider optimal coding mode. Currently also does not support
// multiple slices per frame.
dist->frame_ctr++;
if(img->type == SP_SLICE)
{
if(params->sp2_frame_indicator)
{ // switching SP frame encoding
sp2_frame_indicator=1;
read_SP_coefficients();
}
}
else
{
sp2_frame_indicator=0;
}
if ( params->WPMCPrecision )
{
wpxInitWPXPasses(params);
pWPX->curr_wp_rd_pass = pWPX->wp_rd_passes;
pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
}
if (params->PicInterlace == FIELD_CODING)
{
//Rate control
if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE )
generic_RC->FieldControl = 1;
img->field_picture = 1; // we encode fields
field_picture (field_pic[0], field_pic[1]);
img->fld_flag = TRUE;
}
else
{
int tmpFrameQP;
//Rate control
if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE )
generic_RC->FieldControl = 0;
img->field_picture = 0; // we encode a frame
//Rate control
if(params->RCEnable)
rc_init_frame(img->frm_no_in_file);
if (params->GenerateMultiplePPS)
active_pps = PicParSet[0];
frame_picture (frame_pic[0], &imgData, 0);
if(params->WPIterMC)
img->frameOffsetAvail = 1;
if ((params->RDPictureIntra || img->type!=I_SLICE) && params->RDPictureDecision)
{
rdPictureCoding();
}
tmpFrameQP = img->SumFrameQP; // call it here since rdPictureCoding buffers it and may modify it
if ((img->type==SP_SLICE) && (si_frame_indicator==0) && (params->si_frame_indicator))
{
// once the picture has been encoded as a primary SP frame encode as an SI frame
si_frame_indicator=1;
frame_picture (frame_pic_si, &imgData, 0);
}
if ((img->type == SP_SLICE) && (params->sp_output_indicator))
{
// output the transformed and quantized coefficients (useful for switching SP frames)
output_SP_coefficients();
}
if (params->PicInterlace == ADAPTIVE_CODING)
{
//Rate control
if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE )
generic_RC->FieldControl=1;
img->write_macroblock = FALSE;
img->bot_MB = FALSE;
img->field_picture = 1; // we encode fields
field_picture (field_pic[0], field_pic[1]);
if(img->rd_pass == 0)
img->fld_flag = picture_structure_decision (frame_pic[0], field_pic[0], field_pic[1]);
else if(img->rd_pass == 1)
img->fld_flag = picture_structure_decision (frame_pic[1], field_pic[0], field_pic[1]);
else
img->fld_flag = picture_structure_decision (frame_pic[2], field_pic[0], field_pic[1]);
if ( img->fld_flag )
tmpFrameQP = img->SumFrameQP;
update_field_frame_contexts (img->fld_flag);
//Rate control
if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE )
generic_RC->FieldFrame = !(img->fld_flag) ? 1 : 0;
}
else
img->fld_flag = FALSE;
img->SumFrameQP = tmpFrameQP;
}
stats->frame_counter++;
stats->frame_ctr[img->type]++;
// Here, img->structure may be either FRAME or BOTTOM FIELD depending on whether AFF coding is used
// The picture structure decision changes really only the fld_flag
if (img->fld_flag) // field mode (use field when fld_flag=1 only)
{
field_mode_buffer (img, params);
write_non_vcl_nalu();
writeout_picture (field_pic[0]);
writeout_picture (field_pic[1]);
}
else //frame mode
{
frame_mode_buffer (img, params);
if (img->type==SP_SLICE && si_frame_indicator == 1)
{
write_non_vcl_nalu();
writeout_picture (frame_pic_si);
si_frame_indicator=0;
}
else
{
write_non_vcl_nalu();
writeout_picture (frame_pic[img->rd_pass]);
}
}
if (frame_pic_si)
{
free_slice_list(frame_pic_si);
}
for (i = 0; i < img->frm_iter; i++)
{
if (frame_pic[i])
{
free_slice_list(frame_pic[i]);
}
}
if (field_pic)
{
for (i = 0; i < 2; i++)
{
if (field_pic[i])
free_slice_list(field_pic[i]);
}
}
/*
// Tian Dong (Sept 2002)
// in frame mode, the newly reconstructed frame has been inserted to the mem buffer
// and it is time to prepare the spare picture SEI payload.
if (params->InterlaceCodingOption == FRAME_CODING
&& params->SparePictureOption && img->type != B_SLICE)
CalculateSparePicture ();
*/
//Rate control
if(params->RCEnable)
{
// we could add here a function pointer!
bits = (int) (stats->bit_ctr - stats->bit_ctr_n);
if ( params->RCUpdateMode <= MAX_RC_MODE )
rc_update_pict_frame_ptr(quadratic_RC, bits);
}
if (params->PicInterlace == FRAME_CODING)
{
if ((params->rdopt == 3) && (img->nal_reference_idc != 0))
{
UpdateDecoders (params, img, enc_picture); // simulate packet losses and move decoded image to reference buffers
}
if (params->RestrictRef)
UpdatePixelMap ();
}
compute_distortion(&imgData);
// redundant pictures: save reconstruction to calculate SNR and replace reference picture
if(params->redundant_pic_flag)
{
int k;
if(key_frame)
{
for(j=0; j<img->height; j++)
{
memcpy(imgY_tmp[j], enc_frame_picture[0]->imgY[j], img->width * sizeof(imgpel));
}
for (k = 0; k < 2; k++)
{
for(j=0; j<img->height_cr; j++)
{
memcpy(imgUV_tmp[k][j], enc_frame_picture[0]->imgUV[k][j], img->width_cr * sizeof(imgpel));
}
}
}
if(redundant_coding)
{
for(j=0; j<img->height; j++)
{
memcpy(enc_frame_picture[0]->imgY[j], imgY_tmp[j], img->width * sizeof(imgpel));
}
for (k = 0; k < 2; k++)
{
for(j=0; j<img->height_cr; j++)
{
memcpy(enc_frame_picture[0]->imgUV[k][j], imgUV_tmp[k][j], img->width_cr * sizeof(imgpel));
}
}
}
}
if (params->PicInterlace == ADAPTIVE_CODING)
{
if (img->fld_flag)
{
update_global_stats(&statistics, &enc_field_picture[0]->stats);
update_global_stats(&statistics, &enc_field_picture[1]->stats);
// store bottom field
store_picture_in_dpb(enc_field_picture[1]);
free_storable_picture(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[1]);
free_storable_picture(enc_frame_picture[2]);
}
else
{
update_global_stats(&statistics, &enc_frame_picture[img->rd_pass]->stats);
// replace top with frame
if (img->rd_pass==2)
{
replace_top_pic_with_frame(enc_frame_picture[2]);
free_storable_picture(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[1]);
}
else if (img->rd_pass==1)
{
replace_top_pic_with_frame(enc_frame_picture[1]);
free_storable_picture(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[2]);
}
else
{
if(params->redundant_pic_flag==0 || (key_frame==0))
{
replace_top_pic_with_frame(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[1]);
free_storable_picture(enc_frame_picture[2]);
}
}
free_storable_picture(enc_field_picture[1]);
}
}
else
{
if (img->fld_flag)
{
update_global_stats(&statistics, &enc_field_picture[0]->stats);
update_global_stats(&statistics, &enc_field_picture[1]->stats);
store_picture_in_dpb(enc_field_picture[1]);
}
else
{
if ((params->redundant_pic_flag != 1) || (key_frame == 0))
{
update_global_stats(&statistics, &enc_frame_picture[img->rd_pass]->stats);
store_picture_in_dpb (enc_frame_picture[img->rd_pass]);
free_pictures(img->rd_pass);
}
}
}
img->AverageFrameQP = isign(img->SumFrameQP) * ((iabs(img->SumFrameQP) + (int) (img->FrameSizeInMbs >> 1))/ (int) img->FrameSizeInMbs);
if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE && img->type != B_SLICE && params->basicunit < img->FrameSizeInMbs )
quadratic_RC->CurrLastQP = img->AverageFrameQP;
#ifdef _LEAKYBUCKET_
// Store bits used for this frame and increment counter of no. of coded frames
if (!redundant_coding)
{
Bit_Buffer[total_frame_buffer] = (long) (stats->bit_ctr - stats->bit_ctr_n);
total_frame_buffer++;
}
#endif
// POC200301: Verify that POC coding type 2 is not used if more than one consecutive
// non-reference frame is requested or if decoding order is different from output order
if (img->pic_order_cnt_type == 2)
{
if (!img->nal_reference_idc) consecutive_non_reference_pictures++;
else consecutive_non_reference_pictures = 0;
if (img->frame_no < prev_frame_no || consecutive_non_reference_pictures>1)
error("POC type 2 cannot be applied for the coding pattern where the encoding /decoding order of pictures are different from the output order.\n", -1);
prev_frame_no = img->frame_no;
}
gettime(&end_time); // end time in ms
tmp_time = timediff(&start_time, &end_time);
tot_time += tmp_time;
tmp_time = timenorm(tmp_time);
me_time = timenorm(me_time);
if (stats->bit_ctr_parametersets_n!=0 && params->Verbose != 3)
ReportNALNonVLCBits(tmp_time, me_time);
if (img->frm_number == 0)
ReportFirstframe(tmp_time,me_time);
else
{
//Rate control
if(params->RCEnable)
{
if ((!params->PicInterlace) && (!params->MbInterlace))
bits = (int) (stats->bit_ctr - stats->bit_ctr_n);
else if ( params->RCUpdateMode <= MAX_RC_MODE )
{
bits = (int)(stats->bit_ctr - (quadratic_RC->Pprev_bits)); // used for rate control update
quadratic_RC->Pprev_bits = stats->bit_ctr;
}
}
stats->bit_counter[img->type] += stats->bit_ctr - stats->bit_ctr_n;
switch (img->type)
{
case I_SLICE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -