用于directshow的一些辅助函数

原创 2005年02月25日 16:29:00

没有进行类的封装,只是把一些函数集中在一个文件中。

一个是函数的声明文件DShowUtilities.h,一个是函数的定义文件DShowUtilities.cpp

这里面的函数都是从微软自己带的源代码或是帮助文档中copy过来的。

首先是DShowUtilities.h文件

#ifndef DShowUtilities_H_
#define DShowUtilities_H_

#include <DShow.h>

#pragma comment(lib,"Strmiids.lib")

//这只是一个很小的函数而已,只是一些例子代码中会用到

#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }

HRESULT AddFilterByCLSID(
    IGraphBuilder *pGraph,  // Pointer to the Filter Graph Manager.
    const GUID& clsid,      // CLSID of the filter to create.
    LPCWSTR wszName,        // A name for the filter.
    IBaseFilter **ppF);      // Receives a pointer to the filter.

HRESULT GetUnconnectedPin(
    IBaseFilter *pFilter,   // Pointer to the filter.
    PIN_DIRECTION PinDir,   // Direction of the pin to find.
    IPin **ppPin);           // Receives a pointer to the pin.

HRESULT ConnectFilters(
    IGraphBuilder *pGraph, // Filter Graph Manager.
    IPin *pOut,            // Output pin on the upstream filter.
    IBaseFilter *pDest);    // Downstream filter.

HRESULT ConnectFilters(
    IGraphBuilder *pGraph,
    IBaseFilter *pSrc,
    IBaseFilter *pDest);

//判断pin是否有此mediaType,stolen from sdk amcap
BOOL HasMediaType(IPin* pPin,  REFGUID majorType );

//stolen from sdk amcap,其中用到上面的函数HasMediaType
BOOL IsVideoPin( IPin* pPin );

// Tear down everything downstream of a given filter
//将一个给定的filter下的所有filter都删除,通过递归调用实现
//stolen from sdk amcap
void NukeDownstream(IBaseFilter *pf,IGraphBuilder *pFg);

// Tear down everything downstream of the capture filters, so we can build
// a different capture graph.  Notice that we never destroy the capture filters
// and WDM filters upstream of them, because then all the capture settings
// we've set would be lost.
//将capture filter后面的filter删除,这样就可以建立一个新的capture graph。
//不删除capture filter的原因在于如果删除,那么,我们原先的设置就白设了
//stolen from sdk amcap
void TearDownGraph(IGraphBuilder *pFg,IVideoWindow *pVW,IBaseFilter *pVCap);

#endif

下面的代码是DShowUtilities.cpp里面的,是这些函数的实现

//DShowUtilities.cpp--------------------------------------------------------

#include "stdafx.h"
#include "DShowUtilities.h"


/*-----------------------------------------------------------------------------------
The following function creates a filter with a specified class identifier (CLSID)
and adds it to the filter graph

USE Example: Add AVI Mux filter to the graph

IBaseFilter *pMux;
hr = AddFilterByCLSID(pGraph, CLSID_AviDest, L"AVI Mux", &pMux);
if (SUCCEEDED(hr))
{
    //...............
   pMux->Release();
}
----------------------------------------------------------------------------------*/
HRESULT AddFilterByCLSID(
    IGraphBuilder *pGraph,  // Pointer to the Filter Graph Manager.
    const GUID& clsid,      // CLSID of the filter to create.
    LPCWSTR wszName,        // A name for the filter.
    IBaseFilter **ppF)      // Receives a pointer to the filter.
{
    if (!pGraph || ! ppF) return E_POINTER;
    *ppF = 0;
    IBaseFilter *pF = 0;
    HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
        IID_IBaseFilter, reinterpret_cast<void**>(&pF));
    if (SUCCEEDED(hr))
    {
        hr = pGraph->AddFilter(pF, wszName);
        if (SUCCEEDED(hr))
            *ppF = pF;
        else
            pF->Release();
    }
    return hr;
}

/*----------------------------------------------------------------------------------
This function find an unconnected pin on a filter

The following function searches on a filter for an unconnected pin,
either input or output. It returns the first matching pin.
Finding unconnected pins is useful when you are connecting filters.

USE Example:

IPin *pOut = NULL;
HRESULT hr = GetUnconnectedPin(pFilter, PINDIR_OUTPUT, &pOut);
if (SUCCEEDED(hr))
{
    //...........
    pOut->Release();
}

-----------------------------------------------------------------------------------*/
HRESULT GetUnconnectedPin(
    IBaseFilter *pFilter,   // Pointer to the filter.
    PIN_DIRECTION PinDir,   // Direction of the pin to find.
    IPin **ppPin)           // Receives a pointer to the pin.
{
    *ppPin = 0;
    IEnumPins *pEnum = 0;
    IPin *pPin = 0;
    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    while (pEnum->Next(1, &pPin, NULL) == S_OK)
    {
        PIN_DIRECTION ThisPinDir;
        pPin->QueryDirection(&ThisPinDir);
        if (ThisPinDir == PinDir)
        {
            IPin *pTmp = 0;
            hr = pPin->ConnectedTo(&pTmp);
            if (SUCCEEDED(hr))  // Already connected, not the pin we want.
            {
                pTmp->Release();
            }
            else  // Unconnected, this is the pin we want.
            {
                pEnum->Release();
                *ppPin = pPin;
                return S_OK;
            }
        }
        pPin->Release();
    }
    pEnum->Release();
    // Did not find a matching pin.
    return E_FAIL;
}

/*--------------------------------------------------------------------------------
The following function connects an output pin from one filter to
the first available input pin on another filter.
里面调用了前面定义的函数GetUnconnectedPin

---------------------------------------------------------------------------------*/

HRESULT ConnectFilters(
    IGraphBuilder *pGraph, // Filter Graph Manager.
    IPin *pOut,            // Output pin on the upstream filter.
    IBaseFilter *pDest)    // Downstream filter.
{
    if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
    {
        return E_POINTER;
    }
#ifdef debug
        PIN_DIRECTION PinDir;
        pOut->QueryDirection(&PinDir);
        _ASSERTE(PinDir == PINDIR_OUTPUT);
#endif

    // Find an input pin on the downstream filter.
    IPin *pIn = 0;
    HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);//调用了前面定义的函数
    if (FAILED(hr))
    {
        return hr;
    }
    // Try to connect them.
    hr = pGraph->Connect(pOut, pIn);
    pIn->Release();
    return hr;
}


/*---------------------------------------------------------------------------------
Here is an overloaded version of the same function. The second parameter is
a pointer to a filter, rather than a pin.
The function connects the first filter to the second filter


USE Example:
The following example use this example to connect AVI Mux filter to File Writer
filter

IBaseFilter *pMux, *pWrite;
hr = AddFilterByCLSID(pGraph, CLSID_AviDest, L"AVI Mux", &pMux);
if (SUCCEEDED(hr))
{
    hr = AddFilterByCLSID(pGraph, CLSID_FileWriter, L"File Writer", &pWrite);
    if (SUCCEEDED(hr))
    {
        hr = ConnectFilters(pGraph, pMux, pWrite);
        //Use IFileSinkFilter to set the file name (not shown).
       pWrite->Release();
    }
    pMux->Release();
}

这里面用了前面定义的那个ConnectFilters函数和GetUnconnectedPin函数
----------------------------------------------------------------------------------*/
HRESULT ConnectFilters(
    IGraphBuilder *pGraph,
    IBaseFilter *pSrc,
    IBaseFilter *pDest)
{
    if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
    {
        return E_POINTER;
    }

    // Find an output pin on the first filter.
    IPin *pOut = 0;
    HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);//用了前面定义的函数
    if (FAILED(hr))
    {
        return hr;
    }
    hr = ConnectFilters(pGraph, pOut, pDest);//用了前面定义的函数
    pOut->Release();
    return hr;
}


/*---------------------------------------------------------------------------------
判断pin是否有此mediaType,stolen from sdk amcap
--------------------------------------------------------------------------------*/
BOOL HasMediaType(IPin* pPin,  REFGUID majorType )
{
    if( !pPin )
    {
        return FALSE;
    }

    IEnumMediaTypes* pMediaTypes;
    HRESULT hr = pPin->EnumMediaTypes( &pMediaTypes );
    if( FAILED( hr ) )
    {
        return FALSE;
    }

    hr = pMediaTypes->Reset();
    if( FAILED( hr ) )
    {
        return FALSE;
    }

    ULONG           fetched;
    AM_MEDIA_TYPE   *mediaType;

    while( S_OK == pMediaTypes->Next( 1, &mediaType, &fetched ) )
    {
        if( IsEqualGUID( mediaType->majortype, majorType ) )
        {
       //     DeleteMediaType( mediaType );
            return TRUE;
        }
//        DeleteMediaType( mediaType );
    }

    return FALSE;

}

/*--------------------------------------------------------------------------------
判断是否是video pin,stolen from sdk amcap
此函数用到上面的函数HasMediaType
--------------------------------------------------------------------------------*/

BOOL IsVideoPin( IPin* pPin )
{
    return HasMediaType( pPin, MEDIATYPE_Video );//上面的函数
}


/*---------------------------------------------------------------------------------
 Tear down everything downstream of a given filter
将一个GraphBuilder中的给定的filter下的所有filter都删除,通过递归调用实现
stolen from amcap
----------------------------------------------------------------------------------*/

