diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-03-23 16:18:01 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-04-06 08:12:08 +0000 |
commit | 02a837e71919642afac08478f6aee1eafdb94aaa (patch) | |
tree | 0a8f68c5c5e604d7e18d902374b0ddaa2d5c672c | |
parent | 2f018aad29cebe4b4db3f69ff2d5e11f8ba2cad2 (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>
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; }; |