在格式标记与子格式 GUID 之间进行转换

处理非 PCM WAVE_FORMAT_EXTENSIBLE格式的准则类似于波形格式标记指定的非 PCM 格式的准则。 具体而言,WAVE_FORMAT_EXTENSIBLE格式应具有独立于 PCM 格式的工厂的引脚工厂,并且它需要其自己的数据范围交集处理程序。

格式的音频格式WAVE_FORMAT_EXTENSIBLE由 KSDATAFORMAT 结构的 SubFormat 成员中的 GUID 指定。 每个已注册的波形格式标记都有相应的子格式 GUID,该子格式由 Ksmedia.h 中的 DEFINE_WAVEFORMATEX_GUID 宏生成。 例如,对应于 WAVE_FORMAT_DOLBY_AC3_SPDIF 标记的 GUID 定义为DEFINE_WAVEFORMATEX_GUID (WAVE_FORMAT_DOLBY_AC3_SPDIF) 。

Ksmedia.h 中的此代码片段演示如何将新的 GUID 定义为自动初始化的静态变量:

#define STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX \
 0x00000000L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
DEFINE_GUIDSTRUCT("00000000-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_WAVEFORMATEX);
#define KSDATAFORMAT_SUBTYPE_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_WAVEFORMATEX)

Ksmedia.h 中的这些宏在波形格式标记与其关联的 GUID 之间转换:

#if !defined( DEFINE_WAVEFORMATEX_GUID )
#define DEFINE_WAVEFORMATEX_GUID(x) \
    (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
#endif

#define INIT_WAVEFORMATEX_GUID(Guid, x) \
{ \
    *(Guid) = KSDATAFORMAT_SUBTYPE_WAVEFORMATEX; \
    (Guid)->Data1 = (USHORT)(x); \
}

#define IS_VALID_WAVEFORMATEX_GUID(Guid) \
    (!memcmp(((PUSHORT)&KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, \
    ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))

#define EXTRACT_WAVEFORMATEX_ID(Guid)(USHORT)((Guid)->Data1)

下面的示例代码组合了这些技术,以创建基于波形格式标记的子格式 GUID WAVE_FORMAT_AC3_SPDIF,其值为 0x0092:

#define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF \
    DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF)

DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71",
    KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF);

#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF \
    DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF)
...
INIT_WAVEFORMATEX_GUID(pMyGuid,myWaveFormatTag);
...
if (IS_VALID_WAVEFORMATEX_GUID(aWaveFormatExGuidPtr)) {
    aWaveFormatTag = EXTRACT_WAVEFORMATEX_ID(aWaveFormatExGuidPtr);
}