注册自定义文件类型

[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayerIMFMediaEngine音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

本文介绍 Filter Graph 管理器在给定文件名的情况下如何查找源筛选器。 可以使用此机制注册自己的自定义文件类型。 注册文件类型后,每当应用程序调用 IGraphBuilder::RenderFile 或 IGraphBuilder::AddSourceFilter 时,DirectShow 将自动加载正确的源筛选器。

概述

若要从给定文件名查找源筛选器,Filter Graph 管理器将按顺序尝试执行以下操作:

  1. 匹配协议(如果有)。
  2. 匹配文件扩展名。
  3. 匹配文件中的字节模式,称为检查字节

协议

协议名称(如“ftp”或“http”)在 下注册

HKEY_CLASSES_ROOT

键,具有以下结构:

HKEY_CLASSES_ROOT
    <protocol>
        Source Filter = <Source filter CLSID>
        Extensions
            <.ext1> = <Source filter CLSID>
            <.ext2> = <Source filter CLSID>

如果文件名或 URL 包含冒号 (':') ,则 Filter Graph 管理器将尝试使用“:”之前的部分作为协议名称。 例如,如果名称为“myprot://myfile.ext”,则搜索名为 myprot 的注册表项。 如果此键存在并且包含名为“Extensions”的子项,则 Filter Graph Manager 在该子项内搜索与文件扩展名匹配的条目。 键的值必须是字符串形式的 GUID;例如“{00000000-0000-0000-0000-000000000000}”。 如果 Filter Graph 管理器无法匹配 Extensions 子项中的任何内容,它将查找名为 “源筛选器”的子项,该子项也必须是字符串形式的 GUID。

如果 Filter Graph 管理器找到匹配的 GUID,它将使用它作为源筛选器的 CLSID,并尝试加载筛选器。 如果找不到匹配项,它将使用 文件源 (URL) 筛选器,将文件名视为 URL。

此算法有两个例外:

  • 若要排除驱动程序字母,不将单字符字符串视为协议。
  • 如果字符串为“file:”或“file://”,则不会将其视为协议。

文件扩展名

如果文件名中没有协议,则 Filter Graph 管理器在注册表中查找项 HKEY_CLASSES_ROOT\Media Type\Extensions\ext\,其中 。ext 是文件扩展名。 如果此键存在,则值 “源筛选器 ”包含源筛选器的 CLSID(字符串形式)。 (可选)键可以具有 “媒体类型 ”和“ 子类型”的值,从而提供主类型和子类型 GUID。

检查字节数

某些文件类型可以通过文件中特定字节偏移处发生的位的特定模式来标识。 Filter Graph 管理器在注册表中查找具有以下格式的项:

HKEY_CLASSES_ROOT\MediaType\{ 主要类型 }\{ subtype }

其中,主类型和子类型是定义字节流的媒体类型的 GUID。 每个键都包含一个或多个子项(通常名为 1、2 等),用于定义检查字节;以及一个名为 Source Filter 的子项,该子项以字符串形式提供源筛选器的 CLSID。 检查字节子项是包含一个或多个数字象限的字符串,称为:

offsetcbmaskval

为了匹配文件,Filter Graph 管理器从字节数偏移量开始读取 cb 字节。 然后,它会对掩码中的值执行按位 AND。 如果结果等于 val,则该文件是该象限的匹配项。 值 mask 和 val 以十六进制表示。 掩码的空白条目被视为长度为 cb 的 1s 字符串。 offset 的负值表示与文件末尾的偏移量。 若要匹配键,文件必须匹配任何子项中的所有象限。

例如,假设注册表在 HKCR\Media Type 下包含以下项:

{e436eb83-524f-11ce-9f53-0020af0ba770}
    {7364696D-0000-0010-8000-00AA00389B71}
        0                    "0,4,,52494646,8,4,,524D4944"
        1                    "0,4,,4D546864"
        Source Filter        "{E436EBB5-524F-11CE-9F53-0020AF0BA770}"

第一个键对应于主类型MEDIATYPE_Stream。 下面的子项,对应于子类型MEDIATYPE_Midi。 源筛选器子项的值为 CLSID_AsyncReader,即 文件源 (异步) 筛选器的 CLSID。

每个条目可以有多个四重:它们必须匹配。 在以下示例中,文件的前 4 个字节必须是0xAB、0xCD、0x12、0x34;文件的最后 4 个字节必须是0xAB、0xAB、0x00 0xAB:

    0, 4, , ABCD1234,  -4, 4, , ABAB00AB 

此外,单个媒体类型下可以列出多个条目。 与其中任何一个匹配就足够了。 此方案允许一组替代掩码:例如,可能具有 RIFF 标头的 .wav 文件。

注意

此方案类似于 GetClassFile 函数使用的方案。

 

加载源筛选器

假设 Filter Graph 管理器为文件找到匹配的源筛选器,它会将该筛选器添加到图形中,查询 IFileSourceFilter 接口的筛选器,并调用 IFileSourceFilter::LoadLoad 方法的参数是从注册表确定的文件名和媒体类型。

如果 Filter Graph 管理器无法从注册表中找到任何内容,则默认使用异步文件源筛选器。 在这种情况下,它将媒体类型设置为 MEDIATYPE_StreamMEDIASUBTYPE_None

Windows 媒体播放器 中的自定义文件类型

Windows 媒体播放器使用一组附加的注册表项。 有关详细信息,请参阅 Windows 媒体播放器 SDK 中的文件扩展名注册表设置

编写 DirectShow 筛选器