1. flv檔案格式相對於mp4,簡單很多。
flv header(9bytes) + flv body
a位元: 1:有音訊; 0:無音訊
'f'|'l'|'v'|0x01|0b00000a0v| 0x00 00 00 09|
| |
版本位元組一般為0x01 頭長度 固定為9
flv body由一系列的tag組成,每個tag的結構如下:
| | |...
tag_size(n) = tag_data_size(n-1) + 11
解析完乙個tag後,讀取下4個位元組,可以比較下看是不是前幀完全解碼完畢。
除了可以驗證碼流外,還有什麼樣的好處促使flv格式採用這種方式呢?不太清楚。
0x00000000| | |...
tag body也可以這樣看,編碼時按照: 資料頭 資料體 資料大小 三部分來劃分,更適合一些。下面各個tag都是按照這個結構來寫的。
tag header 11bytes
|3byte data_size資料區長度 | 純資料長度,不包括頭資訊的15位元組
|3byte timestamp 時間戳 | 最終的時間戳 = (timestamp_ex<< 24) | timestamp
|1byte timestamp_ex擴充套件時間戳 | 最終時間戳的高8位。不知道為什麼定義成這樣,可能是因為標準擴充套件
|3byte streamid | 總為0
tag data data_size位元組
|4byte previoustagsize | 是前乙個tag資料長度,第乙個tag此資料段為0.
高4位元定義幀格式:1 關鍵幀; 2 內部幀(非idr幀);3可丟棄內部幀(僅對h.263有用)
低4位元定義編碼器:2:h.263, 4: vp6, 7:h264; ...
3. 音訊tag
高4位元定義音訊編碼格式:0 linear pcm, 1: adpcm, 2: ***, 10:aac ..
第4,3兩位元定義取樣率: 0 5.5khz, 1 11khz, 2 22khz, 3 44khz. 對於aac該值總為3
第2位元定義取樣大小: 0 8位元,1 16位元
第1位元定義聲道數: 0 單聲道,1 立體聲
4. 指令碼tag
理論上不需要解析指令碼tag就可以解碼flv檔案,它只是提供了一些資訊記錄。
指令碼tag裡面的型別比較多,格式也不一樣。
number 類,記錄乙個8位元組double資料。|0x00|8位元組data|.
boolean類,記錄乙個1位元組布林型資料。|0x01|1位元組data|.
string類,記錄乙個變長字串資料。 |0x02|2位元組 字串長度 n| n位元組字串內容|.
注意讀取完字串後加乙個'\0'字串結束符號。因此字串申請的時候,長度為n+1.
ecma array type, 記錄一些資料對。
|0x08| 4位元組 陣列長度 n|2位元組 字串長度 m1 | m1位元組字串內容|1位元組 data1 type | x位元組 data1 | ...
|2位元組 字串長度 nm| nm位元組字串內容|1位元組 datan type| x位元組 datan|
有n個資料對 元素名 (長度|資料) 元素值(型別|資料)
0x0008 "duration" 0x00 8位元組double
0x0005 "width" 0x00 8位元組double
0x0006 "stereo" 0x01 1位元組boolean型
strict array type類,記錄一組資料。
|0x0a|4位元組 陣列長度 n| 1位元組 data1 type| x位元組 data1 | ...
|1位元組 datan type| x位元組 datan|
有n個資料, 每個資料的型別 資料值
一般會用這個類記錄關鍵幀的偏移位址和對應的pts值。型別都是 number類,即x=8位元組double型
object type, 記錄物件資料。一般用它來做keyframes的資料儲存起始。
5.keyframes欄位
flv沒有像mp4一樣定義stbl,flv檔案如果做快進,seek等操作會比較麻煩。
業內通用做法是在指令碼tag裡面增加keyfrmes object類。一般定義為:
|00 09| 9位元組 "keyframes"|00 0d| 13位元組 "filepositions"|0a| 4位元組關鍵字數目 n|00|8位元組 關鍵幀1偏移位址| ...
|00|8位元組 關鍵幀n偏移位址|
|00 05| 5位元組 "times" |0a| 4位元組關鍵字數目 n|00|8位元組 關鍵幀1時間| ...
|00|8位元組 關鍵幀n時間|
有了各個關鍵幀的偏移位址和時間,做seek操作的時候就方便的多。
6. 讀取8位元組double型,這個牽扯浮點型的儲存結構問題,蠻羅嗦,沒看明白,但找到下面一段**可以實現轉換。
uint64_t v = get_8bytes();
if(v+v > 0xffeull<<52) return 0.0/0.0;
double x = ldexp(((v&((1ll<<52)-1)) + (1ll<<52)) * (v>>63|1), (v>>52&0x7ff)-1075);
7. flv結構裡面,資料長度有3位元組和4位元組限制,不會像mp4一樣出現8位元組長度。
3位元組最大表示16m資料,4位元組最大是4g資料。
乙個video tag裡面的nalu長度不能超過16m位元組。
FLV檔案格式分析
flv header 一般比較簡單,包括檔案型別之類的全域性資訊,如圖 檔案型別 3bytes 總是flv 0x46 0x4c 0x56 否則.版本1byte 一般是0x01,表示flv version 1 流資訊1byte header長度 4bytes 整個檔案頭的長度,一般是9 3 1 1 4...
FLV檔案格式分析
flv header 一般比較簡單,包括檔案型別之類的全域性資訊,如圖 檔案型別 3bytes 總是flv 0x46 0x4c 0x56 否則.版本1byte 一般是0x01,表示flv version 1 流資訊1byte header長度 4bytes 整個檔案頭的長度,一般是9 3 1 1 4...
FLV檔案格式解析
flv是流 封裝格式,我們可以將其資料看為二進位制位元組流。總體上看,flv包括檔案頭 file header 和檔案體 file body 兩部分,其中檔案體由一系列的tag及tag size對組成。因此乙個flv檔案看上去是下面的結構 其中,previous tag size 緊跟在每個 tag...