diff options
Diffstat (limited to 'loader/dshow/DS_Filter.c')
-rw-r--r-- | loader/dshow/DS_Filter.c | 198 |
1 files changed, 110 insertions, 88 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c index 7d06473f9c..966b2cde87 100644 --- a/loader/dshow/DS_Filter.c +++ b/loader/dshow/DS_Filter.c @@ -4,6 +4,7 @@ #include <except.h> //#include "../loader/loader.h" #include <string> +#include <iostream> #define __MODULE__ "DirectShow generic filter" using namespace std; @@ -12,7 +13,6 @@ typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); extern "C" char* def_path; extern "C" int STDCALL expLoadLibraryA(const char*); -//extern "C" int WINAPI expLoadLibraryA(char* name); extern "C" STDCALL void* GetProcAddress(int, const char*); extern "C" int STDCALL FreeLibrary(int); @@ -21,13 +21,51 @@ extern "C" void setup_FS_Segment(); DS_Filter::DS_Filter() :m_iHandle(0), m_pFilter(0), m_pInputPin(0), - m_pOutputPin(0), m_pSrcFilter(0), - m_pOurInput(0), m_pOurOutput(0), - m_pImp(0), m_pAll(0), m_pParentFilter(0) + m_pOutputPin(0), m_pSrcFilter(0), m_pParentFilter(0), + m_pOurInput(0), m_pOurOutput(0), m_pAll(0), m_pImp(0), + m_iState(0) { } -void DS_Filter::Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt) +void DS_Filter::clean() +{ + m_iState = 0; + + if (m_pOurInput) + m_pOurInput->vt->Release((IUnknown*)m_pOurInput); + if (m_pInputPin) + m_pInputPin->vt->Disconnect(m_pInputPin); + if (m_pOutputPin) + m_pOutputPin->vt->Disconnect(m_pOutputPin); + if (m_pFilter) + m_pFilter->vt->Release((IUnknown*)m_pFilter); + if (m_pOutputPin) + m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin); + if (m_pInputPin) + m_pInputPin->vt->Release((IUnknown*)m_pInputPin); + if (m_pImp) + m_pImp->vt->Release((IUnknown*)m_pImp); + + delete m_pOurOutput; + delete m_pParentFilter; + delete m_pSrcFilter; + + // FIXME - we are still leaving few things allocated! + if (m_iHandle) + FreeLibrary(m_iHandle); + +} + +DS_Filter::~DS_Filter() +{ + //cout << "Destruction of DS_FILTER" << endl; + Stop(); + if (m_iState == 1) + clean(); + //cout << "Destruction of DS_FILTER done" << endl; +} + +void DS_Filter::Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt) { Setup_LDT_Keeper(); @@ -37,40 +75,37 @@ void DS_Filter::Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_ // string _fullname=def_path; // _fullname+="/"; // _fullname+=dllname; -// m_iHandle= LoadLibraryA(_fullname.c_str()); m_iHandle= expLoadLibraryA(dllname); - if(!m_iHandle)throw FATAL("Could not open DLL"); + if (!m_iHandle) + { + char e[1024]; + sprintf(e, "Could not open DirectShow DLL: %s", dllname); + throw FATAL(e); + } GETCLASS func=(GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject"); - if(!func)throw FATAL("Illegal or corrupt DLL"); + if (!func) + { + char e[1024]; + sprintf(e, "Illegal or corrupt DirectShow DLL: %s", dllname); + throw FATAL(e); + } HRESULT result; IClassFactory* factory=0; - IUnknown* object=0; - result=func(id, &IID_IClassFactory, (void**)&factory); if(result || (!factory)) throw FATAL("No such class object");; - -// printf("# factory = %X\n",(unsigned int)factory); -// printf("# factory->vt = %X\n",(unsigned int)factory->vt); -// printf("# factory->vt->CreateInstance = %X\n",(unsigned int)factory->vt->CreateInstance); - - setup_FS_Segment(); -// printf("Calling factory->vt->CreateInstance()\n"); - result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); -// printf("Calling factory->vt->Release()\n"); - -// result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); - -// printf("CreateInstance ok %x\n",result); + setup_FS_Segment(); + IUnknown* object=0; + result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); factory->vt->Release((IUnknown*)factory); if(result || (!object)) throw FATAL("Class factory failure"); - + result=object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&m_pFilter); object->vt->Release((IUnknown*)object); if(result || (!m_pFilter)) throw FATAL("Object does not have IBaseFilter interface"); - + IEnumPins* enum_pins=0; // enumerate pins result=m_pFilter->vt->EnumPins(m_pFilter, &enum_pins); @@ -79,109 +114,96 @@ void DS_Filter::Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_ ULONG fetched; enum_pins->vt->Reset(enum_pins); result=enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); -// printf("Pins enumeration returned %d pins, error is %x\n", fetched, result); - - for(int i=0; i<fetched; i++) + Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); + + for (unsigned i = 0; i < fetched; i++) { - int direction=-1; + int direction = -1; array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); - if((!m_pInputPin)&&(direction==0)) + if (!m_pInputPin && direction == 0) { - m_pInputPin=array[i]; + m_pInputPin = array[i]; m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin); } - if((!m_pOutputPin)&&(direction==1)) + if (!m_pOutputPin && direction == 1) { - m_pOutputPin=array[i]; + m_pOutputPin = array[i]; m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin); } array[i]->vt->Release((IUnknown*)(array[i])); } - if(!m_pInputPin)throw FATAL("Input pin not found"); - if(!m_pOutputPin)throw FATAL("Output pin not found"); - - result=m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin, &IID_IMemInputPin, (void**)&m_pImp); + if (!m_pInputPin) + throw FATAL("Input pin not found"); + if (!m_pOutputPin) + throw FATAL("Output pin not found"); + + result = m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin, + &IID_IMemInputPin, + (void**)&m_pImp); if(result) throw FATAL("Error getting IMemInputPin interface"); m_pOurType=in_fmt; m_pDestType=out_fmt; result=m_pInputPin->vt->QueryAccept(m_pInputPin, m_pOurType); - if(result) throw FATAL("Source format is not accepted"); + if (result) + throw FATAL("Source format is not accepted"); m_pParentFilter=new CBaseFilter2; m_pSrcFilter=new CBaseFilter(*m_pOurType, m_pParentFilter); m_pOurInput=m_pSrcFilter->GetPin(); m_pOurInput->vt->AddRef((IUnknown*)m_pOurInput); - - result=m_pInputPin->vt->ReceiveConnection(m_pInputPin, m_pOurInput, m_pOurType); - if(result) throw FATAL("Error connecting to input pin"); - - m_pOurOutput=new COutputPin(*m_pDestType); - result=m_pOutputPin->vt->ReceiveConnection(m_pOutputPin, - m_pOurOutput, m_pDestType); - if(result)throw FATAL("Error connecting to output pin"); - m_iState=1; + + result=m_pInputPin->vt->ReceiveConnection(m_pInputPin, m_pOurInput, + m_pOurType); + if (result) + throw FATAL("Error connecting to input pin"); + + m_pOurOutput = new COutputPin(*m_pDestType); + + result = m_pOutputPin->vt->ReceiveConnection(m_pOutputPin, + m_pOurOutput, + m_pDestType); + if (result) + throw FATAL("Error connecting to output pin"); + cout << "Using DirectShow codec: " << dllname << endl; + m_iState = 1; } catch(FatalError e) { e.PrintAll(); - if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter); - if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin); - if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin); - if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp); - if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput); - delete m_pSrcFilter; - delete m_pParentFilter; - delete m_pOurOutput; - if(m_iHandle)FreeLibrary(m_iHandle); + clean(); throw; } } + void DS_Filter::Start() { - if(m_iState!=1) + if (m_iState != 1) return; - + HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0); - if(hr!=0) + if (hr != 0) { - cerr<<"WARNING: m_Filter->Run() failed, error code "<<hex<<hr<<dec<<endl; + Debug cerr<<"WARNING: m_Filter->Run() failed, error code "<<hex<<hr<<dec<<endl; } hr=m_pImp->vt->GetAllocator(m_pImp, &m_pAll); - if(hr) + if (hr) { - cerr<<"Error getting IMemAllocator interface "<<hex<<hr<<dec<<endl; + Debug cerr<<"Error getting IMemAllocator interface "<<hex<<hr<<dec<<endl; m_pImp->vt->Release((IUnknown*)m_pImp); return; } m_pImp->vt->NotifyAllocator(m_pImp, m_pAll, 0); - m_iState=2; - return; + m_iState = 2; } + void DS_Filter::Stop() { - if(m_iState!=2) - return; - m_pAll->vt->Release((IUnknown*)m_pAll); - m_pAll=0; - m_pFilter->vt->Stop(m_pFilter); - m_iState=1; - return; -} -DS_Filter::~DS_Filter() -{ - if(m_iState==0) - return; - if(m_iState==2)Stop(); - if(m_pInputPin)m_pInputPin->vt->Disconnect(m_pInputPin); - if(m_pOutputPin)m_pOutputPin->vt->Disconnect(m_pOutputPin); - if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter); - if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin); - if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin); - if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput); - if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp); - delete m_pSrcFilter; - delete m_pParentFilter; - delete m_pOurOutput; - if(m_iHandle)FreeLibrary(m_iHandle); + if (m_iState == 2) + { + m_pAll->vt->Release((IUnknown*)m_pAll); + m_pAll=0; + m_pFilter->vt->Stop(m_pFilter); + m_iState=1; + } } |