2014-04-04 1 views
0

필터 출력 핀을 다른 필터에 연결하려고 할 때 다음 오류가 발생합니다.Outputpin에서 통화 규칙 충돌이 발생했습니다

class MCMyOutputPin : public CBaseOutputPin 
{ 
    .... 
    HRESULT CheckMediaType(const CMediaType *pmt); 
    HRESULT SetMediaType(const CMediaType *pmt); 
    HRESULT CompleteConnect(IPin *pReceivePin); 
    //virtual HRESULT __stdcall Connect(IPin* pPin, const AM_MEDIA_TYPE *pmt); 
    HRESULT BreakConnect(); 
    HRESULT GetMediaType(int i, CMediaType *pmt); 
    HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProps); 
    HRESULT DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc); 
    HRESULT Deliver(IMediaSample* sample); 
    BOOL IsConnected(); 

    ... 

내가 DecideAllocator 믿을 GetAllocatorRequirements에 의해 호출된다 :

enter image description here

합니다 (outputpin 코드) 오류를 트리거 라인 여기에 함수 선언

HRESULT hr = pPin->GetAllocatorRequirements(pprops); 

입니다.

은 MSDN에 따르면 (Building DirectShw Filters) 함수는 __stdcall로 선언해야합니다. 호출하는 함수와 호출 된 함수 사이에 호출 컨벤션 충돌이있는 것 같습니다. 내가 __stdcall하는 기능을 설정하려고하지만 경우 :

'MCMyOutputPin::DecideAllocator': overriding virtual function differs from 'CBaseOutputPin::DecideAllocator' only by calling convention

그래서 내가 stdcall을 사용하여 호출 규칙을 BASECLASSES가 내장되어 있는지 확인하려고 : 나는 열 내가 컴파일 오류가

HRESULT __stdcall DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc); 

을 BASECLASSES 프로젝트 (C : \ 프로그램 파일 (마이크로 소프트의 SDK \ WINDOWS \ 7.0의 \ 샘플 \ 86) \ 멀티미디어 \ DirectShow를의 \의 BASECLASSES) 그리고

ConfigurationProperties->C/C++->Advanced->Calling Convention to __stdcall(/Gz)

을 설정그래서 요약 :

  • 내가 컨벤션 충돌
  • 를 호출 한 나는 BASECLASSES 프로젝트에서 호출 규칙을 설정 내 코드
  • 의 호출 규칙을 변경할 수 없습니다 및 재 컴파일이 여전히 해결되지 않는 생각 문제

하지만 난 여전히 stdcall을 내 프로젝트의 outputpins 기능의 호출 규칙을 변경할 수 없습니다

업데이트 :

912,992,967,이 내 필터 NonDelegatingQueryInterface : 여기

STDMETHODIMP MyFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv) 
{ 
    if(riid == IID_IMyInterfilter) { 
     mylogger->LogDebug("In Nondelegationqueryinterface", L"D:\\TEMP\\yc.log"); 
     return GetInterface((IMyFilter*)this, ppv); 
    } 

    else 
    { 
     return CBaseFilter::NonDelegatingQueryInterface(riid, ppv); 
    } 
} 

이 필터는 헤더 :

#include "MyInputPin.h" 
#include "CMyOutPutPin.h" 
#include "MyLogger.h" 
#include <windows.h> 
#include <process.h> 
#include <string> 

using namespace std; 



MyFilter::MyFilter(LPUNKNOWN pUnk, HRESULT* phr) : CBaseFilter(NAME("MyFilter"), pUnk, &lockfilter, CLSID_MyInterFilter) 
{ 


    HRESULT *hr_0 = NOERROR; 
    HRESULT *hr_1 = NOERROR; 
    HRESULT* hr_2 = NOERROR; 
    HRESULT* hr_3 = NOERROR; 


    inputpins[0] = new CMyInputPin(TEXT("PIN0"), L"PIN0", pUnk, this, &this->m_lock_filter, hr_0, 0); 
    inputpins[1] = new CMyInputPin(TEXT("PIN1"), L"PIN1", pUnk, this, &this->m_lock_filter, hr_1, 1); 
    inputpins[2] = new CMyInputPin(TEXT("PIN2"), L"PIN2", pUnk, this, &this->m_lock_filter, hr_2, 2); 
    outpin = new MCMyOutputPin(this, hr_3, TEXT("PINOUT0")); 
    this->running = false; 
    mylogger = new MyLogger(); 

    mylogger->LogDebug("Construtor of Filter", L"D:\\TEMP\\yc.log"); 

    m_pTimeGiver = new TimeGiver(2, MEDIATIME); 








} 

