【H264/AVC 句法和語義詳解】(二):h264碼流格式與NALU詳解一

本篇隸屬于文集:《H264/AVC 句法和語義詳解》幻林,查看文集全部文章音念,請點擊文字鏈接。
想看最新文章整葡,可以直接關(guān)注微信公眾號:金架構(gòu)

上一篇中遭居,我們站在句法元素(或稱語法元素)的角度旬渠,介紹了H.264的句法和語義,和句法元素的分層結(jié)構(gòu)鼠次。在這篇中腥寇,我們更進一步,從比特的角度出發(fā)麻敌,來探索h264碼流的組成掂摔。通過這篇的學(xué)習(xí)术羔,我們會初步具備解析h264碼流的能力,從碼流中分離出NAL單元乙漓,并識別NAL類型级历。

1. H264碼流格式

不過大道始于腳下,我們還是先從頭介紹一下叭披,h264的兩種碼流格式寥殖,它們分別為:字節(jié)流格式和RTP包格式。

(1)字節(jié)流格式:這是在h264官方協(xié)議文檔中規(guī)定的格式涩蜘,處于文檔附錄B(Annex-B Byte stream format)中嚼贡。所以它也成為了大多數(shù)編碼器,默認的輸出格式粤策。它的基本數(shù)據(jù)單位為NAL單元,也即NALU误窖。為了從字節(jié)流中提取出NALU掐场,協(xié)議規(guī)定,在每個NALU的前面加上起始碼:0x000001或0x00000001(0x代表十六進制) 贩猎。

(2)RTP包格式:這種格式并沒有在h264中規(guī)定熊户,那為什么還要介紹它呢?是因為在h264的官方參考軟件JM里吭服,有這種封裝格式的實現(xiàn)嚷堡。在這種格式中,NALU并不需要起始碼Start_Code來進行識別艇棕,而是在NALU開始的若干字節(jié)(1蝌戒,2,4字節(jié))沼琉,代表NALU的長度北苟。

顯而易見,我們通常所指打瘪,以及接下來要研究的友鼻,是h264的字節(jié)流格式傻昙。由于它沒有經(jīng)過傳輸協(xié)議封裝,所以也可以稱之為裸流彩扔。比如我們打開一個妆档,經(jīng)編碼器編碼存于本地后綴為.h264文件,里面的數(shù)據(jù)即為h264裸流虫碉。

而我們接下來的研究方向贾惦,就從已經(jīng)打開了一個本地的.h264文件,然后對里面的h264裸流敦捧,按照字節(jié)流格式進行分析開始须板。所以拿到碼流的第一刻,我們需要知道兢卵,如何從中提取出NALU习瑰。

2. 起始碼與NALU

通過上面我們已經(jīng)知道:

H264比特流 = Start_Code_Prefix + NALU + Start_Code_Prefix + NALU + …

只要我們從碼流中,找到一個一個的起始碼济蝉,那么位于起始碼之間的數(shù)據(jù)杰刽,即為NALU菠发。所以拿到碼流王滤,我們需要先從頭開始,找到起始碼0x000001或0x00000001滓鸠,找到Start_Code_Prefix之后雁乡,從它之后的下一個字節(jié)開始,就是NALU的部分糜俗。

這部分的實現(xiàn)過程描述在H264官方文檔附錄B中踱稍,已經(jīng)下載的同學(xué)可以查看B.1.1節(jié):

B.1.1 字節(jié)流NAL單元語法
3. NALU

看到這一小節(jié)時,我們已經(jīng)有能力根據(jù)附錄B的內(nèi)容悠抹,從h264碼流中找出NALU珠月,所以是時候來看一下,h264碼流結(jié)構(gòu)的組成了:

NALU構(gòu)成H264碼流結(jié)構(gòu)

這就是NALU在H264碼流中的構(gòu)成了楔敌,由上圖我們也知道:

NALU = NALU Header + RBSP

這就是接下來我們要干的啤挎,分析NALU Header 和 RBSP,為了對NALU有個宏觀的認識卵凑,我們先來看一下庆聘,NALU有哪些句法元素構(gòu)成,這位于h264文檔的7.3.1節(jié):

7.3.1節(jié) NALU句法元素構(gòu)成

可以看到勺卢,整個NALU語法元素分為三部分:(1)NALU Header伙判、(3)RBSP、(2)1和3之間的部分黑忱。

其中第2部分宴抚,是近期的h264文檔才更新的勒魔,所以我特意查看了JM、x264酱塔、FFmpeg等主流編解碼器沥邻,這部分是還沒有實現(xiàn)的,所以我們可以不必理睬羊娃。而且細心的同學(xué)會發(fā)現(xiàn)唐全,只有當nal_unit_type等于14、20蕊玷、21時邮利,才會進入第二部分。

所以接下來呢垃帅,我們就重點介紹NALU Header和RBSP延届。

3.1 NALU Header

通過上面我們也可以看到,NALU Header由三個句法元素組成贸诚,分別為:forbidden_zero_bit方庭、nal_ref_idc和nal_unit_type,它們總共占據(jù)一個字節(jié)酱固,也就是說械念,NALU Header,在整個NALU中运悲,占據(jù)一個字節(jié)龄减。

而且forbidden_zero_bit的值對應(yīng)1個bit,nal_ref_idc的值對應(yīng)2個bit班眯,nal_unit_type的值對應(yīng)5個bit希停,加起來剛好一個字節(jié)。

