步骤 3A。 实现 CheckInputType 方法
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
这是 编写转换筛选器教程的步骤 3A。
当上游筛选器向转换筛选器推荐媒体类型时,将调用 CTransformFilter::CheckInputType 方法。 此方法采用指向 CMediaType 对象的指针,CMediaType 对象是 AM_MEDIA_TYPE 结构的精简包装器。 在此方法中,应检查 AM_MEDIA_TYPE 结构的每个相关字段,包括格式块中的字段。 可以使用 CMediaType 中定义的访问器方法,也可以直接引用结构成员。 如果任何字段无效,则返回VFW_E_TYPE_NOT_ACCEPTED。 如果整个媒体类型有效,则返回S_OK。
例如,在 RLE 编码器筛选器中,输入类型必须是 8 位或 4 位未压缩的 RGB 视频。 没有理由支持其他输入格式(如 16 位或 24 位 RGB),因为筛选器必须将其转换为较低的位深度,并且 DirectShow 已为此提供 颜色空间转换器 筛选器。 以下示例假定编码器支持 8 位视频,但不支持 4 位视频:
HRESULT CRleFilter::CheckInputType(const CMediaType *mtIn)
{
if ((mtIn->majortype != MEDIATYPE_Video) ||
(mtIn->subtype != MEDIASUBTYPE_RGB8) ||
(mtIn->formattype != FORMAT_VideoInfo) ||
(mtIn->cbFormat < sizeof(VIDEOINFOHEADER)))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
VIDEOINFOHEADER *pVih =
reinterpret_cast<VIDEOINFOHEADER*>(mtIn->pbFormat);
if ((pVih->bmiHeader.biBitCount != 8) ||
(pVih->bmiHeader.biCompression != BI_RGB))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Check the palette table.
if (pVih->bmiHeader.biClrUsed > PALETTE_ENTRIES(pVih))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
DWORD cbPalette = pVih->bmiHeader.biClrUsed * sizeof(RGBQUAD);
if (mtIn->cbFormat < sizeof(VIDEOINFOHEADER) + cbPalette)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Everything is good.
return S_OK;
}
在此示例中,方法首先检查主类型和子类型。 然后,它会检查格式类型,以确保格式块是 VIDEOINFOHEADER 结构。 筛选器还可以支持 VIDEOINFOHEADER2,但在这种情况下没有实际的好处。 VIDEOINFOHEADER2 结构添加了对交错和非方形像素的支持,这些像素在 8 位视频中不太可能相关。
如果格式类型正确,则本示例将检查 VIDEOINFOHEADER 结构的 biBitCount 和 biCompression 成员,以验证格式是否为 8 位未压缩 RGB。 如以下示例所示,必须强制
pbFormat
指向基于格式类型的正确结构的指针。 在强制转换指针之前,始终检查格式类型 GUID (formattype) ,以及 cbFormat) (格式块的大小。
该示例还验证调色板条目的数量是否与位深度兼容,并且格式块的大小足以容纳调色板条目。 如果所有这些信息都正确,该方法将返回S_OK。
下一步: 步骤 3B.实现 GetMediaType 方法。
相关主题