Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2707867
  • 博文数量: 505
  • 博客积分: 1552
  • 博客等级: 上尉
  • 技术积分: 2514
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-23 18:24
文章分类

全部博文(505)

文章存档

2019年(12)

2018年(15)

2017年(1)

2016年(17)

2015年(14)

2014年(93)

2013年(233)

2012年(108)

2011年(1)

2009年(11)

分类:

2012-06-13 23:55:28

本文讲解的H.264的马赛克问题是以T264为基础的。T264是国内的开源项目,官方网站为,目前和JMH.264的官方源码)、X264http://developers.videolan.org/x264.html)一起被称为H.264三大CodecT264的程序做过汇编优化,速度还可以,但只能解T264本身的码流。

MPEG帧的概念和H.264的补充

MPEG定义

根据MPEG的定义,帧分为I,B,P帧。这些帧定义如下:

I帧:就是关键帧,I帧压缩采用基准帧模式,只提供帧内压缩,即把帧图像压缩到I帧时,仅仅考虑了帧内的图像。I帧压缩不能除去帧间冗余度。帧内压缩基于离散余弦变换(DCT),类似于JPEGH.261图像中使用DCT的压缩标准。I帧压缩可以得到61的压缩比而不产生任何可觉察的模糊现象。

B帧:为双向帧间编码。它从前面和后面的I帧或P帧中提取数据。B帧基于当前帧与前一帧和后一帧图像之间的差别进行压缩。B帧压缩可以达到2001的压缩比,其文件尺寸一般为I帧压缩尺寸的15%,不到P帧压缩尺寸的一半。

P帧:采用了前向预测,意思是P帧是根据前面的P帧或I帧预测得来的。P帧采用预测编码,利用相邻帧的一般统计信息进行预测。也就是说,它考虑运动特性,提供帧间编码。P帧预测当前帧与前面最近的I帧或P帧的差别。

H.264补充

H.264中也有I B P帧,不同的是,H.264是以多幅图像为参考,因此可以获取更高的压缩比,以及更连贯的动作。但是这也造成H.264耗资源大,延时也略大于MPEG-4

除了I B P帧外,H.264提出了SPSI帧,这两种帧介于IP之间。SP的编码原理和P类似,仍是基于帧间预测的运动补偿预测编码,两者之间的差异在于SP帧能够参照不同参考帧重构出相同的图像帧。充分利用这一特性,SP帧可以取代I帧,广泛应用于Bitstream Switching, Splicing, Random Access, Fast Forward Fast Backward以及Error Recovery等应用中。同时大大降低了码率的开销。SI则是基于帧内预测的编码技术,其重构图像的方法和SP完全相同。

SP帧的编码效率尽管略低于P,却远远高于I,大大改善了H.264的网络亲和性,支持灵活的流媒体服务应用,具有很强的抗误码性能,适于在噪声干扰大、丢包率高的无线信道中传输。

T264中帧的概念

T264中主要包括了IDR,I,P,B四种。

IDR:类似于H.264标准的I帧,在马赛克问题中起着至关重要的作用。在IDR之后的图像不会再以IDR之前的图像为参考,间断性的插入IDR,可以把视频分成段。

I:类似于H.264标准的SP帧,进行了帧间的预测。T264I的取名让我们走了不少弯路。我们一直把I作为关键帧来处理,但是发现在网络丢包的情况下只播放I帧,也会有马赛克现象出现。而且前面的包丢的越多,I帧的马赛克现象越严重,这就表明I帧也和前面的帧作了帧内预测。对IDR帧的实验和研究才让我们走出误区,IDR才是真正的标准中的I帧。

PB:这两个和标准中一致,和多幅图像做了帧间的预测。

T264流的改造

目前T264支持的码流主要有如下几种:

0) IDR P P P …..P I P P P P … P I P P …

1) IDR B P B P…..B P B P I B P B P …

2) IDR B B P B B P…..B B P I B B P

在数据的刚开始总会有一个IDR帧出现,之后就不再有IDR。这样可以让数据量很小,但是解码端必须要收到第一个IDR帧,否则整个数据都将不能正确解码,这就导致我们实验时必须先启动解压端,然后再启动压缩端,以保证第一个IDR顺利到达。

