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.c198
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;
+ }
}