src/3rdparty/phonon/ds9/fakesource.cpp
changeset 0 1918ee327afb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/3rdparty/phonon/ds9/fakesource.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,144 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fakesource.h"
+#include "qpin.h"
+
+#include <dshow.h>
+#include <initguid.h>
+#include <dvdmedia.h> // VIDEOINFOHEADER2
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+    namespace DS9
+    {
+        static WAVEFORMATEX g_defaultWaveFormat = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0};
+        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} };
+
+        static const AM_MEDIA_TYPE g_fakeAudioType = {MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 0, 0, 2, FORMAT_WaveFormatEx, 0, sizeof(WAVEFORMATEX), reinterpret_cast<BYTE*>(&g_defaultWaveFormat)};
+        static const AM_MEDIA_TYPE g_fakeVideoType = {MEDIATYPE_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 0, FORMAT_VideoInfo2, 0, sizeof(VIDEOINFOHEADER2), reinterpret_cast<BYTE*>(&g_defaultVideoInfo)};
+
+        class FakePin : public QPin
+        {
+        public:
+            FakePin(FakeSource *source, const AM_MEDIA_TYPE &mt) :
+              QPin(source, PINDIR_OUTPUT, QVector<AM_MEDIA_TYPE>() << mt), m_source(source)
+              {
+                  setAvailable(true);
+              }
+
+              ~FakePin()
+              {
+              }
+
+
+              STDMETHODIMP Disconnect()
+              {
+                  HRESULT hr = QPin::Disconnect();
+                  if (SUCCEEDED(hr)) {
+                      setAvailable(true);
+                  }
+                  return hr;
+              }
+
+
+              STDMETHODIMP Connect(IPin *pin, const AM_MEDIA_TYPE *type)
+              {
+                  HRESULT hr = QPin::Connect(pin, type);
+                  if (SUCCEEDED(hr)) {
+                      setAvailable(false);
+                  }
+                  return hr;
+              }
+
+        private:
+            void setAvailable(bool avail)
+            {
+                if (mediaTypes().first().majortype == MEDIATYPE_Audio) {
+                    if (avail) {
+                        m_source->addAvailableAudioPin(this);
+                    } else {
+                        m_source->removeAvailableAudioPin(this);
+                    }
+                } else {
+                    if (avail) {
+                        m_source->addAvailableVideoPin(this);
+                    } else {
+                        m_source->removeAvailableVideoPin(this);
+                    }
+                }
+            }
+
+            FakeSource *m_source;
+
+
+        };
+
+        FakeSource::FakeSource() : QBaseFilter(CLSID_NULL)
+        {
+            createFakeAudioPin();
+            createFakeVideoPin();
+        }
+
+        FakeSource::~FakeSource()
+        {
+        }
+
+        void FakeSource::addAvailableAudioPin(FakePin *pin)
+        {
+            availableAudioPins += pin;
+        }
+
+        void FakeSource::addAvailableVideoPin(FakePin *pin)
+        {
+            availableVideoPins += pin;
+        }
+
+        void FakeSource::removeAvailableAudioPin(FakePin *pin)
+        {
+            availableAudioPins -= pin;
+
+            if (availableAudioPins.isEmpty()) {
+                createFakeAudioPin();
+            }
+        }
+
+        void FakeSource::removeAvailableVideoPin(FakePin *pin)
+        {
+            availableVideoPins -= pin;
+
+            if (availableVideoPins.isEmpty()) {
+                createFakeVideoPin();
+            }
+        }
+
+        void FakeSource::createFakeAudioPin()
+        {
+            new FakePin(this, g_fakeAudioType);
+        }
+
+        void FakeSource::createFakeVideoPin()
+        {
+            new FakePin(this, g_fakeVideoType);
+        }
+
+    }
+}
+
+QT_END_NAMESPACE