聲明:轉帖時請註明出處less
FFmpeg 版本3.0
調用ffmpeg執行轉碼時,發現會有以下打印信息:ide
cur_dts is invalid (this is harmless if it occurs once at the start per stream)this
ffmpeg.c對應代碼以下:編碼
/** * Select the output stream to process. * * @return selected output stream, or NULL if none available */ static OutputStream *choose_output(void) { int i; int64_t opts_min = INT64_MAX; OutputStream *ost_min = NULL; for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; int64_t opts = ost->st->cur_dts == AV_NOPTS_VALUE ? INT64_MIN : av_rescale_q(ost->st->cur_dts, ost->st->time_base, AV_TIME_BASE_Q); if (ost->st->cur_dts == AV_NOPTS_VALUE) av_log(NULL, AV_LOG_DEBUG, "cur_dts is invalid (this is harmless if it occurs once at the start per stream)\n"); if (!ost->finished && opts < opts_min) { opts_min = opts; ost_min = ost->unavailable ? NULL : ost; } } return ost_min; }
h264 encoder.c 初始化代碼以下:命令行
/* Init frames. */ if( h->param.i_bframe_adaptive == X264_B_ADAPT_TRELLIS && !h->param.rc.b_stat_read ) h->frames.i_delay = X264_MAX(h->param.i_bframe,3)*4; else h->frames.i_delay = h->param.i_bframe; if( h->param.rc.b_mb_tree || h->param.rc.i_vbv_buffer_size ) h->frames.i_delay = X264_MAX( h->frames.i_delay, h->param.rc.i_lookahead ); i_slicetype_length = h->frames.i_delay; h->frames.i_delay += h->i_thread_frames - 1; h->frames.i_delay += h->param.i_sync_lookahead; h->frames.i_delay += h->param.b_vfr_input;
等待填滿編碼緩衝區代碼以下:日誌
/* ------------------- Setup new frame from picture -------------------- */ if( pic_in != NULL ) { /* 1: Copy the picture to a frame and move it to a buffer */ x264_frame_t *fenc = x264_frame_pop_unused( h, 0 ); if( !fenc ) return -1; if( x264_frame_copy_picture( h, fenc, pic_in ) < 0 ) return -1; if( h->param.i_width != 16 * h->mb.i_mb_width || h->param.i_height != 16 * h->mb.i_mb_height ) x264_frame_expand_border_mod16( h, fenc ); fenc->i_frame = h->frames.i_input++; if( fenc->i_frame == 0 ) h->frames.i_first_pts = fenc->i_pts; if( h->frames.i_bframe_delay && fenc->i_frame == h->frames.i_bframe_delay ) h->frames.i_bframe_delay_time = fenc->i_pts - h->frames.i_first_pts; if( h->param.b_vfr_input && fenc->i_pts <= h->frames.i_largest_pts ) x264_log( h, X264_LOG_WARNING, "non-strictly-monotonic PTS\n" ); h->frames.i_second_largest_pts = h->frames.i_largest_pts; h->frames.i_largest_pts = fenc->i_pts; if( (fenc->i_pic_struct < PIC_STRUCT_AUTO) || (fenc->i_pic_struct > PIC_STRUCT_TRIPLE) ) fenc->i_pic_struct = PIC_STRUCT_AUTO; if( fenc->i_pic_struct == PIC_STRUCT_AUTO ) { #if HAVE_INTERLACED int b_interlaced = fenc->param ? fenc->param->b_interlaced : h->param.b_interlaced; #else int b_interlaced = 0; #endif if( b_interlaced ) { int b_tff = fenc->param ? fenc->param->b_tff : h->param.b_tff; fenc->i_pic_struct = b_tff ? PIC_STRUCT_TOP_BOTTOM : PIC_STRUCT_BOTTOM_TOP; } else fenc->i_pic_struct = PIC_STRUCT_PROGRESSIVE; } if( h->param.rc.b_mb_tree && h->param.rc.b_stat_read ) { if( x264_macroblock_tree_read( h, fenc, pic_in->prop.quant_offsets ) ) return -1; } else x264_stack_align( x264_adaptive_quant_frame, h, fenc, pic_in->prop.quant_offsets ); if( pic_in->prop.quant_offsets_free ) pic_in->prop.quant_offsets_free( pic_in->prop.quant_offsets ); if( h->frames.b_have_lowres ) x264_frame_init_lowres( h, fenc ); /* 2: Place the frame into the queue for its slice type decision */ x264_lookahead_put_frame( h, fenc ); if( h->frames.i_input <= h->frames.i_delay + 1 - h->i_thread_frames ) { /* Nothing yet to encode, waiting for filling of buffers */ pic_out->i_type = X264_TYPE_AUTO; return 0; } } else { /* signal kills for lookahead thread */ x264_pthread_mutex_lock( &h->lookahead->ifbuf.mutex ); h->lookahead->b_exit_thread = 1; x264_pthread_cond_broadcast( &h->lookahead->ifbuf.cv_fill ); x264_pthread_mutex_unlock( &h->lookahead->ifbuf.mutex ); }
以視頻h264編碼爲例,該打印的數量與輸出編碼幀的時間有關:code
bframes : consecutive B-frames before this P-frame視頻
i_lookahead: Number of frames for frametype lookaheadci
i_thread_frames:/* Number of different frames being encoded by threads;
* 1 when sliced-threads is on. */input
i_sync_lookahead; /* threaded lookahead buffer */
b_vfr_input; /* VFR input. If 1, use timebase and timestamps for ratecontrol purposes.
* If 0, use fps only. */
ffmpeg命令行:
./ffmpeg -i test_2.flv -vcodec libx264 -r 10 -report -y -f flv test_2out.flv
x264 encoder.c中添加打印語句以下:
/* Init frames. */ if( h->param.i_bframe_adaptive == X264_B_ADAPT_TRELLIS && !h->param.rc.b_stat_read ) h->frames.i_delay = X264_MAX(h->param.i_bframe,3)*4; else h->frames.i_delay = h->param.i_bframe; x264_log( h, X264_LOG_DEBUG,"X264 init1 delay:%d\n",h->frames.i_delay); if( h->param.rc.b_mb_tree || h->param.rc.i_vbv_buffer_size ) h->frames.i_delay = X264_MAX( h->frames.i_delay, h->param.rc.i_lookahead ); x264_log( h, X264_LOG_DEBUG,"X264 init2 delay:%d\n",h->frames.i_delay); i_slicetype_length = h->frames.i_delay; h->frames.i_delay += h->i_thread_frames - 1; x264_log( h, X264_LOG_DEBUG,"X264 init3 delay:%d\n",h->frames.i_delay); h->frames.i_delay += h->param.i_sync_lookahead; x264_log( h, X264_LOG_DEBUG,"X264 init4 delay:%d\n",h->frames.i_delay); h->frames.i_delay += h->param.b_vfr_input; x264_log( h, X264_LOG_DEBUG,"X264 init5 delay:%d\n",h->frames.i_delay);
打印日誌:
[libx264 @ 0x335a580] X264 init1 delay:3 [libx264 @ 0x335a580] X264 init2 delay:40 [libx264 @ 0x335a580] X264 init3 delay:40 [libx264 @ 0x335a580] X264 init4 delay:40 [libx264 @ 0x335a580] X264 init5 delay:41
總結:
cur_dts is invalid (this is harmless if it occurs once at the start per stream) 打印信息與編碼輸出幀的延時有關,其中最主要與i_lookahead值有關。
當編碼器有幀輸出時,則不會出現該打印信息。
以下圖所示,解碼41幀後,第42幀開始進行編碼。
[libx264 @ 0x335a580] x264 frame info........ [libx264 @ 0x335a580] x264 frame encoder info........ [libx264 @ 0x335a580] X264 input frame:41, delay frame:41, thread frame:1 [libx264 @ 0x335a580] x264 frame encoder finish........ choose_output, OutputStream stream cur_dts:0 ... cur_dts is invalid (this is harmless if it occurs once at the start per stream) choose_output, OutputStream stream cur_dts:3864 ... OutputStream filter is true ... process input, file index0, ... choose_output, OutputStream stream cur_dts:0 ... cur_dts is invalid (this is harmless if it occurs once at the start per stream) choose_output, OutputStream stream cur_dts:3890 ... OutputStream filter is true ... process input, file index0, ... choose_output, OutputStream stream cur_dts:0 ... cur_dts is invalid (this is harmless if it occurs once at the start per stream) choose_output, OutputStream stream cur_dts:3917 ... OutputStream filter is true ... process input, file index0, ... choose_output, OutputStream stream cur_dts:0 ... cur_dts is invalid (this is harmless if it occurs once at the start per stream) choose_output, OutputStream stream cur_dts:3943 ... OutputStream filter is true ... process input, file index0, ... [h264 @ 0x3355260] decoding video ....... [libx264 @ 0x335a580] x264 frame info........ [libx264 @ 0x335a580] x264 frame encoder info........ [libx264 @ 0x335a580] X264 input frame:42, delay frame:41, thread frame:1 [libx264 @ 0x335a580] frame= 0 QP=2.40 NAL=3 Slice:I Poc:0 I:1064 P:0 SKIP:0 size=1086 bytes [libx264 @ 0x335a580] x264 frame encoder finish........ [flv @ 0x3263460] flv enc type:0, dts:0 pts:200 choose_output, OutputStream stream cur_dts:-100 ..
註釋:
libx264庫在添加打印後,須要進行編譯和安裝,即make && make install
此外,ffmpeg也須要配置,編譯和安裝,才能使打印信息生效。