赞
踩
上一篇音视频同步策略和视频seek策略讲过一些方法,但是总视存在一些小问题,这里花费了近三天的时间对整个 音视频同步,以及seek测率进行较大的调整,使得整个程序更健壮,用户在界面胡乱操作,seek和pause都不会引起程序卡顿和崩溃了。
音视频seek策略最简单的方法,就是一个大锁,将音频解码 和 视频解码播放 各用同一个锁锁住,然后,将seek部分用同一个锁锁住,这样seek的时候清空数据就不会导致缓冲区有数据,或者死锁问题,但是这样效率很低,且看似音视频各 一个线程,其实同时只有一个线程能跑。这里将自己的心血总结一些。大致是对上一篇的优化。
结构图
如图:有四个线程,橙色为条件判断和赋值。
demux 解封装出来,分别为videoPacket 和 audioPacket,分别存入一个 list里面。
audioThread 不停的从audioPacket list 取audioPacket 进行decode 和resample,并且将frame的pts和 重采样数据data存储在 audio data list 和 pts list中
videoThread 不停从 videoPacket list 取出 videoPacket 进行decode,然后于当前播放音频 pts比较,小于就进行显示
音频播放线程,openSELS进行播放,在回调函数中取 audio data 和 pts 进行播放,并且将当前pts(curAudioPts) 设置为播放的pts
node: 为了方便播放器资源的管理,图中其实还有个dataManager类没有画出,这个类是所有对象的成员变量,并且一个播放器只能有一个,所有的数据都在dataManager 对象。一些 list 数据和播放器状态都在 这个类对象当中,包括ffmpeg的一些解码器 和 上下文 都存储在里面,当对播放器操作,seek 和 pause 和close的时候对数据的清理和通信,都是通过公用的dataManager来进行的
音视频同步策略
同步测率没有什么变化,同上一篇一样:因为视频解码后很大,不建议缓存,只能缓存packet,然后与当前音频比较,如果小于音频的pts就显示和播放。没有多大的变化。
Pause策略
通过将音频 线程 和 demux线程分开,现在音频 、 视频 、demux这三个线程都是完全独立的,除了 同步那里会阻塞其他地方都不会堵塞了。并且,在decode 和 resample的时候 不要用while(!isExit)没取到数据就睡2ms然后继续取数据。因为在过程中尽量不要堵塞,方便再后面暂停播放器。
pause:当我们每个线程的一个周期执行完毕后,再进行暂停,因为每个线程都是一秒至少30次,因此人是感觉不到这个暂停的延迟的,即在线程开通进行沉睡(2ms),然后看播放器状态,选择是否继续睡眠。
node
如果用glsurfaceView的时候,可能绘制视频的那个线程是主线程,可能不能堵塞哦。
demux的packet 必须存入后才能暂停,因此,需要用到while(!isExit),可能暂停会堵塞在这里,因此 需要在堵塞的时候判断是否isPauing &#x
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。