首页 > 解决方案 > 德尔福MAKEFOURCC的烦恼

问题描述

我正在为这段代码苦苦挣扎:

MAKEFOURCC('R','I','F','F');

该函数是从 C++ 翻译而来的,在 Delphi 中应该是这样的:

function MAKEFOURCC(const ch0: AnsiChar;
                  const ch1: AnsiChar;
                  const ch2: AnsiChar;
                  const ch3: AnsiChar): FOURCC; inline;
  begin
    Result:= DWORD(Ord(ch0)) or
            (DWORD(Ord(ch1)) shl 8) or
            (DWORD(Ord(ch2)) shl 16) or
            (DWORD(Ord(ch3)) shl 24);
  end;

现在,这将导致 (big-endian) $46464952,这是错误的。应该是 52494646 美元。

看看微软的解释,这个宏的代码是:

#define MAKEFOURCC(ch0, ch1, ch2, ch3)  \ 
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |  \ 
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ));

颠倒 ch3、ch2、ch1 和 ch0 的顺序会得到正确的值:

Result:= DWORD(Ord(ch3)) or
         (DWORD(Ord(ch2)) shl 8) or
         (DWORD(Ord(ch1)) shl 16) or
         (DWORD(Ord(ch0)) shl 24);

现在我在这里错过了什么?提前致谢。

标签: delphidelphi-xe7

解决方案


我认为您误解了字节序对产生的 FOURCC 值的影响。

您声明 $46464952 是“错误”结果,但它是正确的结果,基于 Microsoft 此处的文档:https ://docs.microsoft.com/en-us/windows/win32/directshow/fourcc-codes

请注意,这突出了 Windows 的 little-endian 特性,因此字符串 'YUY2' 的 FOURCC 编码实际上是2YUY. 当编码为 32 位数字字节顺序时,与与字节序无关的字符串表示形式相比,字节顺序是相反的。

YUY2 的 FOURCC 编码为 $59555932,当反转为小端表示时,产生 $32595559,这是从MAKEFOURCC()您的帖子中的原始和文字实现获得的结果。

即你认为错误的结果实际上是正确的。

对特定文件格式的存储表示的要求通常独立于内存中的表示。WAV 标头(实际上通常是 FourCC 规范)需要 Big Endian 表示的事实并不会改变您的原始 MakeFourCC 实现是正确的事实。这只是意味着您在将 FourCC 存储在 WAV 标头块中时还需要反转字节。


推荐阅读