Reputation: 5971
I get the following exception when i call my filters getpin() method:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
So it seems there is a wrong calling convetion used
I tried to fix this in the filter header:
Changed:
CBasePin* GetPin(int n);
To:
CBasePin* __stdcall GetPin(int n);
But this won't compile because it says (translated from german)
The overriding virtual function only differs from CBaseFilter::GetPin by calling convention
I also tried to set the calling convention in the project configuration but this didn't work.
So what do I do now?
This is the filter interface:
class MyFilter : public CBaseFilter, public IMyFilter
{
public:
DECLARE_IUNKNOWN;
MyFilter(LPUNKNOWN pUnk, HRESULT* phr);
virtual ~MyFilter(void);
int GetPinCount();
CBasePin* GetPin(int n);
void acceptFilterInput(LPCWSTR pinname, IMediaSample* sample);
static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
STDMETHODIMP STDMETHODCALLTYPE StartRecording();
STDMETHODIMP STDMETHODCALLTYPE Pause();
STDMETHODIMP STDMETHODCALLTYPE Stop();
CCritSec m_lock_filter;
CBaseInputPin* pin0;
CBaseInputPin* pin1;
CBaseInputPin* pin2;
MCMyOutputPin *outpin;
private:
CCritSec m_critSec;
std::vector<IMediaSample*> samplesPin0;
std::vector<IMediaSample*> samplesPin1;
std::vector<IMediaSample*> samplesPin2;
LPCWSTR currentInputPin;
void workerThread();
void processQueue(std::vector<IMediaSample*> pPinSamples);
};
THis is how I use the filter:
int static doSomeWork()
{
CoInitialize(NULL);
IGraphBuilder* pGraph = NULL;
IMediaControl* pMediaControl = NULL;
IMediaEvent* pMediaEvent = NULL;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_ALL, IID_IFilterGraph, (void **) &pGraph);
if(hr < 0)
{
return -1;
}
IBaseFilter* pSource = NULL;
pGraph->QueryInterface(IID_IMediaControl, (void **) pMediaControl);
pGraph->QueryInterface(IID_IMediaEvent, (void **) pMediaEvent);
pGraph->AddSourceFilter(TEXT("C:\\TEMP\\video1.avi"), 0, &pSource);
IPin* pSourceOut = GetPin(pSource, PINDIR_OUTPUT);
IBaseFilter* pAVISplitter = NULL;
CoCreateInstance(CLSID_AviSplitter, NULL,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
(void**)&pAVISplitter);
IPin* pAvIIn = GetPin(pAVISplitter, PINDIR_INPUT);
pGraph->AddFilter(pAVISplitter, L"Splitter");
pGraph->Connect(pSourceOut, pAvIIn);
IPin* pAVIOut = GetPin(pAVISplitter, PINDIR_OUTPUT);
MyFilter* myfilter;
hr = CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)& myfilter);
if(hr < 0)
{
return -1;
}
IPin* myfilterIn = myfilter->GetPin(0);
IPin* myFilterOut = myfilter->GetPin(3);
pGraph->Connect(pAVIOut, myfilterIn);
pGraph->Render(myFilterOut);
CoUninitialize();
return 0;
}
The error hapens at "myFilter->GetPin(0)"
Upvotes: 3
Views: 320
Reputation: 69706
The problem you are having is caused by your violating COM fundamentals.
MyFilter* myfilter;
hr = CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)& myfilter);
CoCreateInstance
or QueryInterface
or similar with IID_IBaseFilter
argument will return you IBaseFilter*
pointer. You are supposed to correctly reinterpret received pointer for correct further use.
You take IBaseFilter*
and then apply reinterpret cast to MyFilter*
- this is not going to work. You still have IBaseFilter*
pointer and calling other methods on it is causing undefined behavior.
To cut long story short, you cannot (you can, but beginner level version of the answer here is you cannot) have MyFilter*
pointer on the controlling application, you can only have COM interface pointers there.
Upvotes: 5