博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FFmpeg: cur_dts is invalid
阅读量:6881 次
发布时间:2019-06-27

本文共 8098 字,大约阅读时间需要 26 分钟。

hot3.png

声明:转帖时请注明出处

FFmpeg 版本3.0

调用ffmpeg执行转码时,发现会有如下打印信息:

cur_dts is invalid (this is harmless if it occurs once at the start per stream)

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编码为例,该打印的数量与输出编码帧的时间有关:

bframes : consecutive B-frames before this P-frame

i_lookahead: Number of frames for frametype lookahead

i_thread_frames:/* Number of different frames being encoded by threads;

                                      * 1 when sliced-threads is on. */

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:200choose_output, OutputStream stream cur_dts:-100 ..

注释:

libx264库在添加打印后,需要进行编译和安装,即make && make install

此外,ffmpeg也需要配置,编译和安装,才能使打印信息生效。

转载于:https://my.oschina.net/u/2326611/blog/678160

你可能感兴趣的文章
项目、软件开发过程中版本术语
查看>>
CSS实现背景透明,文字不透明(各浏览器兼容)
查看>>
【转】[大学引导]超级链接、字体颜色、音乐播放公式
查看>>
T-SQL中INSERT、UPDATE
查看>>
Linux下Nginx服务器配置Modsecurity实现Web应用防护系统
查看>>
openSUSE13.2安装ruby和rails
查看>>
python 高级函数
查看>>
F.Cards with Numbers
查看>>
简单入门Buffer
查看>>
OO第四阶段总结
查看>>
javascript总结02
查看>>
创建windows服务
查看>>
HTML5 入门基础
查看>>
【转载】读懂IL代码就这么简单(二)
查看>>
C++文件操作(fstream)
查看>>
用main函数传参做简单的计算器的代码
查看>>
python中struct.unpack的用法
查看>>
体绘制(Volume Rendering)概述之4:光线投射算法(Ray Casting)实现流程和代码(基于CPU的实现)...
查看>>
Python实践之(七)逻辑回归(Logistic Regression)
查看>>
PAT (Advanced Level) 1107. Social Clusters (30)
查看>>