视频或动画丢帧_概念介绍和解决策略

1、问题现象——视频丢帧

生活中,不管大家是自己用手机或者摄像机拍短片,或是看电影视频短片都遇到过,视频中声音画面不同步的现象,这其实是视频一种严重的丢帧现象。当视频解码和渲染的总时间大于了视频指定的时间时,就会出现声音比画面快的情况,若单个画面延后的时间在人眼不能察觉的范围内还是能接受的,但如果如此累计起来就会造成这个延迟的加大,就会导致上述说的严重的视频丢帧现象。

2、视频播放原理

我们看到的视频其实就是一幅一幅的图片组成的,就和电影一样遵照 视频暂留原理,一般人在脑海中视频暂留时间大概为0.1~0.4s。电影帧一般是18—24帧,即1秒有18-24张画面,然后连续的把图片展示出来,达到视频连续的效果。比如一般你玩电脑游戏时FPS(frame per second,每秒帧数)大约40或者60左右,那么1秒画面刷新40次或者60次,即1秒显示40或者60张图片,而在1秒中有时候我们发现虽然游戏显示是40帧,但实际1秒显示并没有40张图片,如若只是少了几张我们一般还觉察不到差异,如果图片丢失多了,你会明显感觉到游戏断断续续,画面不连续。

3、视频编码过程(H264)

单纯传输视频画面,视频量非常大,对现有的网络和存储来说是不可接受的。为了能够使视频便于传输和存储,人们发现视频有大量重复的信息,如果将重复信息在发送端去掉,在接收端恢复出来,这样就大大减少了视频数据的文件,因此有了H.264视频压缩标准。

编码器将多张图像进行编码后生产成一段一段的 GOP ( Group of Pictures ) , 解码器在播放时则是读取一段一段的 GOP 进行解码后读取画面再渲染显示。GOP ( Group of Pictures) 是一组连续的画面,由一张 I 帧和数张 B / P 帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。I 帧是内部编码帧(也称为关键帧),P帧是前向预测帧(前向参考帧),B 帧是双向内插帧(双向参考帧)。简单地讲,I 帧是一个完整的画面,而 P 帧和 B 帧记录的是相对于 I 帧的变化。如果没有 I 帧,P 帧和 B 帧就无法解码

在这里插入图片描述
图1 在H.264压缩标准中I帧、P帧、B帧表示传输的视频画面示意图

4、H264中 I帧、P帧、B帧的含义

H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,他的理论依据是: 参照一段时间内图像的统计结果表明,在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内。所以对于一段变化不大图像画面,我们可以先编码出一个完整的图像帧A,随后的B帧就不编码全部图像,只写入与A帧的差别,这样B帧的大小就只有完整帧的1/10或更小!B帧之后的C帧如果变化不大,我们可以继续以参考B的方式编码C帧,这样循环下去。这段图像我们称为一个序列(序列就是有相同特点的一段数据),当某个图像与之前的图像变化很大,无法参考前面的帧来生成,那我们就结束上一个序列,开始下一段序列,也就是对这个图像生成一个完整帧A1,随后的图像就参考A1生成,只写入与A1的差别内容。

5、视频解码过程(H264)

通过前面的讲解,相信大家对视频编码后图片的变化过程有了大概的了解了(了解过程就行,具体技术细节就不用追究了),那么我们的重点就来了,播放器播放视频的过程就和图片编码成视频单元(NALU)的过程相反,而是把我们编码后的I帧、P帧、B帧中的信息解码后,依照编码顺序还原出原来的图片,并按照一定的时间显示(比如每秒显示25幅图片,那么每幅图片之间的间隔就是40ms,也就是每隔40ms显示一幅图片)。请注意这里的一定的时间(这里的40ms)里面播放器需要做许多的事情:

1、读取视频文件或网络数据

2、识别读取的数据中的视频相关的数据

3、解析出里面的每一个单元(NALU),即每一帧(I、P、B)

4、然后把这些帧解码出完整的图片(I帧可以解码成完整图片,P、B帧则不可以,需要参考其他帧的数据)

5、最后按照一定的时间间隔把解码出来的图片显示出来

