📄 image.c
字号:
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(FrameNumberInFile);
if (params->GenerateMultiplePPS)
active_pps = PicParSet[0];
frame_picture (frame_pic[0], 0);
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, 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);
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)
{
writeout_picture (frame_pic_si);
si_frame_indicator=0;
}
else
{
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();
// 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)
{
// 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]);
update_global_stats(&enc_field_picture[0]->stats);
update_global_stats(&enc_field_picture[1]->stats);
}
else
{
// 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]);
update_global_stats(&enc_frame_picture[img->rd_pass]->stats);
}
}
else
{
if (img->fld_flag)
{
store_picture_in_dpb(enc_field_picture[1]);
update_global_stats(&enc_field_picture[0]->stats);
update_global_stats(&enc_field_picture[1]->stats);
}
else
{
if ((params->redundant_pic_flag != 1) || (key_frame == 0))
{
store_picture_in_dpb (enc_frame_picture[img->rd_pass]);
update_global_stats(&enc_frame_picture[img->rd_pass]->stats);
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
Bit_Buffer[total_frame_buffer] = (int) (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 (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 = frame_no;
}
gettime(&end_time); // end time in ms
tmp_time = timediff(&start_time, &end_time);
tot_time += tmp_time;
if (stats->bit_ctr_parametersets_n!=0)
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:
case SI_SLICE:
ReportIntra(tmp_time,me_time);
break;
case SP_SLICE:
ReportSP(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",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 = frame_no;
// Lets also handle the possibility of backward GOPs and hierarchical structures
if ( !(img->b_frame_to_code) )
{
img->lastINTRA = imax(img->lastINTRA, frame_no);
img->lastIntraNumber = img->frm_number;
}
if ( img->currentPicture->idr_flag )
{
img->lastIDRnumber = img->frm_number;
}
}
return ((IMG_NUMBER == 0)? 0 : 1);
}
/*!
************************************************************************
* \brief
* This function write out a picture
* \return
* 0 if OK, \n
* 1 in case of error
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -