檔案包含3部分,2個LIST(必須包括) + 1個索引(可選)。
RIFF ('AVI '
LIST ('hdrl' ... )
LIST ('movi' ... )
['idx1' (<AVI Index>) ]
)
LIST1 hdrl 可以了解為檔案的頭資訊
LIST2 movi 為實際音視訊資料。
進一步細分的結構為:
RIFF ('AVI '
LIST ('hdrl'
'avih'(<Main AVI Header>)
LIST ('strl'
'strh'(<Stream header>)
'strf'(<Stream format>)
[ 'strd'(<Additional header data>) ]
[ 'strn'(<Stream name>) ]
...
)
...
)
LIST ('movi'
{SubChunk | LIST ('rec '
SubChunk1
SubChunk2
...
)
...
}
...
)
['idx1' (<AVI Index>) ]
)
1) LIST ‘hdrl’ 檔案頭資訊 ‘avih’ AVI檔案的主要頭資訊,包含整個AVI檔案的全局資訊。内容為:
typedef struct _avimainheader {
FOURCC fcc; 固定為 ’avih’
DWORD cb; 該結構體的大小,不包含開始的8個位元組
DWORD dwMicroSecPerFrame; 相鄰幀 間隔微秒數
DWORD dwMaxBytesPerSec; 檔案最大資料率,機關位元組
DWORD dwPaddingGranularity; 對齊格式,如字對齊 ,8位元組對齊,機關位元組
DWORD dwFlags; 一些辨別
DWORD dwTotalFrames; 總幀數
DWORD dwInitialFrames; 對于音視訊交叉存取檔案,該值為視訊前面音頻幀數(至少可以播放0.75秒的音頻);否則為0;
DWORD dwStreams; 音視訊流總路數;
DWORD dwSuggestedBufferSize; 建議緩沖大小,應該大于檔案中最大chunk,配置設定太小,或設定為0,這樣将由播放器來裁決,可能會影響性能。
DWORD dwWidth; 視訊寬,機關pixel
DWORD dwHeight;
DWORD dwReserved[4]; 保留位,為0
}
AVIMAINHEADER;
‘strl’音視訊流清單,有1個流,就有一個對應的strl.
‘strh’描述流資訊
typedef struct _avistreamheader {
FOURCC fcc; ‘strh’
DWORD cb; 同上
FOURCC fccType; 用來區分音視訊流,如表1所示
FOURCC fccHandler; 可選,表明codec
DWORD dwFlags; 一些辨別,AVISF_DISABLED和調色闆辨別。
WORD wPriority; 流的優先級,隻有同一類型的流,有多個時,優先級高的為預設流。
WORD wLanguage;
DWORD dwInitialFrames; 同dwInitialFrames
DWORD dwScale; 時間基準,如30000, 90000
DWORD dwRate; 對于視訊dwRate/dwScale 為幀率,對于PCM音頻為采樣率。
DWORD dwStart; 流開始時間。通常為0,除非檔案打開後有延時。
DWORD dwLength; 尚未弄明白。
DWORD dwSuggestedBufferSize; 給解碼器用的建議緩沖大小
DWORD dwQuality; 傳給壓縮軟體的品質值為0-10000間數,寫為-1時,使用預設品質值。
DWORD dwSampleSize; 樣本大小,對于視訊來講就是該幀資料大小,如果每個樣本大小相同可以多個樣本放在1起,否則需要分開放。不然區分不出來了。
struct {
short int left;
short int top;
short int right;
short int bottom;
} rcFrame; 支援多個視訊流時,才會起到真正作用,否則和dwWidth等值一緻。
}
AVISTREAMHEADER;表1:fccType
FOURCC | Description |
'auds' | Audio stream |
'mids' | MIDI stream |
'txts' | Text stream |
'vids' | Video stream |
:流格式
描述流資料格式,對于視訊流為
BITMAPINFO結構體内容,個人覺得此處如果為類似DIVX壓縮格式的視訊的話,就不是這個結構體了。對于音頻流為WAVEFORMATEX結構體。
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} WAVEFORMATEX;
對于’strd’和’strn’與編解碼器的驅動器有關,對于AVI檔案讀寫是不需要的。
以上講述内容執行個體如圖1所示。使用Hex WorkShop打開1個AVI檔案你就會看到類似圖1資訊。
圖1 檔案頭資訊示例
2) LIST ‘movi’ 檔案資料部分音視訊實際資料可以直接放在list中或者成批量放到List rec中,在每一個樣本前面會有1個資料類型辨別用來區分是哪一個流,其格式為 stream num + type
其中 資料流序号是按照資料流在檔案中的先後順序定義的,先後次序該值依次為 00 01 02….; type 如表2所示
表2:資料類型
db | Uncompressed video frame |
dc | Compressed video frame |
pc | Palette change |
wb | Audio data |
例如:音視訊流AVI檔案,音頻在前,則音頻資料前的辨別符為: 00wb, 壓縮資料前面的為 01dc。
緊跟其後的為 資料長度+實際資料
3) 索引用來表示每個資料塊在檔案的位置。
typedef struct _avioldindex {
FOURCC fcc;
DWORD cb;
struct _avioldindex_entry {
DWORD dwChunkId;
DWORD dwFlags;
DWORD dwOffset;
DWORD dwSize;
} aIndex[];
} AVIOLDINDEX;
歡迎大家一起讨論,目前AVI如何封裝mp4我還是不太明白,和以上格式有和差別?
L