深入講解音視頻編碼原理,H264碼流詳解——手寫H264編碼器

音視頻高手課08-H264 I幀 P幀 B幀及手寫H264編碼器

1 三種幀的說明

1焙格、I 幀:幀內(nèi)編碼幀,幀表示關(guān)鍵幀夷都,你可以理解為這一幀畫面的完整保留眷唉;解碼時只需要本幀數(shù)據(jù)就可以完成(因為包含完整畫面)

I 幀的特點:

  • a. 它是一個全幀壓縮編碼幀,它將全幀圖像信息進行JPEG壓縮編碼及傳輸

  • b. 解碼時僅用I 幀的數(shù)據(jù)就可重構(gòu)完整圖像

  • c. I 幀描述了圖像背景和運動主體的詳情

  • d. I 幀不需要參考其他畫面而生成

  • e. I 幀是P幀和B幀的參考幀(其質(zhì)量直接影響到同組中以后各幀的質(zhì)量)

  • f. I 幀不需要考慮運動矢量

  • g. I 幀所占數(shù)據(jù)的信息量比較大

P幀:前向預測編碼幀冬阳。P幀表示的是這一幀跟之前的一個關(guān)鍵幀(或P幀)的差別蛤虐,解碼時需要之前緩存的畫面疊加上本幀定義的差別,生成最終畫面摩泪。(也就是差別幀笆焰,P幀沒有完整畫面數(shù)據(jù),只有與前一幀的畫面差別的數(shù)據(jù))

? P幀的預測與重構(gòu):P幀是以 I 幀為參考幀见坑,在 I 幀中找出P幀“某點”的預測值和運動矢量嚷掠,取預測差值和運動矢量一起傳送。在接收端根據(jù)運行矢量從 I 幀找出P幀“某點”的預測值并與差值相加以得到P幀“某點”樣值荞驴,從而可得到完整的P幀不皆。

P幀的特點:

  • a. P幀是 I 幀后面相隔1~2幀的編碼幀

  • b. P幀采用運動補償?shù)姆椒▊魉退c前面的I或P幀的差值及運動矢量(預測誤差)

  • c. 解碼時必須將幀中的預測值與預測誤差求和后才能重構(gòu)完整的P幀圖像

  • d. P幀屬于前向預測的幀間編碼。它只參考前面最靠近它的 I 幀或P幀

  • e. 由于P幀是參考幀熊楼,它可能造成解碼錯誤的擴散

  • f. 由于是差值傳送霹娄,P幀的壓縮比較高

3、B幀:雙向預測內(nèi)插編碼幀鲫骗。B幀是雙向差別幀犬耻,也就是B幀記錄的是本幀與前后幀的差別(具體比較復雜,有4種情況执泰,但我這樣說簡單些)枕磁,換言之,要解碼B幀术吝。不僅要取得之前的緩存畫面计济,還要解碼之后的畫面,通過前后畫面的與本幀數(shù)據(jù)的疊加取得最終的畫面排苍。B幀壓縮率高沦寂,但是解碼時CPU會比較累。

B幀的預測與重構(gòu)

? B幀以前面的 I 或P幀和后面的P幀為參考幀淘衙,“找出”B幀“某點”的預測值和兩個運動矢量传藏,并取預測差值和運動矢量傳送。接收端根據(jù)運動矢量在兩個參考幀中“找出(算出)”預測值并與差值求和幔翰,得到B幀“某點”樣值漩氨,從而可得到完整的B幀。

B幀的特點:

  • a. B幀是由前面的 I 或P幀和后面的P幀進行預測的

  • b. B幀傳送的是它與前面的 I 或P幀和后面的P幀之間的預測誤差及運動矢量

  • c. B幀是雙向預測編碼幀

  • d. B幀壓縮比最高遗增,因為它只反映并參考幀間運動主體的變化情況,預測比較準確

  • e. B幀不是參考幀款青,不會造成解碼錯誤的擴散

注:I做修、B、P幀是根據(jù)壓縮算法的需要,是人為定義的饰及,他們都是實實在在的物理幀蔗坯。
一般來說,幀的壓縮率是7(跟JPG差不多)燎含,
P幀是20宾濒,B幀可以達到50.可見使用B幀能節(jié)省大量空間,
節(jié)省出來的空間可以用來保存多一些幀屏箍,這樣在相同碼率下绘梦,可以提供更好的畫質(zhì)。

1.2 壓縮算法的說明

h264的壓縮方法

  • 1赴魁、分組:把幾幀圖像分為一組(GOP卸奉,也就是一個序列),為防止運動變化颖御,幀數(shù)不宜取多
  • 2榄棵、定義幀:將每組內(nèi)各幀圖像定義為三種類型,即 I 幀潘拱、B幀和P幀
  • 3疹鳄、預測幀:以幀作為基礎幀,以幀預測P幀芦岂,再由 I 幀和P幀預測B幀
  • 4瘪弓、數(shù)據(jù)傳輸:最后將 I 幀數(shù)據(jù)與預測的差值信息進行存儲和傳輸

? 幀內(nèi)(Intraframe)壓縮也稱為空間壓縮(Spatial compression)。當壓縮一幀圖像時盔腔,僅考慮本幀的數(shù)據(jù)而不考慮相鄰幀之間的冗余信息杠茬,這實際上與靜態(tài)圖像壓縮類似。幀內(nèi)一般采用有損壓縮算法弛随,由于幀內(nèi)壓縮是編碼一個完整的圖像瓢喉,因此可以獨立的解碼、顯示舀透。幀內(nèi)壓縮一般達不到很高的壓縮栓票,跟編碼jpeg差不多。

? 幀間(Interframe)壓縮的原理是:相鄰幾幀的數(shù)據(jù)有很大的相關(guān)性愕够,或者說前后兩幀信息變化很小的特點走贪,也即連續(xù)的視頻及其相鄰幀之間具有冗余信息,根據(jù)這一特性惑芭,壓縮相鄰幀之間的冗余量就可以進一步提高壓縮量坠狡,減少壓縮比。幀間壓縮也稱為時間壓縮遂跟,它通過比較時間軸上不同幀之間的數(shù)據(jù)進行壓縮逃沿。幀間壓縮一般是無損的婴渡。幀差值(Frame differencing)算法是一種典型的時間壓縮發(fā),它通過比較本幀與相鄰幀之間的差異凯亮,僅記錄本幀與其相鄰幀的差值边臼,這樣可以大大減少數(shù)據(jù)量。

? 順便說下有損(Lossy)壓縮和無損(Lossy less)壓縮假消。無損壓縮也即壓縮前和解壓縮后的數(shù)據(jù)完全一致柠并。多數(shù)的無損壓縮都采用RLE行程編碼算法。有損壓縮意味著解壓縮后的數(shù)據(jù)與壓縮前的數(shù)據(jù)不一致富拗。在壓縮的過程中要丟失一些人眼和耳朵所不敏感的圖像或音頻信息臼予,而且丟失的信息不可恢復。幾乎所有高壓縮的算法都采用有損壓縮媒峡,這樣才能達到低數(shù)據(jù)率的目標瘟栖。丟失的數(shù)據(jù)率與壓縮比有關(guān),壓縮比越小谅阿,丟失的數(shù)據(jù)越多半哟,解壓縮后的效果一般越差。此外签餐,某些有損壓縮算法采用多次重復壓縮的方式寓涨,這樣還會引起額外的數(shù)據(jù)丟失。


2 手寫H264編碼器

要徹底理解視頻編碼原理氯檐,看書都是虛的戒良,需要實際動手,實現(xiàn)一個簡單的視頻編碼器:

知識準備:基本圖像處理知識冠摄,信號的時域和頻域問題糯崎,熟練掌握傅立葉正反變換,一維河泳、二維傅立葉變換沃呢,以及其變種,dct變換拆挥,快速dct變換薄霜。

2.1.1 第一步:實現(xiàn)有損圖像壓縮和解壓
參考 JPEG原理,將RGB->YUV纸兔,然后Y/U/V看成三張不同的圖片惰瓜,將其中一張圖片分為 8x8的block進行 dct變換(可以直接進行二維dct變換,或者按一定順序?qū)?x8的二維數(shù)組整理成一個64字節(jié)的一維數(shù)組)汉矿,還是得到一個8x8的整數(shù)頻率數(shù)據(jù)崎坊。于是表示圖像大輪廓的低頻信號(人眼敏感的信號)集中在 8x8的左上角;表示圖像細節(jié)的高頻信號集中在右下角洲拇。

? 接著將其量化流强,所謂量化痹届,就是信號采樣的步長呻待,8x8的整數(shù)頻率數(shù)據(jù)塊打月,每個數(shù)據(jù)都要除以對應位置的步長,左上角相對重要的低頻信號步長是1蚕捉,也就是說0-255奏篙,是多少就是多少。而右下角是不太重要的高頻信號迫淹,比如步長取10秘通,那么這些位置的數(shù)據(jù)都要/10,實際解碼的時候再將他們10恢復出來敛熬,這樣經(jīng)過編碼的時候/10和解碼的時候10肺稀,那么步長為10的信號1, 13, 25, 37就會變成規(guī)矩的:0, 10, 20, 30, 對小于步長10的部分我們直接丟棄了,因為高頻不太重要应民。

? 經(jīng)過量化以后话原,8x8的數(shù)據(jù)塊左上角的數(shù)據(jù)由于步長小,都是比較離散的诲锹,而靠近右下角的高頻數(shù)據(jù)繁仁,都比較統(tǒng)一,或者是一串0归园,因此圖像大量的細節(jié)被我們丟棄了黄虱,這時候,我們用無損壓縮方式庸诱,比如lzma2算法(jpeg是rle + huffman)將這64個byte壓縮起來捻浦,由于后面高頻數(shù)據(jù)步長大,做了除法以后桥爽,這些值都比較小朱灿,而且比較靠近,甚至右下部分都是一串0聚谁,十分便于壓縮母剥。

? JPEG圖像有個問題就是低碼率時 block邊界比較嚴重,現(xiàn)代圖片壓縮技術(shù)往往要配合一些de-block算法形导,比如最簡單的就是邊界部分幾個像素點和周圍插值模糊一下环疼。

做到這里我們實現(xiàn)了一個同 jpeg類似的靜態(tài)圖片有損壓縮算法。在視頻里面用來保存I幀數(shù)據(jù)朵耕。

?

2.1.2 第二步:實現(xiàn)宏塊誤差計算

? 視頻由連續(xù)的若干圖像幀組成炫隶,分為 I幀,P幀阎曹,所謂I幀伪阶,就是不依賴就可以獨立解碼的視頻圖像幀煞檩,而P幀則需要依賴前面已解碼的視頻幀,配合一定數(shù)據(jù)才能生成出來栅贴。所以視頻中I幀往往都比較大斟湃,而P幀比較小,如果播放器一開始收到了P幀那么是無法播放的檐薯,只有收到下一個I幀才能開始播放凝赛。I幀多了視頻就變大,I幀少了坛缕,數(shù)據(jù)量是小了墓猎,但視頻受到丟包或者數(shù)據(jù)錯誤的影響卻又會更嚴重。

? 那么所謂運動預測編碼赚楚,其實就是P幀的生成過程:繼續(xù)將圖片分成 16x16的block(為了簡單只討論yuv的y分量壓縮)毙沾。I幀內(nèi)部單幀圖片壓縮我們采用了8x8的block,而這里用16x16的block來提高幀間編碼壓縮率(當然也會有更多細節(jié)損失)宠页,我們用 x, y表示像素點坐標左胞,而s,t表示block坐標,那么坐標為(x,y)的像素點所屬的block坐標為:

s = x / 16 = x >> 4
t = y / 16 = y >> 4

? 接著要計算兩個block的相似度勇皇,即矢量的距離罩句,可以表示為一個256維矢量(16x16)像素點色彩距離的平方,我們先定義兩個顏色的誤差為:

