以前使用ffmpeg都是从网上找代码,然后直接使用,但是这样不是长久之计,所以想从源码提示开始学习。
大概知道pts,dts是用于音视频同步的,那么他们是怎么使音视频同步的?为什么需要两个参数?难道一个参数不可以吗?
ffmpeg描述dts: * Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will be presented to the user.
看完之后还是云里雾里,查维基百科,得到定义:that is used to achieve synchronization of programs' separate elementary streams (for example Video, Audio, Subtitles) when presented to the viewer. 大意是pts是被用于音频,视频,字幕流的同步。
那么有一个pts标注某个时间播某个流不就ok了,为什么还需要dts?
网上并没有找到dts资料,所以先用pts试试。
昨天找资料发现pts中文意思是显示时间戳,dts中文意思是解码时间戳,dts好像跟有b帧的视频有关,在我这个项目中可以先不用考虑
但是昨天尝试了几次pts,还是没有发现什么规律,那么该怎么使用了?
后来发现AVCodecContext还有一个时间基time_base的概念,它到底代表什么意思?和pts有什么联系了?
time_base是一个结构体,有两个成员den(分母英文单词的缩写),num(分子英文单词的缩写),根据这两个成员变量相除,你可以得到每秒播放多少帧或者每帧播放需要的时间,如果你有音频和视频的帧率,那么pts只要每次累加1,就能实现同步了。
根据时间基的同步并不准确,因为我是从网络上获取的视频流,本身自带了时间戳,有什么办法能让我自带的时间戳去显示图像了?
通过实验终于明白了,time_base的意思,比如你的den=10,num=1;那么表示你一帧是0.1秒,
如果你的pts是每帧pts加1,那么播放器就会每0.1秒播放一帧,你要播放的数据,如果你有自己的时间戳,那么你可以调整den,num来设定时间的单位,
比如den = 100,num = 1;表示以10ms为单位。
当我设置time_base.den = 100;time_base.num = 1;时,ffmpeg居然自己修改了这两个值
case AVMEDIA_TYPE_AUDIO:
den = (int64_t)st->time_base.num * st->codec->sample_rate;
break;
case AVMEDIA_TYPE_VIDEO:
den = (int64_t)st->time_base.num * st->codec->time_base.den;
break;