#include "..\include\asyncio.h"
#include "..\include\asyncrdr.h"
class CCDIPin : public CAsyncStream
{
public:
CCDIPin();
virtual ~CCDIPin();
/* Initialization */
HRESULT Init(LPCOLESTR lpwszFileName, DWORD dwKBPerSec = INFINITE);
HRESULT SetPointer(LONGLONG llPos);
HRESULT Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead);
LONGLONG Size(LONGLONG *pSizeAvailable);
DWORD Alignment() { return 1; }
void Lock() { m_csLock.Lock(); }
void Unlock() { m_csLock.Unlock(); }
private:
CCdiDec m_decoder; // 我的解码器,封装了一个dll中的函数调用
CCritSec m_csLock;
DWORD m_dwSize;
DWORD m_dwPosition;
DWORD m_dwKBPerSec;
DWORD m_dwTimeStart;
};
class CCDISource : public CAsyncReader
{
public:
CCDISource(CCDIPin *pStream, CMediaType *pmt, HRESULT *phr)
: CAsyncReader(NAME("CDI source filter"), NULL, pStream, phr)
{
m_mt = *pmt;
}
~CCDISource() {};
// We're not going to be CoCreate'd so we don't need registration
// stuff etc
STDMETHODIMP Register()
{
return S_OK;
}
STDMETHODIMP Unregister()
{
return S_OK;
}
};
--------------------------------------------------------------------------------
#include <streams.h>
#include "CDISource.h"
CCDIPin::CCDIPin()
: m_dwPosition(0), m_dwSize(0), m_dwKBPerSec(INFINITE)
{}
CCDIPin::~CCDIPin()
{}
HRESULT CCDIPin::Init(LPCOLESTR lpwszFileName, DWORD dwKBPerSec)
{
if(S_OK != m_decoder.LoadFile(lpwszFileName))
return S_FALSE;
if(S_OK != m_decoder.GetSize(&m_dwSize))
return S_FALSE;
m_dwKBPerSec = dwKBPerSec;
m_dwTimeStart = timeGetTime();
return S_OK;
}
HRESULT CCDIPin::SetPointer(LONGLONG llPos)
{
if (llPos < 0 || llPos > (LONGLONG)m_dwSize)
return S_FALSE;
m_dwPosition = (DWORD)llPos;
return S_OK;
}
HRESULT CCDIPin::Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead)
{
CAutoLock lck(&m_csLock);
DWORD dwReadLength;
/* Wait until the bytes are here! */
DWORD dwTime = timeGetTime();
if (m_dwPosition + dwBytesToRead > m_dwSize)
dwReadLength = (DWORD)(m_dwSize - m_dwPosition);
else
dwReadLength = dwBytesToRead;
DWORD dwTimeToArrive = (m_dwPosition + dwReadLength) / m_dwKBPerSec;
if (dwTime - m_dwTimeStart < dwTimeToArrive)
{
Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
}
HRESULT hr = m_decoder.ReadData(m_dwPosition, pbBuffer, dwReadLength, &dwReadLength);
ASSERT(hr == S_OK);
m_dwPosition += dwReadLength;
*pdwBytesRead = dwReadLength;
return S_OK;
}
LONGLONG CCDIPin::Size(LONGLONG *pSizeAvailable)
{
LONGLONG llCurrentAvailable =
static_cast <LONGLONG> (UInt32x32To64((timeGetTime() - m_dwTimeStart), m_dwKBPerSec));
*pSizeAvailable = min((LONGLONG)m_dwSize, llCurrentAvailable);
return (LONGLONG)m_dwSize;
}
--------------------------------------------------------------------------------
//测试程序
#include <streams.h>
#include <stdio.h>
#include <asyncio.h>
#include <asyncrdr.h>
#include "memfile.h"
#include "cdisource.h"
/* Fail gracefully if UNICODE build is enabled */
#ifdef UNICODE
#error This application does not build for UNICODE.
#endif
/* Function prototypes */
HRESULT SelectAndRender(CMemReader *pReader, IFilterGraph **pFG);
HRESULT PlayFileWait(IFilterGraph *pFG);
/* Read a file into memory, play it (or part of it), then exit */
int main(int argc, char *argv[])
{
CMediaType mt;
mt.majortype = MEDIATYPE_Stream;
mt.subtype = MEDIASUBTYPE_NULL;
HRESULT hr = S_OK;
CoInitialize(NULL);
CCDIPin Stream;
Stream.Init(L"c:\\temp\\coffee3.cdi");
CCDISource Source(&Stream, &mt, &hr);
if (FAILED(hr)) {
printf("Could not create filter HRESULT 0x%8.8X\n", hr);
CoUninitialize();
return 1;
}
// Make sure we don't accidentally go away!
Source.AddRef();
IFilterGraph *pFG = NULL;
/* Create filter graph */
// 下面都没有验证返回值,我设了断点,一步一步跟的
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IFilterGraph, (void**) &pFG);
/* Add our filter */
hr = pFG->AddFilter(&Source, NULL);
/* Render our output pin */
IGraphBuilder *pBuilder;
hr = pFG->QueryInterface(IID_IGraphBuilder, (void **)&pBuilder);
hr = pBuilder->Render(Source.GetPin(0));
pBuilder->Release();
if (FAILED(hr))
printf("Failed to create graph and render file HRESULT 0x%8.8X", hr);
else
{
// Play the file
HRESULT hr = PlayFileWait(pFG);
if (FAILED(hr)) {
printf("Failed to play graph HRESULT 0x%8.8X",
hr);
}
}
if (pFG) {
ULONG ulRelease = pFG->Release();
if (ulRelease != 0) {
printf("Filter graph count not 0! was %d", ulRelease);
}
}
CoUninitialize();
return 0;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zcq108/archive/2009/12/17/5027141.aspx