PixelDiff(c1, c2) = (c1- c2) ^ 2

? 那么256個點的誤差可以表示為所有對應點的像素誤差和:

BlockDiff(b1, b2) = sum( PixelDiff(c1, c2) for c1 in b1 for c2 in b2)

代碼化為:

int block_diff(const unsigned char b1[16][16], const unsigned char b2[16][16]) {
    int sum = 0;
    for (int i = 0; i < 16; i++) {
         for (int j = 0; j < 16; j++) {
              int c1 = b1[i][j];
              int c2 = b2[i][j];
              sum += (c1 - c2) * (c1 - c2);
         }
    }
    return sum;
}

有了這個block求差的函數(shù)敛摘,我們就可以針對特定block门烂,搜索另外若干個block中哪個和它最相似了(誤差最小)兄淫。

1.2.3 第三步:實現(xiàn)運動預測編碼

? 根據(jù)上面的宏塊比較函數(shù)屯远,你已經(jīng)可以知道兩個block到底像不像了,越象的block捕虽,block_diff返回值越低慨丐。那么我們有兩幀相鄰的圖片,P1泄私,P2房揭,假設 P1已經(jīng)完成編碼了,現(xiàn)在要對 P2進行P幀編碼晌端,其實就是輪詢 P2里面的每一個 block捅暴,為P2中每一個block找出上一幀中相似度最高的block坐標,并記錄下來咧纠,具體偽代碼可以表示為:

unsigned char block[16][16];
for (int t = 0; t <= maxt; t++) {
    for (int s = 0; s <= maxs; s++) {
         picture_get_block(P2, s * 16, t * 16, block); // 取得圖片 P2 的 block
         int x, y;
         block_search_nearest(P1, &x, &y, block); // 在P1中搜索最相似的block
         output(x, y);  // 將P1中最相似的block的左上角像素坐標 (x, y) 輸出
    }
}

? 其中在P1中搜索最相似 block的 block_search_nearest 函數(shù)原理是比較簡單的蓬痒,我們可以暴力點用兩個for循環(huán)輪詢 P1中每個像素點開始的16x16的block(速度較慢),當然實際中不可能這么暴力搜索漆羔,而是圍繞P2中該block對應坐標在P1中位置作為中心梧奢,慢慢四周擴散狱掂,搜索一定步長,并得到一個 :按照一定順序進行搜索亲轨,并且在一定范圍內(nèi)最相似的宏塊坐標趋惨。 。

于是P2進行運動預測編碼的結(jié)果就是一大堆(x,y)的坐標瓶埋,代表P2上每個block在上一幀P1里面最相似的 block的位置希柿。反過來說可能更容易理解,我們可以把第三步整個過程定義為:

怎么用若干 P1里不同起始位置的block拼湊出圖片P2來养筒,使得拼湊以后的結(jié)果和P2最像。

1.2.4 第四步:實現(xiàn)P幀編碼

? 拼湊的結(jié)果就是一系列(x,y)的坐標數(shù)據(jù)端姚,我們繼續(xù)用lzma2將它們先壓縮起來晕粪,按照 vcd的分辨率

352 x 240,我們橫向需要 352 / 16 = 22個block渐裸,縱向需要 240 / 16 = 15 個block巫湘,可以用 P1中 22 x 15 = 330

個 block的坐標信息生成一張和P2很類似的圖片 P2' :

