x 264 Code Tracing Group 1 9562241 9562314

  • Slides: 20
Download presentation
x. 264 Code Tracing Group 1 9562241薛伊倩 9562314張書瑜 9562134游智詮 9562138邱漢坤 9562208王芳瑜 9562308張宇蓓 9562336廖航緯

x. 264 Code Tracing Group 1 9562241薛伊倩 9562314張書瑜 9562134游智詮 9562138邱漢坤 9562208王芳瑜 9562308張宇蓓 9562336廖航緯

Code segment x 264_param_default x 264_param_parse x 264_param_apply_fastfirstpass x 264_param_apply_profile select_output Parse select_input x

Code segment x 264_param_default x 264_param_parse x 264_param_apply_fastfirstpass x 264_param_apply_profile select_output Parse select_input x 264_reduce_fraction x 264_validate_parameters x 264_slurp_file x 264_cqm_parse_jmlist x 264_set_aspect_ratio x 264_sps_init x 264_pps_init x 264_validate_levels x 264_cqm_init x 264_rdo_init x 264_init_vlc_tables main x 264_encoder_open x 264_encoder_headers parse_qpfile Encode_frame Print_status x 264_encoder_close x 264_dct_init_weights x 264_analyse_init_costs x 264_lookahead_init x 264_macroblock_cache_init x 264_ratecontrol_new x 264_ratecontrol_init_reconfigurble parse_zones init_pass 2

outline • • • Main Encode X 264_encoder_headers Parse_qpfile Encode_frame Print_status

outline • • • Main Encode X 264_encoder_headers Parse_qpfile Encode_frame Print_status

main() Target Parse command line & encode input file Input Command line Output File

main() Target Parse command line & encode input file Input Command line Output File Location x 264. c Caller none

