1
/*  This file is part of the KDE project.
2
3
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5
This library is free software: you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published by
7
the Free Software Foundation, either version 2.1 or 3 of the License.
8
9
This library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU Lesser General Public License for more details.
13
14
You should have received a copy of the GNU Lesser General Public License
15
along with this library.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#include "qbasefilter.h"
19
#include "qpin.h"
20
21
#include <QtCore/QMutex>
22
23
QT_BEGIN_NAMESPACE
24
25
namespace Phonon
26
{
27
    namespace DS9
28
    {
29
30
        class QEnumPins : public IEnumPins
31
        {
32
        public:
33
            QEnumPins(QBaseFilter *filter) : m_refCount(1),
34
                m_filter(filter), m_pins(filter->pins()), m_index(0)
35
            {
36
                m_filter->AddRef();
37
            }
38
39
            virtual ~QEnumPins()
40
            {
41
                m_filter->Release();
42
            }
43
44
            STDMETHODIMP QueryInterface(const IID &iid,void **out)
45
            {
46
                if (!out) {
47
                    return E_POINTER;
48
                }
49
50
                HRESULT hr = S_OK;
51
                if (iid == IID_IEnumPins) {
52
                    *out = static_cast<IEnumPins*>(this);
53
                } else if (iid == IID_IUnknown) {
54
                    *out = static_cast<IUnknown*>(this);
55
                } else {
56
                    *out = 0;
57
                    hr = E_NOINTERFACE;
58
                }
59
60
                if (S_OK)
61
                    AddRef();
62
                return hr;
63
            }
64
65
            STDMETHODIMP_(ULONG) AddRef()
66
            {
67
                return InterlockedIncrement(&m_refCount);
68
            }
69
70
            STDMETHODIMP_(ULONG) Release()
71
            {
72
                ULONG refCount = InterlockedDecrement(&m_refCount);
73
                if (refCount == 0) {
74
                    delete this;
75
                }
76
77
                return refCount;
78
            }
79
80
            STDMETHODIMP Next(ULONG count,IPin **ret,ULONG *fetched)
81
            {
82
                QMutexLocker locker(&m_mutex);
83
                if (m_filter->pins() != m_pins) {
84
                    return VFW_E_ENUM_OUT_OF_SYNC;
85
                }
86
87
                if (fetched == 0 && count > 1) {
88
                    return E_INVALIDARG;
89
                }
90
91
                if (!ret) {
92
                    return E_POINTER;
93
                }
94
95
                uint nbfetched = 0;
96
                while (nbfetched < count && m_index < m_pins.count()) {
97
                    IPin *current = m_pins[m_index];
98
                    current->AddRef();
99
                    ret[nbfetched] = current;
100
                    nbfetched++;
101
                    m_index++;
102
                }
103
104
                if (fetched) {
105
                    *fetched = nbfetched;
106
                }
107
108
                return nbfetched == count ? S_OK : S_FALSE;
109
            }
110
111
            STDMETHODIMP Skip(ULONG count)
112
            {
113
                QMutexLocker locker(&m_mutex);
114
                if (m_filter->pins() != m_pins) {
115
                    return VFW_E_ENUM_OUT_OF_SYNC;
116
                }
117
118
                m_index = qMin(m_index + int(count), m_pins.count());
119
                return m_index == m_pins.count() ? S_FALSE : S_OK;
120
            }
121
122
            STDMETHODIMP Reset()
123
            {
124
                QMutexLocker locker(&m_mutex);
125
                m_index = 0;
126
                return S_OK;
127
            }
128
129
            STDMETHODIMP Clone(IEnumPins **out)
130
            {
131
                QMutexLocker locker(&m_mutex);
132
                if (m_filter->pins() != m_pins) {
133
                    return VFW_E_ENUM_OUT_OF_SYNC;
134
                }
135
136
                if (!out) {
137
                    return E_POINTER;
138
                }
139
140
                *out = new QEnumPins(m_filter);
141
                (*out)->Skip(m_index);
142
                return S_OK;
143
            }
144
145
146
        private:
147
            LONG m_refCount;
148
            QBaseFilter *m_filter;
149
            QList<QPin*> m_pins;
150
            int m_index;
151
            QMutex m_mutex;
152
        };
153
154
155
        QBaseFilter::QBaseFilter(const CLSID &clsid):
156
        m_refCount(1), m_clsid(clsid), m_clock(0), m_graph(0), m_state(State_Stopped)
157
        {
158
        }
159
160
        QBaseFilter::~QBaseFilter()
161
        {
162
            while (!m_pins.isEmpty()) {
163
                delete m_pins.first();
164
            }
165
        }
166
167
        const QList<QPin *> QBaseFilter::pins() const
168
        {
169
            QMutexLocker locker(&m_mutex);
170
            return m_pins;
171
        }
172
173
        void QBaseFilter::addPin(QPin *pin)
174
        {
175
            QMutexLocker locker(&m_mutex);
176
            m_pins.append(pin);
177
        }
178
179
        void QBaseFilter::removePin(QPin *pin)
180
        {
181
            QMutexLocker locker(&m_mutex);
182
            m_pins.removeAll(pin);
183
        }
184
185
        FILTER_STATE QBaseFilter::state() const
186
        {
187
            return m_state;
188
        }
189
        
190
        IFilterGraph *QBaseFilter::graph() const
191
        {
192
            return m_graph;
193
        }
194
195
        STDMETHODIMP QBaseFilter::QueryInterface(REFIID iid, void **out)
196
        {
197
            if (!out) {
198
                return E_POINTER;
199
            }
200
201
            HRESULT hr = S_OK;
202
203
            if (iid == IID_IBaseFilter) {
204
                *out = static_cast<IBaseFilter*>(this);
205
            } else if (iid == IID_IMediaFilter) {
206
                *out = static_cast<IMediaFilter*>(this);
207
            } else if (iid == IID_IPersist) {
208
                *out = static_cast<IPersist*>(this);
209
            } else if (iid == IID_IUnknown) {
210
                *out = static_cast<IUnknown*>(static_cast<IBaseFilter*>(this));
211
            }
212
            else if (iid == IID_IMediaPosition || iid == IID_IMediaSeeking) {
213
                if (inputPins().isEmpty()) {
214
                    *out = getUpStreamInterface(iid);
215
                    if (*out) {
216
                        return S_OK; //we return here to avoid adding a reference
217
                    } else {
218
                        hr = E_NOINTERFACE;
219
                    }
220
                } else if (iid == IID_IMediaSeeking) {
221
                    *out = static_cast<IMediaSeeking*>(this);
222
                } else if (iid == IID_IMediaPosition ||iid == IID_IDispatch) {
223
                    *out = static_cast<IMediaPosition*>(this);
224
                } 
225
            } else {
226
                *out = 0;
227
                hr = E_NOINTERFACE;
228
            }
229
230
            if (hr == S_OK) {
231
                AddRef();
232
            }
233
234
            return hr;
235
        }
236
237
        STDMETHODIMP_(ULONG) QBaseFilter::AddRef()
238
        {
239
            return InterlockedIncrement(&m_refCount);
240
        }
241
242
        STDMETHODIMP_(ULONG) QBaseFilter::Release()
243
        {
244
            ULONG refCount = InterlockedDecrement(&m_refCount);
245
            if (refCount == 0) {
246
                delete this;
247
            }
248
249
            return refCount;
250
        }
251
252
        STDMETHODIMP QBaseFilter::GetClassID(CLSID *clsid)
253
        {
254
            QMutexLocker locker(&m_mutex);
255
            *clsid = m_clsid;
256
            return S_OK;
257
        }
258
259
        STDMETHODIMP QBaseFilter::Stop()
260
        {
261
            QMutexLocker locker(&m_mutex);
262
            m_state = State_Stopped;
263
            return S_OK;
264
        }
265
266
        STDMETHODIMP QBaseFilter::Pause()
267
        {
268
            QMutexLocker locker(&m_mutex);
269
            m_state = State_Paused;
270
            return S_OK;
271
        }
272
273
        STDMETHODIMP QBaseFilter::Run(REFERENCE_TIME)
274
        {
275
            QMutexLocker locker(&m_mutex);
276
            m_state = State_Running;
277
            return S_OK;
278
        }
279
280
        STDMETHODIMP QBaseFilter::GetState(DWORD, FILTER_STATE *state)
281
        {
282
            QMutexLocker locker(&m_mutex);
283
            if (!state) {
284
                return E_POINTER;
285
            }
286
287
            *state = m_state;
288
            return S_OK;
289
        }
290
291
        STDMETHODIMP QBaseFilter::SetSyncSource(IReferenceClock *clock)
292
        {
293
            QMutexLocker locker(&m_mutex);
294
            if (clock) {
295
                clock->AddRef();
296
            }
297
            if (m_clock) {
298
                m_clock->Release();
299
            }
300
            m_clock = clock;
301
            return S_OK;
302
        }
303
304
        STDMETHODIMP QBaseFilter::GetSyncSource(IReferenceClock **clock)
305
        {
306
            QMutexLocker locker(&m_mutex);
307
            if (!clock) {
308
                return E_POINTER;
309
            }
310
311
            if (m_clock) {
312
                m_clock->AddRef();
313
            }
314
315
            *clock = m_clock;
316
            return S_OK;
317
        }
318
319
        STDMETHODIMP QBaseFilter::FindPin(LPCWSTR name, IPin**pin)
320
        {
321
            if (!pin) {
322
                return E_POINTER;
323
            }
324
325
            for (int i = 0; i < m_pins.count(); ++i) {
326
                IPin * current = m_pins.at(i);
327
                PIN_INFO info;
328
                current->QueryPinInfo(&info);
329
                if (info.pFilter) {
330
                    info.pFilter->Release();
331
                }
332
                if ( wcscmp(info.achName, name) == 0) {
333
                    *pin = current;
334
                    current->AddRef();
335
                    return S_OK;
336
                }
337
            }
338
339
            *pin = 0;
340
            return VFW_E_NOT_FOUND;
341
        }
342
343
        STDMETHODIMP QBaseFilter::QueryFilterInfo(FILTER_INFO *info )
344
        {
345
            QMutexLocker locker(&m_mutex);
346
            if (!info) {
347
                return E_POINTER;
348
            }
349
            info->pGraph = m_graph;
350
            if (m_graph) {
351
                m_graph->AddRef();
352
            }
353
            qMemCopy(info->achName, m_name.utf16(), qMin(MAX_FILTER_NAME, m_name.length()+1) *2);
354
            return S_OK;
355
        }
356
357
        STDMETHODIMP QBaseFilter::JoinFilterGraph(IFilterGraph *graph, LPCWSTR name)
358
        {
359
            QMutexLocker locker(&m_mutex);
360
            m_graph = graph;
361
            m_name = QString::fromWCharArray(name);
362
            return S_OK;
363
        }
364
365
        STDMETHODIMP QBaseFilter::EnumPins( IEnumPins **ep)
366
        {
367
            if (!ep) {
368
                return E_POINTER;
369
            }
370
371
            *ep = new QEnumPins(this);
372
            return S_OK;
373
        }
374
375
376
        STDMETHODIMP QBaseFilter::QueryVendorInfo(LPWSTR *)
377
        {
378
            //we give no information on that
379
            return E_NOTIMPL;
380
        }
381
382
                //implementation from IMediaSeeking
383
        STDMETHODIMP QBaseFilter::GetCapabilities(DWORD *pCapabilities)
384
        {
385
            IMediaSeeking *ms = getUpstreamMediaSeeking();
386
            if (!ms) {
387
                return E_NOTIMPL;
388
            }
389
390
            HRESULT hr = ms->GetCapabilities(pCapabilities);
391
            ms->Release();
392
            return hr;
393
        }
394
395
        STDMETHODIMP QBaseFilter::CheckCapabilities(DWORD *pCapabilities)
396
        {
397
            IMediaSeeking *ms = getUpstreamMediaSeeking();
398
            if (!ms) {
399
                return E_NOTIMPL;
400
            }
401
402
            HRESULT hr = ms->CheckCapabilities(pCapabilities);
403
            ms->Release();
404
            return hr;
405
        }
406
407
        STDMETHODIMP QBaseFilter::IsFormatSupported(const GUID *pFormat)
408
        {
409
            IMediaSeeking *ms = getUpstreamMediaSeeking();
410
            if (!ms) {
411
                return E_NOTIMPL;
412
            }
413
414
            HRESULT hr = ms->IsFormatSupported(pFormat);
415
            ms->Release();
416
            return hr;
417
        }
418
419
        STDMETHODIMP QBaseFilter::QueryPreferredFormat(GUID *pFormat)
420
        {
421
            IMediaSeeking *ms = getUpstreamMediaSeeking();
422
            if (!ms) {
423
                return E_NOTIMPL;
424
            }
425
426
            HRESULT hr = ms->QueryPreferredFormat(pFormat);
427
            ms->Release();
428
            return hr;
429
        }
430
431
        STDMETHODIMP QBaseFilter::GetTimeFormat(GUID *pFormat)
432
        {
433
            IMediaSeeking *ms = getUpstreamMediaSeeking();
434
            if (!ms) {
435
                return E_NOTIMPL;
436
            }
437
438
            HRESULT hr = ms->GetTimeFormat(pFormat);
439
            ms->Release();
440
            return hr;
441
        }
442
443
        STDMETHODIMP QBaseFilter::IsUsingTimeFormat(const GUID *pFormat)
444
        {
445
            IMediaSeeking *ms = getUpstreamMediaSeeking();
446
            if (!ms) {
447
                return E_NOTIMPL;
448
            }
449
450
            HRESULT hr = ms->IsUsingTimeFormat(pFormat);
451
            ms->Release();
452
            return hr;
453
        }
454
455
        STDMETHODIMP QBaseFilter::SetTimeFormat(const GUID *pFormat)
456
        {
457
            IMediaSeeking *ms = getUpstreamMediaSeeking();
458
            if (!ms) {
459
                return E_NOTIMPL;
460
            }
461
462
            HRESULT hr = ms->SetTimeFormat(pFormat);
463
            ms->Release();
464
            return hr;
465
        }
466
467
        STDMETHODIMP QBaseFilter::GetDuration(LONGLONG *pDuration)
468
        {
469
            IMediaSeeking *ms = getUpstreamMediaSeeking();
470
            if (!ms) {
471
                return E_NOTIMPL;
472
            }
473
474
            HRESULT hr = ms->GetDuration(pDuration);
475
            ms->Release();
476
            return hr;
477
        }
478
479
        STDMETHODIMP QBaseFilter::GetStopPosition(LONGLONG *pStop)
480
        {
481
            IMediaSeeking *ms = getUpstreamMediaSeeking();
482
            if (!ms) {
483
                return E_NOTIMPL;
484
            }
485
486
            HRESULT hr = ms->GetStopPosition(pStop);
487
            ms->Release();
488
            return hr;
489
        }
490
491
        STDMETHODIMP QBaseFilter::GetCurrentPosition(LONGLONG *pCurrent)
492
        {
493
            IMediaSeeking *ms = getUpstreamMediaSeeking();
494
            if (!ms) {
495
                return E_NOTIMPL;
496
            }
497
498
            HRESULT hr = ms->GetCurrentPosition(pCurrent);
499
            ms->Release();
500
            return hr;
501
        }
502
503
        STDMETHODIMP QBaseFilter::ConvertTimeFormat(LONGLONG *pTarget, 
504
            const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat)
505
        {
506
            IMediaSeeking *ms = getUpstreamMediaSeeking();
507
            if (!ms) {
508
                return E_NOTIMPL;
509
            }
510
511
            HRESULT hr = ms->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
512
            ms->Release();
513
            return hr;
514
        }
515
516
        STDMETHODIMP QBaseFilter::SetPositions(LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags)
517
        {
518
            IMediaSeeking *ms = getUpstreamMediaSeeking();
519
            if (!ms) {
520
                return E_NOTIMPL;
521
            }
522
523
            HRESULT hr = ms->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
524
            ms->Release();
525
            return hr;
526
        }
527
528
        STDMETHODIMP QBaseFilter::GetPositions(LONGLONG *pCurrent, LONGLONG *pStop)
529
        {
530
            IMediaSeeking *ms = getUpstreamMediaSeeking();
531
            if (!ms) {
532
                return E_NOTIMPL;
533
            }
534
535
            HRESULT hr = ms->GetPositions(pCurrent, pStop);
536
            ms->Release();
537
            return hr;
538
        }
539
540
        STDMETHODIMP QBaseFilter::GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest)
541
        {
542
            IMediaSeeking *ms = getUpstreamMediaSeeking();
543
            if (!ms) {
544
                return E_NOTIMPL;
545
            }
546
547
            HRESULT hr = ms->GetAvailable(pEarliest, pLatest);
548
            ms->Release();
549
            return hr;
550
        }
551
552
        STDMETHODIMP QBaseFilter::SetRate(double dRate)
553
        {
554
            IMediaSeeking *ms = getUpstreamMediaSeeking();
555
            if (!ms) {
556
                return E_NOTIMPL;
557
            }
558
559
            HRESULT hr = ms->SetRate(dRate);
560
            ms->Release();
561
            return hr;
562
        }
563
564
        STDMETHODIMP QBaseFilter::GetRate(double *dRate)
565
        {
566
            IMediaSeeking *ms = getUpstreamMediaSeeking();
567
            if (!ms) {
568
                return E_NOTIMPL;
569
            }
570
571
            HRESULT hr = ms->GetRate(dRate);
572
            ms->Release();
573
            return hr;
574
        }
575
576
        STDMETHODIMP QBaseFilter::GetPreroll(LONGLONG *pllPreroll)
577
        {
578
            IMediaSeeking *ms = getUpstreamMediaSeeking();
579
            if (!ms) {
580
                return E_NOTIMPL;
581
            }
582
583
            HRESULT hr = ms->GetPreroll(pllPreroll);
584
            ms->Release();
585
            return hr;
586
        }
587
588
        //implementation from IMediaPosition
589
        STDMETHODIMP QBaseFilter::get_Duration(REFTIME *plength)
590
        {
591
            IMediaPosition *mp = getUpstreamMediaPosition();
592
            if (!mp) {
593
                return E_NOTIMPL;
594
            }
595
596
            HRESULT hr = mp->get_Duration(plength);
597
            mp->Release();
598
            return hr;
599
        }
600
601
        STDMETHODIMP QBaseFilter::put_CurrentPosition(REFTIME llTime)
602
        {
603
            IMediaPosition *mp = getUpstreamMediaPosition();
604
            if (!mp) {
605
                return E_NOTIMPL;
606
            }
607
608
            HRESULT hr = mp->put_CurrentPosition(llTime);
609
            mp->Release();
610
            return hr;
611
        }
612
613
        STDMETHODIMP QBaseFilter::get_CurrentPosition(REFTIME *pllTime)
614
        {
615
            IMediaPosition *mp = getUpstreamMediaPosition();
616
            if (!mp) {
617
                return E_NOTIMPL;
618
            }
619
620
            HRESULT hr = mp->get_CurrentPosition(pllTime);
621
            mp->Release();
622
            return hr;
623
        }
624
625
        STDMETHODIMP QBaseFilter::get_StopTime(REFTIME *pllTime)
626
        {
627
            IMediaPosition *mp = getUpstreamMediaPosition();
628
            if (!mp) {
629
                return E_NOTIMPL;
630
            }
631
632
            HRESULT hr = mp->get_StopTime(pllTime);
633
            mp->Release();
634
            return hr;
635
        }
636
637
        STDMETHODIMP QBaseFilter::put_StopTime(REFTIME llTime)
638
        {
639
            IMediaPosition *mp = getUpstreamMediaPosition();
640
            if (!mp) {
641
                return E_NOTIMPL;
642
            }
643
644
            HRESULT hr = mp->put_StopTime(llTime);
645
            mp->Release();
646
            return hr;
647
        }
648
649
        STDMETHODIMP QBaseFilter::get_PrerollTime(REFTIME *pllTime)
650
        {
651
            IMediaPosition *mp = getUpstreamMediaPosition();
652
            if (!mp) {
653
                return E_NOTIMPL;
654
            }
655
656
            HRESULT hr = mp->get_PrerollTime(pllTime);
657
            mp->Release();
658
            return hr;
659
        }
660
661
        STDMETHODIMP QBaseFilter::put_PrerollTime(REFTIME llTime)
662
        {
663
            IMediaPosition *mp = getUpstreamMediaPosition();
664
            if (!mp) {
665
                return E_NOTIMPL;
666
            }
667
668
            HRESULT hr = mp->put_PrerollTime(llTime);
669
            mp->Release();
670
            return hr;
671
        }
672
673
        STDMETHODIMP QBaseFilter::put_Rate(double dRate)
674
        {
675
            IMediaPosition *mp = getUpstreamMediaPosition();
676
            if (!mp) {
677
                return E_NOTIMPL;
678
            }
679
680
            HRESULT hr = mp->put_Rate(dRate);
681
            mp->Release();
682
            return hr;
683
        }
684
685
        STDMETHODIMP QBaseFilter::get_Rate(double *pdRate)
686
        {
687
            IMediaPosition *mp = getUpstreamMediaPosition();
688
            if (!mp) {
689
                return E_NOTIMPL;
690
            }
691
692
            HRESULT hr = mp->get_Rate(pdRate);
693
            mp->Release();
694
            return hr;
695
        }
696
697
        STDMETHODIMP QBaseFilter::CanSeekForward(LONG *pCanSeekForward)
698
        {
699
            IMediaPosition *mp = getUpstreamMediaPosition();
700
            if (!mp) {
701
                return E_NOTIMPL;
702
            }
703
704
            HRESULT hr = mp->CanSeekForward(pCanSeekForward);
705
            mp->Release();
706
            return hr;
707
        }
708
709
        STDMETHODIMP QBaseFilter::CanSeekBackward(LONG *pCanSeekBackward)
710
        {
711
            IMediaPosition *mp = getUpstreamMediaPosition();
712
            if (!mp) {
713
                return E_NOTIMPL;
714
            }
715
716
            HRESULT hr = mp->CanSeekBackward(pCanSeekBackward);
717
            mp->Release();
718
            return hr;
719
        }
720
721
        STDMETHODIMP QBaseFilter::GetTypeInfoCount(UINT *pctinfo)
722
        {
723
            IMediaPosition *mp = getUpstreamMediaPosition();
724
            if (!mp) {
725
                return E_NOTIMPL;
726
            }
727
728
            HRESULT hr = mp->GetTypeInfoCount(pctinfo);
729
            mp->Release();
730
            return hr;
731
        }
732
733
        STDMETHODIMP QBaseFilter::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
734
        {
735
            IMediaPosition *mp = getUpstreamMediaPosition();
736
            if (!mp) {
737
                return E_NOTIMPL;
738
            }
739
740
            HRESULT hr = mp->GetTypeInfo(iTInfo, lcid, ppTInfo);
741
            mp->Release();
742
            return hr;
743
        }
744
745
        STDMETHODIMP QBaseFilter::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
746
        {
747
            IMediaPosition *mp = getUpstreamMediaPosition();
748
            if (!mp) {
749
                return E_NOTIMPL;
750
            }
751
752
            HRESULT hr = mp->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
753
            mp->Release();
754
            return hr;
755
        }
756
757
        STDMETHODIMP QBaseFilter::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 
758
            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
759
        {
760
            IMediaPosition *mp = getUpstreamMediaPosition();
761
            if (!mp) {
762
                return E_NOTIMPL;
763
            }
764
765
            HRESULT hr = mp->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
766
            mp->Release();
767
            return hr;
768
        }
769
770
771
        IMediaSeeking *QBaseFilter::getUpstreamMediaSeeking()
772
        {
773
            return static_cast<IMediaSeeking*>(getUpStreamInterface(IID_IMediaSeeking));
774
        }
775
776
        IMediaPosition *QBaseFilter::getUpstreamMediaPosition()
777
        {
778
            return static_cast<IMediaPosition*>(getUpStreamInterface(IID_IMediaPosition));
779
        }
780
781
        QList<QPin*> QBaseFilter::inputPins() const
782
        {
783
            QList<QPin*> ret;
784
            for(int i = 0; i < m_pins.count(); ++i) {
785
                QPin * pin = m_pins.at(i);
786
                if (pin->direction() == PINDIR_INPUT) {
787
                    ret += pin;
788
                }
789
            }
790
            return ret;
791
        }
792
793
        QList<QPin*> QBaseFilter::outputPins() const
794
        {
795
            QList<QPin*> ret;
796
            for(int i = 0; i < m_pins.count(); ++i) {
797
                QPin * pin = m_pins.at(i);
798
                if (pin->direction() == PINDIR_OUTPUT) {
799
                    ret += pin;
800
                }
801
            }
802
            return ret;
803
        }
804
805
        void *QBaseFilter::getUpStreamInterface(const IID &iid) const
806
        {
807
            const QList<QPin*> inputs = inputPins();
808
            for (int i = 0; i < inputs.count(); ++i) {
809
                IPin *out = inputs.at(i)->connected();
810
                if (out) {
811
                    void *ms = 0;
812
                    out->QueryInterface(iid, &ms);
813
                    if (ms) {
814
                        return ms;
815
                    }
816
                }
817
            }
818
            //none was found
819
            return 0;
820
        }
821
822
823
        //addition
824
        HRESULT QBaseFilter::processSample(IMediaSample *)
825
        {
826
            return S_OK;
827
        }
828
829
    }
830
}
831
832
QT_END_NAMESPACE