directshow CBaseRenderer クラスから派生したカスタム directshow フィルターを作成しました。次のコードは私のフィルターです。
class CRenderSamples : public CBaseRenderer
{
// private data members
// constructors and destructors are private, need to use CoCreateInstance(.)
protected:
//BYTE *m_pCopyBuffer;
CMediaType m_MediaType;
CRenderSamples(LPUNKNOWN pUnk,HRESULT *phr);
virtual ~CRenderSamples();
public:
//The CheckMediaType method determines if the
//filter accepts a specific media type.
virtual HRESULT CheckMediaType(const CMediaType *pMediaType);
// The DoRenderSample method renders a sample.
virtual HRESULT DoRenderSample(IMediaSample *pMediaSample);
// Instantiate filter object
static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
};
フィルターを正常に作成し、COM に登録しました。また、GraphEdit で pushsourcedesktop フィルターと組み合わせてフィルターをテストしたところ、期待どおりに動作しました。問題はコーディングにあります。フィルター オブジェクトのインスタンス化に使用するポインターの型について、少し混乱しています。IBaseFilter ポインターを使用してフィルター オブジェクトをインスタンス化すると、すべて正常に動作しますが、独自のフィルターに実装する DoRenderSamBple() メソッドを使用できません。ただし、CBaseRenderer を使用すると、AddFilter() 関数の最初のパラメーターが IBaseFilter ポインターを必要とするため、ランタイム エラーが発生します。次のコードは私のアプリです。
#include <stdio.h>
#include <windows.h>
#include <ObjBase.h>
#include <DShow.h>
#include <initguid.h>
#include <stdlib.h>
#include <streams.h>
#include "PushGuids.h"
//#pragma once
#pragma comment(lib,"Strmiids.lib")
static const GUID CLSID_RENDER_SAMPLES = {0x9ddd8a2a, 0xa66c, 0x423a, { 0xa7, 0xb1,
0xc3, 0x22, 0xae, 0xbc, 0x1c, 0x1e } };
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
){
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent* pEvent = NULL;
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
MessageBox(NULL,TEXT("ERROR - Could not initialize COM library."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr)) {
MessageBox(NULL,TEXT("Could not create the Filter Graph Manager."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}
hr = pGraph -> QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph -> QueryInterface(IID_IMediaEvent, (void **)&pEvent);
IBaseFilter* pPushSourceDesktop = 0;
hr = CoCreateInstance(CLSID_PushSourceDesktop, 0, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pPushSourceDesktop);
if (FAILED(hr)) {
MessageBox(NULL,TEXT("Could not create PushSourceDesktop filter."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}
hr = pGraph -> AddFilter(pPushSourceDesktop, L"PushSourceDesktop");
if (FAILED(hr)) {
MessageBox(NULL,TEXT("Could not add PushSourceDesktop filter."),TEXT("Error!"),MB_OK);
return 0;
}
//IBaseFilter *pRenderSamples;
CBaseRenderer *pRenderSamples;
//IBaseFilter *pRenderer;
hr = CoCreateInstance(CLSID_RENDER_SAMPLES,0,CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pRenderSamples);
if (FAILED(hr)) {
MessageBox(NULL,TEXT("Could not instantiate RenderSamples."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}else{
MessageBox(NULL,TEXT("Successfully instantiate RenderSamples filter."),TEXT("Success!"),MB_OK);
}
hr = pGraph -> AddFilter(pRenderSamples, L"Render Samples");
if (FAILED(hr)) {
MessageBox(NULL,TEXT("Could not add RenderSamples filter."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}else{
MessageBox(NULL,TEXT("Successfully add RenderSamples filter."),TEXT("Success!"),MB_OK);
}
IPin **ppPushPinDesktop = new (IPin*);
hr = pPushSourceDesktop -> FindPin(L"1", ppPushPinDesktop);
if (FAILED(hr)) {
MessageBox(NULL,TEXT("Could not find pin of filter PushSourceDesktop."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}
IPin **ppRenderSamples = new (IPin*);
hr = pRenderSamples -> FindPin(L"In", ppRenderSamples);
switch(hr)
{
case S_OK:
MessageBox(NULL,TEXT("Successfully find pin."),TEXT("Success!"),MB_OK);
break;
case E_POINTER:
MessageBox(NULL,TEXT("Null pointer argument."),TEXT("Null Pointer!"),MB_OK);
return EXIT_FAILURE;
case VFW_E_NOT_FOUND:
MessageBox(NULL,TEXT("Could not find a pin with this identifier."),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}
hr = pGraph -> Connect(*ppPushPinDesktop,*ppRenderSamples);
switch(hr){
case S_OK:
MessageBox(NULL,TEXT("Successfully connect PushSourceDesktop and RenderSamples."),TEXT("Success!"),MB_OK);
break;
case VFW_S_PARTIAL_RENDER:
MessageBox(NULL,TEXT("Partial success; some of the streams from this pin use an unsupported format."),
TEXT("Partial success!"),MB_OK);
break;
case E_ABORT:
MessageBox(NULL,TEXT("Operation aborted."),TEXT("Aborted!"),MB_OK);
break;
case E_POINTER:
MessageBox(NULL,TEXT("NULL pointer argument."),TEXT("NULL Pointer!"),MB_OK);
break;
case VFW_E_CANNOT_CONNECT:
MessageBox(NULL,TEXT("No combination of intermediate filters could be found to make the connection."),TEXT("Aborted!"),MB_OK);
break;
case VFW_E_NOT_IN_GRAPH:
MessageBox(NULL,TEXT("At least one of the filters is not in the filter graph."),TEXT("Filter no in filter graph"),MB_OK);
break;
default:
MessageBox(NULL,TEXT("Unknow error"),TEXT("Error!"),MB_OK);
return EXIT_FAILURE;
}
pControl -> Release();
pEvent -> Release();
(*ppPushPinDesktop) -> Release();
pPushSourceDesktop -> Release();
pRenderSamples-> Release();
(*ppRenderSamples)->Release();
pGraph -> Release();
CoUninitialize();
return EXIT_SUCCESS;
}
誰でもそのような問題を解決するためのアイデアを与えることができますか? どうもありがとうございました!!!