时间戳——入门分析
很多新手提到如何音视频同步,最重要的就是时间戳了。这个只要入门了,以后你都会清楚一点。我也是一开始很搞不懂,搜索了很多资料,感觉总说不到点上,要么说的有点高深,对于新手来说很懵懂。 现在已经明白这个思路,就想分享一下,我也说的简单易懂一点。
基础的看这里就行了http://blog.csdn.net/nine_locks/article/details/48007055
为了好理解,就以H264+AAC为例子。
AAC:
一帧 1024个 sample。采样率 Samplerate 44100KHz
AAC一帧的播放时间是= 1024*1000000/44100= 22.32ms(单位为ms)
这里注意,1000000表示是在1000000单位下,计算出来的22.32ms
H264:
帧率为25的话。fps = 25.00 ,计算出来的时常为40ms.可以参考AAC的来计算。
由硬件产生的时间戳一般是系统时间,我们最多进行置0计算(也就是取到第一个时间戳记为0,让时间戳从0开始增长),或者64位到32位的转换(这个转换有的需要有的不需要)。所以一般得到(25fps)2个视频时间戳之差为40000(也就是duration)。进行如下转换后变成1920。
AVRational time_base2;
time_base2.num = 1;
time_base2.den = 48000;
AVRational time_base;
time_base.num = 1;
time_base.den = 1000000;
output_packet.pts= av_rescale_q(output_packet.pts,time_base, time_base2);
av_rescale_q 这个函数的转换,换算成公式如下:
48000*40000/1000000=1920
48000*48000/1000000=1024//aac 参考
就是吧在1000000这个单位下的40000转换成在48000下的“40000”,也就是1920.
1000000 和 48000 就是timescale,就是时钟tick数。就是时钟1秒走了多少下的意思。
1000000这个的由来是:原本的pts是系统时间,us为单位。
48000这个的由来是:这个不清楚,很多都是用48000。可能更好计算吧,换成其他的也可以例如90000,但都需要设置这个timescale,例如:
在ffmpeg下就是:
AVDictionary *opt=NULL;
av_dict_set_int(&opt,"video_track_timescale",48000,0);
avformat_write_header(ofmt_ctx,&opt);
在MP4V2下就是:
MP4SetTimeScale(MP4V2_file, 48000);
Tag:
值得注意的是FLV 是流媒体,是可以进行传输实时播放的。所以它的时间戳一定是以真正的播放时间。例如H264-25fps 的就是40 的递增。