PSI 分析程序筛选器示例

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

说明

PSI 分析器筛选器从 MPEG-2 传输流接收程序特定信息 (PSI) ,并从程序关联表 (PAT) 和程序映射表中提取程序信息, (PMT) 。 此信息使应用程序能够配置 MPEG-2 Demultiplexer。 筛选器支持用于检索 PSI 信息的自定义接口 IMpeg2PsiParser

此筛选器适用于 MPEG-2 设备,例如 IEEE 1394 MPEG-2 摄像机和 D-VHS 设备。 有关详细信息 ,请参阅 MSTape 驱动程序 。 数字电视广播源应使用 TIF 筛选器来获取节目信息。

使用情况

可以在 GraphEdit 中测试 PSI 分析器筛选器,如下所示:

  1. 启动 GraphEdit。

  2. 插入 MPEG-2 传输源。 MPEG-2 摄像机和 D-VHS 设备在视频捕获源类别中显示为“Microsoft AV/C 磁带子单元设备”。

  3. 将源筛选器连接到 MPEG-2 多路复用器筛选器。

  4. 使用 demux 上的 属性页创建具有“MPEG-2 PSI”媒体类型的输出引脚。 此引脚将提供 PAT 和 PMT 部分。

  5. 使用 demux 属性页将 PID 0x00映射到输出引脚。 将内容类型设置为“MPEG2 PSI 分区”。

  6. 将 demux 输出引脚连接到 PSI 分析器,如下图所示。

    psi 分析器筛选器图

  7. 运行图形,以便将 PSI 数据馈送给 PSI 分析器筛选器。 筛选器解码 PAT 部分时,会自动将 PMT PID 映射到 demux 上的同一输出引脚,以便接收 PMT 部分。

  8. 使用 PSI 分析器属性页选择程序编号。 属性页中的基本流列表将显示与所选程序中每个基本流关联的 PID 和流类型。 属性页旨在识别 ISO/IEC 13818-1 中定义的流类型。

  9. 在“音频 PID 编辑”框中输入 音频 PID 编号,在“视频 PID 编辑”框中输入 视频 PID 编号。

  10. 单击“ 查看程序 ”按钮。 PSI 分析器将配置 demux 上的输出引脚,以匹配程序流信息并呈现引脚。

注意

PSI 分析器属性页旨在简化测试,并提供配置 MPEG-2 Demultiplexer 的示例代码。 不建议应用程序使用。 应用程序应以编程方式配置 demux。

 

若要在应用程序中使用 PSI 分析器筛选器,请首先生成从 MPEG-2 源到 MPEG-2 demux 的筛选图。 此处未显示此步骤的代码,因为确切的图形配置将取决于源。

接下来,在 demux 上为 PSI 数据创建输出引脚。 将为 PAT 部分保留的 PID 0x00映射到此图钉,如以下代码所示:

// Set the media type to MPEG-2 table sections.
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = KSDATAFORMAT_TYPE_MPEG2_SECTIONS;

// Create the pin.
IPin *pPsiPin;
hr = pDemux->CreateOutputPin(&mt, L"PSI", &pPsiPin);
if (SUCCEEDED(hr))
{
    // Map to PID 0.
    ULONG Pid = 0x00;
    hr = pPid->MapPID(1, &Pid, MEDIA_MPEG2_PSI);
}

有关详细信息,请参阅 使用 MPEG-2 多路复用器

将 PSI 分析程序筛选器添加到图中,并将其连接到 demux 上的输出引脚。 查询 IMpeg2PsiParser 接口的 PSI 分析程序。 现在运行该图并等待EC_PROGRAM_CHANGED事件,这表示新的 PAT 或 PMT 部分。 此事件是由 PSI 分析程序筛选器定义的自定义事件。 收到EC_PROGRAM_CHANGED事件时,可以通过调用 IMpeg2PsiParser 方法获取可用的 PSI 信息。 本部分介绍最常用的方法。

若要获取程序数,请使用 IMpeg2PsiParser::GetCountOfPrograms 方法:

int NumProgs = 0;
hr = pPsi->GetCountOfPrograms(&NumProgs);

若要获取特定程序的程序编号,请使用 IMpeg2PsiParser::GetRecordProgramNumber 方法:

WORD ProgNum = 0;
for (int i = 0; i < NumProgs; i++)
{
    hr = pPsi->GetRecordProgramNumber(i, &ProgNum);
    ...
}

程序编号用于获取单个程序的 PMT 条目。 若要获取程序中的基本流数,请使用 GetCountOfElementaryStreams 方法:

WORD cElemStreams = 0;
hr = pPsi->GetCountOfElementaryStreams(ProgNum, &cElemStreams);

对于每个基本流, IMpeg2PsiParser::GetRecordElementaryPid 方法返回 PID, IMpeg2PsiParser::GetRecordStreamType 方法返回流类型:

BYTE ESType = 0;
WORD ESPid = 0;
for (WORD j = 0; j < cElemStreams; j++)
{
    hr = pPsi->GetRecordElementaryPid(ProgNum, j, &ESPid);
    hr = pPsi->GetRecordStreamType(ProgNum, j, &ESType);
}

PID 和流类型使你能够在 MPEG-2 多路复用器上配置新的输出引脚。 这可能需要对原始源有一些了解。 例如,ISO/IEC 13818-1 通过0xFF 0x80流类型定义为“用户专用”,但基于 MPEG-2 的其他标准可能会为这些类型赋予其他含义。

在图形运行时,MPEG-2 多路复用器可以创建新引脚和新的 PID 映射,但必须停止图形才能连接引脚。

下载示例

若要下载 DirectShow SDK 示例,请安装最新版本的 Windows SDK

此示例安装在以下路径下: [SDK 根]\Samples\Multimedia\DirectShow\Filters\PSIParser。

DirectShow 示例

IMpeg2PsiParser 接口