标签:blog http io color ar os 使用 sp for
转自: http://blog.csdn.net/bwmwm/article/details/5463852
1.创建一个空的Dll工程,添加5个空文件分别名为:MyOutputPin.h、MySourceFilter.h、MyOutputPin.cpp、MySourceFilter.cpp和MySourceFilter.def。
2.声明两个类,一个是Filter的实现类,一个是输出Pin的实现类,由于是最简单的源Filter,因此Filter只有一个输出Pin。实现的功能是从本地磁盘读取三个图片文件,轮流显示这三张图片,效果是模拟一个视频流。这两个类的声明代码:
- class CMySourceFilter
-
- : public CSource
- {
- public:
-
- static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
- private:
-
- CMySourceFilter(LPUNKNOWN lpunk, HRESULT *phr);
- };
- class CMyOutputPin
-
- :public CSourceStream
- {
- public:
- CMyOutputPin(HRESULT *phr, CSource *pFilter);
- ~CMyOutputPin(void);
-
-
-
-
- HRESULT FillBuffer(IMediaSample *pMediaSample);
-
-
- HRESULT DecideBufferSize(IMemAllocator *pIMemAlloc,
- ALLOCATOR_PROPERTIES *pProperties);
-
-
-
-
- HRESULT GetMediaType(int iPosition, CMediaType *pmt);
-
-
- HRESULT CheckMediaType(const CMediaType *pMediaType);
-
-
- STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q)
- {
- return E_FAIL;
- }
-
- private:
- BYTE* m_pData[3];
- int m_nWidth;
- int m_nHeight;
- int m_nImageSize;
- int m_nCount;
- };
3.实现CMySourceFilter类。这个类只有两个函数需要编写,很简单。
- CUnknown* CMySourceFilter::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
- {
-
- CUnknown *punk = new CMySourceFilter(lpunk,phr);
- if (punk == NULL)
- {
- *phr = E_OUTOFMEMORY;
- }
- return punk;
- }
-
- CMySourceFilter::CMySourceFilter(LPUNKNOWN lpunk, HRESULT *phr)
- : CSource(L"MyFilter",lpunk,CLSID_MyFilter,phr)
- {
-
-
- CMyOutputPin* pOutPin = new CMyOutputPin(phr,this);
- if (FAILED(*phr))
- {
-
- RemovePin(pOutPin);
- pOutPin->Release();
- }
- }
4.实现CMyOutputPin类,编写Filter主要就是写pin。
-
- CMyOutputPin::CMyOutputPin(HRESULT *phr, CSource *pFilter)
- : CSourceStream(L"MyFilter",phr,pFilter,L"Out")
- , m_nWidth(0)
- , m_nHeight(0)
- , m_nImageSize(0)
- , m_nCount(0)
- {
-
- m_pData[0] = LoadBitmapFileToMemory(L"E://DirectShow//MySourceFilter//1.bmp",
- m_nWidth,m_nHeight,m_nImageSize);
- m_pData[1] = LoadBitmapFileToMemory(L"E://DirectShow//MySourceFilter//2.bmp",
- m_nWidth,m_nHeight,m_nImageSize);
- m_pData[2] = LoadBitmapFileToMemory(L"E://DirectShow//MySourceFilter//3.bmp",
- m_nWidth,m_nHeight,m_nImageSize);
- }
-
- CMyOutputPin::~CMyOutputPin(void)
- {
-
- delete []m_pData[0];
- delete []m_pData[1];
- delete []m_pData[2];
- }
-
- HRESULT CMyOutputPin::GetMediaType(int iPosition, CMediaType *pmt)
- {
- CheckPointer(pmt,E_POINTER);
-
- CAutoLock cAutoLock(m_pFilter->pStateLock());
- if(iPosition < 0)
- {
- return E_INVALIDARG;
- }
-
- if(iPosition > 0)
- {
- return VFW_S_NO_MORE_ITEMS;
- }
-
-
-
- VIDEOINFO *pvi = (VIDEOINFO *) pmt->AllocFormatBuffer(sizeof(VIDEOINFO));
- if(NULL == pvi)
- return(E_OUTOFMEMORY);
-
- ZeroMemory(pvi, sizeof(VIDEOINFO));
- pvi->bmiHeader.biBitCount = 24;
- pvi->bmiHeader.biHeight = m_nHeight;
- pvi->bmiHeader.biWidth = m_nWidth;
- pvi->bmiHeader.biSizeImage = m_nImageSize;
- pvi->bmiHeader.biPlanes = 1;
- pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pvi->bmiHeader.biCompression = BI_RGB;
- pvi->bmiHeader.biClrImportant = 0;
-
- SetRectEmpty(&pvi->rcSource);
- SetRectEmpty(&pvi->rcTarget);
-
- pmt->SetType(&MEDIATYPE_Video);
- pmt->SetSubtype(&MEDIASUBTYPE_RGB24);
- pmt->SetFormatType(&FORMAT_VideoInfo);
- pmt->SetSampleSize(m_nImageSize);
- pmt->SetTemporalCompression(FALSE);
-
- return NOERROR;
- }
-
- HRESULT CMyOutputPin::CheckMediaType(const CMediaType *pMediaType)
- {
- CheckPointer(pMediaType,E_POINTER);
-
- if (*(pMediaType->Type()) != MEDIATYPE_Video
- || !(pMediaType->IsFixedSize()))
- {
- return E_INVALIDARG;
- }
-
- const GUID *SubType = pMediaType->Subtype();
- if (SubType == NULL)
- {
- return E_INVALIDARG;
- }
- if (*SubType != MEDIASUBTYPE_RGB24)
- {
- return E_INVALIDARG;
- }
- const GUID* FormatType = pMediaType->FormatType();
- if (FormatType == NULL)
- {
- return E_INVALIDARG;
- }
- if (*FormatType != FORMAT_VideoInfo)
- {
- return E_INVALIDARG;
- }
-
- VIDEOINFO* pvi = (VIDEOINFO*)pMediaType->Format();
- if (pvi == NULL)
- {
- return E_INVALIDARG;
- }
- if (pvi->bmiHeader.biBitCount != 24 ||
- pvi->bmiHeader.biWidth != m_nWidth ||
- pvi->bmiHeader.biHeight != m_nHeight)
- {
- return E_INVALIDARG;
- }
-
- return S_OK;
- }
-
- HRESULT CMyOutputPin::DecideBufferSize(IMemAllocator *pIMemAlloc, ALLOCATOR_PROPERTIES *pProperties)
- {
- CheckPointer(pIMemAlloc,E_POINTER);
- CheckPointer(pProperties,E_POINTER);
-
- CAutoLock cAutoLock(m_pFilter->pStateLock());
- HRESULT hr = NOERROR;
-
- VIDEOINFO *pvi = (VIDEOINFO *) m_mt.Format();
-
- pProperties->cBuffers = 1;
-
- pProperties->cbBuffer = m_nImageSize;
-
- ASSERT(pProperties->cbBuffer);
-
-
- ALLOCATOR_PROPERTIES Actual;
- hr = pIMemAlloc->SetProperties(pProperties,&Actual);
- if(FAILED(hr))
- {
- return hr;
- }
-
- if(Actual.cbBuffer < pProperties->cbBuffer)
- {
- return E_FAIL;
- }
-
- ASSERT(Actual.cBuffers == 1);
- return NOERROR;
- }
-
- HRESULT CMyOutputPin::FillBuffer(IMediaSample *pMediaSample)
- {
- CheckPointer(pMediaSample,E_POINTER);
- BYTE* pData = NULL;
- long lDataSize = 0;
-
-
- pMediaSample->GetPointer(&pData);
-
- lDataSize = pMediaSample->GetSize();
-
- ZeroMemory(pData,lDataSize);
-
- CopyMemory(pData,m_pData[m_nCount%3],m_nImageSize);
-
-
- REFERENCE_TIME start = TS_ONE * m_nCount;
- REFERENCE_TIME stop = TS_ONE + start;
- pMediaSample->SetTime(&start,&stop);
-
-
- m_nCount++;
-
- pMediaSample->SetSyncPoint(TRUE);
-
- return NOERROR;
- }
LoadBitmapFileToMemory函数的实现
- BYTE* LoadBitmapFileToMemory(TCHAR* pFileName, int& nWidth, int& nHeight, int& nImageDataSize)
- {
- HBITMAP hBitmap = (HBITMAP)LoadImage( NULL, pFileName, IMAGE_BITMAP, 0, 0,
- LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
-
- if(hBitmap == NULL)
- return NULL;
-
- HDC hDC = CreateCompatibleDC(NULL);
- HBITMAP hOldBitmap = (HBITMAP)SelectObject(hDC, hBitmap);
-
- BITMAP bmp;
- GetObject(hBitmap, sizeof(bmp), &bmp);
-
- BITMAPINFOHEADER bih = {0};
- bih.biBitCount = bmp.bmBitsPixel;
- bih.biCompression = BI_RGB;
- bih.biHeight = bmp.bmHeight;
- bih.biPlanes = 1;
- bih.biSize = sizeof(BITMAPINFOHEADER);
- bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;
- bih.biWidth = bmp.bmWidth;
-
- nImageDataSize = bmp.bmWidthBytes * bmp.bmHeight;
- byte * p = new byte[nImageDataSize];
- GetDIBits(hDC, hBitmap, 0, bmp.bmHeight, p,
- (LPBITMAPINFO) &bih, DIB_RGB_COLORS);
-
- SelectObject(hDC, hOldBitmap);
- DeleteObject(hBitmap);
- DeleteDC(hDC);
-
- nWidth = bmp.bmWidth;
- nHeight = bmp.bmHeight;
-
- return p;
- }
5.主要的工作已经做完了,功能已经实现,接下来就是生成Filter。
- extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
-
- BOOL APIENTRY DllMain(HANDLE hModule,
- DWORD dwReason,
- LPVOID lpReserved)
- {
- return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
- }
- STDAPI DllRegisterServer()
- {
- return AMovieDllRegisterServer2(TRUE);
-
- }
- STDAPI DllUnregisterServer()
- {
- return AMovieDllRegisterServer2(FALSE);
-
- }
-
- DEFINE_GUID(CLSID_MyFilter,
- 0x159386e0, 0x5193, 0x48ac, 0x8a, 0x57, 0x17, 0x88, 0xc7, 0x33, 0x40, 0xc1);
-
- const AMOVIESETUP_MEDIATYPE sudOpPinTypes =
- {
- &MEDIATYPE_Video,
- &MEDIASUBTYPE_NULL
- };
-
- const AMOVIESETUP_PIN sudOpPin =
- {
- L"Output",
- FALSE,
- TRUE,
- FALSE,
- FALSE,
- &CLSID_NULL,
- NULL,
- 1,
- &sudOpPinTypes };
-
- const AMOVIESETUP_FILTER sudBallax =
- {
- &CLSID_MyFilter,
- L"MyFilter",
- MERIT_DO_NOT_USE,
- 1,
- &sudOpPin
- };
-
-
-
-
- CFactoryTemplate g_Templates[] = {
- { L"MyFilter"
- , &CLSID_MyFilter
- , CMySourceFilter::CreateInstance
- , NULL
- , &sudBallax }
- };
- int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
6.MySourceFilter.def文件的内容
- LIBRARY "MySourceFilter.ax"
-
- EXPORTS
- DllMain PRIVATE
- DllGetClassObject PRIVATE
- DllCanUnloadNow PRIVATE
- DllRegisterServer PRIVATE
- DllUnregisterServer PRIVATE
7.注意
1)包含头文件 #include <initguid.h>,否则有可能提示 error LNK2001: 无法解析的外部符号 _CLSID_MyFilter
2)包含导出库#pragma comment(lib, "winmm")
3)包含导入库#pragma comment(lib, "strmbase.lib"),Debug下包含#pragma comment(lib, "strmbasd.lib")
8.大功告成。调用regsvr32注册Filter。使用GraphEdit调试Filter。(VS2005)
在工程的属性中选择调试,在命令中填入GraphEdit的完整路径,把Filter的工程作为启动项。按下F5,在运行的GraphEdit中选择我们的Filter,Render pin,就可以看到一条完整的链路,然后run,效果出来了,三幅图片轮流显示在窗口中。
DirectShow基础编程 最简单的源Filter的编写步骤 (转)
标签:blog http io color ar os 使用 sp for
原文地址:http://www.cnblogs.com/signal/p/4094102.html