CMyInputPin* MyFilter::getPreviousPIN(LPCWSTR pinname) 
{ 
    CMyInputPin *inpin = GetPinByName(pinname); 
    int position = inpin->m_position; 
    int adjused = position + COUNT_INPUTPINS - 1; 
    int newInex = adjused % COUNT_INPUTPINS; 
    return inputpins[newInex]; 

} 
CMyInputPin* MyFilter::getNextPIN(LPCWSTR pinname) 
{ 
    CMyInputPin *inpin = GetPinByName(pinname); 
    int position = inpin->m_position; 
    int incremented = position++; 
    int newIndex = incremented % COUNT_INPUTPINS; 
    return inputpins[newIndex]; 
} 
//BOOL MyFilter::requestRecordMode(LPCWSTR pinname) { //returns false if previous pin thread is not sleeping 
// for (int i = 0; i < COUNT_INPUTPINS; i++) 
// { 
//  if (wcscmp(pinname, inputpins[i]->Name()) == 0) 
//  { 
//   inputpins[i]->m_bIsSleeping = false; 
//  } 
//  else { 
//   inputpins[i]->m_bIsSleeping = true; 
//  } 
// 
// } 
// return TRUE; 
//} 


HRESULT MyFilter::Run(REFERENCE_TIME tStart) 
{ 
    mylogger->LogDebug("In MyFilter::Run:", L"D:\\TEMP\\yc.log"); 
    CAutoLock cobjectlock(&m_critSec); 
    workerThreadHandle = (HANDLE) _beginthreadex(NULL, 0, workerthreadfunc, (void *)this, 0, NULL); 
    //boost::thread workerThread(&MyFilter::startSyncThread, this); 
    m_tStart = tStart; 
    if (m_State == State_Stopped){ 
     HRESULT hr = Pause(); 

     if (FAILED(hr)) { 
      return hr; 
     } 
    } 


    return S_OK; 
} 

HRESULT MyFilter::Stop() 
{ 
    mylogger->LogDebug("In MyFilter::Stop:", L"D:\\TEMP\\yc.log"); 
    CAutoLock cobjectlock(&m_critSec); 
    m_State = State_Stopped; 
    this->m_pTimeGiver->stop(); 
    //this->m_thread.join(); 
    return S_OK; 
} 

HRESULT MyFilter::Pause() 
{ 
    CAutoLock cobjectlock(&m_critSec); 
    m_State = State_Paused; 

    mylogger->LogDebug("In MyFilter::PAuse:", L"D:\\TEMP\\yc.log"); 

    return S_OK; 
} 



MyFilter::~MyFilter(void) 
{ 


    //delete mylogger; 



    //delete outpin; 
    //delete[] inputpins; 

} 

int MyFilter::GetPinCount() 
{ 
    return COUNT_INPUTPINS + 1; //One outputpin 

} 

IPin* MyFilter::GetMyPin(int n) 
{ 

    CBasePin* pin = this->GetPin(n); 
    return pin; 

} 

CBasePin* MyFilter::GetPin(int n) 
{ 
    if (n >= 0 && n < COUNT_INPUTPINS) 
    { 
     return inputpins[n]; 

    } 
    if (n == 3) 
    { 
     return outpin; 
    } 
    return NULL; 
} 

//HRESULT MyFilter::GetThePinCount(int *result) 
//{ 
// *result = 4; 
//} 

HRESULT MyFilter::GetThePinCount(int* giveme) 
{ 
    *giveme = COUNT_INPUTPINS + 1; 
    return S_OK; 
} 

STDMETHODIMP MyFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv) 
{ 
    if(riid == IID_IMyInterfilter) { 
     mylogger->LogDebug("In Nondelegationqueryinterface", L"D:\\TEMP\\yc.log"); 
     return GetInterface((IMyFilter*)this, ppv); 
    } 

    else 
    { 
     return CBaseFilter::NonDelegatingQueryInterface(riid, ppv); 
    } 
} 

/*RESULT MyFilter::StartRecording() 
{ 
    this->running = true; 
    return S_OK; 

}*/ 
// 
//HRESULT MyFilter::StopRecording() 
//{ 
// this->running = false; 
// return S_OK; 
// 
//} 

CUnknown* WINAPI MyFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) 
{ 

    CUnknown* pNewFilter = new MyFilter(pUnk, phr); 

    if (phr) 
    { 
     if (pNewFilter == NULL) 
      *phr = E_OUTOFMEMORY; 
     else 
      *phr = S_OK; 
    } 

    return pNewFilter; 
} 


void MyFilter::acceptFilterInput(LPCWSTR pinname, IMediaSample* sample) 
{ 

    mylogger->LogDebug("In acceptFIlterInput", L"D:\\TEMP\\yc.log"); 
    outpin->Deliver(sample); 

} 
//STDMETHODIMP MyFilter::Next(ULONG cPins, IPin** pppins, ULONG fetched) 
//{ 
// 
//} 
//STDMETHODIMP MyFilter::(IEnumPins **ppenum) 
//{ 
// 
//} 
//STDMETHODIMP MyFilter::Reset() 
//{ 
// 
//} 
//STDMETHODIMP MyFilter::Skip(ULONG cpins) 
//{ 
// 
//} 




