DX90SDK SDK源码分析(一) 拉模式的例子

原创 2012年03月22日 15:07:22

 

转载请标明是引用于 http://blog.csdn.net/chenyujing1234

 例子代码:(包括asynbase asyncflt baseclasses memfile)(编译工具:VS2005)

 http://www.rayfile.com/zh-cn/files/d2b6051c-73ed-11e1-8768-0015c55db73d/

参考书<<DirectShow开发指南>>

 

工程介绍: 

它位于目录 Samples\C++\DirectShow\Filters\Async下

asynbase:是一个静态项目,实现了异步读写的基类;

async: 使用了asynbase库,实现了一个拉模式的source Filter;

memfile:使用了asynbase库,在应用程序中实现了一个不注册的拉模式source filter,然后进行媒体文件的播放.

DirectShow提供了一个标准的File Source(Async.)(CLSID为CLSDID_AysncReader),作为一般媒体文件播放的Source Filter,

async也实现了类似的功能。可以把它看成是一个简化了的File Source(Async)

将C:\DX90SDK\Samples\C++\DirectShow\Filters\Async\Filter\asyncflt.reg注入注册表.

然后用程序->Microsoft DirectX 9.0 SDK Update (->DirectX Utilities->GraphEdit可以看到,如下图

1.1.1实现要点.

请参考我上传的源码里的注释。

1.1.2编译过程。

  把工程asynbase asyncflt  memfile的C++->命令行里加 /wd4430

  在memfile.cpp里的 _tmain( int argc, TCHAR* argv[] )文件里直接定义媒体文件。

  argc = 2;
 TCHAR *tPlayFile =  "D:\\自己的经验总结\\自己的经验总结\\DX90DK_Samples\\Samples\\C++\\DirectShow\\Filters_vs2005\\Async\\MEMFile\\Debug\\test.avi";
 

1.1.3 调试过程


 为方便调试,把三个工程组织在一个解决方案里,且修改asynbase asyncflt 工程的属性:

调试-> 命令->D:\自己的经验总结\自己的经验总结\DX90DK_Samples\Samples\C++\DirectShow\Filters_vs2005\Async\MEMFile\Debug\memfile.exe

这里请大家注意了:asyncflt 作为一个filter,产生的ax目标文件注不注册对调试memFile没有影响。

但为了学习注册ax文件,我还是做了注册.

把注册表asyncflt.reg注入注册表中,且把asyncflt.ax文件注册到系统中(参考:http://blog.csdn.net/chenyujing1234/article/details/7382232)

 

1.1.4

调试分析:

1、memfile.cpp里的SelectAndRender(CMemReader *pReader, IFilterGraph **ppFG)函数里的 

hr = pBuilder->Render(pReader->GetPin(0));中的GetPin会调用到

CBasePin * CAsyncReader::GetPin(int n)四次

pBuilder->Render调用到了以下函数:

CAsyncOutputPin::Connect(

   HRESULT CAsyncOutputPin::CheckMediaType(const CMediaType* pType)

  CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

 

 

CAsyncOutputPin::Connect(

   HRESULT CAsyncOutputPin::CheckMediaType(const CMediaType* pType)

  CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

 

  CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

 

CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

 

CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

 

CAsyncOutputPin::RequestAllocator( )

 // ----------------------这个函数一直没有调用hr = InitAllocator(&pAlloc);

// ----------------------而是到了
        if(SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
        {
            pPreferred->AddRef();
            *ppActual = pPreferred;
            return S_OK;
        }

就跳出来了

// we need to return an addrefed allocator, even if it is the preferred
// one, since he doesn't know whether it is the preferred one or not.
STDMETHODIMP 
CAsyncOutputPin::RequestAllocator(
    IMemAllocator* pPreferred,
    ALLOCATOR_PROPERTIES* pProps,
    IMemAllocator ** ppActual)
{
    CheckPointer(pPreferred,E_POINTER);
    CheckPointer(pProps,E_POINTER);
    CheckPointer(ppActual,E_POINTER);
    ASSERT(m_pIo);

	_tprintf(_T("------------FILE %s CAsyncOutputPin::RequestAllocator\n"), __FILE__);
    // we care about alignment but nothing else
    if(!pProps->cbAlign || !m_pIo->IsAligned(pProps->cbAlign))
    {
        m_pIo->Alignment(&pProps->cbAlign);
    }

    ALLOCATOR_PROPERTIES Actual;
    HRESULT hr;

    if(pPreferred)
    {
        hr = pPreferred->SetProperties(pProps, &Actual);

        if(SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
        {
            pPreferred->AddRef();
            *ppActual = pPreferred;
            return S_OK;
        }
    }

    // create our own allocator
    IMemAllocator* pAlloc;
    hr = InitAllocator(&pAlloc);
    if(FAILED(hr))
    {
        return hr;
    }

    //...and see if we can make it suitable
    hr = pAlloc->SetProperties(pProps, &Actual);
    if(SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
    {
        // we need to release our refcount on pAlloc, and addref
        // it to pass a refcount to the caller - this is a net nothing.
        *ppActual = pAlloc;
        return S_OK;
    }

    // failed to find a suitable allocator
    pAlloc->Release();

    // if we failed because of the IsAligned test, the error code will
    // not be failure
    if(SUCCEEDED(hr))
    {
        hr = VFW_E_BADALIGN;
    }
    return hr;
}


CAsyncOutputPin::Length(

CAsyncReader::GetPin(int n)

CAsyncReader::GetPin(int n)

CAsyncReader::GetPin(int n)

 

CAsyncOutputPin::Connect(

   HRESULT CAsyncOutputPin::CheckMediaType(const CMediaType* pType)

  CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

 

  CAsyncOutputPin::SyncRead(

  CAsyncIo::SyncRead(

  CAsyncIo::SyncReadAligned(

CAsyncRequest::Complete()

............

 

结束SelectAndRender(CMemReader *pReader, IFilterGraph **ppFG)函数

 

CAsyncReader::GetPin(int n)

CAsyncReader::GetPin(int n)

CAsyncOutputPin::WaitForNext(

  CAsyncOutputPin::SyncRead(

CAsyncReader::GetPin(int

CAsyncIo::WaitForNext(

CAsyncOutputPin::SyncRead(

CAsyncReader::GetPin(int n)

CAsyncIo::WaitForNext(

 

hr = pME->WaitForCompletion(INFINITE, &levCode);

 CAsyncOutputPin::Request(

CAsyncIo::Request(

CAsyncIo::PutWorkItem(CAsyncRequest* pRequest)

 hr = StartThread();

   m_hThread = CreateThread(NULL,                             0,
                            InitialThreadProc,  // InitialThreadProc : 在线程中调用来处理一个活动的请求

                            this,

。。。。。。。

接下来就一直在线程中取请求,等待,处理请求中

表现在运行结果就是发现停在hr = pME->WaitForCompletion(INFINITE, &levCode);没反应了。

 

由于是拉模式的例子,为了调试pullpin.cpp,我们也把baseclasses放到解决方案中。

 ===========================================================================================================

总结:

在《DircctShow开发指南》一书中有下面一段话:

DirectShow为局部存储器传输定义了两种机制:推模式(push model)和拉模式(pull model)。在推模式中,源过滤器生成数据并提交给下一级过滤器。下一级过滤器被动的接收数据,完成处理后再传送给再下一级过滤器。在拉模式中,源过滤器与一个分析过滤器相连。分析过滤器向源过滤器请求数据后,源过滤器才传送数据以响应请求。推模式使用的是IMemInputPin接口,拉模式使用IAsyncReader接口,推模式比拉模式要更常用。

大家可以比较我的两篇文章:

<<DX90SDK SDK源码分析(二) 推模式的例子>> http://blog.csdn.net/chenyujing1234/article/details/7402831

<<DX90SDK SDK源码分析(一) 拉模式的例子>>

就可以发现上面这段话的内容了.

// CAsyncOutputPin实现了一个输出Pin
// 继承自IAsyncReader、CBasePin,这是对拉模式的Source Filter的基本要求
/* IAsyncReader接口方法及描述如下:
BeginFlush  放弃所有正在进行的数据读取
EndFlush    与BeginFlush配对,标示Flush过程结束
Length      得到数据总长度和当前可以读取的长度
RequestAlloctor 要求一个输入Pin上的Sample管理器
Request     发出一个数据请求
SyncReadAligned 同步读取数据(边界对齐)
SyncRead    同步读取数据
WaitForNext 等待一个请求的完成
======================================================================
可以看出CAsyOutputPin类上实现的IAsyncReader的各个接口方法,都“委托”
给了CAsyncIo类对象的同名成员函数
*/
class CAsyncOutputPin
  : public IAsyncReader, 
    public CBasePin
{


 

DirectX9.0b SDK下载地址及安装说明

DirectX9.0 SDK 开发包版本较多,DirectX9.0b 版本之前的SDK 包基本是完整的, DirectX9.0c 版本的SDK 包大多是升级包,里面并未附带DirectShow 部分...
  • xxrhuanhuan
  • xxrhuanhuan
  • 2012年06月08日 21:11
  • 14664

DX90SDK SDK源码分析(一) 拉模式的例子

转载请标明是引用于 http://blog.csdn.net/chenyujing1234  例子代码:(包括asynbase asyncflt baseclasses memfile)(编译工具:...
  • chenyujing1234
  • chenyujing1234
  • 2012年03月22日 15:07
  • 2576

dx90bsdk.7z.002

  • 2012年09月03日 14:19
  • 95MB
  • 下载

DX90SDK SDK源码分析(一) 拉模式的例子 MEMFILE

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 例子代码:(包括asynbase asyncflt baseclasses memfile)(编译工具:V...
  • bigwudan
  • bigwudan
  • 2013年04月28日 00:11
  • 765

DX90SDK SDK源码分析(二) 推模式的例子

转载请标明是引用于 http://blog.csdn.net/chenyujing1234  例子代码:(编译工具:VS2005) http://www.rayfile.com/zh-cn/fil...
  • chenyujing1234
  • chenyujing1234
  • 2012年03月28日 14:48
  • 2217

dx90bsdk.7z.001

  • 2012年09月03日 11:16
  • 95MB
  • 下载

DirectShow SDK下载

  今天忙了一下午终于找到下载DirectShow SDK的网址啦,和大家共享!!dxsdk_feb2005_extras sdk 下载网址 :http://download.microsoft.co...
  • pfjhbui
  • pfjhbui
  • 2008年03月13日 16:55
  • 10156

拉推模式总结

转载至:http://leign.iteye.com/blog/613508最近做一个消息系统,其中涉及到新消息数的即时更新,当时就想到了观察者模式,后来听同事提到推拉模式,感觉推模式原理上应该还是属...
  • u012006909
  • u012006909
  • 2016年10月24日 10:45
  • 1530

观察者模式中的推模式与拉模式

观察者模式中的推模式与拉模式[摘录] 在Observer模式中区分推模式和拉模式,先简单的解释一下两者的区别:推模式是当有消息时,把消息信息以参数的形式传递(推)给所有观察者,而拉模式是当有消息时,...
  • huanghailang
  • huanghailang
  • 2012年12月20日 17:52
  • 1033

DirectShow SDK编译中易出现的问题

由于需要进行视频采集,昨天开始搜索资料,发现现在流行的是DirectShow来进行开发,昨天下载安装了个DirectX 9.0 SDK,于是痛苦的配置旅程开始了。现在我们来重温一下这个痛苦的历程吧。先...
  • abcjennifer
  • abcjennifer
  • 2012年05月10日 21:48
  • 4043
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DX90SDK SDK源码分析(一) 拉模式的例子
举报原因:
原因补充:

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