📄 image.c
字号:
// Following code should consider optimal coding mode. Currently also does not support
// multiple slices per frame.
frame_ctr[img->type]++;
snr->frame_ctr++;
if(img->type == SP_SLICE)
{
if(input->sp2_frame_indicator)
{ // switching SP frame encoding
sp2_frame_indicator=1;
read_SP_coefficients();
}
}
else
{
sp2_frame_indicator=0;
}
if (input->PicInterlace == FIELD_CODING)
{
//Rate control
if ( input->RCEnable )
generic_RC->FieldControl=1;
img->field_picture = 1; // we encode fields
field_picture (field_pic[0], field_pic[1]);
img->fld_flag = 1;
}
else
{
int tmpFrameQP;
//Rate control
if ( input->RCEnable )
generic_RC->FieldControl=0;
// For frame coding, turn MB level field/frame coding flag on
if (input->MbInterlace)
mb_adaptive = 1;
img->field_picture = 0; // we encode a frame
//Rate control
if(input->RCEnable)
init_frame_rc(FrameNumberInFile);
if (input->GenerateMultiplePPS)
active_pps = PicParSet[0];
frame_picture (frame_pic[0], 0);
if ((input->RDPictureIntra || img->type!=I_SLICE) && input->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 && input->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 && input->sp_output_indicator)
{
// output the transformed and quantized coefficients (useful for switching SP frames)
output_SP_coefficients();
}
// For field coding, turn MB level field/frame coding flag off
if (input->MbInterlace)
mb_adaptive = 0;
if (input->PicInterlace == ADAPTIVE_CODING)
{
//Rate control
if ( input->RCEnable )
generic_RC->FieldControl=1;
img->write_macroblock = 0;
img->bot_MB = 0;
img->field_picture = 1; // we encode fields
field_picture (field_pic[0], field_pic[1]);
//! Note: the distortion for a field coded picture is stored in the top field
//! the distortion values in the bottom field are dummies
dis_fld = field_pic[0]->distortion_y + field_pic[0]->distortion_u + field_pic[0]->distortion_v;
dis_frm = frame_pic[0]->distortion_y + frame_pic[0]->distortion_u + frame_pic[0]->distortion_v;
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 ( input->RCEnable )
{
generic_RC->FieldFrame = !(img->fld_flag) ? 1 : 0;
}
}
else
img->fld_flag = 0;
img->SumFrameQP = tmpFrameQP;
}
if (img->fld_flag)
stats->bit_ctr_emulationprevention += stats->em_prev_bits_fld;
else
stats->bit_ctr_emulationprevention += stats->em_prev_bits_frm;
if (img->type != B_SLICE)
{
img->pstruct_next_P = img->fld_flag;
}
// 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 (bits_fld, dis_fld_y, dis_fld_u, dis_fld_v);
writeout_picture (field_pic[0]);
writeout_picture (field_pic[1]);
}
else //frame mode
{
frame_mode_buffer (bits_frm, dis_frm_y, dis_frm_u, dis_frm_v);
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 (input->InterlaceCodingOption == FRAME_CODING
&& input->SparePictureOption && img->type != B_SLICE)
CalculateSparePicture ();
*/
//Rate control
if(input->RCEnable)
{
// we could add here a function pointer!
bits = (int) (stats->bit_ctr - stats->bit_ctr_n);
rc_update_pict_frame(quadratic_RC, bits);
}
if (input->PicInterlace == FRAME_CODING)
{
if ((input->rdopt == 3) && (img->nal_reference_idc != 0))
UpdateDecoders (); // simulate packet losses and move decoded image to reference buffers
if (input->RestrictRef)
UpdatePixelMap ();
}
if (input->Verbose != 0)
if( IS_INDEPENDENT(input) )
{
find_snr_JV ();
}
else
{
find_snr ();
}
else
{
snr->snr_y = 0.0;
snr->snr_u = 0.0;
snr->snr_v = 0.0;
snr->sse_y = 0.0;
snr->sse_u = 0.0;
snr->sse_v = 0.0;
}
// redundant pictures: save reconstruction to calculate SNR and replace reference picture
if(input->redundant_pic_flag && key_frame)
{
for(i=0; i<img->width; i++)
{
for(j=0; j<img->height; j++)
{
imgY_tmp[j][i] = enc_frame_picture[0]->imgY[j][i];
}
}
for(i=0; i<img->width_cr; i++)
{
for(j=0; j<img->height_cr; j++)
{
imgUV_tmp[0][j][i] = enc_frame_picture[0]->imgUV[0][j][i];
imgUV_tmp[1][j][i] = enc_frame_picture[0]->imgUV[1][j][i];
}
}
}
if(input->redundant_pic_flag && redundant_coding)
{
for(i=0; i<img->width; i++)
{
for(j=0; j<img->height; j++)
{
enc_frame_picture[0]->imgY[j][i] = imgY_tmp[j][i];
}
}
for(i=0; i<img->width_cr; i++)
{
for(j=0; j<img->height_cr; j++)
{
enc_frame_picture[0]->imgUV[0][j][i] = imgUV_tmp[0][j][i];
enc_frame_picture[0]->imgUV[1][j][i] = imgUV_tmp[1][j][i];
}
}
}
time (<ime2); // end time sec
ftime (&tstruct2); // end time ms
tmp_time = (ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm);
tot_time = tot_time + tmp_time;
if (input->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]);
}
else
{
// replace top with frame
replace_top_pic_with_frame(enc_frame_picture[0]);
free_storable_picture(enc_field_picture[1]);
}
}
else
{
if (img->fld_flag)
{
store_picture_in_dpb(enc_field_picture[1]);
}
else
{
if (img->rd_pass==2)
{
store_picture_in_dpb(enc_frame_picture[2]);
free_storable_picture(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[1]);
}
else if (img->rd_pass==1)
{
store_picture_in_dpb(enc_frame_picture[1]);
free_storable_picture(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[2]);
}
else
{
if(input->redundant_pic_flag==0)
{
store_picture_in_dpb(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[1]);
free_storable_picture(enc_frame_picture[2]);
}
else
{
// key picture will be stored in dpb after redundant picture is coded
if(key_frame==0)
{
store_picture_in_dpb(enc_frame_picture[0]);
free_storable_picture(enc_frame_picture[1]);
free_storable_picture(enc_frame_picture[2]);
}
}
}
}
}
img->AverageFrameQP = (img->SumFrameQP + (img->FrameSizeInMbs >> 1))/img->FrameSizeInMbs;
if ( input->RCEnable && img->type != B_SLICE && input->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;
}
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(input->RCEnable)
{
if ((!input->PicInterlace) && (!input->MbInterlace))
bits = (int) (stats->bit_ctr - stats->bit_ctr_n);
else
{
bits = (int)(stats->bit_ctr - (quadratic_RC->Pprev_bits)); // used for rate control update
quadratic_RC->Pprev_bits = stats->bit_ctr;
}
}
switch (img->type)
{
case I_SLICE:
stats->bit_ctr_I += stats->bit_ctr - stats->bit_ctr_n;
ReportIntra(tmp_time,me_time);
break;
case SP_SLICE:
stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n;
ReportSP(tmp_time,me_time);
break;
case B_SLICE:
stats->bit_ctr_B += stats->bit_ctr - stats->bit_ctr_n;
ReportB(tmp_time,me_time);
break;
default: // P
stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n;
ReportP(tmp_time,me_time);
}
}
if (input->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);
stats->bit_ctr_n = stats->bit_ctr;
//Rate control
if(input->RCEnable)
{
rc_update_pict(quadratic_RC, bits);
// update the parameters of quadratic R-D model
if( img->type==P_SLICE || (input->RCUpdateMode == RC_MODE_1 && img->frm_number) )
{
updateRCModel(quadratic_RC);
if ( input->RCUpdateMode == RC_MODE_3 )
quadratic_RC->PreviousWholeFrameMAD = ComputeFrameMAD();
}
}
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
img->lastINTRA = imax(img->lastINTRA, frame_no);
img->lastIntraNumber = img->frm_number;
if ( img->currentPicture->idr_flag )
{
img->lastIDR = frame_no;
img->lastIDRnumber = img->frm_number;
}
}
return ((IMG_NUMBER == 0)? 0 : 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -