diff options
Diffstat (limited to 'loader/dshow/DS_Filter.c')
-rw-r--r-- | loader/dshow/DS_Filter.c | 346 |
1 files changed, 187 insertions, 159 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c index 7cb46c00eb..99124074be 100644 --- a/loader/dshow/DS_Filter.c +++ b/loader/dshow/DS_Filter.c @@ -1,223 +1,251 @@ #include "DS_Filter.h" -//#include "../loader/loader.h" -#include "libwin32.h" -//#include <string> +#include "driver.h" +#include "com.h" #include <stdio.h> #include <string.h> -#define __MODULE__ "DirectShow generic filter" - -using namespace std; - -extern "C" int STDCALL expLoadLibraryA(const char*); - typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); -//extern "C" int STDCALL LoadLibraryA(const char*); //extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD -//extern "C" int STDCALL FreeLibrary(int); -DS_Filter::DS_Filter() +static void DS_Filter_Start(DS_Filter* This) { - m_iHandle = 0; - m_pFilter = 0; - m_pInputPin = 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; + HRESULT hr; + + if (This->m_iState != 1) + return; + + //Debug printf("DS_Filter_Start(%p)\n", This); + hr = This->m_pFilter->vt->Run(This->m_pFilter, 0); + if (hr != 0) + { + Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); + } + hr = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll); + + if (hr || !This->m_pAll) + { + Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr); + This->m_pImp->vt->Release((IUnknown*)This->m_pImp); + return; + } + This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); + This->m_iState = 2; } -DS_Filter::~DS_Filter() +static void DS_Filter_Stop(DS_Filter* This) { - //cout << "Destruction of DS_FILTER" << endl; - Stop(); - destroy(); - //cout << "Destruction of DS_FILTER done" << endl; + if (This->m_iState == 2) + { + This->m_iState = 1; + //Debug printf("DS_Filter_Stop(%p)\n", This); + if (This->m_pFilter) + { + //printf("vt: %p\n", m_pFilter->vt); + //printf("vtstop %p\n", m_pFilter->vt->Stop); + This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME + } + else + printf("WARNING: DS_Filter::Stop() m_pFilter is NULL!\n"); + This->m_pAll->vt->Release((IUnknown*)This->m_pAll); + This->m_pAll = 0; + } } -void DS_Filter::destroy() +void DS_Filter_Destroy(DS_Filter* This) { - if (m_iState == 0) - return; - 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; + This->Stop(This); + + This->m_iState = 0; + + if (This->m_pOurInput) + This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); + if (This->m_pInputPin) + This->m_pInputPin->vt->Disconnect(This->m_pInputPin); + if (This->m_pOutputPin) + This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin); + if (This->m_pFilter) + This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter); + if (This->m_pOutputPin) + This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin); + if (This->m_pInputPin) + This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin); + if (This->m_pImp) + This->m_pImp->vt->Release((IUnknown*)This->m_pImp); + + if (This->m_pOurOutput) + This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput); + if (This->m_pParentFilter) + This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pParentFilter); + if (This->m_pSrcFilter) + This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter); // FIXME - we are still leaving few things allocated! - if (m_iHandle) - FreeLibrary(m_iHandle); + if (This->m_iHandle) + FreeLibrary(This->m_iHandle); + + free(This); + + CodecRelease(); } -void DS_Filter::Create(const char* dllname, const GUID* id, - AM_MEDIA_TYPE* in_fmt, - AM_MEDIA_TYPE* out_fmt) +DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, + AM_MEDIA_TYPE* in_fmt, + AM_MEDIA_TYPE* out_fmt) { - try + DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter)); + if (!This) + return NULL; + + CodecAlloc(); + + This->m_pFilter = NULL; + This->m_pInputPin = NULL; + This->m_pOutputPin = NULL; + This->m_pSrcFilter = NULL; + This->m_pParentFilter = NULL; + This->m_pOurInput = NULL; + This->m_pOurOutput = NULL; + This->m_pAll = NULL; + This->m_pImp = NULL; + This->m_iState = 0; + + This->Start = DS_Filter_Start; + This->Stop = DS_Filter_Stop; + + for (;;) { - m_iHandle = expLoadLibraryA(dllname); - if (!m_iHandle) + HRESULT result; + GETCLASS func; + struct IClassFactory* factory = NULL; + struct IUnknown* object = NULL; + IEnumPins* enum_pins = 0; + IPin* array[256]; + ULONG fetched; + unsigned int i; + + This->m_iHandle = LoadLibraryA(dllname); + if (!This->m_iHandle) { - char e[256]; - snprintf((char *)&e[0], 256, "Could not open DirectShow DLL: %.200s", dllname); - throw FATAL(e); + printf("Could not open DirectShow DLL: %.200s\n", dllname); + break; } - GETCLASS func = (GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject"); + func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject"); if (!func) { - char e[256]; - snprintf((char *)&e[0], 256, "Illegal or corrupt DirectShow DLL: %.200s", dllname); - throw FATAL(e); + printf("Illegal or corrupt DirectShow DLL: %.200s\n", dllname); + break; } - - HRESULT result; - IClassFactory* factory = 0; result = func(id, &IID_IClassFactory, (void**)&factory); if (result || !factory) - throw FATAL("No such class object");; - - IUnknown* object = 0; + { + printf("No such class object\n"); + break; + } 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); + { + printf("Class factory failure\n"); + break; + } + result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter); object->vt->Release((IUnknown*)object); - if (result || !m_pFilter) - throw FATAL("Object does not have IBaseFilter interface"); - - IEnumPins* enum_pins = 0; + if (result || !This->m_pFilter) + { + printf("Object does not have IBaseFilter interface\n"); + break; + } // enumerate pins - result = m_pFilter->vt->EnumPins(m_pFilter, &enum_pins); + result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); if (result || !enum_pins) - throw FATAL("Could not enumerate pins"); + { + printf("Could not enumerate pins\n"); + break; + } - IPin* array[256]; - ULONG fetched; enum_pins->vt->Reset(enum_pins); result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); - for (unsigned i = 0; i < fetched; i++) + for (i = 0; i < fetched; i++) { int direction = -1; array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); - if (!m_pInputPin && direction == 0) + if (!This->m_pInputPin && direction == 0) { - m_pInputPin = array[i]; - m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin); + This->m_pInputPin = array[i]; + This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin); } - if (!m_pOutputPin && direction == 1) + if (!This->m_pOutputPin && direction == 1) { - m_pOutputPin = array[i]; - m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin); + This->m_pOutputPin = array[i]; + This->m_pOutputPin->vt->AddRef((IUnknown*)This->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 (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 (!This->m_pInputPin) + { + printf("Input pin not found\n"); + break; + } + if (!This->m_pOutputPin) + { + printf("Output pin not found\n"); + break; + } + result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, + &IID_IMemInputPin, + (void**)&This->m_pImp); 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); + { + printf("Error getting IMemInputPin interface\n"); + break; + } - result = m_pInputPin->vt->ReceiveConnection(m_pInputPin, - m_pOurInput, - m_pOurType); + This->m_pOurType = in_fmt; + This->m_pDestType = out_fmt; + result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); if (result) - throw FATAL("Error connecting to input pin"); + { + printf("Source format is not accepted\n"); + break; + } + This->m_pParentFilter = CBaseFilter2Create(); + This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter); + This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter); + This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput); + + result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin, + This->m_pOurInput, + This->m_pOurType); + if (result) + { + printf("Error connecting to input pin\n"); + break; + } - m_pOurOutput = new COutputPin(*m_pDestType); + This->m_pOurOutput = COutputPinCreate(This->m_pDestType); - //extern void trapbug(); - //trapbug(); - result = m_pOutputPin->vt->ReceiveConnection(m_pOutputPin, - m_pOurOutput, - m_pDestType); + result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, + (IPin*) This->m_pOurOutput, + This->m_pDestType); if (result) { //printf("Tracking ACELP %d 0%x\n", result); - throw FATAL("Error connecting to output pin"); + printf("Error connecting to output pin\n"); + break; } printf("Using DirectShow codec: %s\n", dllname); - m_iState = 1; - } - catch (FatalError e) - { - //e.PrintAll(); - destroy(); - throw; - } -} - -void DS_Filter::Start() -{ - if (m_iState != 1) - return; - - HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0); - if (hr != 0) - { - Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); + This->m_iState = 1; + break; } - hr = m_pImp->vt->GetAllocator(m_pImp, &m_pAll); - if (hr) - { - Debug printf("Error getting IMemAllocator interface %x\n", (int)hr); - m_pImp->vt->Release((IUnknown*)m_pImp); - return; - } - m_pImp->vt->NotifyAllocator(m_pImp, m_pAll, 0); - m_iState = 2; -} -void DS_Filter::Stop() -{ - if (m_iState == 2) + if (This->m_iState != 1) { - m_pAll->vt->Release((IUnknown*)m_pAll); - if (m_pFilter) - m_pFilter->vt->Stop(m_pFilter); // causes weird crash ??? FIXME - else - printf("m_pFilter is NULL!\n"); - m_pAll = 0; - m_iState = 1; + DS_Filter_Destroy(This); + This = 0; } + return This; } |