DirectShow 常见问题解答

本文解答了许多有关 Microsoft DirectShow 的常见问题。

DirectShow 支持哪些操作系统?

DirectShow 在所有受支持的 Windows 版本中都可用。

使用 DirectShow 编程需要多少 COM 知识?

对于应用程序开发,需要了解使用 COM 对象的基础知识:如何实例化它们、访问它们公开的接口以及管理这些接口上的引用计数。 筛选器开发需要更多的 COM 知识。

DirectShow 支持哪些格式?

HCL) 是否有 DirectShow 硬件兼容性列表 (?

不是。 DirectShow 使用 Microsoft DirectDraw 和 Microsoft DirectSound 硬件功能(如果可用)。 如果没有特殊硬件可用,DirectShow 使用 GDI 来绘制视频,并使用 waveOut * 多媒体 API 播放音频。

可以使用哪些语言编写 DirectShow 应用程序?

DirectShow 主要用于 C++ 开发。 DirectShow API 的一个小子集通过 Visual Basic 6.0 公开;但是,此功能已弃用。

是否可以通过托管代码访问 DirectShow?

Microsoft 目前没有实施托管 DirectShow API 的计划。

DirectShow 开发需要哪些编译器?

正确配置编译器环境后,任何能够生成组件对象模型 (COM) 对象的编译器都应正常工作。

DirectShow 与 Microsoft DirectX 有何关联?

在内部,当硬件支持 DirectSound 和 DirectDraw 时,DirectShow 会使用 DirectSound 和 DirectDraw。 视频呈现器和覆盖混音器筛选器使用 DirectDraw 3 和 DirectDraw 5 图面。 视频混合呈现器 7 (Windows XP 仅) 使用 DirectDraw 7 图面。 视频混合呈现器 9 和增强的视频呈现器使用最新的 Microsoft Direct3D API。 无需使用其他 DirectX API 来编写 DirectShow 应用程序,尽管可以将它们组合在一起。

DirectShow 与 Microsoft ActiveMovie 有何关系?

ActiveMovie 是 DirectShow 的原始名称。 不再使用术语 ActiveMovie。

GraphEdit 实用工具的源代码是否可用? GraphEdit 是否可以重新分发?

否,源不可用,Graphedt.exe不可再发行。

DMO 是否替换 DirectShow 筛选器?

Microsoft DirectX 媒体对象 (DSO) 可在 DirectShow 应用程序中使用。 对于编码器、解码器和效果,建议编写 DMO 而不是 DirectShow 筛选器。 (注意:如果要在解码器中使用 DirectX 视频加速,则必须将其作为 filter 实现。) 出于其他目的,DirectShow 筛选器可能更合适。 有关 DSO 的详细信息,请参阅 DirectX 媒体对象

我正在播放包含 Windows 媒体播放器 的 AVI 格式化文件。 我能听到音频,但似乎没有任何视频-相反,我只看到黑色。 为什么会这样?

该文件可能是使用系统上不存在的编解码器编码的。 虽然 AVI 文件格式很常见,但 AVI 文件可以使用许多不同的压缩格式创建, (编解码器) 。 如果尝试播放使用不受支持的编解码器的 AVI 文件,可能会听到音频组件,但视频将显示为黑屏或屏幕内容将保持不变。

注意

如果系统上不存在编解码器,Windows 媒体播放器通常会尝试下载并安装编解码器。

 

如何实现生成应用程序? 我需要哪些库和头文件?

请参阅 设置生成环境

GraphEdit 显示许多未记录的筛选器。 这些筛选器是什么?

GraphEdit 枚举在系统中注册的筛选器类别中的所有筛选器。 这可能包括由第三方应用程序安装的筛选器,或者由其他 Microsoft 技术(如 Windows Media 或 NetMeeting)安装的筛选器。 此外,某些 DirectShow 筛选器充当编解码器或硬件设备的包装器,每个编解码器或设备显示为不同的筛选器。 Microsoft H.263 视频编解码器由 NetMeeting 使用,在 DirectShow 中不再受支持。 有关详细信息,请参阅 枚举设备和筛选器

我在以编程方式生成自定义图形时遇到问题。

首先尝试使用 GraphEdit 生成筛选器图。 此工具使你能够快速模拟许多可能性。 在尝试使用源代码生成图形之前,GraphEdit 始终是测试图形的绝佳位置。

有关图形构建的详细信息,请参阅以下文章:

如何检测给定计算机上是否安装了 DirectShow?

调用 CoCreateInstance 以创建筛选器关系图管理器的实例。 如果此调用成功,则在计算机上安装 DirectShow。 以下代码演示了如何执行此操作:

IGraphBuilder *pGraph;

HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
    NULL, CLSCTX_INPROC_SERVER,
    IID_IGraphBuilder, (void **) &pGraph);