正如在上一篇(鏈接)中所介紹的署隘,知道了句法元素宠能,我們就來分別看看它的語義:

3.1.1 forbidden_zero_bit

h264文檔規(guī)定,這個值應(yīng)該為0磁餐,當它不為0時违崇,表示網(wǎng)絡(luò)傳輸過程中,當前NALU中可能存在錯誤崖媚,解碼器可以考慮不對這個NALU進行解碼亦歉。

3.1.2 nal_ref_idc

取值0~3,代表當前這個NALU的重要性畅哑,取值越大肴楷,代表當前NALU越重要,就需要優(yōu)先被保護荠呐。尤其是當前NALU為圖像參數(shù)集赛蔫、序列參數(shù)集或IDR圖像時砂客,或者為參考圖像條帶(片/Slice),或者為參考圖像的條帶數(shù)據(jù)分割時呵恢,nal_ref_idc值肯定不為0鞠值。

而當NALU 類型,nal_unit_type為6渗钉、9彤恶、10、11鳄橘、或12時声离,nal_ref_idc都為0。

【注】IDR幀瘫怜,即:即時解碼刷新圖像术徊,它是一個序列的第一個圖像,H.264引入IDR圖像是為了解碼的重新同步鲸湃。當解碼器解碼到IDR圖像時赠涮,立即將參考幀隊列清空,將已解碼的數(shù)據(jù)全部輸出或拋棄暗挑,重新查找參數(shù)集笋除,開始一個新的序列。這樣一來窿祥,如果前一個序列發(fā)生重大錯誤株憾,在這里就可以獲得重新同步蝙寨。

所以IDR圖像之后的圖像晒衩,永遠不會引用IDR圖像之前的圖像來解碼。并且IDR圖像一定是I圖像墙歪,而I圖像不一定是IDR圖像(H264里沒有圖像層听系,圖像可以理解為幀、片或宏塊)虹菲。

3.1.3 nal_unit_type

顧名思義靠胜,這個應(yīng)該是最好理解的了,它表示NALU Header后面的RBSP的數(shù)據(jù)結(jié)構(gòu)的類型毕源。下圖為nal_unit_type所有可能的取值浪漠,和對應(yīng)的語義,它處于h264文檔7.4.1節(jié):

nal_unit_type 語義

可以看到霎褐,nal_unit_type的值為1-5時址愿,表示RBSP里面包含的數(shù)據(jù)為條帶(片/Slice)數(shù)據(jù),所以值為1-5的NALU統(tǒng)稱為VCL(視像編碼層)單元冻璃,其他的NALU則稱為非VCL NAL單元响谓。

當nal_unit_type為7時损合,代表當前NALU為序列參數(shù)集,為8時為圖像參數(shù)集娘纷。這也是我們打開.h264文件后嫁审,遇到的前兩個NALU,它們位于碼流的最前面赖晶。

而且當nal_unit_type為14-31時律适,我們可以不用理睬,目前幾乎用不到遏插。

解析完NALU Header之后擦耀,下面就開始解析RBSP了,它包含了NALU數(shù)據(jù)的主體部分涩堤,我們放在下一篇詳細介紹眷蜓。

4. 關(guān)于H.264的協(xié)議文檔

有的同學(xué)可能還沒下載H.264的官方文檔,這里我再貼一下下載地址:

全部版本胎围,下載2017最新版:

http://www.itu.int/rec/T-REC-H.264

最新版為英文版吁系,05年3月份有中文版:

http://www.itu.int/rec/T-REC-H.264-200503-S/en

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市白魂,隨后出現(xiàn)的幾起案子汽纤,更是在濱河造成了極大的恐慌,老刑警劉巖福荸,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕴坪,死亡現(xiàn)場離奇詭異,居然都是意外死亡敬锐,警方通過查閱死者的電腦和手機背传,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來台夺,“玉大人径玖,你說我怎么就攤上這事〔椋” “怎么了梳星?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滚朵。 經(jīng)常有香客問我冤灾,道長,這世上最難降的妖魔是什么辕近? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任韵吨,我火速辦了婚禮,結(jié)果婚禮上亏推,老公的妹妹穿的比我還像新娘学赛。我一直安慰自己年堆,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布盏浇。 她就那樣靜靜地躺著变丧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绢掰。 梳的紋絲不亂的頭發(fā)上痒蓬,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音滴劲,去河邊找鬼攻晒。 笑死,一個胖子當著我的面吹牛班挖,可吹牛的內(nèi)容都是我干的鲁捏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼萧芙,長吁一口氣:“原來是場噩夢啊……” “哼给梅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起双揪,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤动羽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后渔期,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體运吓,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年疯趟,在試婚紗的時候發(fā)現(xiàn)自己被綠了拘哨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡迅办,死狀恐怖宅静,靈堂內(nèi)的尸體忽然破棺而出章蚣,到底是詐尸還是另有隱情站欺,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布纤垂,位于F島的核電站矾策,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏峭沦。R本人自食惡果不足惜贾虽,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吼鱼。 院中可真熱鬧蓬豁,春花似錦绰咽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蟆技,卻和暖如春玩敏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背质礼。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工旺聚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眶蕉。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓砰粹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親造挽。 傳聞我的和親對象是個殘疾皇子伸眶,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容