summaryrefslogtreecommitdiffstats
path: root/loader/dshow/DS_Filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/dshow/DS_Filter.c')
-rw-r--r--loader/dshow/DS_Filter.c346
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;
}