音视频同步之系统中的缓存

前言

这几天做录屏软件,生成的h264文件,用vlc播放是音视频同步的,但是用自己写的播放器,总是差那么一点点。从感知上来看大概0.2s~0.4s之间。
原始视频是音视频同步的。
就是当人快速说话的时候,口型跟声音是对上的。

音视频同步的两种方式

前提:音频帧和视频帧都必须有自己的时间戳。
没有时间戳:
如果没有这个前提。音频还好说,设置好音频播放参数之后持续的播就是了。
视频帧就麻烦了,要么以固定帧率播放,要么就播放的忽快忽慢。
没有时间戳的不考虑,这是初学者的做法。

以音频的时间戳为基准

也就是将视频同步到音频上。这种方式声音是流畅播放的。
应用场景:绝大部分视频播放器。

以视频的时间戳为基准

视频帧以自己的节奏播放(缓冲区中未播放的帧多了就播放的快些,反之就播慢点;或者是固定帧率);
缺点是:为了音视频同步,声音会卡顿。
应用场景:直播类接收端播放器。

以外部时钟为基准

选择一个外部时钟为基准,视频和音频的播放速度都以该时钟为标准。

音视频同步的标准

从感知上来看(这是我的感知,不是标准的)。
先约定一些数据:
Tv0:当前显示视频帧的时间戳;
Ta0:当前显示的视频帧应当播放的音频帧的时间戳;
Ta1:当前显示的视频帧实际播放的音频帧的时间戳;
如果 |Ta0-Ta1| < 0.1s,可以认为是同步的。
如果 |Ta0-Ta1| >= 0.3s,对话的时候就感觉很明显对不上了。

写到这里感觉跑题了,这篇blog主题不是写音视频同步,而是写音视频同步一个被忽视的地方

音视频同步,网上文章很多。自己找,不解释。

下面这张图片是声音在系统中的播放
这里写图片描述
几个名词的描述:
T0:当前正在播放的声音的时刻
T1-T0:当前系统缓存中还未播放的音频数据所需的时间
T2-T1:每次音频回调函数读取的数据播放的时间
Buf0: 系统中还未播放的数据
Buf1: 每次音频回调函数读取的数据

当播放器将Buf0播放完了,而Buf1还没有读进来。那么现在就没声了。
Buf1的大小,应该是按系统来的。我用Qt在win下,每次读取16384个byte。
16383个字节:
如果是11025hz,双声道,16bit,那么声音持续时间大概是0.371519s。
如果是44100hz,双声道,16bit,那么声音持续时间大概是0.0928798s。

一般情况下Buf0的大小<=BUf1。但是没有绝对的。也许它就是想多读取一点数据。

在我修改了播放的采样率之后,QAudioOutput::bufferSize()也跟着改变了,但是我没感觉出来这里改变有什么影响。
在我修改了播放的采样率之后,每次读取的字节数16384没有改变。

其实我一直想改变Buf1的大小,但是没找到方法。

总结

这个地方的细节很容易忽略掉。之前写播放器,没注意掉这么一点差距;当自己编码也要处理的时候,这个问题就冒出来了。
其实我是不想用44100的采样率的,因为数据量是11025的4倍。
但是因为这里音视频同步的时间差,不得不采用了44100的采样率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值