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 "fakesource.h"
19
#include "qpin.h"
20
21
#include <dshow.h>
22
#include <initguid.h>
23
#include <dvdmedia.h> // VIDEOINFOHEADER2
24
25
QT_BEGIN_NAMESPACE
26
27
namespace Phonon
28
{
29
    namespace DS9
30
    {
31
        static WAVEFORMATEX g_defaultWaveFormat = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0};
32
        static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0} };
33
34
        static const AM_MEDIA_TYPE g_fakeAudioType = {MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 0, 0, 2, FORMAT_WaveFormatEx, 0, sizeof(WAVEFORMATEX), reinterpret_cast<BYTE*>(&g_defaultWaveFormat)};
35
        static const AM_MEDIA_TYPE g_fakeVideoType = {MEDIATYPE_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 0, FORMAT_VideoInfo2, 0, sizeof(VIDEOINFOHEADER2), reinterpret_cast<BYTE*>(&g_defaultVideoInfo)};
36
37
        class FakePin : public QPin
38
        {
39
        public:
40
            FakePin(FakeSource *source, const AM_MEDIA_TYPE &mt) :
41
              QPin(source, PINDIR_OUTPUT, QVector<AM_MEDIA_TYPE>() << mt), m_source(source)
42
              {
43
                  setAvailable(true);
44
              }
45
46
              ~FakePin()
47
              {
48
              }
49
50
51
              STDMETHODIMP Disconnect()
52
              {
53
                  HRESULT hr = QPin::Disconnect();
54
                  if (SUCCEEDED(hr)) {
55
                      setAvailable(true);
56
                  }
57
                  return hr;
58
              }
59
60
61
              STDMETHODIMP Connect(IPin *pin, const AM_MEDIA_TYPE *type)
62
              {
63
                  HRESULT hr = QPin::Connect(pin, type);
64
                  if (SUCCEEDED(hr)) {
65
                      setAvailable(false);
66
                  }
67
                  return hr;
68
              }
69
70
        private:
71
            void setAvailable(bool avail)
72
            {
73
                if (mediaTypes().first().majortype == MEDIATYPE_Audio) {
74
                    if (avail) {
75
                        m_source->addAvailableAudioPin(this);
76
                    } else {
77
                        m_source->removeAvailableAudioPin(this);
78
                    }
79
                } else {
80
                    if (avail) {
81
                        m_source->addAvailableVideoPin(this);
82
                    } else {
83
                        m_source->removeAvailableVideoPin(this);
84
                    }
85
                }
86
            }
87
88
            FakeSource *m_source;
89
90
91
        };
92
93
        FakeSource::FakeSource() : QBaseFilter(CLSID_NULL)
94
        {
95
            createFakeAudioPin();
96
            createFakeVideoPin();
97
        }
98
99
        FakeSource::~FakeSource()
100
        {
101
        }
102
103
        void FakeSource::addAvailableAudioPin(FakePin *pin)
104
        {
105
            availableAudioPins += pin;
106
        }
107
108
        void FakeSource::addAvailableVideoPin(FakePin *pin)
109
        {
110
            availableVideoPins += pin;
111
        }
112
113
        void FakeSource::removeAvailableAudioPin(FakePin *pin)
114
        {
115
            availableAudioPins -= pin;
116
117
            if (availableAudioPins.isEmpty()) {
118
                createFakeAudioPin();
119
            }
120
        }
121
122
        void FakeSource::removeAvailableVideoPin(FakePin *pin)
123
        {
124
            availableVideoPins -= pin;
125
126
            if (availableVideoPins.isEmpty()) {
127
                createFakeVideoPin();
128
            }
129
        }
130
131
        void FakeSource::createFakeAudioPin()
132
        {
133
            new FakePin(this, g_fakeAudioType);
134
        }
135
136
        void FakeSource::createFakeVideoPin()
137
        {
138
            new FakePin(this, g_fakeVideoType);
139
        }
140
141
    }
142
}
143
144
QT_END_NAMESPACE