实现file writer filter

Directshow中用来写文件的filter主要是file writer filter,另外在DirectX的参考代码中有一个dump的例子。由于特定的应用及PPC/Smartphone等Windows CE平台的需求,常常要自己编写file writer filter。

1. filter之间传送数据

两个filter之间是怎样传送数据在Directshow文档中有详细说明,一般都是input pin实现IMemInput接口,outpin pin调用input pin的IMemInput接口上的Receive函数。其实这就是一种推模式,一个filter graph链路中,除了source filter和后续transform filter(如mux/demux filter)之间可能是拉模式外,后面filter之间一般都是采用推模式来传送数据。形象地说,上一级filter对后一级filter说:“来,你要的东东已经准备好了,把你的手升过来,我给你”。这里所说的手也就是下filter提供的接受数据的方法,如IMemInput::Receive()。当然,下一个filter如果是render filter的话,它还可以提供其他方法去供上一级filter调用来获取数据。也就是下面所说的Istream接口。

2. IStream接口

里面的方法就不多说了,它是一个提供数据传送和控制的接口。如果在render filter上实现这个接口,那么它就是向上级filter提供的又一个“手”。当然,IStream接口提供的方法与IMemInput::Receive()用着很大的区别,前者可控制流对象,如文件和整个读写缓存等,在file writer filter中实际应用;后者只是负责接收media sample,在两个filter之间起到传接数据的作用。

3. file writer filter的实现

从文档中可以看出,MS提供的file writer filter与dump filter之间最大的区别在于前者实现的IStream接口。它可以对读写的文件对象进行控制和操作,如在写文件结束之前,在文件的开始处插入一个文件格式头,如AVI文件头。实际的写音视频码流一般是IMemInput::Receive()接收之后,再writefile的,我们也可以直接调用IStream::Write()来实现。所以说,写file writer filter实现Istream接口是关键。下面是我写avi writer filter时IStream::write()的实现,实际上它也可以用来写其他格式的文件:

STDMETHODIMP CStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
{
 DWORD dwWritten;
 
    // If the file has already been closed, don't continue
    if (m_pAVIWriter->m_hFile == INVALID_HANDLE_VALUE) {
        return S_FALSE;
    }
    if (!WriteFile(m_pAVIWriter->m_hFile, (PVOID)pv, (DWORD)cb,
  &dwWritten, NULL))
    {
        return S_FALSE;
    }
 
    return S_OK;
}

也就是一般的写文件,再配合seek()等方法,就可以实现在写文件结束前把avi头写到文件的开始处


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wolf_baby/archive/2006/04/21/671312.aspx

你可能感兴趣的:(File,filter,Graph,文档,input,avi)