diff options
Diffstat (limited to 'src/plugins/wmf')
22 files changed, 0 insertions, 6753 deletions
diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.cpp b/src/plugins/wmf/player/evr9videowindowcontrol.cpp deleted file mode 100644 index e653dd9..0000000 --- a/src/plugins/wmf/player/evr9videowindowcontrol.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "evr9videowindowcontrol.h" -#include <QtCore/qdebug.h> -#include <QtCore/qglobal.h> - -Evr9VideoWindowControl::Evr9VideoWindowControl(QObject *parent) - : QVideoWindowControl(parent) - , m_windowId(0) - , m_dirtyValues(0) - , m_aspectRatioMode(Qt::KeepAspectRatio) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) - , m_fullScreen(false) - , m_currentActivate(0) - , m_evrSink(0) - , m_displayControl(0) -{ - if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) { - qWarning() << "Failed to create evr video renderer activate!"; - return; - } - if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) { - qWarning() << "Failed to activate evr media sink!"; - return; - } - if (FAILED(MFGetService(m_evrSink, MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) { - qWarning() << "Failed to get display control from evr media sink!"; - return; - } - if (FAILED(MFGetService(m_evrSink, MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)))) { - qWarning() << "Failed to get video processor from evr media sink!"; - return; - } -} - -Evr9VideoWindowControl::~Evr9VideoWindowControl() -{ - if (m_processor) - m_processor->Release(); - if (m_displayControl) - m_displayControl->Release(); - if (m_evrSink) - m_evrSink->Release(); - if (m_currentActivate) { - m_currentActivate->ShutdownObject(); - m_currentActivate->Release(); - } -} - - -WId Evr9VideoWindowControl::winId() const -{ - return m_windowId; -} - -void Evr9VideoWindowControl::setWinId(WId id) -{ - m_windowId = id; - - if (QWidget *widget = QWidget::find(m_windowId)) { - const QColor color = widget->palette().color(QPalette::Window); - - m_windowColor = RGB(color.red(), color.green(), color.blue()); - } - - if (m_displayControl) { - m_displayControl->SetVideoWindow(m_windowId); - } -} - -QRect Evr9VideoWindowControl::displayRect() const -{ - return m_displayRect; -} - -void Evr9VideoWindowControl::setDisplayRect(const QRect &rect) -{ - m_displayRect = rect; - - if (m_displayControl) { - RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 }; - QSize sourceSize = nativeSize(); - - RECT sourceRect = { 0, 0, sourceSize.width(), sourceSize.height() }; - - if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) { - QSize clippedSize = rect.size(); - clippedSize.scale(sourceRect.right, sourceRect.bottom, Qt::KeepAspectRatio); - - sourceRect.left = (sourceRect.right - clippedSize.width()) / 2; - sourceRect.top = (sourceRect.bottom - clippedSize.height()) / 2; - sourceRect.right = sourceRect.left + clippedSize.width(); - sourceRect.bottom = sourceRect.top + clippedSize.height(); - } - - if (sourceSize.width() > 0 && sourceSize.height() > 0) { - MFVideoNormalizedRect sourceNormRect; - sourceNormRect.left = float(sourceRect.left) / float(sourceRect.right); - sourceNormRect.top = float(sourceRect.top) / float(sourceRect.bottom); - sourceNormRect.right = float(sourceRect.right) / float(sourceRect.right); - sourceNormRect.bottom = float(sourceRect.bottom) / float(sourceRect.bottom); - m_displayControl->SetVideoPosition(&sourceNormRect, &displayRect); - } else { - m_displayControl->SetVideoPosition(NULL, &displayRect); - } - } -} - -bool Evr9VideoWindowControl::isFullScreen() const -{ - return m_fullScreen; -} - -void Evr9VideoWindowControl::setFullScreen(bool fullScreen) -{ - if (m_fullScreen == fullScreen) - return; - emit fullScreenChanged(m_fullScreen = fullScreen); -} - -void Evr9VideoWindowControl::repaint() -{ - QSize size = nativeSize(); - if (size.width() > 0 && size.height() > 0 - && m_displayControl - && SUCCEEDED(m_displayControl->RepaintVideo())) { - return; - } - - PAINTSTRUCT paint; - if (HDC dc = ::BeginPaint(m_windowId, &paint)) { - HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor); - HBRUSH brush = ::CreateSolidBrush(m_windowColor); - ::SelectObject(dc, pen); - ::SelectObject(dc, brush); - - ::Rectangle( - dc, - m_displayRect.left(), - m_displayRect.top(), - m_displayRect.right() + 1, - m_displayRect.bottom() + 1); - - ::DeleteObject(pen); - ::DeleteObject(brush); - ::EndPaint(m_windowId, &paint); - } -} - -QSize Evr9VideoWindowControl::nativeSize() const -{ - QSize size; - if (m_displayControl) { - SIZE sourceSize; - if (SUCCEEDED(m_displayControl->GetNativeVideoSize(&sourceSize, 0))) - size = QSize(sourceSize.cx, sourceSize.cy); - } - return size; -} - -Qt::AspectRatioMode Evr9VideoWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void Evr9VideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_aspectRatioMode = mode; - - if (m_displayControl) { - switch (mode) { - case Qt::IgnoreAspectRatio: - //comment from MSDN: Do not maintain the aspect ratio of the video. Stretch the video to fit the output rectangle. - m_displayControl->SetAspectRatioMode(MFVideoARMode_None); - break; - case Qt::KeepAspectRatio: - //comment from MSDN: Preserve the aspect ratio of the video by letterboxing or within the output rectangle. - m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture); - break; - case Qt::KeepAspectRatioByExpanding: - //for this mode, more adjustment will be done in setDisplayRect - m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture); - break; - default: - break; - } - setDisplayRect(m_displayRect); - } -} - -int Evr9VideoWindowControl::brightness() const -{ - return m_brightness; -} - -void Evr9VideoWindowControl::setBrightness(int brightness) -{ - if (m_brightness == brightness) - return; - - m_brightness = brightness; - - m_dirtyValues |= DXVA2_ProcAmp_Brightness; - - setProcAmpValues(); - - emit brightnessChanged(brightness); -} - -int Evr9VideoWindowControl::contrast() const -{ - return m_contrast; -} - -void Evr9VideoWindowControl::setContrast(int contrast) -{ - if (m_contrast == contrast) - return; - - m_contrast = contrast; - - m_dirtyValues |= DXVA2_ProcAmp_Contrast; - - setProcAmpValues(); - - emit contrastChanged(contrast); -} - -int Evr9VideoWindowControl::hue() const -{ - return m_hue; -} - -void Evr9VideoWindowControl::setHue(int hue) -{ - if (m_hue == hue) - return; - - m_hue = hue; - - m_dirtyValues |= DXVA2_ProcAmp_Hue; - - setProcAmpValues(); - - emit hueChanged(hue); -} - -int Evr9VideoWindowControl::saturation() const -{ - return m_saturation; -} - -void Evr9VideoWindowControl::setSaturation(int saturation) -{ - if (m_saturation == saturation) - return; - - m_saturation = saturation; - - m_dirtyValues |= DXVA2_ProcAmp_Saturation; - - setProcAmpValues(); - - emit saturationChanged(saturation); -} - -IMFActivate* Evr9VideoWindowControl::currentActivate() const -{ - return m_currentActivate; -} - -void Evr9VideoWindowControl::setProcAmpValues() -{ - if (m_processor) { - DXVA2_ProcAmpValues values; - if (m_dirtyValues & DXVA2_ProcAmp_Brightness) { - values.Brightness = scaleProcAmpValue(DXVA2_ProcAmp_Brightness, m_brightness); - } - if (m_dirtyValues & DXVA2_ProcAmp_Contrast) { - values.Contrast = scaleProcAmpValue(DXVA2_ProcAmp_Contrast, m_contrast); - } - if (m_dirtyValues & DXVA2_ProcAmp_Hue) { - values.Hue = scaleProcAmpValue(DXVA2_ProcAmp_Hue, m_hue); - } - if (m_dirtyValues & DXVA2_ProcAmp_Saturation) { - values.Saturation = scaleProcAmpValue(DXVA2_ProcAmp_Saturation, m_saturation); - } - - if (SUCCEEDED(m_processor->SetProcAmpValues(0, &values))) { - m_dirtyValues = 0; - } - } -} - -DXVA2_Fixed32 Evr9VideoWindowControl::scaleProcAmpValue(DWORD prop, int value) const -{ - float scaledValue = 0.0; - - DXVA2_ValueRange range; - if (SUCCEEDED(m_processor->GetProcAmpRange(prop, &range))) { - scaledValue = DXVA2FixedToFloat(range.DefaultValue); - if (value > 0) - scaledValue += float(value) * (DXVA2FixedToFloat(range.MaxValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100; - else if (value < 0) - scaledValue -= float(value) * (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100; - } - - return DXVA2FloatToFixed(scaledValue); -} diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.h b/src/plugins/wmf/player/evr9videowindowcontrol.h deleted file mode 100644 index a415243..0000000 --- a/src/plugins/wmf/player/evr9videowindowcontrol.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EVR9VIDEOWINDOWCONTROL_H -#define EVR9VIDEOWINDOWCONTROL_H - -#include "../../src/multimedia/qvideowindowcontrol.h" - -#include <Mfidl.h> -#include <d3d9.h> -#include <Evr9.h> - -QT_USE_NAMESPACE - -class Evr9VideoWindowControl : public QVideoWindowControl -{ - Q_OBJECT -public: - Evr9VideoWindowControl(QObject *parent = 0); - ~Evr9VideoWindowControl(); - - WId winId() const; - void setWinId(WId id); - - QRect displayRect() const; - void setDisplayRect(const QRect &rect); - - bool isFullScreen() const; - void setFullScreen(bool fullScreen); - - void repaint(); - - QSize nativeSize() const; - - Qt::AspectRatioMode aspectRatioMode() const; - void setAspectRatioMode(Qt::AspectRatioMode mode); - - int brightness() const; - void setBrightness(int brightness); - - int contrast() const; - void setContrast(int contrast); - - int hue() const; - void setHue(int hue); - - int saturation() const; - void setSaturation(int saturation); - - IMFActivate* currentActivate() const; - -private: - void setProcAmpValues(); - DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, int value) const; - - WId m_windowId; - COLORREF m_windowColor; - DWORD m_dirtyValues; - Qt::AspectRatioMode m_aspectRatioMode; - QRect m_displayRect; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - bool m_fullScreen; - - IMFActivate *m_currentActivate; - IMFMediaSink *m_evrSink; - IMFVideoDisplayControl *m_displayControl; - IMFVideoProcessor *m_processor; -}; - -#endif diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp deleted file mode 100644 index 290afe5..0000000 --- a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "QtCore/qdebug.h" -#include "mfaudioendpointcontrol.h" - -MFAudioEndpointControl::MFAudioEndpointControl(QObject *parent) - : QAudioEndpointSelector(parent) - , m_currentActivate(0) -{ - updateEndpoints(); - setActiveEndpoint(m_defaultEndpoint); -} - -MFAudioEndpointControl::~MFAudioEndpointControl() -{ - foreach (LPWSTR wstrID, m_devices) - CoTaskMemFree(wstrID); - - if (m_currentActivate) - m_currentActivate->Release(); -} - -QList<QString> MFAudioEndpointControl::availableEndpoints() const -{ - return m_devices.keys(); -} - -QString MFAudioEndpointControl::endpointDescription(const QString &name) const -{ - return name.section(QLatin1Char('\\'), -1); -} - -QString MFAudioEndpointControl::defaultEndpoint() const -{ - return m_defaultEndpoint; -} - -QString MFAudioEndpointControl::activeEndpoint() const -{ - return m_activeEndpoint; -} - -void MFAudioEndpointControl::setActiveEndpoint(const QString &name) -{ - if (m_activeEndpoint == name) - return; - QMap<QString, LPWSTR>::iterator it = m_devices.find(name); - if (it == m_devices.end()) - return; - - LPWSTR wstrID = *it; - IMFActivate *activate = NULL; - HRESULT hr = MFCreateAudioRendererActivate(&activate); - if (FAILED(hr)) { - qWarning() << "Failed to create audio renderer activate"; - return; - } - - if (wstrID) { - hr = activate->SetString(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, wstrID); - } else { - //This is the default one that has been inserted in updateEndpoints(), - //so give the activate a hint that we want to use the device for multimedia playback - //then the media foundation will choose an appropriate one. - - //from MSDN: - //The ERole enumeration defines constants that indicate the role that the system has assigned to an audio endpoint device. - //eMultimedia: Music, movies, narration, and live music recording. - hr = activate->SetUINT32(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia); - } - - if (FAILED(hr)) { - qWarning() << "Failed to set attribute for audio device" << name; - return; - } - - if (m_currentActivate) - m_currentActivate->Release(); - m_currentActivate = activate; - m_activeEndpoint = name; -} - -IMFActivate* MFAudioEndpointControl::currentActivate() const -{ - return m_currentActivate; -} - -void MFAudioEndpointControl::updateEndpoints() -{ - m_defaultEndpoint = QString::fromLatin1("Default"); - m_devices.insert(m_defaultEndpoint, NULL); - - IMMDeviceEnumerator *pEnum = NULL; - HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), - NULL, CLSCTX_ALL, - __uuidof(IMMDeviceEnumerator), - (void**)&pEnum); - if (SUCCEEDED(hr)) { - IMMDeviceCollection *pDevices = NULL; - hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices); - if (SUCCEEDED(hr)) { - UINT count; - hr = pDevices->GetCount(&count); - if (SUCCEEDED(hr)) { - for (UINT i = 0; i < count; ++i) { - IMMDevice *pDevice = NULL; - hr = pDevices->Item(i, &pDevice); - if (SUCCEEDED(hr)) { - LPWSTR wstrID = NULL; - hr = pDevice->GetId(&wstrID); - if (SUCCEEDED(hr)) { - QString deviceId = QString::fromWCharArray(wstrID); - m_devices.insert(deviceId, wstrID); - } - pDevice->Release(); - } - } - } - pDevices->Release(); - } - pEnum->Release(); - } -} diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.h b/src/plugins/wmf/player/mfaudioendpointcontrol.h deleted file mode 100644 index 67f7756..0000000 --- a/src/plugins/wmf/player/mfaudioendpointcontrol.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFAUDIOENDPOINTCONTROL_H -#define MFAUDIOENDPOINTCONTROL_H - -#include <mfapi.h> -#include <mfidl.h> -#include <mmdeviceapi.h> - -#include "../../src/multimedia/qaudioendpointselector.h" - -class MFPlayerService; - -QT_USE_NAMESPACE - -class MFAudioEndpointControl : public QAudioEndpointSelector -{ - Q_OBJECT -public: - MFAudioEndpointControl(QObject *parent = 0); - ~MFAudioEndpointControl(); - - QList<QString> availableEndpoints() const; - - QString endpointDescription(const QString &name) const; - - QString defaultEndpoint() const; - QString activeEndpoint() const; - - void setActiveEndpoint(const QString& name); - - IMFActivate* currentActivate() const; - -private: - void updateEndpoints(); - - QString m_defaultEndpoint; - QString m_activeEndpoint; - QMap<QString, LPWSTR> m_devices; - IMFActivate *m_currentActivate; - -}; - -#endif - diff --git a/src/plugins/wmf/player/mfmetadatacontrol.cpp b/src/plugins/wmf/player/mfmetadatacontrol.cpp deleted file mode 100644 index 4e62706..0000000 --- a/src/plugins/wmf/player/mfmetadatacontrol.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfmetadatacontrol.h" -#include "mfplayerservice.h" -#include "Propkey.h" - -//#define DEBUG_MEDIAFOUNDATION - -MFMetaDataControl::MFMetaDataControl(QObject *parent) - : QMetaDataReaderControl(parent) - , m_metaData(0) - , m_content(0) -{ -} - -MFMetaDataControl::~MFMetaDataControl() -{ - if (m_metaData) - m_metaData->Release(); - if (m_content) - m_content->Release(); -} - -bool MFMetaDataControl::isMetaDataAvailable() const -{ - return m_content || m_metaData; -} - -QVariant MFMetaDataControl::metaData(QtMultimedia::MetaData key) const -{ - QVariant value; - if (!isMetaDataAvailable()) - return value; - - int index = m_availableMetaDatas.indexOf(key); - if (index < 0) - return value; - - PROPVARIANT var; - PropVariantInit(&var); - HRESULT hr = S_FALSE; - if (m_content) - hr = m_content->GetValue(m_commonKeys[index], &var); - else if (m_metaData) - hr = m_metaData->GetProperty(m_commonNames[index].utf16(), &var); - - if (SUCCEEDED(hr)) - value = convertValue(var); - - PropVariantClear(&var); - return value; -} - -QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const -{ - QVariant value; - //form MSDN: http://msdn.microsoft.com/en-us/library/ff384862%28v=VS.85%29.aspx - //it seems that those 4 types are enough for media foundation metadata - //add more later if necessary - switch (var.vt) { - case VT_LPWSTR: - value = QString::fromUtf16(var.pwszVal); - break; - case VT_UI4: - value = uint(var.ulVal); - break; - case VT_UI8: - value = qulonglong(var.uhVal.QuadPart); - break; - case VT_BOOL: - value = bool(var.boolVal); - break; - } - return value; -} - -QList<QtMultimedia::MetaData> MFMetaDataControl::availableMetaData() const -{ - return m_availableMetaDatas; -} - -QVariant MFMetaDataControl::extendedMetaData(const QString &key) const -{ - QVariant value; - HRESULT hr = S_FALSE; - PROPVARIANT var; - PropVariantInit(&var); - if (m_content) { - int index = m_extendedMetaDatas.indexOf(key); - if (index >= 0) { - hr = m_content->GetValue(m_extendedKeys[index], &var); - } - } else if (m_metaData) { - hr = m_metaData->GetProperty(key.utf16(), &var); - } - - if (SUCCEEDED(hr)) - value = convertValue(var); - - PropVariantClear(&var); - return value; -} - -QStringList MFMetaDataControl::availableExtendedMetaData() const -{ - return m_extendedMetaDatas; -} - -void MFMetaDataControl::updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource) -{ - if (m_metaData) { - m_metaData->Release(); - m_metaData = 0; - } - - if (m_content) { - m_content->Release(); - m_content = 0; - } - - m_availableMetaDatas.clear(); - m_commonKeys.clear(); - m_commonNames.clear(); - m_extendedMetaDatas.clear(); - m_extendedKeys.clear(); - - if (SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&m_content)))) { - DWORD cProps; - if (SUCCEEDED(m_content->GetCount(&cProps))) { - for (DWORD i = 0; i < cProps; i++) - { - PROPERTYKEY key; - if (FAILED(m_content->GetAt(i, &key))) - continue; - bool common = true; - if (key == PKEY_Author) { - m_availableMetaDatas.push_back(QtMultimedia::Author); - } else if (key == PKEY_Title) { - m_availableMetaDatas.push_back(QtMultimedia::Title); - } else if (key == PKEY_ParentalRating) { - m_availableMetaDatas.push_back(QtMultimedia::ParentalRating); - } else if (key == PKEY_Comment) { - m_availableMetaDatas.push_back(QtMultimedia::Description); - } else if (key == PKEY_Copyright) { - m_availableMetaDatas.push_back(QtMultimedia::Copyright); - //TODO: add more common keys - } else { - common = false; - //TODO: add more extended keys - } - if (common) - m_commonKeys.push_back(key); - } - } else { - m_content->Release(); - m_content = NULL; - } - } - - if (!m_content) { - //fallback to Vista approach - IMFMetadataProvider *provider = NULL; - if (SUCCEEDED(MFGetService(mediaSource, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&provider)))) { - if (SUCCEEDED(provider->GetMFMetadata(sourcePD, 0, 0, &m_metaData))) { - PROPVARIANT varNames; - PropVariantInit(&varNames); - if (SUCCEEDED(m_metaData->GetAllPropertyNames(&varNames)) && varNames.vt == (VT_VECTOR | VT_LPWSTR)) { - ULONG cElements = varNames.calpwstr.cElems; - for (ULONG i = 0; i < cElements; i++) - { - const WCHAR* sName = varNames.calpwstr.pElems[i]; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "metadata: " << QString::fromUtf16(sName); -#endif - bool common = true; - if (wcscmp(sName, L"Author") == 0) { - m_availableMetaDatas.push_back(QtMultimedia::Author); - } else if (wcscmp(sName, L"Title") == 0) { - m_availableMetaDatas.push_back(QtMultimedia::Title); - } else if (wcscmp(sName, L"Rating") == 0) { - m_availableMetaDatas.push_back(QtMultimedia::ParentalRating); - } else if (wcscmp(sName, L"Description") == 0) { - m_availableMetaDatas.push_back(QtMultimedia::Description); - } else if (wcscmp(sName, L"Copyright") == 0) { - m_availableMetaDatas.push_back(QtMultimedia::Copyright); - //TODO: add more common keys - } else { - common = false; - m_extendedMetaDatas.push_back(QString::fromUtf16(sName)); - } - if (common) - m_commonNames.push_back(QString::fromUtf16(sName)); - } - } - PropVariantClear(&varNames); - } else { - qWarning("Failed to get IMFMetadata"); - } - provider->Release(); - } else { - qWarning("Failed to get IMFMetadataProvider from source"); - } - } - - emit metaDataChanged(); - emit metaDataAvailableChanged(m_metaData || m_content); -} diff --git a/src/plugins/wmf/player/mfmetadatacontrol.h b/src/plugins/wmf/player/mfmetadatacontrol.h deleted file mode 100644 index a73b778..0000000 --- a/src/plugins/wmf/player/mfmetadatacontrol.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFMETADATACONTROL_H -#define MFMETADATACONTROL_H - -#include <qmetadatareadercontrol.h> -#include "Mfidl.h" - -QT_USE_NAMESPACE - -class MFMetaDataControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - MFMetaDataControl(QObject *parent = 0); - ~MFMetaDataControl(); - - bool isMetaDataAvailable() const; - - QVariant metaData(QtMultimedia::MetaData key) const; - QList<QtMultimedia::MetaData> availableMetaData() const; - - QVariant extendedMetaData(const QString &key) const; - QStringList availableExtendedMetaData() const; - - void updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource); - -private: - QVariant convertValue(const PROPVARIANT& var) const; - IPropertyStore *m_content; //for Windows7 - IMFMetadata *m_metaData; //for Vista - - QList<QtMultimedia::MetaData> m_availableMetaDatas; - QList<PROPERTYKEY> m_commonKeys; //for Windows7 - QStringList m_commonNames; //for Vista - - QStringList m_extendedMetaDatas; - QList<PROPERTYKEY> m_extendedKeys; //for Windows7 -}; - -#endif diff --git a/src/plugins/wmf/player/mfplayercontrol.cpp b/src/plugins/wmf/player/mfplayercontrol.cpp deleted file mode 100644 index e3a3d80..0000000 --- a/src/plugins/wmf/player/mfplayercontrol.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfplayercontrol.h" -#include <qtcore/qdebug.h> - -//#define DEBUG_MEDIAFOUNDATION - -MFPlayerControl::MFPlayerControl(MFPlayerSession *session) -: QMediaPlayerControl(session) -, m_state(QMediaPlayer::StoppedState) -, m_videoAvailable(false) -, m_audioAvailable(false) -, m_duration(-1) -, m_seekable(false) -, m_session(session) -{ - QObject::connect(m_session, SIGNAL(statusChanged()), this, SLOT(handleStatusChanged())); - QObject::connect(m_session, SIGNAL(videoAvailable()), this, SLOT(handleVideoAvailable())); - QObject::connect(m_session, SIGNAL(audioAvailable()), this, SLOT(handleAudioAvailable())); - QObject::connect(m_session, SIGNAL(durationUpdate(qint64)), this, SLOT(handleDurationUpdate(qint64))); - QObject::connect(m_session, SIGNAL(seekableUpdate(bool)), this, SLOT(handleSeekableUpdate(bool))); - QObject::connect(m_session, SIGNAL(error(QMediaPlayer::Error, QString, bool)), this, SLOT(handleError(QMediaPlayer::Error, QString, bool))); - QObject::connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64))); - QObject::connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int))); - QObject::connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); - QObject::connect(m_session, SIGNAL(playbackRateChanged(qreal)), this, SIGNAL(playbackRateChanged(qreal))); - QObject::connect(m_session, SIGNAL(bufferStatusChanged(int)), this, SIGNAL(bufferStatusChanged(int))); -} - -MFPlayerControl::~MFPlayerControl() -{ -} - -void MFPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream) -{ - if (m_state != QMediaPlayer::StoppedState) { - changeState(QMediaPlayer::StoppedState); - m_session->stop(true); - refreshState(); - } - - m_media = media; - m_stream = stream; - resetAudioVideoAvailable(); - handleDurationUpdate(-1); - handleSeekableUpdate(false); - m_session->load(media, stream); - emit mediaChanged(m_media); -} - -void MFPlayerControl::play() -{ - if (m_state == QMediaPlayer::PlayingState) - return; - if (QMediaPlayer::InvalidMedia == m_session->status()) - m_session->load(m_media, m_stream); - - switch (m_session->status()) { - case QMediaPlayer::UnknownMediaStatus: - case QMediaPlayer::NoMedia: - case QMediaPlayer::InvalidMedia: - return; - case QMediaPlayer::LoadedMedia: - case QMediaPlayer::BufferingMedia: - case QMediaPlayer::BufferedMedia: - case QMediaPlayer::EndOfMedia: - changeState(QMediaPlayer::PlayingState); - m_session->start(); - break; - default: //Loading/Stalled - changeState(QMediaPlayer::PlayingState); - break; - } - refreshState(); -} - -void MFPlayerControl::pause() -{ - if (m_state != QMediaPlayer::PlayingState) - return; - changeState(QMediaPlayer::PausedState); - m_session->pause(); - refreshState(); -} - -void MFPlayerControl::stop() -{ - if (m_state == QMediaPlayer::StoppedState) - return; - changeState(QMediaPlayer::StoppedState); - m_session->stop(); - refreshState(); -} - -void MFPlayerControl::changeState(QMediaPlayer::State state) -{ - if (m_state == state) - return; - m_state = state; - m_stateDirty = true; -} - -void MFPlayerControl::refreshState() -{ - if (!m_stateDirty) - return; - m_stateDirty = false; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MFPlayerControl::emit stateChanged" << m_state; -#endif - emit stateChanged(m_state); -} - -void MFPlayerControl::handleStatusChanged() -{ - QMediaPlayer::MediaStatus status = m_session->status(); - switch (status) { - case QMediaPlayer::EndOfMedia: - changeState(QMediaPlayer::StoppedState); - break; - case QMediaPlayer::InvalidMedia: - break; - case QMediaPlayer::LoadedMedia: - case QMediaPlayer::BufferingMedia: - case QMediaPlayer::BufferedMedia: - if (m_state == QMediaPlayer::PlayingState) - m_session->start(); - break; - } - emit mediaStatusChanged(m_session->status()); - refreshState(); -} - -void MFPlayerControl::handleVideoAvailable() -{ - if (m_videoAvailable) - return; - m_videoAvailable = true; - emit videoAvailableChanged(m_videoAvailable); -} - -void MFPlayerControl::handleAudioAvailable() -{ - if (m_audioAvailable) - return; - m_audioAvailable = true; - emit audioAvailableChanged(m_audioAvailable); -} - -void MFPlayerControl::resetAudioVideoAvailable() -{ - bool videoDirty = false; - if (m_videoAvailable) { - m_videoAvailable = false; - videoDirty = true; - } - if (m_audioAvailable) { - m_audioAvailable = false; - emit audioAvailableChanged(m_audioAvailable); - } - if (videoDirty) - emit videoAvailableChanged(m_videoAvailable); -} - -void MFPlayerControl::handleDurationUpdate(qint64 duration) -{ - if (m_duration == duration) - return; - m_duration = duration; - emit durationChanged(m_duration); -} - -void MFPlayerControl::handleSeekableUpdate(bool seekable) -{ - if (m_seekable == seekable) - return; - m_seekable = seekable; - emit seekableChanged(m_seekable); -} - -QMediaPlayer::State MFPlayerControl::state() const -{ - return m_state; -} - -QMediaPlayer::MediaStatus MFPlayerControl::mediaStatus() const -{ - return m_session->status(); -} - -qint64 MFPlayerControl::duration() const -{ - return m_duration; -} - -qint64 MFPlayerControl::position() const -{ - return m_session->position(); -} - -void MFPlayerControl::setPosition(qint64 position) -{ - if (!m_seekable || position == m_session->position()) - return; - m_session->setPosition(position); -} - -int MFPlayerControl::volume() const -{ - return m_session->volume(); -} - -void MFPlayerControl::setVolume(int volume) -{ - m_session->setVolume(volume); -} - -bool MFPlayerControl::isMuted() const -{ - return m_session->isMuted(); -} - -void MFPlayerControl::setMuted(bool muted) -{ - m_session->setMuted(muted); -} - -int MFPlayerControl::bufferStatus() const -{ - return m_session->bufferStatus(); -} - -bool MFPlayerControl::isAudioAvailable() const -{ - return m_audioAvailable; -} - -bool MFPlayerControl::isVideoAvailable() const -{ - return m_videoAvailable; -} - -bool MFPlayerControl::isSeekable() const -{ - return m_seekable; -} - -QMediaTimeRange MFPlayerControl::availablePlaybackRanges() const -{ - return m_session->availablePlaybackRanges(); -} - -qreal MFPlayerControl::playbackRate() const -{ - return m_session->playbackRate(); -} - -void MFPlayerControl::setPlaybackRate(qreal rate) -{ - m_session->setPlaybackRate(rate); -} - -QMediaContent MFPlayerControl::media() const -{ - return m_media; -} - -const QIODevice* MFPlayerControl::mediaStream() const -{ - return m_stream; -} - -void MFPlayerControl::handleError(QMediaPlayer::Error errorCode, const QString& errorString, bool isFatal) -{ - if (isFatal) - stop(); - emit error(int(errorCode), errorString); -} diff --git a/src/plugins/wmf/player/mfplayercontrol.h b/src/plugins/wmf/player/mfplayercontrol.h deleted file mode 100644 index 0256b89..0000000 --- a/src/plugins/wmf/player/mfplayercontrol.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFPLAYERCONTROL_H -#define MFPLAYERCONTROL_H - -#include "qmediacontent.h" -#include "qmediaplayercontrol.h" - -#include <QtCore/qcoreevent.h> - -#include "mfplayersession.h" - -QT_USE_NAMESPACE - -class MFPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT -public: - MFPlayerControl(MFPlayerSession *session); - ~MFPlayerControl(); - - QMediaPlayer::State state() const; - - QMediaPlayer::MediaStatus mediaStatus() const; - - qint64 duration() const; - - qint64 position() const; - void setPosition(qint64 position); - - int volume() const; - void setVolume(int volume); - - bool isMuted() const; - void setMuted(bool muted); - - int bufferStatus() const; - - bool isAudioAvailable() const; - bool isVideoAvailable() const; - - bool isSeekable() const; - - QMediaTimeRange availablePlaybackRanges() const; - - qreal playbackRate() const; - void setPlaybackRate(qreal rate); - - QMediaContent media() const; - const QIODevice *mediaStream() const; - void setMedia(const QMediaContent &media, QIODevice *stream); - - void play(); - void pause(); - void stop(); - -private Q_SLOTS: - void handleStatusChanged(); - void handleVideoAvailable(); - void handleAudioAvailable(); - void handleDurationUpdate(qint64 duration); - void handleSeekableUpdate(bool seekable); - void handleError(QMediaPlayer::Error errorCode, const QString& errorString, bool isFatal); - -private: - void changeState(QMediaPlayer::State state); - void resetAudioVideoAvailable(); - void refreshState(); - - QMediaPlayer::State m_state; - bool m_stateDirty; - QMediaPlayer::MediaStatus m_status; - QMediaPlayer::Error m_error; - - bool m_videoAvailable; - bool m_audioAvailable; - qint64 m_duration; - bool m_seekable; - - QIODevice *m_stream; - QMediaContent m_media; - MFPlayerSession *m_session; -}; - -#endif diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp deleted file mode 100644 index bda86a3..0000000 --- a/src/plugins/wmf/player/mfplayerservice.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmediacontent.h" - -#include <QtCore/qdebug.h> - -#include "mfplayercontrol.h" -#ifndef Q_WS_SIMULATOR -#include "evr9videowindowcontrol.h" -#endif -#include "mfvideorenderercontrol.h" -#include "mfaudioendpointcontrol.h" -#include "mfplayerservice.h" -#include "mfplayersession.h" -#include "mfmetadatacontrol.h" - -MFPlayerService::MFPlayerService(QObject *parent) - : QMediaService(parent) - , m_session(0) -#ifndef Q_WS_SIMULATOR - , m_videoWindowControl(0) -#endif - , m_videoRendererControl(0) -{ - CoInitialize(NULL); - MFStartup(MF_VERSION); - m_session = new MFPlayerSession(this); - m_player = new MFPlayerControl(m_session); - m_audioEndpointControl = new MFAudioEndpointControl(this); - m_metaDataControl = new MFMetaDataControl(this); -} - -MFPlayerService::~MFPlayerService() -{ - -#ifndef Q_WS_SIMULATOR - if (m_videoWindowControl) - delete m_videoWindowControl; -#endif - - if (m_videoRendererControl) - delete m_videoRendererControl; - - delete m_session; - - MFShutdown(); - CoUninitialize(); -} - -QMediaControl* MFPlayerService::requestControl(const char *name) -{ - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { - return m_player; - } else if (qstrcmp(name, QAudioEndpointSelector_iid) == 0) { - return m_audioEndpointControl; - } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { - return m_metaDataControl; - } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { -#ifndef Q_WS_SIMULATOR - if (!m_videoRendererControl && !m_videoWindowControl) { -#else - if (!m_videoRendererControl) { -#endif - m_videoRendererControl = new MFVideoRendererControl; - return m_videoRendererControl; - } -#ifndef Q_WS_SIMULATOR - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoWindowControl = new Evr9VideoWindowControl; - return m_videoWindowControl; - } -#endif - } - - return 0; -} - -void MFPlayerService::releaseControl(QMediaControl *control) -{ - if (!control) { - qWarning("QMediaService::releaseControl():" - " Attempted release of null control"); - } else if (control == m_videoRendererControl) { - m_videoRendererControl->setSurface(0); - delete m_videoRendererControl; - m_videoRendererControl = 0; -#ifndef Q_WS_SIMULATOR - } else if (control == m_videoWindowControl) { - delete m_videoWindowControl; - m_videoWindowControl = 0; -#endif - } -} - -MFAudioEndpointControl* MFPlayerService::audioEndpointControl() const -{ - return m_audioEndpointControl; -} - -MFVideoRendererControl* MFPlayerService::videoRendererControl() const -{ - return m_videoRendererControl; -} - -#ifndef Q_WS_SIMULATOR -Evr9VideoWindowControl* MFPlayerService::videoWindowControl() const -{ - return m_videoWindowControl; -} -#endif - -MFMetaDataControl* MFPlayerService::metaDataControl() const -{ - return m_metaDataControl; -} diff --git a/src/plugins/wmf/player/mfplayerservice.h b/src/plugins/wmf/player/mfplayerservice.h deleted file mode 100644 index 1e8a617..0000000 --- a/src/plugins/wmf/player/mfplayerservice.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFPLAYERSERVICE_H -#define MFPLAYERSERVICE_H - -#include <mfapi.h> -#include <mfidl.h> - -#include "qmediaplayer.h" -#include "qmediaresource.h" -#include "qmediaservice.h" -#include "qmediatimerange.h" - -QT_BEGIN_NAMESPACE -class QMediaContent; -QT_END_NAMESPACE - -QT_USE_NAMESPACE - -#ifndef Q_WS_SIMULATOR -class Evr9VideoWindowControl; -#endif -class MFAudioEndpointControl; -class MFVideoRendererControl; -class MFPlayerControl; -class MFMetaDataControl; -class MFPlayerSession; - -class MFPlayerService : public QMediaService -{ - Q_OBJECT -public: - MFPlayerService(QObject *parent = 0); - ~MFPlayerService(); - - QMediaControl* requestControl(const char *name); - void releaseControl(QMediaControl *control); - - MFAudioEndpointControl* audioEndpointControl() const; - MFVideoRendererControl* videoRendererControl() const; -#ifndef Q_WS_SIMULATOR - Evr9VideoWindowControl* videoWindowControl() const; -#endif - MFMetaDataControl* metaDataControl() const; - -private: - MFPlayerSession *m_session; - MFVideoRendererControl *m_videoRendererControl; - MFAudioEndpointControl *m_audioEndpointControl; -#ifndef Q_WS_SIMULATOR - Evr9VideoWindowControl *m_videoWindowControl; -#endif - MFPlayerControl *m_player; - MFMetaDataControl *m_metaDataControl; -}; - -#endif diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp deleted file mode 100644 index afe91da..0000000 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ /dev/null @@ -1,1393 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmediacontent.h" -#include "qmediaplayercontrol.h" - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qthread.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> -#include <QtCore/qbuffer.h> - -#include "mfplayercontrol.h" -#ifndef Q_WS_SIMULATOR -#include "evr9videowindowcontrol.h" -#endif -#include "mfvideorenderercontrol.h" -#include "mfaudioendpointcontrol.h" - -#include "mfplayersession.h" -#include "mfplayerservice.h" -#include "mfmetadatacontrol.h" -#include <Mferror.h> -#include <nserror.h> -#include <sourceresolver.h> - -//#define DEBUG_MEDIAFOUNDATION -//#define TEST_STREAMING - -namespace -{ - //MFStream is added for supporting QIODevice type of media source. - //It is used to delegate invocations from media foundation(through IMFByteStream) to QIODevice. - class MFStream : public QObject, public IMFByteStream - { - Q_OBJECT - public: - MFStream(QIODevice *stream, bool ownStream) - : m_cRef(1) - , m_stream(stream) - , m_ownStream(ownStream) - , m_currentReadResult(0) - { - //Move to the thread of the stream object - //to make sure invocations on stream - //are happened in the same thread of stream object - this->moveToThread(stream->thread()); - connect(stream, SIGNAL(readyRead()), this, SLOT(handleReadyRead())); - } - - ~MFStream() - { - if (m_currentReadResult) - m_currentReadResult->Release(); - if (m_ownStream) - m_stream->deleteLater(); - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFByteStream) { - *ppvObject = static_cast<IMFByteStream*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - this->deleteLater(); - } - return cRef; - } - - - //from IMFByteStream - STDMETHODIMP GetCapabilities(DWORD *pdwCapabilities) - { - if (!pdwCapabilities) - return E_INVALIDARG; - *pdwCapabilities = MFBYTESTREAM_IS_READABLE; - if (!m_stream->isSequential()) - *pdwCapabilities |= MFBYTESTREAM_IS_SEEKABLE; - return S_OK; - } - - STDMETHODIMP GetLength(QWORD *pqwLength) - { - if (!pqwLength) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pqwLength = QWORD(m_stream->size()); - return S_OK; - } - - STDMETHODIMP SetLength(QWORD) - { - return E_NOTIMPL; - } - - STDMETHODIMP GetCurrentPosition(QWORD *pqwPosition) - { - if (!pqwPosition) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pqwPosition = m_stream->pos(); - return S_OK; - } - - STDMETHODIMP SetCurrentPosition(QWORD qwPosition) - { - QMutexLocker locker(&m_mutex); - //SetCurrentPosition may happend during the BeginRead/EndRead pair, - //refusing to execute SetCurrentPosition during that time seems to be - //the simplest workable solution - if (m_currentReadResult) - return S_FALSE; - - bool seekOK = m_stream->seek(qint64(qwPosition)); - if (seekOK) - return S_OK; - else - return S_FALSE; - } - - STDMETHODIMP IsEndOfStream(BOOL *pfEndOfStream) - { - if (!pfEndOfStream) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pfEndOfStream = m_stream->atEnd() ? TRUE : FALSE; - return S_OK; - } - - STDMETHODIMP Read(BYTE *pb, ULONG cb, ULONG *pcbRead) - { - QMutexLocker locker(&m_mutex); - qint64 read = m_stream->read((char*)(pb), qint64(cb)); - if (pcbRead) - *pcbRead = ULONG(read); - return S_OK; - } - - STDMETHODIMP BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, - IUnknown *punkState) - { - if (!pCallback || !pb) - return E_INVALIDARG; - - Q_ASSERT(m_currentReadResult == NULL); - - AsyncReadState *state = new (std::nothrow) AsyncReadState(pb, cb); - if (state == NULL) - return E_OUTOFMEMORY; - - HRESULT hr = MFCreateAsyncResult(state, pCallback, punkState, &m_currentReadResult); - state->Release(); - if (FAILED(hr)) - return hr; - - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - return hr; - } - - STDMETHODIMP EndRead(IMFAsyncResult* pResult, ULONG *pcbRead) - { - if (!pcbRead) - return E_INVALIDARG; - IUnknown *pUnk; - pResult->GetObject(&pUnk); - AsyncReadState *state = static_cast<AsyncReadState*>(pUnk); - *pcbRead = state->bytesRead(); - pUnk->Release(); - - m_currentReadResult->Release(); - m_currentReadResult = NULL; - - return S_OK; - } - - STDMETHODIMP Write(const BYTE *, ULONG, ULONG *) - { - return E_NOTIMPL; - } - - STDMETHODIMP BeginWrite(const BYTE *, ULONG , - IMFAsyncCallback *, - IUnknown *) - { - return E_NOTIMPL; - } - - STDMETHODIMP EndWrite(IMFAsyncResult *, - ULONG *) - { - return E_NOTIMPL; - } - - STDMETHODIMP Seek( - MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, - LONGLONG llSeekOffset, - DWORD, - QWORD *pqwCurrentPosition) - { - QMutexLocker locker(&m_mutex); - if (m_currentReadResult) - return S_FALSE; - - qint64 pos = qint64(llSeekOffset); - switch (SeekOrigin) { - case msoCurrent: - pos += m_stream->pos(); - break; - } - bool seekOK = m_stream->seek(pos); - if (*pqwCurrentPosition) - *pqwCurrentPosition = pos; - if (seekOK) - return S_OK; - else - return S_FALSE; - } - - STDMETHODIMP Flush() - { - return E_NOTIMPL; - } - - STDMETHODIMP Close() - { - QMutexLocker locker(&m_mutex); - if (m_ownStream) - m_stream->close(); - return S_OK; - } - - private: - //AsyncReadState is a helper class used in BeginRead for asynchronous operation - //to record some BeginRead parameters, so these parameters could be - //used later when actually executing the read operation in another thread. - class AsyncReadState : public IUnknown - { - public: - AsyncReadState(BYTE *pb, ULONG cb) - : m_cRef(1) - , m_pb(pb) - , m_cb(cb) - , m_cbRead(0) - { - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject) - { - if (!ppvObject) - return E_POINTER; - - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - BYTE* pb() const { return m_pb; } - ULONG cb() const { return m_cb; } - ULONG bytesRead() const { return m_cbRead; } - - void setBytesRead(ULONG cbRead) { m_cbRead = cbRead; } - - private: - long m_cRef; - BYTE *m_pb; - ULONG m_cb; - ULONG m_cbRead; - }; - - long m_cRef; - QIODevice *m_stream; - bool m_ownStream; - DWORD m_workQueueId; - QMutex m_mutex; - - void doRead() - { - bool readDone = true; - IUnknown *pUnk = NULL; - HRESULT hr = m_currentReadResult->GetObject(&pUnk); - if (SUCCEEDED(hr)) { - //do actual read - AsyncReadState *state = static_cast<AsyncReadState*>(pUnk); - ULONG cbRead; - Read(state->pb(), state->cb() - state->bytesRead(), &cbRead); - pUnk->Release(); - - state->setBytesRead(cbRead + state->bytesRead()); - if (state->cb() > state->bytesRead() && !m_stream->atEnd()) { - readDone = false; - } - } - - if (readDone) { - //now inform the original caller - m_currentReadResult->SetStatus(hr); - MFInvokeCallback(m_currentReadResult); - } - } - - - private Q_SLOTS: - void handleReadyRead() - { - doRead(); - } - - protected: - void customEvent(QEvent *event) - { - if (event->type() != QEvent::User) { - QObject::customEvent(event); - return; - } - doRead(); - } - IMFAsyncResult *m_currentReadResult; - }; -} - - -MFPlayerSession::MFPlayerSession(QObject *parent) - : QObject(parent) - , m_session(0) - , m_presentationClock(0) - , m_rateControl(0) - , m_rateSupport(0) - , m_volumeControl(0) - , m_netsourceStatistics(0) - , m_hCloseEvent(0) - , m_pendingRate(1) - , m_volume(1) - , m_muted(false) - , m_status(QMediaPlayer::NoMedia) - , m_scrubbing(false) - , m_restoreRate(1) - , m_mediaTypes(0) -{ - m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - m_sourceResolver = new SourceResolver(this); - QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady())); - QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long))); - QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent *)), this, SLOT(handleSessionEvent(IMFMediaEvent *))); - - m_pendingState = NoPending; - ZeroMemory(&m_state, sizeof(m_state)); - m_state.command = CmdStop; - m_state.prevCmd = CmdNone; - m_state.rate = 1.0f; - ZeroMemory(&m_request, sizeof(m_request)); - m_request.command = CmdNone; - m_request.prevCmd = CmdNone; - m_request.rate = 1.0f; - - createSession(); - PropVariantInit(&m_varStart); - m_varStart.vt = VT_I8; - m_varStart.uhVal.QuadPart = 0; -} - -MFPlayerSession::~MFPlayerSession() -{ - m_sourceResolver->Release(); - clear(); - HRESULT hr = S_OK; - if (m_session) { - hr = m_session->Close(); - if (SUCCEEDED(hr)) { - DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 5000); - if (dwWaitResult == WAIT_TIMEOUT) { - qWarning() << "session close time out!"; - } - } - } - - if (SUCCEEDED(hr)) { - m_sourceResolver->shutdown(); - if (m_session) - m_session->Shutdown(); - } - - if (m_session) - m_session->Release(); - - CloseHandle(m_hCloseEvent); -} - - -void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "load"; -#endif - clear(); - QMediaResourceList resources = media.resources(); - - if (m_status == QMediaPlayer::LoadingMedia) - m_sourceResolver->cancel(); - - if (resources.isEmpty() && !stream) { - changeStatus(QMediaPlayer::NoMedia); - } else if (stream && (!stream->isReadable())) { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::ResourceError, tr("Invalid stream source!"), true); - } else { - changeStatus(QMediaPlayer::LoadingMedia); - m_sourceResolver->load(resources, stream); - } - emit positionChanged(position()); -} - -void MFPlayerSession::handleSourceError(long hr) -{ - QString errorString; - QMediaPlayer::Error errorCode = QMediaPlayer::ResourceError; - switch (hr) { - case QMediaPlayer::FormatError: - errorCode = QMediaPlayer::FormatError; - errorString = tr("Attempting to play invalid Qt resource"); - break; - case NS_E_FILE_NOT_FOUND: - errorString = tr("The system cannot find the file specified."); - break; - case NS_E_SERVER_NOT_FOUND: - errorString = tr("The specified server could not be found."); - break; - default: - errorString = tr("Failed to load source."); - break; - } - changeStatus(QMediaPlayer::InvalidMedia); - emit error(errorCode, errorString, true); -} - -void MFPlayerSession::handleMediaSourceReady() -{ - if (QMediaPlayer::LoadingMedia != m_status) - return; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "handleMediaSourceReady"; -#endif - HRESULT hr = S_OK; - IMFPresentationDescriptor* sourcePD; - IMFMediaSource* mediaSource = m_sourceResolver->mediaSource(); - hr = mediaSource->CreatePresentationDescriptor(&sourcePD); - if (SUCCEEDED(hr)) { - m_duration = 0; - static_cast<MFPlayerService*>(this->parent())->metaDataControl()->updateSource(sourcePD, mediaSource); - sourcePD->GetUINT64(MF_PD_DURATION, &m_duration); - //convert from 100 nanosecond to milisecond - emit durationUpdate(qint64(m_duration / 10000)); - setupPlaybackTopology(mediaSource, sourcePD); - } else { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::ResourceError, tr("Can't create presentation descriptor!"), true); - } -} - -void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD) -{ - HRESULT hr = S_OK; - // Get the number of streams in the media source. - DWORD cSourceStreams = 0; - hr = sourcePD->GetStreamDescriptorCount(&cSourceStreams); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Failed to get stream count"), true); - return; - } - - IMFTopology *topology; - hr = MFCreateTopology(&topology); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Failed to create topology!"), true); - return; - } - - // For each stream, create the topology nodes and add them to the topology. - DWORD succeededCount = 0; - for (DWORD i = 0; i < cSourceStreams; i++) - { - BOOL fSelected = FALSE; - IMFStreamDescriptor *streamDesc = NULL; - - HRESULT hr = sourcePD->GetStreamDescriptorByIndex(i, &fSelected, &streamDesc); - if (SUCCEEDED(hr)) { - MediaType mediaType = Unknown; - IMFTopologyNode *sourceNode = addSourceNode(topology, source, sourcePD, streamDesc); - if (sourceNode) { - IMFTopologyNode *outputNode = addOutputNode(streamDesc, mediaType, topology, 0); - if (outputNode) { - hr = sourceNode->ConnectOutput(0, outputNode, 0); - if (FAILED(hr)) { - emit error(QMediaPlayer::FormatError, tr("Unable to play some stream"), false); - } - else { - succeededCount++; - m_mediaTypes |= mediaType; - switch (mediaType) { - case Audio: - emit audioAvailable(); - break; - case Video: - emit videoAvailable(); - break; - } - } - } - sourceNode->Release(); - } - streamDesc->Release(); - } - } - - if (succeededCount == 0) { - changeStatus(QMediaPlayer::InvalidMedia); - emit error(QMediaPlayer::ResourceError, tr("Unable to play"), true); - } else { - hr = m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Failed to set topology!"), true); - } - } - topology->Release(); -} - -IMFTopologyNode* MFPlayerSession::addSourceNode(IMFTopology* topology, IMFMediaSource* source, - IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc) -{ - IMFTopologyNode *node = NULL; - HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node); - if (SUCCEEDED(hr)) { - hr = node->SetUnknown(MF_TOPONODE_SOURCE, source); - if (SUCCEEDED(hr)) { - hr = node->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, presentationDesc); - if (SUCCEEDED(hr)) { - hr = node->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, streamDesc); - if (SUCCEEDED(hr)) { - hr = topology->AddNode(node); - if (SUCCEEDED(hr)) - return node; - } - } - } - node->Release(); - } - return NULL; -} - -IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc, MediaType& mediaType, IMFTopology* topology, DWORD sinkID) -{ - IMFTopologyNode *node = NULL; - HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node); - if (FAILED(hr)) - return NULL; - node->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); - - mediaType = Unknown; - IMFMediaTypeHandler *handler = NULL; - hr = streamDesc->GetMediaTypeHandler(&handler); - if (SUCCEEDED(hr)) { - GUID guidMajorType; - hr = handler->GetMajorType(&guidMajorType); - if (SUCCEEDED(hr)) { - IMFActivate *activate = NULL; - MFPlayerService *service = static_cast<MFPlayerService*>(this->parent()); - if (MFMediaType_Audio == guidMajorType) { - mediaType = Audio; - activate = service->audioEndpointControl()->currentActivate(); - } else if (MFMediaType_Video == guidMajorType) { - mediaType = Video; - if (service->videoRendererControl()) { - activate = service->videoRendererControl()->currentActivate(); -#ifndef Q_WS_SIMULATOR - } else if (service->videoWindowControl()) { - activate = service->videoWindowControl()->currentActivate(); -#endif - } else { - qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data"; - } - } else { - // Unknown stream type. - emit error(QMediaPlayer::FormatError, tr("Unknown stream type"), false); - } - - if (activate) { - hr = node->SetObject(activate); - if (SUCCEEDED(hr)) { - hr = node->SetUINT32(MF_TOPONODE_STREAMID, sinkID); - if (SUCCEEDED(hr)) { - if (SUCCEEDED(topology->AddNode(node))) - return node; - } - } - } - } - } - node->Release(); - return NULL; -} - -void MFPlayerSession::stop(bool immediate) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "stop"; -#endif - if (!immediate && m_pendingState != NoPending) { - m_request.setCommand(CmdStop); - } else { - if (m_state.command == CmdStop) - return; - - if (m_scrubbing) - scrub(false); - - if (SUCCEEDED(m_session->Stop())) { - m_state.setCommand(CmdStop); - m_pendingState = CmdPending; - if (m_status != QMediaPlayer::EndOfMedia) { - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = 0; - } - } else { - emit error(QMediaPlayer::ResourceError, tr("failed to stop"), true); - } - } -} - -void MFPlayerSession::start() -{ - switch (m_status) { - case QMediaPlayer::EndOfMedia: - m_varStart.hVal.QuadPart = 0; - //since it must be loaded already, just fallthrough - case QMediaPlayer::LoadedMedia: - changeStatus(QMediaPlayer::BufferedMedia); - return; - } - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "start"; -#endif - - if (m_pendingState != NoPending) { - m_request.setCommand(CmdStart); - } else { - if (m_state.command == CmdStart) - return; - - if (m_scrubbing) - scrub(false); - - if (SUCCEEDED(m_session->Start(&GUID_NULL, &m_varStart))) { - m_state.setCommand(CmdStart); - m_pendingState = CmdPending; - PropVariantInit(&m_varStart); - } else { - emit error(QMediaPlayer::ResourceError, tr("failed to start playback"), true); - } - } -} - -void MFPlayerSession::pause() -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "pause"; -#endif - if (m_pendingState != NoPending) { - m_request.setCommand(CmdPause); - } else { - if (m_state.command == CmdPause) - return; - if (SUCCEEDED(m_session->Pause())) { - m_state.setCommand(CmdPause); - m_pendingState = CmdPending; - } else { - emit error(QMediaPlayer::ResourceError, tr("failed to pause"), false); - } - } -} - -void MFPlayerSession::changeStatus(QMediaPlayer::MediaStatus newStatus) -{ - if (m_status == newStatus) - return; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MFPlayerSession::changeStatus" << newStatus; -#endif - m_status = newStatus; - emit statusChanged(); -} - -QMediaPlayer::MediaStatus MFPlayerSession::status() const -{ - return m_status; -} - -void MFPlayerSession::createSession() -{ - Q_ASSERT(m_session == NULL); - HRESULT hr = MFCreateMediaSession(NULL, &m_session); - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Unable to create mediasession"), true); - } - - hr = m_session->BeginGetEvent(this, m_session); - - if (FAILED(hr)) { - changeStatus(QMediaPlayer::UnknownMediaStatus); - emit error(QMediaPlayer::ResourceError, tr("Unable to pulling session events"), false); - } -} - -qint64 MFPlayerSession::position() -{ - if (m_request.command == CmdSeek || m_request.command == CmdSeekResume) - return m_request.start; - - if (m_pendingState == SeekPending) - return m_state.start; - - if (m_state.command == CmdStop) - return qint64(m_varStart.hVal.QuadPart / 10000); - - if (m_presentationClock) { - MFTIME time, sysTime; - if (FAILED(m_presentationClock->GetCorrelatedTime(0, &time, &sysTime))) - return 0; - return qint64(time / 10000); - } - return 0; -} - -void MFPlayerSession::setPosition(qint64 position) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "setPosition"; -#endif - if (m_pendingState != NoPending) { - m_request.setCommand(CmdSeek); - m_request.start = position; - } else { - setPositionInternal(position, CmdNone); - } -} - -void MFPlayerSession::setPositionInternal(qint64 position, Command requestCmd) -{ - if (m_status == QMediaPlayer::EndOfMedia) - changeStatus(QMediaPlayer::LoadedMedia); - if (m_state.command == CmdStop && requestCmd != CmdSeekResume) { - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = LONGLONG(position * 10000); - return; - } - - if (m_state.command == CmdPause) - scrub(true); - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "setPositionInternal"; -#endif - - PROPVARIANT varStart; - varStart.vt = VT_I8; - varStart.hVal.QuadPart = LONGLONG(position * 10000); - if (SUCCEEDED(m_session->Start(NULL, &varStart))) - { - PropVariantInit(&m_varStart); - // Store the pending state. - m_state.setCommand(CmdStart); - m_state.start = position; - m_pendingState = SeekPending; - } else { - emit error(QMediaPlayer::ResourceError, tr("failed to seek"), true); - } -} - -qreal MFPlayerSession::playbackRate() const -{ - if (m_pendingState != NoPending) - return m_request.rate; - return m_state.rate; -} - -void MFPlayerSession::setPlaybackRate(qreal rate) -{ - if (m_scrubbing) { - m_restoreRate = rate; - return; - } - setPlaybackRateInternal(rate); -} - -void MFPlayerSession::setPlaybackRateInternal(qreal rate) -{ - if (rate == m_request.rate) - return; - - m_pendingRate = rate; - if (!m_rateSupport) - return; - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "setPlaybackRate"; -#endif - BOOL isThin = FALSE; - - //from MSDN http://msdn.microsoft.com/en-us/library/aa965220%28v=vs.85%29.aspx - //Thinning applies primarily to video streams. - //In thinned mode, the source drops delta frames and deliver only key frames. - //At very high playback rates, the source might skip some key frames (for example, deliver every other key frame). - - if (FAILED(m_rateSupport->IsRateSupported(FALSE, rate, NULL))) { - isThin = TRUE; - if (FAILED(m_rateSupport->IsRateSupported(isThin, rate, NULL))) { - qWarning() << "unable to set playbackrate = " << rate; - } - } - if (m_pendingState != NoPending) { - m_request.rate = rate; - m_request.isThin = isThin; - // Remember the current transport state (play, paused, etc), so that we - // can restore it after the rate change, if necessary. However, if - // anothercommand is already pending, that one takes precedent. - if (m_request.command == CmdNone) - m_request.setCommand(m_state.command); - } else { - //No pending operation. Commit the new rate. - commitRateChange(rate, isThin); - } -} - -void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin) -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "commitRateChange"; -#endif - Q_ASSERT(m_pendingState == NoPending); - MFTIME hnsSystemTime = 0; - MFTIME hnsClockTime = 0; - Command cmdNow = m_state.command; - // Allowed rate transitions: - // Positive <-> negative: Stopped - // Negative <-> zero: Stopped - // Postive <-> zero: Paused or stopped - if ((rate > 0 && m_state.rate <= 0) || (rate < 0 && m_state.rate >= 0)) { - // Transition to stopped. - if (cmdNow == CmdStart) { - // Get the current clock position. This will be the restart time. - m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime); - Q_ASSERT(hnsSystemTime != 0); - - // Stop and set the rate - stop(); - - //Cache Request: Restart from stop. - m_request.setCommand(CmdSeekResume); - m_request.start = hnsClockTime / 10000; - } else if (cmdNow == CmdPause) { - // The current state is paused. - // For this rate change, the session must be stopped. However, the - // session cannot transition back from stopped to paused. - // Therefore, this rate transition is not supported while paused. - if (rate < 0 || m_state.rate < 0) { - qWarning() << "Unable to change rate from positive to negative or vice versa in paused state"; - return; - } - } - } else if (rate == 0 && m_state.rate != 0) { - if (cmdNow != CmdPause) { - // Transition to paused. - // This transisition requires the paused state. - // Pause and set the rate. - pause(); - - // Request: Switch back to current state. - m_request.setCommand(cmdNow); - } - } - - // Set the rate. - if (FAILED(m_rateControl->SetRate(isThin, rate))) { - qWarning() << "failed to set playbackrate = " << rate; - return; - } - - // Adjust our current rate and requested rate. - m_pendingRate = m_request.rate = m_state.rate = rate; - -} - -void MFPlayerSession::scrub(bool enableScrub) -{ - if (m_scrubbing == enableScrub) - return; - - m_scrubbing = enableScrub; - - if (!canScrub()) { - if (!enableScrub) - m_pendingRate = m_restoreRate; - return; - } - - if (enableScrub) { - // Enter scrubbing mode. Cache the rate. - m_restoreRate = m_request.rate; - setPlaybackRateInternal(0.0f); - } else { - // Leaving scrubbing mode. Restore the old rate. - setPlaybackRateInternal(m_restoreRate); - } -} - -int MFPlayerSession::volume() const -{ - return m_volume; -} - -void MFPlayerSession::setVolume(int volume) -{ - if (m_volume == volume) - return; - m_volume = volume; - if (m_volumeControl) - m_volumeControl->SetMasterVolume(m_volume * 0.01f); - emit volumeChanged(m_volume); -} - -bool MFPlayerSession::isMuted() const -{ - return m_muted; -} - -void MFPlayerSession::setMuted(bool muted) -{ - if (m_muted == muted) - return; - m_muted = muted; - if (m_volumeControl) - m_volumeControl->SetMute(BOOL(m_muted)); - emit mutedChanged(m_muted); -} - -int MFPlayerSession::bufferStatus() -{ - if (!m_netsourceStatistics) - return 0; - PROPVARIANT var; - PROPERTYKEY key; - key.fmtid = MFNETSOURCE_STATISTICS; - key.pid = MFNETSOURCE_BUFFERPROGRESS_ID; - int progress = -1; - if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) { - progress = var.lVal; - } - PropVariantClear(&var); - -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "bufferStatus: progress = " << progress; -#endif - - return progress; -} - -QMediaTimeRange MFPlayerSession::availablePlaybackRanges() -{ - if (!m_netsourceStatistics) - return QMediaTimeRange(); - - qint64 start = 0, end = 0; - PROPVARIANT var; - PROPERTYKEY key; - key.fmtid = MFNETSOURCE_STATISTICS; - key.pid = MFNETSOURCE_SEEKRANGESTART_ID; - if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) { - start = qint64(var.uhVal.QuadPart / 10000); - key.pid = MFNETSOURCE_SEEKRANGEEND_ID; - if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) { - end = qint64(var.uhVal.QuadPart / 10000); - } - } - PropVariantClear(&var); - return QMediaTimeRange(start, end); -} - -HRESULT MFPlayerSession::QueryInterface(REFIID riid, void** ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFAsyncCallback) { - *ppvObject = static_cast<IMFAsyncCallback*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - return S_OK; -} - -ULONG MFPlayerSession::AddRef(void) -{ - return 1; -} - -ULONG MFPlayerSession::Release(void) -{ - return 1; -} - -HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult) -{ - if (pResult->GetStateNoAddRef() != m_session) - return S_OK; - - IMFMediaEvent *pEvent = NULL; - // Get the event from the event queue. - HRESULT hr = m_session->EndGetEvent(pResult, &pEvent); - if (FAILED(hr)) { - return S_OK; - } - - MediaEventType meType = MEUnknown; - hr = pEvent->GetType(&meType); - if (FAILED(hr)) { - pEvent->Release(); - return S_OK; - } - - if (meType == MESessionClosed) { - SetEvent(m_hCloseEvent); - return S_OK; - } else { - hr = m_session->BeginGetEvent(this, m_session); - if (FAILED(hr)) { - pEvent->Release(); - return S_OK; - } - } - - emit sessionEvent(pEvent); - return S_OK; -} - -void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) -{ - HRESULT hrStatus = S_OK; - HRESULT hr = sessionEvent->GetStatus(&hrStatus); - if (FAILED(hr)) { - sessionEvent->Release(); - return; - } - - MediaEventType meType = MEUnknown; - hr = sessionEvent->GetType(&meType); - -#ifdef DEBUG_MEDIAFOUNDATION - if (FAILED(hrStatus)) - qDebug() << "handleSessionEvent: MediaEventType = " << meType << "Failed"; - else - qDebug() << "handleSessionEvent: MediaEventType = " << meType; -#endif - - switch (meType) { - case MENonFatalError: { - PROPVARIANT var; - PropVariantInit(&var); - sessionEvent->GetValue(&var); - qWarning() << "handleSessionEvent: non fatal error = " << var.ulVal; - PropVariantClear(&var); - emit error(QMediaPlayer::ResourceError, tr("media session non-fatal error!"), false); - } - break; - case MESourceUnknown: - changeStatus(QMediaPlayer::InvalidMedia); - case MEError: - qWarning() << "handleSessionEvent: serious error = " << hrStatus; - emit error(QMediaPlayer::ResourceError, tr("media session serious error!"), true); - break; - case MESessionRateChanged: - // If the rate change succeeded, we've already got the rate - // cached. If it failed, try to get the actual rate. - if (FAILED(hrStatus)) { - PROPVARIANT var; - PropVariantInit(&var); - if (SUCCEEDED(sessionEvent->GetValue(&var)) && (var.vt == VT_R4)) { - m_state.rate = var.fltVal; - } - emit playbackRateChanged(playbackRate()); - } - break; - case MESessionScrubSampleComplete : - if (m_scrubbing) - updatePendingCommands(CmdStart); - break; - case MESessionStarted: - if (!m_scrubbing) - updatePendingCommands(CmdStart); - break; - case MESessionStopped: - if (m_status != QMediaPlayer::EndOfMedia) { - m_varStart.vt = VT_I8; - m_varStart.hVal.QuadPart = 0; - - //only change to loadedMedia when not loading a new media source - if (m_status != QMediaPlayer::LoadingMedia) { - changeStatus(QMediaPlayer::LoadedMedia); - } - } - updatePendingCommands(CmdStop); - break; - case MESessionPaused: - updatePendingCommands(CmdPause); - break; - case MEReconnectStart: -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MEReconnectStart" << ((hrStatus == S_OK) ? "OK" : "Failed"); -#endif - break; - case MEReconnectEnd: -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MEReconnectEnd" << ((hrStatus == S_OK) ? "OK" : "Failed"); -#endif - break; - } - - if (FAILED(hrStatus)) { - sessionEvent->Release(); - return; - } - - switch (meType) { - case MEBufferingStarted: - changeStatus(QMediaPlayer::StalledMedia); - emit bufferStatusChanged(bufferStatus()); - break; - case MEBufferingStopped: - changeStatus(QMediaPlayer::BufferedMedia); - emit bufferStatusChanged(bufferStatus()); - break; - case MEEndOfPresentation: - stop(); - changeStatus(QMediaPlayer::EndOfMedia); - m_varStart.vt = VT_I8; - //keep reporting the final position after end of media - m_varStart.hVal.QuadPart = m_duration; - break; - case MESessionEnded: - m_pendingState = NoPending; - m_state.command = CmdStop; - m_state.prevCmd = CmdNone; - m_request.command = CmdNone; - m_request.prevCmd = CmdNone; - break; - case MEEndOfPresentationSegment: - break; - case MEAudioSessionVolumeChanged: - if (m_volumeControl) { - float currentVolume = 1; - if (SUCCEEDED(m_volumeControl->GetMasterVolume(¤tVolume))) { - if (currentVolume != m_volume) { - m_volume = currentVolume; - emit volumeChanged(int(m_volume * 100)); - } - } - BOOL currentMuted = FALSE; - if (SUCCEEDED(m_volumeControl->GetMute(¤tMuted))) { - if (currentMuted != BOOL(m_muted)) { - m_muted = bool(currentMuted); - emit mutedChanged(m_muted); - } - } - } - break; - case MESessionTopologySet: { - if (SUCCEEDED(MFGetService(m_session, MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl)))) { - m_volumeControl->SetMasterVolume(m_volume); - m_volumeControl->SetMute(m_muted); - } - DWORD dwCharacteristics = 0; - m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics); - emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics); - changeStatus(QMediaPlayer::LoadedMedia); - } - break; - case MESessionTopologyStatus: { - UINT32 status; - if (SUCCEEDED(sessionEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &status))) { - if (status == MF_TOPOSTATUS_READY) { - IMFClock* clock; - if (SUCCEEDED(m_session->GetClock(&clock))) { - clock->QueryInterface(IID_IMFPresentationClock, (void**)(&m_presentationClock)); - clock->Release(); - } - - if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateControl)))) { - if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateSupport)))) { - if ((m_mediaTypes & Video) == Video - && SUCCEEDED(m_rateSupport->IsRateSupported(TRUE, 0, NULL))) - m_canScrub = true; - } - BOOL isThin = FALSE; - float rate = 1; - if (SUCCEEDED(m_rateControl->GetRate(&isThin, &rate))) { - if (m_pendingRate != rate) { - m_state.rate = m_request.rate = rate; - setPlaybackRate(m_pendingRate); - } - } - } - MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics)); - } - } - } - break; - } - - sessionEvent->Release(); -} - -void MFPlayerSession::updatePendingCommands(Command command) -{ - emit positionChanged(position()); - if (m_state.command != command || m_pendingState == NoPending) - return; - - // The current pending command has completed. - if (m_pendingState == SeekPending && m_state.prevCmd == CmdPause) { - m_pendingState = NoPending; - //if we have pending seek request, - //then we just keep current state to paused and continue the seek request, - //otherwise we will restore to pause state - if (m_request.command == CmdSeek) { - m_state.setCommand(CmdPause); - } else { - pause(); - return; - } - } - - m_pendingState = NoPending; - - //First look for rate changes. - if (m_request.rate != m_state.rate) { - commitRateChange(m_request.rate, m_request.isThin); - } - - // Now look for new requests. - if (m_pendingState == NoPending) { - switch (m_request.command) { - case CmdStart: - start(); - break; - case CmdPause: - pause(); - break; - case CmdStop: - stop(); - break; - case CmdSeek: - case CmdSeekResume: - setPositionInternal(m_request.start, m_request.command); - } - m_request.setCommand(CmdNone); - } - -} - -bool MFPlayerSession::canScrub() const -{ - return m_canScrub && m_rateSupport && m_rateControl; -} - -void MFPlayerSession::clear() -{ -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MFPlayerSession::clear"; -#endif - m_mediaTypes = 0; - m_canScrub = false; - - m_pendingState = NoPending; - m_state.command = CmdStop; - m_state.prevCmd = CmdNone; - m_request.command = CmdNone; - m_request.prevCmd = CmdNone; - - if (m_presentationClock) { - m_presentationClock->Release(); - m_presentationClock = NULL; - } - if (m_rateControl) { - m_rateControl->Release(); - m_rateControl = NULL; - } - if (m_rateSupport) { - m_rateSupport->Release(); - m_rateSupport = NULL; - } - if (m_volumeControl) { - m_volumeControl->Release(); - m_volumeControl = NULL; - } - if (m_netsourceStatistics) { - m_netsourceStatistics->Release(); - m_netsourceStatistics = NULL; - } -} diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h deleted file mode 100644 index 169a404..0000000 --- a/src/plugins/wmf/player/mfplayersession.h +++ /dev/null @@ -1,212 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFPLAYERSESSION_H -#define MFPLAYERSESSION_H - -#include <mfapi.h> -#include <mfidl.h> - -#include "qmediaplayer.h" -#include "qmediaresource.h" -#include "qmediaservice.h" -#include "qmediatimerange.h" - -#include <QtCore/qcoreevent.h> -#include <QtCore/qmutex.h> -#include <QtCore/qurl.h> -#include <QtCore/qwaitcondition.h> - -QT_BEGIN_NAMESPACE -class QMediaContent; -QT_END_NAMESPACE - -QT_USE_NAMESPACE - -class SourceResolver; -#ifndef Q_WS_SIMULATOR -class Evr9VideoWindowControl; -#endif -class MFAudioEndpointControl; -class MFVideoRendererControl; -class MFPlayerControl; -class MFMetaDataControl; - -class MFPlayerSession : public QObject, public IMFAsyncCallback -{ - Q_OBJECT - friend class SourceResolver; -public: - MFPlayerSession(QObject *parent = 0); - ~MFPlayerSession(); - - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - STDMETHODIMP Invoke(IMFAsyncResult *pResult); - - STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue) - { - Q_UNUSED(pdwFlags); - Q_UNUSED(pdwQueue); - return E_NOTIMPL; - } - - void load(const QMediaContent &media, QIODevice *stream); - void stop(bool immediate = false); - void start(); - void pause(); - - QMediaPlayer::MediaStatus status() const; - qint64 position(); - void setPosition(qint64 position); - qreal playbackRate() const; - void setPlaybackRate(qreal rate); - int volume() const; - void setVolume(int volume); - bool isMuted() const; - void setMuted(bool muted); - int bufferStatus(); - QMediaTimeRange availablePlaybackRanges(); - - void changeStatus(QMediaPlayer::MediaStatus newStatus); - -Q_SIGNALS: - void error(QMediaPlayer::Error error, QString errorString, bool isFatal); - void sessionEvent(IMFMediaEvent *sessionEvent); - void statusChanged(); - void audioAvailable(); - void videoAvailable(); - void durationUpdate(qint64 duration); - void seekableUpdate(bool seekable); - void positionChanged(qint64 position); - void playbackRateChanged(qreal rate); - void volumeChanged(int volume); - void mutedChanged(bool muted); - void bufferStatusChanged(int percentFilled); - -private Q_SLOTS: - void handleMediaSourceReady(); - void handleSessionEvent(IMFMediaEvent *sessionEvent); - void handleSourceError(long hr); - -private: - IMFMediaSession *m_session; - IMFPresentationClock *m_presentationClock; - IMFRateControl *m_rateControl; - IMFRateSupport *m_rateSupport; - IMFSimpleAudioVolume *m_volumeControl; - IPropertyStore *m_netsourceStatistics; - PROPVARIANT m_varStart; - UINT64 m_duration; - - enum Command - { - CmdNone = 0, - CmdStop, - CmdStart, - CmdPause, - CmdSeek, - CmdSeekResume, - }; - - void clear(); - void setPositionInternal(qint64 position, Command requestCmd); - void setPlaybackRateInternal(qreal rate); - void commitRateChange(qreal rate, BOOL isThin); - bool canScrub() const; - void scrub(bool enableScrub); - bool m_scrubbing; - float m_restoreRate; - - SourceResolver *m_sourceResolver; - HANDLE m_hCloseEvent; - - enum MediaType - { - Unknown = 0, - Audio = 1, - Video = 2, - }; - DWORD m_mediaTypes; - - enum PendingState - { - NoPending = 0, - CmdPending, - SeekPending, - }; - - struct SeekState - { - void setCommand(Command cmd) { - prevCmd = command; - command = cmd; - } - Command command; - Command prevCmd; - float rate; // Playback rate - BOOL isThin; // Thinned playback? - qint64 start; // Start position - }; - SeekState m_state; // Current nominal state. - SeekState m_request; // Pending request. - PendingState m_pendingState; - float m_pendingRate; - void updatePendingCommands(Command command); - - QMediaPlayer::MediaStatus m_status; - bool m_canScrub; - int m_volume; - bool m_muted; - - void createSession(); - void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD); - IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source, - IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc); - IMFTopologyNode* addOutputNode(IMFStreamDescriptor *streamDesc, MediaType& mediaType, IMFTopology* topology, DWORD sinkID); -}; - - -#endif diff --git a/src/plugins/wmf/player/mfstream.cpp b/src/plugins/wmf/player/mfstream.cpp deleted file mode 100644 index be91175..0000000 --- a/src/plugins/wmf/player/mfstream.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfstream.h" -#include <QtCore/qcoreapplication.h> - -//MFStream is added for supporting QIODevice type of media source. -//It is used to delegate invocations from media foundation(through IMFByteStream) to QIODevice. - -MFStream::MFStream(QIODevice *stream, bool ownStream) - : m_cRef(1) - , m_stream(stream) - , m_ownStream(ownStream) - , m_currentReadResult(0) -{ - //Move to the thread of the stream object - //to make sure invocations on stream - //are happened in the same thread of stream object - this->moveToThread(stream->thread()); - connect(stream, SIGNAL(readyRead()), this, SLOT(handleReadyRead())); -} - -MFStream::~MFStream() -{ - if (m_currentReadResult) - m_currentReadResult->Release(); - if (m_ownStream) - m_stream->deleteLater(); -} - -//from IUnknown -STDMETHODIMP MFStream::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFByteStream) { - *ppvObject = static_cast<IMFByteStream*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) MFStream::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) MFStream::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - this->deleteLater(); - } - return cRef; -} - - -//from IMFByteStream -STDMETHODIMP MFStream::GetCapabilities(DWORD *pdwCapabilities) -{ - if (!pdwCapabilities) - return E_INVALIDARG; - *pdwCapabilities = MFBYTESTREAM_IS_READABLE; - if (!m_stream->isSequential()) - *pdwCapabilities |= MFBYTESTREAM_IS_SEEKABLE; - return S_OK; -} - -STDMETHODIMP MFStream::GetLength(QWORD *pqwLength) -{ - if (!pqwLength) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pqwLength = QWORD(m_stream->size()); - return S_OK; -} - -STDMETHODIMP MFStream::SetLength(QWORD) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::GetCurrentPosition(QWORD *pqwPosition) -{ - if (!pqwPosition) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pqwPosition = m_stream->pos(); - return S_OK; -} - -STDMETHODIMP MFStream::SetCurrentPosition(QWORD qwPosition) -{ - QMutexLocker locker(&m_mutex); - //SetCurrentPosition may happend during the BeginRead/EndRead pair, - //refusing to execute SetCurrentPosition during that time seems to be - //the simplest workable solution - if (m_currentReadResult) - return S_FALSE; - - bool seekOK = m_stream->seek(qint64(qwPosition)); - if (seekOK) - return S_OK; - else - return S_FALSE; -} - -STDMETHODIMP MFStream::IsEndOfStream(BOOL *pfEndOfStream) -{ - if (!pfEndOfStream) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pfEndOfStream = m_stream->atEnd() ? TRUE : FALSE; - return S_OK; -} - -STDMETHODIMP MFStream::Read(BYTE *pb, ULONG cb, ULONG *pcbRead) -{ - QMutexLocker locker(&m_mutex); - qint64 read = m_stream->read((char*)(pb), qint64(cb)); - if (pcbRead) - *pcbRead = ULONG(read); - return S_OK; -} - -STDMETHODIMP MFStream::BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, - IUnknown *punkState) -{ - if (!pCallback || !pb) - return E_INVALIDARG; - - Q_ASSERT(m_currentReadResult == NULL); - - AsyncReadState *state = new (std::nothrow) AsyncReadState(pb, cb); - if (state == NULL) - return E_OUTOFMEMORY; - - HRESULT hr = MFCreateAsyncResult(state, pCallback, punkState, &m_currentReadResult); - state->Release(); - if (FAILED(hr)) - return hr; - - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - return hr; -} - -STDMETHODIMP MFStream::EndRead(IMFAsyncResult* pResult, ULONG *pcbRead) -{ - if (!pcbRead) - return E_INVALIDARG; - IUnknown *pUnk; - pResult->GetObject(&pUnk); - AsyncReadState *state = static_cast<AsyncReadState*>(pUnk); - *pcbRead = state->bytesRead(); - pUnk->Release(); - - m_currentReadResult->Release(); - m_currentReadResult = NULL; - - return S_OK; -} - -STDMETHODIMP MFStream::Write(const BYTE *, ULONG, ULONG *) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::BeginWrite(const BYTE *, ULONG , - IMFAsyncCallback *, - IUnknown *) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::EndWrite(IMFAsyncResult *, - ULONG *) -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::Seek( - MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, - LONGLONG llSeekOffset, - DWORD, - QWORD *pqwCurrentPosition) -{ - QMutexLocker locker(&m_mutex); - if (m_currentReadResult) - return S_FALSE; - - qint64 pos = qint64(llSeekOffset); - switch (SeekOrigin) { - case msoCurrent: - pos += m_stream->pos(); - break; - } - bool seekOK = m_stream->seek(pos); - if (*pqwCurrentPosition) - *pqwCurrentPosition = pos; - if (seekOK) - return S_OK; - else - return S_FALSE; -} - -STDMETHODIMP MFStream::Flush() -{ - return E_NOTIMPL; -} - -STDMETHODIMP MFStream::Close() -{ - QMutexLocker locker(&m_mutex); - if (m_ownStream) - m_stream->close(); - return S_OK; -} - -void MFStream::doRead() -{ - bool readDone = true; - IUnknown *pUnk = NULL; - HRESULT hr = m_currentReadResult->GetObject(&pUnk); - if (SUCCEEDED(hr)) { - //do actual read - AsyncReadState *state = static_cast<AsyncReadState*>(pUnk); - ULONG cbRead; - Read(state->pb(), state->cb() - state->bytesRead(), &cbRead); - pUnk->Release(); - - state->setBytesRead(cbRead + state->bytesRead()); - if (state->cb() > state->bytesRead() && !m_stream->atEnd()) { - readDone = false; - } - } - - if (readDone) { - //now inform the original caller - m_currentReadResult->SetStatus(hr); - MFInvokeCallback(m_currentReadResult); - } -} - - -void MFStream::handleReadyRead() -{ - doRead(); -} - -void MFStream::customEvent(QEvent *event) -{ - if (event->type() != QEvent::User) { - QObject::customEvent(event); - return; - } - doRead(); -} - -//AsyncReadState is a helper class used in BeginRead for asynchronous operation -//to record some BeginRead parameters, so these parameters could be -//used later when actually executing the read operation in another thread. -MFStream::AsyncReadState::AsyncReadState(BYTE *pb, ULONG cb) - : m_cRef(1) - , m_pb(pb) - , m_cb(cb) - , m_cbRead(0) -{ -} - -//from IUnknown -STDMETHODIMP MFStream::AsyncReadState::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) MFStream::AsyncReadState::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) MFStream::AsyncReadState::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; -} - -BYTE* MFStream::AsyncReadState::pb() const -{ - return m_pb; -} - -ULONG MFStream::AsyncReadState::cb() const -{ - return m_cb; -} - -ULONG MFStream::AsyncReadState::bytesRead() const -{ - return m_cbRead; -} - -void MFStream::AsyncReadState::setBytesRead(ULONG cbRead) -{ - m_cbRead = cbRead; -} diff --git a/src/plugins/wmf/player/mfstream.h b/src/plugins/wmf/player/mfstream.h deleted file mode 100644 index 226bda9..0000000 --- a/src/plugins/wmf/player/mfstream.h +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFSTREAM_H -#define MFSTREAM_H - -#include <mfapi.h> -#include <mfidl.h> -#include <QtCore/qmutex.h> -#include <QtCore/qiodevice.h> -#include <QtCore/qcoreevent.h> - -QT_USE_NAMESPACE - -class MFStream : public QObject, public IMFByteStream -{ - Q_OBJECT -public: - MFStream(QIODevice *stream, bool ownStream); - - ~MFStream(); - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - - //from IMFByteStream - STDMETHODIMP GetCapabilities(DWORD *pdwCapabilities); - - STDMETHODIMP GetLength(QWORD *pqwLength); - - STDMETHODIMP SetLength(QWORD); - - STDMETHODIMP GetCurrentPosition(QWORD *pqwPosition); - - STDMETHODIMP SetCurrentPosition(QWORD qwPosition); - - STDMETHODIMP IsEndOfStream(BOOL *pfEndOfStream); - - STDMETHODIMP Read(BYTE *pb, ULONG cb, ULONG *pcbRead); - - STDMETHODIMP BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback, - IUnknown *punkState); - - STDMETHODIMP EndRead(IMFAsyncResult* pResult, ULONG *pcbRead); - - STDMETHODIMP Write(const BYTE *, ULONG, ULONG *); - - STDMETHODIMP BeginWrite(const BYTE *, ULONG , - IMFAsyncCallback *, - IUnknown *); - - STDMETHODIMP EndWrite(IMFAsyncResult *, - ULONG *); - - STDMETHODIMP Seek( - MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, - LONGLONG llSeekOffset, - DWORD, - QWORD *pqwCurrentPosition); - - STDMETHODIMP Flush(); - - STDMETHODIMP Close(); - -private: - class AsyncReadState : public IUnknown - { - public: - AsyncReadState(BYTE *pb, ULONG cb); - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - BYTE* pb() const; - ULONG cb() const; - ULONG bytesRead() const; - - void setBytesRead(ULONG cbRead); - - private: - long m_cRef; - BYTE *m_pb; - ULONG m_cb; - ULONG m_cbRead; - }; - - long m_cRef; - QIODevice *m_stream; - bool m_ownStream; - DWORD m_workQueueId; - QMutex m_mutex; - - void doRead(); - -private Q_SLOTS: - void handleReadyRead(); - -protected: - void customEvent(QEvent *event); - IMFAsyncResult *m_currentReadResult; -}; - -#endif diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp deleted file mode 100644 index a879d0e..0000000 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ /dev/null @@ -1,2200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfvideorenderercontrol.h" -#include <mferror.h> -#include <qabstractvideosurface.h> -#include <qvideosurfaceformat.h> -#include <qtcore/qtimer.h> -#include <qtcore/qmutex.h> -#include <qtcore/qcoreevent.h> -#include <qtcore/qcoreapplication.h> -#include <qtcore/qthread.h> -#include "guiddef.h" -#include <qtcore/qdebug.h> - -//#define DEBUG_MEDIAFOUNDATION -#define PAD_TO_DWORD(x) (((x) + 3) & ~3) - -namespace -{ - class MediaSampleVideoBuffer : public QAbstractVideoBuffer - { - public: - MediaSampleVideoBuffer(IMFMediaBuffer *buffer, int bytesPerLine) - : QAbstractVideoBuffer(NoHandle) - , m_buffer(buffer) - , m_bytesPerLine(bytesPerLine) - , m_mapMode(NotMapped) - { - buffer->AddRef(); - } - - ~MediaSampleVideoBuffer() - { - m_buffer->Release(); - } - - uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) - { - if (m_mapMode == NotMapped && mode != NotMapped) { - BYTE *bytes; - DWORD length; - HRESULT hr = m_buffer->Lock(&bytes, NULL, &length); - if (SUCCEEDED(hr)) { - if (numBytes) - *numBytes = int(length); - - if (bytesPerLine) - *bytesPerLine = m_bytesPerLine; - - m_mapMode = mode; - return reinterpret_cast<uchar *>(bytes); - } else { - qWarning("Faild to lock mf buffer!"); - } - } - return 0; - } - - void unmap() - { - if (m_mapMode == NotMapped) - return; - m_mapMode = NotMapped; - m_buffer->Unlock(); - } - - MapMode mapMode() const - { - return m_mapMode; - } - - private: - IMFMediaBuffer *m_buffer; - int m_bytesPerLine; - MapMode m_mapMode; - }; - - template<class T> - class AsyncCallback : public IMFAsyncCallback - { - public: - typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult); - - AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn) - { - } - - // IUnknown - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if (!ppv) - { - return E_POINTER; - } - if (iid == __uuidof(IUnknown)) - { - *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this)); - } - else if (iid == __uuidof(IMFAsyncCallback)) - { - *ppv = static_cast<IMFAsyncCallback*>(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - STDMETHODIMP_(ULONG) AddRef() - { - // Delegate to parent class. - return m_pParent->AddRef(); - } - STDMETHODIMP_(ULONG) Release() - { - // Delegate to parent class. - return m_pParent->Release(); - } - - // IMFAsyncCallback methods - STDMETHODIMP GetParameters(DWORD*, DWORD*) - { - // Implementation of this method is optional. - return E_NOTIMPL; - } - - STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult) - { - return (m_pParent->*m_pInvokeFn)(pAsyncResult); - } - - T *m_pParent; - InvokeFn m_pInvokeFn; - }; - - - // Custom interface for handling IMFStreamSink::PlaceMarker calls asynchronously. - MIDL_INTERFACE("a3ff32de-1031-438a-8b47-82f8acda59b7") - IMarker : public IUnknown - { - virtual STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType) = 0; - virtual STDMETHODIMP GetMarkerValue(PROPVARIANT *pvar) = 0; - virtual STDMETHODIMP GetContext(PROPVARIANT *pvar) = 0; - }; - - class Marker : public IMarker - { - public: - static HRESULT Create( - MFSTREAMSINK_MARKER_TYPE eMarkerType, - const PROPVARIANT* pvarMarkerValue, // Can be NULL. - const PROPVARIANT* pvarContextValue, // Can be NULL. - IMarker **ppMarker) - { - if (ppMarker == NULL) - return E_POINTER; - - HRESULT hr = S_OK; - Marker *pMarker = new Marker(eMarkerType); - if (pMarker == NULL) - hr = E_OUTOFMEMORY; - - // Copy the marker data. - if (SUCCEEDED(hr) && pvarMarkerValue) - hr = PropVariantCopy(&pMarker->m_varMarkerValue, pvarMarkerValue); - - if (SUCCEEDED(hr) && pvarContextValue) - hr = PropVariantCopy(&pMarker->m_varContextValue, pvarContextValue); - - if (SUCCEEDED(hr)) { - *ppMarker = pMarker; - (*ppMarker)->AddRef(); - } - - if (pMarker) - pMarker->Release(); - - return hr; - } - - // IUnknown methods. - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if (!ppv) - return E_POINTER; - if (iid == IID_IUnknown) { - *ppv = static_cast<IUnknown*>(this); - } else if (iid == __uuidof(IMarker)) { - *ppv = static_cast<IMarker*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef() - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release() - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType) - { - if (pType == NULL) - return E_POINTER; - *pType = m_eMarkerType; - return S_OK; - } - - STDMETHODIMP GetMarkerValue(PROPVARIANT *pvar) - { - if (pvar == NULL) - return E_POINTER; - return PropVariantCopy(pvar, &m_varMarkerValue); - } - - STDMETHODIMP GetContext(PROPVARIANT *pvar) - { - if (pvar == NULL) - return E_POINTER; - return PropVariantCopy(pvar, &m_varContextValue); - } - - protected: - MFSTREAMSINK_MARKER_TYPE m_eMarkerType; - PROPVARIANT m_varMarkerValue; - PROPVARIANT m_varContextValue; - - private: - long m_cRef; - - Marker(MFSTREAMSINK_MARKER_TYPE eMarkerType) : m_cRef(1), m_eMarkerType(eMarkerType) - { - PropVariantInit(&m_varMarkerValue); - PropVariantInit(&m_varContextValue); - } - - virtual ~Marker() - { - PropVariantClear(&m_varMarkerValue); - PropVariantClear(&m_varContextValue); - } - }; - - class MediaStream : public QObject, public IMFStreamSink, public IMFMediaTypeHandler - { - Q_OBJECT - friend class MFVideoRendererControl; - public: - static const DWORD DEFAULT_MEDIA_STREAM_ID = 0x0; - - MediaStream(IMFMediaSink *parent, MFVideoRendererControl *rendererControl) - : m_cRef(1) - , m_eventQueue(0) - , m_shutdown(false) - , m_surface(0) - , m_state(State_TypeNotSet) - , m_currentFormatIndex(-1) - , m_bytesPerLine(0) - , m_workQueueId(0) - , m_workQueueCB(this, &MediaStream::onDispatchWorkItem) - , m_finalizeResult(0) - , m_scheduledBuffer(0) - , m_presentationClock(0) - , m_currentMediaType(0) - , m_prerolling(false) - , m_prerollTargetTime(0) - , m_startTime(0) - , m_rendererControl(rendererControl) - { - m_sink = parent; - - if (FAILED(MFCreateEventQueue(&m_eventQueue))) - qWarning("Failed to create mf event queue!"); - if (FAILED(MFAllocateWorkQueue(&m_workQueueId))) - qWarning("Failed to allocated mf work queue!"); - } - - ~MediaStream() - { - Q_ASSERT(m_shutdown); - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFStreamSink) { - *ppvObject = static_cast<IMFStreamSink*>(this); - } else if (riid == IID_IMFMediaEventGenerator) { - *ppvObject = static_cast<IMFMediaEventGenerator*>(this); - } else if (riid == IID_IMFMediaTypeHandler) { - *ppvObject = static_cast<IMFMediaTypeHandler*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFStreamSink*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - //from IMFMediaEventGenerator - STDMETHODIMP GetEvent( - DWORD dwFlags, - IMFMediaEvent **ppEvent) - { - // GetEvent can block indefinitely, so we don't hold the lock. - // This requires some juggling with the event queue pointer. - HRESULT hr = S_OK; - IMFMediaEventQueue *queue = NULL; - - m_mutex.lock(); - if (m_shutdown) - hr = MF_E_SHUTDOWN; - if (SUCCEEDED(hr)) { - queue = m_eventQueue; - queue->AddRef(); - } - m_mutex.unlock(); - - // Now get the event. - if (SUCCEEDED(hr)) { - hr = queue->GetEvent(dwFlags, ppEvent); - queue->Release(); - } - - return hr; - } - - STDMETHODIMP BeginGetEvent( - IMFAsyncCallback *pCallback, - IUnknown *punkState) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_eventQueue->BeginGetEvent(pCallback, punkState); - } - - STDMETHODIMP EndGetEvent( - IMFAsyncResult *pResult, - IMFMediaEvent **ppEvent) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_eventQueue->EndGetEvent(pResult, ppEvent); - } - - STDMETHODIMP QueueEvent( - MediaEventType met, - REFGUID guidExtendedType, - HRESULT hrStatus, - const PROPVARIANT *pvValue) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::QueueEvent" << met; -#endif - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_eventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); - } - - //from IMFStreamSink - STDMETHODIMP GetMediaSink( - IMFMediaSink **ppMediaSink) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - else if (!ppMediaSink) - return E_INVALIDARG; - - m_sink->AddRef(); - *ppMediaSink = m_sink; - return S_OK; - } - - STDMETHODIMP GetIdentifier( - DWORD *pdwIdentifier) - { - *pdwIdentifier = MediaStream::DEFAULT_MEDIA_STREAM_ID; - return S_OK; - } - - STDMETHODIMP GetMediaTypeHandler( - IMFMediaTypeHandler **ppHandler) - { - LPVOID handler = NULL; - HRESULT hr = QueryInterface(IID_IMFMediaTypeHandler, &handler); - *ppHandler = (IMFMediaTypeHandler*)(handler); - return hr; - } - - STDMETHODIMP ProcessSample( - IMFSample *pSample) - { - if (pSample == NULL) - return E_INVALIDARG; - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - if (!m_prerolling) { - hr = validateOperation(OpProcessSample); - if (FAILED(hr)) - return hr; - } - - pSample->AddRef(); - m_sampleQueue.push_back(pSample); - - // Unless we are paused, start an async operation to dispatch the next sample. - if (m_state != State_Paused) - hr = queueAsyncOperation(OpProcessSample); - - return hr; - } - - STDMETHODIMP PlaceMarker( - MFSTREAMSINK_MARKER_TYPE eMarkerType, - const PROPVARIANT *pvarMarkerValue, - const PROPVARIANT *pvarContextValue) - { - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - IMarker *pMarker = NULL; - if (m_shutdown) - return MF_E_SHUTDOWN; - - hr = validateOperation(OpPlaceMarker); - if (FAILED(hr)) - return hr; - - // Create a marker object and put it on the sample queue. - hr = Marker::Create(eMarkerType, pvarMarkerValue, pvarContextValue, &pMarker); - if (FAILED(hr)) - return hr; - - m_sampleQueue.push_back(pMarker); - - // Unless we are paused, start an async operation to dispatch the next sample/marker. - if (m_state != State_Paused) - hr = queueAsyncOperation(OpPlaceMarker); // Increments ref count on pOp. - return hr; - } - - STDMETHODIMP Flush( void) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::Flush"; -#endif - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - // Note: Even though we are flushing data, we still need to send - // any marker events that were queued. - clearBufferCache(); - return processSamplesFromQueue(DropSamples); - } - - //from IMFMediaTypeHandler - STDMETHODIMP IsMediaTypeSupported( - IMFMediaType *pMediaType, - IMFMediaType **ppMediaType) - { - if (ppMediaType) - *ppMediaType = NULL; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - int index = getMediaTypeIndex(pMediaType); - if (index < 0) { - if (ppMediaType && m_mediaTypes.size() > 0) { - *ppMediaType = m_mediaTypes[0]; - (*ppMediaType)->AddRef(); - } - return MF_E_INVALIDMEDIATYPE; - } - - BOOL compressed = TRUE; - pMediaType->IsCompressedFormat(&compressed); - if (compressed) { - if (ppMediaType && (SUCCEEDED(MFCreateMediaType(ppMediaType)))) { - (*ppMediaType)->CopyAllItems(pMediaType); - (*ppMediaType)->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE); - (*ppMediaType)->SetUINT32(MF_MT_COMPRESSED, FALSE); - (*ppMediaType)->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - } - return MF_E_INVALIDMEDIATYPE; - } - - return S_OK; - } - - STDMETHODIMP GetMediaTypeCount( - DWORD *pdwTypeCount) - { - if (pdwTypeCount == NULL) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - *pdwTypeCount = DWORD(m_mediaTypes.size()); - return S_OK; - } - - STDMETHODIMP GetMediaTypeByIndex( - DWORD dwIndex, - IMFMediaType **ppType) - { - if (ppType == NULL) - return E_INVALIDARG; - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - hr = MF_E_SHUTDOWN; - - if (SUCCEEDED(hr)) { - if (dwIndex >= DWORD(m_mediaTypes.size())) - hr = MF_E_NO_MORE_TYPES; - } - - if (SUCCEEDED(hr)) { - *ppType = m_mediaTypes[dwIndex]; - (*ppType)->AddRef(); - } - return hr; - } - - STDMETHODIMP SetCurrentMediaType( - IMFMediaType *pMediaType) - { - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - DWORD flag = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | - MF_MEDIATYPE_EQUAL_FORMAT_TYPES | - MF_MEDIATYPE_EQUAL_FORMAT_DATA; - - if (m_currentMediaType && (m_currentMediaType->IsEqual(pMediaType, &flag) == S_OK)) - return S_OK; - - hr = validateOperation(OpSetMediaType); - - if (SUCCEEDED(hr)) { - int index = getMediaTypeIndex(pMediaType); - if (index >= 0) { - UINT64 size; - hr = pMediaType->GetUINT64(MF_MT_FRAME_SIZE, &size); - if (SUCCEEDED(hr)) { - m_currentFormatIndex = index; - int width = int(HI32(size)); - int height = int(LO32(size)); - QVideoSurfaceFormat format(QSize(width, height), m_pixelFormats[index]); - m_surfaceFormat = format; - - if (FAILED(pMediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&m_bytesPerLine))) { - m_bytesPerLine = getBytesPerLine(format); - } - - m_state = State_Ready; - if (m_currentMediaType) - m_currentMediaType->Release(); - m_currentMediaType = pMediaType; - pMediaType->AddRef(); - } - } else { - hr = MF_E_INVALIDREQUEST; - } - } - return hr; - } - - STDMETHODIMP GetCurrentMediaType( - IMFMediaType **ppMediaType) - { - if (ppMediaType == NULL) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - if (m_currentFormatIndex < 0) - return MF_E_NOT_INITIALIZED; - *ppMediaType = m_currentMediaType; - (*ppMediaType)->AddRef(); - return S_OK; - } - - STDMETHODIMP GetMajorType( - GUID *pguidMajorType) - { - if (pguidMajorType == NULL) - return E_INVALIDARG; - *pguidMajorType = MFMediaType_Video; - return S_OK; - } - - // - void setSurface(QAbstractVideoSurface *surface) - { - m_mutex.lock(); - m_surface = surface; - m_mutex.unlock(); - supportedFormatsChanged(); - } - - void setClock(IMFPresentationClock *presentationClock) - { - QMutexLocker locker(&m_mutex); - if (!m_shutdown) { - if (m_presentationClock) - m_presentationClock->Release(); - m_presentationClock = presentationClock; - if (m_presentationClock) - m_presentationClock->AddRef(); - } - } - - void shutdown() - { - QMutexLocker locker(&m_mutex); - Q_ASSERT(!m_shutdown); - - if (m_currentMediaType) { - m_currentMediaType->Release(); - m_currentMediaType = NULL; - m_currentFormatIndex = -1; - } - - if (m_eventQueue) - m_eventQueue->Shutdown(); - - MFUnlockWorkQueue(m_workQueueId); - - if (m_presentationClock) { - m_presentationClock->Release(); - m_presentationClock = NULL; - } - - if (m_scheduledBuffer) { - m_scheduledBuffer->Release(); - m_scheduledBuffer = NULL; - } - - clearMediaTypes(); - clearSampleQueue(); - clearBufferCache(); - - if (m_eventQueue) { - m_eventQueue->Release(); - m_eventQueue = NULL; - } - - m_shutdown = true; - } - - HRESULT startPreroll(MFTIME hnsUpcomingStartTime) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpPreroll); - if (SUCCEEDED(hr)) { - m_prerollTargetTime = hnsUpcomingStartTime; - hr = queueAsyncOperation(OpPreroll); - } - return hr; - } - - HRESULT finalize(IMFAsyncCallback *pCallback, IUnknown *punkState) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - hr = validateOperation(OpFinalize); - if (SUCCEEDED(hr) && m_finalizeResult != NULL) - hr = MF_E_INVALIDREQUEST; // The operation is already pending. - - // Create and store the async result object. - if (SUCCEEDED(hr)) - hr = MFCreateAsyncResult(NULL, pCallback, punkState, &m_finalizeResult); - - if (SUCCEEDED(hr)) { - m_state = State_Finalized; - hr = queueAsyncOperation(OpFinalize); - } - return hr; - } - - HRESULT start(MFTIME start) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::start" << start; -#endif - HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - if (m_rate != 0) - hr = validateOperation(OpStart); - - if (SUCCEEDED(hr)) { - MFTIME sysTime; - if (start != PRESENTATION_CURRENT_POSITION) - m_startTime = start; // Cache the start time. - else - m_presentationClock->GetCorrelatedTime(0, &m_startTime, &sysTime); - m_state = State_Started; - hr = queueAsyncOperation(OpStart); - } - return hr; - } - - HRESULT restart() - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::restart"; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpRestart); - if (SUCCEEDED(hr)) { - m_state = State_Started; - hr = queueAsyncOperation(OpRestart); - } - return hr; - } - - HRESULT stop() - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::stop"; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpStop); - if (SUCCEEDED(hr)) { - m_state = State_Stopped; - hr = queueAsyncOperation(OpStop); - } - return hr; - } - - HRESULT pause() - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::pause"; -#endif - QMutexLocker locker(&m_mutex); - HRESULT hr = validateOperation(OpPause); - if (SUCCEEDED(hr)) { - m_state = State_Paused; - hr = queueAsyncOperation(OpPause); - } - return hr; - } - - HRESULT setRate(float rate) - { -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "MediaStream::setRate" << rate; -#endif - QMutexLocker locker(&m_mutex); - m_rate = rate; - queueEvent(MEStreamSinkRateChanged, GUID_NULL, S_OK, NULL); - return S_OK; - } - - void supportedFormatsChanged() - { - QMutexLocker locker(&m_mutex); - m_pixelFormats.clear(); - clearMediaTypes(); - QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(); - foreach (QVideoFrame::PixelFormat format, formats) { - IMFMediaType *mediaType; - if (FAILED(MFCreateMediaType(&mediaType))) { - qWarning("Failed to create mf media type!"); - continue; - } - mediaType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE); - mediaType->SetUINT32(MF_MT_COMPRESSED, FALSE); - mediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); - switch (format) { - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_ARGB32_Premultiplied: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32); - break; - case QVideoFrame::Format_RGB32: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32); - break; - case QVideoFrame::Format_RGB24: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24); - break; - case QVideoFrame::Format_RGB565: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565); - break; - case QVideoFrame::Format_RGB555: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555); - break; - case QVideoFrame::Format_AYUV444: - case QVideoFrame::Format_AYUV444_Premultiplied: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV); - break; - case QVideoFrame::Format_YUV420P: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_I420); - break; - case QVideoFrame::Format_UYVY: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY); - break; - case QVideoFrame::Format_YV12: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); - break; - case QVideoFrame::Format_NV12: - mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); - break; - default: - mediaType->Release(); - continue; - } - m_pixelFormats.push_back(format); - m_mediaTypes.push_back(mediaType); - } - } - - void present() - { - QMutexLocker locker(&m_mutex); - if (!m_scheduledBuffer) - return; - m_surface->present(QVideoFrame( - new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat())); - m_scheduledBuffer->Release(); - m_scheduledBuffer = NULL; - if (m_rate != 0) - schedulePresentation(true); - } - - enum - { - StartSurface = QEvent::User, - StopSurface, - FlushSurface, - PresentSurface - }; - - class PresentEvent : public QEvent - { - public: - PresentEvent(MFTIME targetTime) - : QEvent(QEvent::Type(PresentSurface)) - , m_time(targetTime) - { - } - - int targetTime() - { - return m_time; - } - - private: - MFTIME m_time; - }; - - protected: - void customEvent(QEvent *event) - { - QMutexLocker locker(&m_mutex); - if (event->type() == StartSurface) { - if (m_state == State_WaitForSurfaceStart) { - m_startResult = startSurface(); - queueAsyncOperation(OpStart); - } - } else if (event->type() == StopSurface) { - stopSurface(); - } else { - QObject::customEvent(event); - } - } - HRESULT m_startResult; - - private: - HRESULT startSurface() - { - if (!m_surface->isFormatSupported(m_surfaceFormat)) - return S_FALSE; - if (!m_surface->start(m_surfaceFormat)) - return S_FALSE; - return S_OK; - } - - void stopSurface() - { - m_surface->stop(); - } - - enum FlushState - { - DropSamples = 0, - WriteSamples - }; - - // State enum: Defines the current state of the stream. - enum State - { - State_TypeNotSet = 0, // No media type is set - State_Ready, // Media type is set, Start has never been called. - State_Started, - State_Paused, - State_Stopped, - State_WaitForSurfaceStart, - State_Finalized, - State_Count = State_Finalized + 1 // Number of states - }; - - // StreamOperation: Defines various operations that can be performed on the stream. - enum StreamOperation - { - OpSetMediaType = 0, - OpPreroll, - OpStart, - OpRestart, - OpPause, - OpStop, - OpSetRate, - OpProcessSample, - OpPlaceMarker, - OpFinalize, - - Op_Count = OpFinalize + 1 // Number of operations - }; - - // AsyncOperation: - // Used to queue asynchronous operations. When we call MFPutWorkItem, we use this - // object for the callback state (pState). Then, when the callback is invoked, - // we can use the object to determine which asynchronous operation to perform. - class AsyncOperation : public IUnknown - { - public: - AsyncOperation(StreamOperation op) - :m_cRef(1), m_op(op) - { - } - - StreamOperation m_op; // The operation to perform. - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if (!ppv) - return E_POINTER; - if (iid == IID_IUnknown) { - *ppv = static_cast<IUnknown*>(this); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - STDMETHODIMP_(ULONG) AddRef() - { - return InterlockedIncrement(&m_cRef); - } - STDMETHODIMP_(ULONG) Release() - { - ULONG uCount = InterlockedDecrement(&m_cRef); - if (uCount == 0) - delete this; - // For thread safety, return a temporary variable. - return uCount; - } - - private: - long m_cRef; - virtual ~AsyncOperation() - { - Q_ASSERT(m_cRef == 0); - } - }; - - // ValidStateMatrix: Defines a look-up table that says which operations - // are valid from which states. - static BOOL ValidStateMatrix[State_Count][Op_Count]; - - long m_cRef; - QMutex m_mutex; - - IMFMediaType *m_currentMediaType; - State m_state; - IMFMediaSink *m_sink; - IMFMediaEventQueue *m_eventQueue; - DWORD m_workQueueId; - AsyncCallback<MediaStream> m_workQueueCB; - QList<IUnknown*> m_sampleQueue; - IMFAsyncResult *m_finalizeResult; // Result object for Finalize operation. - MFTIME m_startTime; // Presentation time when the clock started. - - bool m_shutdown; - QList<IMFMediaType*> m_mediaTypes; - QList<QVideoFrame::PixelFormat> m_pixelFormats; - int m_currentFormatIndex; - int m_bytesPerLine; - QVideoSurfaceFormat m_surfaceFormat; - QAbstractVideoSurface* m_surface; - MFVideoRendererControl *m_rendererControl; - - void clearMediaTypes() - { - foreach (IMFMediaType* mediaType, m_mediaTypes) - mediaType->Release(); - m_mediaTypes.clear(); - } - - int getMediaTypeIndex(IMFMediaType *mt) - { - GUID majorType; - if (FAILED(mt->GetMajorType(&majorType))) - return -1; - if (majorType != MFMediaType_Video) - return -1; - - GUID subType; - if (FAILED(mt->GetGUID(MF_MT_SUBTYPE, &subType))) - return -1; - - for (int index = 0; index < m_mediaTypes.size(); ++index) { - GUID st; - m_mediaTypes[index]->GetGUID(MF_MT_SUBTYPE, &st); - if (st == subType) - return index; - } - return -1; - } - - int getBytesPerLine(const QVideoSurfaceFormat &format) - { - switch (format.pixelFormat()) { - // 32 bpp packed formats. - case QVideoFrame::Format_RGB32: - case QVideoFrame::Format_AYUV444: - return format.frameWidth() * 4; - // 24 bpp packed formats. - case QVideoFrame::Format_RGB24: - return PAD_TO_DWORD(format.frameWidth() * 3); - // 16 bpp packed formats. - case QVideoFrame::Format_RGB565: - case QVideoFrame::Format_RGB555: - case QVideoFrame::Format_YUYV: - case QVideoFrame::Format_UYVY: - return PAD_TO_DWORD(format.frameWidth() * 2); - // Planar formats. - case QVideoFrame::Format_IMC1: - case QVideoFrame::Format_IMC2: - case QVideoFrame::Format_IMC3: - case QVideoFrame::Format_IMC4: - case QVideoFrame::Format_YV12: - case QVideoFrame::Format_NV12: - case QVideoFrame::Format_YUV420P: - return PAD_TO_DWORD(format.frameWidth()); - default: - return 0; - } - } - - // Callback for MFPutWorkItem. - HRESULT onDispatchWorkItem(IMFAsyncResult* pAsyncResult) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - IUnknown *pState = NULL; - hr = pAsyncResult->GetState(&pState); - if (SUCCEEDED(hr)) { - // The state object is an AsncOperation object. - AsyncOperation *pOp = (AsyncOperation*)pState; - StreamOperation op = pOp->m_op; - switch (op) { - case OpStart: - endPreroll(S_FALSE); - if (m_state == State_WaitForSurfaceStart) { - hr = m_startResult; - m_state = State_Started; - } else if (!m_surface->isActive()) { - if (thread() == QThread::currentThread()) { - hr = startSurface(); - } - else { - m_state = State_WaitForSurfaceStart; - QCoreApplication::postEvent(m_rendererControl, new QChildEvent(QEvent::Type(StartSurface), this)); - break; - } - } - case OpRestart: - endPreroll(S_FALSE); - if (SUCCEEDED(hr)) { - // Send MEStreamSinkStarted. - hr = queueEvent(MEStreamSinkStarted, GUID_NULL, hr, NULL); - // Kick things off by requesting samples... - schedulePresentation(true); - // There might be samples queue from earlier (ie, while paused). - if (SUCCEEDED(hr)) - hr = processSamplesFromQueue(WriteSamples); - } - break; - case OpPreroll: - beginPreroll(); - break; - case OpStop: - // Drop samples from queue. - hr = processSamplesFromQueue(DropSamples); - if (m_scheduledBuffer) { - m_scheduledBuffer->Release(); - m_scheduledBuffer = NULL; - } - // Send the event even if the previous call failed. - hr = queueEvent(MEStreamSinkStopped, GUID_NULL, hr, NULL); - if (m_surface->isActive()) { - if (thread() == QThread::currentThread()) { - stopSurface(); - } - else { - QCoreApplication::postEvent(m_rendererControl, new QChildEvent(QEvent::Type(StopSurface), this)); - } - } - break; - case OpPause: - hr = queueEvent(MEStreamSinkPaused, GUID_NULL, hr, NULL); - break; - case OpSetRate: - //TODO: - break; - case OpProcessSample: - case OpPlaceMarker: - hr = dispatchProcessSample(pOp); - break; - case OpFinalize: - endPreroll(S_FALSE); - hr = dispatchFinalize(pOp); - break; - } - } - - if (pState) - pState->Release(); - return hr; - } - - - HRESULT queueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue) - { - HRESULT hr = S_OK; - if (m_shutdown) - hr = MF_E_SHUTDOWN; - if (SUCCEEDED(hr)) - hr = m_eventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); - return hr; - } - - HRESULT validateOperation(StreamOperation op) - { - Q_ASSERT(!m_shutdown); - if (ValidStateMatrix[m_state][op]) - return S_OK; - else - return MF_E_INVALIDREQUEST; - } - - HRESULT queueAsyncOperation(StreamOperation op) - { - HRESULT hr = S_OK; - AsyncOperation *asyncOp = new AsyncOperation(op); - if (asyncOp == NULL) - hr = E_OUTOFMEMORY; - - if (SUCCEEDED(hr)) - hr = MFPutWorkItem(m_workQueueId, &m_workQueueCB, asyncOp); - - if (asyncOp) - asyncOp->Release(); - - return hr; - } - - HRESULT processSamplesFromQueue(FlushState bFlushData) - { - HRESULT hr = S_OK; - QList<IUnknown*>::Iterator pos = m_sampleQueue.begin(); - // Enumerate all of the samples/markers in the queue. - while (pos != m_sampleQueue.end()) { - IUnknown *pUnk = NULL; - IMarker *pMarker = NULL; - IMFSample *pSample = NULL; - pUnk = *pos; - // Figure out if this is a marker or a sample. - if (SUCCEEDED(hr)) { - hr = pUnk->QueryInterface(__uuidof(IMarker), (void**)&pMarker); - if (hr == E_NOINTERFACE) - hr = pUnk->QueryInterface(IID_IMFSample, (void**)&pSample); - } - - // Now handle the sample/marker appropriately. - if (SUCCEEDED(hr)) { - if (pMarker) { - hr = sendMarkerEvent(pMarker, bFlushData); - } else { - Q_ASSERT(pSample != NULL); // Not a marker, must be a sample - if (bFlushData == WriteSamples) - hr = processSampleData(pSample); - } - } - if (pMarker) - pMarker->Release(); - if (pSample) - pSample->Release(); - - if (FAILED(hr)) - break; - - pos++; - } - - clearSampleQueue(); - return hr; - } - - void beginPreroll() - { - if (m_prerolling) - return; - m_prerolling = true; - clearSampleQueue(); - clearBufferCache(); - queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - - void endPreroll(HRESULT hrStatus) - { - if (!m_prerolling) - return; - m_prerolling = false; - queueEvent(MEStreamSinkPrerolled, GUID_NULL, hrStatus, NULL); - } - MFTIME m_prerollTargetTime; - bool m_prerolling; - - void clearSampleQueue() { - foreach (IUnknown* sample, m_sampleQueue) - sample->Release(); - m_sampleQueue.clear(); - } - - HRESULT sendMarkerEvent(IMarker *pMarker, FlushState FlushState) - { - HRESULT hr = S_OK; - HRESULT hrStatus = S_OK; // Status code for marker event. - if (FlushState == DropSamples) - hrStatus = E_ABORT; - - PROPVARIANT var; - PropVariantInit(&var); - - // Get the context data. - hr = pMarker->GetContext(&var); - - if (SUCCEEDED(hr)) - hr = queueEvent(MEStreamSinkMarker, GUID_NULL, hrStatus, &var); - - PropVariantClear(&var); - return hr; - } - - HRESULT dispatchProcessSample(AsyncOperation* pOp) - { - HRESULT hr = S_OK; - Q_ASSERT(pOp != NULL); - hr = processSamplesFromQueue(WriteSamples); - // We are in the middle of an asynchronous operation, so if something failed, send an error. - if (FAILED(hr)) - hr = queueEvent(MEError, GUID_NULL, hr, NULL); - - return hr; - } - - HRESULT dispatchFinalize(AsyncOperation*) - { - HRESULT hr = S_OK; - // Write any samples left in the queue... - hr = processSamplesFromQueue(WriteSamples); - - // Set the async status and invoke the callback. - m_finalizeResult->SetStatus(hr); - hr = MFInvokeCallback(m_finalizeResult); - return hr; - } - - HRESULT processSampleData(IMFSample *pSample) - { - LONGLONG time; - HRESULT hr = pSample->GetSampleTime(&time); - - if (m_prerolling) { - if (SUCCEEDED(hr) && time >= m_prerollTargetTime) { - IMFMediaBuffer *pBuffer = NULL; - hr = pSample->ConvertToContiguousBuffer(&pBuffer); - if (SUCCEEDED(hr)) { - SampleBuffer sb; - sb.m_buffer = pBuffer; - sb.m_time = time; - m_bufferCache.push_back(sb); - endPreroll(S_OK); - } - } else { - queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - } else { - bool requestSample = true; - // If the time stamp is too early, just discard this sample. - if (SUCCEEDED(hr) && time >= m_startTime) { - IMFMediaBuffer *pBuffer = NULL; - hr = pSample->ConvertToContiguousBuffer(&pBuffer); - if (SUCCEEDED(hr)) { - SampleBuffer sb; - sb.m_buffer = pBuffer; - sb.m_time = time; - m_bufferCache.push_back(sb); - } - if (m_rate == 0) - requestSample = false; - } - schedulePresentation(requestSample); - } - return hr; - } - - class SampleBuffer - { - public: - IMFMediaBuffer *m_buffer; - LONGLONG m_time; - }; - QList<SampleBuffer> m_bufferCache; - static const int BUFFER_CACHE_SIZE = 2; - - void clearBufferCache() - { - foreach (SampleBuffer sb, m_bufferCache) - sb.m_buffer->Release(); - m_bufferCache.clear(); - } - - void schedulePresentation(bool requestSample) - { - if (m_state == State_Paused) - return; - if (!m_scheduledBuffer) { - //get time from presentation time - MFTIME currentTime = m_startTime, sysTime; - bool timeOK = true; - if (m_rate != 0) { - if (FAILED(m_presentationClock->GetCorrelatedTime(0, ¤tTime, &sysTime))) - timeOK = false; - } - while (!m_bufferCache.isEmpty()) { - SampleBuffer sb = m_bufferCache.first(); - m_bufferCache.pop_front(); - if (timeOK && currentTime > sb.m_time) { - sb.m_buffer->Release(); - qDebug() << "currentPresentTime =" << float(currentTime / 10000) * 0.001f << " and sampleTime is" << float(sb.m_time / 10000) * 0.001f; - continue; - } - m_scheduledBuffer = sb.m_buffer; - QCoreApplication::postEvent(m_rendererControl, new PresentEvent(sb.m_time)); - if (m_rate == 0) - queueEvent(MEStreamSinkScrubSampleComplete, GUID_NULL, S_OK, NULL); - break; - } - } - if (requestSample && m_bufferCache.size() < BUFFER_CACHE_SIZE) - queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - IMFMediaBuffer *m_scheduledBuffer; - IMFPresentationClock *m_presentationClock; - float m_rate; - }; - - BOOL MediaStream::ValidStateMatrix[MediaStream::State_Count][MediaStream::Op_Count] = - { - // States: Operations: - // SetType Start Preroll, Restart Pause Stop SetRate Sample Marker Finalize - /* NotSet */ TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, - - /* Ready */ TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, - - /* Start */ FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, - - /* Pause */ FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, - - /* Stop */ FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, - - /*WaitForSurfaceStart*/ FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, - - /* Final */ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE - - // Note about states: - // 1. OnClockRestart should only be called from paused state. - // 2. While paused, the sink accepts samples but does not process them. - }; - - class MediaSink : public IMFFinalizableMediaSink, public IMFClockStateSink, public IMFMediaSinkPreroll - { - public: - MediaSink(MFVideoRendererControl *rendererControl) - : m_cRef(1) - , m_shutdown(false) - , m_presentationClock(0) - , m_playRate(1) - { - m_stream = new MediaStream(this, rendererControl); - } - - ~MediaSink() - { - Q_ASSERT(m_shutdown); - } - - void setSurface(QAbstractVideoSurface *surface) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->setSurface(surface); - } - - void supportedFormatsChanged() - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->supportedFormatsChanged(); - } - - void present() - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return; - m_stream->present(); - } - - MFTIME getTime() - { - QMutexLocker locker(&m_mutex); - if (!m_presentationClock) - return 0; - MFTIME time, sysTime; - m_presentationClock->GetCorrelatedTime(0, &time, &sysTime); - return time; - } - - float getPlayRate() - { - QMutexLocker locker(&m_mutex); - return m_playRate; - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFMediaSink) { - *ppvObject = static_cast<IMFMediaSink*>(this); - } else if (riid == IID_IMFMediaSinkPreroll) { - *ppvObject = static_cast<IMFMediaSinkPreroll*>(this); - } else if (riid == IID_IMFClockStateSink) { - *ppvObject = static_cast<IMFClockStateSink*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFFinalizableMediaSink*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - - - //IMFMediaSinkPreroll - STDMETHODIMP NotifyPreroll(MFTIME hnsUpcomingStartTime) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->startPreroll(hnsUpcomingStartTime); - } - - //from IMFFinalizableMediaSink - STDMETHODIMP BeginFinalize(IMFAsyncCallback *pCallback, IUnknown *punkState) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->finalize(pCallback, punkState); - } - - STDMETHODIMP EndFinalize(IMFAsyncResult *pResult) - { - HRESULT hr = S_OK; - // Return the status code from the async result. - if (pResult == NULL) - hr = E_INVALIDARG; - else - hr = pResult->GetStatus(); - return hr; - } - - //from IMFMediaSink - STDMETHODIMP GetCharacteristics( - DWORD *pdwCharacteristics) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - *pdwCharacteristics = MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL; - return S_OK; - } - - STDMETHODIMP AddStreamSink( - DWORD, - IMFMediaType *, - IMFStreamSink **) - { - QMutexLocker locker(&m_mutex); - return m_shutdown ? MF_E_SHUTDOWN : MF_E_STREAMSINKS_FIXED; - } - - STDMETHODIMP RemoveStreamSink( - DWORD) - { - QMutexLocker locker(&m_mutex); - return m_shutdown ? MF_E_SHUTDOWN : MF_E_STREAMSINKS_FIXED; - } - - STDMETHODIMP GetStreamSinkCount( - DWORD *pcStreamSinkCount) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - *pcStreamSinkCount = 1; - return S_OK; - } - - STDMETHODIMP GetStreamSinkByIndex( - DWORD dwIndex, - IMFStreamSink **ppStreamSink) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - if (dwIndex != 0) - return MF_E_INVALIDINDEX; - - *ppStreamSink = m_stream; - m_stream->AddRef(); - return S_OK; - } - - STDMETHODIMP GetStreamSinkById( - DWORD dwStreamSinkIdentifier, - IMFStreamSink **ppStreamSink) - { - if (ppStreamSink == NULL) - return E_INVALIDARG; - if (dwStreamSinkIdentifier != MediaStream::DEFAULT_MEDIA_STREAM_ID) - return MF_E_INVALIDSTREAMNUMBER; - - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - *ppStreamSink = m_stream; - m_stream->AddRef(); - return S_OK; - } - - STDMETHODIMP SetPresentationClock( - IMFPresentationClock *pPresentationClock) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - if (m_presentationClock) { - m_presentationClock->RemoveClockStateSink(this); - m_presentationClock->Release(); - } - m_presentationClock = pPresentationClock; - if (m_presentationClock) { - m_presentationClock->AddRef(); - m_presentationClock->AddClockStateSink(this); - } - m_stream->setClock(m_presentationClock); - return S_OK; - } - - STDMETHODIMP GetPresentationClock( - IMFPresentationClock **ppPresentationClock) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - *ppPresentationClock = m_presentationClock; - if (m_presentationClock) { - m_presentationClock->AddRef(); - return S_OK; - } - return MF_E_NO_CLOCK; - } - - STDMETHODIMP Shutdown(void) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - - m_stream->shutdown(); - if (m_presentationClock) { - m_presentationClock->Release(); - m_presentationClock = NULL; - } - m_stream->Release(); - m_stream = NULL; - m_shutdown = true; - return S_OK; - } - - // IMFClockStateSink methods - STDMETHODIMP OnClockStart(MFTIME, LONGLONG llClockStartOffset) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->start(llClockStartOffset); - } - - STDMETHODIMP OnClockStop(MFTIME) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->stop(); - } - - STDMETHODIMP OnClockPause(MFTIME) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->pause(); - } - - STDMETHODIMP OnClockRestart(MFTIME) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - return m_stream->restart(); - } - - STDMETHODIMP OnClockSetRate(MFTIME, float flRate) - { - QMutexLocker locker(&m_mutex); - if (m_shutdown) - return MF_E_SHUTDOWN; - m_playRate = flRate; - return m_stream->setRate(flRate); - } - - private: - long m_cRef; - QMutex m_mutex; - bool m_shutdown; - IMFPresentationClock *m_presentationClock; - MediaStream *m_stream; - float m_playRate; - }; - - class VideoRendererActivate : public IMFActivate - { - public: - VideoRendererActivate(MFVideoRendererControl *rendererControl) - : m_cRef(1) - , m_sink(0) - , m_rendererControl(rendererControl) - , m_attributes(0) - { - MFCreateAttributes(&m_attributes, 0); - m_sink = new MediaSink(rendererControl); - } - - ~VideoRendererActivate() - { - m_attributes->Release(); - } - - //from IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) - { - if (!ppvObject) - return E_POINTER; - if (riid == IID_IMFActivate) { - *ppvObject = static_cast<IMFActivate*>(this); - } else if (riid == IID_IMFAttributes) { - *ppvObject = static_cast<IMFAttributes*>(this); - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(static_cast<IMFActivate*>(this)); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release(void) - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; - } - - //from IMFActivate - STDMETHODIMP ActivateObject(REFIID riid, void **ppv) - { - if (!ppv) - return E_INVALIDARG; - QMutexLocker locker(&m_mutex); - if (!m_sink) { - m_sink = new MediaSink(m_rendererControl); - if (m_surface) - m_sink->setSurface(m_surface); - } - return m_sink->QueryInterface(riid, ppv); - } - - STDMETHODIMP ShutdownObject(void) - { - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - if (m_sink) { - hr = m_sink->Shutdown(); - m_sink->Release(); - m_sink = NULL; - } - return hr; - } - - STDMETHODIMP DetachObject(void) - { - QMutexLocker locker(&m_mutex); - if (m_sink) { - m_sink->Release(); - m_sink = NULL; - } - return S_OK; - } - - //from IMFAttributes - STDMETHODIMP GetItem( - REFGUID guidKey, - PROPVARIANT *pValue) - { - return m_attributes->GetItem(guidKey, pValue); - } - - STDMETHODIMP GetItemType( - REFGUID guidKey, - MF_ATTRIBUTE_TYPE *pType) - { - return m_attributes->GetItemType(guidKey, pType); - } - - STDMETHODIMP CompareItem( - REFGUID guidKey, - REFPROPVARIANT Value, - BOOL *pbResult) - { - return m_attributes->CompareItem(guidKey, Value, pbResult); - } - - STDMETHODIMP Compare( - IMFAttributes *pTheirs, - MF_ATTRIBUTES_MATCH_TYPE MatchType, - BOOL *pbResult) - { - return m_attributes->Compare(pTheirs, MatchType, pbResult); - } - - STDMETHODIMP GetUINT32( - REFGUID guidKey, - UINT32 *punValue) - { - return m_attributes->GetUINT32(guidKey, punValue); - } - - STDMETHODIMP GetUINT64( - REFGUID guidKey, - UINT64 *punValue) - { - return m_attributes->GetUINT64(guidKey, punValue); - } - - STDMETHODIMP GetDouble( - REFGUID guidKey, - double *pfValue) - { - return m_attributes->GetDouble(guidKey, pfValue); - } - - STDMETHODIMP GetGUID( - REFGUID guidKey, - GUID *pguidValue) - { - return m_attributes->GetGUID(guidKey, pguidValue); - } - - STDMETHODIMP GetStringLength( - REFGUID guidKey, - UINT32 *pcchLength) - { - return m_attributes->GetStringLength(guidKey, pcchLength); - } - - STDMETHODIMP GetString( - REFGUID guidKey, - LPWSTR pwszValue, - UINT32 cchBufSize, - UINT32 *pcchLength) - { - return m_attributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength); - } - - STDMETHODIMP GetAllocatedString( - REFGUID guidKey, - LPWSTR *ppwszValue, - UINT32 *pcchLength) - { - return m_attributes->GetAllocatedString(guidKey, ppwszValue, pcchLength); - } - - STDMETHODIMP GetBlobSize( - REFGUID guidKey, - UINT32 *pcbBlobSize) - { - return m_attributes->GetBlobSize(guidKey, pcbBlobSize); - } - - STDMETHODIMP GetBlob( - REFGUID guidKey, - UINT8 *pBuf, - UINT32 cbBufSize, - UINT32 *pcbBlobSize) - { - return m_attributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize); - } - - STDMETHODIMP GetAllocatedBlob( - REFGUID guidKey, - UINT8 **ppBuf, - UINT32 *pcbSize) - { - return m_attributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize); - } - - STDMETHODIMP GetUnknown( - REFGUID guidKey, - REFIID riid, - LPVOID *ppv) - { - return m_attributes->GetUnknown(guidKey, riid, ppv); - } - - STDMETHODIMP SetItem( - REFGUID guidKey, - REFPROPVARIANT Value) - { - return m_attributes->SetItem(guidKey, Value); - } - - STDMETHODIMP DeleteItem( - REFGUID guidKey) - { - return m_attributes->DeleteItem(guidKey); - } - - STDMETHODIMP DeleteAllItems(void) - { - return m_attributes->DeleteAllItems(); - } - - STDMETHODIMP SetUINT32( - REFGUID guidKey, - UINT32 unValue) - { - return m_attributes->SetUINT32(guidKey, unValue); - } - - STDMETHODIMP SetUINT64( - REFGUID guidKey, - UINT64 unValue) - { - return m_attributes->SetUINT64(guidKey, unValue); - } - - STDMETHODIMP SetDouble( - REFGUID guidKey, - double fValue) - { - return m_attributes->SetDouble(guidKey, fValue); - } - - STDMETHODIMP SetGUID( - REFGUID guidKey, - REFGUID guidValue) - { - return m_attributes->SetGUID(guidKey, guidValue); - } - - STDMETHODIMP SetString( - REFGUID guidKey, - LPCWSTR wszValue) - { - return m_attributes->SetString(guidKey, wszValue); - } - - STDMETHODIMP SetBlob( - REFGUID guidKey, - const UINT8 *pBuf, - UINT32 cbBufSize) - { - return m_attributes->SetBlob(guidKey, pBuf, cbBufSize); - } - - STDMETHODIMP SetUnknown( - REFGUID guidKey, - IUnknown *pUnknown) - { - return m_attributes->SetUnknown(guidKey, pUnknown); - } - - STDMETHODIMP LockStore(void) - { - return m_attributes->LockStore(); - } - - STDMETHODIMP UnlockStore(void) - { - return m_attributes->UnlockStore(); - } - - STDMETHODIMP GetCount( - UINT32 *pcItems) - { - return m_attributes->GetCount(pcItems); - } - - STDMETHODIMP GetItemByIndex( - UINT32 unIndex, - GUID *pguidKey, - PROPVARIANT *pValue) - { - return m_attributes->GetItemByIndex(unIndex, pguidKey, pValue); - } - - STDMETHODIMP CopyAllItems( - IMFAttributes *pDest) - { - return m_attributes->CopyAllItems(pDest); - } - - ///////////////////////////////// - void setSurface(QAbstractVideoSurface *surface) - { - QMutexLocker locker(&m_mutex); - if (m_surface == surface) - return; - - m_surface = surface; - - if (!m_sink) - return; - m_sink->setSurface(m_surface); - } - - void supportedFormatsChanged() - { - QMutexLocker locker(&m_mutex); - if (!m_sink) - return; - m_sink->supportedFormatsChanged(); - } - - void present() - { - QMutexLocker locker(&m_mutex); - if (!m_sink) - return; - m_sink->present(); - } - - MFTIME getTime() - { - if (m_sink) - return m_sink->getTime(); - return 0; - } - - float getPlayRate() - { - if (m_sink) - return m_sink->getPlayRate(); - return 1; - } - - private: - long m_cRef; - bool m_shutdown; - MediaSink *m_sink; - MFVideoRendererControl *m_rendererControl; - IMFAttributes *m_attributes; - QAbstractVideoSurface *m_surface; - QMutex m_mutex; - }; -} - -MFVideoRendererControl::MFVideoRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_surface(0) - , m_callback(0) -{ - m_currentActivate = new VideoRendererActivate(this); -} - -MFVideoRendererControl::~MFVideoRendererControl() -{ - if (m_currentActivate) { - m_currentActivate->ShutdownObject(); - m_currentActivate->Release(); - } -} - -QAbstractVideoSurface *MFVideoRendererControl::surface() const -{ - return m_surface; -} - -void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface == surface) - return; - - if (m_surface) - disconnect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); - m_surface = surface; - - if (m_surface) { - connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); - } - static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface); -} - -void MFVideoRendererControl::customEvent(QEvent *event) -{ - if (event->type() == MediaStream::PresentSurface) { - MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime(); - MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime(); - float playRate = static_cast<VideoRendererActivate*>(m_currentActivate)->getPlayRate(); - if (playRate > 0.0001f && targetTime > currentTime) - QTimer::singleShot(int((float)((targetTime - currentTime) / 10000) / playRate), this, SLOT(present())); - else - present(); - return; - } - QChildEvent *childEvent = dynamic_cast<QChildEvent*>(event); - if (!childEvent) { - QObject::customEvent(event); - return; - } - static_cast<MediaStream*>(childEvent->child())->customEvent(event); -} - -void MFVideoRendererControl::supportedFormatsChanged() -{ - static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged(); -} - -void MFVideoRendererControl::present() -{ - static_cast<VideoRendererActivate*>(m_currentActivate)->present(); -} - -IMFActivate* MFVideoRendererControl::currentActivate() const -{ - return m_currentActivate; -} - -#include "moc_mfvideorenderercontrol.cpp" -#include "mfvideorenderercontrol.moc" diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h deleted file mode 100644 index ad02772..0000000 --- a/src/plugins/wmf/player/mfvideorenderercontrol.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MFVIDEORENDERERCONTROL_H -#define MFVIDEORENDERERCONTROL_H - -#include "../../src/multimedia/qvideorenderercontrol.h" -#include <mfapi.h> -#include <mfidl.h> - -QT_USE_NAMESPACE - -class MFVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - MFVideoRendererControl(QObject *parent = 0); - ~MFVideoRendererControl(); - - QAbstractVideoSurface *surface() const; - void setSurface(QAbstractVideoSurface *surface); - - IMFActivate* currentActivate() const; - -protected: - void customEvent(QEvent *event); - -private Q_SLOTS: - void supportedFormatsChanged(); - void present(); - -private: - QAbstractVideoSurface *m_surface; - IMFActivate *m_currentActivate; - IMFSampleGrabberSinkCallback *m_callback; -}; - -#endif diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri deleted file mode 100644 index 58375ba..0000000 --- a/src/plugins/wmf/player/player.pri +++ /dev/null @@ -1,30 +0,0 @@ -INCLUDEPATH += $$PWD - -LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 -lMf -lMfuuid -lMfplat -lPropsys - -DEFINES += QMEDIA_MEDIAFOUNDATION_PLAYER - -HEADERS += \ - $$PWD/mfplayerservice.h \ - $$PWD/mfplayersession.h \ - $$PWD/mfstream.h \ - $$PWD/sourceresolver.h \ - $$PWD/mfplayercontrol.h \ - $$PWD/mfvideorenderercontrol.h \ - $$PWD/mfaudioendpointcontrol.h \ - $$PWD/mfmetadatacontrol.h - -SOURCES += \ - $$PWD/mfplayerservice.cpp \ - $$PWD/mfplayersession.cpp \ - $$PWD/mfstream.cpp \ - $$PWD/sourceresolver.cpp \ - $$PWD/mfplayercontrol.cpp \ - $$PWD/mfvideorenderercontrol.cpp \ - $$PWD/mfaudioendpointcontrol.cpp \ - $$PWD/mfmetadatacontrol.cpp - -!simulator { - HEADERS += $$PWD/evr9videowindowcontrol.h - SOURCES += $$PWD/evr9videowindowcontrol.cpp -} diff --git a/src/plugins/wmf/player/sourceresolver.cpp b/src/plugins/wmf/player/sourceresolver.cpp deleted file mode 100644 index 9c62fa8..0000000 --- a/src/plugins/wmf/player/sourceresolver.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mfplayersession.h" -#include "mfstream.h" -#include "sourceresolver.h" -#include <Mferror.h> -#include <nserror.h> -#include <QtCore/qfile.h> - -/* - SourceResolver is separated from MFPlayerSession to handle the work of resolving a media source - asynchronously. You call SourceResolver::load to request resolving a media source asynchronously, - and it will emit mediaSourceReady() when resolving is done. You can call SourceResolver::cancel to - stop the previous load operation if there is any. -*/ - -SourceResolver::SourceResolver(QObject *parent) - : QObject(parent) - , m_cRef(1) - , m_cancelCookie(0) - , m_sourceResolver(0) - , m_mediaSource(0) - , m_stream(0) -{ -} - -SourceResolver::~SourceResolver() -{ - shutdown(); - if (m_cancelCookie) - m_cancelCookie->Release(); - if (m_sourceResolver) - m_sourceResolver->Release(); -} - -STDMETHODIMP SourceResolver::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else if (riid == IID_IMFAsyncCallback) { - *ppvObject = static_cast<IMFAsyncCallback*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) SourceResolver::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) SourceResolver::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - this->deleteLater(); - return cRef; -} - -HRESULT STDMETHODCALLTYPE SourceResolver::Invoke(IMFAsyncResult *pAsyncResult) -{ - QMutexLocker locker(&m_mutex); - MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; - IUnknown* pSource = NULL; - State *state = static_cast<State*>(pAsyncResult->GetStateNoAddRef()); - - HRESULT hr = S_OK; - if (state->fromStream()) - hr = m_sourceResolver->EndCreateObjectFromByteStream(pAsyncResult, &ObjectType, &pSource); - else - hr = m_sourceResolver->EndCreateObjectFromURL(pAsyncResult, &ObjectType, &pSource); - - if (state->sourceResolver() != m_sourceResolver) { - //This is a cancelled one - return S_OK; - } - - if (m_cancelCookie) { - m_cancelCookie->Release(); - m_cancelCookie = NULL; - } - - if (FAILED(hr)) { - emit error(hr); - return S_OK; - } - - if (m_mediaSource) { - m_mediaSource->Release(); - m_mediaSource = NULL; - } - - hr = pSource->QueryInterface(IID_PPV_ARGS(&m_mediaSource)); - if (FAILED(hr)) { - emit error(hr); - return S_OK; - } - - emit mediaSourceReady(); - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE SourceResolver::GetParameters(DWORD*, DWORD*) -{ - return E_NOTIMPL; -} - -void SourceResolver::load(QMediaResourceList& resources, QIODevice* stream) -{ - QMutexLocker locker(&m_mutex); - HRESULT hr = S_OK; - if (!m_sourceResolver) - hr = MFCreateSourceResolver(&m_sourceResolver); - - if (m_stream) { - m_stream->Release(); - m_stream = NULL; - } - - if (FAILED(hr)) { - qWarning() << "Failed to create Source Resolver!"; - emit error(hr); - } else if (stream) { - if (resources.count() > 0) { - QMediaResource resource = resources.takeFirst(); - QUrl url = resource.url(); - m_stream = new MFStream(stream, false); - hr = m_sourceResolver->BeginCreateObjectFromByteStream(m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE, NULL, &m_cancelCookie, this, new State(m_sourceResolver, true)); - if (FAILED(hr)) { - qWarning() << "Unsupported stream!"; - emit error(hr); - } - } else { - hr = MF_E_UNSUPPORTED_BYTESTREAM_TYPE; - qWarning() << "Can't load stream without a hint of MIME type in a url"; - emit error(hr); - } - } else { - QMediaResource resource = resources.takeFirst(); - QUrl url = resource.url(); -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "loading :" << url; - qDebug() << "url path =" << url.path().mid(1); -#endif -#ifdef TEST_STREAMING - //Testing stream function - if (url.scheme() == QLatin1String("file")) { - stream = new QFile(url.path().mid(1), this); - if (stream->open(QIODevice::ReadOnly)) { - m_stream = new MFStream(stream, true); - hr = m_sourceResolver->BeginCreateObjectFromByteStream(m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE, NULL, &m_cancelCookie, this, new State(m_sourceResolver, true)); - if (FAILED(hr)) { - qWarning() << "Unsupported stream!"; - emit error(hr); - } - } else { - delete stream; - emit error(QMediaPlayer::FormatError); - } - } else -#endif - if (url.scheme() == QLatin1String("qrc")) { - // If the canonical URL refers to a Qt resource, open with QFile and use - // the stream playback capability to play. - stream = new QFile(QLatin1Char(':') + url.path(), this); - if (stream->open(QIODevice::ReadOnly)) { - m_stream = new MFStream(stream, true); - hr = m_sourceResolver->BeginCreateObjectFromByteStream(m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE, NULL, &m_cancelCookie, this, new State(m_sourceResolver, true)); - if (FAILED(hr)) { - qWarning() << "Unsupported stream!"; - emit error(hr); - } - } else { - delete stream; - emit error(QMediaPlayer::FormatError); - } - } else { - hr = m_sourceResolver->BeginCreateObjectFromURL(reinterpret_cast<const OLECHAR *>(url.toString().utf16()), - MF_RESOLUTION_MEDIASOURCE, NULL, &m_cancelCookie, this, new State(m_sourceResolver, false)); - if (FAILED(hr)) { - qWarning() << "Unsupported url scheme!"; - emit error(hr); - } - } - } -} - -void SourceResolver::cancel() -{ - QMutexLocker locker(&m_mutex); - if (m_cancelCookie) { - m_sourceResolver->CancelObjectCreation(m_cancelCookie); - m_cancelCookie->Release(); - m_cancelCookie = NULL; - m_sourceResolver->Release(); - m_sourceResolver = NULL; - } -} - -void SourceResolver::shutdown() -{ - if (m_mediaSource) { - m_mediaSource->Shutdown(); - m_mediaSource->Release(); - m_mediaSource = NULL; - } - - if (m_stream) { - m_stream->Release(); - m_stream = NULL; - } -} - -IMFMediaSource* SourceResolver::mediaSource() const -{ - return m_mediaSource; -} - -///////////////////////////////////////////////////////////////////////////////// -SourceResolver::State::State(IMFSourceResolver *sourceResolver, bool fromStream) - : m_cRef(1) - , m_sourceResolver(sourceResolver) - , m_fromStream(fromStream) -{ - sourceResolver->AddRef(); -} - -SourceResolver::State::~State() -{ - m_sourceResolver->Release(); -} - -STDMETHODIMP SourceResolver::State::QueryInterface(REFIID riid, LPVOID *ppvObject) -{ - if (!ppvObject) - return E_POINTER; - if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -STDMETHODIMP_(ULONG) SourceResolver::State::AddRef(void) -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) SourceResolver::State::Release(void) -{ - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - delete this; - // For thread safety, return a temporary variable. - return cRef; -} - -IMFSourceResolver* SourceResolver::State::sourceResolver() const -{ - return m_sourceResolver; -} - -bool SourceResolver::State::fromStream() const -{ - return m_fromStream; -} - diff --git a/src/plugins/wmf/player/sourceresolver.h b/src/plugins/wmf/player/sourceresolver.h deleted file mode 100644 index 18eb737..0000000 --- a/src/plugins/wmf/player/sourceresolver.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SOURCERESOLVER_H -#define SOURCERESOLVER_H - -#include "mfstream.h" -#include "qmediaresource.h" - -class SourceResolver: public QObject, public IMFAsyncCallback -{ - Q_OBJECT -public: - SourceResolver(QObject *parent); - - ~SourceResolver(); - - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - - HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult *pAsyncResult); - - HRESULT STDMETHODCALLTYPE GetParameters(DWORD*, DWORD*); - - void load(QMediaResourceList& resources, QIODevice* stream); - - void cancel(); - - void shutdown(); - - IMFMediaSource* mediaSource() const; - -Q_SIGNALS: - void error(long hr); - void mediaSourceReady(); - -private: - class State : public IUnknown - { - public: - State(IMFSourceResolver *sourceResolver, bool fromStream); - ~State(); - - STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); - - STDMETHODIMP_(ULONG) AddRef(void); - - STDMETHODIMP_(ULONG) Release(void); - - IMFSourceResolver* sourceResolver() const; - bool fromStream() const; - - private: - long m_cRef; - IMFSourceResolver *m_sourceResolver; - bool m_fromStream; - }; - - long m_cRef; - IUnknown *m_cancelCookie; - IMFSourceResolver *m_sourceResolver; - IMFMediaSource *m_mediaSource; - MFStream *m_stream; - QMutex m_mutex; -}; - -#endif diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro deleted file mode 100644 index d0b4ec3..0000000 --- a/src/plugins/wmf/wmf.pro +++ /dev/null @@ -1,16 +0,0 @@ -load(qt_module) - -TARGET = wmfengine -QT += multimedia-private network multimediawidgets-private -PLUGIN_TYPE=mediaservice - -load(qt_plugin) - -DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} - -DEPENDPATH += . - -HEADERS += wmfserviceplugin.h -SOURCES += wmfserviceplugin.cpp - -include (player/player.pri) diff --git a/src/plugins/wmf/wmfserviceplugin.cpp b/src/plugins/wmf/wmfserviceplugin.cpp deleted file mode 100644 index ccc4ada..0000000 --- a/src/plugins/wmf/wmfserviceplugin.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QFile> - -#include "wmfserviceplugin.h" -#ifdef QMEDIA_MEDIAFOUNDATION_PLAYER -#include "mfplayerservice.h" -#endif -#include <qmediaserviceprovider.h> - -QStringList WMFServicePlugin::keys() const -{ - return QStringList() -#ifdef QMEDIA_MEDIAFOUNDATION_PLAYER - << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) -#endif - ; -} - -QMediaService* WMFServicePlugin::create(QString const& key) -{ -#ifdef QMEDIA_MEDIAFOUNDATION_PLAYER - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) - return new MFPlayerService; -#endif - - //qDebug() << "unsupported key:" << key; - return 0; -} - -void WMFServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QMediaServiceProviderHint::Features WMFServicePlugin::supportedFeatures( - const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_MEDIAPLAYER) - return QMediaServiceProviderHint::StreamPlayback; - else - return QMediaServiceProviderHint::Features(); -} - -QList<QByteArray> WMFServicePlugin::devices(const QByteArray &service) const -{ - return QList<QByteArray>(); -} - -QString WMFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) -{ - return QString(); -} - -Q_EXPORT_PLUGIN2(qtmedia_wmfengine, WMFServicePlugin); - diff --git a/src/plugins/wmf/wmfserviceplugin.h b/src/plugins/wmf/wmfserviceplugin.h deleted file mode 100644 index 9bcffaf..0000000 --- a/src/plugins/wmf/wmfserviceplugin.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WMFSERVICEPLUGIN_H -#define WMFSERVICEPLUGIN_H - -#include "qmediaserviceproviderplugin.h" - -QT_USE_NAMESPACE - -class WMFServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedDevicesInterface - , public QMediaServiceFeaturesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_INTERFACES(QMediaServiceFeaturesInterface) -public: - QStringList keys() const; - QMediaService* create(QString const& key); - void release(QMediaService *service); - - QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const; - - QList<QByteArray> devices(const QByteArray &service) const; - QString deviceDescription(const QByteArray &service, const QByteArray &device); -}; - -#endif // DSSERVICEPLUGIN_H |