📄 encoder.c
字号:
} h->mb = x264_macroblocks_new( h->sps->i_mb_width, h->sps->i_mb_height ); /* reference frame (2 for B frame) and current one */ for( i = 0; i < h->param.i_frame_reference+2; i++ ) { h->freference[i] = x264_frame_new( h ); } h->fdec = h->freference[0]; h->i_ref0 = 0; h->i_ref1 = 0; /* init cabac adaptive model */ x264_cabac_model_init( &h->cabac ); /* init predict_XxX */ x264_predict_16x16_init( h->cpu, h->predict_16x16 ); x264_predict_8x8_init( h->cpu, h->predict_8x8 ); x264_predict_4x4_init( h->cpu, h->predict_4x4 ); x264_pixel_init( h->cpu, &h->pixf ); x264_dct_init( h->cpu, &h->dctf ); x264_mc_init( h->cpu, h->mc ); x264_me_init( h->cpu, me ); h->me = me[h->param.i_me]; /* rate control */ h->rc = x264_ratecontrol_new( &h->param ); return h;}/**************************************************************************** * x264_nal_encode: ****************************************************************************/int x264_nal_encode( void *p_data, int *pi_data, int b_annexeb, x264_nal_t *nal ){ uint8_t *dst = p_data; uint8_t *src = nal->p_payload; uint8_t *end = &nal->p_payload[nal->i_payload]; int i_count = 0; /* FIXME this code doesn't check overflow */ if( b_annexeb ) { /* long nal start code (we always use long ones)*/ *dst++ = 0x00; *dst++ = 0x00; *dst++ = 0x00; *dst++ = 0x01; } /* nal header */ *dst++ = ( 0x00 << 7 ) | ( nal->i_ref_idc << 5 ) | nal->i_type; while( src < end ) { if( i_count == 2 && *src <= 0x03 ) { *dst++ = 0x03; i_count = 0; } if( *src == 0 ) { i_count++; } else { i_count = 0; } *dst++ = *src++; } *pi_data = dst - (uint8_t*)p_data; return *pi_data;}/* internal usage */static void x264_nal_start( x264_t *h, int i_type, int i_ref_idc ){ x264_nal_t *nal = &h->nal[h->i_nal]; nal->i_ref_idc = i_ref_idc; nal->i_type = i_type; bs_align_0( &h->bs ); /* not needed */ nal->i_payload= 0; nal->p_payload= &h->p_bitstream[bs_pos( &h->bs) / 8];}static void x264_nal_end( x264_t *h ){ x264_nal_t *nal = &h->nal[h->i_nal]; bs_align_0( &h->bs ); /* not needed */ nal->i_payload = &h->p_bitstream[bs_pos( &h->bs) / 8] - nal->p_payload; h->i_nal++;}/**************************************************************************** * x264_encoder_headers: ****************************************************************************/int x264_encoder_headers( x264_t *h, x264_nal_t **pp_nal, int *pi_nal ){ /* 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 ); } /* now set output*/ *pi_nal = h->i_nal; *pp_nal = &h->nal[0]; return 0;}static void x264_encoder_frame_put( x264_frame_t *buffer[X264_BFRAME_MAX], x264_frame_t *frame ){ int i; /* put the frame in buffer */ for( i = 0; buffer[i] != NULL; i++ ) { if( i >= X264_BFRAME_MAX ) { fprintf( stderr, "not enough room\n" ); return; } } buffer[i] = frame;}static x264_frame_t *x264_encoder_frame_put_from_picture( x264_t *h, x264_frame_t *buffer[X264_BFRAME_MAX], x264_picture_t *picture ){ int i; x264_frame_t *frame; /* get an unused bframe */ frame = h->frame_unused[0]; for( i = 0; i < X264_BFRAME_MAX; i++ ) { h->frame_unused[i] = h->frame_unused[i+1]; } h->frame_unused[X264_BFRAME_MAX] = NULL; /* copy the picture in it */ x264_frame_copy_picture( frame, picture ); /* put the frame in buffer */ x264_encoder_frame_put( buffer, frame ); buffer[i] = frame; return frame;}static x264_frame_t *x264_encoder_frame_get( x264_frame_t *buffer[X264_BFRAME_MAX]){ int i; x264_frame_t *frame = buffer[0]; for( i = 0; i < X264_BFRAME_MAX-1; i++ ) { buffer[i] = buffer[i+1]; } buffer[X264_BFRAME_MAX-1] = NULL; return frame;}static int64_t i_mtime_analyse = 0;static int64_t i_mtime_encode = 0;static int64_t i_mtime_write = 0;static int64_t i_mtime_filter = 0;#define TIMER_START( d ) \ { \ int64_t d##start = x264_mdate();#define TIMER_STOP( d ) \ d += x264_mdate() - d##start;\ }/**************************************************************************** * x264_encoder_encode: * XXX: i_poc : is the poc of the current given picture * i_frame : is the number of the frame being coded * ex: type frame poc * I 0 2*0 * P 1 2*3 * B 2 2*1 * B 3 2*2 * P 4 2*6 * B 5 2*4 * B 6 2*5 ****************************************************************************/int x264_encoder_encode( x264_t *h, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic ){ x264_picture_t picture_tmp; x264_frame_t *frame_psnr = h->fdec; /* just to kept the current decoded frame for psnr calculation */ int i_nal_type; int i_nal_ref_idc; int i_slice_type; int mb_xy; int i; int i_skip; int b_ok; float psnr_y, psnr_u, psnr_v; /* no data out */ *pp_nal = NULL; *pi_nal = 0; /* ------------------- Select slice type and frame --------------------- */ if( h->i_frame % (h->param.i_iframe * h->param.i_idrframe) == 0 ) { i_nal_type = NAL_SLICE_IDR; i_nal_ref_idc = NAL_PRIORITY_HIGHEST; i_slice_type = SLICE_TYPE_I; /* we encode the given frame */ h->picture = pic; /* null poc */ h->i_poc = 0; h->fdec->i_poc = 0; /* null frame */ h->i_frame_num = 0; /* reset ref pictures */ for( i = 1; i < h->param.i_frame_reference+2; i++ ) { h->freference[i]->i_poc = -1; } h->freference[0]->i_poc = 0; } else { /* TODO detect scene changes and switch to I slice */ if( h->param.i_bframe > 0 ) { x264_frame_t *frame; /* TODO avoid always doing x264_encoder_frame_put_from_picture */ /* TODO implement adaptive B frame patern (not fixed one)*/ /* put the current picture in frame_next */ frame = x264_encoder_frame_put_from_picture( h, h->frame_next, pic ); frame->i_poc = h->i_poc; /* get the frame to be encoded */ if( h->bframe_current[0] ) { frame = x264_encoder_frame_get( h->bframe_current ); i_slice_type = SLICE_TYPE_B; } else if( h->frame_next[h->param.i_bframe] == NULL ) { /* not enough b-frame yet */ frame = NULL; i_slice_type = -1; } else { int i_mod = h->i_frame % h->param.i_iframe; if( i_mod == 0 ) { i_slice_type = SLICE_TYPE_I; frame = x264_encoder_frame_get( h->frame_next ); } else { int i; for( i = 0; i < h->param.i_bframe; i++ ) { h->bframe_current[i] = x264_encoder_frame_get( h->frame_next ); } frame = x264_encoder_frame_get( h->frame_next ); i_slice_type = SLICE_TYPE_P; } } if( frame ) { h->picture = &picture_tmp; for( i = 0; i < frame->i_plane; i++ ) { h->picture->i_stride[i] = frame->i_stride[i]; h->picture->plane[i] = frame->plane[i]; } h->fdec->i_poc = frame->i_poc; x264_encoder_frame_put( h->frame_unused, frame ); /* it's ok to do it now */ } else { h->picture = NULL; } } else { i_slice_type = h->i_frame % h->param.i_iframe == 0 ? SLICE_TYPE_I : SLICE_TYPE_P; /* we encode the given frame */ h->picture = pic; h->fdec->i_poc = h->i_poc; /* low delay */ } i_nal_type = NAL_SLICE; if( i_slice_type == SLICE_TYPE_I || i_slice_type == SLICE_TYPE_P ) { i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ } else /* if( i_slice_type == SLICE_TYPE_B ) */ { i_nal_ref_idc = NAL_PRIORITY_DISPOSABLE; } } /* increase poc */ h->i_poc += 2; if( h->picture == NULL ) { /* waiting for filling bframe buffer */ return 0; } /* increase frame num but only once for B frame */ if( i_slice_type != SLICE_TYPE_B || h->sh.i_type != SLICE_TYPE_B ) { h->i_frame_num++; } /* build ref list 0/1 */ h->i_ref0 = 0; h->i_ref1 = 0; for( i = 1; i < h->param.i_frame_reference+2; i++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -