马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?快速注册
x
视频压缩中,每帧代表一幅静止的图像。而在实际压缩时,会采取各种算法减少数据的容量,其中IPB就是最常见的。1 W0 {# J! u7 [8 z* N8 P: {, ~5 }, z) s
简单地说,I帧是关键帧,属于帧内压缩。就是和AVI的压缩是一样的。P是向前搜索的意思。B是双向搜索。他们
' |$ ?0 G0 |: s3 d) l都是基于I帧来压缩数据。
& _; |' G: V" [; r- O1 d. K. ]: y4 y9 l! U I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
5 Z5 E8 ^3 X. i, L7 }# L+ g P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,* q% E9 y: Z0 v G' Q
生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
: C& Z2 c) Q( f9 b/ _/ C" C4 y, c; b B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况),$ ^4 }: h& o' j0 [8 z g
换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与% @- \# L5 @2 ]7 k4 D' L
本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累~。
# X3 s: m/ R+ E$ n 采用的压缩方法: 分组:把几帧图像分为一组(GOP),为防止运动变化,帧数不宜取多。- S/ ^0 P4 w6 m' D; _6 p& ~- p7 O
1.定义帧:将每组内各帧图像定义为三种类型,即I帧、B帧和P帧;
" Y4 P) J3 x: y 2.预测帧:以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;- w7 M7 o s/ `+ O& B) G
3.数据传输:最后将I帧数据与预测的差值信息进行存储和传输。
9 S$ D! U5 J& `, _- W: c2 Z! w2 k
一、I帧
9 I) l! T- `- R; D I图像(帧)是靠尽可能去除图像空间冗余信息来压缩传输数据量的帧内编码图像。# B2 a+ p% A: L4 |4 i3 \
I帧又称为内部画面 (intra picture),I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)
' g& L4 q% t2 S; Q# |的第一个帧,经过适度地压缩(做为随机访问的参考点)可以当成图象。在MPEG编码的过程中
+ |% {8 P2 w. y部分视频帧序列压缩成为I帧,部分压缩成P帧,还有部分压缩成B帧。I帧法是帧内压缩法(P、B为帧间),& v9 x) `% f% e
也称为“关键帧”压缩法。I帧法是基于离散余弦变换DCT(Discrete Cosine Transform)的压缩技术,( c X, ?4 e! ? v
这种算法与JPEG压缩算法类似。采用I帧压缩可达到1/6的压缩比而无明显的压缩痕迹。
2 a5 S, B% F: G' `' `1 u0 s0 e) D I帧特点:
0 J$ m) |% E$ [- t' e, Q+ B 1.它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;
7 r( Q% E8 M w0 p 2.解码时仅用I帧的数据就可重构完整图像;8 \7 r4 m, S9 [2 Y
3.I帧描述了图像背景和运动主体的详情;
3 O2 R5 P3 Z; `, E 4.I帧不需要参考其他画面而生成;
* c& P7 ]! S$ P) V5 J" B8 P! C 5.I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
6 I* Z2 ?- b+ _7 d$ f* r$ ` 6.I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;
& c4 q+ q8 z8 C8 R7 j) Z 7.I帧不需要考虑运动矢量;2 I1 C1 s0 a& q( D x
8.I帧所占数据的信息量比较大。
/ {' Y& @# \4 }* x- ]4 W1 N I帧编码流程:) @' j6 l z- @
(1)进行帧内预测,决定所采用的帧内预测模式。7 T$ Y3 C1 T. t7 E8 X
(2)像素值减去预测值,得到残差。1 C8 m2 L$ S: n8 ?( c s
(3)对残差进行变换和量化。0 U. A4 i7 G5 c; t! u% f! k2 v$ `
(4)变长编码和算术编码。5 P: ]' M: N4 m6 B& r2 \+ o6 h
(5)重构图像并滤波,得到的图像作为其它帧的参考帧。+ d: n6 N: r, m7 z k$ ~8 H- B- }
1 {( n3 @0 [6 N4 \, z" D) C二、P帧
, M( K* z; \6 I3 K H P图像(帧)是通过充分降低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,
6 r0 h: ]+ a$ O m8 b; O也叫预测帧。
7 ?% B% }' }9 Y# S4 N& q) r 在针对连续动态图像编码时,将连续若干幅图像分成P,B,I三种类型,P帧由在它前面的P帧或者I帧预测而来,5 {% V e9 P2 p$ s: U7 I
它比较与它前面的P帧或者I帧之间的相同信息或数据,也即考虑运动的特性进行帧间压缩。P帧法是根据本帧与+ X" X2 v6 @2 ~; m
相邻的前一帧(I帧或P帧)的不同点来压缩本帧数据。采取P帧和I帧联合压缩的方法可达到更高的压缩且无明显的压缩痕迹。
: P) {7 E; k- k8 l P帧的预测与重构:/ e% K8 {* p% k8 b( h
P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。0 N, B i; i) b) _. n. ]
在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,从而可得到完整的P帧。 n8 s9 Z+ F7 c1 ^9 Q4 f7 c
P帧特点:0 ~3 _+ Q6 A" D+ a) g% l+ c
①P帧是I帧后面相隔1-2帧的编码帧。 ! i2 F5 R2 L" R0 x
②P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差)。 " K6 w: t0 P8 R; ~) S
③解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像。
2 e) E1 [- [1 Q4 P1 g6 F0 D6 |- G ④P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧。 ) D6 R a2 y( E4 v
⑤P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧。) c9 r$ I7 Z. r1 f# B& q# y4 Y9 `$ d
⑥由于P帧是参考帧,它可能造成解码错误的扩散。
- \4 q G2 x1 [" q, P5 Q( p ⑦由于是差值传送,P帧的压缩比较高。
0 H+ m9 F! p* Y: P
. Y2 u1 } |5 e+ ~& I E( L! I2 z三、B帧0 U) F/ Y" Y# K* ?3 ^8 p, w
B图像(帧)是既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来6 w- L7 l8 }5 b
压缩传输数据量的编码图像,也叫双向预测帧。
a8 j) T9 t" o) t B帧法是双向预测的帧间压缩算法。当把一帧压缩成B帧时,它根据相邻的前一帧、本帧以及后一帧数据的. [% E. G) W4 b, `: O
不同点来压缩本帧,也即仅记录本帧与前后帧的差值。只有采用B帧压缩才能达到200:1的高压缩。一般地,I帧压缩效率最低,P帧较高,B帧最高。4 Z9 f l2 v2 Y6 A- h+ O
B帧的预测与重构:' p0 B' T7 }0 T' v+ E
B帧以前面的I或P帧和后面的P帧为参考帧,“找出”B帧“某点”的预测值和两个运动矢量,并取' c* d7 `, e# a: x7 v B! _
预测差值和运动矢量传送。接收端根据运动矢量在两个参考帧中“找出(算出)”预测值并与差值求和,
& s7 B2 |3 x |' v3 S得到B帧“某点”样值,从而可得到完整的B帧。9 w/ o2 Y4 Z4 D- x9 X7 n
B帧特点:
" F0 F! ^: `- E, A9 w: H% | 1.B帧是由前面的I或P帧和后面的P帧来进行预测的;
2 o: F& d0 P" N6 F 2.B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;1 h4 Q- s/ D$ U0 k0 m ]3 a
3.B帧是双向预测编码帧;
" q1 U* B- |% h/ f% h0 K 4.B帧压缩比最高,因为它只反映2参考帧间运动主体的变化情况,预测比较准确;8 o! `1 e' g* U+ ]
5.B帧不是参考帧,不会造成解码错误的扩散。 ( q2 G5 V- [# |# B9 I
P 帧和 B 帧编码的基本流程为:
5 j- K, F5 R+ R2 x/ r/ r7 F (1)进行运动估计,计算采用帧间编码模式的率失真函数(节)值。P 帧 只参考前面的帧,B 帧可参考后面的帧。- V; W: g1 {& W- }1 v
(2)进行帧内预测,选取率失真函数值最小的帧内模式与帧间模式比较,确定采用哪种编码模式。
. _; L6 d" B5 G" I (3)计算实际值和预测值的差值。2 e( ]* n O; l, t) w5 ~; s
(4)对残差进行变换和量化。
2 z2 i# G9 B/ A (5)若编码,如果是帧间编码模式,编码运动矢量。3 j, R" a; F2 m" U6 C
注:I、B、P各帧是根据压缩算法的需要,是人为定义的,它们都是实实在在的物理帧,至于图像中的
' l% O* H! S% H+ G8 q哪一帧是I帧,是随机的,一但确定了I帧,以后的各帧就严格按规定顺序排列。 - U7 C! ]2 `7 R5 A0 _7 D) @/ h8 ~
9 ^8 f: I* T0 Y4 g1 a# r! |8 f/ C' Z
四、实际应用
; a! B& O+ G0 R' B" v 从上面的解释看,我们知道I和P的解码算法比较简单,资源占用也比较少,I只要自己完成就行了,P呢,) r% N' L3 ^+ X
也只需要解码器把前一个画面缓存一下,遇到P时就使用之前缓存的画面就好了,如果视频流只有I和P,4 g% m4 F4 P3 R% M6 U' ~( O( ~
解码器可以不管后面的数据,边读边解码,线性前进,大家很舒服。
! F1 g+ ?7 x0 a6 q& L 但网络上的电影很多都采用了B帧,因为B帧记录的是前后帧的差别,比P帧能节约更多的空间,但这样一来,. B3 y) o" t/ ?" u ^
文件小了,解码器就麻烦了,因为在解码时,不仅要用之前缓存的画面,还要知道下一个I或者P的画面(
: s ?& y9 E. ]0 } a也就是说要预读预解码),而且,B帧不能简单地丢掉,因为B帧其实也包含了画面信息,如果简单丢掉,
: B) ^8 q" @4 G) P并用之前的画面简单重复,就会造成画面卡(其实就是丢帧了),并且由于网络上的电影为了节约空间,& E0 k/ C! P9 a6 y K3 F
往往使用相当多的B帧,B帧用的多,对不支持B帧的播放器就造成更大的困扰,画面也就越卡。& e9 j8 d+ X1 }) i
一般平均来说,I的压缩率是7(跟JPG差不多),P是20,B可以达到50,可见使用B帧能节省大量空间, [ |9 R9 f( T! D+ V" i
节省出来的空间可以用来保存多一些I帧,这样在相同码率下,可以提供更好的画质。
+ @% h4 t1 w0 {4 R
) U; q+ p# Z0 g+ H" t3 Q------------------------------------------------------------------------------------------------------------------% S' L! G5 Y% G' m; @5 H
注:此文由Littlepox编写- @8 L* x2 `- u4 W- u* q i$ q
1、IBP帧
0 q/ q0 y$ J/ j& y5 x( P' Z视频压缩的过程中,对于一段时间内相似的帧,采用记录第一张,后续几张只记录和第一张的区别,
- n7 y' Q; l+ o2 K- J% Q这种想法是很自然的。由此引申出两种帧:
O [5 y7 Q( E9 W# ?; z% D: i# h1 k6 B4 x1 u' {$ v
I帧(Independent Frame),独立编码的帧。I帧相当于记录一张jpg;一般常见于一个场景开头。后续的帧就需要依赖I帧1 v' S/ [8 _8 P1 [* K4 G4 a% d8 P
P帧(Predictive Frame),需要依赖其他帧来编码的类型。P帧需要参照在它之前的I帧或者其他的P帧,因为它只记录差别,; ~$ m5 [1 O% R& g9 w; E
所以对于那种前后差别很小甚至没有的帧,使用P帧编码能极大地减少体积。1 N( j6 z/ g( u" \
9 @: T. [6 ~) Y. M# l& i8 _7 B9 CMPEG2之后,引入了第三种帧:, ^! y( T: {& \6 w6 v
B帧(Bi-directional Frame),双向预测帧。B帧跟P帧类似,都是需要参照别的帧,区别在于B帧可以(# `) t& _" r+ m2 S; |0 v
但不必要)参照它后面的帧,B帧的记录和预测方式也做了调整,使得B帧的预测方式更灵活,对付高度静态规律的- t/ Y6 I) _- _* a& o% j
场景可以更有效的降低体积6 j* ~* r+ V' q ]* U& d
. x1 Q, D- l" c* I& K# Q
一种典型的排列方式:
; x- M( f! a8 b. m' }1 q! AIPBBPBPIPPB………$ B- _1 d+ e7 _' r
+ L3 @' G" t5 a8 p视频开头一定是一个I帧。' h" r! p) t- H) a
 1 B d: J: o3 b! t4 {2 W, \5 p- q# x
2、IDR帧与GOP区间/ p0 u% f K$ O! s) G
$ l5 M! C3 i& X0 [I帧中,有一类特殊的I帧,叫做IDR帧。IDR帧的性质是,比如第1000帧是IDR帧,那么这一帧相当于一个分水岭,
5 I4 I5 N# o# v" k+ K7 ^8 J( c8 n从1001帧开始,所有的帧都不能再参照1000帧之前的帧。在closed GOP规定下(x264设置中可以指定,并且vcb-s一直指定),0~999帧也不允许参照这个IDR帧以及之后的帧。这个性质在播放的时候额外有用:如果我直接从第1000帧开始播放,我可以毫无问题的播放下去,因为我不需要参照1000帧之前的内容完成解码。我从开头播放,直到999帧的时候,我都不需要参照1000帧及它后面的东西;1000帧之后的数据都损坏了,0~999帧也能正常播放。
: }' r& ]- e3 z" c a! I
8 R9 w+ ?; B+ P* V视频开头的I帧一定是IDR帧。" X5 }' l6 d- z* q7 G( t( g7 d! Z
: w$ m( A, Q( s. f/ q u在我们拖动进度条的时候,为啥有时候会卡顿,或者拖不准呢?其实是播放器干了这些事:' K! o" I3 R5 w2 C/ C" p
1. 计算你拖动进度条的时间,找出它应该是哪一帧,假设为N! l6 u9 `. }4 Q2 V m- o
2. 通过搜索视频索引信息,找出N帧前面最近的一个IDR帧,假设为M(M<=N)。很显然,M和N同属于一个GOP区间,: O( N. \9 T1 Z, P6 q& u+ g
这个区间开头的帧是M. B" E" T4 f. b$ x! v L
3. 如果你的播放器设置了快速索引,视频将直接从M帧开始播放,因为M帧是IDR,它不需要参照任何帧,所以立刻5 d1 s$ R6 O2 @- a& N6 c
可以开始播放。这是为啥你会发现开始的地方总是在之前一点。$ z) a- O1 @3 w1 @& W9 d
4. 否则,如果你的播放器设置了精确索引,解码器会从M帧一直开始解码,解码到N帧,然后显示N帧的画面,并继续播放。
- l' i! V% g9 O, q i3 v& N% t# T: I) S/ R
当N-M比较大的时候,播放器可能需要先解码几百甚至上千帧,才能继续播放。如果视频允许很长的GOP区间,
2 }7 k& s j2 T- U这个视频在播放的时候,拖动进度条就特容易卡顿。
' m. j. M, a7 R5 }9 S$ ^1 B8 ~' o8 y l% A
在x264中,如果设置了--min-keyint 1,那么所有I帧都是IDR帧(vcb-s也一直在用)。而GOP区间最大的范围是
: l: ~1 ` `: s+ [0 C通过--keyint指定的。这些在后续x264参数教程中再讨论。
+ P* H' M, A) C1 R5 t( A4 ]" m2 k
- _5 C1 p9 E Q) l \" ]' c两个IDR帧之间的区间,从一个IDR帧开始,到下一个IDR前的帧结束,叫做IDR区间,又叫做GOP区间。GOP区间
, ]4 P8 k- g: I6 [$ p: |5 v: J3 T可以看做是独立的一段视频:它里面的所有帧,都不需要参照任何区间之外的东西,只要一个GOP区间是齐全的,
( I L; N" e* q' L区间里面所有的帧都能被解码。我们平时看的视频就是多段GOP区间连接起来的。 |