有很多的采集卡,摄像头,在做采集的时候,明明设置的25FPS,但实际采集数据回调过来,发现并不是40毫秒的间隔,而是50,60,甚至100不等的时间间隔。
这就给编码后打时间戳带来很大的困难。
在libav里,我们的默认编码参数都是:
ptAvEncoder->ptAvStreamVideo->codec->time_base.den = s32Fps;
ptAvEncoder->ptAvStreamVideo->codec->time_base.num = 1;
这样在编码后的时间戳以1递增,只适合于固定帧率。
我们来改一下:
ptAvEncoder->ptAvStreamVideo->codec->time_base.den = s32Fps * 1000;
ptAvEncoder->ptAvStreamVideo->codec->time_base.num = 1* 1000;
这样就把时间戳的scale变成了毫秒,就可以以毫秒为单位进行计算了,如下:
tAvPacket.pts = ((s64)u32TimeStamp * (s64)s32Fps);
u32TimeStamp是从开始记录的时间差值,以毫秒为单位;s32Fps是帧率。
对于音频,mp4文件默认是采样率为tick的,时间戳计算为:
tAvPacket.pts = (AvEncoderAudioInSizeGet(hHandle) * ( (s64)(u32TimeStamp)) / (AvEncoderAudioInSizeGet(hHandle) * 1000 / ptAvEncoder->ptAvStreamAudio->codec->sample_rate);
AvEncoderAudioInSizeGet(hHandle) 每次编码器需要的PCM数据长度。
u32TimeStamp是从开始记录的时间差值,以毫秒为单位。
ptAvEncoder->ptAvStreamAudio->codec->sample_rate PCM采样率,代表一秒的数据量。
因为乘以了1000,所以也化成了毫秒单位。
对于mp4,视频直接用绝对时间,音频用数据量,对rtmp,视频是毫秒计算,音频也换算成毫秒计算