大多数情况下,播放器所在设备的软硬件环境的解码能力都是可以让播放器在这个一定时间(比如40ms)内完成图片的显示的,这种情况下就是最好不过的了。而也有设备软硬件环境的解码能力不能在这个一定时间(比如40ms)内完成图片的显示,但是呢又相差不大(比如相差几毫秒),但是随着解码的次数增加,这个时间就会累计,后面就有可能相差几秒、几十秒、几分钟等,这样就需要“丢帧”操作了。

6、开始丢帧

丢帧丢帧,怎么丢,丢掉哪些帧我们怎么决定呢,这就要从视频图像是怎么解码得到的原理下手了,不然随便丢帧的话,最容易出现的情况就是花屏,导致视频基本不能看。下面我就举个例子来说明怎样丢帧:

比如我们的视频规定的是隔40ms(每秒25帧,且没秒的第一帧是I帧)显示一幅图片,而我们的设备解码能力有限,最快的解码出一幅图片的时间也需要42ms,这样本来该在40ms出显示第一幅图片,但是由于解码时间花了42ms,那么这一幅图片就在42ms时才显示出来,比规定的时间(40ms)延迟了(42-40)2ms,当我们连续解码24幅图片时,这个延迟就到了20 * 2ms = 40ms,假设这个40ms的延迟已经很大了,再加大延迟就会造成我们明显感觉到视频的声音和画面不同步了,所以我们就需要把后面的(25-24)1帧没解码的给丢了不显示(因为此时解码24帧的时间已经消耗了24*42=1008ms了,也就是说下一个40ms该显示第二秒的第一帧了,如果再显示第一秒的最后一帧,这样就会发生明显不同步的现象了),而是接着第二秒的数据开始解码显示,这样我们就成功的丢掉了一帧数据,来尽量保证我们的声音和画面同步了。

7、丢帧优化

前面提到的都是理想情况(每秒25帧,并且每一秒的第一帧都是I帧,能独立解码出图像,不依赖其他帧)下的丢帧,而不理想的情况(2个I帧直接的间隔不是定长的,比如第一个I帧和第二个I帧直接间隔24个其他帧,而第三个I帧和第二个I帧之间相差35个其他帧)则是经常遇到的,这种情况下我们就不能写死解码播放24帧然后丢掉第25帧,因为可能出现丢掉25帧后的下一帧仍然不是I帧,这样解码就会解不出完整的图片,显示出来的画面就会有花屏,影响体验。那么比较好的办法就是,我们定义一个内存缓冲区域,尽量在这个区域里面包含2个及以上的I帧(注意是解码前),比如:播放器从第一个关键帧开始解码播放,由于解码能力有限,当理论时间应该马上解码显示第二个关键帧时,而此时播放器还在解码这个关键帧之前的第5帧,也就是说播放器还得再解码5帧才能到这个关键帧,那么我们就可以把这5帧给丢掉了,不解码了,直接从这个关键帧开始解码,这样就能保证在每个关键帧解码播放时都和理论播放的时间几乎一致,让人察觉不到不同步现象,而还不会造成花屏的现象。这种丢帧个人觉得才是比较不错的方案。

6. 丢帧检测策略

在视频采集的时候是录制一帧就编码一帧发送一帧的,在编码的时候会生成 PTS,这里需要特别注意的是frame(帧)的编码方式,在通常的场景中,编解码器编码一个I帧,然后向前跳过几个帧,用编码I帧作为基准帧对一个未来P帧进行编码,然后跳回到I帧之后的下一个帧。编码的I帧和P帧之间的帧被编码为B帧。之后,编码器会再次跳过几个帧,使用第一个P帧作为基准帧编码另外一个P帧,然后再次跳回,用B帧填充显示序列中的空隙。这个过程不断继续,每12到15个P帧和B帧内插入一个新的I帧。P帧由前一个I帧或P帧图像来预测,而B帧由前后的两个P帧或一个I帧和一个P帧来预测,因而编解码和帧的显示顺序有所不同,如下图GOP示意图。在播放动画时,读取数据帧上的时间帧,判断时间帧是否完整便可判断动画是否丢帧。
在这里插入图片描述
图2 GOP示意图

其中,DTS(Decoding Time Stamp)和PTS(Presentation Time Stamp)即解码时间戳和显示时间戳,用这两个时间戳用来告诉播放器该在什么时候解码和显示这一帧的数据。所以,通过分析显示的时间戳,我们可以判断视频或者动画内容是否丢帧。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一知半解-老同志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值