将项目写入文件

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

[此 API 不受支持,将来可能会更改或不可用。]

本文介绍如何将 DirectShow 编辑服务 项目写入文件。 首先介绍如何使用基本呈现引擎编写文件。 然后描述智能渲染引擎的智能重新压缩。

有关 DirectShow 编辑服务如何呈现项目的概述,请参阅 关于呈现引擎

使用基本呈现引擎

首先生成图形的前端,如下所示:

  1. 创建呈现引擎。
  2. 指定时间线。
  3. 设置呈现区域。 (可选)
  4. 生成图形的前端。

下面的代码示例演示了这些步骤。

IRenderEngine *pRender = NULL; 
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
    IID_IRenderEngine, (void**) &pRender);

hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );

接下来,将多路复用器和文件写入筛选器添加到筛选器图。 执行此操作的最简单方法是使用 捕获图生成器,这是用于生成捕获图的 DirectShow 组件。 捕获图生成器公开 ICaptureGraphBuilder2 接口。 执行以下步骤:

  1. 创建捕获图生成器的实例。
  2. 获取指向图形的指针并将其传递给图形生成器。
  3. 指定输出文件的名称和媒体类型。 此步骤还会获取指向复用器筛选器的指针,这是稍后需要用到的。

下面的代码示例演示了这些步骤。

CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, 
    IID_ICaptureGraphBuilder2, (void **)&pBuilder);

// Get a pointer to the graph front end.
IGraphBuilder *pGraph;
pRender->GetFilterGraph(&pGraph);
pBuilder->SetFiltergraph(pGraph);

// Create the file-writing section.
IBaseFilter *pMux;
pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, 
    OLESTR("Output.avi"), &pMux, NULL);

最后,将前端的输出引脚连接到复用筛选器。

  1. 检索组数。
  2. 对于每个引脚,获取指向该引脚的指针。
  3. (可选)创建压缩筛选器的实例以压缩流。 压缩器的类型取决于组的媒体类型。 可以使用 系统设备枚举器 来枚举可用的压缩筛选器。 有关详细信息,请参阅 枚举设备和筛选器
  4. (可选)设置压缩参数,例如关键帧速率。 本文稍后将详细介绍此步骤。
  5. 调用 ICaptureGraphBuilder2::RenderStream。 此方法获取指向引脚的指针、压缩筛选器 ((如果有任何) )和多路复用器。

下面的代码示例演示如何连接输出引脚。

long NumGroups;
pTimeline->GetGroupCount(&NumGroups);

// Loop through the groups and get the output pins.
for (i = 0; i < NumGroups; i++)
{
    IPin *pPin;
    if (pRender->GetGroupOutputPin(i, &pPin) == S_OK) 
    {
        IBaseFilter *pCompressor;
        // Create a compressor filter. (Not shown.)
        // Set compression parameters. (Not shown.)

        // Connect the pin.
        pBuilder->RenderStream(NULL, NULL, pPin, pCompressor, pMux);
        pCompressor->Release();
        pPin->Release();
    }
}

若要 (步骤 4(以前) )设置压缩参数,请使用 IAMVideoCompression 接口。 此接口在压缩筛选器的输出引脚上公开。 枚举压缩筛选器的引脚,并查询每个输出引脚以获取 IAMVideoCompression。 (有关枚举引脚的信息,请参阅 枚举 Pins.) 请确保释放在此步骤中获取的所有接口指针。

生成筛选器图后,在筛选器关系图管理器上调用 IMediaControl::Run 方法。 筛选器图运行时,它会将数据写入文件。 使用事件通知等待播放完成。 (请参阅 响应事件。) 播放完成后,必须显式调用 IMediaControl::Stop 以停止筛选图。 否则,无法正确写入文件。

使用智能渲染引擎

若要获得智能重压的优势,请使用智能呈现引擎代替基本呈现引擎。 生成图形的步骤几乎相同。 主要区别在于压缩在图形的前端处理,而不是在文件写入部分中处理。

重要

请勿使用智能呈现引擎读取或写入 Windows Media 文件。

 

每个视频组都有一个 属性,该属性指定该组的压缩格式。 压缩格式在高度、宽度、位深度和帧速率上必须与组的未压缩格式完全匹配。 智能呈现引擎在构造图形时使用压缩格式。 在设置压缩格式之前,请确保通过调用 IAMTimelineGroup::SetMediaType 为该组设置未压缩格式。

若要设置组的压缩格式,请调用 IAMTimelineGroup::SetSmartRecompressFormat 方法。 此方法采用指向 SCompFmt0 结构的指针。 SCompFmt0 结构有两个成员nFormatId(必须为零)和 MediaType(AM_MEDIA_TYPE 结构)。 使用格式信息初始化 AM_MEDIA_TYPE 结构。

注意

如果希望最终项目的格式与源文件之一相同,则可以使用媒体检测器直接从源文件获取AM_MEDIA_TYPE结构。 请参阅 IMediaDet::get_StreamMediaType

 

SCompFmt0 变量强制转换为 long 类型的指针,如以下示例所示。

SCompFmt0 *pFormat = new SCompFmt0;
memset(pFormat, 0, sizeof(SCompFmt0));
pFormat->nFormatId = 0;

// Initialize pFormat->MediaType. (Not shown.)

pGroup->SetSmartRecompressFormat( (long*) pFormat );

智能呈现引擎会自动搜索兼容的压缩筛选器。 还可以通过调用 ISmartRenderEngine::SetGroupCompressor 为组指定压缩筛选器。

若要生成图形,请使用上一部分中基本呈现引擎所述的相同步骤。 唯一的区别如下:

  • 使用智能呈现引擎,而不是基本呈现引擎。 类标识符CLSID_SmartRenderEngine。
  • 在生成前端之后、呈现输出引脚之前设置压缩参数。 调用 ISmartRenderEngine::GetGroupCompressor 方法以获取指向组压缩筛选器的指针。 然后查询 IAMVideoCompression 接口,如前所述。
  • 呈现输出引脚时,无需插入压缩筛选器。 流已压缩。

呈现项目