main() • 流程圖 Parse command line Start encode int main( int argc, char **argv

main() • 流程圖 Parse command line Start encode int main( int argc, char **argv ){ x 264_param_t param; cli_opt_t opt; int ret; … /* Parse command line */ if( Parse( argc, argv, &param, &opt ) < 0 ) return -1; … /*start to encode*/ ret = Encode( &param, &opt ); return ret; }

Encode() Target encode Input *param , *opt Output 0 / -1 File Location x

Encode() Target encode Input *param , *opt Output 0 / -1 File Location x 264. c Caller main()

Encode() Get frame # Update interval X 264_encoder_open( ) Create a new pic static

Encode() Get frame # Update interval X 264_encoder_open( ) Create a new pic static int Encode( x 264_param_t *param, cli_opt_t *opt ) { … /* 得到frame數 */ opt->b_progress &= param->i_log_level < X 264_LOG_DEBUG; i_frame_total = input. get_frame_total( opt->hin ); //所有的frame i_frame_total = X 264_MAX( i_frame_total - opt->i_seek, 0 ) /*param->i_frame_total為user給的最大編碼frame#,若此數>0且i_frame_total=0或大於此數, i_frame_total就設為param->i_frame_total*/ if( ( i_frame_total == 0 || param->i_frame_total < i_frame_total ) && param->i_frame_total > 0 ) i_frame_total = param->i_frame_total; param->i_frame_total = i_frame_total; …… …… /* 算 i_update_interval, 範圍是 1~10 */ i_update_interval = i_frame_total ? x 264_clip 3( i_frame_total / 1000, 1, 10 ) : 10; …… …… /* x 264_encoder_open:create a new encoder handler, all parameters from x 264_param_t are 各結構體參數、編碼、預測等需要的參數(h) 初始化)*/ if( ( h = x 264_encoder_open( param ) ) == NULL ) { …} …… …… if( input. picture_alloc( &pic, param->i_csp, param->i_width, param->i_height ) ) {……}

Encode() if( !param->b_repeat_headers ) { b_repeat_headers // Write SPS/PPS/SEI F x 264_nal_t *headers; int

Encode() if( !param->b_repeat_headers ) { b_repeat_headers // Write SPS/PPS/SEI F x 264_nal_t *headers; int i_nal; if( x 264_encoder_headers( h, &headers, &i_nal ) < 0 ) { ……} x 264_encoder_headers() // write header if( (i_file = output. write_headers( opt->hout, headers )) < 0 ) For all frames return -1; } T Input. read_frame() for( i_frame = 0, i_frame_output = 0; b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); ) { //read frame if( input. read_frame( &pic, opt->hin, i_frame + opt->i_seek ) ) break; …… …… if( opt->qpfile ) parse_qpfile( opt, &pic, i_frame + opt->i_seek ); else { /* Do not force any parameters */ pic. i_type = X 264_TYPE_AUTO; pic. i_qpplus 1 = 0; } T opt->qpfile parse_qpfile() F Frametype = AUTO Qpplus 1=0

Encode() i_frame_size = Encode_frame( h, opt->hout, &pic, &last_pts ); …… if( opt->b_progress && i_frame_output

Encode() i_frame_size = Encode_frame( h, opt->hout, &pic, &last_pts ); …… if( opt->b_progress && i_frame_output % i_update_interval == 0 &&i_frame_output ) Print_status( i_start, i_frame_output, i_frame_total, i_file, param, last_pts ); } // end for Encode_frame() Update status? T Print_status() I B B B P while( !b_ctrl_c && x 264_encoder_delayed_frames( h ) ) { i_frame_size = Encode_frame( h, opt->hout, NULL, &last_pts ); …… if( opt->b_progress && i_frame_output % i_update_interval == 0 && i_frame_output ) Print_status( i_start, i_frame_output, i_frame_total, i_file, param, last_pts ); } // end while i_end = x 264_mdate(); input. picture_clean( &pic ); /* Erase progress indicator before printing encoding stats. */ if( opt->b_progress ) fprintf( stderr, " r" ); x 264_encoder_close( h ); //free mem …… input. close_file( opt->hin ); output. close_file( opt->hout, largest_pts, second_largest_pts ); Flush all delayed frames x 264_encoder_close()

x 264_encoder_headers() Target Input return the SPS(sequence parameter set) and PPS( picture parameter set

x 264_encoder_headers() Target Input return the SPS(sequence parameter set) and PPS( picture parameter set ) that will be used for the whole stream *h , **pp_nal , *pi_nal : Output framesize File Location encoder. c Caller Encode()

x 264_encoder_headers() int x 264_encoder_headers( x 264_t *h, x 264_nal_t **pp_nal, int *pi_nal )

x 264_encoder_headers() int x 264_encoder_headers( x 264_t *h, x 264_nal_t **pp_nal, int *pi_nal ) { int frame_size = 0; /* init bitstream context */ h->out. i_nal = 0; bs_init( &h->out. bs, h->out. p_bitstream, h->out. i_bitstream ); initial /* Write SEI, SPS and PPS. */ x 264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE ); if( x 264_sei_version_write( h, &h->out. bs ) ) return -1; //把x 264版本寫到output if( x 264_nal_end( h ) ) return -1; /* generate sequence parameters */ Write PPS x 264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST ); x 264_sps_write( &h->out. bs, h->sps ); //把sps寫到output if( x 264_nal_end( h ) ) return -1; /* generate picture parameters */ x 264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST ); Encapsulate x 264_pps_write( &h->out. bs, h->pps ); //把pps寫到output nal if( x 264_nal_end( h ) ) return -1; frame_size = x 264_encoder_encapsulate_nals( h ); //封裝nal /* now set output*/ *pi_nal = h->out. i_nal; *pp_nal = &h->out. nal[0]; h->out. i_nal = 0; return frame_size; } Write SEI Write SPS Set output

parse_qpfile() Target Input Output File Location Caller Parse qpfile to set frametype and QP

parse_qpfile() Target Input Output File Location Caller Parse qpfile to set frametype and QP *opt , *pic, i_frame pic->i-type , pic->i_qpplus 1 x 264. c Encode()

parse_qpfile() • format 1 P 20 framenum frametype quantizer • Frametype I IDR (key)

parse_qpfile() • format 1 P 20 framenum frametype quantizer • Frametype I IDR (key) I-frame P P-frame B Referenced B-frame i Non-IDR (non-key) I-frame b Non-referenced B-frame When only need to set frametype, using 1 as desired quantizer allows x 264 to choose the optimal quantizer value

parse_qpfile() • code static void parse_qpfile( cli_opt_t *opt, x 264_picture_t *pic, int i_frame )

parse_qpfile() • code static void parse_qpfile( cli_opt_t *opt, x 264_picture_t *pic, int i_frame ) { … while( num < i_frame ) { file_pos = ftell( opt->qpfile ); // 記住現在檔案讀寫的位置 ret = fscanf( opt->qpfile, "%d %c %dn", &num, &type, &qpframe); // ret是指共讀到幾個變數 if( num > i_frame || ret == EOF) { // 要qpfile目前的frame#在現在要encode的frame後面 pic->i_type = X 264_TYPE_AUTO; pic->i_qpplus 1 = 0; //設AUTO fseek( opt->qpfile, file_pos, SEEK_SET ); //把讀寫位置設為之前記下的位置file_pos break; } if( num < i_frame && ret == 3 ) continue; pic->i_qpplus 1 = qp+1; 根據qpfile設定frametype和QP if ( type == 'I' ) pic->i_type = X 264_TYPE_IDR; 若是frametype格式錯誤,將ret=0 else if( type == 'i' ) pic->i_type = X 264_TYPE_I; … else ret = 0; if( ret != 3 || qp < -1 || qp > 51 ) { // 格式不對,全部設自動,opt->qpfile = NULL表示之後不再參考qpfile …; fclose( opt->qpfile ); opt->qpfile = NULL; pic->i_type = X 264_TYPE_AUTO; pic->i_qpplus 1 = 0; break; } }}

parse_qpfile() • 流程圖

parse_qpfile() • 流程圖

Encode_frame() Target Encode a frame and write the encoded result to output Input *h

Encode_frame() Target Encode a frame and write the encoded result to output Input *h , hout , *pic Output File Location Caller i_frame_size x 264. c Encode()

Encode_frame() static int Encode_frame( x 264_t *h, hnd_t hout, x 264_picture_t *pic, int 64_t

Encode_frame() static int Encode_frame( x 264_t *h, hnd_t hout, x 264_picture_t *pic, int 64_t *last_pts ) { x 264_picture_t pic_out; x 264_nal_t *nal; int i_nal; X 264_encoder_encode() int i_frame_size = 0; // x 264_encoder_encode -> encode i_frame_size = x 264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ); // frame size < 0 ---> error if( i_frame_size < 0 ) { fprintf( stderr, "x 264 [error]: x 264_encoder_encode failedn" ); Output. write_frame return -1; } // frame size > 0 ---> write frame if( i_frame_size ) { i_frame_size = output. write_frame( hout, nal[0]. p_payload, i_frame_size, &pic_out ); *last_pts = pic_out. i_pts; } return i_frame_size; }

Print_status() Target Count fps and bitrate then print them Input i_start ( 開始encode的時間 ),

Print_status() Target Count fps and bitrate then print them Input i_start ( 開始encode的時間 ), i_frame_total, i_file, *param , last_pts none Output File Location x 264. c Caller Encode()

print_status() • 流程圖 fps bitrate print static void Print_status( int 64_t i_start, int i_frame,

print_status() • 流程圖 fps bitrate print static void Print_status( int 64_t i_start, int i_frame, …… ){ … int 64_t i_elapsed = x 264_mdate() - i_start; //目前為止經過的時間 double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0; //算 frame per second double bitrate = (double) i_file * 8 / ( (double) last_pts * 1000 * param->i_timebase_num / param>i_timebase_den ); X 264 [20. 0%] 2/10 frames, 1. 12 fps, 2. 18 kb/s, eta 00: 02: 45 if( i_frame_total ) { int eta = i_elapsed * (i_frame_total - i_frame) / ((int 64_t)i_frame * 1000000); sprintf( buf, "x 264 [%. 1 f%%] %d/%d frames, %. 2 f fps, %. 2 f kb/s, eta %d: %02 d", 100. * i_frame / i_frame_total, fps, bitrate, eta/3600, (eta/60)%60, eta%60 ); } else {sprintf( buf, "x 264 %d frames: %. 2 f fps, %. 2 f kb/s", i_frame, fps, bitrate ); } fprintf( stderr, "%s r", buf+5 ); x 264 1 frames: 1. 21 fps, 3. 36 kb/s … }

Thank you

Thank you