168
|
1 #include <stdio.h>
|
|
2 #include <string.h>
|
|
3 #include "DS_Filter.h"
|
|
4 #include <except.h>
|
|
5 //#include "../loader/loader.h"
|
|
6 #include <string>
|
|
7 #define __MODULE__ "DirectShow generic filter"
|
|
8
|
|
9 using namespace std;
|
|
10
|
|
11 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
|
|
12 extern "C" char* def_path;
|
|
13
|
|
14 extern "C" int STDCALL LoadLibraryA(const char*);
|
|
15 extern "C" STDCALL void* GetProcAddress(int, const char*);
|
|
16 extern "C" int STDCALL FreeLibrary(int);
|
|
17
|
|
18 DS_Filter::DS_Filter()
|
|
19 :m_iHandle(0), m_pFilter(0), m_pInputPin(0),
|
|
20 m_pOutputPin(0), m_pSrcFilter(0),
|
|
21 m_pOurInput(0), m_pOurOutput(0),
|
|
22 m_pImp(0), m_pAll(0), m_pParentFilter(0)
|
|
23 {
|
|
24 }
|
|
25
|
|
26 void DS_Filter::Create(string dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt)
|
|
27 {
|
|
28 try
|
|
29 {
|
|
30 string _fullname=def_path;
|
|
31 _fullname+="/";
|
|
32 _fullname+=dllname;
|
|
33 m_iHandle= LoadLibraryA(_fullname.c_str());
|
|
34 if(!m_iHandle)throw FATAL("Could not open DLL");
|
|
35 GETCLASS func=(GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject");
|
|
36 if(!func)throw FATAL("Illegal or corrupt DLL");
|
|
37
|
|
38 HRESULT result;
|
|
39 IClassFactory* factory=0;
|
|
40 IUnknown* object=0;
|
|
41
|
|
42 result=func(id, &IID_IClassFactory, (void**)&factory);
|
|
43 if(result || (!factory)) throw FATAL("No such class object");;
|
|
44
|
|
45 printf("# factory = %X\n",(unsigned int)factory);
|
|
46 printf("# factory->vt = %X\n",(unsigned int)factory->vt);
|
|
47 printf("# factory->vt->CreateInstance = %X\n",(unsigned int)factory->vt->CreateInstance);
|
|
48
|
|
49 printf("Calling factory->vt->CreateInstance()\n");
|
|
50 result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
|
|
51 printf("Calling factory->vt->Release()\n");
|
|
52
|
|
53 // result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
|
|
54
|
|
55 printf("CreateInstance ok %x\n",result);
|
|
56
|
|
57 factory->vt->Release((IUnknown*)factory);
|
|
58 if(result || (!object)) throw FATAL("Class factory failure");
|
|
59
|
|
60 result=object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&m_pFilter);
|
|
61 object->vt->Release((IUnknown*)object);
|
|
62 if(result || (!m_pFilter)) throw FATAL("Object does not have IBaseFilter interface");
|
|
63
|
|
64 IEnumPins* enum_pins=0;
|
|
65 // enumerate pins
|
|
66 result=m_pFilter->vt->EnumPins(m_pFilter, &enum_pins);
|
|
67 if(result || (!enum_pins)) throw FATAL("Could not enumerate pins");
|
|
68 IPin* array[256];
|
|
69 ULONG fetched;
|
|
70 enum_pins->vt->Reset(enum_pins);
|
|
71 result=enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
|
|
72 printf("Pins enumeration returned %d pins, error is %x\n", fetched, result);
|
|
73
|
|
74 for(int i=0; i<fetched; i++)
|
|
75 {
|
|
76 int direction=-1;
|
|
77 array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction);
|
|
78 if((!m_pInputPin)&&(direction==0))
|
|
79 {
|
|
80 m_pInputPin=array[i];
|
|
81 m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin);
|
|
82 }
|
|
83 if((!m_pOutputPin)&&(direction==1))
|
|
84 {
|
|
85 m_pOutputPin=array[i];
|
|
86 m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin);
|
|
87 }
|
|
88 array[i]->vt->Release((IUnknown*)(array[i]));
|
|
89 }
|
|
90 if(!m_pInputPin)throw FATAL("Input pin not found");
|
|
91 if(!m_pOutputPin)throw FATAL("Output pin not found");
|
|
92
|
|
93 result=m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin, &IID_IMemInputPin, (void**)&m_pImp);
|
|
94 if(result)
|
|
95 throw FATAL("Error getting IMemInputPin interface");
|
|
96 m_pOurType=in_fmt;
|
|
97 m_pDestType=out_fmt;
|
|
98 result=m_pInputPin->vt->QueryAccept(m_pInputPin, m_pOurType);
|
|
99 if(result) throw FATAL("Source format is not accepted");
|
|
100
|
|
101 m_pParentFilter=new CBaseFilter2;
|
|
102 m_pSrcFilter=new CBaseFilter(*m_pOurType, m_pParentFilter);
|
|
103 m_pOurInput=m_pSrcFilter->GetPin();
|
|
104 m_pOurInput->vt->AddRef((IUnknown*)m_pOurInput);
|
|
105
|
|
106 result=m_pInputPin->vt->ReceiveConnection(m_pInputPin, m_pOurInput, m_pOurType);
|
|
107 if(result) throw FATAL("Error connecting to input pin");
|
|
108
|
|
109 m_pOurOutput=new COutputPin(*m_pDestType);
|
|
110 result=m_pOutputPin->vt->ReceiveConnection(m_pOutputPin,
|
|
111 m_pOurOutput, m_pDestType);
|
|
112 if(result)throw FATAL("Error connecting to output pin");
|
|
113 m_iState=1;
|
|
114 }
|
|
115 catch(FatalError e)
|
|
116 {
|
|
117 e.PrintAll();
|
|
118 if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter);
|
|
119 if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
|
|
120 if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
|
|
121 if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp);
|
|
122 if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
|
|
123 delete m_pSrcFilter;
|
|
124 delete m_pParentFilter;
|
|
125 delete m_pOurOutput;
|
|
126 if(m_iHandle)FreeLibrary(m_iHandle);
|
|
127 throw;
|
|
128 }
|
|
129 }
|
|
130 void DS_Filter::Start()
|
|
131 {
|
|
132 if(m_iState!=1)
|
|
133 return;
|
|
134
|
|
135 HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0);
|
|
136 if(hr!=0)
|
|
137 {
|
|
138 cerr<<"WARNING: m_Filter->Run() failed, error code "<<hex<<hr<<dec<<endl;
|
|
139 }
|
|
140 hr=m_pImp->vt->GetAllocator(m_pImp, &m_pAll);
|
|
141 if(hr)
|
|
142 {
|
|
143 cerr<<"Error getting IMemAllocator interface "<<hex<<hr<<dec<<endl;
|
|
144 m_pImp->vt->Release((IUnknown*)m_pImp);
|
|
145 return;
|
|
146 }
|
|
147 m_pImp->vt->NotifyAllocator(m_pImp, m_pAll, 0);
|
|
148 m_iState=2;
|
|
149 return;
|
|
150 }
|
|
151 void DS_Filter::Stop()
|
|
152 {
|
|
153 if(m_iState!=2)
|
|
154 return;
|
|
155 m_pAll->vt->Release((IUnknown*)m_pAll);
|
|
156 m_pAll=0;
|
|
157 m_pFilter->vt->Stop(m_pFilter);
|
|
158 m_iState=1;
|
|
159 return;
|
|
160 }
|
|
161 DS_Filter::~DS_Filter()
|
|
162 {
|
|
163 if(m_iState==0)
|
|
164 return;
|
|
165 if(m_iState==2)Stop();
|
|
166 if(m_pInputPin)m_pInputPin->vt->Disconnect(m_pInputPin);
|
|
167 if(m_pOutputPin)m_pOutputPin->vt->Disconnect(m_pOutputPin);
|
|
168 if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter);
|
|
169 if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
|
|
170 if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
|
|
171 if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
|
|
172 if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp);
|
|
173 delete m_pSrcFilter;
|
|
174 delete m_pParentFilter;
|
|
175 delete m_pOurOutput;
|
|
176 if(m_iHandle)FreeLibrary(m_iHandle);
|
|
177 }
|