CMyInputPin* MyFilter::GetPinByName(LPCWSTR name) 
{ 
    for (int i = 0; i < COUNT_INPUTPINS; i++) 
    { 
     if (wcscmp(name, inputpins[0]->Name())) 
     { 
      return inputpins[0]; 
     } 
    } 


    return NULL; 
} 


void MyFilter::startSyncThread() 
{ 
    this->m_pTimeGiver->start(); 
} 

unsigned int MyFilter::workerthreadfunc(void * param) 
{ 
    MyFilter* myfilter; 
    myfilter = (MyFilter *)param; 
    myfilter->m_pTimeGiver->start(); 
    return S_OK; 
} 

답변

0

잘못된 호출 규칙이 얻을 수있는 일반적인 문제 :

여기
class MyFilter : public CBaseFilter, public IMyFilter 
{ 
public: 

    CCritSec lockfilter; 
    DECLARE_IUNKNOWN; 

    const LONGLONG MEDIATIME = 5; 

    MyFilter(LPUNKNOWN pUnk, HRESULT* phr); 
    virtual ~MyFilter(void); 

    virtual int GetPinCount(); 
    virtual CBasePin* GetPin(int n); 

    STDMETHODIMP Run(REFERENCE_TIME tStart); 
    STDMETHODIMP Pause(); 
    STDMETHODIMP Stop(); 

    void acceptFilterInput(LPCWSTR pinname, IMediaSample* sample); 
    CMyInputPin* getPreviousPIN(LPCWSTR pinname); 
    CMyInputPin* getNextPIN(LPCWSTR pinname); 
    //BOOL requestRecordMode(LPCWSTR pinname); //returns false if previous pin thread is not sleeping 

    static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); 

    //STDMETHODIMP StartRecording(); 
    STDMETHODIMP GetThePinCount(int* result); 
    //STDMETHODIMP StopRecording(); 
    STDMETHOD_(IPin*,GetMyPin)(int index); 

    //STDMETHODIMP Next(ULONG cPins, IPin** pppins, ULONG fetched); 
    //STDMETHODIMP Clone(IEnumPins **ppenum); 
    //STDMETHODIMP Reset(); 
    //STDMETHODIMP Skip(ULONG cpins); 
    // 

    CCritSec m_lock_filter; 

    TimeGiver* m_pTimeGiver;  

    MCMyOutputPin *outpin; 
    static const int COUNT_INPUTPINS = 3; 
    static unsigned __stdcall workerthreadfunc(void *); 
    HANDLE workerThreadHandle; 
private: 

    MyLogger *mylogger; 
    CCritSec m_critSec; 
    bool running; 




    LPCWSTR currentInputPin; 

    void startSyncThread(); 






    CMyInputPin* GetPinByName(LPCWSTR name); 

    LONGLONG* mediaTimeBuffer; 


    CMyInputPin* inputpins[COUNT_INPUTPINS]; 

}; 

이 필터 구현 그러나이 오류 메시지는 가능한 원인 중 하나 일뿐입니다. 예를 들어 IFooA* 포인터를 반환해야하는 불량 포인터 캐스팅을 사용하면 동일한 불일치가 "달성"될 수 있으며 대신 IFooB*을 반환합니다. 그런 다음 IFooA::BarA을 호출하면 IFooB::BarB 코드가 효과적으로 실행되며 해당 구문/호출 차이 결과는 스택 프레임 오류입니다. 특정 인터페이스/메소드에서만 잘못된 호출 규칙을 사용하여 빌드하는 것이 그리 쉽지 않기 때문에이 경우가 발생했다고 생각합니다.

문제는 디버거가 중단 된 인터페이스 주위에 있어야합니다. NonDelegatingQueryInterface 구현을 점검하여 올바르게 일치하는 올바른 인터페이스를 반환하는지 확인하십시오. 정확히 일치하는 것은 IID입니다.

UPD. 원래 문제가 무엇이든지간에 이것은 전혀 좋지 않습니다.

CMyInputPin* MyFilter::GetPinByName(LPCWSTR name) 
{ 
    for (int i = 0; i < COUNT_INPUTPINS; i++) 
    { 
     // 1. you want [i], not [0] 
     // 2. you want if(wcscmp(...) == 0) 
     if (wcscmp(name, inputpins[0]->Name())) 
     { 
      // 3. you want [i], not [0] 
      return inputpins[0]; 
     } 
    } 
+0

문제는 필터가 아닌 핀에 있습니까? 핀이 com 클래스가 아니기 때문에 NoDelegatingQueryInterface 메소드가 없습니다. – Luke

+0

Pin은 COM 객체이기도합니다. 특히 인터페이스를 구현합니다. 문제는 나쁜 캐스트 일 수 있지만 자세한 정보를 추가 할 정보는 없습니다. –

+0

나는 더 많은 코드를 추가했다. 희망이 당신이 나를 도울 필요가있는 정보입니다. – Luke

관련 문제