📄 encoder.c
字号:
{ if( h->freference[i]->i_poc >= 0 ) { if( h->freference[i]->i_poc < h->fdec->i_poc ) { h->fref0[h->i_ref0++] = h->freference[i]; } else if( h->freference[i]->i_poc > h->fdec->i_poc ) { h->fref1[h->i_ref1++] = h->freference[i]; } } } /* Order ref0 from higher to lower poc */ do { b_ok = 1; for( i = 0; i < h->i_ref0 - 1; i++ ) { if( h->fref0[i]->i_poc < h->fref0[i+1]->i_poc ) { x264_frame_t *tmp = h->fref0[i+1]; h->fref0[i+1] = h->fref0[i]; h->fref0[i] = tmp; b_ok = 0; break; } } } while( !b_ok ); /* Order ref1 from lower to higher poc (bubble sort) for B-frame */ do { b_ok = 1; for( i = 0; i < h->i_ref1 - 1; i++ ) { if( h->fref1[i]->i_poc > h->fref1[i+1]->i_poc ) { x264_frame_t *tmp = h->fref1[i+1]; h->fref1[i+1] = h->fref1[i]; h->fref1[i] = tmp; b_ok = 0; break; } } } while( !b_ok ); if( h->i_ref0 > h->param.i_frame_reference ) { h->i_ref0 = h->param.i_frame_reference; } if( h->i_ref1 > 1 ) { h->i_ref1 = 1; } /* Init the rate control */ x264_ratecontrol_start( h->rc, i_slice_type ); /* ------------------------ Create slice header ----------------------- */ if( i_nal_type == NAL_SLICE_IDR ) { x264_slice_header_init( &h->sh, &h->param, h->sps, h->pps, i_slice_type, h->i_idr_pic_id, h->i_frame_num - 1 ); /* increment id */ h->i_idr_pic_id = ( h->i_idr_pic_id + 1 ) % 65535; } else { x264_slice_header_init( &h->sh, &h->param, h->sps, h->pps, i_slice_type, -1, h->i_frame_num - 1 ); /* always set the real higher num of ref frame used */ h->sh.b_num_ref_idx_override = 1; h->sh.i_num_ref_idx_l0_active = h->i_ref0 <= 0 ? 1 : h->i_ref0; h->sh.i_num_ref_idx_l1_active = h->i_ref1 <= 0 ? 1 : h->i_ref1; } if( h->sps->i_poc_type == 0 ) { h->sh.i_poc_lsb = h->fdec->i_poc & ( (1 << h->sps->i_log2_max_poc_lsb) - 1 ); h->sh.i_delta_poc_bottom = 0; /* XXX won't work for field */ } else if( h->sps->i_poc_type == 1 ) { /* FIXME TODO FIXME */ } else { /* Nothing to do ? */ } /* global qp */ h->sh.i_qp_delta = x264_ratecontrol_qp( h->rc ) - h->pps->i_pic_init_qp; /* get adapative cabac model if needed */ if( h->param.b_cabac ) { if( h->param.i_cabac_init_idc == -1 ) { h->sh.i_cabac_init_idc = x264_cabac_model_get( &h->cabac, i_slice_type ); } } /* ---------------------- Write the bitstream -------------------------- */ /* init bitstream context */ h->i_nal = 0; bs_init( &h->bs, h->p_bitstream, h->i_bitstream ); /* Put SPS and PPS */ if( h->i_frame == 0 ) { /* generate sequence parameters */ x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST ); x264_sps_write( &h->bs, h->sps ); x264_nal_end( h ); /* generate picture parameters */ x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST ); x264_pps_write( &h->bs, h->pps ); x264_nal_end( h ); } /* Reset stats */ for( i = 0; i < 18; i++ ) h->stat.i_mb_count[i] = 0; /* Slice */ x264_nal_start( h, i_nal_type, i_nal_ref_idc ); /* Slice header */ x264_slice_header_write( &h->bs, &h->sh, i_nal_ref_idc ); if( h->param.b_cabac ) { /* alignement needed */ bs_align_1( &h->bs ); /* init cabac */ x264_cabac_context_init( &h->cabac, h->sh.i_type, h->sh.pps->i_pic_init_qp + h->sh.i_qp_delta, h->sh.i_cabac_init_idc ); x264_cabac_encode_init ( &h->cabac, &h->bs ); } for( mb_xy = 0, i_skip = 0; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ ) { x264_mb_context_t context; x264_macroblock_t *mb; mb = &h->mb[mb_xy]; /* load neighbour */ x264_macroblock_context_load( h, mb, &context ); /* analyse parameters * Slice I: choose I_4x4 or I_16x16 mode * Slice P: choose between using P mode or intra (4x4 or 16x16) * */ TIMER_START( i_mtime_analyse ); x264_macroblock_analyse( h, &h->mb[mb_xy] ); TIMER_STOP( i_mtime_analyse ); /* encode this macrobock -> be carefull it can change the mb type to P_SKIP if needed */ TIMER_START( i_mtime_encode ); x264_macroblock_encode( h, mb ); TIMER_STOP( i_mtime_encode ); TIMER_START( i_mtime_write ); if( IS_SKIP( mb->i_type ) ) { if( h->param.b_cabac ) { if( mb_xy > 0 ) { /* not end_of_slice_flag */ x264_cabac_encode_terminal( &h->cabac, 0 ); } x264_cabac_mb_skip( h, mb, 1 ); } else { i_skip++; } } else { if( h->param.b_cabac ) { if( mb_xy > 0 ) { /* not end_of_slice_flag */ x264_cabac_encode_terminal( &h->cabac, 0 ); } if( i_slice_type != SLICE_TYPE_I ) { x264_cabac_mb_skip( h, mb, 0 ); } x264_macroblock_write_cabac( h, &h->bs, mb ); } else { if( i_slice_type != SLICE_TYPE_I ) { bs_write_ue( &h->bs, i_skip ); /* skip run */ i_skip = 0; } x264_macroblock_write_cavlc( h, &h->bs, mb ); } } TIMER_STOP( i_mtime_write ); h->stat.i_mb_count[mb->i_type]++; } if( h->param.b_cabac ) { /* end of slice */ x264_cabac_encode_terminal( &h->cabac, 1 ); } else if( i_skip > 0 ) { bs_write_ue( &h->bs, i_skip ); /* last skip run */ } if( h->param.b_cabac ) { int i_cabac_word; x264_cabac_encode_flush( &h->cabac ); /* TODO cabac stuffing things (p209) */ i_cabac_word = (((3 * h->cabac.i_sym_cnt - 3 * 96 * h->sps->i_mb_width * h->sps->i_mb_height)/32) - bs_pos( &h->bs)/8)/3; while( i_cabac_word > 0 ) { bs_write( &h->bs, 16, 0x0000 ); i_cabac_word--; } } else { /* rbsp_slice_trailing_bits */ bs_rbsp_trailing( &h->bs ); } x264_nal_end( h ); /* now set output*/ *pi_nal = h->i_nal; *pp_nal = &h->nal[0]; /* update cabac */ if( h->param.b_cabac ) { x264_cabac_model_update( &h->cabac, i_slice_type, h->sh.pps->i_pic_init_qp + h->sh.i_qp_delta ); } /* update rc */ x264_ratecontrol_end( h->rc, h->nal[h->i_nal-1].i_payload * 8 ); /* ----------------------- handle frame reference ---------------------- */ if( i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE ) { /* apply deblocking filter to the current decoded picture */ if( h->param.b_deblocking_filter ) { TIMER_START( i_mtime_filter ); x264_frame_deblocking_filter( h, i_slice_type ); TIMER_STOP( i_mtime_filter ); } /* expand border */ x264_frame_expand_border( h->fdec ); /* move frame in the buffer */ h->fdec = h->freference[h->param.i_frame_reference+1]; for( i = h->param.i_frame_reference+1; i > 0; i-- ) { h->freference[i] = h->freference[i-1]; } h->freference[0] = h->fdec; } /* increase frame count */ h->i_frame++; /* restore CPU state (before using float again) */ x264_cpu_restore( h->cpu ); /* PSNR */ psnr_y = x264_psnr( frame_psnr->plane[0], frame_psnr->i_stride[0], h->picture->plane[0], h->picture->i_stride[0], h->param.i_width, h->param.i_height ); psnr_u = x264_psnr( frame_psnr->plane[1], frame_psnr->i_stride[1], h->picture->plane[1], h->picture->i_stride[1], h->param.i_width/2, h->param.i_height/2); psnr_v = x264_psnr( frame_psnr->plane[2], frame_psnr->i_stride[2], h->picture->plane[2], h->picture->i_stride[2], h->param.i_width/2, h->param.i_height/2); /* print stat */ fprintf( stderr, "frame=%4d NAL=%d Slice:%c Poc:%-3d I4x4:%-5d I16x16:%-5d P:%-5d SKIP:%-3d size=%d bytes PSNR Y:%2.2f U:%2.2f V:%2.2f\n", h->i_frame - 1, i_nal_ref_idc, i_slice_type == SLICE_TYPE_I ? 'I' : (i_slice_type == SLICE_TYPE_P ? 'P' : 'B' ), frame_psnr->i_poc, h->stat.i_mb_count[I_4x4], h->stat.i_mb_count[I_16x16], h->stat.i_mb_count[P_L0] + h->stat.i_mb_count[P_8x8], h->stat.i_mb_count[P_SKIP], h->nal[h->i_nal-1].i_payload, psnr_y, psnr_u, psnr_v );#if 0 /* Dump reconstructed frame */ x264_frame_dump( h, frame_psnr, "fdec.yuv" );#endif#if 0 if( h->i_ref0 > 0 ) { x264_frame_dump( h, h->fref0[0], "ref0.yuv" ); } if( h->i_ref1 > 0 ) { x264_frame_dump( h, h->fref1[0], "ref1.yuv" ); }#endif return 0;}/**************************************************************************** * x264_encoder_close: ****************************************************************************/void x264_encoder_close ( x264_t *h ){ int64_t i_mtime_total = i_mtime_analyse + i_mtime_encode + i_mtime_write + i_mtime_filter + 1; int i; fprintf( stderr, "x264: analyse=%d(%lldms) encode=%d(%lldms) write=%d(%lldms) filter=%d(%lldms)", (int)(100*i_mtime_analyse/i_mtime_total), i_mtime_analyse/1000, (int)(100*i_mtime_encode/i_mtime_total), i_mtime_encode/1000, (int)(100*i_mtime_write/i_mtime_total), i_mtime_write/1000, (int)(100*i_mtime_filter/i_mtime_total), i_mtime_filter/1000 ); /* ref frames */ for( i = 0; i < h->param.i_frame_reference+2; i++ ) { x264_frame_delete( h->freference[i] ); } /* empty all allocated picture for bframes */ for( i = 0; i < h->param.i_bframe; i++ ) { if( h->frame_unused[i] ) { x264_frame_delete( h->frame_unused[i] ); } if( h->bframe_current[i] ) { x264_frame_delete( h->bframe_current[i] ); } if( h->frame_next[i] ) { x264_frame_delete( h->frame_next[i] ); } } /* rc */ x264_ratecontrol_delete( h->rc ); x264_free( h->mb ); x264_free( h->p_bitstream ); x264_free( h );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -