]> git.vomp.tv Git - vompclient.git/blob - dssourcefilter.cc
Windows updates
[vompclient.git] / dssourcefilter.cc
1 /*
2     Copyright 2004-2006 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 #include "dssourcefilter.h"
21
22 #define AUDIOPIN_NAME L"Audio"
23 #define VIDEOPIN_NAME L"Video"
24
25 class DsSFEnumPins: public IEnumPins {
26 public:
27         DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos=0);
28         virtual ~DsSFEnumPins();
29         virtual HRESULT STDMETHODCALLTYPE Next(ULONG numpin,IPin **pins,ULONG *fetched);
30         virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);
31         virtual HRESULT STDMETHODCALLTYPE Reset();
32         virtual HRESULT STDMETHODCALLTYPE Clone(IEnumPins **enuma);
33         virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
34         virtual ULONG STDMETHODCALLTYPE AddRef();
35     virtual ULONG STDMETHODCALLTYPE Release();
36 protected:
37         DsSourcePin* audiopin;
38         DsSourcePin* videopin;
39         DsSourceFilter *filter;
40         ULONG curpos;
41         volatile long refs;
42 };
43
44 DsSFEnumPins::DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos){
45         audiopin=audio;
46         videopin=video;
47         curpos=pos;
48         filter=filt;
49         filt->AddRef();
50         refs=0;
51         
52 }
53
54 DsSFEnumPins::~DsSFEnumPins(){
55         filter->Release();
56         
57 }
58
59 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Next(ULONG numpin,IPin **pins,ULONG *fetched) {
60         int i;
61         if (fetched==NULL) return E_POINTER;
62         if (pins==NULL) return E_POINTER;
63         *fetched=0;
64
65         for (i=0;(i<numpin)&& (curpos<2);i++) {
66                 switch (curpos) {
67                 case 0: audiopin->AddRef();  pins[i]=(IPin*)audiopin;break;
68                 case 1: videopin->AddRef(); pins[i]=(IPin*)videopin;break;
69                 };
70                 (*fetched)++;
71                 curpos++;
72         }
73         if ((*fetched)!=numpin) return S_FALSE;
74         return S_OK;
75 }
76
77 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Skip(ULONG numpin){
78         curpos+=numpin;
79         if (curpos>2) return S_FALSE;
80         return S_OK;
81 }
82 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Reset(){
83         curpos=0;
84         return S_OK;
85 }
86 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Clone(IEnumPins **enuma){
87         if (enuma==NULL) return E_POINTER;
88         *enuma=new DsSFEnumPins(audiopin,videopin,filter,curpos);
89         (*enuma)->AddRef();
90         return S_OK;
91 }
92
93 HRESULT STDMETHODCALLTYPE  DsSFEnumPins::QueryInterface(REFIID id,void ** object){
94         if (object==NULL) return E_POINTER;
95         if (id==IID_IUnknown ||id == IID_IEnumPins) {
96                 *object=(IUnknown*)this;
97                 ((IUnknown*)object)->AddRef();
98                 return NOERROR;
99         } else {
100                 *object=NULL;
101                 return E_NOINTERFACE;
102         }
103 }
104
105
106
107 ULONG STDMETHODCALLTYPE DsSFEnumPins::AddRef(){
108         InterlockedIncrement(&refs);
109         long tempref=refs;
110         if (tempref>1) return tempref;
111         else return 1;
112 }
113
114 ULONG STDMETHODCALLTYPE DsSFEnumPins::Release(){
115         long tempref=InterlockedDecrement(&refs);
116         
117         if (tempref==0) {
118                 refs++;
119                 delete this;
120                 return NULL;
121         } else {
122                 if (tempref>1) return tempref;
123                 else return 1;
124         }
125 }
126
127
128
129
130
131
132
133 DsSourceFilter::DsSourceFilter()
134 {
135         //add audio pin
136         HRESULT res;
137         audiopin=new DsSourcePin(this,&res,L"Vomp Audio Out",true);
138         videopin=new DsSourcePin(this,&res,L"Vomp Video Out",false);
139         filtergraph=NULL;
140         clock=NULL;
141         mystate=State_Stopped;
142         laststart=0;
143         refs=0;
144         InitializeCriticalSection(&filterlock);
145
146 }
147
148 DsSourceFilter::~DsSourceFilter()
149 {
150         if (audiopin) delete audiopin;
151         if (videopin) delete videopin;
152         if (clock) {
153                 clock->Release();
154                 clock=NULL;
155         }
156         DeleteCriticalSection(&filterlock);
157         
158 }
159
160 HRESULT STDMETHODCALLTYPE  DsSourceFilter::GetClassID(CLSID *clsid){
161         if (clsid==NULL) return E_POINTER;
162         *clsid=_uuidof(this);
163         return S_OK;
164 }
165
166 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryInterface(REFIID id,void ** object){
167         if (object==NULL) return E_POINTER;
168         if (id==IID_IUnknown) {
169                 *object=(IUnknown*)this;
170                 AddRef();
171                 return NOERROR;
172         } else if (id==IID_IBaseFilter) {
173                 *object=(IBaseFilter*)this;
174                 AddRef();
175                 return NOERROR;
176         } else if (id==IID_IMediaFilter) {
177                 *object=(IMediaFilter*)this;
178                 AddRef();
179                 return NOERROR;
180         }else {
181                 *object=NULL;
182                 return E_NOINTERFACE;
183         }
184 }
185
186 ULONG STDMETHODCALLTYPE DsSourceFilter::AddRef(){
187         InterlockedIncrement(&refs);
188         long tempref=refs;
189         if (tempref>1) return tempref;
190         else return 1;
191 }
192 ULONG STDMETHODCALLTYPE DsSourceFilter::Release(){
193         long tempref=InterlockedDecrement(&refs);
194         
195         if (tempref==0) {
196                 refs++;
197                 delete this;
198                 return NULL;
199         } else {
200                 if (tempref>1) return tempref;
201                 else return 1;
202         }
203 }
204
205 /*IBaseFilter*/
206 HRESULT STDMETHODCALLTYPE DsSourceFilter::EnumPins(IEnumPins **enumar){
207         if (enumar==NULL) return E_POINTER;
208         *enumar=new DsSFEnumPins(audiopin,videopin, this);
209         (*enumar)->AddRef();
210         return S_OK;
211 }
212
213 HRESULT STDMETHODCALLTYPE DsSourceFilter::FindPin(LPCWSTR iden,IPin **pin){
214         if (pin==NULL) return E_POINTER;
215         EnterCriticalSection(&filterlock);
216
217         if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
218                 *pin=(IPin*)audiopin;
219                 (*pin)->AddRef();
220                 LeaveCriticalSection(&filterlock);
221                 return S_OK;
222         }
223         if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
224                 *pin=(IPin*)videopin;
225                 (*pin)->AddRef();
226                 LeaveCriticalSection(&filterlock);
227                 return S_OK;
228         }
229
230         *pin=NULL;
231         LeaveCriticalSection(&filterlock);
232     return VFW_E_NOT_FOUND;
233 }
234 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryFilterInfo(FILTER_INFO *info){
235         if (info==NULL) return E_POINTER;
236         wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
237         info->pGraph=filtergraph;
238         if (info->pGraph!=NULL) info->pGraph->AddRef();
239         return NOERROR;
240 }
241
242 HRESULT STDMETHODCALLTYPE DsSourceFilter::JoinFilterGraph(IFilterGraph *graph,LPCWSTR name){
243         //Should we lock
244         EnterCriticalSection(&filterlock);
245         filtergraph=graph;
246         //filtergraph->AddRef();
247         //We ignore the name
248         LeaveCriticalSection(&filterlock);
249         
250         return S_OK;
251 }
252 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryVendorInfo(LPWSTR *vendinf) {
253         return E_NOTIMPL;
254 }
255
256
257 /*IMediaFilter*/
258 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetState(DWORD timeout,FILTER_STATE *state){
259         if (state==NULL) return E_POINTER;
260         EnterCriticalSection(&filterlock);
261         *state=mystate;
262         LeaveCriticalSection(&filterlock);
263         return S_OK;
264 }
265
266 HRESULT STDMETHODCALLTYPE DsSourceFilter::SetSyncSource(IReferenceClock *uhr){
267         EnterCriticalSection(&filterlock);
268         //MessageBox(0,"Sets ync","",0);
269         if (clock!=NULL) {
270                 clock->Release();
271         }
272         if (uhr!=NULL) {
273                 uhr->AddRef();
274         }
275         clock=uhr;
276         LeaveCriticalSection(&filterlock);
277         
278         return S_OK;
279 }
280 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetSyncSource(IReferenceClock **uhr){
281         if (uhr==NULL) return E_POINTER;
282         EnterCriticalSection(&filterlock);
283         if (clock!=NULL) clock->AddRef();
284         *uhr=clock;
285         LeaveCriticalSection(&filterlock);
286         
287         return S_OK;
288 }
289
290 HRESULT STDMETHODCALLTYPE DsSourceFilter::Stop(){
291         EnterCriticalSection(&filterlock);
292         HRESULT aphres=S_OK;
293         HRESULT vphres=S_OK;
294         
295         if (audiopin->IsConnected()){
296                 aphres=audiopin->Inactive();
297         }
298         if (videopin->IsConnected()){
299                 vphres=videopin->Inactive();
300         }
301                 
302         mystate=State_Stopped;
303         LeaveCriticalSection(&filterlock);
304         if (aphres!=S_OK) return aphres;
305         if (vphres!=S_OK) return vphres;
306         return S_OK;
307 }
308
309 HRESULT STDMETHODCALLTYPE DsSourceFilter::Pause(){
310         EnterCriticalSection(&filterlock);
311         HRESULT aphres;
312         HRESULT vphres;
313         
314         if (audiopin->IsConnected()){
315                 aphres=audiopin->Active();
316                 if (aphres!=S_OK) {
317                         LeaveCriticalSection(&filterlock);
318                         return aphres;
319                 }
320         }
321         if (videopin->IsConnected()){
322                 vphres=videopin->Active();
323                 if (vphres!=S_OK) {
324                         LeaveCriticalSection(&filterlock);
325                         return vphres;
326                 }
327         }
328                 
329         mystate=State_Paused;
330         LeaveCriticalSection(&filterlock);
331         
332
333         return S_OK;
334 }
335 HRESULT STDMETHODCALLTYPE DsSourceFilter::Run(REFERENCE_TIME start){
336         
337         HRESULT aphres;
338         HRESULT vphres;
339         EnterCriticalSection(&filterlock);
340
341         if (mystate==State_Stopped) {
342                 HRESULT phres=Pause();
343                 if (phres!=S_OK){
344                         LeaveCriticalSection(&filterlock);
345                         return phres;
346                 }
347         }
348         
349         laststart=start;
350         
351
352         if (audiopin->IsConnected()){
353                 aphres=audiopin->Run(start);
354                 if (aphres!=S_OK) {
355                         LeaveCriticalSection(&filterlock);
356                         return aphres;
357                 }
358         }
359         
360         if (videopin->IsConnected()){
361                 vphres=videopin->Run(start);
362                 if (vphres!=S_OK) {
363                         LeaveCriticalSection(&filterlock);
364                         return vphres;
365                 }
366         }
367                 
368         mystate=State_Running;
369         LeaveCriticalSection(&filterlock);
370         
371
372         return S_OK;
373 }
374
375
376
377 int DsSourceFilter::GetPinCount()
378 {
379         return 2; //audio and video
380 }
381
382
383
384 int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
385 {
386         if (!audiopin  || !IsActive()) {
387                 return 0;
388         }
389         if (audiopin->getCurrentMediaSample(ms)!=S_OK) {
390                 return 0;
391         }
392         return 1;
393 }
394
395 int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
396 {
397         if (!videopin || !IsActive()) {
398                 return 0;
399         }
400         if (videopin->getCurrentMediaSample(ms)!=S_OK) {
401                 return 0;
402         }
403         return 1;
404 }
405
406 int DsSourceFilter::DeliverAudioMediaSample(IMediaSample* ms)
407 {
408         if (!audiopin || !IsActive()) {
409                 ms->Release();
410                 return 0;
411         }
412         if (audiopin->deliver(ms)!=S_OK) {
413                 ms->Release();
414                 return 0;
415         }
416         ms->Release();
417         return 1;
418
419 }
420
421 int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
422 {
423         if (!videopin || !IsActive()) {
424                 ms->Release();
425                 return 0;
426         }
427         if (videopin->deliver(ms)!=S_OK) {
428                 ms->Release();
429                 return 0;
430         }
431         ms->Release();
432         return 1;
433
434 }
435
436