PSI 分析程序筛选器示例
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 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 分析器筛选器,如下所示:
启动 GraphEdit。
插入 MPEG-2 传输源。 MPEG-2 摄像机和 D-VHS 设备在视频捕获源类别中显示为“Microsoft AV/C 磁带子单元设备”。
将源筛选器连接到 MPEG-2 多路复用器筛选器。
使用 demux 上的 属性页创建具有“MPEG-2 PSI”媒体类型的输出引脚。 此引脚将提供 PAT 和 PMT 部分。
使用 demux 属性页将 PID 0x00映射到输出引脚。 将内容类型设置为“MPEG2 PSI 分区”。
将 demux 输出引脚连接到 PSI 分析器,如下图所示。
运行图形,以便将 PSI 数据馈送给 PSI 分析器筛选器。 筛选器解码 PAT 部分时,会自动将 PMT PID 映射到 demux 上的同一输出引脚,以便接收 PMT 部分。
使用 PSI 分析器属性页选择程序编号。 属性页中的基本流列表将显示与所选程序中每个基本流关联的 PID 和流类型。 属性页旨在识别 ISO/IEC 13818-1 中定义的流类型。
在“音频 PID 编辑”框中输入 音频 PID 编号,在“视频 PID 编辑”框中输入 视频 PID 编号。
单击“ 查看程序 ”按钮。 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。
相关主题