Mercurial > mplayer.hg
comparison loader/dshow/DS_Filter.c @ 168:bdc4a8fc04d8
Initial revision
author | arpi_esp |
---|---|
date | Tue, 20 Mar 2001 00:05:27 +0000 |
parents | |
children | 1c3029be6713 |
comparison
equal
deleted
inserted
replaced
167:53f289e99102 | 168:bdc4a8fc04d8 |
---|---|
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 } |