如何实现更改筛选器的设置而不显示属性页?

大多数筛选器公开一个或多个接口,用于在筛选器上设置属性。 请参阅相关筛选器的参考页。 (请参阅 DirectShow Filters.)

是否可以使用 GraphEdit 测试筛选器?

开发筛选器时,GraphEdit 可以帮助你可视化筛选器之间的连接。 它还可以提供筛选器功能的快速测试。 但是,它并不是一个可靠的测试平台。

筛选器以什么特权圈运行?

筛选器在环 3 处运行,但某些筛选器控制在环 0 上运行的流式处理设备。 有关详细信息,请参阅 硬件设备如何参与筛选器图

是否需要使用内核调试器?

这取决于你的特定项目。 安装 DirectX 调试运行时库意味着要安装调试驱动程序和其他内核模式组件,如果应用程序在其中一个组件中导致调试断言,计算机将自动重启,除非进程附加了内核调试器。

在调试器中运行应用程序时,应用程序崩溃。

某些解码器设计为在将应用程序附加到调试器时不起作用。 尝试在调试器外部运行应用程序。

DEFINE\_GUID宏的工作原理是什么?

DEFINE_GUID宏解决了在源代码中声明extern对 GUID 值的引用的问题。 例如,假设项目有三个源文件 Src1.cpp、Src2.cpp 和 Src3.cpp,并且所有三个文件都使用已定义的特定 GUID 值。 GUID 值必须在项目中定义一次,其他源文件必须声明 extern 对其的引用。 使用 DEFINE_GUID 宏,可以将同一头文件用于这两个目的。 在头文件中,按如下所示声明 GUID:

DEFINE_GUID(CLSID_MyObject, 
0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);

(如果此示例具有零,请放置实际的 GUID 值。) 可以使用 Guidgen.exe 实用工具创建新的 GUID,并将其粘贴到 DEFINE_GUID 格式的头文件中。 将此头文件包含在引用 GUID 的每个源文件中。 正好在其中一个源文件中,在头文件之前包括头文件 Initguid.h。 例如:

// Src1.cpp
#include <initguid.h>
#include "MyGuids.h"

// Src2.cpp
#include "MyGuids.h"

// Src3.cpp
#include "MyGuids.h"

只要不包含 Initguid.h 头文件, DEFINE_GUID 宏将 extern 创建对 GUID 值的引用。 当包含 Initguid.h 头文件时,它会重新定义 DEFINE_GUID 宏,以便 DEFINE_GUID 创建 GUID 的定义声明。

如果未在任何源文件中包含 Initguid.h,则会收到链接错误“未解析的外部符号”。如果为同一 GUID 包含 Initguid.h 两次,则会收到编译错误“重新定义;多个初始化。”若要解决这些错误,请确保仅包含 Initguid.h 一次。 此外,请勿在预编译头文件中包含 Initguid.h,因为实际上预编译标头包含在每个源文件中。

DirectShow 简介