for (int t = 0; t < 15; t++) {
    for (int s = 0; s < 22; s++, next++) {
         int x = block_positions[next].x;   // 取得對應 P1上的 block像素位置 x
         int y = block_positions[next].y;   // 取得對應 P1上的 block像素位置 y
         // 將 P1位置(x,y)開始的 16 x 16 的圖塊拷貝到 P2'的 (s * 16, t * 16)處
         CopyRect(P2', s * 16, t * 16, P1, x, y, 16, 16); 
    }
}

    我們把用來生成P2的P1稱為 P2的 “參考幀”,再把剛才那一堆P1內(nèi)用來拼成P2的 block坐標稱為 “**運動矢量**”昏鹃,這是P幀里面最主要的數(shù)據(jù)內(nèi)容尚氛。但是此時由P1和這些坐標數(shù)據(jù)拼湊出來的P2,你會發(fā)現(xiàn)粗看和P2很象洞渤,但細看會發(fā)現(xiàn)有些支離破碎阅嘶,并且邊緣比較明顯,怎么辦呢载迄?我們需要第四步讯柔。

1.2.5第五步:實現(xiàn)P幀編碼
    有了剛才的運動預測矢量(一堆block的坐標),我們先用P1按照這些數(shù)據(jù)拼湊出一張類似 P2的新圖片叫做P2'护昧,然后同P2上每個像素做減法魂迄,得到一張保存 differ的圖片: 

D2 = (P2 - P2') / 2

? 誤差圖片 D2上每一個點等于 P2上對應位置的點的顏色減去 P2'上對應位置的點的顏色再除以2,用8位表示差值惋耙,值是循環(huán)的捣炬,比如-2就是255,這里一般可以在結(jié)果上 + 0x80绽榛,即 128代表0湿酸,129代表2,127代表-2蒜田。繼續(xù)用一個 8位的整數(shù)可以表示 [-254, 254] 之間的誤差范圍稿械,步長精度是2。

? 按照第三步實現(xiàn)的邏輯冲粤,P2'其實已經(jīng)很像P2了美莫,只是有些誤差页眯,我們將這些誤差保存成了圖片D2,所以圖片D2中厢呵,信息量其實已經(jīng)很小了窝撵,都是些細節(jié)修善,比起直接保存一張完整圖片熵要低很多的襟铭。所以我們將 D2用類似第一步提到的有損圖片壓縮方法進行編碼碌奉,得到最終的P幀數(shù)據(jù):

Encode(P2) = Lzma2(block_positions) + 有損圖像編碼(D2)

? 具體在操作的時候,D2的圖像塊可以用16x16進行有損編碼寒砖,因為前面的運動預測數(shù)據(jù)是按16x16的宏塊搜索的赐劣,而不用象I幀那樣精確的用8x8表示,同時保存誤差圖時哩都,量化的精度可以更粗一些用不著象I幀那么精確魁兼,可以理解成用質(zhì)量更低的JPEG編碼,按照16x16的塊進行編碼漠嵌,加上誤差圖D2本來信息量就不高咐汞,這樣的保存方式能夠節(jié)省不少空間。

?

1.2.6 第六步:實現(xiàn)GOP生成

? 通過前面的代碼儒鹿,我們實現(xiàn)了I幀編碼和P幀編碼化撕,P幀是參考P1對P2進行編碼,而所謂B幀约炎,就是參考 P1和 P3對P2進行編碼植阴,當然間隔不一定是1,比如可以是參考P1和P5對P2進行編碼章钾,前提條件是P5可以依賴P1及以前的數(shù)據(jù)進行解碼墙贱。

? 不過對于一個完整的簡版視頻編碼器,I幀和P幀編碼已經(jīng)夠了贱傀,市面上任然有很多面向低延遲的商用編碼器是直接干掉B幀的惨撇,因為做實時傳輸時收到B幀沒法播放,之后再往后好幾幀收到下一個I或者P幀時府寒,先前收到的B幀才能被解碼出來魁衙,造成不少的延遲。

? 而所謂的 GOP (Group of picture) 就是由一系列類似 I, P, B, B, P, B, B, P, B, B P 組成的一個可以完整被解碼出來的圖像組株搔,而所謂視頻文件剖淀,就是一個接一個的GOP,每個GOP由一個I幀開頭纤房,然后接下來一組連續(xù)的P 或者 B構(gòu)成纵隔,播放時只有完整收到下一個GOP的I幀才能開始播放。

    最后是關(guān)于參考幀選擇,前面提到的 P2生成過程是參考了 P1捌刮,假設一個GOP中十張圖片碰煌,是 I1, P1, P2, P3, P4, ... P9 保存的,如果P1參考I1绅作,P2參考P1, P3參考P2 .... P9參考P8這樣每一個P幀都是參考上一幀進行編碼的話芦圾,誤差容易越來越大,因為P1已經(jīng)引入一定誤差了俄认,P2在P1的基礎上誤差更大个少,到了P9的話,圖片質(zhì)量可能已經(jīng)沒法看了眯杏。 

? 因此正確的參考幀選擇往往不需要這樣死板夜焦,比如可以P1-P9全部參考I1來生成,或者役拴,P1-P4參考I1來生成糊探,而P5-P9則參考P5來生成,這樣步子小點河闰,誤差也不算太離譜。

1.2.7 第七步:容器組裝

? 我們生成了一組組編碼過的GOP了褥紫,這時候需要一定的文件格式將他們恰當?shù)谋4嫦聛斫裕涗浺曨l信息,比如分辨率髓考,幀率部念,時間索引等,就是一個類似MP4(h.264的容器)文件的東西氨菇。至此一個簡單的小型編碼器我們已經(jīng)完成了儡炼,可以用 SDL / DirectX / OpenGL 配合實現(xiàn)一個播放器,愉快的將自己編碼器編碼的視頻播放出來查蓉。

1.2.8第八步:優(yōu)化改進

? 這時候你已經(jīng)大概學習并掌握了視頻編碼的基礎原理了乌询,接下來大量的優(yōu)化改進的坑等著你去填呢。優(yōu)化有兩大方向豌研,編碼效率優(yōu)化和編碼性能優(yōu)化:前者追求同質(zhì)量(同信噪比)下更低的碼率妹田,后者追求同樣質(zhì)量和碼率的情況下,更快的編碼速度鹃共。

? 有這個基礎后接下來可以回過頭去看JPEG標準鬼佣,MPEG1-2標準,并閱讀相關(guān)實現(xiàn)代碼霜浴,你會發(fā)現(xiàn)簡單很多了晶衷,接著肯H.264代碼,不用全部看可以針對性的了解以下H.264的I幀編碼和各種搜索預測方法,有H.264的底子晌纫,你了解 HEVC和 vpx就比較容易了税迷。

? 參考這些編碼器一些有意思的實現(xiàn)來改進自己的編碼器,試驗性質(zhì)缸匪,可以側(cè)重原理翁狐,各種優(yōu)化技巧了解下即可,本來就是hack性質(zhì)的凌蔬。

有卯用呢露懒?首先肯定很好玩,其次砂心,當你有需要使用并修改這些編碼器為他們增加新特性的時候懈词,你會發(fā)現(xiàn)前面的知識很管用了。

------有朋友說光有代碼沒有圖片演示看不大明白辩诞,好我們補充一下圖片演示:

1.3 畫面演示

  1. 3.1 這是第一幀畫面:P1(我們的參考幀)
image

這是第二幀畫面:P2(需要編碼的幀)

image

從視頻中截取的兩張間隔1-2秒的畫面坎弯,和實際情況類似,下面我們進行幾次運動搜索:

1.3.2 搜索演示1:搜索P2中車輛的車牌在P1中最接近的位置(上圖P1译暂,下圖P2)
image

這是一個演示程序抠忘,鼠標選中P2上任意16x16的Block,即可搜索出P1上的 BestMatch 宏塊外永。雖然車輛在運動崎脉,從遠到近,但是依然找到了最接近的宏塊坐標伯顶。

1.3.3 搜索演示2:空中電線交叉位置(上圖P1囚灼,下圖P2)
image
1.3.3 搜索演示3:報刊停的廣告海報
image

同樣順利在P1中找到最接近P2里海報的宏塊位置。

圖片全搜索:根據(jù)P1和運動矢量數(shù)據(jù)(在P2中搜索到每一個宏塊在P1中最相似的位置集合)還原出來的P2'祭衩,即完全用P1各個位置的宏塊拼湊出來最像P2的圖片P2'灶体,效果如下:

image

仔細觀察,有些支離破碎對吧掐暮?肯定啊蝎抽,拼湊出來的東西就是這樣,現(xiàn)在我們用P2`和P2像素相減劫乱,得到差分圖 D2 = (P2' - P2) / 2 + 0x80:

image

嗯织中,這就是P2`和P2兩幅圖片的不同處,看到?jīng)]衷戈?基本只有低頻了狭吼!高頻數(shù)據(jù)少到我們可以忽略,這時用有損壓縮方式比較差的效果來保存誤差圖D2殖妇,只要5KB的大小刁笙。
接著我們根據(jù)運動矢量還原的 P2'及差分圖D2來還原新的 P2,NewP2 = P2' + (D2 - 0x80) * 2:

