Enumerating Objects in a Filter Graph

39 篇文章 1 订阅
37 篇文章 1 订阅

    应用程序可能需要在过滤器图表中找到特定的过滤器,或者甚至需要在过滤器上定位特定的过滤器。例如,它可能使用特定过滤器暴露的接口, 或者它可能会构建专门的过滤器图形,并需要调用各个引脚上的方法来连接过滤器。为此,DirectShow提供了几种枚举过滤器图形中对象的方法。

 

Enumerating Filters

    Filter Graph Manager支持IFilterGraph :: EnumFilters方法,枚举过滤器图中的所有过滤器。 它返回一个指向IEnumFilters接口的指针。 IEnumFilters :: Next方法检索IBaseFilter接口指针。

    以下示例显示了枚举图中的过滤器并显示每个过滤器名称的消息框的函数。 它使用IBaseFilter :: QueryFilterInfo方法来检索过滤器的名称。 请注意函数在接口上调用Release以减少引用计数的位置。

HRESULT EnumFilters (IFilterGraph *pGraph) 
{
    IEnumFilters *pEnum = NULL;
    IBaseFilter *pFilter;
    ULONG cFetched;

    HRESULT hr = pGraph->EnumFilters(&pEnum);
    if (FAILED(hr)) return hr;

    while(pEnum->Next(1, &pFilter, &cFetched) == S_OK)
    {
        FILTER_INFO FilterInfo;
        hr = pFilter->QueryFilterInfo(&FilterInfo);
        if (FAILED(hr))
        {
            MessageBox(NULL, TEXT("Could not get the filter info"),
                TEXT("Error"), MB_OK | MB_ICONERROR);
            continue;  // Maybe the next one will work.
        }

#ifdef UNICODE
        MessageBox(NULL, FilterInfo.achName, TEXT("Filter Name"), MB_OK);
#else
        char szName[MAX_FILTER_NAME];
        int cch = WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName,
            MAX_FILTER_NAME, szName, MAX_FILTER_NAME, 0, 0);
        if (cch > 0)
            MessageBox(NULL, szName, TEXT("Filter Name"), MB_OK);
#endif

        // The FILTER_INFO structure holds a pointer to the Filter Graph
        // Manager, with a reference count that must be released.
        if (FilterInfo.pGraph != NULL)
        {
            FilterInfo.pGraph->Release();
        }
        pFilter->Release();
    }

    pEnum->Release();
    return S_OK;
}

 

Enumerating Pins

    过滤器支持IBaseFilter :: EnumPins方法,枚举过滤器上可用的引脚。 它返回一个指向IEnumPins接口的指针。 IEnumPins :: Next方法检索IPin接口指针。

    以下示例显示了一个函数,该函数在给定滤波器上定位具有给定方向(输入或输出)的引脚。 它使用PIN_DIRECTION枚举来指定引脚方向,并使用IPin :: QueryDirection方法来查找每个枚举引脚的方向。 如果这个函数找到一个匹配的引脚,它将返回一个IPin接口指针,其中引用计数为未完成。 调用者负责释放界面。

HRESULT GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
{
    IEnumPins  *pEnum = NULL;
    IPin       *pPin = NULL;
    HRESULT    hr;

    if (ppPin == NULL)
    {
        return E_POINTER;
    }

    hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    while(pEnum->Next(1, &pPin, 0) == S_OK)
    {
        PIN_DIRECTION PinDirThis;
        hr = pPin->QueryDirection(&PinDirThis);
        if (FAILED(hr))
        {
            pPin->Release();
            pEnum->Release();
            return hr;
        }
        if (PinDir == PinDirThis)
        {
            // Found a match. Return the IPin pointer to the caller.
            *ppPin = pPin;
            pEnum->Release();
            return S_OK;
        }
        // Release the pin for the next time through the loop.
        pPin->Release();
    }
    // No more pins. We did not find a match.
    pEnum->Release();
    return E_FAIL;  
}

 

Enmerating Media Types

 

    引脚支持IPin :: EnumMediaTypes方法,枚举引脚的首选媒体类型。 它返回一个指向IEnumMediaTypes接口的指针。 IEnumMediaTypes :: Next方法检索指向描述媒体类型的AM_MEDIA_TYPE结构的指针。

    媒体类型枚举器主要用于帮助Filter Graph Manager进行智能连接,并且您的应用程序可能不会使用它。 引脚不一定会返回任何首选的媒体类型。 而且,它返回的媒体类型可能取决于过滤器的连接状态。 例如,根据为过滤器的输入引脚设置哪种介质类型,过滤器的输出引脚可能会返回一组不同的介质类型。

    以下示例查找与指定的主要类型,子类型或格式类型匹配的首选媒体类型。

/ Given a pin, find a preferred media type 
//
// pPin         Pointer to the pin.
// majorType    Preferred major type (GUID_NULL = don't care).
// subType      Preferred subtype (GUID_NULL = don't care).
// formatType   Preferred format type (GUID_NULL = don't care).
// ppmt         Receives a pointer to the media type. Can be NULL.
//
// Note: If you want to check whether a pin supports a desired media type,
//       but do not need the format details, set ppmt to NULL.
//
//       If ppmt is not NULL and the method succeeds, the caller must
//       delete the media type, including the format block. 

HRESULT GetPinMediaType(
    IPin *pPin,             // pointer to the pin
    REFGUID majorType,      // desired major type, or GUID_NULL = don't care
    REFGUID subType,        // desired subtype, or GUID_NULL = don't care
    REFGUID formatType,     // desired format type, of GUID_NULL = don't care
    AM_MEDIA_TYPE **ppmt    // Receives a pointer to the media type. (Can be NULL)
    )
{
    *ppmt = NULL;

    IEnumMediaTypes *pEnum = NULL;
    AM_MEDIA_TYPE *pmt = NULL;
    BOOL bFound = FALSE;
    
    HRESULT hr = pPin->EnumMediaTypes(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }

    while (hr = pEnum->Next(1, &pmt, NULL), hr == S_OK)
    {
        if ((majorType == GUID_NULL) || (majorType == pmt->majortype))
        {
            if ((subType == GUID_NULL) || (subType == pmt->subtype))
            {
                if ((formatType == GUID_NULL) || 
                    (formatType == pmt->formattype))
                {
                    // Found a match. 
                    if (ppmt)
                    {
                        *ppmt = pmt;  // Return it to the caller
                    }
                    else
                    {
                        _DeleteMediaType(pmt);
                    }
                    bFound = TRUE;
                    break;
                }
            }
        }
        _DeleteMediaType(pmt);
    }

    SafeRelease(&pEnum);
    if (SUCCEEDED(hr))
    {
        if (!bFound)
        {
            hr = VFW_E_NOT_FOUND;
        }
    }
    return hr;
}

参考:

https://www.yuque.com/docs/share/9656d65c-4f49-49a1-ba9e-3019c2cecf1a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值