How to creat a filter with multiple inputs?
Hi,
I am trying to create a directshow filter which has 2 input
pins and 1 output pin . I have added the pin details to the array of AMOVIESETUP_PIN's, and I have changed the umber of pins in the AMOVIESETUP_FILTER structure. Override the GetPinCount,GetPin.
class CAudioSwichInPlaceFilter : public CTransInPlaceFilter
,public ISpecifyPropertyPages
,public IAudioSwControler
{
public:
CAudioSwichInPlaceFilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr);
virtual ~CAudioSwichInPlaceFilter();
public:
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
//is called when the upstream filter proposes a media type to the transform filter
HRESULT CheckInputType(const CMediaType* mtIn);
//
// Overrides the PURE virtual Transform of CTransInPlaceFilter base class
// This is where the "real work" is done.
//
HRESULT Transform(IMediaSample *pSample);
HRESULT Receive(IMediaSample *pSample);
CBasePin * GetPin(int n);
int GetPinCount(){return 3;}
// override state changes to allow derived transform filter
// to control streaming start/stop
STDMETHODIMP Stop();
STDMETHODIMP Pause();
//ISpecifyPropertyPages
public:
STDMETHODIMP GetPages(CAUUID *pPages);
//IViaAudioSwControler
private:
CCritSec m_csShared; // Protects shared data.
public:
private:
friend class CAudioSwIPPin;
friend class CTransformOutputPin;
CAudioSwIPPin *m_pInput1,*m_pInput2;
CTransformOutputPin *m_pOutput1;
private:
...
};
the filter has tow pins,CAudioSwIPPin *m_pInput1,*m_pInput2,but the base filter CTransInPlaceFilter has a default pin m_pInput,and all of the operation are based m_pInput.
and when m_pInput->Receive(...),it call the filter->Receive(..),how can i know which pin called this?
Does have some samples?
[2038 byte] By [
Brilly] at [2008-2-22]
This is pretty simple. Here is some code with the neccesary stuff you need. These are just the pin stuff, you will still need locks to synchronize access.
Regards,
Mark Essien.
--
http://www.essien.de | DirectEncode MPEG Encoder
-
//// In the HEADER file
class CMyFilter : public CBaseFilter
{
public:
CCritSec* GetMainLock();
// Pin enumeration
CBasePin * GetPin(int n);
int GetPinCount();
// Open and close the file as necessary
STDMETHODIMP Run(REFERENCE_TIME tStart);
STDMETHODIMP Pause();
STDMETHODIMP Stop();
private:
CMyInputPin *m_pPinVideo;
CMyInputPin *m_pPinAudio;
};
///////////////////////
// In the implementation (.cpp) file
// We define our input media types.
const AMOVIESETUP_MEDIATYPE sudPinTypes[] =
{
{ &MEDIATYPE_Video, // Major CLSID
&MEDIASUBTYPE_RGB24 }, // Minor type
{ &MEDIATYPE_Audio, // Major CLSID
&MEDIASUBTYPE_PCM } // Minor type
};
// Define our pins
const AMOVIESETUP_PIN psudPins[] =
{
{ L"Input 01", // Pin's string name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE, // Allowed none
FALSE, // Allowed many
&CLSID_NULL, // Connects to filter
L"Output", // Connects to pin
1, // Number of types
&sudPinTypes[0] }, // Pin information
{ L"Input 02", // Pin's string name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE, // Allowed none
FALSE, // Allowed many
&CLSID_NULL, // Connects to filter
L"Output", // Connects to pin
1, // Number of types
&sudPinTypes[1] } // Pin information
};
const AMOVIESETUP_FILTER sudInfTee =
{
&CLSID_MyFilter, // CLSID of filter
L"My Filter v4", // Filter's name
MERIT_DO_NOT_USE, // Filter merit
2, // Number of pins
psudPins // Pin information
};
CMyFilter::CMyFilter( LPUNKNOWN pUnk,
HRESULT *phr) :
CBaseFilter(NAME("CMyFilter"),
pUnk, &m_Lock,
CLSID_MyFilter)
{
m_pPinVideo = new CMyInputPin(pUnk,
this,
&m_Lock,
&m_ReceiveLock,
Video,
L"Video Input",
phr);
if (m_pPinVideo == NULL) {
*phr = E_OUTOFMEMORY;
return;
}
m_pPinAudio = new CMyInputPin(pUnk,
this,
&m_Lock,
&m_ReceiveLock,
Audio,
L"Audio Input",
phr);
if (m_pPinAudio == NULL) {
*phr = E_OUTOFMEMORY;
return;
}
}
CBasePin * CMyFilter::GetPin(int n)
{
if (n == 0) {
return m_pPinVideo;
} else if (n == 1) {
return m_pPinAudio;
}
return NULL;
}
int CMyFilter::GetPinCount()
{
return 2;
}