image

? 這就是之前支離破碎的 P2` 加上誤差 D2之后變成了清晰可見的樣子,基本還原了原圖P2疲吸。
? 由于D2僅僅占5KB座每,加上壓縮過后的運動矢量不過7KB,

? 所以參考P1我們只需要額外 7KB的數(shù)據(jù)量就可以完整表示P2了摘悴,而如果獨立將P2用質(zhì)量尚可的有損壓縮方式獨立壓縮峭梳,則至少要去到50-60KB,這一下節(jié)省了差不多8倍的空間蹂喻,正就是所謂運動編碼的基本原理葱椭。

再者誤差我們保存的是(P2-P2’)/2 + 0x80,實際使用時我們會用更有效率的方式口四,比如讓[-64,64]之間的色差精度為1孵运,[-255,-64], [64, 255] 之間的色差精度為2-3,這樣會更加真實一些蔓彩。

? 現(xiàn)代視頻編碼中治笨,除了幀間預測,I幀還使用了大量幀內(nèi)預測赤嚼,而不是完全dct量化后編碼旷赖,前面幀間預測我們使用了參考幀的宏塊移動拼湊新幀的方式進行,而所謂幀內(nèi)預測就是同一幅畫面中更卒,未編碼部分使用已編碼部分拼湊而成杠愧。。逞壁。。锐锣。腌闯。油吭。

H264是新一代的編碼標準阳距,以高壓縮高質(zhì)量和支持多種網(wǎng)絡的流媒體傳輸著稱在編碼方面,

后續(xù):

轉(zhuǎn)發(fā)自:http://www.reibang.com/p/cf537a4a154a

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豹悬,一起剝皮案震驚了整個濱河市斤彼,隨后出現(xiàn)的幾起案子分瘦,更是在濱河造成了極大的恐慌,老刑警劉巖琉苇,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘲玫,死亡現(xiàn)場離奇詭異,居然都是意外死亡并扇,警方通過查閱死者的電腦和手機去团,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人土陪,你說我怎么就攤上這事昼汗。” “怎么了鬼雀?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵顷窒,是天一觀的道長。 經(jīng)常有香客問我源哩,道長鞋吉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任璧疗,我火速辦了婚禮坯辩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘崩侠。我一直安慰自己漆魔,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布却音。 她就那樣靜靜地躺著改抡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪系瓢。 梳的紋絲不亂的頭發(fā)上阿纤,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音夷陋,去河邊找鬼欠拾。 笑死,一個胖子當著我的面吹牛骗绕,可吹牛的內(nèi)容都是我干的藐窄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼酬土,長吁一口氣:“原來是場噩夢啊……” “哼荆忍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撤缴,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤刹枉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后屈呕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體微宝,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年凉袱,在試婚紗的時候發(fā)現(xiàn)自己被綠了芥吟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侦铜。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钟鸵,靈堂內(nèi)的尸體忽然破棺而出钉稍,到底是詐尸還是另有隱情,我是刑警寧澤棺耍,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布贡未,位于F島的核電站,受9級特大地震影響蒙袍,放射性物質(zhì)發(fā)生泄漏俊卤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一害幅、第九天 我趴在偏房一處隱蔽的房頂上張望消恍。 院中可真熱鬧,春花似錦以现、人聲如沸狠怨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽佣赖。三九已至,卻和暖如春记盒,著一層夾襖步出監(jiān)牢的瞬間憎蛤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工纪吮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俩檬,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓碾盟,卻偏偏與公主長得像豆胸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子巷疼,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345