void NukeDownstream(IBaseFilter *pf,IGraphBuilder *pFg)
{
    IPin *pP=0, *pTo=0;
    ULONG u;
    IEnumPins *pins = NULL;
    PIN_INFO pininfo;

    if (!pf)
        return;

    HRESULT hr = pf->EnumPins(&pins);
    pins->Reset();//通过这个函数调用,获得最新的数据?

    while(hr == NOERROR)
    {
        hr = pins->Next(1, &pP, &u);//找到filter上的pin
        if(hr == S_OK && pP)
        {
            pP->ConnectedTo(&pTo);//找到与这个pin相连的另一个filter上的pin
            if(pTo)
            {
                hr = pTo->QueryPinInfo(&pininfo);
                if(hr == NOERROR)
                {
                    if(pininfo.dir == PINDIR_INPUT)//只寻找input的pin
                    {
                        NukeDownstream(pininfo.pFilter,pFg);//递归调用
                        pFg->Disconnect(pTo);//要将pin的两端同时移除
                        pFg->Disconnect(pP);
                        pFg->RemoveFilter(pininfo.pFilter);//在递归调用中,
         //最先删除的是只有input pin的filter
                    }
                    pininfo.pFilter->Release();
                }
                pTo->Release();
            }
            pP->Release();
        }
    }//end while

    if(pins)
        pins->Release();
}

/*---------------------------------------------------------------------------------
 Tear down everything downstream of the capture filters, so we can build
 a different capture graph.  Notice that we never destroy the capture filters
 and WDM filters upstream of them, because then all the capture settings
 we've set would be lost.
将capture filter后面的filter删除,这样就可以建立一个新的capture graph。
不删除capture filter的原因在于如果删除,那么,我们原先的设置就白设了
stolen from sdk amcap
---------------------------------------------------------------------------------*/
void TearDownGraph(IGraphBuilder *pFg,IVideoWindow *pVW,IBaseFilter *pVCap)
{
    if(pVW)//IVideoWindow停止视频显示
    {
        // stop drawing in our window, or we may get wierd repaint effects
        pVW->put_Owner(NULL);
        pVW->put_Visible(OAFALSE);
        pVW->Release();
        pVW = NULL;
    }

    // destroy the graph downstream of our capture filters
    if(pVCap)
        NukeDownstream(pVCap,pFg);//这个函数 Tear down everything downstream of a given filter
                              //但是,这个filter却是会保留的
 //然后应该是对一些filter的release
}


 

 

常用辅助函数集合

1. 输出日志文件
  • encoder1234
  • encoder1234
  • 2013年10月28日 17:47
  • 656

【PHP】声名使用一个辅助函数

例7-3---声名使用一个辅助函数 //在这个模板里使用一个特定的辅助函数 ... 描述 TIP 如果你要声明多个辅助函数组,给user_helper()函数传多个参数就可以了. 例如,要在一个...
  • ljx008
  • ljx008
  • 2014年08月19日 16:16
  • 293

迭代器和辅助函数

 迭代器(iterator)是连接容器和算法的纽带,为数据提供了抽象,使写算法的人不必关心各种数据结构的细节。迭代器提供了数据访问的标准模型——对象序列,使对容器更广泛的访问操作成为可能。...
  • ggz631047367
  • ggz631047367
  • 2014年07月21日 11:25
  • 5107

Qt对directshow的封装

在源码路径中:qt-everywhere-opensource-src-5.1.1\qtmultimedia\src\plugins\directshow, 有两个文件夹player 和 camera...
  • chinabinlang
  • chinabinlang
  • 2014年01月20日 18:28
  • 3644

C++标准库笔记:13.12.3 以辅助函数完成I/O

如果执行IO操作符时需要存取对象的私有成员,通常有以下两种方法:使用辅助函数IO操作符应该将实际任务委派给辅助的成员函数。这种技术允许具有多态性,如下:class Fraction { public:...
  • s634772208
  • s634772208
  • 2017年06月12日 08:54
  • 162

CI(CodeIgniter)框架入门教程——第四课 辅助函数和类库的使用

本文转载自:http://www.softeng.cn/?p=95 最近这段时间因为项目比较忙,所以一直没有更新,还望大家见谅。 下面开始今天的正式内容,今天主要讲CI框架中辅助函数和类库的使用,在...
  • whh306318848
  • whh306318848
  • 2015年02月25日 02:12
  • 2200

【C++ STL应用与实现】17: 如何使用迭代器辅助函数

本文介绍了STL中的迭代器辅助函数的用法及注意事项,这些迭代器辅助函数包括:advance, next (since C++11), prev (since C++11), distance, ite...
  • elloop
  • elloop
  • 2015年12月26日 23:33
  • 1468

Directshow完整介绍

最近一段时间,在编写DirectShow应用程序时常常遇到一些问题,原因是对DirectShow技术没有较全面地掌握,对各个接口间的关系以及filter与filter之间连接的内部过程等都只是一知半解...
  • l5201314131413141314
  • l5201314131413141314
  • 2011年12月12日 15:08
  • 7955

利用DirectShow开发C#版的视频播放器

    今天这里要给各位朋友介绍的是本人利用业余时间使用C#编写的一个视频播放器,开发环境为Microsoft Visual Studio 2008/C#、Microsoft DirectX 9.0 ...
  • huangxinfeng
  • huangxinfeng
  • 2010年09月19日 19:58
  • 9452

关于日期计算的一些辅助函数

最近项目用到大量的日期计算,现在整理了一下,供大家参考下,后续慢慢补充…… ...
  • qq_27682041
  • qq_27682041
  • 2017年09月28日 17:59
  • 115
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用于directshow的一些辅助函数
举报原因:
原因补充:

(最多只允许输入30个字)