步骤 3B。 实现 GetMediaType 方法

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

这是 编写转换筛选器教程的步骤 3B。

注意

对于从 CTransInPlaceFilter 派生的筛选器,不需要执行此步骤。

 

CTransformFilter::GetMediaType 方法返回筛选器的首选输出类型之一,由索引号引用。 除非已连接筛选器的输入引脚,否则永远不会调用此方法。 因此,可以使用上游连接的媒体类型来确定首选输出类型。

编码器通常提供单个首选类型,表示目标格式。 解码器通常支持一系列输出格式,并按质量或效率降序提供。 例如,列表可能按该顺序为 UYVY、Y211、RGB-24、RGB-565、RGB-555 和 RGB-8。 效果筛选器可能需要输出格式和输入格式之间的完全匹配。

以下示例返回单个输出类型,该类型通过修改输入类型以指定 RLE8 压缩来构造:

HRESULT CRleFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
    ASSERT(m_pInput->IsConnected());
    if (iPosition < 0)
    {
        return E_INVALIDARG;
    }
    if (iPosition == 0)
    {
        HRESULT hr = m_pInput->ConnectionMediaType(pMediaType);
        if (FAILED(hr))
        {
            return hr;
        }
        FOURCCMap fccMap = FCC('MRLE'); 
        pMediaType->subtype = static_cast<GUID>(fccMap);
        pMediaType->SetVariableSize();
        pMediaType->SetTemporalCompression(FALSE);

        ASSERT(pMediaType->formattype == FORMAT_VideoInfo);
        VIDEOINFOHEADER *pVih =
            reinterpret_cast<VIDEOINFOHEADER*>(pMediaType->pbFormat);
        pVih->bmiHeader.biCompression = BI_RLE8;
        pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader); 
        return S_OK;
    }
    // else
    return VFW_S_NO_MORE_ITEMS;
}

在此示例中,方法调用 IPin::ConnectionMediaType 以从输入引脚获取输入类型。 然后,它会更改一些字段以指示压缩格式,如下所示:

  • 它分配使用 FOURCCMap 类根据 FOURCC 代码“MRLE”构造的新子类型 GUID。
  • 它调用 CMediaType::SetVariableSize 方法,该方法将 bFixedSizeSamples 标志设置为 FALSElSampleSize 成员设置为零,指示大小可变的样本。
  • 它调用值为 FALSECMediaType::SetTemporalCompression 方法,表示每个帧都是关键帧。 (此字段仅供信息使用,因此可以放心地忽略它。)
  • 它将 biCompression 字段设置为 BI_RLE8。
  • 它将 biSizeImage 字段设置为图像大小。

下一步: 步骤 3C.实现 CheckTransform 方法

编写 DirectShow 筛选器