[✔️]视频同步的心得

简介: [✔️]视频同步的心得

同步问题


因为ffmpeg解码出来的纹理需要传递给engine渲染,如果在play的时候就开始进行ffmpeg解码,生成的texture传递给engine进行渲染,这样也没啥问题


但是如果要符合视频的正常速率,就需要我们在合适的时机进行ffmpeg解码,然后再和engine进行同步,否则的话,就会造成渲染的视频播放速率和实际的视频播放速率不太一致


要解决这个同步问题,有很多办法


如果ffmpeg解码是在另外一个线程解码,的确可以缓解OpenGL线程卡顿的问题,但是需要注意ffmpeg的解码时机,如果ffmpeg的解码跟时间无关,


void thread(){
    while(ffmpeg->decode()){
        results->push(ffmpeg->currentFrame());
    }
}


如上的代码,在这个线程开始执行的时候,ffmpeg的解码结果就会不停的产生,那么你就得注意缓存ffmpeg的解码结果,否则OpenGL要真正渲染当前时间的画面时,就拿不到了


视频帧率和游戏帧率不一致导致的同步问题


因为游戏引擎一般的帧率都是每秒60帧,有些情况下,出于性能考虑,会将帧率锁定在30左右, FFMpeg解码视频也需要花费时间,如果视频的帧率比游戏的帧率还要高,那么游戏引擎在渲染视频时,必定会发生丢帧现象。


举个例子:


▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
| time | 0s    | 0.1s | 0.2s | 0.3s | 0.4s | 0.5s | 0.6s | 0.7s | 0.8s | 0.9s | 1s  |
--------------------------------------------------------------------------------------
|video | f0    |  f1  |  f2  |  f3  |  f4  |  f5  |  f6  |  f7  |  f8  |  f9  |  f10|
|game  | f0    |      |  f1  |      |  f2  |      |  f3  |      |  f4  |      |  f5 |
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


如上所示例,游戏引擎的fps是每秒5帧,视频的fps是每秒10帧。


当游戏的帧率走到f1时,时间已经过去了0.2s,此时的0.2s对应的是视频的f2,也就是说,视频的f1帧就是解码出来了,游戏引擎在渲染的时候,因为时间同步的原因也会抛弃掉。


因此,视频的帧率不建议比游戏的帧率高,这样会浪费好多解码的视频帧,产生无效帧的同时还增加了CPU的负担,但是我们在处理音频时,还需要处理好这种情况,主动将落后时间过多的视频帧丢弃掉。


如果视频的帧率过高,还会导致解码的速度跟不上播放的速度,比如当前时间已经流逝到第1s,但是解码的视频帧还在第0.5s,通常的处理办法就是画面卡在解码出来的视频最后一帧,这样循环往复下去,视频的播放速率是比正常要慢的,原因就出在解码速度跟不上。


只有游戏引擎的帧率高于视频的帧率,渲染出来的视频效果才能表现出更多的细节,因为这种情况下,播放视频时不会发生丢帧现象。


视频帧过于提前当前时间,导致播放节奏变快


还有一种情况,就是我们也要校验当前的视频帧,是否提前于当前时间,如果过于视频帧过于提前,我们需要等待下当前时间,也就是说我们播放的视频帧时间和当前时间的关系如下:


当前时间-offset1 <= 视频帧时间 <= 当前时间+offset2


一般来说:


  • offset1(我设置的是40)要大一点,因为丢帧是为了追赶当前时间


  • offset2(我设置的是20)要小一点,因为等待时间到来时,当前是有画面的,稍微停留一下是感知不出来的


目录
相关文章
|
7月前
|
存储 关系型数据库 MySQL
数据同步大事务同步延迟
数据同步大事务同步延迟
88 6
|
4月前
|
SQL 缓存 关系型数据库
MySQL主从同步如何操作?
随着业务增长,单台MySQL服务器难以应对高并发访问和潜在的故障风险。主从同步(Master-Slave)通过读写分离提升数据库处理能力,具备多项优势:读写分离减轻主数据库压力、支持一主多从增强扩展性与高可用性、以及数据备份确保容灾恢复。MySQL利用binlog实现主从数据同步,记录所有写操作,不包含查询。binlog有三种格式:Statement(基于SQL语句)、Row(基于行更改)、Mixed(结合前两者优点)。主从复制涉及三个关键线程:主库的binlog dump thread和从库的I/O thread与SQL thread。
140 0
MySQL主从同步如何操作?
|
6月前
|
存储 Oracle 关系型数据库
几种常见的数据同步方式
【6月更文挑战第18天】几种常见的数据同步方式
786 4
|
7月前
|
Java 数据处理 调度
异步、半同步、同步
异步、半同步、同步
170 0
|
7月前
|
数据采集 关系型数据库 MySQL
dts同步问题之同步冲突
dts同步问题之同步冲突
190 5
|
7月前
|
关系型数据库 MySQL 网络安全
dts同步问题之同步状态异常
dts同步问题之同步状态异常
173 4
|
7月前
|
SQL 运维 监控
dts同步问题之实时同步延迟
dts同步问题之实时同步延迟
246 2
|
7月前
|
存储 NoSQL 数据库连接
Redis主从模式以及数据同步原理:全量数据同步、增量数据同步
Redis主从模式以及数据同步原理:全量数据同步、增量数据同步
835 0
|
缓存 NoSQL Redis
redis全量同步和增量同步周期
redis全量同步和增量同步周期
106 0
|
算法 小程序 调度
同步
同步
80 0