后两种带有B的码流在目前的T264的源码中已经不再使用。B帧的加入虽然可以让数据量变小,但是也会造成CPU消耗过多,在丢包的情况下数据难以恢复的现象。我想T264只所以不采用后面两种码流,大概就是考虑这些问题。

目前T264采用的码流为第一种,对于本地文件压缩,这种码流非常适合,但是对于网络传输来说,这种码流有着重大的问题。因为网络传输时第一个IDR帧很可能不能被解压缩端所获取,这样就造成严重的误码和程序错误。对于这个问题,我的解决方案是定期投放IDR帧。由于过多的IDR会带来数据量变大,为此我们又要采取另外一种措施,就是尽可能放弃I帧,以此来减少由于IDR数量增加造成的数据量增大的问题。因此我们的码流如下所示:

IDR P P P …..P IDR P P P P … P IDR P P …

马赛克问题的探讨

在确定好我们的码流后,我将对马赛克问题做详细的分析。目前我们采用了每10帧一个IDR的方式,为了更好的说明问题作出了如下图表:

码流

IDR

P

P

P

P

P

P

P

P

P

IDR

P

P

P

P

P

帧号

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

上表中111号帧为IDR帧,其余位P帧。假设第7帧丢失,如下图所示:

码流

IDR

P

P

P

P

P

P

P

P

IDR

P

P

P

P

P

帧号

1

2

3

4

5

6

8

9

10

11

12

13

14

15

16

那么根据P帧的特性,第8帧就会参考前面的序列1-6来解码,由于第7帧和第6帧是有细微的区别的,这样第八帧率在解码的时候就会产生误码,也就会有轻微的马赛克现象。

当第9帧再参考第8帧解码时,由于8本身已经有了轻微的马赛克,9将会对马赛克放大。到了10马赛克更加严重。

如下表所示,如果丢失第3帧:

码流

IDR

P

P

P

P

P

P

P

P

IDR

P

P

P

P

P

帧号

1

2

4

5

6

7

8

9

10

11

12

13

14

15

16

45678910将会依次对马赛克进行放大,这时的马赛克会比丢失第7帧更严重。

这也说明,在同一个IDRP的序列中丢失的包越往前,马赛克越严重。直到下一个IDR帧,马赛克将会结束。

马赛克问题的解决方案

分析了马赛克出现的原理之后,我们提出了马赛克问题的解决方案。仍然拿上面丢失第7帧的例子来看。

码流

IDR

P

P

P

P

P

P

P

P

IDR

P

P

P

P

P

帧号

1

2

3

4

5

6

8

9

10

11

12

13

14

15

16

我们可以考虑在丢失第7帧的情况下,同时也把该序列中在该帧后面的其他帧丢失,本例中,我们应该丢失8910,等待下一个IDR帧的到来。

如果丢失IDR帧,我们会把IDR相关的帧序列都丢失,以防止误码的产生。

这种方式可以有效地解决马赛克现象,源节点发出去30fps的视频,在网络上丢包之后到接收端可能看到的只是20fps,或者10fps,但是不会有马赛克问题产生。

我们这种解决方式也有缺陷的地方,比如第7帧的丢失,造成8,9,10帧也跟着丢失,那么在播放视频时,1-6帧都播放的很流畅,到7-10就会停住,也就是会出现忽快忽慢的现象。但是由于互联网丢包的随机性,这种现象在互联网上可能不太严重。另外这种方式对接收到的帧的利用率不是很高,如果第3帧丢失,那么第4-10帧即使收到也要人为的丢失。以后我们可以考虑利用相关的帧对丢失的帧进行预测,重新生成丢失的帧,并补齐。但是这样的实现的难度很大,目前还没有一个技术去实现这个。还有一个办法就是8910帧做去方块滤波处理,同时对边缘进行模糊处理,让8-10模糊的播放出来,而不至于出现马赛克和忽快忽慢的现象。

总结

H.264的加入让我们的带宽有了1/3的节省,目前30fps 320*240的视频占据带宽大概为15kBytes/s,比MPEG-425kBytes/s以上有了很大提高。同时马赛克问题也得到了合适的解决。

阅读(2292) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~