سؤال

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)"

هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top