在编码时 video 的情况如下:
1. 在 yuv 数据 阶段,和时间相关参数如下:
yuv数据我们在设置的时候要 设置参数,其中和时间相关的是 yuvfps 和 timebase,yuvfps一般是每秒25帧,yuvfps=25;timebase 一般设置为 1000,000 这样 我们就能计算出来再yuv数据阶段一张图片花费时间为: 1/25 * 1000000 = 40,000
整理:也就是说:我们在yuv阶段,yuv的timebase 是1000000,yuv的pts 的计算是每次读取一张图片,就给pts+= 1.0 / yuvfps * videotimebase
这两个值都是开发者设定的。
2. 当yuv数据在变成AVFrame时的过程中,时间相关
在从yuv 变成 avframe的过程中,一定要弄一个AVCodecContext,这时候要设置AVCodecContext 的相关参数,除了video的三要素外,还需要设置 AVCodecContext.timebase 为 1000000。
在将yuv数据变成AVFrame的代码中,我们需要重新设置 AVFrame的pts。如何设置呢?
yuv的pts * yuv的timebase = 这张图片显示的时间 = avframe阶段的 pts * avframe阶段的 timebase
avframe阶段的 pts = yuv的pts * yuv的timebase/avframe阶段的 timebase
对于video 来说:avframe阶段的 timebase就是avcodeContext 中的timebase,也是开发者手动设自动的。
在计算出来avframe的pts 后,记得设置avframe的pts的值。
3.当从avframe变成avpacket的过程中。时间相关
在前面,我们计算了avframe的pts,也知道avframe的timebase 就是avcodecContext的timebase。
那么avpacket 的pts 也要重新计算。
AVFrame pts * avFrame timebase = 这张图片的显示时间 = avpacket pts * avpacket timebase
也就是:
avpacket pts = AVFrame pts * avFrame timebase / avpacket timebase
AVFrame pts 和 avFrame timebase 的值我们在前面已经知道了,
关键问题是 avpacket timebase 是怎么来的呢?
实际上是,avpacket timebase 使用的是 AVStream中的timebase,那么AVStream 的timebase又是怎么来的呢?当我们使用
avformat_write_header(this->_avformatContext,nullptr);
发送头部的后,AVStream的timebase就有值了,不同的格式,AVStream的timebase不同,对于video来说,很多都是1,90000.
值的注意的是,我们在将avframe变成avpacket的时候,这时候还没有调用 avformat_write_header这个方法,因此这时候avpacket 中的pts,dts ,duration都是和avframe的pts,dts,duration一样的值。
4. 最终将avpacket 变成 MP4或者flv
在编码时 audio 的情况如下:
在解码时 video 的情况如下:
在解码时 audio 的情况如下:
/// 关于时间问题,看了网上的资料,大致结论如下,
/// 不同结构体的 time_base
///1、AVStream的time_base的单位是秒。每种格式的time_base的值不一样,根据采样来计算,比如mpeg的pts、dts都是以90kHz来采样的,所以采样间隔就是1/900000秒。
///2、AVCodecContext的time_base单位同样为秒,不过精度没有AVStream->time_base高,大小为1/framerate。
///3、AVPacket下的pts和dts以AVStream->time_base为单位(数值比较大),时间间隔就是AVStream->time_base。
///4、AVFrame里面的pkt_pts和pkt_dts是拷贝自AVPacket,同样以AVStream->time_base为单位;而pts是为输出(显示)准备的,以AVCodecContex->time_base为单位。
///5、输入流InputStream下的pts和dts以AV_TIME_BASE为单位(微秒),至于为什么要转化为微秒,可能是为了避免使用浮点数。
///6、输出流OutputStream涉及音视频同步,结构和InputStream不同,暂时只作记录,不分析