fourcc

FourCC全稱Four-Character Codes,代表四字元代碼 (four character code), 它是一個32位的標示符,其實就是typedef unsigned int FOURCC;是一種獨立標示視頻數據流格式的四字元代碼。

代碼介紹,傳統方法,

代碼介紹

視頻播放軟體通過查詢 FourCC 代碼並且尋找與 FourCC 代碼相關聯的視頻解碼器來播放特定的視頻流。比如: DIV3 = DivX Low-Motion, DIV4 = DivX Fast-Motion, DIVX = DivX4, FFDS = FFDShow 等。比如wav、avi等RIFF檔案的標籤頭標示,Quake 3的模型檔案.md3中也大量存在等於“IDP3”的FOURCC。

傳統方法

一般用宏生成FOURCC,FOURCC是由4個字元拼接而成的,生成FOURCC的傳統方法是:
#define MAKE_FOURCC(a,b,c,d) \
( ((uint32_t)d) | ( ((uint32_t)c) << 8 ) | ( ((uint32_t)b) << 16 ) | ( ((uint32_t)a) << 24 ) )
這種方法簡單直觀,可以方便使用下面一個模型操作
switch(val)
{
case MAKE_FOURCC('f','m','t',' '):
.....
break;
case MAKE_FOURCC('Y','4','4','2'):
....
break;
...
}
因為宏能生成常量,符合case 的條件。
難道要退回古老的宏?當然不是,C++的模板機制給程式設計師帶來的無限的空間,它不光能讓類型作為參數,還能將常量作為參數(這一點常常被人遺忘),而且這一切都是編譯期決定的!這是我們用它來生成FOURCC的第一個基礎。
於是,你就迫不及待的利用模板來改寫上面的函式:
template <char ch0, char ch1, char ch2, char ch3>inline FOURCC MakeFOURCC(){ return (ch0 << 0) + (ch1 << 8) + (ch2 << 16) + (ch3 << 24);}可是錯誤照舊。雖然這次可以保證返回值能在編譯期計算出來,但可惜的是那個return語句卻要等到運行才能運行(也有可能在最佳化階段就能消除這個語句,但肯定不能再編譯期就全部完成)。
別急,還有第二個基礎才可以。那是什麼?是一個從C語言繼承來的東西――enum。很多朋友認為,它不是很重要,因為很多情況下可以用別的方法來取代它,比如const。但是它有一個經常被人忽略的特性,而且這個特性非常重要,那就是――它的值必須在編譯期就得出,即它是個編譯期常量!這不是正符合我們的需要嗎?請看下面的模板:
template <char ch0, char ch1, char ch2, char ch3> struct MakeFOURCC{ enum { value = (ch0 << 0) + (ch1 << 8) + (ch2 << 16) + (ch3 << 24) }; };核心還是和上面一樣,通過表達式(ch0 << 0) + (ch1 << 8) + (ch2 << 16) + (ch3 << 24)計算FOURCC(那當然是一樣的)。但是計算的時機從運行期或者最佳化期移到了編譯期。編譯器在編譯時,通過模板帶入的char常量計算出表達式的值,並把它保存在枚舉值value里。看看現在的代碼:
const FOURCC fccFMT = MakeFOURCC<'f', 'm', 't', ' '>::value;const FOURCC fccDATA = MakeFOURCC<'d', 'a', 't', 'a'>::value;...switch (val){case fccFMT: ... break;case fccDATA: ... break; ...}成功了,MakeFOURCC模板順利地完成了任務。FOURCC的模板生成法既讓我們拋棄了那個不安全的宏,又讓我們看到了inline的局限性,還讓我們重新認識了enum的一些特性。其它許多類似的問題也能通過template + enum來解決。

相關詞條

熱門詞條

聯絡我們