summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-03-23 16:18:01 +0100
committerLars Knoll <lars.knoll@qt.io>2021-04-06 08:12:08 +0000
commit02a837e71919642afac08478f6aee1eafdb94aaa (patch)
tree0a8f68c5c5e604d7e18d902374b0ddaa2d5c672c
parent2f018aad29cebe4b4db3f69ff2d5e11f8ba2cad2 (diff)
Fix video playback on Windows
Adjust to the output architecture changes. Things compile and windowed playback does work again. Textured and SW playback will require more work. Change-Id: Iab433c0821167c7c7de2e5c41330e922313327af Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Doris Verria <doris.verria@qt.io>
-rw-r--r--src/imports/multimedia/qmldir1
-rw-r--r--src/multimedia/platform/qplatformvideosink.cpp6
-rw-r--r--src/multimedia/platform/windows/evr/evrcustompresenter.cpp65
-rw-r--r--src/multimedia/platform/windows/evr/evrcustompresenter_p.h7
-rw-r--r--src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp9
-rw-r--r--src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h1
-rw-r--r--src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp11
-rw-r--r--src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h2
-rw-r--r--src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp2
-rw-r--r--src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h2
-rw-r--r--src/multimedia/platform/windows/player/mfplayercontrol.cpp4
-rw-r--r--src/multimedia/platform/windows/player/mfplayercontrol_p.h2
-rw-r--r--src/multimedia/platform/windows/player/mfplayersession.cpp4
-rw-r--r--src/multimedia/platform/windows/player/mfplayersession_p.h2
-rw-r--r--src/multimedia/platform/windows/player/mftvideo.cpp3
-rw-r--r--src/multimedia/platform/windows/player/mftvideo_p.h1
-rw-r--r--src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp177
-rw-r--r--src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h15
-rw-r--r--src/multimedia/platform/windows/qwindowsintegration.cpp6
-rw-r--r--src/multimedia/platform/windows/qwindowsintegration_p.h2
20 files changed, 91 insertions, 231 deletions
diff --git a/src/imports/multimedia/qmldir b/src/imports/multimedia/qmldir
index e7dcc3dd6..48cdb0c8c 100644
--- a/src/imports/multimedia/qmldir
+++ b/src/imports/multimedia/qmldir
@@ -2,6 +2,7 @@ module QtMultimedia
plugin declarative_multimedia
classname QMultimediaDeclarativeModule
typeinfo plugins.qmltypes
+prefer :/qt-project.org/imports/QtMultimedia/
typeinfo plugins.qmltypes
Video 5.0 Video.qml
diff --git a/src/multimedia/platform/qplatformvideosink.cpp b/src/multimedia/platform/qplatformvideosink.cpp
index a57350372..f1ec3dcbc 100644
--- a/src/multimedia/platform/qplatformvideosink.cpp
+++ b/src/multimedia/platform/qplatformvideosink.cpp
@@ -110,12 +110,6 @@ QPlatformVideoSink::QPlatformVideoSink(QVideoSink *parent)
*/
/*!
- \fn QPlatformVideoSink::fullScreenChanged(bool fullScreen)
-
- Signals that the \a fullScreen state of a video overlay has changed.
-*/
-
-/*!
\fn QPlatformVideoSink::repaint()
Repaints the last frame.
diff --git a/src/multimedia/platform/windows/evr/evrcustompresenter.cpp b/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
index f23debc81..c43382ed6 100644
--- a/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
+++ b/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
@@ -540,7 +540,7 @@ HRESULT SamplePool::clear()
}
-EVRCustomPresenter::EVRCustomPresenter(QAbstractVideoSurface *surface)
+EVRCustomPresenter::EVRCustomPresenter(QVideoSink *sink)
: QObject()
, m_sampleFreeCB(this, &EVRCustomPresenter::onSampleFree)
, m_refCount(1)
@@ -557,7 +557,7 @@ EVRCustomPresenter::EVRCustomPresenter(QAbstractVideoSurface *surface)
, m_mixer(0)
, m_mediaEventSink(0)
, m_mediaType(0)
- , m_surface(0)
+ , m_videoSink(0)
, m_canRenderToSurface(false)
, m_positionOffset(0)
{
@@ -567,7 +567,7 @@ EVRCustomPresenter::EVRCustomPresenter(QAbstractVideoSurface *surface)
m_sourceRect.bottom = 1;
m_sourceRect.right = 1;
- setSurface(surface);
+ setSink(sink);
}
EVRCustomPresenter::~EVRCustomPresenter()
@@ -1025,14 +1025,14 @@ void EVRCustomPresenter::supportedFormatsChanged()
m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, false);
// check if we can render to the surface (compatible formats)
- if (m_surface) {
- QList<QVideoSurfaceFormat::PixelFormat> formats = m_surface->supportedPixelFormats(QVideoFrame::GLTextureHandle);
- if (m_presentEngine->supportsTextureRendering() && formats.contains(QVideoSurfaceFormat::Format_RGB32)) {
+ if (m_videoSink) {
+ if (m_presentEngine->supportsTextureRendering() && m_videoSink->graphicsType() == QVideoSink::OpenGL) {
m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, true);
m_canRenderToSurface = true;
} else {
- formats = m_surface->supportedPixelFormats(QVideoFrame::NoHandle);
- for (QVideoSurfaceFormat::PixelFormat format : qAsConst(formats)) {
+ for (int f = 0; f < QVideoSurfaceFormat::NPixelFormats; ++f) {
+ // ### set a better preference order
+ QVideoSurfaceFormat::PixelFormat format = QVideoSurfaceFormat::PixelFormat(f);
if (SUCCEEDED(m_presentEngine->checkFormat(qt_evr_D3DFormatFromPixelFormat(format)))) {
m_canRenderToSurface = true;
break;
@@ -1044,22 +1044,10 @@ void EVRCustomPresenter::supportedFormatsChanged()
// TODO: if media type already set, renegotiate?
}
-void EVRCustomPresenter::setSurface(QAbstractVideoSurface *surface)
+void EVRCustomPresenter::setSink(QVideoSink *sink)
{
m_mutex.lock();
-
- if (m_surface) {
- disconnect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged,
- this, &EVRCustomPresenter::supportedFormatsChanged);
- }
-
- m_surface = surface;
-
- if (m_surface) {
- connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged,
- this, &EVRCustomPresenter::supportedFormatsChanged);
- }
-
+ m_videoSink = sink;
m_mutex.unlock();
supportedFormatsChanged();
@@ -1146,7 +1134,7 @@ HRESULT EVRCustomPresenter::flush()
sample->Release();
m_frameStep.samples.clear();
- if (m_renderState == RenderStopped && m_surface && m_surface->isActive()) {
+ if (m_renderState == RenderStopped && m_videoSink) {
// Repaint with black.
presentSample(NULL);
}
@@ -1483,13 +1471,6 @@ HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed)
if (pixelFormat == QVideoSurfaceFormat::Format_Invalid)
return MF_E_INVALIDMEDIATYPE;
- // When not rendering to texture, only accept pixel formats supported by the video surface
- if (!m_presentEngine->isTextureRenderingEnabled()
- && m_surface
- && !m_surface->supportedPixelFormats().contains(pixelFormat)) {
- return MF_E_INVALIDMEDIATYPE;
- }
-
// Reject compressed media types.
hr = proposed->IsCompressedFormat(&compressed);
if (FAILED(hr))
@@ -1899,15 +1880,6 @@ void EVRCustomPresenter::startSurface()
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StartSurface)));
return;
}
-
- if (!m_surface || m_surface->isActive())
- return;
-
- QVideoSurfaceFormat format = m_presentEngine->videoSurfaceFormat();
- if (!format.isValid())
- return;
-
- m_surface->start(format);
}
void EVRCustomPresenter::stopSurface()
@@ -1916,11 +1888,6 @@ void EVRCustomPresenter::stopSurface()
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StopSurface)));
return;
}
-
- if (!m_surface || !m_surface->isActive())
- return;
-
- m_surface->stop();
}
void EVRCustomPresenter::presentSample(IMFSample *sample)
@@ -1930,7 +1897,7 @@ void EVRCustomPresenter::presentSample(IMFSample *sample)
return;
}
- if (!m_surface || !m_presentEngine->videoSurfaceFormat().isValid())
+ if (!m_videoSink || !m_presentEngine->videoSurfaceFormat().isValid())
return;
QVideoFrame frame = m_presentEngine->makeVideoFrame(sample);
@@ -1944,13 +1911,7 @@ void EVRCustomPresenter::presentSample(IMFSample *sample)
frame.setEndTime(frame.endTime() + m_positionOffset);
}
- if (!m_surface->isActive() || m_surface->surfaceFormat() != m_presentEngine->videoSurfaceFormat()) {
- m_surface->stop();
- if (!m_surface->start(m_presentEngine->videoSurfaceFormat()))
- return;
- }
-
- m_surface->present(frame);
+ m_videoSink->newVideoFrame(frame);
}
void EVRCustomPresenter::positionChanged(qint64 position)
diff --git a/src/multimedia/platform/windows/evr/evrcustompresenter_p.h b/src/multimedia/platform/windows/evr/evrcustompresenter_p.h
index d60bc4d4c..70a27d6a8 100644
--- a/src/multimedia/platform/windows/evr/evrcustompresenter_p.h
+++ b/src/multimedia/platform/windows/evr/evrcustompresenter_p.h
@@ -56,6 +56,7 @@
#include <qqueue.h>
#include <qevent.h>
#include <qvideosurfaceformat.h>
+#include <qvideosink.h>
#include "evrdefs_p.h"
@@ -230,7 +231,7 @@ public:
PresentSample = QEvent::User + 2
};
- EVRCustomPresenter(QAbstractVideoSurface *surface = 0);
+ EVRCustomPresenter(QVideoSink *sink = 0);
~EVRCustomPresenter() override;
bool isValid() const;
@@ -267,7 +268,7 @@ public:
STDMETHODIMP ReleaseServicePointers() override;
void supportedFormatsChanged();
- void setSurface(QAbstractVideoSurface *surface);
+ void setSink(QVideoSink *sink);
void startSurface();
void stopSurface();
@@ -376,7 +377,7 @@ private:
IMediaEventSink *m_mediaEventSink; // The EVR's event-sink interface.
IMFMediaType *m_mediaType; // Output media type
- QAbstractVideoSurface *m_surface;
+ QVideoSink *m_videoSink;
bool m_canRenderToSurface;
qint64 m_positionOffset; // Seek position in microseconds.
};
diff --git a/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp b/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
index afbbbcb3a..39d202fe0 100644
--- a/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
+++ b/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
@@ -370,9 +370,7 @@ done:
if (SUCCEEDED(hr)) {
m_surfaceFormat = QVideoSurfaceFormat(QSize(width, height),
m_useTextureRendering ? QVideoSurfaceFormat::Format_RGB32
- : qt_evr_pixelFormatFromD3DFormat(d3dFormat),
- m_useTextureRendering ? QVideoFrame::GLTextureHandle
- : QVideoFrame::NoHandle);
+ : qt_evr_pixelFormatFromD3DFormat(d3dFormat));
} else {
releaseResources();
}
@@ -387,9 +385,8 @@ QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample)
if (!sample)
return QVideoFrame();
- QVideoFrame frame(new IMFSampleVideoBuffer(this, sample, m_surfaceFormat.handleType()),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
+ QVideoFrame frame(new IMFSampleVideoBuffer(this, sample, (m_useTextureRendering ? QVideoFrame::GLTextureHandle : QVideoFrame::NoHandle)),
+ m_surfaceFormat);
// WMF uses 100-nanosecond units, Qt uses microseconds
LONGLONG startTime = 0;
diff --git a/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h b/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
index 1e70feadb..8d5f91c8f 100644
--- a/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
+++ b/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
@@ -63,6 +63,7 @@ struct IDirect3DSurface9;
struct IDirect3DTexture9;
struct IMFSample;
struct IMFMediaType;
+class QVideoFrame;
// Randomly generated GUIDs
static const GUID MFSamplePresenter_SampleCounter =
diff --git a/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp b/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp
index 49e8d68e7..00f29793a 100644
--- a/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp
+++ b/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp
@@ -39,7 +39,7 @@
#include "evrvideowindowcontrol_p.h"
-EvrVideoWindowControl::EvrVideoWindowControl(QObject *parent)
+EvrVideoWindowControl::EvrVideoWindowControl(QVideoSink *parent)
: QPlatformVideoSink(parent)
, m_windowId(0)
, m_windowColor(RGB(0, 0, 0))
@@ -161,7 +161,6 @@ void EvrVideoWindowControl::setFullScreen(bool fullScreen)
{
if (m_fullScreen == fullScreen)
return;
- emit fullScreenChanged(m_fullScreen = fullScreen);
}
void EvrVideoWindowControl::repaint()
@@ -249,8 +248,6 @@ void EvrVideoWindowControl::setBrightness(int brightness)
m_dirtyValues |= DXVA2_ProcAmp_Brightness;
applyImageControls();
-
- emit brightnessChanged(brightness);
}
int EvrVideoWindowControl::contrast() const
@@ -268,8 +265,6 @@ void EvrVideoWindowControl::setContrast(int contrast)
m_dirtyValues |= DXVA2_ProcAmp_Contrast;
applyImageControls();
-
- emit contrastChanged(contrast);
}
int EvrVideoWindowControl::hue() const
@@ -287,8 +282,6 @@ void EvrVideoWindowControl::setHue(int hue)
m_dirtyValues |= DXVA2_ProcAmp_Hue;
applyImageControls();
-
- emit hueChanged(hue);
}
int EvrVideoWindowControl::saturation() const
@@ -306,8 +299,6 @@ void EvrVideoWindowControl::setSaturation(int saturation)
m_dirtyValues |= DXVA2_ProcAmp_Saturation;
applyImageControls();
-
- emit saturationChanged(saturation);
}
void EvrVideoWindowControl::applyImageControls()
diff --git a/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h b/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h
index 276476475..0d829398f 100644
--- a/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h
+++ b/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h
@@ -61,7 +61,7 @@ class EvrVideoWindowControl : public QPlatformVideoSink
{
Q_OBJECT
public:
- EvrVideoWindowControl(QObject *parent = 0);
+ EvrVideoWindowControl(QVideoSink *parent = 0);
~EvrVideoWindowControl() override;
bool setEvr(IUnknown *evr);
diff --git a/src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp b/src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp
index 24c176c24..105424253 100644
--- a/src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp
+++ b/src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp
@@ -41,7 +41,7 @@
#include <qdebug.h>
-MFEvrVideoWindowControl::MFEvrVideoWindowControl(QObject *parent)
+MFEvrVideoWindowControl::MFEvrVideoWindowControl(QVideoSink *parent)
: EvrVideoWindowControl(parent)
, m_currentActivate(NULL)
, m_evrSink(NULL)
diff --git a/src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h b/src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h
index c74148431..2f9d867d6 100644
--- a/src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h
+++ b/src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h
@@ -58,7 +58,7 @@ QT_USE_NAMESPACE
class MFEvrVideoWindowControl : public EvrVideoWindowControl
{
public:
- MFEvrVideoWindowControl(QObject *parent = 0);
+ MFEvrVideoWindowControl(QVideoSink *parent = 0);
~MFEvrVideoWindowControl();
IMFActivate* createActivate();
diff --git a/src/multimedia/platform/windows/player/mfplayercontrol.cpp b/src/multimedia/platform/windows/player/mfplayercontrol.cpp
index d14494f6a..f9797c3d7 100644
--- a/src/multimedia/platform/windows/player/mfplayercontrol.cpp
+++ b/src/multimedia/platform/windows/player/mfplayercontrol.cpp
@@ -136,9 +136,9 @@ QAudioDeviceInfo MFPlayerControl::audioOutput() const
return m_session->audioOutput();
}
-void MFPlayerControl::setVideoSurface(QAbstractVideoSurface *surface)
+void MFPlayerControl::setVideoSink(QVideoSink *sink)
{
- m_session->setVideoSurface(surface);
+ m_session->setVideoSink(sink);
}
void MFPlayerControl::changeState(QMediaPlayer::State state)
diff --git a/src/multimedia/platform/windows/player/mfplayercontrol_p.h b/src/multimedia/platform/windows/player/mfplayercontrol_p.h
index 834b63537..d3659cf93 100644
--- a/src/multimedia/platform/windows/player/mfplayercontrol_p.h
+++ b/src/multimedia/platform/windows/player/mfplayercontrol_p.h
@@ -108,7 +108,7 @@ public:
bool setAudioOutput(const QAudioDeviceInfo &) override;
QAudioDeviceInfo audioOutput() const override;
- void setVideoSurface(QAbstractVideoSurface *surface) override;
+ void setVideoSink(QVideoSink *sink) override;
void handleStatusChanged();
void handleVideoAvailable();
diff --git a/src/multimedia/platform/windows/player/mfplayersession.cpp b/src/multimedia/platform/windows/player/mfplayersession.cpp
index 36857b452..3ce531ddb 100644
--- a/src/multimedia/platform/windows/player/mfplayersession.cpp
+++ b/src/multimedia/platform/windows/player/mfplayersession.cpp
@@ -1829,7 +1829,7 @@ bool MFPlayerSession::setAudioOutput(const QAudioDeviceInfo &device)
return true;
}
-void MFPlayerSession::setVideoSurface(QAbstractVideoSurface *surface)
+void MFPlayerSession::setVideoSink(QVideoSink *sink)
{
- m_videoRendererControl->setSurface(surface);
+ m_videoRendererControl->setSink(sink);
}
diff --git a/src/multimedia/platform/windows/player/mfplayersession_p.h b/src/multimedia/platform/windows/player/mfplayersession_p.h
index 6f98114a1..08aaf577e 100644
--- a/src/multimedia/platform/windows/player/mfplayersession_p.h
+++ b/src/multimedia/platform/windows/player/mfplayersession_p.h
@@ -128,7 +128,7 @@ public:
QMediaMetaData metaData() const { return m_metaData; }
- void setVideoSurface(QAbstractVideoSurface *surface);
+ void setVideoSink(QVideoSink *sink);
void statusChanged() { m_playerControl->handleStatusChanged(); }
void audioAvailable() { m_playerControl->handleAudioAvailable(); }
diff --git a/src/multimedia/platform/windows/player/mftvideo.cpp b/src/multimedia/platform/windows/player/mftvideo.cpp
index c97c479d6..d271ccf7d 100644
--- a/src/multimedia/platform/windows/player/mftvideo.cpp
+++ b/src/multimedia/platform/windows/player/mftvideo.cpp
@@ -654,6 +654,7 @@ QVideoSurfaceFormat MFTransform::videoFormatForMFMediaType(IMFMediaType *mediaTy
QVideoSurfaceFormat::PixelFormat pixelFormat = formatFromSubtype(subtype);
QVideoSurfaceFormat format(size, pixelFormat);
+ quint32 num, den;
if (SUCCEEDED(MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE, &num, &den))) {
format.setFrameRate(qreal(num)/den);
}
@@ -682,7 +683,7 @@ QVideoFrame MFTransform::makeVideoFrame()
// IMFSample for a "long" time without affecting the rest of the topology.
// If IMFSample is held for more than 5 frames decoder starts to reuse it even though it hasn't been released it yet.
// That is why we copy data from IMFMediaBuffer here.
- frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format.frameSize(), m_format.pixelFormat());
+ frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format);
// WMF uses 100-nanosecond units, Qt uses microseconds
LONGLONG startTime = -1;
diff --git a/src/multimedia/platform/windows/player/mftvideo_p.h b/src/multimedia/platform/windows/player/mftvideo_p.h
index 26f12b889..548c9ba6a 100644
--- a/src/multimedia/platform/windows/player/mftvideo_p.h
+++ b/src/multimedia/platform/windows/player/mftvideo_p.h
@@ -60,6 +60,7 @@
QT_USE_NAMESPACE
class MFVideoProbeControl;
+class QVideoFrame;
class MFTransform: public IMFTransform
{
diff --git a/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp b/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
index 5a7ff6d2b..b9ea1dbb1 100644
--- a/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
+++ b/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
@@ -43,6 +43,7 @@
#include "evrcustompresenter_p.h"
#include <private/qabstractvideobuffer_p.h>
+#include <qvideosink.h>
#include <qvideosurfaceformat.h>
#include <qtcore/qtimer.h>
#include <qtcore/qmutex.h>
@@ -242,7 +243,7 @@ namespace
: m_cRef(1)
, m_eventQueue(0)
, m_shutdown(false)
- , m_surface(0)
+ , m_videoSink(0)
, m_state(State_TypeNotSet)
, m_currentFormatIndex(-1)
, m_bytesPerLine(0)
@@ -622,10 +623,10 @@ namespace
}
//
- void setSurface(QAbstractVideoSurface *surface)
+ void setSink(QVideoSink *sink)
{
m_mutex.lock();
- m_surface = surface;
+ m_videoSink = sink;
m_mutex.unlock();
supportedFormatsChanged();
}
@@ -789,10 +790,10 @@ namespace
QMutexLocker locker(&m_mutex);
m_pixelFormats.clear();
clearMediaTypes();
- if (!m_surface)
+ if (!m_videoSink)
return;
- const QList<QVideoSurfaceFormat::PixelFormat> formats = m_surface->supportedPixelFormats();
- for (QVideoSurfaceFormat::PixelFormat format : formats) {
+ for (int f = 0; f < QVideoSurfaceFormat::NPixelFormats; ++f) {
+ QVideoSurfaceFormat::PixelFormat format = QVideoSurfaceFormat::PixelFormat(f);
IMFMediaType *mediaType;
if (FAILED(MFCreateMediaType(&mediaType))) {
qWarning("Failed to create mf media type!");
@@ -853,12 +854,10 @@ namespace
if (!m_scheduledBuffer)
return;
QVideoFrame frame = QVideoFrame(
- new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
+ new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine), m_surfaceFormat);
frame.setStartTime(m_bufferStartTime * 0.1);
frame.setEndTime((m_bufferStartTime + m_bufferDuration) * 0.1);
- m_surface->present(frame);
+ m_videoSink->newVideoFrame(frame);
m_scheduledBuffer->Release();
m_scheduledBuffer = NULL;
if (m_rate != 0)
@@ -877,9 +876,6 @@ namespace
enum
{
- StartSurface = QEvent::User,
- StopSurface,
- FlushSurface,
PresentSurface
};
@@ -902,37 +898,9 @@ namespace
};
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,
@@ -1042,7 +1010,7 @@ namespace
int m_currentFormatIndex;
int m_bytesPerLine;
QVideoSurfaceFormat m_surfaceFormat;
- QAbstractVideoSurface* m_surface;
+ QVideoSink *m_videoSink;
MFVideoRendererControl *m_rendererControl;
void clearMediaTypes()
@@ -1121,22 +1089,7 @@ namespace
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;
- }
- }
-
- if (m_state == State_Started)
- schedulePresentation(true);
+ schedulePresentation(true);
case OpRestart:
endPreroll(S_FALSE);
if (SUCCEEDED(hr)) {
@@ -1158,14 +1111,6 @@ namespace
clearBufferCache();
// 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);
@@ -1494,20 +1439,12 @@ namespace
Q_ASSERT(m_shutdown);
}
- void setSurface(QAbstractVideoSurface *surface)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return;
- m_stream->setSurface(surface);
- }
-
- void supportedFormatsChanged()
+ void setSurface(QVideoSink *surface)
{
QMutexLocker locker(&m_mutex);
if (m_shutdown)
return;
- m_stream->supportedFormatsChanged();
+ m_stream->setSink(surface);
}
void present()
@@ -1867,7 +1804,7 @@ namespace
, m_sink(0)
, m_rendererControl(rendererControl)
, m_attributes(0)
- , m_surface(0)
+ , m_videoSink(0)
{
MFCreateAttributes(&m_attributes, 0);
m_sink = new MediaSink(rendererControl);
@@ -1919,8 +1856,8 @@ namespace
QMutexLocker locker(&m_mutex);
if (!m_sink) {
m_sink = new MediaSink(m_rendererControl);
- if (m_surface)
- m_sink->setSurface(m_surface);
+ if (m_videoSink)
+ m_sink->setSurface(m_videoSink);
}
return m_sink->QueryInterface(riid, ppv);
}
@@ -2161,25 +2098,17 @@ namespace
}
/////////////////////////////////
- void setSurface(QAbstractVideoSurface *surface)
+ void setSink(QVideoSink *sink)
{
QMutexLocker locker(&m_mutex);
- if (m_surface == surface)
+ if (m_videoSink == sink)
return;
- m_surface = surface;
-
- if (!m_sink)
- return;
- m_sink->setSurface(m_surface);
- }
+ m_videoSink = sink;
- void supportedFormatsChanged()
- {
- QMutexLocker locker(&m_mutex);
if (!m_sink)
return;
- m_sink->supportedFormatsChanged();
+ m_sink->setSurface(m_videoSink);
}
void present()
@@ -2218,7 +2147,7 @@ namespace
MediaSink *m_sink;
MFVideoRendererControl *m_rendererControl;
IMFAttributes *m_attributes;
- QAbstractVideoSurface *m_surface;
+ QVideoSink *m_videoSink;
QMutex m_mutex;
};
}
@@ -2235,21 +2164,17 @@ public:
STDMETHODIMP ShutdownObject();
STDMETHODIMP DetachObject();
- void setSurface(QAbstractVideoSurface *surface);
+ void setSink(QVideoSink *sink);
private:
EVRCustomPresenter *m_presenter;
- QAbstractVideoSurface *m_surface;
+ QVideoSink *m_videoSink;
QMutex m_mutex;
};
MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
: QObject(parent)
- , m_surface(0)
- , m_currentActivate(0)
- , m_callback(0)
- , m_presenterActivate(0)
{
}
@@ -2260,8 +2185,8 @@ MFVideoRendererControl::~MFVideoRendererControl()
void MFVideoRendererControl::clear()
{
- if (m_surface)
- m_surface->stop();
+ if (m_sink)
+ m_sink->newVideoFrame(QVideoFrame());
if (m_presenterActivate) {
m_presenterActivate->ShutdownObject();
@@ -2281,25 +2206,19 @@ void MFVideoRendererControl::releaseActivate()
clear();
}
-QAbstractVideoSurface *MFVideoRendererControl::surface() const
+QVideoSink *MFVideoRendererControl::sink() const
{
- return m_surface;
+ return m_sink;
}
-void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+void MFVideoRendererControl::setSink(QVideoSink *sink)
{
- 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()));
- }
+ m_sink = sink;
if (m_presenterActivate)
- m_presenterActivate->setSurface(m_surface);
+ m_presenterActivate->setSink(m_sink);
else if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
+ static_cast<VideoRendererActivate*>(m_currentActivate)->setSink(m_sink);
}
void MFVideoRendererControl::customEvent(QEvent *event)
@@ -2326,21 +2245,7 @@ void MFVideoRendererControl::customEvent(QEvent *event)
}
return;
}
- if (event->type() >= MediaStream::StartSurface) {
- QChildEvent *childEvent = static_cast<QChildEvent*>(event);
- static_cast<MediaStream*>(childEvent->child())->customEvent(event);
- } else {
- QObject::customEvent(event);
- }
-}
-
-void MFVideoRendererControl::supportedFormatsChanged()
-{
- if (m_presenterActivate)
- return;
-
- if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
+ QObject::customEvent(event);
}
void MFVideoRendererControl::present()
@@ -2354,7 +2259,7 @@ void MFVideoRendererControl::present()
IMFActivate* MFVideoRendererControl::createActivate()
{
- Q_ASSERT(m_surface);
+ Q_ASSERT(m_sink);
clear();
@@ -2366,7 +2271,7 @@ IMFActivate* MFVideoRendererControl::createActivate()
m_currentActivate = new VideoRendererActivate(this);
}
- setSurface(m_surface);
+ setSink(m_sink);
return m_currentActivate;
}
@@ -2375,7 +2280,7 @@ IMFActivate* MFVideoRendererControl::createActivate()
EVRCustomPresenterActivate::EVRCustomPresenterActivate()
: MFAbstractActivate()
, m_presenter(0)
- , m_surface(0)
+ , m_videoSink(0)
{ }
HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
@@ -2385,8 +2290,8 @@ HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
QMutexLocker locker(&m_mutex);
if (!m_presenter) {
m_presenter = new EVRCustomPresenter;
- if (m_surface)
- m_presenter->setSurface(m_surface);
+ if (m_videoSink)
+ m_presenter->setSink(m_videoSink);
}
return m_presenter->QueryInterface(riid, ppv);
}
@@ -2408,16 +2313,16 @@ HRESULT EVRCustomPresenterActivate::DetachObject()
return S_OK;
}
-void EVRCustomPresenterActivate::setSurface(QAbstractVideoSurface *surface)
+void EVRCustomPresenterActivate::setSink(QVideoSink *sink)
{
QMutexLocker locker(&m_mutex);
- if (m_surface == surface)
+ if (m_videoSink == sink)
return;
- m_surface = surface;
+ m_videoSink = sink;
if (m_presenter)
- m_presenter->setSurface(surface);
+ m_presenter->setSink(sink);
}
#include "moc_mfvideorenderercontrol_p.cpp"
diff --git a/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h b/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h
index ca80c6fba..fa6fd6c5c 100644
--- a/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h
+++ b/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h
@@ -58,7 +58,7 @@
QT_USE_NAMESPACE
class EVRCustomPresenterActivate;
-class QAbstractVideoSurface;
+class QVideoSink;
class MFVideoRendererControl : public QObject
{
@@ -67,8 +67,8 @@ public:
MFVideoRendererControl(QObject *parent = 0);
~MFVideoRendererControl();
- QAbstractVideoSurface *surface() const;
- void setSurface(QAbstractVideoSurface *surface);
+ QVideoSink *sink() const;
+ void setSink(QVideoSink *surface);
IMFActivate* createActivate();
void releaseActivate();
@@ -77,17 +77,16 @@ protected:
void customEvent(QEvent *event);
private Q_SLOTS:
- void supportedFormatsChanged();
void present();
private:
void clear();
- QAbstractVideoSurface *m_surface;
- IMFActivate *m_currentActivate;
- IMFSampleGrabberSinkCallback *m_callback;
+ QVideoSink *m_sink = nullptr;
+ IMFActivate *m_currentActivate = nullptr;
+ IMFSampleGrabberSinkCallback *m_callback = nullptr;
- EVRCustomPresenterActivate *m_presenterActivate;
+ EVRCustomPresenterActivate *m_presenterActivate = nullptr;
};
#endif
diff --git a/src/multimedia/platform/windows/qwindowsintegration.cpp b/src/multimedia/platform/windows/qwindowsintegration.cpp
index 6df750c82..4127a48bb 100644
--- a/src/multimedia/platform/windows/qwindowsintegration.cpp
+++ b/src/multimedia/platform/windows/qwindowsintegration.cpp
@@ -42,6 +42,7 @@
#include "qwindowsformatinfo_p.h"
#include <private/mfplayercontrol_p.h>
#include <private/mfaudiodecodercontrol_p.h>
+#include <private/mfevrvideowindowcontrol_p.h>
QT_BEGIN_NAMESPACE
@@ -93,4 +94,9 @@ QPlatformMediaPlayer *QWindowsIntegration::createPlayer(QMediaPlayer *parent)
return new MFPlayerControl(parent);
}
+QPlatformVideoSink *QWindowsIntegration::createVideoSink(QVideoSink *sink)
+{
+ return new MFEvrVideoWindowControl(sink);
+}
+
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/qwindowsintegration_p.h b/src/multimedia/platform/windows/qwindowsintegration_p.h
index 07407c2b6..378e4d050 100644
--- a/src/multimedia/platform/windows/qwindowsintegration_p.h
+++ b/src/multimedia/platform/windows/qwindowsintegration_p.h
@@ -73,6 +73,8 @@ public:
QPlatformAudioDecoder *createAudioDecoder() override;
QPlatformMediaPlayer *createPlayer(QMediaPlayer *parent) override;
+ QPlatformVideoSink *createVideoSink(QVideoSink *sink) override;
+
QWindowsDeviceManager *m_manager = nullptr;
QWindowsFormatInfo *m_formatInfo = nullptr;
};