avc格式
前面寫了flv文件的解析,有h264裸流的話就開始封裝吧。網上大多數都是用ffmeg庫來做這個工作的,哎,學習資料少學不會,還是自己動手吧。
封裝前要先了解下h.264格式,只需要知道一點點就可以了,我看了h.264官方文檔,我靠,3百多頁,還全是中文,什么,是中文?既然是中文的我就勉強看下吧,我靠,看起來還很復雜的,果斷不看了,不需要,也沒時間,我又不做解碼,這東西具體步驟資料又少,基本都是那一兩篇轉來轉去,這還要感謝我上一篇提到的那個連接的兄弟,記錄下過程,不然以后就忘干凈了。 ? h264是一個個NALU單元組成的,每個單元以00 00 01 或者 00 00 00 01分隔開來,每2個00 00 00 01之間就是一個NALU單元。我們實際上就是將一個個NALU單元封裝進FLV文件。 每個NALU單元開頭第一個byte的低5bits表示著該單元的類型,即NAL nal_unit_type: #define NALU_TYPE_SLICE 1#define NALU_TYPE_DPA 2
#define NALU_TYPE_DPB 3
#define NALU_TYPE_DPC 4
#define NALU_TYPE_IDR 5
#define NALU_TYPE_SEI 6??????????
#define NALU_TYPE_SPS 7
#define NALU_TYPE_PPS 8
#define NALU_TYPE_AUD 9 #define NALU_TYPE_EOSEQ 10
#define NALU_TYPE_EOSTREAM 11
#define NALU_TYPE_FILL 12 每個NALU第一個byte & 0x1f 就可以得出它的類型,比如上圖第一個NALU:67 & 0x1f = 7,則此單元是SPS,第三個:68 & 0x1f = 8,則此單元是PPS。 ? 前一章說到如果數據是AAC或者AVC的話,則有一個音頻和視頻的配置信息需要寫入前兩個tag(metadata之后),AAC音頻就不說了,在ISO-14496-3 Audio?中有描述,給一張圖。 ? 說下AVC視頻流的configuretion,ISO-14496-15 AVC file format?有詳細描述,先給兩張圖,一張是說明,一張是實際截圖。 ? 這個例子是對應我第一個截圖來的,一般h264數據最開始的兩個NALU就是PSP和PPS,但是我現在還沒有明白為什么我的那個h264裸流在開始的時候會有兩個SPS、PPS,而且之后數據還會不時的出現,但是我沒有管這個,依然只各弄了一個進去,其他的忽略掉了,反正多余的我都忽略了,也沒發現有什么錯。反正首先把音視頻的配置信息封進metadata之后的tag,然后就可以封數據了。再說下元數據,flv header之后就是它了,再之后就是音視頻配置信息,再后面就是音視頻數據,元數據前一章說了是amf格式的,安格式封就行了,測試其實沒有元數據視頻也可以正常播放,等會再簡單說下amf吧。 ? ? 現在開始封裝h264數據吧,前一章提到了flv關于AVC的格式,除開元數據,其他數據是:一個byte的video信息+一個byte的AVCPacket type+3個bytes的無用數據(composition time,當AVC時無用,全是0)+ 4個bytes的NALU單元長度 + N個bytes的NALU數據,所以包頭數據長度信息是剛才提到的信息的總和長度。要強調下,當音視頻配置信息tag的時候,是沒有4個bytes的NALU單元長度的。 AVC的配置信息時,先上一個圖, 17 -- 高4bits:1,keyframe。 低4bits:7,代表AVC。 后面一個byte 0x00,AVCPacket type,代表AVC sequence header。后3個bytes無意義,之后就是decoder configuration record的內容了。 圖中綠色后面 00 00 00 28就是前面tag的總長度。 ? 當NALU第一個byte xx & 0x1f == 5的時候,說明該單元是一個I frame,關鍵幀 17 -- 和上面的一樣。 01 -- AVC NALU。藍色框內的4個bytes記錄后面NALU數據的長度。65 & 0x1f == 5. ? 如果NALU第一個byte xx & 0x1f != 5的時候,就不是一個I frame 27 -- 高4bits:2,inter frame ,P frame。 低4bits:7,AVC NALU。其他都一樣。圖中綠色后面 00 00 00 28就是前面tag的總長度。 ? ? 整個的flv文件其實是:FLV header + previous tag size0 + tag1 + previous tag size1 + tag2 + previous tag size2 + ... +tagN + previous tag sizeN。 tag1是metadata,記錄視頻的一些信息;tag2是視頻配置信息(AVC?decoder configuration record),tag3是音頻配置信息(如果沒有音頻則去掉此項),tag4以及之后的tag就是音視頻數據了。 每一個結構怎么封都說清楚了,安上面的步驟一個一個NALU封就行了。 ? ? 封包的時候要特別注意一下包頭里面的時間戳,因為這個控制著播放的速度,如果不填,全是0的話,播放會相當快,一般按視頻幀率來設置。我這個h264流是8幀的,所以我每個tag的時間間隔是125ms左右。 注意了,flv里面的數據都是大端模式,放數據進去要轉換一下,如果你是通常的小端的機器的話。
總結
- 上一篇: ubuntu编译ffmpeg并且demo
- 下一篇: 自定义MVC项目02