ffmpeg里time_base总结
本来是想写一篇time_base
的详细文章,后来发现很多大神写过,那这里我就总结一下各种time_base
,方便大家理解。
一、time_base
-
AVStream
的time_base
的单位是秒。每种格式的time_base
的值不一样,根据采样来计算,比如mpeg
的pts
、dts
都是以90kHz
来采样的,所以采样间隔就是1/900000
秒。 -
AVCodecContext
的time_base
单位同样为秒,不过精度没有AVStream->time_base
高,大小为1/framerate
。 -
AVPacket
下的pts
和dts
以AVStream->time_base
为单位(数值比较大),时间间隔就是AVStream->time_base
。 -
AVFrame
里面的pkt_pts
和pkt_dts
是拷贝自AVPacket,同样以AVStream->time_base
为单位;而pts
是为输出(显示)准备的,以AVCodecContex->time_base
为单位。 -
输入流
InputStream
下的pts
和dts
以AV_TIME_BASE
为单位(微秒),至于为什么要转化为微秒,可能是为了避免使用浮点数。 -
输出流
OutputStream
涉及音视频同步,结构和InputStream
不同,暂时只作记录,不分析。
二、各个time_base之前的转换
ffmpeg提供av_rescale_q
函数用于time_base
之间转换,av_rescale_q(a,b,c)
作用相当于执行a*b/c
,通过设置b,c
的值,可以很方便的实现time_base
之间转换。
例如
InputStream(AV_TIME_BASE)
到AVPacket(AVStream->time_base)
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) { pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base); }
AVPacket(AVStream->time_base)
到InputStream(AV_TIME_BASE)
static int process_input_packet(InputStream *ist, const AVPacket *pkt) { if (pkt->dts != AV_NOPTS_VALUE) { ist->next_dts = ist->dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); } }
三、其他
AVFrame->pts
和AVPacket->pts
、AVPacket->dts
的值,在解码/编码后,会经历短暂的time_base不匹配的情况:
- 解码后,
decoded_frame->pts
的值使用AVStream->time_base
为单位,后在AVFilter
里面转换成以AVCodecContext->time_base
为单位。 - 编码后,
pkt.pts
、pkt.dts
使用AVCodecContext->time_base
为单位,后通过调用"av_packet_rescale_ts"
转换为AVStream->time_base
为单位。
作者:耕地
链接:http://www.jianshu.com/p/bf323cee3b8e
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。