ffmpeg里time_base总结

本来是想写一篇time_base的详细文章,后来发现很多大神写过,那这里我就总结一下各种time_base,方便大家理解。

一、time_base

  1. AVStreamtime_base的单位是秒。每种格式的time_base的值不一样,根据采样来计算,比如mpegptsdts都是以90kHz来采样的,所以采样间隔就是1/900000秒。

  2. AVCodecContexttime_base单位同样为秒,不过精度没有AVStream->time_base高,大小为1/framerate

  3. AVPacket下的ptsdtsAVStream->time_base为单位(数值比较大),时间间隔就是AVStream->time_base

  4. AVFrame里面的pkt_ptspkt_dts是拷贝自AVPacket,同样以AVStream->time_base为单位;而pts是为输出(显示)准备的,以AVCodecContex->time_base为单位。

  5. 输入流InputStream下的ptsdtsAV_TIME_BASE为单位(微秒),至于为什么要转化为微秒,可能是为了避免使用浮点数。

  6. 输出流OutputStream涉及音视频同步,结构和InputStream不同,暂时只作记录,不分析。

二、各个time_base之前的转换

ffmpeg提供av_rescale_q函数用于time_base之间转换,av_rescale_q(a,b,c)作用相当于执行a*b/c,通过设置b,c的值,可以很方便的实现time_base之间转换。

例如

  1. 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);
    }
  2. 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->ptsAVPacket->ptsAVPacket->dts的值,在解码/编码后,会经历短暂的time_base不匹配的情况:

  1. 解码后,decoded_frame->pts的值使用AVStream->time_base为单位,后在AVFilter里面转换成以AVCodecContext->time_base为单位。
  2. 编码后,pkt.ptspkt.dts使用AVCodecContext->time_base为单位,后通过调用"av_packet_rescale_ts"转换为AVStream->time_base为单位。


作者:耕地
链接:http://www.jianshu.com/p/bf323cee3b8e
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2017-08-09 19:44  爱吃土豆的男孩  阅读(415)  评论(0编辑  收藏  举报