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