diff options
Diffstat (limited to 'src/plugins')
95 files changed, 1245 insertions, 3950 deletions
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java index 7fb4a8690..b1da2f1fa 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java @@ -212,6 +212,11 @@ public class QtAndroidMediaPlayer mContext = context; } + public MediaPlayer getMediaPlayerHandle() + { + return mMediaPlayer; + } + private void setState(int state) { if (mState == state) diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index 7aa7b97b8..df1463a87 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -93,7 +93,9 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) mPendingVolume(-1), mPendingMute(-1), mReloadingMedia(false), - mActiveStateChangeNotifiers(0) + mActiveStateChangeNotifiers(0), + mPendingPlaybackRate(1.0), + mHasPendingPlaybackRate(false) { connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)), this,SLOT(onBufferingChanged(qint32))); @@ -290,12 +292,45 @@ void QAndroidMediaPlayerControl::updateAvailablePlaybackRanges() qreal QAndroidMediaPlayerControl::playbackRate() const { - return 1.0f; + if (mHasPendingPlaybackRate || + (mState & (AndroidMediaPlayer::Initialized + | AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted + | AndroidMediaPlayer::Error)) == 0) { + return mPendingPlaybackRate; + } + + return mMediaPlayer->playbackRate(); } void QAndroidMediaPlayerControl::setPlaybackRate(qreal rate) { - Q_UNUSED(rate); + if ((mState & (AndroidMediaPlayer::Initialized + | AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted + | AndroidMediaPlayer::Error)) == 0) { + if (mPendingPlaybackRate != rate) { + mPendingPlaybackRate = rate; + mHasPendingPlaybackRate = true; + Q_EMIT playbackRateChanged(rate); + } + return; + } + + bool succeeded = mMediaPlayer->setPlaybackRate(rate); + + if (mHasPendingPlaybackRate) { + mHasPendingPlaybackRate = false; + mPendingPlaybackRate = qreal(1.0); + if (!succeeded) + Q_EMIT playbackRateChanged(playbackRate()); + } else if (succeeded) { + Q_EMIT playbackRateChanged(rate); + } } QMediaContent QAndroidMediaPlayerControl::media() const @@ -720,6 +755,8 @@ void QAndroidMediaPlayerControl::flushPendingStates() setVolume(mPendingVolume); if (mPendingMute != -1) setMuted((mPendingMute == 1)); + if (mHasPendingPlaybackRate) + setPlaybackRate(mPendingPlaybackRate); switch (newState) { case QMediaPlayer::PlayingState: diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h index 04f728a59..119add7f8 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h @@ -117,6 +117,8 @@ private: int mPendingMute; bool mReloadingMedia; int mActiveStateChangeNotifiers; + qreal mPendingPlaybackRate; + bool mHasPendingPlaybackRate; // we need this because the rate can theoretically be negative void setState(QMediaPlayer::State state); void setMediaStatus(QMediaPlayer::MediaStatus status); diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp index 582d8aa9d..b81f98cbd 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp @@ -109,6 +109,33 @@ bool AndroidMediaPlayer::isMuted() return mMediaPlayer.callMethod<jboolean>("isMuted"); } +qreal AndroidMediaPlayer::playbackRate() +{ + qreal rate(1.0); + + if (QtAndroidPrivate::androidSdkVersion() < 23) + return rate; + + QJNIObjectPrivate player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle", "()Landroid/media/MediaPlayer;"); + if (player.isValid()) { + QJNIObjectPrivate playbackParams = player.callObjectMethod("getPlaybackParams", "()Landroid/media/PlaybackParams;"); + if (playbackParams.isValid()) { + const qreal speed = playbackParams.callMethod<jfloat>("getSpeed", "()F"); + QJNIEnvironmentPrivate env; + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif // QT_DEBUG + env->ExceptionClear(); + } else { + rate = speed; + } + } + } + + return rate; +} + jobject AndroidMediaPlayer::display() { return mMediaPlayer.callObjectMethod("display", "()Landroid/view/SurfaceHolder;").object(); @@ -155,6 +182,40 @@ void AndroidMediaPlayer::setVolume(int volume) mMediaPlayer.callMethod<void>("setVolume", "(I)V", jint(volume)); } +bool AndroidMediaPlayer::setPlaybackRate(qreal rate) +{ + if (QtAndroidPrivate::androidSdkVersion() < 23) { + qWarning("Setting the playback rate on a media player requires Android 6.0 (API level 23) or later"); + return false; + } + + QJNIEnvironmentPrivate env; + + QJNIObjectPrivate player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle", "()Landroid/media/MediaPlayer;"); + if (player.isValid()) { + QJNIObjectPrivate playbackParams = player.callObjectMethod("getPlaybackParams", "()Landroid/media/PlaybackParams;"); + if (playbackParams.isValid()) { + playbackParams.callObjectMethod("setSpeed", "(F)Landroid/media/PlaybackParams;", jfloat(rate)); + // pitch can only be > 0 + if (!qFuzzyIsNull(rate)) + playbackParams.callObjectMethod("setPitch", "(F)Landroid/media/PlaybackParams;", jfloat(qAbs(rate))); + player.callMethod<void>("setPlaybackParams", "(Landroid/media/PlaybackParams;)V", playbackParams.object()); + if (Q_UNLIKELY(env->ExceptionCheck())) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif // QT_DEBUG + env->ExceptionClear(); + qWarning() << "Invalid playback rate" << rate; + return false; + } else { + return true; + } + } + } + + return false; +} + void AndroidMediaPlayer::setDisplay(AndroidSurfaceTexture *surfaceTexture) { mMediaPlayer.callMethod<void>("setDisplay", diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h index 28bfa3662..a7284bb0c 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h @@ -103,6 +103,7 @@ public: bool isPlaying(); int volume(); bool isMuted(); + qreal playbackRate(); jobject display(); void play(); @@ -113,6 +114,7 @@ public: void setDataSource(const QString &path); void prepareAsync(); void setVolume(int volume); + bool setPlaybackRate(qreal rate); void setDisplay(AndroidSurfaceTexture *surfaceTexture); static bool initJNI(JNIEnv *env); diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp index b07dbe719..5ebde2dda 100644 --- a/src/plugins/common/evr/evrcustompresenter.cpp +++ b/src/plugins/common/evr/evrcustompresenter.cpp @@ -98,7 +98,7 @@ public: m_sample->AddRef(); } - ~PresentSampleEvent() + ~PresentSampleEvent() override { if (m_sample) m_sample->Release(); @@ -510,19 +510,16 @@ HRESULT SamplePool::initialize(QList<IMFSample*> &samples) if (m_initialized) return MF_E_INVALIDREQUEST; - IMFSample *sample = NULL; - // Move these samples into our allocated queue. - for (int i = 0; i < samples.size(); ++i) { - sample = samples.at(i); + for (auto sample : qAsConst(samples)) { sample->AddRef(); m_videoSampleQueue.append(sample); } m_initialized = true; - for (int i = 0; i < samples.size(); ++i) - samples[i]->Release(); + for (auto sample : qAsConst(samples)) + sample->Release(); samples.clear(); return S_OK; } @@ -531,8 +528,8 @@ HRESULT SamplePool::clear() { QMutexLocker locker(&m_mutex); - for (int i = 0; i < m_videoSampleQueue.size(); ++i) - m_videoSampleQueue[i]->Release(); + for (auto sample : qAsConst(m_videoSampleQueue)) + sample->Release(); m_videoSampleQueue.clear(); m_initialized = false; @@ -928,8 +925,8 @@ HRESULT EVRCustomPresenter::OnClockSetRate(MFTIME, float rate) // frame-step operation. if ((m_playbackRate == 0.0f) && (rate != 0.0f)) { cancelFrameStep(); - for (int i = 0; i < m_frameStep.samples.size(); ++i) - m_frameStep.samples[i]->Release(); + for (auto sample : qAsConst(m_frameStep.samples)) + sample->Release(); m_frameStep.samples.clear(); } @@ -1142,8 +1139,8 @@ HRESULT EVRCustomPresenter::flush() m_scheduler.flush(); // Flush the frame-step queue. - for (int i = 0; i < m_frameStep.samples.size(); ++i) - m_frameStep.samples[i]->Release(); + for (auto sample : qAsConst(m_frameStep.samples)) + sample->Release(); m_frameStep.samples.clear(); if (m_renderState == RenderStopped) { @@ -1365,18 +1362,21 @@ HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, I if (FAILED(hr)) goto done; - hr = mtOptimal->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&displayArea, sizeof(displayArea)); + hr = mtOptimal->SetBlob(MF_MT_GEOMETRIC_APERTURE, reinterpret_cast<UINT8*>(&displayArea), + sizeof(displayArea)); if (FAILED(hr)) goto done; // Set the pan/scan aperture and the minimum display aperture. We don't care // about them per se, but the mixer will reject the type if these exceed the // frame dimentions. - hr = mtOptimal->SetBlob(MF_MT_PAN_SCAN_APERTURE, (UINT8*)&displayArea, sizeof(displayArea)); + hr = mtOptimal->SetBlob(MF_MT_PAN_SCAN_APERTURE, reinterpret_cast<UINT8*>(&displayArea), + sizeof(displayArea)); if (FAILED(hr)) goto done; - hr = mtOptimal->SetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&displayArea, sizeof(displayArea)); + hr = mtOptimal->SetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, reinterpret_cast<UINT8*>(&displayArea), + sizeof(displayArea)); if (FAILED(hr)) goto done; @@ -1405,8 +1405,6 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType) MFRatio fps = { 0, 0 }; QList<IMFSample*> sampleQueue; - IMFSample *sample = NULL; - // Cannot set the media type after shutdown. HRESULT hr = checkShutdown(); if (FAILED(hr)) @@ -1430,9 +1428,7 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType) // Mark each sample with our token counter. If this batch of samples becomes // invalid, we increment the counter, so that we know they should be discarded. - for (int i = 0; i < sampleQueue.size(); ++i) { - sample = sampleQueue.at(i); - + for (auto sample : qAsConst(sampleQueue)) { hr = sample->SetUINT32(MFSamplePresenter_SampleCounter, m_tokenCounter); if (FAILED(hr)) goto done; @@ -1474,7 +1470,7 @@ HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed) UINT32 width = 0, height = 0; // Validate the format. - HRESULT hr = qt_evr_getFourCC(proposed, (DWORD*)&d3dFormat); + HRESULT hr = qt_evr_getFourCC(proposed, reinterpret_cast<DWORD*>(&d3dFormat)); if (FAILED(hr)) return hr; @@ -1503,7 +1499,7 @@ HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed) return hr; // Reject interlaced formats. - hr = proposed->GetUINT32(MF_MT_INTERLACE_MODE, (UINT32*)&interlaceMode); + hr = proposed->GetUINT32(MF_MT_INTERLACE_MODE, reinterpret_cast<UINT32*>(&interlaceMode)); if (FAILED(hr)) return hr; @@ -1518,15 +1514,21 @@ HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed) // Any of these apertures may be unspecified in the media type, in which case // we ignore it. We just want to reject invalid apertures. - if (SUCCEEDED(proposed->GetBlob(MF_MT_PAN_SCAN_APERTURE, (UINT8*)&videoCropArea, sizeof(videoCropArea), NULL))) + if (SUCCEEDED(proposed->GetBlob(MF_MT_PAN_SCAN_APERTURE, + reinterpret_cast<UINT8*>(&videoCropArea), + sizeof(videoCropArea), nullptr))) { hr = qt_evr_validateVideoArea(videoCropArea, width, height); - - if (SUCCEEDED(proposed->GetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&videoCropArea, sizeof(videoCropArea), NULL))) + } + if (SUCCEEDED(proposed->GetBlob(MF_MT_GEOMETRIC_APERTURE, + reinterpret_cast<UINT8*>(&videoCropArea), + sizeof(videoCropArea), nullptr))) { hr = qt_evr_validateVideoArea(videoCropArea, width, height); - - if (SUCCEEDED(proposed->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&videoCropArea, sizeof(videoCropArea), NULL))) + } + if (SUCCEEDED(proposed->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, + reinterpret_cast<UINT8*>(&videoCropArea), + sizeof(videoCropArea), nullptr))) { hr = qt_evr_validateVideoArea(videoCropArea, width, height); - + } return hr; } @@ -1580,12 +1582,10 @@ HRESULT EVRCustomPresenter::processOutput() // Try to get a free sample from the video sample pool. hr = m_samplePool.getSample(&sample); - if (hr == MF_E_SAMPLEALLOCATOR_EMPTY) { - // No free samples. Try again when a sample is released. + if (hr == MF_E_SAMPLEALLOCATOR_EMPTY) // No free samples. Try again when a sample is released. return S_FALSE; - } else if (FAILED(hr)) { + if (FAILED(hr)) return hr; - } // From now on, we have a valid video sample pointer, where the mixer will // write the video data. @@ -1642,7 +1642,7 @@ HRESULT EVRCustomPresenter::processOutput() m_clock->GetCorrelatedTime(0, &mixerEndTime, &systemTime); LONGLONG latencyTime = mixerEndTime - mixerStartTime; - notifyEvent(EC_PROCESSING_LATENCY, (LONG_PTR)&latencyTime, 0); + notifyEvent(EC_PROCESSING_LATENCY, reinterpret_cast<LONG_PTR>(&latencyTime), 0); } // Set up notification for when the sample is released. @@ -1734,7 +1734,7 @@ HRESULT EVRCustomPresenter::deliverFrameStepSample(IMFSample *sample) if (FAILED(hr)) goto done; - m_frameStep.sampleNoRef = (DWORD_PTR)unk; // No add-ref. + m_frameStep.sampleNoRef = reinterpret_cast<DWORD_PTR>(unk); // No add-ref. // NOTE: We do not AddRef the IUnknown pointer, because that would prevent the // sample from invoking the OnSampleFree callback after the sample is presented. @@ -1807,7 +1807,7 @@ HRESULT EVRCustomPresenter::onSampleFree(IMFAsyncResult *result) if (FAILED(hr)) goto done; - if (m_frameStep.sampleNoRef == (DWORD_PTR)unk) { + if (m_frameStep.sampleNoRef == reinterpret_cast<DWORD_PTR>(unk)) { // Notify the EVR. hr = completeFrameStep(sample); if (FAILED(hr)) @@ -1997,7 +1997,8 @@ HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect &sou HRESULT hr = mixer->GetAttributes(&attributes); if (SUCCEEDED(hr)) { - hr = attributes->SetBlob(video_ZOOM_RECT, (const UINT8*)&sourceRect, sizeof(sourceRect)); + hr = attributes->SetBlob(video_ZOOM_RECT, reinterpret_cast<const UINT8*>(&sourceRect), + sizeof(sourceRect)); attributes->Release(); } return hr; @@ -2017,23 +2018,23 @@ static QVideoFrame::PixelFormat pixelFormatFromMediaType(IMFMediaType *type) if (subtype == MFVideoFormat_RGB32) return QVideoFrame::Format_RGB32; - else if (subtype == MFVideoFormat_ARGB32) + if (subtype == MFVideoFormat_ARGB32) return QVideoFrame::Format_ARGB32; - else if (subtype == MFVideoFormat_RGB24) + if (subtype == MFVideoFormat_RGB24) return QVideoFrame::Format_RGB24; - else if (subtype == MFVideoFormat_RGB565) + if (subtype == MFVideoFormat_RGB565) return QVideoFrame::Format_RGB565; - else if (subtype == MFVideoFormat_RGB555) + if (subtype == MFVideoFormat_RGB555) return QVideoFrame::Format_RGB555; - else if (subtype == MFVideoFormat_AYUV) + if (subtype == MFVideoFormat_AYUV) return QVideoFrame::Format_AYUV444; - else if (subtype == MFVideoFormat_I420) + if (subtype == MFVideoFormat_I420) return QVideoFrame::Format_YUV420P; - else if (subtype == MFVideoFormat_UYVY) + if (subtype == MFVideoFormat_UYVY) return QVideoFrame::Format_UYVY; - else if (subtype == MFVideoFormat_YV12) + if (subtype == MFVideoFormat_YV12) return QVideoFrame::Format_YV12; - else if (subtype == MFVideoFormat_NV12) + if (subtype == MFVideoFormat_NV12) return QVideoFrame::Format_NV12; return QVideoFrame::Format_Invalid; diff --git a/src/plugins/common/evr/evrcustompresenter.h b/src/plugins/common/evr/evrcustompresenter.h index 199dee774..bd04bd952 100644 --- a/src/plugins/common/evr/evrcustompresenter.h +++ b/src/plugins/common/evr/evrcustompresenter.h @@ -58,6 +58,7 @@ class QAbstractVideoSurface; template<class T> class AsyncCallback : public IMFAsyncCallback { + Q_DISABLE_COPY(AsyncCallback) public: typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *asyncResult); @@ -66,7 +67,7 @@ public: } // IUnknown - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) + STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override { if (!ppv) return E_POINTER; @@ -83,23 +84,23 @@ public: return S_OK; } - STDMETHODIMP_(ULONG) AddRef() { + STDMETHODIMP_(ULONG) AddRef() override { // Delegate to parent class. return m_parent->AddRef(); } - STDMETHODIMP_(ULONG) Release() { + STDMETHODIMP_(ULONG) Release() override { // Delegate to parent class. return m_parent->Release(); } // IMFAsyncCallback methods - STDMETHODIMP GetParameters(DWORD*, DWORD*) + STDMETHODIMP GetParameters(DWORD*, DWORD*) override { // Implementation of this method is optional. return E_NOTIMPL; } - STDMETHODIMP Invoke(IMFAsyncResult* asyncResult) + STDMETHODIMP Invoke(IMFAsyncResult* asyncResult) override { return (m_parent->*m_invokeFn)(asyncResult); } @@ -110,6 +111,7 @@ public: class Scheduler { + Q_DISABLE_COPY(Scheduler) public: enum ScheduleEvent { @@ -164,6 +166,7 @@ private: class SamplePool { + Q_DISABLE_COPY(SamplePool) public: SamplePool(); ~SamplePool(); @@ -188,6 +191,7 @@ class EVRCustomPresenter , public IMFGetService , public IMFTopologyServiceLookupClient { + Q_DISABLE_COPY(EVRCustomPresenter) public: // Defines the state of the presenter. enum RenderState @@ -216,40 +220,40 @@ public: }; EVRCustomPresenter(QAbstractVideoSurface *surface = 0); - ~EVRCustomPresenter(); + ~EVRCustomPresenter() override; bool isValid() const; // IUnknown methods - STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); + STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; // IMFGetService methods - STDMETHODIMP GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject); + STDMETHODIMP GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject) override; // IMFVideoPresenter methods - STDMETHODIMP ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param); - STDMETHODIMP GetCurrentMediaType(IMFVideoMediaType** mediaType); + STDMETHODIMP ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param) override; + STDMETHODIMP GetCurrentMediaType(IMFVideoMediaType** mediaType) override; // IMFClockStateSink methods - STDMETHODIMP OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset); - STDMETHODIMP OnClockStop(MFTIME systemTime); - STDMETHODIMP OnClockPause(MFTIME systemTime); - STDMETHODIMP OnClockRestart(MFTIME systemTime); - STDMETHODIMP OnClockSetRate(MFTIME systemTime, float rate); + STDMETHODIMP OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset) override; + STDMETHODIMP OnClockStop(MFTIME systemTime) override; + STDMETHODIMP OnClockPause(MFTIME systemTime) override; + STDMETHODIMP OnClockRestart(MFTIME systemTime) override; + STDMETHODIMP OnClockSetRate(MFTIME systemTime, float rate) override; // IMFRateSupport methods - STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate); - STDMETHODIMP GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate); - STDMETHODIMP IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate); + STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override; + STDMETHODIMP GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override; + STDMETHODIMP IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate) override; // IMFVideoDeviceID methods - STDMETHODIMP GetDeviceID(IID* deviceID); + STDMETHODIMP GetDeviceID(IID* deviceID) override; // IMFTopologyServiceLookupClient methods - STDMETHODIMP InitServicePointers(IMFTopologyServiceLookup *lookup); - STDMETHODIMP ReleaseServicePointers(); + STDMETHODIMP InitServicePointers(IMFTopologyServiceLookup *lookup) override; + STDMETHODIMP ReleaseServicePointers() override; void supportedFormatsChanged(); void setSurface(QAbstractVideoSurface *surface); @@ -258,7 +262,7 @@ public: void stopSurface(); void presentSample(IMFSample *sample); - bool event(QEvent *); + bool event(QEvent *) override; private: HRESULT checkShutdown() const @@ -324,17 +328,10 @@ private: // Holds information related to frame-stepping. struct FrameStep { - FrameStep() - : state(FrameStepNone) - , steps(0) - , sampleNoRef(0) - { - } - - FrameStepState state; + FrameStepState state = FrameStepNone; QList<IMFSample*> samples; - DWORD steps; - DWORD_PTR sampleNoRef; + DWORD steps = 0; + DWORD_PTR sampleNoRef = 0; }; long m_refCount; diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp index 513fe66ca..ab694b795 100644 --- a/src/plugins/common/evr/evrd3dpresentengine.cpp +++ b/src/plugins/common/evr/evrd3dpresentengine.cpp @@ -202,7 +202,7 @@ private: unsigned int m_glTexture; QOpenGLContext *m_glContext; - ~OpenGLResources() + ~OpenGLResources() override { QScopedPointer<QOffscreenSurface> surface; if (m_glContext != QOpenGLContext::currentContext()) { @@ -251,7 +251,7 @@ public: } } - ~IMFSampleVideoBuffer() + ~IMFSampleVideoBuffer() override { if (m_surface) { if (m_mapMode != NotMapped) @@ -262,11 +262,11 @@ public: m_sample->Release(); } - QVariant handle() const; + QVariant handle() const override; - MapMode mapMode() const { return m_mapMode; } - uchar *map(MapMode, int*, int*); - void unmap(); + MapMode mapMode() const override { return m_mapMode; } + uchar *map(MapMode, int*, int*) override; + void unmap() override; private: mutable D3DPresentEngine *m_engine; diff --git a/src/plugins/common/evr/evrd3dpresentengine.h b/src/plugins/common/evr/evrd3dpresentengine.h index 258d8b548..8e2a444f3 100644 --- a/src/plugins/common/evr/evrd3dpresentengine.h +++ b/src/plugins/common/evr/evrd3dpresentengine.h @@ -72,6 +72,7 @@ class OpenGLResources; class EGLWrapper { + Q_DISABLE_COPY(EGLWrapper) public: EGLWrapper(); @@ -99,6 +100,7 @@ private: class D3DPresentEngine { + Q_DISABLE_COPY(D3DPresentEngine) public: enum Hint { diff --git a/src/plugins/common/evr/evrhelpers.cpp b/src/plugins/common/evr/evrhelpers.cpp index 96b61e2eb..a315f1a73 100644 --- a/src/plugins/common/evr/evrhelpers.cpp +++ b/src/plugins/common/evr/evrhelpers.cpp @@ -69,7 +69,7 @@ bool qt_evr_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2) { if (!type1 && !type2) return true; - else if (!type1 || !type2) + if (!type1 || !type2) return false; DWORD dwFlags = 0; @@ -84,10 +84,10 @@ HRESULT qt_evr_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 h float fOffsetY = qt_evr_MFOffsetToFloat(area.OffsetY); if ( ((LONG)fOffsetX + area.Area.cx > (LONG)width) || - ((LONG)fOffsetY + area.Area.cy > (LONG)height) ) + ((LONG)fOffsetY + area.Area.cy > (LONG)height) ) { return MF_E_INVALIDMEDIATYPE; - else - return S_OK; + } + return S_OK; } bool qt_evr_isSampleTimePassed(IMFClock *clock, IMFSample *sample) diff --git a/src/plugins/common/evr/evrhelpers.h b/src/plugins/common/evr/evrhelpers.h index 527612c45..b5bdf5ead 100644 --- a/src/plugins/common/evr/evrhelpers.h +++ b/src/plugins/common/evr/evrhelpers.h @@ -87,7 +87,9 @@ inline MFVideoArea qt_evr_makeMFArea(float x, float y, DWORD width, DWORD height inline HRESULT qt_evr_getFrameRate(IMFMediaType *pType, MFRatio *pRatio) { - return MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, (UINT32*)&pRatio->Numerator, (UINT32*)&pRatio->Denominator); + return MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, + reinterpret_cast<UINT32*>(&pRatio->Numerator), + reinterpret_cast<UINT32*>(&pRatio->Denominator)); } QVideoFrame::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format); diff --git a/src/plugins/common/evr/evrvideowindowcontrol.h b/src/plugins/common/evr/evrvideowindowcontrol.h index fcfe20958..ce3b7746f 100644 --- a/src/plugins/common/evr/evrvideowindowcontrol.h +++ b/src/plugins/common/evr/evrvideowindowcontrol.h @@ -51,37 +51,37 @@ class EvrVideoWindowControl : public QVideoWindowControl Q_OBJECT public: EvrVideoWindowControl(QObject *parent = 0); - ~EvrVideoWindowControl(); + ~EvrVideoWindowControl() override; bool setEvr(IUnknown *evr); - WId winId() const; - void setWinId(WId id); + WId winId() const override; + void setWinId(WId id) override; - QRect displayRect() const; - void setDisplayRect(const QRect &rect); + QRect displayRect() const override; + void setDisplayRect(const QRect &rect) override; - bool isFullScreen() const; - void setFullScreen(bool fullScreen); + bool isFullScreen() const override; + void setFullScreen(bool fullScreen) override; - void repaint(); + void repaint() override; - QSize nativeSize() const; + QSize nativeSize() const override; - Qt::AspectRatioMode aspectRatioMode() const; - void setAspectRatioMode(Qt::AspectRatioMode mode); + Qt::AspectRatioMode aspectRatioMode() const override; + void setAspectRatioMode(Qt::AspectRatioMode mode) override; - int brightness() const; - void setBrightness(int brightness); + int brightness() const override; + void setBrightness(int brightness) override; - int contrast() const; - void setContrast(int contrast); + int contrast() const override; + void setContrast(int contrast) override; - int hue() const; - void setHue(int hue); + int hue() const override; + void setHue(int hue) override; - int saturation() const; - void setSaturation(int saturation); + int saturation() const override; + void setSaturation(int saturation) override; void applyImageControls(); diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri index 0e1c1e895..3be1acc49 100644 --- a/src/plugins/directshow/camera/camera.pri +++ b/src/plugins/directshow/camera/camera.pri @@ -15,7 +15,8 @@ HEADERS += \ $$PWD/directshowcameraexposurecontrol.h \ $$PWD/directshowcameracapturedestinationcontrol.h \ $$PWD/directshowcameracapturebufferformatcontrol.h \ - $$PWD/directshowcamerazoomcontrol.h + $$PWD/directshowcamerazoomcontrol.h \ + $$PWD/directshowcameraimageencodercontrol.h SOURCES += \ $$PWD/dscameraservice.cpp \ @@ -29,7 +30,8 @@ SOURCES += \ $$PWD/directshowcameraexposurecontrol.cpp \ $$PWD/directshowcameracapturedestinationcontrol.cpp \ $$PWD/directshowcameracapturebufferformatcontrol.cpp \ - $$PWD/directshowcamerazoomcontrol.cpp + $$PWD/directshowcamerazoomcontrol.cpp \ + $$PWD/directshowcameraimageencodercontrol.cpp *-msvc*:INCLUDEPATH += $$(DXSDK_DIR)/include QMAKE_USE += directshow diff --git a/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp b/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp index 7ece366ea..6f138450c 100644 --- a/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp +++ b/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp @@ -68,13 +68,16 @@ DirectShowCameraExposureControl::DirectShowCameraExposureControl(DSCameraSession bool DirectShowCameraExposureControl::isParameterSupported(QCameraExposureControl::ExposureParameter parameter) const { - if (parameter == ShutterSpeed) - return (m_shutterSpeedValues.caps & CameraControl_Flags_Manual); - if (parameter == Aperture) + switch (parameter) { + case QCameraExposureControl::Aperture: return (m_apertureValues.caps & CameraControl_Flags_Manual); - if (parameter == ExposureMode) + case QCameraExposureControl::ShutterSpeed: + return (m_shutterSpeedValues.caps & CameraControl_Flags_Manual); + case QCameraExposureControl::ExposureMode: return true; - + default: + break; + } return false; } @@ -156,10 +159,9 @@ bool DirectShowCameraExposureControl::setValue(QCameraExposureControl::ExposureP if (parameter == ShutterSpeed) { m_requestedShutterSpeed = newValue; return setShutterSpeed(cameraControl, m_requestedShutterSpeed); - } else { - m_requestedAperture = newValue; - return setAperture(cameraControl, m_requestedAperture); } + m_requestedAperture = newValue; + return setAperture(cameraControl, m_requestedAperture); } if (parameter == ExposureMode) { diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp new file mode 100644 index 000000000..912f67a2d --- /dev/null +++ b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowcameraimageencodercontrol.h" +#include "dscamerasession.h" +#include <QImageWriter> + +QT_BEGIN_NAMESPACE + +DirectShowCameraImageEncoderControl::DirectShowCameraImageEncoderControl(DSCameraSession *session) + : QImageEncoderControl(session) + , m_session(session) +{ +} + +QList<QSize> DirectShowCameraImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const +{ + QList<QSize> res; + if (!settings.codec().isEmpty() && !supportedImageCodecs().contains(settings.codec(), Qt::CaseInsensitive)) + return res; + + QList<QSize> resolutions = m_session->supportedResolutions(continuous); + QSize r = settings.resolution(); + if (!r.isValid()) + return resolutions; + + if (resolutions.contains(r)) + res << settings.resolution(); + + return res; +} + +QStringList DirectShowCameraImageEncoderControl::supportedImageCodecs() const +{ + QStringList supportedCodecs; + for (const QByteArray &type: QImageWriter::supportedImageFormats()) { + supportedCodecs << type; + } + + return supportedCodecs; +} + +QString DirectShowCameraImageEncoderControl::imageCodecDescription(const QString &codecName) const +{ + Q_UNUSED(codecName); + return QString(); +} + +QImageEncoderSettings DirectShowCameraImageEncoderControl::imageSettings() const +{ + return m_session->imageEncoderSettings(); +} + +void DirectShowCameraImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) +{ + m_session->setImageEncoderSettings(settings); +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h new file mode 100644 index 000000000..6891bea77 --- /dev/null +++ b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H +#define DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H + +#include <qimageencodercontrol.h> + +QT_BEGIN_NAMESPACE + +class DSCameraSession; +class DirectShowCameraImageEncoderControl : public QImageEncoderControl +{ + Q_OBJECT +public: + DirectShowCameraImageEncoderControl(DSCameraSession *session); + + QList<QSize> supportedResolutions( + const QImageEncoderSettings &settings = QImageEncoderSettings(), + bool *continuous = nullptr) const override; + + QStringList supportedImageCodecs() const override; + QString imageCodecDescription(const QString &formatName) const override; + + QImageEncoderSettings imageSettings() const override; + void setImageSettings(const QImageEncoderSettings &settings) override; + +private: + DSCameraSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H diff --git a/src/plugins/directshow/camera/dscameracontrol.cpp b/src/plugins/directshow/camera/dscameracontrol.cpp index daf104e1c..67971d1b5 100644 --- a/src/plugins/directshow/camera/dscameracontrol.cpp +++ b/src/plugins/directshow/camera/dscameracontrol.cpp @@ -61,9 +61,7 @@ DSCameraControl::DSCameraControl(QObject *parent) this, &DSCameraControl::error); } -DSCameraControl::~DSCameraControl() -{ -} +DSCameraControl::~DSCameraControl() = default; void DSCameraControl::setState(QCamera::State state) { diff --git a/src/plugins/directshow/camera/dscameracontrol.h b/src/plugins/directshow/camera/dscameracontrol.h index 2f50db560..b9fb2766d 100644 --- a/src/plugins/directshow/camera/dscameracontrol.h +++ b/src/plugins/directshow/camera/dscameracontrol.h @@ -45,7 +45,6 @@ QT_BEGIN_NAMESPACE -class DSCameraService; class DSCameraSession; @@ -54,22 +53,22 @@ class DSCameraControl : public QCameraControl Q_OBJECT public: DSCameraControl(QObject *parent = 0); - ~DSCameraControl(); + ~DSCameraControl() override; - QCamera::State state() const { return m_state; } + QCamera::State state() const override { return m_state; } - QCamera::CaptureModes captureMode() const { return m_captureMode; } - void setCaptureMode(QCamera::CaptureModes mode); + QCamera::CaptureModes captureMode() const override { return m_captureMode; } + void setCaptureMode(QCamera::CaptureModes mode) override; - void setState(QCamera::State state); + void setState(QCamera::State state) override; - QCamera::Status status() const; - bool isCaptureModeSupported(QCamera::CaptureModes mode) const; - bool canChangeProperty(PropertyChangeType /* changeType */, QCamera::Status /* status */) const {return false; } + QCamera::Status status() const override; + bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; + bool canChangeProperty(PropertyChangeType, QCamera::Status) const override + { return false; } private: DSCameraSession *m_session; - DSCameraService *m_service; QCamera::State m_state; QCamera::CaptureModes m_captureMode; }; diff --git a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp index cbecb8b86..6d0f45ae9 100644 --- a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp +++ b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp @@ -48,9 +48,7 @@ DSCameraImageProcessingControl::DSCameraImageProcessingControl(DSCameraSession * { } -DSCameraImageProcessingControl::~DSCameraImageProcessingControl() -{ -} +DSCameraImageProcessingControl::~DSCameraImageProcessingControl() = default; bool DSCameraImageProcessingControl::isParameterSupported( QCameraImageProcessingControl::ProcessingParameter parameter) const diff --git a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h index 86ecce720..48f1b6b2c 100644 --- a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h +++ b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h @@ -53,12 +53,13 @@ class DSCameraImageProcessingControl : public QCameraImageProcessingControl public: DSCameraImageProcessingControl(DSCameraSession *session); - virtual ~DSCameraImageProcessingControl(); + ~DSCameraImageProcessingControl() override; - bool isParameterSupported(ProcessingParameter) const; - bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const; - QVariant parameter(ProcessingParameter parameter) const; - void setParameter(ProcessingParameter parameter, const QVariant &value); + bool isParameterSupported(ProcessingParameter) const override; + bool isParameterValueSupported(ProcessingParameter parameter, + const QVariant &value) const override; + QVariant parameter(ProcessingParameter parameter) const override; + void setParameter(ProcessingParameter parameter, const QVariant &value) override; private: DSCameraSession *m_session; diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp index a806cabe3..8115ef385 100644 --- a/src/plugins/directshow/camera/dscameraservice.cpp +++ b/src/plugins/directshow/camera/dscameraservice.cpp @@ -53,6 +53,7 @@ #include "directshowcameracapturebufferformatcontrol.h" #include "directshowvideoprobecontrol.h" #include "directshowcamerazoomcontrol.h" +#include "directshowcameraimageencodercontrol.h" QT_BEGIN_NAMESPACE @@ -70,6 +71,7 @@ DSCameraService::DSCameraService(QObject *parent): , m_captureBufferFormatControl(new DirectShowCameraCaptureBufferFormatControl) , m_videoProbeControl(nullptr) , m_zoomControl(new DirectShowCameraZoomControl(m_session)) + , m_imageEncoderControl(new DirectShowCameraImageEncoderControl(m_session)) { } @@ -81,6 +83,7 @@ DSCameraService::~DSCameraService() delete m_videoDevice; delete m_videoRenderer; delete m_imageCapture; + delete m_imageEncoderControl; delete m_session; delete m_exposureControl; delete m_captureDestinationControl; @@ -134,6 +137,9 @@ QMediaControl* DSCameraService::requestControl(const char *name) if (qstrcmp(name, QCameraZoomControl_iid) == 0) return m_zoomControl; + if (qstrcmp(name, QImageEncoderControl_iid) == 0) + return m_imageEncoderControl; + return 0; } diff --git a/src/plugins/directshow/camera/dscameraservice.h b/src/plugins/directshow/camera/dscameraservice.h index f444eeb51..9a8f745f6 100644 --- a/src/plugins/directshow/camera/dscameraservice.h +++ b/src/plugins/directshow/camera/dscameraservice.h @@ -57,6 +57,7 @@ class DirectShowCameraCaptureDestinationControl; class DirectShowCameraCaptureBufferFormatControl; class DirectShowVideoProbeControl; class DirectShowCameraZoomControl; +class DirectShowCameraImageEncoderControl; class DSCameraService : public QMediaService { @@ -64,10 +65,10 @@ class DSCameraService : public QMediaService public: DSCameraService(QObject *parent = 0); - ~DSCameraService(); + ~DSCameraService() override; - virtual QMediaControl* requestControl(const char *name); - virtual void releaseControl(QMediaControl *control); + QMediaControl* requestControl(const char *name) override; + void releaseControl(QMediaControl *control) override; private: DSCameraSession *m_session; @@ -82,6 +83,7 @@ private: DirectShowCameraCaptureBufferFormatControl *m_captureBufferFormatControl; DirectShowVideoProbeControl *m_videoProbeControl; DirectShowCameraZoomControl *m_zoomControl; + DirectShowCameraImageEncoderControl *m_imageEncoderControl; }; QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index c309359ed..8d0c72057 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -130,30 +130,28 @@ void DSCameraSession::setViewfinderSettings(const QCameraViewfinderSettings &set qreal DSCameraSession::scaledImageProcessingParameterValue( const ImageProcessingParameterInfo &sourceValueInfo) { - if (sourceValueInfo.currentValue == sourceValueInfo.defaultValue) { + if (sourceValueInfo.currentValue == sourceValueInfo.defaultValue) return 0.0f; - } else if (sourceValueInfo.currentValue < sourceValueInfo.defaultValue) { + if (sourceValueInfo.currentValue < sourceValueInfo.defaultValue) { return ((sourceValueInfo.currentValue - sourceValueInfo.minimumValue) / qreal(sourceValueInfo.defaultValue - sourceValueInfo.minimumValue)) + (-1.0f); - } else { - return ((sourceValueInfo.currentValue - sourceValueInfo.defaultValue) - / qreal(sourceValueInfo.maximumValue - sourceValueInfo.defaultValue)); } + return ((sourceValueInfo.currentValue - sourceValueInfo.defaultValue) + / qreal(sourceValueInfo.maximumValue - sourceValueInfo.defaultValue)); } qint32 DSCameraSession::sourceImageProcessingParameterValue( qreal scaledValue, const ImageProcessingParameterInfo &valueRange) { - if (qFuzzyIsNull(scaledValue)) { + if (qFuzzyIsNull(scaledValue)) return valueRange.defaultValue; - } else if (scaledValue < 0.0f) { + if (scaledValue < 0.0f) { return ((scaledValue - (-1.0f)) * (valueRange.defaultValue - valueRange.minimumValue)) + valueRange.minimumValue; - } else { - return (scaledValue * (valueRange.maximumValue - valueRange.defaultValue)) - + valueRange.defaultValue; } + return (scaledValue * (valueRange.maximumValue - valueRange.defaultValue)) + + valueRange.defaultValue; } static QCameraImageProcessingControl::ProcessingParameter searchRelatedResultingParameter( @@ -482,7 +480,7 @@ bool DSCameraSession::startPreview() if (m_surface) m_surface->start(m_previewSurfaceFormat); - hr = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); + hr = m_filterGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&pControl)); if (FAILED(hr)) { errorString = tr("Failed to get stream control"); goto failed; @@ -520,7 +518,8 @@ bool DSCameraSession::stopPreview() QString errorString; IMediaControl* pControl = 0; - HRESULT hr = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); + HRESULT hr = m_filterGraph->QueryInterface(IID_IMediaControl, + reinterpret_cast<void**>(&pControl)); if (FAILED(hr)) { errorString = tr("Failed to get stream control"); goto failed; @@ -585,10 +584,13 @@ int DSCameraSession::captureImage(const QString &fileName) return m_imageIdCounter; } + const QString ext = !m_imageEncoderSettings.codec().isEmpty() + ? m_imageEncoderSettings.codec().toLower() + : QLatin1String("jpg"); m_imageCaptureFileName = m_fileNameGenerator.generateFileName(fileName, QMediaStorageLocation::Pictures, QLatin1String("IMG_"), - QLatin1String("jpg")); + ext); updateReadyForCapture(); @@ -688,8 +690,9 @@ void DSCameraSession::processCapturedImage(int id, const QImage &image, const QString &path) { + const QString format = m_imageEncoderSettings.codec(); if (captureDestinations & QCameraImageCapture::CaptureToFile) { - if (image.save(path, "JPG")) { + if (image.save(path, !format.isEmpty() ? format.toUtf8().constData() : "JPG")) { Q_EMIT imageSaved(id, path); } else { Q_EMIT captureError(id, QCameraImageCapture::ResourceError, @@ -714,7 +717,7 @@ bool DSCameraSession::createFilterGraph() // Create the filter graph hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC, - IID_IGraphBuilder, (void**)&m_filterGraph); + IID_IGraphBuilder, reinterpret_cast<void**>(&m_filterGraph)); if (FAILED(hr)) { errorString = tr("Failed to create filter graph"); goto failed; @@ -722,7 +725,8 @@ bool DSCameraSession::createFilterGraph() // Create the capture graph builder hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, - IID_ICaptureGraphBuilder2, (void**)&m_graphBuilder); + IID_ICaptureGraphBuilder2, + reinterpret_cast<void**>(&m_graphBuilder)); if (FAILED(hr)) { errorString = tr("Failed to create graph builder"); goto failed; @@ -756,7 +760,8 @@ bool DSCameraSession::createFilterGraph() QString output = QString::fromWCharArray(strName); mallocInterface->Free(strName); if (m_sourceDeviceName.contains(output)) { - hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_sourceFilter); + hr = pMoniker->BindToObject(nullptr, nullptr, IID_IBaseFilter, + reinterpret_cast<void**>(&m_sourceFilter)); if (SUCCEEDED(hr)) { pMoniker->Release(); break; @@ -775,7 +780,8 @@ bool DSCameraSession::createFilterGraph() while (pEnum->Next(1, &pMoniker, NULL) == S_OK) { IPropertyBag *pPropBag = 0; - hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag)); + hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, + reinterpret_cast<void**>(&pPropBag)); if (FAILED(hr)) { pMoniker->Release(); continue; // Don't panic yet @@ -783,7 +789,8 @@ bool DSCameraSession::createFilterGraph() // No need to get the description, just grab it - hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_sourceFilter); + hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, + reinterpret_cast<void**>(&m_sourceFilter)); pPropBag->Release(); pMoniker->Release(); if (SUCCEEDED(hr)) { @@ -841,9 +848,11 @@ bool DSCameraSession::configurePreviewFormat() { // Resolve viewfinder settings int settingsIndex = 0; + const QSize captureResolution = m_imageEncoderSettings.resolution(); + const QSize resolution = captureResolution.isValid() ? captureResolution : m_viewfinderSettings.resolution(); QCameraViewfinderSettings resolvedViewfinderSettings; for (const QCameraViewfinderSettings &s : qAsConst(m_supportedViewfinderSettings)) { - if ((m_viewfinderSettings.resolution().isEmpty() || m_viewfinderSettings.resolution() == s.resolution()) + if ((resolution.isEmpty() || resolution == s.resolution()) && (qFuzzyIsNull(m_viewfinderSettings.minimumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.minimumFrameRate(), (float)s.minimumFrameRate())) && (qFuzzyIsNull(m_viewfinderSettings.maximumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.maximumFrameRate(), (float)s.maximumFrameRate())) && (m_viewfinderSettings.pixelFormat() == QVideoFrame::Format_Invalid || m_viewfinderSettings.pixelFormat() == s.pixelFormat()) @@ -887,10 +896,9 @@ bool DSCameraSession::configurePreviewFormat() HRESULT hr; IAMStreamConfig* pConfig = 0; - hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, - &MEDIATYPE_Video, - m_sourceFilter, - IID_IAMStreamConfig, (void**)&pConfig); + hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, + m_sourceFilter, IID_IAMStreamConfig, + reinterpret_cast<void**>(&pConfig)); if (FAILED(hr)) { qWarning() << "Failed to get config for capture device"; return false; @@ -1064,8 +1072,8 @@ void DSCameraSession::updateSourceCapabilities() IAMVideoControl *pVideoControl = 0; hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, - m_sourceFilter, - IID_IAMVideoControl, (void**)&pVideoControl); + m_sourceFilter, IID_IAMVideoControl, + reinterpret_cast<void**>(&pVideoControl)); if (FAILED(hr)) { qWarning() << "Failed to get the video control"; } else { @@ -1091,8 +1099,8 @@ void DSCameraSession::updateSourceCapabilities() } hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, - m_sourceFilter, - IID_IAMStreamConfig, (void**)&pConfig); + m_sourceFilter, IID_IAMStreamConfig, + reinterpret_cast<void**>(&pConfig)); if (FAILED(hr)) { qWarning() << "failed to get config on capture device"; return; @@ -1169,4 +1177,23 @@ void DSCameraSession::updateSourceCapabilities() updateImageProcessingParametersInfos(); } +QList<QSize> DSCameraSession::supportedResolutions(bool *continuous) const +{ + if (continuous) + *continuous = false; + + QList<QSize> res; + for (auto &settings : m_supportedViewfinderSettings) { + auto size = settings.resolution(); + if (!res.contains(size)) + res << size; + } + + std::sort(res.begin(), res.end(), [](const QSize &r1, const QSize &r2) { + return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height(); + }); + + return res; +} + QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index 433db8994..361a0220e 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -51,6 +51,7 @@ #include <QtMultimedia/qvideosurfaceformat.h> #include <QtMultimedia/qcameraimageprocessingcontrol.h> #include <QtMultimedia/qcameraimagecapture.h> +#include <QtMultimedia/qmediaencodersettings.h> #include <private/qmediastoragelocation_p.h> #include <tchar.h> @@ -84,7 +85,7 @@ class DSCameraSession : public QObject Q_OBJECT public: DSCameraSession(QObject *parent = 0); - ~DSCameraSession(); + ~DSCameraSession() override; QCamera::Status status() const { return m_status; } @@ -129,6 +130,11 @@ public: void addVideoProbe(DirectShowVideoProbeControl *probe); void removeVideoProbe(DirectShowVideoProbeControl *probe); + QList<QSize> supportedResolutions(bool *continuous) const; + QImageEncoderSettings imageEncoderSettings() const { return m_imageEncoderSettings; } + void setImageEncoderSettings(const QImageEncoderSettings &settings) + { m_imageEncoderSettings = settings; } + Q_SIGNALS: void statusChanged(QCamera::Status); void imageExposed(int id); @@ -145,25 +151,15 @@ private Q_SLOTS: void updateReadyForCapture(); private: - struct ImageProcessingParameterInfo { - ImageProcessingParameterInfo() - : minimumValue(0) - , maximumValue(0) - , defaultValue(0) - , currentValue(0) - , capsFlags(0) - , hasBeenExplicitlySet(false) - , videoProcAmpProperty(VideoProcAmp_Brightness) - { - } - - LONG minimumValue; - LONG maximumValue; - LONG defaultValue; - LONG currentValue; - LONG capsFlags; - bool hasBeenExplicitlySet; - VideoProcAmpProperty videoProcAmpProperty; + struct ImageProcessingParameterInfo + { + LONG minimumValue = 0; + LONG maximumValue = 0; + LONG defaultValue = 0; + LONG currentValue = 0; + LONG capsFlags = 0; + bool hasBeenExplicitlySet = false; + VideoProcAmpProperty videoProcAmpProperty = VideoProcAmp_Brightness; }; void setStatus(QCamera::Status status); @@ -227,6 +223,8 @@ private: QMutex m_probeMutex; DirectShowVideoProbeControl *m_videoProbeControl; + QImageEncoderSettings m_imageEncoderSettings; + // Internal state QCamera::Status m_status; QTimer m_deviceLostEventTimer; diff --git a/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h b/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h index 5ab3c2d93..a2b646edf 100644 --- a/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h +++ b/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h @@ -51,10 +51,10 @@ class DSCameraViewfinderSettingsControl : public QCameraViewfinderSettingsContro public: DSCameraViewfinderSettingsControl(DSCameraSession *session); - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const; + QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override; - QCameraViewfinderSettings viewfinderSettings() const; - void setViewfinderSettings(const QCameraViewfinderSettings &settings); + QCameraViewfinderSettings viewfinderSettings() const override; + void setViewfinderSettings(const QCameraViewfinderSettings &settings) override; private: DSCameraSession *m_session; diff --git a/src/plugins/directshow/camera/dsimagecapturecontrol.cpp b/src/plugins/directshow/camera/dsimagecapturecontrol.cpp index c92ce98e1..2a6a794d5 100644 --- a/src/plugins/directshow/camera/dsimagecapturecontrol.cpp +++ b/src/plugins/directshow/camera/dsimagecapturecontrol.cpp @@ -61,9 +61,7 @@ DSImageCaptureControl::DSImageCaptureControl(DSCameraSession *session) this, &DSImageCaptureControl::imageAvailable); } -DSImageCaptureControl::~DSImageCaptureControl() -{ -} +DSImageCaptureControl::~DSImageCaptureControl() = default; bool DSImageCaptureControl::isReadyForCapture() const { diff --git a/src/plugins/directshow/camera/dsimagecapturecontrol.h b/src/plugins/directshow/camera/dsimagecapturecontrol.h index 38b832dc4..c619de1a1 100644 --- a/src/plugins/directshow/camera/dsimagecapturecontrol.h +++ b/src/plugins/directshow/camera/dsimagecapturecontrol.h @@ -50,15 +50,15 @@ class DSImageCaptureControl : public QCameraImageCaptureControl Q_OBJECT public: DSImageCaptureControl(DSCameraSession *session); - ~DSImageCaptureControl(); + ~DSImageCaptureControl() override; - bool isReadyForCapture() const; - int capture(const QString &fileName); + bool isReadyForCapture() const override; + int capture(const QString &fileName) override; - QCameraImageCapture::DriveMode driveMode() const; - void setDriveMode(QCameraImageCapture::DriveMode mode); + QCameraImageCapture::DriveMode driveMode() const override; + void setDriveMode(QCameraImageCapture::DriveMode mode) override; - void cancelCapture() {} + void cancelCapture() override {} private: DSCameraSession *m_session; diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp index 26410fc3a..2c1fab764 100644 --- a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp +++ b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp @@ -156,7 +156,8 @@ void DSVideoDeviceControl::updateDevices() devInfo.first = output.toUtf8(); IPropertyBag *pPropBag; - hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag)); + hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, + reinterpret_cast<void**>(&pPropBag)); if (SUCCEEDED(hr)) { // Find the description VARIANT varName; diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.h b/src/plugins/directshow/camera/dsvideodevicecontrol.h index 09f46aff0..7a7a0af1e 100644 --- a/src/plugins/directshow/camera/dsvideodevicecontrol.h +++ b/src/plugins/directshow/camera/dsvideodevicecontrol.h @@ -56,16 +56,16 @@ class DSVideoDeviceControl : public QVideoDeviceSelectorControl public: DSVideoDeviceControl(QObject *parent = 0); - int deviceCount() const; - QString deviceName(int index) const; - QString deviceDescription(int index) const; - int defaultDevice() const; - int selectedDevice() const; + int deviceCount() const override; + QString deviceName(int index) const override; + QString deviceDescription(int index) const override; + int defaultDevice() const override; + int selectedDevice() const override; static const QList<DSVideoDeviceInfo> &availableDevices(); public Q_SLOTS: - void setSelectedDevice(int index); + void setSelectedDevice(int index) override; private: static void updateDevices(); diff --git a/src/plugins/directshow/camera/dsvideorenderer.cpp b/src/plugins/directshow/camera/dsvideorenderer.cpp index 4eacb5456..bf0aa2684 100644 --- a/src/plugins/directshow/camera/dsvideorenderer.cpp +++ b/src/plugins/directshow/camera/dsvideorenderer.cpp @@ -50,9 +50,7 @@ DSVideoRendererControl::DSVideoRendererControl(DSCameraSession* session, QObject { } -DSVideoRendererControl::~DSVideoRendererControl() -{ -} +DSVideoRendererControl::~DSVideoRendererControl() = default; QAbstractVideoSurface* DSVideoRendererControl::surface() const { diff --git a/src/plugins/directshow/camera/dsvideorenderer.h b/src/plugins/directshow/camera/dsvideorenderer.h index 7618f0ca6..3a4570b4c 100644 --- a/src/plugins/directshow/camera/dsvideorenderer.h +++ b/src/plugins/directshow/camera/dsvideorenderer.h @@ -43,8 +43,6 @@ #include <qvideorenderercontrol.h> #include "dscamerasession.h" -class CameraFormatConverter; - QT_BEGIN_NAMESPACE @@ -53,17 +51,16 @@ class DSVideoRendererControl : public QVideoRendererControl Q_OBJECT public: DSVideoRendererControl(DSCameraSession* session, QObject *parent = 0); - ~DSVideoRendererControl(); + ~DSVideoRendererControl() override; - QAbstractVideoSurface *surface() const; - void setSurface(QAbstractVideoSurface *surface); + QAbstractVideoSurface *surface() const override; + void setSurface(QAbstractVideoSurface *surface) override; void setSession(DSCameraSession* session); private: QAbstractVideoSurface* m_surface; DSCameraSession* m_session; - CameraFormatConverter* converter; }; QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowaudioprobecontrol.h b/src/plugins/directshow/common/directshowaudioprobecontrol.h index 553bd1178..034e958fd 100644 --- a/src/plugins/directshow/common/directshowaudioprobecontrol.h +++ b/src/plugins/directshow/common/directshowaudioprobecontrol.h @@ -51,7 +51,7 @@ class DirectShowAudioProbeControl : public QMediaAudioProbeControl Q_OBJECT public: explicit DirectShowAudioProbeControl(QObject *p = nullptr); - ~DirectShowAudioProbeControl(); + ~DirectShowAudioProbeControl() override; bool ref() { return m_ref.ref(); } bool deref() { return m_ref.deref(); } diff --git a/src/plugins/directshow/common/directshowbasefilter.cpp b/src/plugins/directshow/common/directshowbasefilter.cpp index 1e45eea51..2792dc3c6 100644 --- a/src/plugins/directshow/common/directshowbasefilter.cpp +++ b/src/plugins/directshow/common/directshowbasefilter.cpp @@ -172,51 +172,43 @@ HRESULT DirectShowBaseFilter::SetSyncSource(IReferenceClock *pClock) HRESULT DirectShowBaseFilter::GetSyncSource(IReferenceClock **ppClock) { - if (!ppClock) { + if (!ppClock) return E_POINTER; - } else { - if (!m_clock) { - *ppClock = 0; - - return S_FALSE; - } else { - m_clock->AddRef(); - *ppClock = m_clock; - - return S_OK; - } + if (!m_clock) { + *ppClock = nullptr; + return S_FALSE; } + m_clock->AddRef(); + *ppClock = m_clock; + return S_OK; } HRESULT DirectShowBaseFilter::EnumPins(IEnumPins **ppEnum) { - if (!ppEnum) { + if (!ppEnum) return E_POINTER; - } else { - *ppEnum = new DirectShowPinEnum(this); - return S_OK; - } + *ppEnum = new DirectShowPinEnum(this); + return S_OK; } HRESULT DirectShowBaseFilter::FindPin(LPCWSTR Id, IPin **ppPin) { - if (!ppPin || !Id) { + if (!ppPin || !Id) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - const QList<DirectShowPin *> pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (QString::fromWCharArray(Id) == pin->name()) { - pin->AddRef(); - *ppPin = pin; - return S_OK; - } - } - *ppPin = 0; - return VFW_E_NOT_FOUND; + QMutexLocker locker(&m_mutex); + const QList<DirectShowPin *> pinList = pins(); + for (DirectShowPin *pin : pinList) { + if (pin->name() == QStringView(Id)) { + pin->AddRef(); + *ppPin = pin; + return S_OK; + } } + + *ppPin = 0; + return VFW_E_NOT_FOUND; } HRESULT DirectShowBaseFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) @@ -237,24 +229,23 @@ HRESULT DirectShowBaseFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pNam HRESULT DirectShowBaseFilter::QueryFilterInfo(FILTER_INFO *pInfo) { - if (!pInfo) { + if (!pInfo) return E_POINTER; - } else { - QString name = m_filterName; - if (name.length() >= MAX_FILTER_NAME) - name.truncate(MAX_FILTER_NAME - 1); + QString name = m_filterName; - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; + if (name.length() >= MAX_FILTER_NAME) + name.truncate(MAX_FILTER_NAME - 1); - if (m_graph) - m_graph->AddRef(); + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; - pInfo->pGraph = m_graph; + if (m_graph) + m_graph->AddRef(); - return S_OK; - } + pInfo->pGraph = m_graph; + + return S_OK; } HRESULT DirectShowBaseFilter::QueryVendorInfo(LPWSTR *pVendorInfo) diff --git a/src/plugins/directshow/common/directshowbasefilter.h b/src/plugins/directshow/common/directshowbasefilter.h index 21ca648eb..fe78f96b2 100644 --- a/src/plugins/directshow/common/directshowbasefilter.h +++ b/src/plugins/directshow/common/directshowbasefilter.h @@ -48,7 +48,7 @@ class DirectShowBaseFilter : public IBaseFilter { public: DirectShowBaseFilter(); - ~DirectShowBaseFilter(); + virtual ~DirectShowBaseFilter(); FILTER_STATE state() const { return m_state; } HRESULT NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2); @@ -56,26 +56,26 @@ public: virtual QList<DirectShowPin *> pins() = 0; // IPersist - STDMETHODIMP GetClassID(CLSID *pClassID); + STDMETHODIMP GetClassID(CLSID *pClassID) override; // IMediaFilter - STDMETHODIMP Run(REFERENCE_TIME tStart); - STDMETHODIMP Pause(); - STDMETHODIMP Stop(); + STDMETHODIMP Run(REFERENCE_TIME tStart) override; + STDMETHODIMP Pause() override; + STDMETHODIMP Stop() override; - STDMETHODIMP GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState); + STDMETHODIMP GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) override; - STDMETHODIMP SetSyncSource(IReferenceClock *pClock); - STDMETHODIMP GetSyncSource(IReferenceClock **ppClock); + STDMETHODIMP SetSyncSource(IReferenceClock *pClock) override; + STDMETHODIMP GetSyncSource(IReferenceClock **ppClock) override; // IBaseFilter - STDMETHODIMP EnumPins(IEnumPins **ppEnum); - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); + STDMETHODIMP EnumPins(IEnumPins **ppEnum) override; + STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin) override; - STDMETHODIMP JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); + STDMETHODIMP JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) override; - STDMETHODIMP QueryFilterInfo(FILTER_INFO *pInfo); - STDMETHODIMP QueryVendorInfo(LPWSTR *pVendorInfo); + STDMETHODIMP QueryFilterInfo(FILTER_INFO *pInfo) override; + STDMETHODIMP QueryVendorInfo(LPWSTR *pVendorInfo) override; protected: QMutex m_mutex; diff --git a/src/plugins/directshow/common/directshoweventloop.cpp b/src/plugins/directshow/common/directshoweventloop.cpp index ef85c0429..fbc7b8cee 100644 --- a/src/plugins/directshow/common/directshoweventloop.cpp +++ b/src/plugins/directshow/common/directshoweventloop.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE class DirectShowPostedEvent { + Q_DISABLE_COPY(DirectShowPostedEvent) public: DirectShowPostedEvent(QObject *receiver, QEvent *event) : receiver(receiver) diff --git a/src/plugins/directshow/common/directshoweventloop.h b/src/plugins/directshow/common/directshoweventloop.h index 609e53134..a29274b7b 100644 --- a/src/plugins/directshow/common/directshoweventloop.h +++ b/src/plugins/directshow/common/directshoweventloop.h @@ -55,7 +55,7 @@ class DirectShowEventLoop : public QObject Q_OBJECT public: DirectShowEventLoop(QObject *parent = 0); - ~DirectShowEventLoop(); + ~DirectShowEventLoop() override; void wait(QMutex *mutex); void wake(); @@ -63,7 +63,7 @@ public: void postEvent(QObject *object, QEvent *event); protected: - void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private: void processEvents(); diff --git a/src/plugins/directshow/common/directshowmediatype.cpp b/src/plugins/directshow/common/directshowmediatype.cpp index 65882806c..fe86e0204 100644 --- a/src/plugins/directshow/common/directshowmediatype.cpp +++ b/src/plugins/directshow/common/directshowmediatype.cpp @@ -98,7 +98,7 @@ DirectShowMediaType::DirectShowMediaType(const DirectShowMediaType &other) copy(&mediaType, &other.mediaType); } -DirectShowMediaType::DirectShowMediaType(DirectShowMediaType &&other) +DirectShowMediaType::DirectShowMediaType(DirectShowMediaType &&other) noexcept : DirectShowMediaType() { move(&mediaType, other.mediaType); @@ -110,7 +110,7 @@ DirectShowMediaType &DirectShowMediaType::operator=(const DirectShowMediaType &o return *this; } -DirectShowMediaType &DirectShowMediaType::operator=(DirectShowMediaType &&other) +DirectShowMediaType &DirectShowMediaType::operator=(DirectShowMediaType &&other) noexcept { move(&mediaType, other.mediaType); return *this; @@ -222,11 +222,10 @@ void DirectShowMediaType::clear(AM_MEDIA_TYPE &type) GUID DirectShowMediaType::convertPixelFormat(QVideoFrame::PixelFormat format) { - const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); - - for (int i = 0; i < count; ++i) - if (qt_typeLookup[i].pixelFormat == format) - return qt_typeLookup[i].mediaType; + for (const auto &lookupType : qt_typeLookup) { + if (lookupType.pixelFormat == format) + return lookupType.mediaType; + } return MEDIASUBTYPE_None; } @@ -236,16 +235,14 @@ QVideoSurfaceFormat DirectShowMediaType::videoFormatFromType(const AM_MEDIA_TYPE if (!type) return QVideoSurfaceFormat(); - const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); - - for (int i = 0; i < count; ++i) { - if (IsEqualGUID(qt_typeLookup[i].mediaType, type->subtype) && type->cbFormat > 0) { + for (const auto &lookupType : qt_typeLookup) { + if (IsEqualGUID(lookupType.mediaType, type->subtype) && type->cbFormat > 0) { if (IsEqualGUID(type->formattype, FORMAT_VideoInfo)) { VIDEOINFOHEADER *header = reinterpret_cast<VIDEOINFOHEADER *>(type->pbFormat); QVideoSurfaceFormat format( QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), - qt_typeLookup[i].pixelFormat); + lookupType.pixelFormat); if (header->AvgTimePerFrame > 0) format.setFrameRate(10000 /header->AvgTimePerFrame); @@ -253,12 +250,13 @@ QVideoSurfaceFormat DirectShowMediaType::videoFormatFromType(const AM_MEDIA_TYPE format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); return format; - } else if (IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) { + } + if (IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) { VIDEOINFOHEADER2 *header = reinterpret_cast<VIDEOINFOHEADER2 *>(type->pbFormat); QVideoSurfaceFormat format( QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), - qt_typeLookup[i].pixelFormat); + lookupType.pixelFormat); if (header->AvgTimePerFrame > 0) format.setFrameRate(10000 / header->AvgTimePerFrame); @@ -277,12 +275,9 @@ QVideoFrame::PixelFormat DirectShowMediaType::pixelFormatFromType(const AM_MEDIA if (!type) return QVideoFrame::Format_Invalid; - const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); - - for (int i = 0; i < count; ++i) { - if (IsEqualGUID(qt_typeLookup[i].mediaType, type->subtype)) { - return qt_typeLookup[i].pixelFormat; - } + for (const auto &lookupType : qt_typeLookup) { + if (IsEqualGUID(lookupType.mediaType, type->subtype)) + return lookupType.pixelFormat; } return QVideoFrame::Format_Invalid; diff --git a/src/plugins/directshow/common/directshowmediatype.h b/src/plugins/directshow/common/directshowmediatype.h index 7f495f3b2..ee44329a5 100644 --- a/src/plugins/directshow/common/directshowmediatype.h +++ b/src/plugins/directshow/common/directshowmediatype.h @@ -54,13 +54,13 @@ class DirectShowMediaType public: DirectShowMediaType(); DirectShowMediaType(const DirectShowMediaType &other); - DirectShowMediaType(DirectShowMediaType &&other); + DirectShowMediaType(DirectShowMediaType &&other) noexcept; explicit DirectShowMediaType(const AM_MEDIA_TYPE &type); explicit DirectShowMediaType(AM_MEDIA_TYPE &&type); ~DirectShowMediaType() { clear(mediaType); } DirectShowMediaType &operator =(const DirectShowMediaType &other); - DirectShowMediaType &operator =(DirectShowMediaType &&other); + DirectShowMediaType &operator =(DirectShowMediaType &&other) noexcept; void clear() { clear(mediaType); } diff --git a/src/plugins/directshow/common/directshowmediatypeenum.cpp b/src/plugins/directshow/common/directshowmediatypeenum.cpp index a6afcd5f1..10623a246 100644 --- a/src/plugins/directshow/common/directshowmediatypeenum.cpp +++ b/src/plugins/directshow/common/directshowmediatypeenum.cpp @@ -78,21 +78,20 @@ HRESULT DirectShowMediaTypeEnum::QueryInterface(REFIID riid, void **ppv) HRESULT DirectShowMediaTypeEnum::Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) { - if (ppMediaTypes && (pcFetched || cMediaTypes == 1)) { - ULONG count = qBound<ULONG>(0, cMediaTypes, m_mediaTypes.count() - m_index); - - for (ULONG i = 0; i < count; ++i, ++m_index) { - ppMediaTypes[i] = reinterpret_cast<AM_MEDIA_TYPE *>(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); - DirectShowMediaType::copyToUninitialized(ppMediaTypes[i], &m_mediaTypes.at(m_index)); - } + if (!ppMediaTypes || (!pcFetched && cMediaTypes != 1)) + return E_POINTER; - if (pcFetched) - *pcFetched = count; + ULONG count = qBound<ULONG>(0, cMediaTypes, m_mediaTypes.count() - m_index); - return count == cMediaTypes ? S_OK : S_FALSE; - } else { - return E_POINTER; + for (ULONG i = 0; i < count; ++i, ++m_index) { + ppMediaTypes[i] = reinterpret_cast<AM_MEDIA_TYPE *>(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); + DirectShowMediaType::copyToUninitialized(ppMediaTypes[i], &m_mediaTypes.at(m_index)); } + + if (pcFetched) + *pcFetched = count; + + return count == cMediaTypes ? S_OK : S_FALSE; } HRESULT DirectShowMediaTypeEnum::Skip(ULONG cMediaTypes) @@ -109,14 +108,9 @@ HRESULT DirectShowMediaTypeEnum::Reset() HRESULT DirectShowMediaTypeEnum::Clone(IEnumMediaTypes **ppEnum) { - if (ppEnum) { - if (m_pin) - *ppEnum = new DirectShowMediaTypeEnum(m_pin); - else - *ppEnum = new DirectShowMediaTypeEnum(m_mediaTypes); - return S_OK; - } else { + if (!ppEnum) return E_POINTER; - } + *ppEnum = m_pin ? new DirectShowMediaTypeEnum(m_pin) : new DirectShowMediaTypeEnum(m_mediaTypes); + return S_OK; } diff --git a/src/plugins/directshow/common/directshowpin.cpp b/src/plugins/directshow/common/directshowpin.cpp index 65b54b8e9..508a9b21d 100644 --- a/src/plugins/directshow/common/directshowpin.cpp +++ b/src/plugins/directshow/common/directshowpin.cpp @@ -56,10 +56,7 @@ DirectShowPin::DirectShowPin(DirectShowBaseFilter *filter, const QString &name, { } -DirectShowPin::~DirectShowPin() -{ - -} +DirectShowPin::~DirectShowPin() = default; HRESULT DirectShowPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) { @@ -233,70 +230,60 @@ HRESULT DirectShowPin::Disconnect() HRESULT DirectShowPin::ConnectedTo(IPin **ppPin) { - if (!ppPin) { + if (!ppPin) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) { - *ppPin = 0; - return VFW_E_NOT_CONNECTED; - } else { - m_peerPin->AddRef(); - *ppPin = m_peerPin; - return S_OK; - } + + QMutexLocker locker(&m_mutex); + if (!m_peerPin) { + *ppPin = 0; + return VFW_E_NOT_CONNECTED; } + m_peerPin->AddRef(); + *ppPin = m_peerPin; + return S_OK; } HRESULT DirectShowPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) { - if (!pmt) { + if (!pmt) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - if (!m_peerPin) { - DirectShowMediaType::init(pmt); - return VFW_E_NOT_CONNECTED; - } else { - DirectShowMediaType::copy(pmt, &m_mediaType); - return S_OK; - } + QMutexLocker locker(&m_mutex); + if (!m_peerPin) { + DirectShowMediaType::init(pmt); + return VFW_E_NOT_CONNECTED; } + DirectShowMediaType::copy(pmt, &m_mediaType); + return S_OK; } HRESULT DirectShowPin::QueryPinInfo(PIN_INFO *pInfo) { - if (!pInfo) { + if (!pInfo) return E_POINTER; - } else { - pInfo->pFilter = m_filter; - if (m_filter) { - m_filter->AddRef(); - } - pInfo->dir = m_direction; - QString name = m_name; - if (name.length() >= MAX_PIN_NAME) - name.truncate(MAX_PIN_NAME - 1); - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; + pInfo->pFilter = m_filter; + if (m_filter) + m_filter->AddRef(); + pInfo->dir = m_direction; - return S_OK; - } + QString name = m_name; + if (name.length() >= MAX_PIN_NAME) + name.truncate(MAX_PIN_NAME - 1); + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; + + return S_OK; } HRESULT DirectShowPin::QueryId(LPWSTR *Id) { - if (!Id) { + if (!Id) return E_POINTER; - } else { - const int bytes = (m_name.length() + 1) * 2; - *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); - ::memcpy(*Id, m_name.utf16(), bytes); - return S_OK; - } + const int bytes = (m_name.length() + 1) * 2; + *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); + ::memcpy(*Id, m_name.utf16(), bytes); + return S_OK; } HRESULT DirectShowPin::QueryAccept(const AM_MEDIA_TYPE *pmt) @@ -312,12 +299,10 @@ HRESULT DirectShowPin::QueryAccept(const AM_MEDIA_TYPE *pmt) HRESULT DirectShowPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) { - if (!ppEnum) { + if (!ppEnum) return E_POINTER; - } else { - *ppEnum = new DirectShowMediaTypeEnum(this); - return S_OK; - } + *ppEnum = new DirectShowMediaTypeEnum(this); + return S_OK; } HRESULT DirectShowPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) @@ -352,12 +337,10 @@ HRESULT DirectShowPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, d HRESULT DirectShowPin::QueryDirection(PIN_DIRECTION *pPinDir) { - if (!pPinDir) { + if (!pPinDir) return E_POINTER; - } else { - *pPinDir = m_direction; - return S_OK; - } + *pPinDir = m_direction; + return S_OK; } QList<DirectShowMediaType> DirectShowPin::supportedMediaTypes() @@ -403,9 +386,7 @@ DirectShowOutputPin::DirectShowOutputPin(DirectShowBaseFilter *filter, const QSt } -DirectShowOutputPin::~DirectShowOutputPin() -{ -} +DirectShowOutputPin::~DirectShowOutputPin() = default; HRESULT DirectShowOutputPin::completeConnection(IPin *pin) { @@ -511,10 +492,7 @@ DirectShowInputPin::DirectShowInputPin(DirectShowBaseFilter *filter, const QStri ZeroMemory(&m_sampleProperties, sizeof(m_sampleProperties)); } -DirectShowInputPin::~DirectShowInputPin() -{ - -} +DirectShowInputPin::~DirectShowInputPin() = default; HRESULT DirectShowInputPin::connectionEnded() { @@ -630,7 +608,8 @@ HRESULT DirectShowInputPin::Receive(IMediaSample *pSample) IMediaSample2 *sample2; if (SUCCEEDED(pSample->QueryInterface(IID_PPV_ARGS(&sample2)))) { - hr = sample2->GetProperties(sizeof(m_sampleProperties), (PBYTE)&m_sampleProperties); + hr = sample2->GetProperties(sizeof(m_sampleProperties), + reinterpret_cast<PBYTE>(&m_sampleProperties)); sample2->Release(); if (FAILED(hr)) return hr; diff --git a/src/plugins/directshow/common/directshowpin.h b/src/plugins/directshow/common/directshowpin.h index 9598cf525..5e513d002 100644 --- a/src/plugins/directshow/common/directshowpin.h +++ b/src/plugins/directshow/common/directshowpin.h @@ -68,30 +68,30 @@ public: virtual HRESULT setActive(bool active); // IPin - STDMETHODIMP Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); - STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); - STDMETHODIMP Disconnect(); - STDMETHODIMP ConnectedTo(IPin **ppPin); + STDMETHODIMP Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) override; + STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) override; + STDMETHODIMP Disconnect() override; + STDMETHODIMP ConnectedTo(IPin **ppPin) override; - STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt); + STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt) override; - STDMETHODIMP QueryPinInfo(PIN_INFO *pInfo); - STDMETHODIMP QueryId(LPWSTR *Id); + STDMETHODIMP QueryPinInfo(PIN_INFO *pInfo) override; + STDMETHODIMP QueryId(LPWSTR *Id) override; - STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt); + STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt) override; - STDMETHODIMP EnumMediaTypes(IEnumMediaTypes **ppEnum); + STDMETHODIMP EnumMediaTypes(IEnumMediaTypes **ppEnum) override; - STDMETHODIMP QueryInternalConnections(IPin **apPin, ULONG *nPin); + STDMETHODIMP QueryInternalConnections(IPin **apPin, ULONG *nPin) override; - STDMETHODIMP EndOfStream(); + STDMETHODIMP EndOfStream() override; - STDMETHODIMP BeginFlush(); - STDMETHODIMP EndFlush(); + STDMETHODIMP BeginFlush() override; + STDMETHODIMP EndFlush() override; - STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) override; - STDMETHODIMP QueryDirection(PIN_DIRECTION *pPinDir); + STDMETHODIMP QueryDirection(PIN_DIRECTION *pPinDir) override; protected: DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction); @@ -140,27 +140,28 @@ class DirectShowInputPin : public DirectShowPin , public IMemInputPin { public: - virtual ~DirectShowInputPin(); + ~DirectShowInputPin() override; const AM_SAMPLE2_PROPERTIES *currentSampleProperties() const { return &m_sampleProperties; } // DirectShowPin - HRESULT connectionEnded(); - HRESULT setActive(bool active); + HRESULT connectionEnded() override; + HRESULT setActive(bool active) override; // IPin - STDMETHODIMP EndOfStream(); - STDMETHODIMP BeginFlush(); - STDMETHODIMP EndFlush(); + STDMETHODIMP EndOfStream() override; + STDMETHODIMP BeginFlush() override; + STDMETHODIMP EndFlush() override; // IMemInputPin - STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator); - STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly); - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); - - STDMETHODIMP Receive(IMediaSample *pSample); - STDMETHODIMP ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed); - STDMETHODIMP ReceiveCanBlock(); + STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator) override; + STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) override; + STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) override; + + STDMETHODIMP Receive(IMediaSample *pSample) override; + STDMETHODIMP ReceiveMultiple(IMediaSample **pSamples, long nSamples, + long *nSamplesProcessed) override; + STDMETHODIMP ReceiveCanBlock() override; protected: DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name); diff --git a/src/plugins/directshow/common/directshowpinenum.cpp b/src/plugins/directshow/common/directshowpinenum.cpp index e0ab58d19..20fa93d6e 100644 --- a/src/plugins/directshow/common/directshowpinenum.cpp +++ b/src/plugins/directshow/common/directshowpinenum.cpp @@ -87,21 +87,20 @@ HRESULT DirectShowPinEnum::QueryInterface(REFIID riid, void **ppv) HRESULT DirectShowPinEnum::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) { - if (ppPins && (pcFetched || cPins == 1)) { - ULONG count = qBound<ULONG>(0, cPins, m_pins.count() - m_index); - - for (ULONG i = 0; i < count; ++i, ++m_index) { - ppPins[i] = m_pins.at(m_index); - ppPins[i]->AddRef(); - } + if (!ppPins || (!pcFetched && cPins != 1)) + return E_POINTER; - if (pcFetched) - *pcFetched = count; + ULONG count = qBound<ULONG>(0, cPins, m_pins.count() - m_index); - return count == cPins ? S_OK : S_FALSE; - } else { - return E_POINTER; + for (ULONG i = 0; i < count; ++i, ++m_index) { + ppPins[i] = m_pins.at(m_index); + ppPins[i]->AddRef(); } + + if (pcFetched) + *pcFetched = count; + + return count == cPins ? S_OK : S_FALSE; } HRESULT DirectShowPinEnum::Skip(ULONG cPins) @@ -120,16 +119,10 @@ HRESULT DirectShowPinEnum::Reset() HRESULT DirectShowPinEnum::Clone(IEnumPins **ppEnum) { - if (ppEnum) { - if (m_filter) - *ppEnum = new DirectShowPinEnum(m_filter); - else - *ppEnum = new DirectShowPinEnum(m_pins); - - return S_OK; - } else { + if (!ppEnum) return E_POINTER; - } + *ppEnum = m_filter ? new DirectShowPinEnum(m_filter) : new DirectShowPinEnum(m_pins); + return S_OK; } QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowsamplegrabber.cpp b/src/plugins/directshow/common/directshowsamplegrabber.cpp index fb95370ca..fec59b538 100644 --- a/src/plugins/directshow/common/directshowsamplegrabber.cpp +++ b/src/plugins/directshow/common/directshowsamplegrabber.cpp @@ -51,20 +51,21 @@ static const CLSID cLSID_SampleGrabber = { 0xC1F400A0, 0x3F08, 0x11d3, { 0x9F, 0 class SampleGrabberCallbackPrivate : public ISampleGrabberCB { + Q_DISABLE_COPY(SampleGrabberCallbackPrivate) public: explicit SampleGrabberCallbackPrivate(DirectShowSampleGrabber *grabber) : m_ref(1) , m_grabber(grabber) { } - virtual ~SampleGrabberCallbackPrivate() { } + virtual ~SampleGrabberCallbackPrivate() = default; - STDMETHODIMP_(ULONG) AddRef() + STDMETHODIMP_(ULONG) AddRef() override { return InterlockedIncrement(&m_ref); } - STDMETHODIMP_(ULONG) Release() + STDMETHODIMP_(ULONG) Release() override { ULONG ref = InterlockedDecrement(&m_ref); if (ref == 0) @@ -72,7 +73,7 @@ public: return ref; } - STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) + STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override { if (NULL == ppvObject) return E_POINTER; @@ -89,7 +90,7 @@ public: return E_NOTIMPL; } - STDMETHODIMP SampleCB(double time, IMediaSample *mediaSample) + STDMETHODIMP SampleCB(double time, IMediaSample *mediaSample) override { if (m_grabber) Q_EMIT m_grabber->sampleAvailable(time, mediaSample); @@ -97,7 +98,7 @@ public: return S_OK; } - STDMETHODIMP BufferCB(double time, BYTE *buffer, long bufferLen) + STDMETHODIMP BufferCB(double time, BYTE *buffer, long bufferLen) override { if (m_grabber) { // Deep copy, the data might be modified or freed after the callback returns diff --git a/src/plugins/directshow/common/directshowvideobuffer.h b/src/plugins/directshow/common/directshowvideobuffer.h index 85e02b53d..a85a3ca34 100644 --- a/src/plugins/directshow/common/directshowvideobuffer.h +++ b/src/plugins/directshow/common/directshowvideobuffer.h @@ -50,14 +50,14 @@ class DirectShowVideoBuffer : public QAbstractVideoBuffer { public: DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine); - ~DirectShowVideoBuffer(); + ~DirectShowVideoBuffer() override; IMediaSample *sample() { return m_sample; } - uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); - void unmap(); + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override; + void unmap() override; - MapMode mapMode() const; + MapMode mapMode() const override; private: IMediaSample *m_sample; diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp index cb4f0cdf9..64b30f561 100644 --- a/src/plugins/directshow/dsserviceplugin.cpp +++ b/src/plugins/directshow/dsserviceplugin.cpp @@ -114,10 +114,9 @@ void DSServicePlugin::release(QMediaService *service) QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures( const QByteArray &service) const { - if (service == Q_MEDIASERVICE_MEDIAPLAYER) - return QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface; - else - return QMediaServiceProviderHint::Features(); + return service == Q_MEDIASERVICE_MEDIAPLAYER + ? (QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface) + : QMediaServiceProviderHint::Features(); } QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const diff --git a/src/plugins/directshow/dsserviceplugin.h b/src/plugins/directshow/dsserviceplugin.h index f57262e37..2e87058c3 100644 --- a/src/plugins/directshow/dsserviceplugin.h +++ b/src/plugins/directshow/dsserviceplugin.h @@ -64,14 +64,14 @@ class DSServicePlugin #endif public: - QMediaService* create(QString const& key); - void release(QMediaService *service); + QMediaService* create(QString const& key) override; + void release(QMediaService *service) override; - QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const; + QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const override; - QByteArray defaultDevice(const QByteArray &service) const; - QList<QByteArray> devices(const QByteArray &service) const; - QString deviceDescription(const QByteArray &service, const QByteArray &device); + QByteArray defaultDevice(const QByteArray &service) const override; + QList<QByteArray> devices(const QByteArray &service) const override; + QString deviceDescription(const QByteArray &service, const QByteArray &device) override; }; QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowaudioendpointcontrol.h b/src/plugins/directshow/player/directshowaudioendpointcontrol.h index e0e6a1545..b6f8a6724 100644 --- a/src/plugins/directshow/player/directshowaudioendpointcontrol.h +++ b/src/plugins/directshow/player/directshowaudioendpointcontrol.h @@ -53,16 +53,16 @@ class DirectShowAudioEndpointControl : public QAudioOutputSelectorControl Q_OBJECT public: DirectShowAudioEndpointControl(DirectShowPlayerService *service, QObject *parent = 0); - ~DirectShowAudioEndpointControl(); + ~DirectShowAudioEndpointControl() override; - QList<QString> availableOutputs() const; + QList<QString> availableOutputs() const override; - QString outputDescription(const QString &name) const; + QString outputDescription(const QString &name) const override; - QString defaultOutput() const; - QString activeOutput() const; + QString defaultOutput() const override; + QString activeOutput() const override; - void setActiveOutput(const QString& name); + void setActiveOutput(const QString& name) override; private: void updateEndpoints(); diff --git a/src/plugins/directshow/player/directshowioreader.cpp b/src/plugins/directshow/player/directshowioreader.cpp index 7f3303633..3482cee02 100644 --- a/src/plugins/directshow/player/directshowioreader.cpp +++ b/src/plugins/directshow/player/directshowioreader.cpp @@ -123,76 +123,65 @@ ULONG DirectShowIOReader::Release() HRESULT DirectShowIOReader::RequestAllocator( IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual) { - if (!ppActual || !pProps) { + if (!ppActual || !pProps) return E_POINTER; - } else { - ALLOCATOR_PROPERTIES actualProperties; - if (pProps->cbAlign == 0) - pProps->cbAlign = 1; + ALLOCATOR_PROPERTIES actualProperties; - if (pPreferred && pPreferred->SetProperties(pProps, &actualProperties) == S_OK) { - pPreferred->AddRef(); + if (pProps->cbAlign == 0) + pProps->cbAlign = 1; - *ppActual = pPreferred; + if (pPreferred && pPreferred->SetProperties(pProps, &actualProperties) == S_OK) { + pPreferred->AddRef(); - m_source->setAllocator(*ppActual); + *ppActual = pPreferred; + m_source->setAllocator(*ppActual); + return S_OK; + } + *ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator); + if (*ppActual) { + if ((*ppActual)->SetProperties(pProps, &actualProperties) == S_OK) { + m_source->setAllocator(*ppActual); return S_OK; - } else { - *ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator); - - if (*ppActual) { - if ((*ppActual)->SetProperties(pProps, &actualProperties) != S_OK) { - (*ppActual)->Release(); - } else { - m_source->setAllocator(*ppActual); - - return S_OK; - } - } } - ppActual = 0; - - return E_FAIL; + (*ppActual)->Release(); } + ppActual = nullptr; + return E_FAIL; } HRESULT DirectShowIOReader::Request(IMediaSample *pSample, DWORD_PTR dwUser) { QMutexLocker locker(&m_mutex); - if (!pSample) { + if (!pSample) return E_POINTER; - } else if (m_flushing) { + if (m_flushing) return VFW_E_WRONG_STATE; - } else { - REFERENCE_TIME startTime = 0; - REFERENCE_TIME endTime = 0; - BYTE *buffer; - if (pSample->GetTime(&startTime, &endTime) != S_OK - || pSample->GetPointer(&buffer) != S_OK) { - return VFW_E_SAMPLE_TIME_NOT_SET; - } else { - LONGLONG position = startTime / 10000000; - LONG length = (endTime - startTime) / 10000000; - - DirectShowSampleRequest *request = new DirectShowSampleRequest( - pSample, dwUser, position, length, buffer); + REFERENCE_TIME startTime = 0; + REFERENCE_TIME endTime = 0; + BYTE *buffer; - if (m_pendingTail) { - m_pendingTail->next = request; - } else { - m_pendingHead = request; + if (pSample->GetTime(&startTime, &endTime) != S_OK + || pSample->GetPointer(&buffer) != S_OK) { + return VFW_E_SAMPLE_TIME_NOT_SET; + } + LONGLONG position = startTime / 10000000; + LONG length = (endTime - startTime) / 10000000; - m_loop->postEvent(this, new QEvent(QEvent::User)); - } - m_pendingTail = request; + auto request = new DirectShowSampleRequest(pSample, dwUser, position, length, buffer); - return S_OK; - } + if (m_pendingTail) { + m_pendingTail->next = request; + } else { + m_pendingHead = request; + m_loop->postEvent(this, new QEvent(QEvent::User)); } + m_pendingTail = request; + + return S_OK; } HRESULT DirectShowIOReader::WaitForNext( @@ -220,7 +209,8 @@ HRESULT DirectShowIOReader::WaitForNext( delete request; return hr; - } else if (m_flushing) { + } + if (m_flushing) { *ppSample = 0; *pdwUser = 0; @@ -236,90 +226,80 @@ HRESULT DirectShowIOReader::WaitForNext( HRESULT DirectShowIOReader::SyncReadAligned(IMediaSample *pSample) { - if (!pSample) { + if (!pSample) return E_POINTER; - } else { - REFERENCE_TIME startTime = 0; - REFERENCE_TIME endTime = 0; - BYTE *buffer; - if (pSample->GetTime(&startTime, &endTime) != S_OK - || pSample->GetPointer(&buffer) != S_OK) { - return VFW_E_SAMPLE_TIME_NOT_SET; - } else { - LONGLONG position = startTime / 10000000; - LONG length = (endTime - startTime) / 10000000; + REFERENCE_TIME startTime = 0; + REFERENCE_TIME endTime = 0; + BYTE *buffer; - QMutexLocker locker(&m_mutex); + if (pSample->GetTime(&startTime, &endTime) != S_OK + || pSample->GetPointer(&buffer) != S_OK) { + return VFW_E_SAMPLE_TIME_NOT_SET; + } + LONGLONG position = startTime / 10000000; + LONG length = (endTime - startTime) / 10000000; - if (thread() == QThread::currentThread()) { - qint64 bytesRead = 0; + QMutexLocker locker(&m_mutex); - HRESULT hr = blockingRead(position, length, buffer, &bytesRead); + if (thread() == QThread::currentThread()) { + qint64 bytesRead = 0; - if (SUCCEEDED(hr)) - pSample->SetActualDataLength(bytesRead); + HRESULT hr = blockingRead(position, length, buffer, &bytesRead); + if (SUCCEEDED(hr)) + pSample->SetActualDataLength(bytesRead); - return hr; - } else { - m_synchronousPosition = position; - m_synchronousLength = length; - m_synchronousBuffer = buffer; + return hr; + } + m_synchronousPosition = position; + m_synchronousLength = length; + m_synchronousBuffer = buffer; - m_loop->postEvent(this, new QEvent(QEvent::User)); + m_loop->postEvent(this, new QEvent(QEvent::User)); - m_wait.wait(&m_mutex); + m_wait.wait(&m_mutex); - m_synchronousBuffer = 0; + m_synchronousBuffer = nullptr; - if (SUCCEEDED(m_synchronousResult)) - pSample->SetActualDataLength(m_synchronousBytesRead); + if (SUCCEEDED(m_synchronousResult)) + pSample->SetActualDataLength(m_synchronousBytesRead); - return m_synchronousResult; - } - } - } + return m_synchronousResult; } HRESULT DirectShowIOReader::SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer) { - if (!pBuffer) { + if (!pBuffer) return E_POINTER; - } else { - if (thread() == QThread::currentThread()) { - qint64 bytesRead; - return blockingRead(llPosition, lLength, pBuffer, &bytesRead); - } else { - QMutexLocker locker(&m_mutex); + if (thread() == QThread::currentThread()) { + qint64 bytesRead; + return blockingRead(llPosition, lLength, pBuffer, &bytesRead); + } + QMutexLocker locker(&m_mutex); - m_synchronousPosition = llPosition; - m_synchronousLength = lLength; - m_synchronousBuffer = pBuffer; + m_synchronousPosition = llPosition; + m_synchronousLength = lLength; + m_synchronousBuffer = pBuffer; - m_loop->postEvent(this, new QEvent(QEvent::User)); + m_loop->postEvent(this, new QEvent(QEvent::User)); - m_wait.wait(&m_mutex); + m_wait.wait(&m_mutex); - m_synchronousBuffer = 0; + m_synchronousBuffer = nullptr; - return m_synchronousResult; - } - } + return m_synchronousResult; } HRESULT DirectShowIOReader::Length(LONGLONG *pTotal, LONGLONG *pAvailable) { - if (!pTotal || !pAvailable) { + if (!pTotal || !pAvailable) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - *pTotal = m_totalLength; - *pAvailable = m_availableLength; - - return S_OK; - } + QMutexLocker locker(&m_mutex); + *pTotal = m_totalLength; + *pAvailable = m_availableLength; + return S_OK; } @@ -432,9 +412,8 @@ HRESULT DirectShowIOReader::blockingRead( ::memset(buffer + *bytesRead, 0, length - *bytesRead); return S_FALSE; - } else { - return S_OK; } + return S_OK; } bool DirectShowIOReader::nonBlockingRead( @@ -447,30 +426,29 @@ bool DirectShowIOReader::nonBlockingRead( *result = S_FALSE; return true; - } else if (m_device->bytesAvailable() + m_device->pos() >= maxSize) { + } + if (m_device->bytesAvailable() + m_device->pos() >= maxSize) { if (m_device->pos() != position && !m_device->seek(position)) { *bytesRead = 0; *result = S_FALSE; return true; - } else { - const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable()); - - *bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes); + } + const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable()); - if (*bytesRead != length) { - ::memset(buffer + *bytesRead, 0, length - *bytesRead); + *bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes); - *result = S_FALSE; - } else { - *result = S_OK; - } + if (*bytesRead != length) { + ::memset(buffer + *bytesRead, 0, length - *bytesRead); - return true; + *result = S_FALSE; + } else { + *result = S_OK; } - } else { - return false; + + return true; } + return false; } void DirectShowIOReader::flushRequests() diff --git a/src/plugins/directshow/player/directshowioreader.h b/src/plugins/directshow/player/directshowioreader.h index 2d62c0b95..550990648 100644 --- a/src/plugins/directshow/player/directshowioreader.h +++ b/src/plugins/directshow/player/directshowioreader.h @@ -58,33 +58,34 @@ class DirectShowIOReader : public QObject, public IAsyncReader Q_OBJECT public: DirectShowIOReader(QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop); - ~DirectShowIOReader(); + ~DirectShowIOReader() override; // IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; + ULONG STDMETHODCALLTYPE AddRef() override; + ULONG STDMETHODCALLTYPE Release() override; // IAsyncReader HRESULT STDMETHODCALLTYPE RequestAllocator( - IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual); + IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, + IMemAllocator **ppActual) override; - HRESULT STDMETHODCALLTYPE Request(IMediaSample *pSample, DWORD_PTR dwUser); + HRESULT STDMETHODCALLTYPE Request(IMediaSample *pSample, DWORD_PTR dwUser) override; HRESULT STDMETHODCALLTYPE WaitForNext( - DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser); + DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser) override; - HRESULT STDMETHODCALLTYPE SyncReadAligned(IMediaSample *pSample); + HRESULT STDMETHODCALLTYPE SyncReadAligned(IMediaSample *pSample) override; - HRESULT STDMETHODCALLTYPE SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer); + HRESULT STDMETHODCALLTYPE SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer) override; - HRESULT STDMETHODCALLTYPE Length(LONGLONG *pTotal, LONGLONG *pAvailable); + HRESULT STDMETHODCALLTYPE Length(LONGLONG *pTotal, LONGLONG *pAvailable) override; - HRESULT STDMETHODCALLTYPE BeginFlush(); - HRESULT STDMETHODCALLTYPE EndFlush(); + HRESULT STDMETHODCALLTYPE BeginFlush() override; + HRESULT STDMETHODCALLTYPE EndFlush() override; protected: - void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private Q_SLOTS: void readyRead(); diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp index b3aa3fab9..31e9a1300 100644 --- a/src/plugins/directshow/player/directshowiosource.cpp +++ b/src/plugins/directshow/player/directshowiosource.cpp @@ -99,8 +99,8 @@ DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop) static const int count = sizeof(directshow_subtypes) / sizeof(GUID); - for (int i = 0; i < count; ++i) { - type.subtype = directshow_subtypes[i]; + for (const auto &directshowSubtype : directshow_subtypes) { + type.subtype = directshowSubtype; m_supportedMediaTypes.append(DirectShowMediaType(type)); } } @@ -140,12 +140,11 @@ HRESULT DirectShowIOSource::QueryInterface(REFIID riid, void **ppvObject) static const GUID iid_IAmFilterMiscFlags = { 0x2dd74950, 0xa890, 0x11d1, {0xab, 0xe8, 0x00, 0xa0, 0xc9, 0x05, 0xf3, 0x75}}; - if (!ppvObject) { + if (!ppvObject) return E_POINTER; - } else if (riid == IID_IUnknown - || riid == IID_IPersist - || riid == IID_IMediaFilter - || riid == IID_IBaseFilter) { + + if (riid == IID_IUnknown || riid == IID_IPersist || riid == IID_IMediaFilter + || riid == IID_IBaseFilter) { *ppvObject = static_cast<IBaseFilter *>(this); } else if (riid == iid_IAmFilterMiscFlags) { *ppvObject = static_cast<IAMFilterMiscFlags *>(this); @@ -222,15 +221,12 @@ HRESULT DirectShowIOSource::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pSt { Q_UNUSED(dwMilliSecsTimeout); - if (!pState) { + if (!pState) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - *pState = m_state; - return S_OK; - } + QMutexLocker locker(&m_mutex); + *pState = m_state; + return S_OK; } HRESULT DirectShowIOSource::SetSyncSource(IReferenceClock *pClock) @@ -250,53 +246,41 @@ HRESULT DirectShowIOSource::SetSyncSource(IReferenceClock *pClock) HRESULT DirectShowIOSource::GetSyncSource(IReferenceClock **ppClock) { - if (!ppClock) { + if (!ppClock) return E_POINTER; - } else { - if (!m_clock) { - *ppClock = 0; - - return S_FALSE; - } else { - m_clock->AddRef(); - *ppClock = m_clock; - - return S_OK; - } + if (!m_clock) { + *ppClock = nullptr; + return S_FALSE; } + m_clock->AddRef(); + *ppClock = m_clock; + return S_OK; } // IBaseFilter HRESULT DirectShowIOSource::EnumPins(IEnumPins **ppEnum) { - if (!ppEnum) { + if (!ppEnum) return E_POINTER; - } else { - *ppEnum = new DirectShowPinEnum(QList<IPin *>() << this); - return S_OK; - } + *ppEnum = new DirectShowPinEnum(QList<IPin *>() << this); + return S_OK; } HRESULT DirectShowIOSource::FindPin(LPCWSTR Id, IPin **ppPin) { - if (!ppPin || !Id) { + if (!ppPin || !Id) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - if (QString::fromWCharArray(Id) == m_pinId) { - AddRef(); - - *ppPin = this; - return S_OK; - } else { - *ppPin = 0; - - return VFW_E_NOT_FOUND; - } + QMutexLocker locker(&m_mutex); + if (m_pinId == QStringView(Id)) { + AddRef(); + *ppPin = this; + return S_OK; } + *ppPin = nullptr; + return VFW_E_NOT_FOUND; } HRESULT DirectShowIOSource::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) @@ -311,24 +295,22 @@ HRESULT DirectShowIOSource::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) HRESULT DirectShowIOSource::QueryFilterInfo(FILTER_INFO *pInfo) { - if (!pInfo) { + if (!pInfo) return E_POINTER; - } else { - QString name = m_filterName; - if (name.length() >= MAX_FILTER_NAME) - name.truncate(MAX_FILTER_NAME - 1); + QString name = m_filterName; + if (name.length() >= MAX_FILTER_NAME) + name.truncate(MAX_FILTER_NAME - 1); - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; - if (m_graph) - m_graph->AddRef(); + if (m_graph) + m_graph->AddRef(); - pInfo->pGraph = m_graph; + pInfo->pGraph = m_graph; - return S_OK; - } + return S_OK; } HRESULT DirectShowIOSource::QueryVendorInfo(LPWSTR *pVendorInfo) @@ -424,121 +406,96 @@ HRESULT DirectShowIOSource::Disconnect() { QMutexLocker locker(&m_mutex); - if (!m_peerPin) { + if (!m_peerPin) return S_FALSE; - } else if (m_state != State_Stopped) { + if (m_state != State_Stopped) return VFW_E_NOT_STOPPED; - } else { - HRESULT hr = m_peerPin->Disconnect(); - if (!SUCCEEDED(hr)) - return hr; + HRESULT hr = m_peerPin->Disconnect(); + if (!SUCCEEDED(hr)) + return hr; - if (m_allocator) { - m_allocator->Release(); - m_allocator = 0; - } + if (m_allocator) { + m_allocator->Release(); + m_allocator = nullptr; + } - m_peerPin->Release(); - m_peerPin = 0; + m_peerPin->Release(); + m_peerPin = nullptr; - return S_OK; - } + return S_OK; } HRESULT DirectShowIOSource::ConnectedTo(IPin **ppPin) { - if (!ppPin) { + if (!ppPin) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - if (!m_peerPin) { - *ppPin = 0; - - return VFW_E_NOT_CONNECTED; - } else { - m_peerPin->AddRef(); - - *ppPin = m_peerPin; - - return S_OK; - } + QMutexLocker locker(&m_mutex); + if (!m_peerPin) { + *ppPin = nullptr; + return VFW_E_NOT_CONNECTED; } + m_peerPin->AddRef(); + *ppPin = m_peerPin; + return S_OK; } HRESULT DirectShowIOSource::ConnectionMediaType(AM_MEDIA_TYPE *pmt) { - if (!pmt) { + if (!pmt) return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) { - pmt = 0; - return VFW_E_NOT_CONNECTED; - } else { - DirectShowMediaType::copy(pmt, &m_connectionMediaType); - - return S_OK; - } + QMutexLocker locker(&m_mutex); + if (!m_peerPin) { + pmt = nullptr; + return VFW_E_NOT_CONNECTED; } + DirectShowMediaType::copy(pmt, &m_connectionMediaType); + return S_OK; } HRESULT DirectShowIOSource::QueryPinInfo(PIN_INFO *pInfo) { - if (!pInfo) { + if (!pInfo) return E_POINTER; - } else { - AddRef(); - pInfo->pFilter = this; - pInfo->dir = PINDIR_OUTPUT; + AddRef(); - const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2); + pInfo->pFilter = this; + pInfo->dir = PINDIR_OUTPUT; - ::memcpy(pInfo->achName, m_pinId.utf16(), bytes); + const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2); - return S_OK; - } + ::memcpy(pInfo->achName, m_pinId.utf16(), bytes); + + return S_OK; } HRESULT DirectShowIOSource::QueryId(LPWSTR *Id) { - if (!Id) { + if (!Id) return E_POINTER; - } else { - const int bytes = (m_pinId.length() + 1) * 2; - - *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); - - ::memcpy(*Id, m_pinId.utf16(), bytes); - return S_OK; - } + const int bytes = (m_pinId.length() + 1) * 2; + *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); + ::memcpy(*Id, m_pinId.utf16(), bytes); + return S_OK; } HRESULT DirectShowIOSource::QueryAccept(const AM_MEDIA_TYPE *pmt) { - if (!pmt) { + if (!pmt) return E_POINTER; - } else if (pmt->majortype == MEDIATYPE_Stream) { - return S_OK; - } else { - return S_FALSE; - } + return pmt->majortype == MEDIATYPE_Stream ? S_OK : S_FALSE; } HRESULT DirectShowIOSource::EnumMediaTypes(IEnumMediaTypes **ppEnum) { - if (!ppEnum) { + if (!ppEnum) return E_POINTER; - } else { - *ppEnum = new DirectShowMediaTypeEnum(m_supportedMediaTypes); - - return S_OK; - } + *ppEnum = new DirectShowMediaTypeEnum(m_supportedMediaTypes); + return S_OK; } HRESULT DirectShowIOSource::QueryInternalConnections(IPin **apPin, ULONG *nPin) @@ -575,13 +532,10 @@ HRESULT DirectShowIOSource::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tSt HRESULT DirectShowIOSource::QueryDirection(PIN_DIRECTION *pPinDir) { - if (!pPinDir) { + if (!pPinDir) return E_POINTER; - } else { - *pPinDir = PINDIR_OUTPUT; - - return S_OK; - } + *pPinDir = PINDIR_OUTPUT; + return S_OK; } QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowiosource.h b/src/plugins/directshow/player/directshowiosource.h index 43df6c34f..02639de7c 100644 --- a/src/plugins/directshow/player/directshowiosource.h +++ b/src/plugins/directshow/player/directshowiosource.h @@ -53,6 +53,7 @@ class DirectShowIOSource , public IAMFilterMiscFlags , public IPin { + Q_DISABLE_COPY(DirectShowIOSource) public: DirectShowIOSource(DirectShowEventLoop *loop); virtual ~DirectShowIOSource(); @@ -61,60 +62,61 @@ public: void setAllocator(IMemAllocator *allocator); // IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; + ULONG STDMETHODCALLTYPE AddRef() override; + ULONG STDMETHODCALLTYPE Release() override; // IPersist - HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID); + HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID) override; // IMediaFilter - HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart); - HRESULT STDMETHODCALLTYPE Pause(); - HRESULT STDMETHODCALLTYPE Stop(); + HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart) override; + HRESULT STDMETHODCALLTYPE Pause() override; + HRESULT STDMETHODCALLTYPE Stop() override; - HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState); + HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) override; - HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock); - HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock); + HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock) override; + HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock) override; // IBaseFilter - HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum); - HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin); + HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum) override; + HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin) override; - HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); + HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) override; - HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo); - HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo); + HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo) override; + HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo) override; // IAMFilterMiscFlags - ULONG STDMETHODCALLTYPE GetMiscFlags(); + ULONG STDMETHODCALLTYPE GetMiscFlags() override; // IPin - HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); - HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); - HRESULT STDMETHODCALLTYPE Disconnect(); - HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin); + HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) override; + HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) override; + HRESULT STDMETHODCALLTYPE Disconnect() override; + HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin) override; - HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt) override; - HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo); - HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id); + HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo) override; + HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id) override; - HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt) override; - HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum); + HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum) override; - HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin); + HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin) override; - HRESULT STDMETHODCALLTYPE EndOfStream(); + HRESULT STDMETHODCALLTYPE EndOfStream() override; - HRESULT STDMETHODCALLTYPE BeginFlush(); - HRESULT STDMETHODCALLTYPE EndFlush(); + HRESULT STDMETHODCALLTYPE BeginFlush() override; + HRESULT STDMETHODCALLTYPE EndFlush() override; - HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, + double dRate) override; - HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir); + HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir) override; private: volatile LONG m_ref; diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.cpp b/src/plugins/directshow/player/directshowmetadatacontrol.cpp index 84f990830..90d2b3e7d 100644 --- a/src/plugins/directshow/player/directshowmetadatacontrol.cpp +++ b/src/plugins/directshow/player/directshowmetadatacontrol.cpp @@ -113,101 +113,99 @@ static QString nameForGUIDString(const QString &guid) // Audio formats if (guid == "{00001610-0000-0010-8000-00AA00389B71}" || guid == "{000000FF-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG AAC Audio"); - else if (guid == "{00001600-0000-0010-8000-00AA00389B71}") + if (guid == "{00001600-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG ADTS AAC Audio"); - else if (guid == "{00000092-0000-0010-8000-00AA00389B71}") + if (guid == "{00000092-0000-0010-8000-00AA00389B71}") return QStringLiteral("Dolby AC-3 SPDIF"); - else if (guid == "{E06D802C-DB46-11CF-B4D1-00805F6CBBEA}" || guid == "{00002000-0000-0010-8000-00AA00389B71}") + if (guid == "{E06D802C-DB46-11CF-B4D1-00805F6CBBEA}" || guid == "{00002000-0000-0010-8000-00AA00389B71}") return QStringLiteral("Dolby AC-3"); - else if (guid == "{A7FB87AF-2D02-42FB-A4D4-05CD93843BDD}") + if (guid == "{A7FB87AF-2D02-42FB-A4D4-05CD93843BDD}") return QStringLiteral("Dolby Digital Plus"); - else if (guid == "{00000009-0000-0010-8000-00AA00389B71}") + if (guid == "{00000009-0000-0010-8000-00AA00389B71}") return QStringLiteral("DRM"); - else if (guid == "{00000008-0000-0010-8000-00AA00389B71}") + if (guid == "{00000008-0000-0010-8000-00AA00389B71}") return QStringLiteral("Digital Theater Systems Audio (DTS)"); - else if (guid == "{00000003-0000-0010-8000-00AA00389B71}") + if (guid == "{00000003-0000-0010-8000-00AA00389B71}") return QStringLiteral("IEEE Float Audio"); - else if (guid == "{00000055-0000-0010-8000-00AA00389B71}") + if (guid == "{00000055-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG Audio Layer-3 (MP3)"); - else if (guid == "{00000050-0000-0010-8000-00AA00389B71}") + if (guid == "{00000050-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG-1 Audio"); - else if (guid == "{2E6D7033-767A-494D-B478-F29D25DC9037}") + if (guid == "{2E6D7033-767A-494D-B478-F29D25DC9037}") return QStringLiteral("MPEG Audio Layer 1/2"); - else if (guid == "{0000000A-0000-0010-8000-00AA00389B71}") + if (guid == "{0000000A-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Audio Voice"); - else if (guid == "{00000001-0000-0010-8000-00AA00389B71}") + if (guid == "{00000001-0000-0010-8000-00AA00389B71}") return QStringLiteral("Uncompressed PCM Audio"); - else if (guid == "{00000164-0000-0010-8000-00AA00389B71}") + if (guid == "{00000164-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Audio 9 SPDIF"); - else if (guid == "{00000161-0000-0010-8000-00AA00389B71}") + if (guid == "{00000161-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Audio 8 (WMA2)"); - else if (guid == "{00000162-0000-0010-8000-00AA00389B71}") + if (guid == "{00000162-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Audio 9 (WMA3"); - else if (guid == "{00000163-0000-0010-8000-00AA00389B71}") + if (guid == "{00000163-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Audio 9 Lossless"); - else if (guid == "{8D2FD10B-5841-4a6b-8905-588FEC1ADED9}") + if (guid == "{8D2FD10B-5841-4a6b-8905-588FEC1ADED9}") return QStringLiteral("Vorbis"); - else if (guid == "{0000F1AC-0000-0010-8000-00AA00389B71}") + if (guid == "{0000F1AC-0000-0010-8000-00AA00389B71}") return QStringLiteral("Free Lossless Audio Codec (FLAC)"); - else if (guid == "{00006C61-0000-0010-8000-00AA00389B71}") + if (guid == "{00006C61-0000-0010-8000-00AA00389B71}") return QStringLiteral("Apple Lossless Audio Codec (ALAC)"); // Video formats if (guid == "{35327664-0000-0010-8000-00AA00389B71}") return QStringLiteral("DVCPRO 25 (DV25)"); - else if (guid == "{30357664-0000-0010-8000-00AA00389B71}") + if (guid == "{30357664-0000-0010-8000-00AA00389B71}") return QStringLiteral("DVCPRO 50 (DV50)"); - else if (guid == "{20637664-0000-0010-8000-00AA00389B71}") + if (guid == "{20637664-0000-0010-8000-00AA00389B71}") return QStringLiteral("DVC/DV Video"); - else if (guid == "{31687664-0000-0010-8000-00AA00389B71}") + if (guid == "{31687664-0000-0010-8000-00AA00389B71}") return QStringLiteral("DVCPRO 100 (DVH1)"); - else if (guid == "{64687664-0000-0010-8000-00AA00389B71}") + if (guid == "{64687664-0000-0010-8000-00AA00389B71}") return QStringLiteral("HD-DVCR (DVHD)"); - else if (guid == "{64737664-0000-0010-8000-00AA00389B71}") + if (guid == "{64737664-0000-0010-8000-00AA00389B71}") return QStringLiteral("SDL-DVCR (DVSD)"); - else if (guid == "{6C737664-0000-0010-8000-00AA00389B71}") + if (guid == "{6C737664-0000-0010-8000-00AA00389B71}") return QStringLiteral("SD-DVCR (DVSL)"); - else if (guid == "{33363248-0000-0010-8000-00AA00389B71}") + if (guid == "{33363248-0000-0010-8000-00AA00389B71}") return QStringLiteral("H.263 Video"); - else if (guid == "{34363248-0000-0010-8000-00AA00389B71}") + if (guid == "{34363248-0000-0010-8000-00AA00389B71}") return QStringLiteral("H.264 Video"); - else if (guid == "{35363248-0000-0010-8000-00AA00389B71}") + if (guid == "{35363248-0000-0010-8000-00AA00389B71}") return QStringLiteral("H.265 Video"); - else if (guid == "{43564548-0000-0010-8000-00AA00389B71}") + if (guid == "{43564548-0000-0010-8000-00AA00389B71}") return QStringLiteral("High Efficiency Video Coding (HEVC)"); - else if (guid == "{3253344D-0000-0010-8000-00AA00389B71}") + if (guid == "{3253344D-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG-4 part 2 Video (M4S2)"); - else if (guid == "{47504A4D-0000-0010-8000-00AA00389B71}") + if (guid == "{47504A4D-0000-0010-8000-00AA00389B71}") return QStringLiteral("Motion JPEG (MJPG)"); - else if (guid == "{3334504D-0000-0010-8000-00AA00389B71}") + if (guid == "{3334504D-0000-0010-8000-00AA00389B71}") return QStringLiteral("Microsoft MPEG 4 version 3 (MP43)"); - else if (guid == "{5334504D-0000-0010-8000-00AA00389B71}") + if (guid == "{5334504D-0000-0010-8000-00AA00389B71}") return QStringLiteral("ISO MPEG 4 version 1 (MP4S)"); - else if (guid == "{5634504D-0000-0010-8000-00AA00389B71}") + if (guid == "{5634504D-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG-4 part 2 Video (MP4V)"); - else if (guid == "{E06D8026-DB46-11CF-B4D1-00805F6CBBEA}") + if (guid == "{E06D8026-DB46-11CF-B4D1-00805F6CBBEA}") return QStringLiteral("MPEG-2 Video"); - else if (guid == "{3147504D-0000-0010-8000-00AA00389B71}") + if (guid == "{3147504D-0000-0010-8000-00AA00389B71}") return QStringLiteral("MPEG-1 Video"); - else if (guid == "{3153534D-0000-0010-8000-00AA00389B71}") + if (guid == "{3153534D-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Screen 1 (MSS1)"); - else if (guid == "{3253534D-0000-0010-8000-00AA00389B71}") + if (guid == "{3253534D-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Video 9 Screen (MSS2)"); - else if (guid == "{31564D57-0000-0010-8000-00AA00389B71}") + if (guid == "{31564D57-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Video 7 (WMV1)"); - else if (guid == "{32564D57-0000-0010-8000-00AA00389B71}") + if (guid == "{32564D57-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Video 8 (WMV2)"); - else if (guid == "{33564D57-0000-0010-8000-00AA00389B71}") + if (guid == "{33564D57-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Video 9 (WMV3)"); - else if (guid == "{31435657-0000-0010-8000-00AA00389B71}") + if (guid == "{31435657-0000-0010-8000-00AA00389B71}") return QStringLiteral("Windows Media Video VC1 (WVC1)"); - else if (guid == "{30385056-0000-0010-8000-00AA00389B71}") + if (guid == "{30385056-0000-0010-8000-00AA00389B71}") return QStringLiteral("VP8 Video"); - else if (guid == "{30395056-0000-0010-8000-00AA00389B71}") + if (guid == "{30395056-0000-0010-8000-00AA00389B71}") return QStringLiteral("VP9 Video"); - - else - return QStringLiteral("Unknown codec"); + return QStringLiteral("Unknown codec"); } typedef HRESULT (WINAPI *q_SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **); @@ -451,9 +449,7 @@ DirectShowMetaDataControl::DirectShowMetaDataControl(QObject *parent) { } -DirectShowMetaDataControl::~DirectShowMetaDataControl() -{ -} +DirectShowMetaDataControl::~DirectShowMetaDataControl() = default; bool DirectShowMetaDataControl::isMetaDataAvailable() const { diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.h b/src/plugins/directshow/player/directshowmetadatacontrol.h index 3d2fa5e8e..ea20bf0c5 100644 --- a/src/plugins/directshow/player/directshowmetadatacontrol.h +++ b/src/plugins/directshow/player/directshowmetadatacontrol.h @@ -55,19 +55,19 @@ class DirectShowMetaDataControl : public QMetaDataReaderControl Q_OBJECT public: DirectShowMetaDataControl(QObject *parent = 0); - ~DirectShowMetaDataControl(); + ~DirectShowMetaDataControl() override; - bool isMetaDataAvailable() const; + bool isMetaDataAvailable() const override; - QVariant metaData(const QString &key) const; - QStringList availableMetaData() const; + QVariant metaData(const QString &key) const override; + QStringList availableMetaData() const override; void reset(); void updateMetadata(IFilterGraph2 *graph, IBaseFilter *source, const QString &fileSrc = QString()); protected: - void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private: void setMetadataAvailable(bool available); diff --git a/src/plugins/directshow/player/directshowplayercontrol.h b/src/plugins/directshow/player/directshowplayercontrol.h index fd2c21c38..dba9ab9a0 100644 --- a/src/plugins/directshow/player/directshowplayercontrol.h +++ b/src/plugins/directshow/player/directshowplayercontrol.h @@ -56,42 +56,42 @@ class DirectShowPlayerControl : public QMediaPlayerControl Q_OBJECT public: DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent = 0); - ~DirectShowPlayerControl(); + ~DirectShowPlayerControl() override; - QMediaPlayer::State state() const; + QMediaPlayer::State state() const override; - QMediaPlayer::MediaStatus mediaStatus() const; + QMediaPlayer::MediaStatus mediaStatus() const override; - qint64 duration() const; + qint64 duration() const override; - qint64 position() const; - void setPosition(qint64 position); + qint64 position() const override; + void setPosition(qint64 position) override; - int volume() const; - void setVolume(int volume); + int volume() const override; + void setVolume(int volume) override; - bool isMuted() const; - void setMuted(bool muted); + bool isMuted() const override; + void setMuted(bool muted) override; - int bufferStatus() const; + int bufferStatus() const override; - bool isAudioAvailable() const; - bool isVideoAvailable() const; + bool isAudioAvailable() const override; + bool isVideoAvailable() const override; - bool isSeekable() const; + bool isSeekable() const override; - QMediaTimeRange availablePlaybackRanges() const; + QMediaTimeRange availablePlaybackRanges() const override; - qreal playbackRate() const; - void setPlaybackRate(qreal rate); + qreal playbackRate() const override; + void setPlaybackRate(qreal rate) override; - QMediaContent media() const; - const QIODevice *mediaStream() const; - void setMedia(const QMediaContent &media, QIODevice *stream); + QMediaContent media() const override; + const QIODevice *mediaStream() const override; + void setMedia(const QMediaContent &media, QIODevice *stream) override; - void play(); - void pause(); - void stop(); + void play() override; + void pause() override; + void stop() override; void updateState(QMediaPlayer::State state); void updateStatus(QMediaPlayer::MediaStatus status); @@ -102,7 +102,7 @@ public: void updatePosition(qint64 position); protected: - void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private: enum Properties diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index b975677a6..27108063d 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -61,6 +61,8 @@ #if QT_CONFIG(evr) #include "directshowevrvideowindowcontrol.h" +#else +#include <mmreg.h> #endif #include "qmediacontent.h" @@ -113,7 +115,7 @@ public: } protected: - void run() { m_service->run(); } + void run() override { m_service->run(); } private: DirectShowPlayerService *m_service; @@ -217,11 +219,13 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) IBaseFilter *filter; #if QT_CONFIG(evr) - DirectShowEvrVideoWindowControl *evrControl = new DirectShowEvrVideoWindowControl; - if ((filter = evrControl->filter())) - m_videoWindowControl = evrControl; - else - delete evrControl; + if (!qgetenv("QT_DIRECTSHOW_NO_EVR").toInt()) { + DirectShowEvrVideoWindowControl *evrControl = new DirectShowEvrVideoWindowControl; + if ((filter = evrControl->filter())) + m_videoWindowControl = evrControl; + else + delete evrControl; + } #endif // Fall back to the VMR9 if the EVR is not available if (!m_videoWindowControl) { @@ -1092,9 +1096,9 @@ qint64 DirectShowPlayerService::position() const QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); if (m_graphStatus == Loaded) { - if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek)) { + if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek)) return m_position; - } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { LONGLONG position = 0; seeking->GetCurrentPosition(&position); @@ -1113,9 +1117,9 @@ QMediaTimeRange DirectShowPlayerService::availablePlaybackRanges() const QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); if (m_graphStatus == Loaded) { - if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek)) { + if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek)) return m_playbackRange; - } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { LONGLONG minimum = 0; LONGLONG maximum = 0; @@ -1196,9 +1200,8 @@ int DirectShowPlayerService::bufferStatus() const reader->Release(); return percentage; - } else { - return 0; } + return 0; #else return 0; #endif diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h index 01d05449e..4a9e25678 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -79,10 +79,10 @@ public: }; DirectShowPlayerService(QObject *parent = 0); - ~DirectShowPlayerService(); + ~DirectShowPlayerService() override; - QMediaControl* requestControl(const char *name); - void releaseControl(QMediaControl *control); + QMediaControl *requestControl(const char *name) override; + void releaseControl(QMediaControl *control) override; void load(const QMediaContent &media, QIODevice *stream); void play(); @@ -101,7 +101,7 @@ public: void setVideoOutput(IBaseFilter *filter); protected: - void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private Q_SLOTS: void videoOutputChanged(); diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp index ee7f5ec9e..88b5a51eb 100644 --- a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp +++ b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp @@ -98,13 +98,15 @@ void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface) if (m_surface) { #if QT_CONFIG(evr) - m_filter = com_new<IBaseFilter>(clsid_EnhancedVideoRenderer); - m_evrPresenter = new EVRCustomPresenter(m_surface); - if (!m_evrPresenter->isValid() || !qt_evr_setCustomPresenter(m_filter, m_evrPresenter)) { - m_filter->Release(); - m_filter = 0; - m_evrPresenter->Release(); - m_evrPresenter = 0; + if (!qgetenv("QT_DIRECTSHOW_NO_EVR").toInt()) { + m_filter = com_new<IBaseFilter>(clsid_EnhancedVideoRenderer); + m_evrPresenter = new EVRCustomPresenter(m_surface); + if (!m_evrPresenter->isValid() || !qt_evr_setCustomPresenter(m_filter, m_evrPresenter)) { + m_filter->Release(); + m_filter = 0; + m_evrPresenter->Release(); + m_evrPresenter = 0; + } } if (!m_filter) diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.h b/src/plugins/directshow/player/directshowvideorenderercontrol.h index ce515a329..b2abeeaed 100644 --- a/src/plugins/directshow/player/directshowvideorenderercontrol.h +++ b/src/plugins/directshow/player/directshowvideorenderercontrol.h @@ -59,10 +59,10 @@ class DirectShowVideoRendererControl : public QVideoRendererControl Q_OBJECT public: DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent = 0); - ~DirectShowVideoRendererControl(); + ~DirectShowVideoRendererControl() override; - QAbstractVideoSurface *surface() const; - void setSurface(QAbstractVideoSurface *surface); + QAbstractVideoSurface *surface() const override; + void setSurface(QAbstractVideoSurface *surface) override; IBaseFilter *filter(); diff --git a/src/plugins/directshow/player/player.pri b/src/plugins/directshow/player/player.pri index 9111cc545..ec1066db7 100644 --- a/src/plugins/directshow/player/player.pri +++ b/src/plugins/directshow/player/player.pri @@ -37,6 +37,8 @@ qtConfig(evr) { SOURCES += \ $$PWD/directshowevrvideowindowcontrol.cpp +} else { + LIBS += -lwinmm } qtConfig(wshellitem): \ diff --git a/src/plugins/directshow/player/videosurfacefilter.cpp b/src/plugins/directshow/player/videosurfacefilter.cpp index c521a251b..826d26bdb 100644 --- a/src/plugins/directshow/player/videosurfacefilter.cpp +++ b/src/plugins/directshow/player/videosurfacefilter.cpp @@ -330,12 +330,11 @@ bool VideoSurfaceFilter::setMediaType(const AM_MEDIA_TYPE *type) m_surfaceFormat = QVideoSurfaceFormat(); m_bytesPerLine = 0; return true; - } else { - m_surfaceFormat = DirectShowMediaType::videoFormatFromType(type); - m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat); - qCDebug(qLcRenderFilter) << "setMediaType -->" << m_surfaceFormat; - return m_surfaceFormat.isValid(); } + m_surfaceFormat = DirectShowMediaType::videoFormatFromType(type); + m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat); + qCDebug(qLcRenderFilter) << "setMediaType -->" << m_surfaceFormat; + return m_surfaceFormat.isValid(); } HRESULT VideoSurfaceFilter::completeConnection(IPin *pin) @@ -344,10 +343,7 @@ HRESULT VideoSurfaceFilter::completeConnection(IPin *pin) qCDebug(qLcRenderFilter, "completeConnection"); - if (!startSurface()) - return VFW_E_TYPE_NOT_ACCEPTED; - else - return S_OK; + return startSurface() ? S_OK : VFW_E_TYPE_NOT_ACCEPTED; } HRESULT VideoSurfaceFilter::connectionEnded() @@ -783,32 +779,40 @@ void VideoSurfaceFilter::renderPendingSample() bool VideoSurfaceFilter::event(QEvent *e) { - if (e->type() == QEvent::Type(StartSurface)) { + switch (e->type()) { + case StartSurface: { QMutexLocker locker(&m_mutex); startSurface(); m_waitSurface.wakeAll(); return true; - } else if (e->type() == QEvent::Type(StopSurface)) { + } + case StopSurface: { QMutexLocker locker(&m_mutex); stopSurface(); m_waitSurface.wakeAll(); return true; - } else if (e->type() == QEvent::Type(RestartSurface)) { + } + case RestartSurface: { QMutexLocker locker(&m_mutex); restartSurface(); m_waitSurface.wakeAll(); return true; - } else if (e->type() == QEvent::Type(FlushSurface)) { + } + case FlushSurface: { QMutexLocker locker(&m_mutex); flushSurface(); m_waitSurface.wakeAll(); return true; - } else if (e->type() == QEvent::Type(RenderSample)) { + } + case RenderSample: { QMutexLocker locker(&m_mutex); renderPendingSample(); m_waitSurface.wakeAll(); return true; } + default: + break; + } return QObject::event(e); } diff --git a/src/plugins/directshow/player/vmr9videowindowcontrol.h b/src/plugins/directshow/player/vmr9videowindowcontrol.h index ed3b53233..8ab9bd506 100644 --- a/src/plugins/directshow/player/vmr9videowindowcontrol.h +++ b/src/plugins/directshow/player/vmr9videowindowcontrol.h @@ -53,37 +53,37 @@ class Vmr9VideoWindowControl : public QVideoWindowControl Q_OBJECT public: Vmr9VideoWindowControl(QObject *parent = 0); - ~Vmr9VideoWindowControl(); + ~Vmr9VideoWindowControl() override; IBaseFilter *filter() const { return m_filter; } - WId winId() const; - void setWinId(WId id); + WId winId() const override; + void setWinId(WId id) override; - QRect displayRect() const; - void setDisplayRect(const QRect &rect); + QRect displayRect() const override; + void setDisplayRect(const QRect &rect) override; - bool isFullScreen() const; - void setFullScreen(bool fullScreen); + bool isFullScreen() const override; + void setFullScreen(bool fullScreen) override; - void repaint(); + void repaint() override; - QSize nativeSize() const; + QSize nativeSize() const override; - Qt::AspectRatioMode aspectRatioMode() const; - void setAspectRatioMode(Qt::AspectRatioMode mode); + Qt::AspectRatioMode aspectRatioMode() const override; + void setAspectRatioMode(Qt::AspectRatioMode mode) override; - int brightness() const; - void setBrightness(int brightness); + int brightness() const override; + void setBrightness(int brightness) override; - int contrast() const; - void setContrast(int contrast); + int contrast() const override; + void setContrast(int contrast) override; - int hue() const; - void setHue(int hue); + int hue() const override; + void setHue(int hue) override; - int saturation() const; - void setSaturation(int saturation); + int saturation() const override; + void setSaturation(int saturation) override; private: void setProcAmpValues(); diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp index b268592c6..c83e467a6 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp @@ -107,8 +107,6 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap qWarning() << QMediaRecorder::Error(e) << ":" << str.toLatin1().constData(); }); m_mediaContainerControl = new QGstreamerMediaContainerControl(this); - - setState(StoppedState); } QGstreamerCaptureSession::~QGstreamerCaptureSession() diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp index 958204803..ba26d8df8 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp @@ -115,6 +115,9 @@ void QGstreamerRecorderControl::updateStatus() if (m_status != newStatus) { m_status = newStatus; emit statusChanged(m_status); + // If stop has been called and session state became stopped. + if (m_status == QMediaRecorder::LoadedStatus) + emit stateChanged(m_state); } } @@ -204,7 +207,6 @@ void QGstreamerRecorderControl::stop() m_session->setState(QGstreamerCaptureSession::PreviewState); } - emit stateChanged(m_state); updateStatus(); } diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro index 5ccf89bfd..8150d8f5b 100644 --- a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro +++ b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro @@ -5,18 +5,14 @@ include(../common.pri) INCLUDEPATH += $$PWD HEADERS += \ - $$PWD/qgstreamerplayercontrol.h \ $$PWD/qgstreamerplayerservice.h \ - $$PWD/qgstreamerplayersession.h \ $$PWD/qgstreamerstreamscontrol.h \ $$PWD/qgstreamermetadataprovider.h \ $$PWD/qgstreameravailabilitycontrol.h \ $$PWD/qgstreamerplayerserviceplugin.h SOURCES += \ - $$PWD/qgstreamerplayercontrol.cpp \ $$PWD/qgstreamerplayerservice.cpp \ - $$PWD/qgstreamerplayersession.cpp \ $$PWD/qgstreamerstreamscontrol.cpp \ $$PWD/qgstreamermetadataprovider.cpp \ $$PWD/qgstreameravailabilitycontrol.cpp \ diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp index b9e29245f..50ab0256b 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "qgstreamermetadataprovider.h" -#include "qgstreamerplayersession.h" +#include <private/qgstreamerplayersession_p.h> #include <QDebug> #include <QtMultimedia/qmediametadata.h> diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp deleted file mode 100644 index ff17e37eb..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerplayercontrol.h" -#include "qgstreamerplayersession.h" - -#include <private/qmediaplaylistnavigator_p.h> -#include <private/qmediaresourcepolicy_p.h> -#include <private/qmediaresourceset_p.h> - -#include <QtCore/qdir.h> -#include <QtCore/qsocketnotifier.h> -#include <QtCore/qurl.h> -#include <QtCore/qdebug.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -//#define DEBUG_PLAYBIN - -QT_BEGIN_NAMESPACE - -QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent) - : QMediaPlayerControl(parent) - , m_session(session) - , m_userRequestedState(QMediaPlayer::StoppedState) - , m_currentState(QMediaPlayer::StoppedState) - , m_mediaStatus(QMediaPlayer::NoMedia) - , m_bufferProgress(-1) - , m_pendingSeekPosition(-1) - , m_setMediaPending(false) - , m_stream(0) -{ - m_resources = QMediaResourcePolicy::createResourceSet<QMediaPlayerResourceSetInterface>(); - Q_ASSERT(m_resources); - - connect(m_session, SIGNAL(positionChanged(qint64)), - this, SIGNAL(positionChanged(qint64))); - connect(m_session, SIGNAL(durationChanged(qint64)), - this, SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(mutedStateChanged(bool)), - this, SIGNAL(mutedChanged(bool))); - connect(m_session, SIGNAL(volumeChanged(int)), - this, SIGNAL(volumeChanged(int))); - connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SLOT(updateSessionState(QMediaPlayer::State))); - connect(m_session,SIGNAL(bufferingProgressChanged(int)), - this, SLOT(setBufferProgress(int))); - connect(m_session, SIGNAL(playbackFinished()), - this, SLOT(processEOS())); - connect(m_session, SIGNAL(audioAvailableChanged(bool)), - this, SIGNAL(audioAvailableChanged(bool))); - connect(m_session, SIGNAL(videoAvailableChanged(bool)), - this, SIGNAL(videoAvailableChanged(bool))); - connect(m_session, SIGNAL(seekableChanged(bool)), - this, SIGNAL(seekableChanged(bool))); - connect(m_session, SIGNAL(error(int,QString)), - this, SIGNAL(error(int,QString))); - connect(m_session, SIGNAL(invalidMedia()), - this, SLOT(handleInvalidMedia())); - connect(m_session, SIGNAL(playbackRateChanged(qreal)), - this, SIGNAL(playbackRateChanged(qreal))); - - connect(m_resources, SIGNAL(resourcesGranted()), SLOT(handleResourcesGranted())); - //denied signal should be queued to have correct state update process, - //since in playOrPause, when acquire is call on resource set, it may trigger a resourcesDenied signal immediately, - //so handleResourcesDenied should be processed later, otherwise it will be overwritten by state update later in playOrPause. - connect(m_resources, SIGNAL(resourcesDenied()), this, SLOT(handleResourcesDenied()), Qt::QueuedConnection); - connect(m_resources, SIGNAL(resourcesLost()), SLOT(handleResourcesLost())); -} - -QGstreamerPlayerControl::~QGstreamerPlayerControl() -{ - QMediaResourcePolicy::destroyResourceSet(m_resources); -} - -QMediaPlayerResourceSetInterface* QGstreamerPlayerControl::resources() const -{ - return m_resources; -} - -qint64 QGstreamerPlayerControl::position() const -{ - if (m_mediaStatus == QMediaPlayer::EndOfMedia) - return m_session->duration(); - - return m_pendingSeekPosition != -1 ? m_pendingSeekPosition : m_session->position(); -} - -qint64 QGstreamerPlayerControl::duration() const -{ - return m_session->duration(); -} - -QMediaPlayer::State QGstreamerPlayerControl::state() const -{ - return m_currentState; -} - -QMediaPlayer::MediaStatus QGstreamerPlayerControl::mediaStatus() const -{ - return m_mediaStatus; -} - -int QGstreamerPlayerControl::bufferStatus() const -{ - if (m_bufferProgress == -1) { - return m_session->state() == QMediaPlayer::StoppedState ? 0 : 100; - } else - return m_bufferProgress; -} - -int QGstreamerPlayerControl::volume() const -{ - return m_session->volume(); -} - -bool QGstreamerPlayerControl::isMuted() const -{ - return m_session->isMuted(); -} - -bool QGstreamerPlayerControl::isSeekable() const -{ - return m_session->isSeekable(); -} - -QMediaTimeRange QGstreamerPlayerControl::availablePlaybackRanges() const -{ - return m_session->availablePlaybackRanges(); -} - -qreal QGstreamerPlayerControl::playbackRate() const -{ - return m_session->playbackRate(); -} - -void QGstreamerPlayerControl::setPlaybackRate(qreal rate) -{ - m_session->setPlaybackRate(rate); -} - -void QGstreamerPlayerControl::setPosition(qint64 pos) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << pos/1000.0; -#endif - - pushState(); - - if (m_mediaStatus == QMediaPlayer::EndOfMedia) { - m_mediaStatus = QMediaPlayer::LoadedMedia; - } - - if (m_currentState == QMediaPlayer::StoppedState) { - m_pendingSeekPosition = pos; - emit positionChanged(m_pendingSeekPosition); - } else if (m_session->isSeekable()) { - m_session->showPrerollFrames(true); - m_session->seek(pos); - m_pendingSeekPosition = -1; - } else if (m_session->state() == QMediaPlayer::StoppedState) { - m_pendingSeekPosition = pos; - emit positionChanged(m_pendingSeekPosition); - } else if (m_pendingSeekPosition != -1) { - m_pendingSeekPosition = -1; - emit positionChanged(m_pendingSeekPosition); - } - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::play() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - //m_userRequestedState is needed to know that we need to resume playback when resource-policy - //regranted the resources after lost, since m_currentState will become paused when resources are - //lost. - m_userRequestedState = QMediaPlayer::PlayingState; - playOrPause(QMediaPlayer::PlayingState); -} - -void QGstreamerPlayerControl::pause() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - m_userRequestedState = QMediaPlayer::PausedState; - - playOrPause(QMediaPlayer::PausedState); -} - -void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState) -{ - if (m_mediaStatus == QMediaPlayer::NoMedia) - return; - - pushState(); - - if (m_setMediaPending) { - m_mediaStatus = QMediaPlayer::LoadingMedia; - setMedia(m_currentResource, m_stream); - } - - if (m_mediaStatus == QMediaPlayer::EndOfMedia && m_pendingSeekPosition == -1) { - m_pendingSeekPosition = 0; - } - - if (!m_resources->isGranted()) - m_resources->acquire(); - - if (m_resources->isGranted()) { - // show prerolled frame if switching from stopped state - if (m_pendingSeekPosition == -1) { - m_session->showPrerollFrames(true); - } else if (m_session->state() == QMediaPlayer::StoppedState) { - // Don't evaluate the next two conditions. - } else if (m_session->isSeekable()) { - m_session->pause(); - m_session->showPrerollFrames(true); - m_session->seek(m_pendingSeekPosition); - m_pendingSeekPosition = -1; - } else { - m_pendingSeekPosition = -1; - } - - bool ok = false; - - //To prevent displaying the first video frame when playback is resumed - //the pipeline is paused instead of playing, seeked to requested position, - //and after seeking is finished (position updated) playback is restarted - //with show-preroll-frame enabled. - if (newState == QMediaPlayer::PlayingState && m_pendingSeekPosition == -1) - ok = m_session->play(); - else - ok = m_session->pause(); - - if (!ok) - newState = QMediaPlayer::StoppedState; - } - - if (m_mediaStatus == QMediaPlayer::InvalidMedia) - m_mediaStatus = QMediaPlayer::LoadingMedia; - - m_currentState = newState; - - if (m_mediaStatus == QMediaPlayer::EndOfMedia || m_mediaStatus == QMediaPlayer::LoadedMedia) { - if (m_bufferProgress == -1 || m_bufferProgress == 100) - m_mediaStatus = QMediaPlayer::BufferedMedia; - else - m_mediaStatus = QMediaPlayer::BufferingMedia; - } - - popAndNotifyState(); - - emit positionChanged(position()); -} - -void QGstreamerPlayerControl::stop() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - m_userRequestedState = QMediaPlayer::StoppedState; - - pushState(); - - if (m_currentState != QMediaPlayer::StoppedState) { - m_currentState = QMediaPlayer::StoppedState; - m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state - // Since gst is not going to send GST_STATE_PAUSED - // when pipeline is already paused, - // needs to update media status directly. - if (m_session->state() == QMediaPlayer::PausedState) - updateMediaStatus(); - else if (m_resources->isGranted()) - m_session->pause(); - - if (m_mediaStatus != QMediaPlayer::EndOfMedia) { - m_pendingSeekPosition = 0; - emit positionChanged(position()); - } - } - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::setVolume(int volume) -{ - m_session->setVolume(volume); -} - -void QGstreamerPlayerControl::setMuted(bool muted) -{ - m_session->setMuted(muted); -} - -QMediaContent QGstreamerPlayerControl::media() const -{ - return m_currentResource; -} - -const QIODevice *QGstreamerPlayerControl::mediaStream() const -{ - return m_stream; -} - -void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - - pushState(); - - m_currentState = QMediaPlayer::StoppedState; - QMediaContent oldMedia = m_currentResource; - m_pendingSeekPosition = 0; - m_session->showPrerollFrames(false); // do not show prerolled frames until pause() or play() explicitly called - m_setMediaPending = false; - - if (!content.isNull() || stream) { - if (!m_resources->isGranted()) - m_resources->acquire(); - } else { - m_resources->release(); - } - - m_session->stop(); - - bool userStreamValid = false; - - if (m_bufferProgress != -1) { - m_bufferProgress = -1; - emit bufferStatusChanged(0); - } - - m_currentResource = content; - m_stream = stream; - - QNetworkRequest request; - - if (m_stream) { - userStreamValid = stream->isOpen() && m_stream->isReadable(); - request = content.canonicalRequest(); - } else if (!content.isNull()) { - request = content.canonicalRequest(); - } - -#if !QT_CONFIG(gstreamer_app) - m_session->loadFromUri(request); -#else - if (m_stream) { - if (userStreamValid){ - m_session->loadFromStream(request, m_stream); - } else { - m_mediaStatus = QMediaPlayer::InvalidMedia; - emit error(QMediaPlayer::FormatError, tr("Attempting to play invalid user stream")); - if (m_currentState != QMediaPlayer::PlayingState) - m_resources->release(); - popAndNotifyState(); - return; - } - } else - m_session->loadFromUri(request); -#endif - -#if QT_CONFIG(gstreamer_app) - if (!request.url().isEmpty() || userStreamValid) { -#else - if (!request.url().isEmpty()) { -#endif - m_mediaStatus = QMediaPlayer::LoadingMedia; - m_session->pause(); - } else { - m_mediaStatus = QMediaPlayer::NoMedia; - setBufferProgress(0); - } - - if (m_currentResource != oldMedia) - emit mediaChanged(m_currentResource); - - emit positionChanged(position()); - - if (content.isNull() && !stream) - m_resources->release(); - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::setVideoOutput(QObject *output) -{ - m_session->setVideoRenderer(output); -} - -bool QGstreamerPlayerControl::isAudioAvailable() const -{ - return m_session->isAudioAvailable(); -} - -bool QGstreamerPlayerControl::isVideoAvailable() const -{ - return m_session->isVideoAvailable(); -} - -void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state) -{ - pushState(); - - if (state == QMediaPlayer::StoppedState) { - m_session->showPrerollFrames(false); - m_currentState = QMediaPlayer::StoppedState; - } - - if (state == QMediaPlayer::PausedState && m_currentState != QMediaPlayer::StoppedState) { - if (m_pendingSeekPosition != -1 && m_session->isSeekable()) { - m_session->showPrerollFrames(true); - m_session->seek(m_pendingSeekPosition); - } - m_pendingSeekPosition = -1; - - if (m_currentState == QMediaPlayer::PlayingState) - m_session->play(); - } - - updateMediaStatus(); - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::updateMediaStatus() -{ - pushState(); - QMediaPlayer::MediaStatus oldStatus = m_mediaStatus; - - switch (m_session->state()) { - case QMediaPlayer::StoppedState: - if (m_currentResource.isNull()) - m_mediaStatus = QMediaPlayer::NoMedia; - else if (oldStatus != QMediaPlayer::InvalidMedia) - m_mediaStatus = QMediaPlayer::LoadingMedia; - break; - - case QMediaPlayer::PlayingState: - case QMediaPlayer::PausedState: - if (m_currentState == QMediaPlayer::StoppedState) { - m_mediaStatus = QMediaPlayer::LoadedMedia; - } else { - if (m_bufferProgress == -1 || m_bufferProgress == 100) - m_mediaStatus = QMediaPlayer::BufferedMedia; - else - m_mediaStatus = QMediaPlayer::StalledMedia; - } - break; - } - - if (m_currentState == QMediaPlayer::PlayingState && !m_resources->isGranted()) - m_mediaStatus = QMediaPlayer::StalledMedia; - - //EndOfMedia status should be kept, until reset by pause, play or setMedia - if (oldStatus == QMediaPlayer::EndOfMedia) - m_mediaStatus = QMediaPlayer::EndOfMedia; - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::processEOS() -{ - pushState(); - m_mediaStatus = QMediaPlayer::EndOfMedia; - emit positionChanged(position()); - m_session->endOfMediaReset(); - - if (m_currentState != QMediaPlayer::StoppedState) { - m_currentState = QMediaPlayer::StoppedState; - m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state - } - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::setBufferProgress(int progress) -{ - if (m_bufferProgress == progress || m_mediaStatus == QMediaPlayer::NoMedia) - return; - -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << progress; -#endif - m_bufferProgress = progress; - - if (m_resources->isGranted()) { - if (m_currentState == QMediaPlayer::PlayingState && - m_bufferProgress == 100 && - m_session->state() != QMediaPlayer::PlayingState) - m_session->play(); - - if (!m_session->isLiveSource() && m_bufferProgress < 100 && - (m_session->state() == QMediaPlayer::PlayingState || - m_session->pendingState() == QMediaPlayer::PlayingState)) - m_session->pause(); - } - - updateMediaStatus(); - - emit bufferStatusChanged(m_bufferProgress); -} - -void QGstreamerPlayerControl::handleInvalidMedia() -{ - pushState(); - m_mediaStatus = QMediaPlayer::InvalidMedia; - m_currentState = QMediaPlayer::StoppedState; - m_setMediaPending = true; - popAndNotifyState(); -} - -void QGstreamerPlayerControl::handleResourcesGranted() -{ - pushState(); - - //This may be triggered when there is an auto resume - //from resource-policy, we need to take action according to m_userRequestedState - //rather than m_currentState - m_currentState = m_userRequestedState; - if (m_currentState != QMediaPlayer::StoppedState) - playOrPause(m_currentState); - else - updateMediaStatus(); - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::handleResourcesLost() -{ - //on resource lost the pipeline should be paused - //player status is changed to paused - pushState(); - QMediaPlayer::State oldState = m_currentState; - - m_session->pause(); - - if (oldState != QMediaPlayer::StoppedState ) - m_currentState = QMediaPlayer::PausedState; - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::handleResourcesDenied() -{ - //on resource denied the pipeline should stay paused - //player status is changed to paused - pushState(); - - if (m_currentState != QMediaPlayer::StoppedState ) - m_currentState = QMediaPlayer::PausedState; - - popAndNotifyState(); -} - -void QGstreamerPlayerControl::pushState() -{ - m_stateStack.push(m_currentState); - m_mediaStatusStack.push(m_mediaStatus); -} - -void QGstreamerPlayerControl::popAndNotifyState() -{ - Q_ASSERT(!m_stateStack.isEmpty()); - - QMediaPlayer::State oldState = m_stateStack.pop(); - QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatusStack.pop(); - - if (m_stateStack.isEmpty()) { - if (m_mediaStatus != oldMediaStatus) { -#ifdef DEBUG_PLAYBIN - qDebug() << "Media status changed:" << m_mediaStatus; -#endif - emit mediaStatusChanged(m_mediaStatus); - } - - if (m_currentState != oldState) { -#ifdef DEBUG_PLAYBIN - qDebug() << "State changed:" << m_currentState; -#endif - emit stateChanged(m_currentState); - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h deleted file mode 100644 index 6067a68fc..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERPLAYERCONTROL_H -#define QGSTREAMERPLAYERCONTROL_H - -#include <QtCore/qobject.h> -#include <QtCore/qstack.h> - -#include <qmediaplayercontrol.h> -#include <qmediaplayer.h> - -#include <limits.h> - -QT_BEGIN_NAMESPACE - -class QMediaPlayerResourceSetInterface; - -class QMediaPlaylist; -class QMediaPlaylistNavigator; -class QSocketNotifier; - -class QGstreamerPlayerSession; -class QGstreamerPlayerService; - -class QGstreamerPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT - -public: - QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent = 0); - ~QGstreamerPlayerControl(); - - QMediaPlayer::State state() const override; - QMediaPlayer::MediaStatus mediaStatus() const override; - - qint64 position() const override; - qint64 duration() const override; - - int bufferStatus() const override; - - int volume() const override; - bool isMuted() const override; - - bool isAudioAvailable() const override; - bool isVideoAvailable() const override; - void setVideoOutput(QObject *output); - - bool isSeekable() const override; - QMediaTimeRange availablePlaybackRanges() const override; - - qreal playbackRate() const override; - void setPlaybackRate(qreal rate) override; - - QMediaContent media() const override; - const QIODevice *mediaStream() const override; - void setMedia(const QMediaContent&, QIODevice *) override; - - QMediaPlayerResourceSetInterface* resources() const; - -public Q_SLOTS: - void setPosition(qint64 pos) override; - - void play() override; - void pause() override; - void stop() override; - - void setVolume(int volume) override; - void setMuted(bool muted) override; - -private Q_SLOTS: - void updateSessionState(QMediaPlayer::State state); - void updateMediaStatus(); - void processEOS(); - void setBufferProgress(int progress); - - void handleInvalidMedia(); - - void handleResourcesGranted(); - void handleResourcesLost(); - void handleResourcesDenied(); - -private: - void playOrPause(QMediaPlayer::State state); - - void pushState(); - void popAndNotifyState(); - - QGstreamerPlayerSession *m_session; - QMediaPlayer::State m_userRequestedState; - QMediaPlayer::State m_currentState; - QMediaPlayer::MediaStatus m_mediaStatus; - QStack<QMediaPlayer::State> m_stateStack; - QStack<QMediaPlayer::MediaStatus> m_mediaStatusStack; - - int m_bufferProgress; - qint64 m_pendingSeekPosition; - bool m_setMediaPending; - QMediaContent m_currentResource; - QIODevice *m_stream; - - QMediaPlayerResourceSetInterface *m_resources; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp index 2c2de1bbc..0712f6e6c 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp @@ -46,8 +46,6 @@ #endif #include "qgstreamerplayerservice.h" -#include "qgstreamerplayercontrol.h" -#include "qgstreamerplayersession.h" #include "qgstreamermetadataprovider.h" #include "qgstreameravailabilitycontrol.h" @@ -64,6 +62,8 @@ #include "qgstreamerstreamscontrol.h" #include <private/qgstreameraudioprobecontrol_p.h> #include <private/qgstreamervideoprobecontrol_p.h> +#include <private/qgstreamerplayersession_p.h> +#include <private/qgstreamerplayercontrol_p.h> #include <private/qmediaplaylistnavigator_p.h> #include <qmediaplaylist.h> diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp deleted file mode 100644 index d7cc5ed12..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ /dev/null @@ -1,1876 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamerplayersession.h" -#include <private/qgstreamerbushelper_p.h> - -#include <private/qgstreameraudioprobecontrol_p.h> -#include <private/qgstreamervideoprobecontrol_p.h> -#include <private/qgstreamervideorendererinterface_p.h> -#if !GST_CHECK_VERSION(1,0,0) -#include <private/gstvideoconnector_p.h> -#endif -#include <private/qgstutils_p.h> -#include <private/qgstutils_p.h> - -#include <gst/gstvalue.h> -#include <gst/base/gstbasesrc.h> - -#include <QtMultimedia/qmediametadata.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qdebug.h> -#include <QtCore/qsize.h> -#include <QtCore/qtimer.h> -#include <QtCore/qdebug.h> -#include <QtCore/qdir.h> -#include <QtCore/qstandardpaths.h> - -//#define DEBUG_PLAYBIN -//#define DEBUG_VO_BIN_DUMP - -QT_BEGIN_NAMESPACE - -static bool usePlaybinVolume() -{ - static enum { Yes, No, Unknown } status = Unknown; - if (status == Unknown) { - QByteArray v = qgetenv("QT_GSTREAMER_USE_PLAYBIN_VOLUME"); - bool value = !v.isEmpty() && v != "0" && v != "false"; - if (value) - status = Yes; - else - status = No; - } - return status == Yes; -} - -typedef enum { - GST_PLAY_FLAG_VIDEO = 0x00000001, - GST_PLAY_FLAG_AUDIO = 0x00000002, - GST_PLAY_FLAG_TEXT = 0x00000004, - GST_PLAY_FLAG_VIS = 0x00000008, - GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010, - GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020, - GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040, - GST_PLAY_FLAG_DOWNLOAD = 0x00000080, - GST_PLAY_FLAG_BUFFERING = 0x000000100 -} GstPlayFlags; - -#if !GST_CHECK_VERSION(1,0,0) -#define DEFAULT_RAW_CAPS \ - "video/x-raw-yuv; " \ - "video/x-raw-rgb; " \ - "video/x-raw-gray; " \ - "video/x-surface; " \ - "video/x-android-buffer; " \ - "audio/x-raw-int; " \ - "audio/x-raw-float; " \ - "text/plain; " \ - "text/x-pango-markup; " \ - "video/x-dvd-subpicture; " \ - "subpicture/x-pgs" - -static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS); -#endif - -QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) - :QObject(parent), - m_state(QMediaPlayer::StoppedState), - m_pendingState(QMediaPlayer::StoppedState), - m_busHelper(0), - m_playbin(0), - m_videoSink(0), -#if !GST_CHECK_VERSION(1,0,0) - m_usingColorspaceElement(false), -#endif - m_pendingVideoSink(0), - m_nullVideoSink(0), - m_audioSink(0), - m_volumeElement(0), - m_bus(0), - m_videoOutput(0), - m_renderer(0), -#if QT_CONFIG(gstreamer_app) - m_appSrc(0), -#endif - m_videoProbe(0), - m_audioProbe(0), - m_volume(100), - m_playbackRate(1.0), - m_muted(false), - m_audioAvailable(false), - m_videoAvailable(false), - m_seekable(false), - m_lastPosition(0), - m_duration(0), - m_durationQueries(0), - m_displayPrerolledFrame(true), - m_sourceType(UnknownSrc), - m_everPlayed(false), - m_isLiveSource(false) -{ - m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, NULL); - if (m_playbin) { - //GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale, - //since those elements are included in the video output bin when necessary. - int flags = GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO; - QByteArray envFlags = qgetenv("QT_GSTREAMER_PLAYBIN_FLAGS"); - if (!envFlags.isEmpty()) { - flags |= envFlags.toInt(); -#if !GST_CHECK_VERSION(1,0,0) - } else { - flags |= GST_PLAY_FLAG_NATIVE_VIDEO; -#endif - } - g_object_set(G_OBJECT(m_playbin), "flags", flags, NULL); - - const QByteArray envAudioSink = qgetenv("QT_GSTREAMER_PLAYBIN_AUDIOSINK"); - GstElement *audioSink = gst_element_factory_make(envAudioSink.isEmpty() ? "autoaudiosink" : envAudioSink, "audiosink"); - if (audioSink) { - if (usePlaybinVolume()) { - m_audioSink = audioSink; - m_volumeElement = m_playbin; - } else { - m_volumeElement = gst_element_factory_make("volume", "volumeelement"); - if (m_volumeElement) { - m_audioSink = gst_bin_new("audio-output-bin"); - - gst_bin_add_many(GST_BIN(m_audioSink), m_volumeElement, audioSink, NULL); - gst_element_link(m_volumeElement, audioSink); - - GstPad *pad = gst_element_get_static_pad(m_volumeElement, "sink"); - gst_element_add_pad(GST_ELEMENT(m_audioSink), gst_ghost_pad_new("sink", pad)); - gst_object_unref(GST_OBJECT(pad)); - } else { - m_audioSink = audioSink; - m_volumeElement = m_playbin; - } - } - - g_object_set(G_OBJECT(m_playbin), "audio-sink", m_audioSink, NULL); - addAudioBufferProbe(); - } - } - -#if GST_CHECK_VERSION(1,0,0) - m_videoIdentity = gst_element_factory_make("identity", NULL); // floating ref -#else - m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref - g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this); - m_colorSpace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "ffmpegcolorspace-vo"); - - // might not get a parent, take ownership to avoid leak - qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace)); -#endif - - m_nullVideoSink = gst_element_factory_make("fakesink", NULL); - g_object_set(G_OBJECT(m_nullVideoSink), "sync", true, NULL); - gst_object_ref(GST_OBJECT(m_nullVideoSink)); - - m_videoOutputBin = gst_bin_new("video-output-bin"); - // might not get a parent, take ownership to avoid leak - qt_gst_object_ref_sink(GST_OBJECT(m_videoOutputBin)); - gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, NULL); - gst_element_link(m_videoIdentity, m_nullVideoSink); - - m_videoSink = m_nullVideoSink; - - // add ghostpads - GstPad *pad = gst_element_get_static_pad(m_videoIdentity,"sink"); - gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("sink", pad)); - gst_object_unref(GST_OBJECT(pad)); - - if (m_playbin != 0) { - // Sort out messages - m_bus = gst_element_get_bus(m_playbin); - m_busHelper = new QGstreamerBusHelper(m_bus, this); - m_busHelper->installMessageFilter(this); - - g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL); - - g_signal_connect(G_OBJECT(m_playbin), "notify::source", G_CALLBACK(playbinNotifySource), this); - g_signal_connect(G_OBJECT(m_playbin), "element-added", G_CALLBACK(handleElementAdded), this); - - if (usePlaybinVolume()) { - updateVolume(); - updateMuted(); - g_signal_connect(G_OBJECT(m_playbin), "notify::volume", G_CALLBACK(handleVolumeChange), this); - g_signal_connect(G_OBJECT(m_playbin), "notify::mute", G_CALLBACK(handleMutedChange), this); - } - - g_signal_connect(G_OBJECT(m_playbin), "video-changed", G_CALLBACK(handleStreamsChange), this); - g_signal_connect(G_OBJECT(m_playbin), "audio-changed", G_CALLBACK(handleStreamsChange), this); - g_signal_connect(G_OBJECT(m_playbin), "text-changed", G_CALLBACK(handleStreamsChange), this); - -#if QT_CONFIG(gstreamer_app) - g_signal_connect(G_OBJECT(m_playbin), "deep-notify::source", G_CALLBACK(configureAppSrcElement), this); -#endif - } -} - -QGstreamerPlayerSession::~QGstreamerPlayerSession() -{ - if (m_playbin) { - stop(); - - removeVideoBufferProbe(); - removeAudioBufferProbe(); - - delete m_busHelper; - gst_object_unref(GST_OBJECT(m_bus)); - gst_object_unref(GST_OBJECT(m_playbin)); -#if !GST_CHECK_VERSION(1,0,0) - gst_object_unref(GST_OBJECT(m_colorSpace)); -#endif - gst_object_unref(GST_OBJECT(m_nullVideoSink)); - gst_object_unref(GST_OBJECT(m_videoOutputBin)); - } -} - -GstElement *QGstreamerPlayerSession::playbin() const -{ - return m_playbin; -} - -#if QT_CONFIG(gstreamer_app) -void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerPlayerSession* self) -{ - Q_UNUSED(object); - Q_UNUSED(pspec); - - if (!self->appsrc()) - return; - - GstElement *appsrc; - g_object_get(orig, "source", &appsrc, NULL); - - if (!self->appsrc()->setup(appsrc)) - qWarning()<<"Could not setup appsrc element"; - - g_object_unref(G_OBJECT(appsrc)); -} -#endif - -void QGstreamerPlayerSession::loadFromStream(const QNetworkRequest &request, QIODevice *appSrcStream) -{ -#if QT_CONFIG(gstreamer_app) -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - m_request = request; - m_duration = 0; - m_lastPosition = 0; - - if (!m_appSrc) - m_appSrc = new QGstAppSrc(this); - m_appSrc->setStream(appSrcStream); - - if (m_playbin) { - m_tags.clear(); - emit tagsChanged(); - - g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", NULL); - - if (!m_streamTypes.isEmpty()) { - m_streamProperties.clear(); - m_streamTypes.clear(); - - emit streamsChanged(); - } - } -#endif -} - -void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << request.url(); -#endif - m_request = request; - m_duration = 0; - m_lastPosition = 0; - -#if QT_CONFIG(gstreamer_app) - if (m_appSrc) { - m_appSrc->deleteLater(); - m_appSrc = 0; - } -#endif - - if (m_playbin) { - m_tags.clear(); - emit tagsChanged(); - - g_object_set(G_OBJECT(m_playbin), "uri", m_request.url().toEncoded().constData(), NULL); - - if (!m_streamTypes.isEmpty()) { - m_streamProperties.clear(); - m_streamTypes.clear(); - - emit streamsChanged(); - } - } -} - -qint64 QGstreamerPlayerSession::duration() const -{ - return m_duration; -} - -qint64 QGstreamerPlayerSession::position() const -{ - gint64 position = 0; - - if (m_playbin && qt_gst_element_query_position(m_playbin, GST_FORMAT_TIME, &position)) - m_lastPosition = position / 1000000; - return m_lastPosition; -} - -qreal QGstreamerPlayerSession::playbackRate() const -{ - return m_playbackRate; -} - -void QGstreamerPlayerSession::setPlaybackRate(qreal rate) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << rate; -#endif - if (!qFuzzyCompare(m_playbackRate, rate)) { - m_playbackRate = rate; - if (m_playbin && m_seekable) { - gst_element_seek(m_playbin, rate, GST_FORMAT_TIME, - GstSeekFlags(GST_SEEK_FLAG_FLUSH), - GST_SEEK_TYPE_NONE,0, - GST_SEEK_TYPE_NONE,0 ); - } - emit playbackRateChanged(m_playbackRate); - } -} - -QMediaTimeRange QGstreamerPlayerSession::availablePlaybackRanges() const -{ - QMediaTimeRange ranges; - - if (duration() <= 0) - return ranges; - -#if GST_CHECK_VERSION(0, 10, 31) - //GST_FORMAT_TIME would be more appropriate, but unfortunately it's not supported. - //with GST_FORMAT_PERCENT media is treated as encoded with constant bitrate. - GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT); - - if (!gst_element_query(m_playbin, query)) { - gst_query_unref(query); - return ranges; - } - - gint64 rangeStart = 0; - gint64 rangeStop = 0; - for (guint index = 0; index < gst_query_get_n_buffering_ranges(query); index++) { - if (gst_query_parse_nth_buffering_range(query, index, &rangeStart, &rangeStop)) - ranges.addInterval(rangeStart * duration() / 100, - rangeStop * duration() / 100); - } - - gst_query_unref(query); -#endif - - if (ranges.isEmpty() && !isLiveSource() && isSeekable()) - ranges.addInterval(0, duration()); - -#ifdef DEBUG_PLAYBIN - qDebug() << ranges; -#endif - - return ranges; -} - -int QGstreamerPlayerSession::activeStream(QMediaStreamsControl::StreamType streamType) const -{ - int streamNumber = -1; - if (m_playbin) { - switch (streamType) { - case QMediaStreamsControl::AudioStream: - g_object_get(G_OBJECT(m_playbin), "current-audio", &streamNumber, NULL); - break; - case QMediaStreamsControl::VideoStream: - g_object_get(G_OBJECT(m_playbin), "current-video", &streamNumber, NULL); - break; - case QMediaStreamsControl::SubPictureStream: - g_object_get(G_OBJECT(m_playbin), "current-text", &streamNumber, NULL); - break; - default: - break; - } - } - - if (streamNumber >= 0) - streamNumber += m_playbin2StreamOffset.value(streamType,0); - - return streamNumber; -} - -void QGstreamerPlayerSession::setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << streamType << streamNumber; -#endif - - if (streamNumber >= 0) - streamNumber -= m_playbin2StreamOffset.value(streamType,0); - - if (m_playbin) { - switch (streamType) { - case QMediaStreamsControl::AudioStream: - g_object_set(G_OBJECT(m_playbin), "current-audio", streamNumber, NULL); - break; - case QMediaStreamsControl::VideoStream: - g_object_set(G_OBJECT(m_playbin), "current-video", streamNumber, NULL); - break; - case QMediaStreamsControl::SubPictureStream: - g_object_set(G_OBJECT(m_playbin), "current-text", streamNumber, NULL); - break; - default: - break; - } - } -} - -int QGstreamerPlayerSession::volume() const -{ - return m_volume; -} - -bool QGstreamerPlayerSession::isMuted() const -{ - return m_muted; -} - -bool QGstreamerPlayerSession::isAudioAvailable() const -{ - return m_audioAvailable; -} - -#if GST_CHECK_VERSION(1,0,0) -static GstPadProbeReturn block_pad_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) -#else -static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data) -#endif -{ - Q_UNUSED(pad); -#if GST_CHECK_VERSION(1,0,0) - Q_UNUSED(info); - Q_UNUSED(user_data); - return GST_PAD_PROBE_OK; -#else -#ifdef DEBUG_PLAYBIN - qDebug() << "block_pad_cb, blocked:" << blocked; -#endif - if (blocked && user_data) { - QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data); - QMetaObject::invokeMethod(session, "finishVideoOutputChange", Qt::QueuedConnection); - } -#endif -} - -void QGstreamerPlayerSession::updateVideoRenderer() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << "Video sink has chaged, reload video output"; -#endif - - if (m_videoOutput) - setVideoRenderer(m_videoOutput); -} - -void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - if (m_videoOutput != videoOutput) { - if (m_videoOutput) { - disconnect(m_videoOutput, SIGNAL(sinkChanged()), - this, SLOT(updateVideoRenderer())); - disconnect(m_videoOutput, SIGNAL(readyChanged(bool)), - this, SLOT(updateVideoRenderer())); - - m_busHelper->removeMessageFilter(m_videoOutput); - } - - m_videoOutput = videoOutput; - - if (m_videoOutput) { - connect(m_videoOutput, SIGNAL(sinkChanged()), - this, SLOT(updateVideoRenderer())); - connect(m_videoOutput, SIGNAL(readyChanged(bool)), - this, SLOT(updateVideoRenderer())); - - m_busHelper->installMessageFilter(m_videoOutput); - } - } - - QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput); - - m_renderer = renderer; - -#ifdef DEBUG_VO_BIN_DUMP - gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin), - GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/), - "playbin_set"); -#endif - - GstElement *videoSink = 0; - if (m_renderer && m_renderer->isReady()) - videoSink = m_renderer->videoSink(); - - if (!videoSink) - videoSink = m_nullVideoSink; - -#ifdef DEBUG_PLAYBIN - qDebug() << "Set video output:" << videoOutput; - qDebug() << "Current sink:" << (m_videoSink ? GST_ELEMENT_NAME(m_videoSink) : "") << m_videoSink - << "pending:" << (m_pendingVideoSink ? GST_ELEMENT_NAME(m_pendingVideoSink) : "") << m_pendingVideoSink - << "new sink:" << (videoSink ? GST_ELEMENT_NAME(videoSink) : "") << videoSink; -#endif - - if (m_pendingVideoSink == videoSink || - (m_pendingVideoSink == 0 && m_videoSink == videoSink)) { -#ifdef DEBUG_PLAYBIN - qDebug() << "Video sink has not changed, skip video output reconfiguration"; -#endif - return; - } - -#ifdef DEBUG_PLAYBIN - qDebug() << "Reconfigure video output"; -#endif - - if (m_state == QMediaPlayer::StoppedState) { -#ifdef DEBUG_PLAYBIN - qDebug() << "The pipeline has not started yet, pending state:" << m_pendingState; -#endif - //the pipeline has not started yet - flushVideoProbes(); - m_pendingVideoSink = 0; - gst_element_set_state(m_videoSink, GST_STATE_NULL); - gst_element_set_state(m_playbin, GST_STATE_NULL); - -#if !GST_CHECK_VERSION(1,0,0) - if (m_usingColorspaceElement) { - gst_element_unlink(m_colorSpace, m_videoSink); - gst_bin_remove(GST_BIN(m_videoOutputBin), m_colorSpace); - } else { - gst_element_unlink(m_videoIdentity, m_videoSink); - } -#endif - - removeVideoBufferProbe(); - - gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink); - - m_videoSink = videoSink; - - gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink); - - bool linked = gst_element_link(m_videoIdentity, m_videoSink); -#if !GST_CHECK_VERSION(1,0,0) - m_usingColorspaceElement = false; - if (!linked) { - m_usingColorspaceElement = true; -#ifdef DEBUG_PLAYBIN - qDebug() << "Failed to connect video output, inserting the colorspace element."; -#endif - gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace); - linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL); - } -#endif - - if (!linked) - qWarning() << "Linking video output element failed"; - - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) { - gboolean value = m_displayPrerolledFrame; - g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, NULL); - } - - addVideoBufferProbe(); - - switch (m_pendingState) { - case QMediaPlayer::PausedState: - gst_element_set_state(m_playbin, GST_STATE_PAUSED); - break; - case QMediaPlayer::PlayingState: - gst_element_set_state(m_playbin, GST_STATE_PLAYING); - break; - default: - break; - } - - resumeVideoProbes(); - - } else { - if (m_pendingVideoSink) { -#ifdef DEBUG_PLAYBIN - qDebug() << "already waiting for pad to be blocked, just change the pending sink"; -#endif - m_pendingVideoSink = videoSink; - return; - } - - m_pendingVideoSink = videoSink; - -#ifdef DEBUG_PLAYBIN - qDebug() << "Blocking the video output pad..."; -#endif - - //block pads, async to avoid locking in paused state - GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src"); -#if GST_CHECK_VERSION(1,0,0) - this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCKING), block_pad_cb, this, NULL); -#else - gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this); -#endif - gst_object_unref(GST_OBJECT(srcPad)); - - //Unpause the sink to avoid waiting until the buffer is processed - //while the sink is paused. The pad will be blocked as soon as the current - //buffer is processed. - if (m_state == QMediaPlayer::PausedState) { -#ifdef DEBUG_PLAYBIN - qDebug() << "Starting video output to avoid blocking in paused state..."; -#endif - gst_element_set_state(m_videoSink, GST_STATE_PLAYING); - } - } -} - -void QGstreamerPlayerSession::finishVideoOutputChange() -{ - if (!m_pendingVideoSink) - return; - -#ifdef DEBUG_PLAYBIN - qDebug() << "finishVideoOutputChange" << m_pendingVideoSink; -#endif - - GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src"); - - if (!gst_pad_is_blocked(srcPad)) { - //pad is not blocked, it's possible to swap outputs only in the null state - qWarning() << "Pad is not blocked yet, could not switch video sink"; - GstState identityElementState = GST_STATE_NULL; - gst_element_get_state(m_videoIdentity, &identityElementState, NULL, GST_CLOCK_TIME_NONE); - if (identityElementState != GST_STATE_NULL) { - gst_object_unref(GST_OBJECT(srcPad)); - return; //can't change vo yet, received async call from the previous change - } - } - - if (m_pendingVideoSink == m_videoSink) { - qDebug() << "Abort, no change"; - //video output was change back to the current one, - //no need to torment the pipeline, just unblock the pad - if (gst_pad_is_blocked(srcPad)) -#if GST_CHECK_VERSION(1,0,0) - gst_pad_remove_probe(srcPad, this->pad_probe_id); -#else - gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); -#endif - - m_pendingVideoSink = 0; - gst_object_unref(GST_OBJECT(srcPad)); - return; - } - -#if !GST_CHECK_VERSION(1,0,0) - if (m_usingColorspaceElement) { - gst_element_set_state(m_colorSpace, GST_STATE_NULL); - gst_element_set_state(m_videoSink, GST_STATE_NULL); - - gst_element_unlink(m_colorSpace, m_videoSink); - gst_bin_remove(GST_BIN(m_videoOutputBin), m_colorSpace); - } else { -#else - { -#endif - gst_element_set_state(m_videoSink, GST_STATE_NULL); - gst_element_unlink(m_videoIdentity, m_videoSink); - } - - removeVideoBufferProbe(); - - gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink); - - m_videoSink = m_pendingVideoSink; - m_pendingVideoSink = 0; - - gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink); - - addVideoBufferProbe(); - - bool linked = gst_element_link(m_videoIdentity, m_videoSink); -#if !GST_CHECK_VERSION(1,0,0) - m_usingColorspaceElement = false; - if (!linked) { - m_usingColorspaceElement = true; -#ifdef DEBUG_PLAYBIN - qDebug() << "Failed to connect video output, inserting the colorspace element."; -#endif - gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace); - linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL); - } -#endif - - if (!linked) - qWarning() << "Linking video output element failed"; - -#ifdef DEBUG_PLAYBIN - qDebug() << "notify the video connector it has to emit a new segment message..."; -#endif - -#if !GST_CHECK_VERSION(1,0,0) - //it's necessary to send a new segment event just before - //the first buffer pushed to the new sink - g_signal_emit_by_name(m_videoIdentity, - "resend-new-segment", - true //emit connection-failed signal - //to have a chance to insert colorspace element - ); -#endif - - GstState state = GST_STATE_VOID_PENDING; - - switch (m_pendingState) { - case QMediaPlayer::StoppedState: - state = GST_STATE_NULL; - break; - case QMediaPlayer::PausedState: - state = GST_STATE_PAUSED; - break; - case QMediaPlayer::PlayingState: - state = GST_STATE_PLAYING; - break; - } - -#if !GST_CHECK_VERSION(1,0,0) - if (m_usingColorspaceElement) - gst_element_set_state(m_colorSpace, state); -#endif - - gst_element_set_state(m_videoSink, state); - - if (state == GST_STATE_NULL) - flushVideoProbes(); - - // Set state change that was deferred due the video output - // change being pending - gst_element_set_state(m_playbin, state); - - if (state != GST_STATE_NULL) - resumeVideoProbes(); - - //don't have to wait here, it will unblock eventually - if (gst_pad_is_blocked(srcPad)) -#if GST_CHECK_VERSION(1,0,0) - gst_pad_remove_probe(srcPad, this->pad_probe_id); -#else - gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); -#endif - - gst_object_unref(GST_OBJECT(srcPad)); - -#ifdef DEBUG_VO_BIN_DUMP - gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin), - GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* | GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES */), - "playbin_finish"); -#endif -} - -#if !GST_CHECK_VERSION(1,0,0) - -void QGstreamerPlayerSession::insertColorSpaceElement(GstElement *element, gpointer data) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - Q_UNUSED(element); - QGstreamerPlayerSession* session = reinterpret_cast<QGstreamerPlayerSession*>(data); - - if (session->m_usingColorspaceElement) - return; - session->m_usingColorspaceElement = true; - -#ifdef DEBUG_PLAYBIN - qDebug() << "Failed to connect video output, inserting the colorspace elemnt."; - qDebug() << "notify the video connector it has to emit a new segment message..."; -#endif - //it's necessary to send a new segment event just before - //the first buffer pushed to the new sink - g_signal_emit_by_name(session->m_videoIdentity, - "resend-new-segment", - false // don't emit connection-failed signal - ); - - gst_element_unlink(session->m_videoIdentity, session->m_videoSink); - gst_bin_add(GST_BIN(session->m_videoOutputBin), session->m_colorSpace); - gst_element_link_many(session->m_videoIdentity, session->m_colorSpace, session->m_videoSink, NULL); - - GstState state = GST_STATE_VOID_PENDING; - - switch (session->m_pendingState) { - case QMediaPlayer::StoppedState: - state = GST_STATE_NULL; - break; - case QMediaPlayer::PausedState: - state = GST_STATE_PAUSED; - break; - case QMediaPlayer::PlayingState: - state = GST_STATE_PLAYING; - break; - } - - gst_element_set_state(session->m_colorSpace, state); -} - -#endif - -bool QGstreamerPlayerSession::isVideoAvailable() const -{ - return m_videoAvailable; -} - -bool QGstreamerPlayerSession::isSeekable() const -{ - return m_seekable; -} - -bool QGstreamerPlayerSession::play() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - - m_everPlayed = false; - if (m_playbin) { - m_pendingState = QMediaPlayer::PlayingState; - if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { - qWarning() << "GStreamer; Unable to play -" << m_request.url().toString(); - m_pendingState = m_state = QMediaPlayer::StoppedState; - emit stateChanged(m_state); - } else { - resumeVideoProbes(); - return true; - } - } - - return false; -} - -bool QGstreamerPlayerSession::pause() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - if (m_playbin) { - m_pendingState = QMediaPlayer::PausedState; - if (m_pendingVideoSink != 0) - return true; - - if (gst_element_set_state(m_playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) { - qWarning() << "GStreamer; Unable to pause -" << m_request.url().toString(); - m_pendingState = m_state = QMediaPlayer::StoppedState; - emit stateChanged(m_state); - } else { - resumeVideoProbes(); - return true; - } - } - - return false; -} - -void QGstreamerPlayerSession::stop() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - m_everPlayed = false; - if (m_playbin) { - - if (m_renderer) - m_renderer->stopRenderer(); - - flushVideoProbes(); - gst_element_set_state(m_playbin, GST_STATE_NULL); - - m_lastPosition = 0; - QMediaPlayer::State oldState = m_state; - m_pendingState = m_state = QMediaPlayer::StoppedState; - - finishVideoOutputChange(); - - //we have to do it here, since gstreamer will not emit bus messages any more - setSeekable(false); - if (oldState != m_state) - emit stateChanged(m_state); - } -} - -bool QGstreamerPlayerSession::seek(qint64 ms) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << ms; -#endif - //seek locks when the video output sink is changing and pad is blocked - if (m_playbin && !m_pendingVideoSink && m_state != QMediaPlayer::StoppedState && m_seekable) { - ms = qMax(ms,qint64(0)); - gint64 position = ms * 1000000; - bool isSeeking = gst_element_seek(m_playbin, - m_playbackRate, - GST_FORMAT_TIME, - GstSeekFlags(GST_SEEK_FLAG_FLUSH), - GST_SEEK_TYPE_SET, - position, - GST_SEEK_TYPE_NONE, - 0); - if (isSeeking) - m_lastPosition = ms; - - return isSeeking; - } - - return false; -} - -void QGstreamerPlayerSession::setVolume(int volume) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << volume; -#endif - - if (m_volume != volume) { - m_volume = volume; - - if (m_volumeElement) - g_object_set(G_OBJECT(m_volumeElement), "volume", m_volume / 100.0, NULL); - - emit volumeChanged(m_volume); - } -} - -void QGstreamerPlayerSession::setMuted(bool muted) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << muted; -#endif - if (m_muted != muted) { - m_muted = muted; - - if (m_volumeElement) - g_object_set(G_OBJECT(m_volumeElement), "mute", m_muted ? TRUE : FALSE, NULL); - - emit mutedStateChanged(m_muted); - } -} - - -void QGstreamerPlayerSession::setSeekable(bool seekable) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << seekable; -#endif - if (seekable != m_seekable) { - m_seekable = seekable; - emit seekableChanged(m_seekable); - } -} - -bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - if (gm) { - //tag message comes from elements inside playbin, not from playbin itself - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) { - GstTagList *tag_list; - gst_message_parse_tag(gm, &tag_list); - - QMap<QByteArray, QVariant> newTags = QGstUtils::gstTagListToMap(tag_list); - QMap<QByteArray, QVariant>::const_iterator it = newTags.constBegin(); - for ( ; it != newTags.constEnd(); ++it) - m_tags.insert(it.key(), it.value()); // overwrite existing tags - - gst_tag_list_free(tag_list); - - emit tagsChanged(); - } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_DURATION) { - updateDuration(); - } - -#ifdef DEBUG_PLAYBIN - if (m_sourceType == MMSSrc && qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) { - qDebug() << "Message from MMSSrc: " << GST_MESSAGE_TYPE(gm); - } else if (m_sourceType == RTSPSrc && qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) { - qDebug() << "Message from RTSPSrc: " << GST_MESSAGE_TYPE(gm); - } else { - qDebug() << "Message from " << GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)) << ":" << GST_MESSAGE_TYPE(gm); - } -#endif - - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_BUFFERING) { - int progress = 0; - gst_message_parse_buffering(gm, &progress); - emit bufferingProgressChanged(progress); - } - - bool handlePlaybin2 = false; - if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) { - switch (GST_MESSAGE_TYPE(gm)) { - case GST_MESSAGE_STATE_CHANGED: - { - GstState oldState; - GstState newState; - GstState pending; - - gst_message_parse_state_changed(gm, &oldState, &newState, &pending); - -#ifdef DEBUG_PLAYBIN - QStringList states; - states << "GST_STATE_VOID_PENDING" << "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING"; - - qDebug() << QString("state changed: old: %1 new: %2 pending: %3") \ - .arg(states[oldState]) \ - .arg(states[newState]) \ - .arg(states[pending]); -#endif - - switch (newState) { - case GST_STATE_VOID_PENDING: - case GST_STATE_NULL: - setSeekable(false); - finishVideoOutputChange(); - if (m_state != QMediaPlayer::StoppedState) - emit stateChanged(m_state = QMediaPlayer::StoppedState); - break; - case GST_STATE_READY: - setSeekable(false); - if (m_state != QMediaPlayer::StoppedState) - emit stateChanged(m_state = QMediaPlayer::StoppedState); - break; - case GST_STATE_PAUSED: - { - QMediaPlayer::State prevState = m_state; - m_state = QMediaPlayer::PausedState; - - //check for seekable - if (oldState == GST_STATE_READY) { - if (m_sourceType == SoupHTTPSrc || m_sourceType == MMSSrc) { - //since udpsrc is a live source, it is not applicable here - m_everPlayed = true; - } - - getStreamsInfo(); - updateVideoResolutionTag(); - - //gstreamer doesn't give a reliable indication the duration - //information is ready, GST_MESSAGE_DURATION is not sent by most elements - //the duration is queried up to 5 times with increasing delay - m_durationQueries = 5; - // This should also update the seekable flag. - updateDuration(); - - if (!qFuzzyCompare(m_playbackRate, qreal(1.0))) { - qreal rate = m_playbackRate; - m_playbackRate = 1.0; - setPlaybackRate(rate); - } - } - - if (m_state != prevState) - emit stateChanged(m_state); - - break; - } - case GST_STATE_PLAYING: - m_everPlayed = true; - if (m_state != QMediaPlayer::PlayingState) { - emit stateChanged(m_state = QMediaPlayer::PlayingState); - - // For rtsp streams duration information might not be available - // until playback starts. - if (m_duration <= 0) { - m_durationQueries = 5; - updateDuration(); - } - } - - break; - } - } - break; - - case GST_MESSAGE_EOS: - emit playbackFinished(); - break; - - case GST_MESSAGE_TAG: - case GST_MESSAGE_STREAM_STATUS: - case GST_MESSAGE_UNKNOWN: - break; - case GST_MESSAGE_ERROR: { - GError *err; - gchar *debug; - gst_message_parse_error(gm, &err, &debug); - if (err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND) - processInvalidMedia(QMediaPlayer::FormatError, tr("Cannot play stream of type: <unknown>")); - else - processInvalidMedia(QMediaPlayer::ResourceError, QString::fromUtf8(err->message)); - qWarning() << "Error:" << QString::fromUtf8(err->message); - g_error_free(err); - g_free(debug); - } - break; - case GST_MESSAGE_WARNING: - { - GError *err; - gchar *debug; - gst_message_parse_warning (gm, &err, &debug); - qWarning() << "Warning:" << QString::fromUtf8(err->message); - g_error_free (err); - g_free (debug); - } - break; - case GST_MESSAGE_INFO: -#ifdef DEBUG_PLAYBIN - { - GError *err; - gchar *debug; - gst_message_parse_info (gm, &err, &debug); - qDebug() << "Info:" << QString::fromUtf8(err->message); - g_error_free (err); - g_free (debug); - } -#endif - break; - case GST_MESSAGE_BUFFERING: - case GST_MESSAGE_STATE_DIRTY: - case GST_MESSAGE_STEP_DONE: - case GST_MESSAGE_CLOCK_PROVIDE: - case GST_MESSAGE_CLOCK_LOST: - case GST_MESSAGE_NEW_CLOCK: - case GST_MESSAGE_STRUCTURE_CHANGE: - case GST_MESSAGE_APPLICATION: - case GST_MESSAGE_ELEMENT: - break; - case GST_MESSAGE_SEGMENT_START: - { - const GstStructure *structure = gst_message_get_structure(gm); - qint64 position = g_value_get_int64(gst_structure_get_value(structure, "position")); - position /= 1000000; - m_lastPosition = position; - emit positionChanged(position); - } - break; - case GST_MESSAGE_SEGMENT_DONE: - break; - case GST_MESSAGE_LATENCY: -#if GST_CHECK_VERSION(0,10,13) - case GST_MESSAGE_ASYNC_START: - break; - case GST_MESSAGE_ASYNC_DONE: - { - gint64 position = 0; - if (qt_gst_element_query_position(m_playbin, GST_FORMAT_TIME, &position)) { - position /= 1000000; - m_lastPosition = position; - emit positionChanged(position); - } - break; - } -#if GST_CHECK_VERSION(0,10,23) - case GST_MESSAGE_REQUEST_STATE: -#endif -#endif - case GST_MESSAGE_ANY: - break; - default: - break; - } - } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) { - GError *err; - gchar *debug; - gst_message_parse_error(gm, &err, &debug); - // If the source has given up, so do we. - if (qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) { - bool everPlayed = m_everPlayed; - // Try and differentiate network related resource errors from the others - if (!m_request.url().isRelative() && m_request.url().scheme().compare(QLatin1String("file"), Qt::CaseInsensitive) != 0 ) { - if (everPlayed || - (err->domain == GST_RESOURCE_ERROR && ( - err->code == GST_RESOURCE_ERROR_BUSY || - err->code == GST_RESOURCE_ERROR_OPEN_READ || - err->code == GST_RESOURCE_ERROR_READ || - err->code == GST_RESOURCE_ERROR_SEEK || - err->code == GST_RESOURCE_ERROR_SYNC))) { - processInvalidMedia(QMediaPlayer::NetworkError, QString::fromUtf8(err->message)); - } else { - processInvalidMedia(QMediaPlayer::ResourceError, QString::fromUtf8(err->message)); - } - } - else - processInvalidMedia(QMediaPlayer::ResourceError, QString::fromUtf8(err->message)); - } else if (err->domain == GST_STREAM_ERROR - && (err->code == GST_STREAM_ERROR_DECRYPT || err->code == GST_STREAM_ERROR_DECRYPT_NOKEY)) { - processInvalidMedia(QMediaPlayer::AccessDeniedError, QString::fromUtf8(err->message)); - } else { - handlePlaybin2 = true; - } - if (!handlePlaybin2) - qWarning() << "Error:" << QString::fromUtf8(err->message); - g_error_free(err); - g_free(debug); - } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT - && qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0 - && m_sourceType == UDPSrc - && gst_structure_has_name(gst_message_get_structure(gm), "GstUDPSrcTimeout")) { - //since udpsrc will not generate an error for the timeout event, - //we need to process its element message here and treat it as an error. - processInvalidMedia(m_everPlayed ? QMediaPlayer::NetworkError : QMediaPlayer::ResourceError, - tr("UDP source timeout")); - } else { - handlePlaybin2 = true; - } - - if (handlePlaybin2) { - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_WARNING) { - GError *err; - gchar *debug; - gst_message_parse_warning(gm, &err, &debug); - if (err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND) - emit error(int(QMediaPlayer::FormatError), tr("Cannot play stream of type: <unknown>")); - // GStreamer shows warning for HTTP playlists - if (err && err->message) - qWarning() << "Warning:" << QString::fromUtf8(err->message); - g_error_free(err); - g_free(debug); - } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) { - GError *err; - gchar *debug; - gst_message_parse_error(gm, &err, &debug); - - // Nearly all errors map to ResourceError - QMediaPlayer::Error qerror = QMediaPlayer::ResourceError; - if (err->domain == GST_STREAM_ERROR - && (err->code == GST_STREAM_ERROR_DECRYPT - || err->code == GST_STREAM_ERROR_DECRYPT_NOKEY)) { - qerror = QMediaPlayer::AccessDeniedError; - } - processInvalidMedia(qerror, QString::fromUtf8(err->message)); - if (err && err->message) - qWarning() << "Error:" << QString::fromUtf8(err->message); - - g_error_free(err); - g_free(debug); - } - } - } - - return false; -} - -void QGstreamerPlayerSession::getStreamsInfo() -{ - QList< QMap<QString,QVariant> > oldProperties = m_streamProperties; - QList<QMediaStreamsControl::StreamType> oldTypes = m_streamTypes; - QMap<QMediaStreamsControl::StreamType, int> oldOffset = m_playbin2StreamOffset; - - //check if video is available: - bool haveAudio = false; - bool haveVideo = false; - m_streamProperties.clear(); - m_streamTypes.clear(); - m_playbin2StreamOffset.clear(); - - gint audioStreamsCount = 0; - gint videoStreamsCount = 0; - gint textStreamsCount = 0; - - g_object_get(G_OBJECT(m_playbin), "n-audio", &audioStreamsCount, NULL); - g_object_get(G_OBJECT(m_playbin), "n-video", &videoStreamsCount, NULL); - g_object_get(G_OBJECT(m_playbin), "n-text", &textStreamsCount, NULL); - - haveAudio = audioStreamsCount > 0; - haveVideo = videoStreamsCount > 0; - - m_playbin2StreamOffset[QMediaStreamsControl::AudioStream] = 0; - m_playbin2StreamOffset[QMediaStreamsControl::VideoStream] = audioStreamsCount; - m_playbin2StreamOffset[QMediaStreamsControl::SubPictureStream] = audioStreamsCount+videoStreamsCount; - - for (int i=0; i<audioStreamsCount; i++) - m_streamTypes.append(QMediaStreamsControl::AudioStream); - - for (int i=0; i<videoStreamsCount; i++) - m_streamTypes.append(QMediaStreamsControl::VideoStream); - - for (int i=0; i<textStreamsCount; i++) - m_streamTypes.append(QMediaStreamsControl::SubPictureStream); - - for (int i=0; i<m_streamTypes.count(); i++) { - QMediaStreamsControl::StreamType streamType = m_streamTypes[i]; - QMap<QString, QVariant> streamProperties; - - int streamIndex = i - m_playbin2StreamOffset[streamType]; - - GstTagList *tags = 0; - switch (streamType) { - case QMediaStreamsControl::AudioStream: - g_signal_emit_by_name(G_OBJECT(m_playbin), "get-audio-tags", streamIndex, &tags); - break; - case QMediaStreamsControl::VideoStream: - g_signal_emit_by_name(G_OBJECT(m_playbin), "get-video-tags", streamIndex, &tags); - break; - case QMediaStreamsControl::SubPictureStream: - g_signal_emit_by_name(G_OBJECT(m_playbin), "get-text-tags", streamIndex, &tags); - break; - default: - break; - } -#if GST_CHECK_VERSION(1,0,0) - if (tags && GST_IS_TAG_LIST(tags)) { -#else - if (tags && gst_is_tag_list(tags)) { -#endif - gchar *languageCode = 0; - if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &languageCode)) - streamProperties[QMediaMetaData::Language] = QString::fromUtf8(languageCode); - - //qDebug() << "language for setream" << i << QString::fromUtf8(languageCode); - g_free (languageCode); - gst_tag_list_free(tags); - } - - m_streamProperties.append(streamProperties); - } - - bool emitAudioChanged = (haveAudio != m_audioAvailable); - bool emitVideoChanged = (haveVideo != m_videoAvailable); - - m_audioAvailable = haveAudio; - m_videoAvailable = haveVideo; - - if (emitAudioChanged) { - emit audioAvailableChanged(m_audioAvailable); - } - if (emitVideoChanged) { - emit videoAvailableChanged(m_videoAvailable); - } - - if (oldProperties != m_streamProperties || oldTypes != m_streamTypes || oldOffset != m_playbin2StreamOffset) - emit streamsChanged(); -} - -void QGstreamerPlayerSession::updateVideoResolutionTag() -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - QSize size; - QSize aspectRatio; - GstPad *pad = gst_element_get_static_pad(m_videoIdentity, "src"); - GstCaps *caps = qt_gst_pad_get_current_caps(pad); - - if (caps) { - const GstStructure *structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &size.rwidth()); - gst_structure_get_int(structure, "height", &size.rheight()); - - gint aspectNum = 0; - gint aspectDenum = 0; - if (!size.isEmpty() && gst_structure_get_fraction( - structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) { - if (aspectDenum > 0) - aspectRatio = QSize(aspectNum, aspectDenum); - } - gst_caps_unref(caps); - } - - gst_object_unref(GST_OBJECT(pad)); - - QSize currentSize = m_tags.value("resolution").toSize(); - QSize currentAspectRatio = m_tags.value("pixel-aspect-ratio").toSize(); - - if (currentSize != size || currentAspectRatio != aspectRatio) { - if (aspectRatio.isEmpty()) - m_tags.remove("pixel-aspect-ratio"); - - if (size.isEmpty()) { - m_tags.remove("resolution"); - } else { - m_tags.insert("resolution", QVariant(size)); - if (!aspectRatio.isEmpty()) - m_tags.insert("pixel-aspect-ratio", QVariant(aspectRatio)); - } - - emit tagsChanged(); - } -} - -void QGstreamerPlayerSession::updateDuration() -{ - gint64 gstDuration = 0; - int duration = 0; - - if (m_playbin && qt_gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &gstDuration)) - duration = gstDuration / 1000000; - - if (m_duration != duration) { - m_duration = duration; - emit durationChanged(m_duration); - } - - gboolean seekable = false; - if (m_duration > 0) { - m_durationQueries = 0; - GstQuery *query = gst_query_new_seeking(GST_FORMAT_TIME); - if (gst_element_query(m_playbin, query)) - gst_query_parse_seeking(query, 0, &seekable, 0, 0); - gst_query_unref(query); - } - setSeekable(seekable); - - if (m_durationQueries > 0) { - //increase delay between duration requests - int delay = 25 << (5 - m_durationQueries); - QTimer::singleShot(delay, this, SLOT(updateDuration())); - m_durationQueries--; - } -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << m_duration; -#endif -} - -void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpointer d) -{ - Q_UNUSED(p); - - GstElement *source = 0; - g_object_get(o, "source", &source, NULL); - if (source == 0) - return; - -#ifdef DEBUG_PLAYBIN - qDebug() << "Playbin source added:" << G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)); -#endif - - // Set Headers - const QByteArray userAgentString("User-Agent"); - - QGstreamerPlayerSession *self = reinterpret_cast<QGstreamerPlayerSession *>(d); - - // User-Agent - special case, souphhtpsrc will always set something, even if - // defined in extra-headers - if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "user-agent") != 0) { - g_object_set(G_OBJECT(source), "user-agent", - self->m_request.rawHeader(userAgentString).constData(), NULL); - } - - // The rest - if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0) { - GstStructure *extras = qt_gst_structure_new_empty("extras"); - - const auto rawHeaderList = self->m_request.rawHeaderList(); - for (const QByteArray &rawHeader : rawHeaderList) { - if (rawHeader == userAgentString) // Filter User-Agent - continue; - else { - GValue headerValue; - - memset(&headerValue, 0, sizeof(GValue)); - g_value_init(&headerValue, G_TYPE_STRING); - - g_value_set_string(&headerValue, - self->m_request.rawHeader(rawHeader).constData()); - - gst_structure_set_value(extras, rawHeader.constData(), &headerValue); - } - } - - if (gst_structure_n_fields(extras) > 0) - g_object_set(G_OBJECT(source), "extra-headers", extras, NULL); - - gst_structure_free(extras); - } - - //set timeout property to 30 seconds - const int timeout = 30; - if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstUDPSrc") == 0) { - quint64 convertedTimeout = timeout; -#if GST_CHECK_VERSION(1,0,0) - // Gst 1.x -> nanosecond - convertedTimeout *= 1000000000; -#else - // Gst 0.10 -> microsecond - convertedTimeout *= 1000000; -#endif - g_object_set(G_OBJECT(source), "timeout", convertedTimeout, NULL); - self->m_sourceType = UDPSrc; - //The udpsrc is always a live source. - self->m_isLiveSource = true; - } else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstSoupHTTPSrc") == 0) { - //souphttpsrc timeout unit = second - g_object_set(G_OBJECT(source), "timeout", guint(timeout), NULL); - self->m_sourceType = SoupHTTPSrc; - //since gst_base_src_is_live is not reliable, so we check the source property directly - gboolean isLive = false; - g_object_get(G_OBJECT(source), "is-live", &isLive, NULL); - self->m_isLiveSource = isLive; - } else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstMMSSrc") == 0) { - self->m_sourceType = MMSSrc; - self->m_isLiveSource = gst_base_src_is_live(GST_BASE_SRC(source)); - g_object_set(G_OBJECT(source), "tcp-timeout", G_GUINT64_CONSTANT(timeout*1000000), NULL); - } else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstRTSPSrc") == 0) { - //rtspsrc acts like a live source and will therefore only generate data in the PLAYING state. - self->m_sourceType = RTSPSrc; - self->m_isLiveSource = true; - g_object_set(G_OBJECT(source), "buffer-mode", 1, NULL); - } else { - self->m_sourceType = UnknownSrc; - self->m_isLiveSource = gst_base_src_is_live(GST_BASE_SRC(source)); - } - -#ifdef DEBUG_PLAYBIN - if (self->m_isLiveSource) - qDebug() << "Current source is a live source"; - else - qDebug() << "Current source is a non-live source"; -#endif - - if (self->m_videoSink) - g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, NULL); - - gst_object_unref(source); -} - -bool QGstreamerPlayerSession::isLiveSource() const -{ - return m_isLiveSource; -} - -void QGstreamerPlayerSession::handleVolumeChange(GObject *o, GParamSpec *p, gpointer d) -{ - Q_UNUSED(o); - Q_UNUSED(p); - QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession *>(d); - QMetaObject::invokeMethod(session, "updateVolume", Qt::QueuedConnection); -} - -void QGstreamerPlayerSession::updateVolume() -{ - double volume = 1.0; - g_object_get(m_playbin, "volume", &volume, NULL); - - if (m_volume != int(volume*100 + 0.5)) { - m_volume = int(volume*100 + 0.5); -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << m_volume; -#endif - emit volumeChanged(m_volume); - } -} - -void QGstreamerPlayerSession::handleMutedChange(GObject *o, GParamSpec *p, gpointer d) -{ - Q_UNUSED(o); - Q_UNUSED(p); - QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession *>(d); - QMetaObject::invokeMethod(session, "updateMuted", Qt::QueuedConnection); -} - -void QGstreamerPlayerSession::updateMuted() -{ - gboolean muted = FALSE; - g_object_get(G_OBJECT(m_playbin), "mute", &muted, NULL); - if (m_muted != muted) { - m_muted = muted; -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << m_muted; -#endif - emit mutedStateChanged(muted); - } -} - -#if !GST_CHECK_VERSION(0, 10, 33) -static gboolean factory_can_src_any_caps (GstElementFactory *factory, const GstCaps *caps) -{ - GList *templates; - - g_return_val_if_fail(factory != NULL, FALSE); - g_return_val_if_fail(caps != NULL, FALSE); - - templates = factory->staticpadtemplates; - - while (templates) { - GstStaticPadTemplate *templ = (GstStaticPadTemplate *)templates->data; - - if (templ->direction == GST_PAD_SRC) { - GstCaps *templcaps = gst_static_caps_get(&templ->static_caps); - - if (qt_gst_caps_can_intersect(caps, templcaps)) { - gst_caps_unref(templcaps); - return TRUE; - } - gst_caps_unref(templcaps); - } - templates = g_list_next(templates); - } - - return FALSE; -} -#endif - -GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session) -{ - Q_UNUSED(bin); - Q_UNUSED(pad); - Q_UNUSED(caps); - - GstAutoplugSelectResult res = GST_AUTOPLUG_SELECT_TRY; - - // if VAAPI is available and can be used to decode but the current video sink cannot handle - // the decoded format, don't use it - const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory)); - if (g_str_has_prefix(factoryName, "vaapi")) { - GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink"); -#if GST_CHECK_VERSION(1,0,0) - GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, NULL); -#else - GstCaps *sinkCaps = gst_pad_get_caps(sinkPad); -#endif - -#if !GST_CHECK_VERSION(0, 10, 33) - if (!factory_can_src_any_caps(factory, sinkCaps)) -#else - if (!gst_element_factory_can_src_any_caps(factory, sinkCaps)) -#endif - res = GST_AUTOPLUG_SELECT_SKIP; - - gst_object_unref(sinkPad); - gst_caps_unref(sinkCaps); - } - - return res; -} - -void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session) -{ - Q_UNUSED(bin); - //we have to configure queue2 element to enable media downloading - //and reporting available ranges, - //but it's added dynamically to playbin2 - - gchar *elementName = gst_element_get_name(element); - - if (g_str_has_prefix(elementName, "queue2")) { - // Disable on-disk buffering. - g_object_set(G_OBJECT(element), "temp-template", NULL, NULL); - } else if (g_str_has_prefix(elementName, "uridecodebin") || -#if GST_CHECK_VERSION(1,0,0) - g_str_has_prefix(elementName, "decodebin")) { -#else - g_str_has_prefix(elementName, "decodebin2")) { - if (g_str_has_prefix(elementName, "uridecodebin")) { - // Add video/x-surface (VAAPI) to default raw formats - g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL); - // listen for uridecodebin autoplug-select to skip VAAPI usage when the current - // video sink doesn't support it - g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session); - } -#endif - //listen for queue2 element added to uridecodebin/decodebin2 as well. - //Don't touch other bins since they may have unrelated queues - g_signal_connect(element, "element-added", - G_CALLBACK(handleElementAdded), session); - } - - g_free(elementName); -} - -void QGstreamerPlayerSession::handleStreamsChange(GstBin *bin, gpointer user_data) -{ - Q_UNUSED(bin); - - QGstreamerPlayerSession* session = reinterpret_cast<QGstreamerPlayerSession*>(user_data); - QMetaObject::invokeMethod(session, "getStreamsInfo", Qt::QueuedConnection); -} - -//doing proper operations when detecting an invalidMedia: change media status before signal the erorr -void QGstreamerPlayerSession::processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - emit invalidMedia(); - stop(); - emit error(int(errorCode), errorString); -} - -void QGstreamerPlayerSession::showPrerollFrames(bool enabled) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO << enabled; -#endif - if (enabled != m_displayPrerolledFrame && m_videoSink && - g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) { - - gboolean value = enabled; - g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, NULL); - m_displayPrerolledFrame = enabled; - } -} - -void QGstreamerPlayerSession::addProbe(QGstreamerVideoProbeControl* probe) -{ - Q_ASSERT(!m_videoProbe); - m_videoProbe = probe; - addVideoBufferProbe(); -} - -void QGstreamerPlayerSession::removeProbe(QGstreamerVideoProbeControl* probe) -{ - Q_ASSERT(m_videoProbe == probe); - removeVideoBufferProbe(); - m_videoProbe = 0; -} - -void QGstreamerPlayerSession::addProbe(QGstreamerAudioProbeControl* probe) -{ - Q_ASSERT(!m_audioProbe); - m_audioProbe = probe; - addAudioBufferProbe(); -} - -void QGstreamerPlayerSession::removeProbe(QGstreamerAudioProbeControl* probe) -{ - Q_ASSERT(m_audioProbe == probe); - removeAudioBufferProbe(); - m_audioProbe = 0; -} - -// This function is similar to stop(), -// but does not set m_everPlayed, m_lastPosition, -// and setSeekable() values. -void QGstreamerPlayerSession::endOfMediaReset() -{ - if (m_renderer) - m_renderer->stopRenderer(); - - flushVideoProbes(); - gst_element_set_state(m_playbin, GST_STATE_NULL); - - QMediaPlayer::State oldState = m_state; - m_pendingState = m_state = QMediaPlayer::StoppedState; - - finishVideoOutputChange(); - - if (oldState != m_state) - emit stateChanged(m_state); -} - -void QGstreamerPlayerSession::removeVideoBufferProbe() -{ - if (!m_videoProbe) - return; - - GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); - if (pad) { - m_videoProbe->removeProbeFromPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } -} - -void QGstreamerPlayerSession::addVideoBufferProbe() -{ - if (!m_videoProbe) - return; - - GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); - if (pad) { - m_videoProbe->addProbeToPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } -} - -void QGstreamerPlayerSession::removeAudioBufferProbe() -{ - if (!m_audioProbe) - return; - - GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink"); - if (pad) { - m_audioProbe->removeProbeFromPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } -} - -void QGstreamerPlayerSession::addAudioBufferProbe() -{ - if (!m_audioProbe) - return; - - GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink"); - if (pad) { - m_audioProbe->addProbeToPad(pad); - gst_object_unref(GST_OBJECT(pad)); - } -} - -void QGstreamerPlayerSession::flushVideoProbes() -{ - if (m_videoProbe) - m_videoProbe->startFlushing(); -} - -void QGstreamerPlayerSession::resumeVideoProbes() -{ - if (m_videoProbe) - m_videoProbe->stopFlushing(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h deleted file mode 100644 index 7f46e8f41..000000000 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERPLAYERSESSION_H -#define QGSTREAMERPLAYERSESSION_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <QObject> -#include <QtCore/qmutex.h> -#include <QtNetwork/qnetworkrequest.h> -#include "qgstreamerplayercontrol.h" -#include <private/qgstreamerbushelper_p.h> -#include <qmediaplayer.h> -#include <qmediastreamscontrol.h> -#include <qaudioformat.h> - -#if QT_CONFIG(gstreamer_app) -#include <private/qgstappsrc_p.h> -#endif - -#include <gst/gst.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerBusHelper; -class QGstreamerMessage; - -class QGstreamerVideoRendererInterface; -class QGstreamerVideoProbeControl; -class QGstreamerAudioProbeControl; - -typedef enum { - GST_AUTOPLUG_SELECT_TRY, - GST_AUTOPLUG_SELECT_EXPOSE, - GST_AUTOPLUG_SELECT_SKIP -} GstAutoplugSelectResult; - -class QGstreamerPlayerSession : public QObject, - public QGstreamerBusMessageFilter -{ -Q_OBJECT -Q_INTERFACES(QGstreamerBusMessageFilter) - -public: - QGstreamerPlayerSession(QObject *parent); - virtual ~QGstreamerPlayerSession(); - - GstElement *playbin() const; - QGstreamerBusHelper *bus() const { return m_busHelper; } - - QNetworkRequest request() const; - - QMediaPlayer::State state() const { return m_state; } - QMediaPlayer::State pendingState() const { return m_pendingState; } - - qint64 duration() const; - qint64 position() const; - - int volume() const; - bool isMuted() const; - - bool isAudioAvailable() const; - - void setVideoRenderer(QObject *renderer); - bool isVideoAvailable() const; - - bool isSeekable() const; - - qreal playbackRate() const; - void setPlaybackRate(qreal rate); - - QMediaTimeRange availablePlaybackRanges() const; - - QMap<QByteArray ,QVariant> tags() const { return m_tags; } - QMap<QString,QVariant> streamProperties(int streamNumber) const { return m_streamProperties[streamNumber]; } - int streamCount() const { return m_streamProperties.count(); } - QMediaStreamsControl::StreamType streamType(int streamNumber) { return m_streamTypes.value(streamNumber, QMediaStreamsControl::UnknownStream); } - - int activeStream(QMediaStreamsControl::StreamType streamType) const; - void setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber); - - bool processBusMessage(const QGstreamerMessage &message) override; - -#if QT_CONFIG(gstreamer_app) - QGstAppSrc *appsrc() const { return m_appSrc; } - static void configureAppSrcElement(GObject*, GObject*, GParamSpec*,QGstreamerPlayerSession* _this); -#endif - - bool isLiveSource() const; - - void addProbe(QGstreamerVideoProbeControl* probe); - void removeProbe(QGstreamerVideoProbeControl* probe); - - void addProbe(QGstreamerAudioProbeControl* probe); - void removeProbe(QGstreamerAudioProbeControl* probe); - - void endOfMediaReset(); - -public slots: - void loadFromUri(const QNetworkRequest &url); - void loadFromStream(const QNetworkRequest &url, QIODevice *stream); - bool play(); - bool pause(); - void stop(); - - bool seek(qint64 pos); - - void setVolume(int volume); - void setMuted(bool muted); - - void showPrerollFrames(bool enabled); - -signals: - void durationChanged(qint64 duration); - void positionChanged(qint64 position); - void stateChanged(QMediaPlayer::State state); - void volumeChanged(int volume); - void mutedStateChanged(bool muted); - void audioAvailableChanged(bool audioAvailable); - void videoAvailableChanged(bool videoAvailable); - void bufferingProgressChanged(int percentFilled); - void playbackFinished(); - void tagsChanged(); - void streamsChanged(); - void seekableChanged(bool); - void error(int error, const QString &errorString); - void invalidMedia(); - void playbackRateChanged(qreal); - -private slots: - void getStreamsInfo(); - void setSeekable(bool); - void finishVideoOutputChange(); - void updateVideoRenderer(); - void updateVideoResolutionTag(); - void updateVolume(); - void updateMuted(); - void updateDuration(); - -private: - static void playbinNotifySource(GObject *o, GParamSpec *p, gpointer d); - static void handleVolumeChange(GObject *o, GParamSpec *p, gpointer d); - static void handleMutedChange(GObject *o, GParamSpec *p, gpointer d); -#if !GST_CHECK_VERSION(1,0,0) - static void insertColorSpaceElement(GstElement *element, gpointer data); -#endif - static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session); - static void handleStreamsChange(GstBin *bin, gpointer user_data); - static GstAutoplugSelectResult handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session); - - void processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString); - - void removeVideoBufferProbe(); - void addVideoBufferProbe(); - void removeAudioBufferProbe(); - void addAudioBufferProbe(); - void flushVideoProbes(); - void resumeVideoProbes(); - - QNetworkRequest m_request; - QMediaPlayer::State m_state; - QMediaPlayer::State m_pendingState; - QGstreamerBusHelper* m_busHelper; - GstElement* m_playbin; - - GstElement* m_videoSink; - - GstElement* m_videoOutputBin; - GstElement* m_videoIdentity; -#if !GST_CHECK_VERSION(1,0,0) - GstElement* m_colorSpace; - bool m_usingColorspaceElement; -#endif - GstElement* m_pendingVideoSink; - GstElement* m_nullVideoSink; - - GstElement* m_audioSink; - GstElement* m_volumeElement; - - GstBus* m_bus; - QObject *m_videoOutput; - QGstreamerVideoRendererInterface *m_renderer; - -#if QT_CONFIG(gstreamer_app) - QGstAppSrc *m_appSrc; -#endif - - QMap<QByteArray, QVariant> m_tags; - QList< QMap<QString,QVariant> > m_streamProperties; - QList<QMediaStreamsControl::StreamType> m_streamTypes; - QMap<QMediaStreamsControl::StreamType, int> m_playbin2StreamOffset; - - QGstreamerVideoProbeControl *m_videoProbe; - QGstreamerAudioProbeControl *m_audioProbe; - - int m_volume; - qreal m_playbackRate; - bool m_muted; - bool m_audioAvailable; - bool m_videoAvailable; - bool m_seekable; - - mutable qint64 m_lastPosition; - qint64 m_duration; - int m_durationQueries; - - bool m_displayPrerolledFrame; - - enum SourceType - { - UnknownSrc, - SoupHTTPSrc, - UDPSrc, - MMSSrc, - RTSPSrc, - }; - SourceType m_sourceType; - bool m_everPlayed; - bool m_isLiveSource; - - gulong pad_probe_id; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERPLAYERSESSION_H diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp index 99caa2ae0..4f5c3f0b2 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "qgstreamerstreamscontrol.h" -#include "qgstreamerplayersession.h" +#include <private/qgstreamerplayersession_p.h> QGstreamerStreamsControl::QGstreamerStreamsControl(QGstreamerPlayerSession *session, QObject *parent) :QMediaStreamsControl(parent), m_session(session) diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp index 465ccfa7d..4b68f47a4 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp @@ -103,7 +103,7 @@ void QSGVivanteVideoMaterial::setCurrentFrame(const QVideoFrame &frame, QSGVideo { QMutexLocker lock(&mFrameMutex); mNextFrame = frame; - mMappable = !flags.testFlag(QSGVideoNode::FrameFiltered); + mMappable = mMapError == GL_NO_ERROR && !flags.testFlag(QSGVideoNode::FrameFiltered); #ifdef QT_VIVANTE_VIDEO_DEBUG qDebug() << Q_FUNC_INFO << " new frame: " << frame; @@ -172,6 +172,7 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) mWidth = vF.width(); mHeight = vF.height(); mFormat = vF.pixelFormat(); + mMapError = GL_NO_ERROR; clearTextures(); } @@ -236,7 +237,12 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D); - return tmpTexId; + mMapError = glGetError(); + if (mMapError == GL_NO_ERROR) + return tmpTexId; + + // Error occurred. + // Fallback to copying data. } else { // Fastest path: already seen this logical address. Just // indicate that the data belonging to the texture has changed. @@ -244,40 +250,40 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D); return mBitsToTextureMap.value(vF.bits()); } + } + + // Cannot map. So copy. + if (!mTexDirectTexture) { + glGenTextures(1, &mTexDirectTexture); + glBindTexture(GL_TEXTURE_2D, mTexDirectTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexDirectVIV_LOCAL(GL_TEXTURE_2D, mCurrentFrame.width(), mCurrentFrame.height(), + QSGVivanteVideoNode::getVideoFormat2GLFormatMap().value(mCurrentFrame.pixelFormat()), + (GLvoid **) &mTexDirectPlanes); } else { - // Cannot map. So copy. - if (!mTexDirectTexture) { - glGenTextures(1, &mTexDirectTexture); - glBindTexture(GL_TEXTURE_2D, mTexDirectTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexDirectVIV_LOCAL(GL_TEXTURE_2D, mCurrentFrame.width(), mCurrentFrame.height(), - QSGVivanteVideoNode::getVideoFormat2GLFormatMap().value(mCurrentFrame.pixelFormat()), - (GLvoid **) &mTexDirectPlanes); - } else { - glBindTexture(GL_TEXTURE_2D, mTexDirectTexture); - } - switch (mCurrentFrame.pixelFormat()) { - case QVideoFrame::Format_YUV420P: - case QVideoFrame::Format_YV12: - memcpy(mTexDirectPlanes[0], mCurrentFrame.bits(0), mCurrentFrame.height() * mCurrentFrame.bytesPerLine(0)); - memcpy(mTexDirectPlanes[1], mCurrentFrame.bits(1), mCurrentFrame.height() * mCurrentFrame.bytesPerLine(1)); - memcpy(mTexDirectPlanes[2], mCurrentFrame.bits(2), mCurrentFrame.height() * mCurrentFrame.bytesPerLine(2)); - break; - case QVideoFrame::Format_NV12: - case QVideoFrame::Format_NV21: - memcpy(mTexDirectPlanes[0], mCurrentFrame.bits(0), mCurrentFrame.height() * mCurrentFrame.bytesPerLine(0)); - memcpy(mTexDirectPlanes[1], mCurrentFrame.bits(1), mCurrentFrame.height() / 2 * mCurrentFrame.bytesPerLine(1)); - break; - default: - memcpy(mTexDirectPlanes[0], mCurrentFrame.bits(), mCurrentFrame.height() * mCurrentFrame.bytesPerLine()); - break; - } - glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D); - return mTexDirectTexture; + glBindTexture(GL_TEXTURE_2D, mTexDirectTexture); + } + switch (mCurrentFrame.pixelFormat()) { + case QVideoFrame::Format_YUV420P: + case QVideoFrame::Format_YV12: + memcpy(mTexDirectPlanes[0], mCurrentFrame.bits(0), mCurrentFrame.height() * mCurrentFrame.bytesPerLine(0)); + memcpy(mTexDirectPlanes[1], mCurrentFrame.bits(1), mCurrentFrame.height() / 2 * mCurrentFrame.bytesPerLine(1)); + memcpy(mTexDirectPlanes[2], mCurrentFrame.bits(2), mCurrentFrame.height() / 2 * mCurrentFrame.bytesPerLine(2)); + break; + case QVideoFrame::Format_NV12: + case QVideoFrame::Format_NV21: + memcpy(mTexDirectPlanes[0], mCurrentFrame.bits(0), mCurrentFrame.height() * mCurrentFrame.bytesPerLine(0)); + memcpy(mTexDirectPlanes[1], mCurrentFrame.bits(1), mCurrentFrame.height() / 2 * mCurrentFrame.bytesPerLine(1)); + break; + default: + memcpy(mTexDirectPlanes[0], mCurrentFrame.bits(), mCurrentFrame.height() * mCurrentFrame.bytesPerLine()); + break; } + glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D); + return mTexDirectTexture; } else { #ifdef QT_VIVANTE_VIDEO_DEBUG diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.h b/src/plugins/videonode/imx6/qsgvivantevideomaterial.h index 862747f27..adbd960a4 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.h +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.h @@ -81,6 +81,7 @@ private: QVideoFrame mCurrentFrame, mNextFrame; GLuint mCurrentTexture; bool mMappable; + GLenum mMapError = GL_NO_ERROR; QMutex mFrameMutex; diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp index d1c0b475f..26eecb768 100644 --- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp @@ -295,11 +295,22 @@ bool QWindowsAudioOutput::open() return true; } +void QWindowsAudioOutput::pauseAndSleep() +{ + waveOutPause(hWaveOut); + int bitrate = settings.sampleRate() * settings.channelCount() * settings.sampleSize() / 8; + // Time of written data. + int delay = (buffer_size - bytesFree()) * 1000 / bitrate; + Sleep(delay + 10); +} + void QWindowsAudioOutput::close() { if(deviceState == QAudio::StoppedState) return; + // Pause playback before reset to avoid uneeded crackling at the end. + pauseAndSleep(); deviceState = QAudio::StoppedState; errorState = QAudio::NoError; waveOutReset(hWaveOut); @@ -455,10 +466,7 @@ void QWindowsAudioOutput::resume() void QWindowsAudioOutput::suspend() { if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState) { - int delay = (buffer_size-bytesFree())*1000/(settings.sampleRate() - *settings.channelCount()*(settings.sampleSize()/8)); - waveOutPause(hWaveOut); - Sleep(delay+10); + pauseAndSleep(); deviceState = QAudio::SuspendedState; errorState = QAudio::NoError; emit stateChanged(deviceState); diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.h b/src/plugins/windowsaudio/qwindowsaudiooutput.h index f25475b02..b71f00e98 100644 --- a/src/plugins/windowsaudio/qwindowsaudiooutput.h +++ b/src/plugins/windowsaudio/qwindowsaudiooutput.h @@ -115,6 +115,7 @@ private slots: bool deviceReady(); private: + void pauseAndSleep(); QByteArray m_device; int bytesAvailable; QTime timeStamp; diff --git a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp index 3544031a7..654d0e605 100644 --- a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp +++ b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp @@ -91,7 +91,7 @@ struct QWinRTVideoRendererControlGlobal #ifdef _DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif - hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, + hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &context); #ifdef _DEBUG @@ -106,7 +106,7 @@ struct QWinRTVideoRendererControlGlobal qErrnoWarning(hr, "Failed to create D3D device"); if (!device || FAILED(hr)) { - hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, flags, + hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, flags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &context); if (FAILED(hr)) { @@ -160,7 +160,7 @@ public: Q_UNUSED(mode); Q_UNUSED(numBytes); Q_UNUSED(bytesPerLine); - return 0; + return nullptr; } void unmap() override @@ -227,9 +227,9 @@ QWinRTAbstractVideoRendererControl::QWinRTAbstractVideoRendererControl(const QSi d->format = QVideoSurfaceFormat(size, QVideoFrame::Format_BGRA32, QAbstractVideoBuffer::GLTextureHandle); d->dirtyState = TextureDirty; - d->shareHandle = 0; + d->shareHandle = nullptr; d->eglDisplay = EGL_NO_DISPLAY; - d->eglConfig = 0; + d->eglConfig = nullptr; d->eglSurface = EGL_NO_SURFACE; d->active = false; d->blitMode = DirectVideo; @@ -278,7 +278,7 @@ void QWinRTAbstractVideoRendererControl::syncAndRender() CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, d->format.frameWidth(), d->format.frameHeight(), 1, 1); desc.BindFlags |= D3D11_BIND_RENDER_TARGET; desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; - hr = g->device->CreateTexture2D(&desc, NULL, d->texture.ReleaseAndGetAddressOf()); + hr = g->device->CreateTexture2D(&desc, nullptr, d->texture.ReleaseAndGetAddressOf()); BREAK_IF_FAILED("Failed to get create video texture"); ComPtr<IDXGIResource> resource; hr = d->texture.As(&resource); @@ -398,7 +398,7 @@ void QWinRTAbstractVideoRendererControl::setBlitMode(QWinRTAbstractVideoRenderer if (d->texture) { d->texture.Reset(); - d->shareHandle = 0; + d->shareHandle = nullptr; } if (d->eglSurface) { diff --git a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.h b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.h index e190c8c4a..819dd9c3a 100644 --- a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.h +++ b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.h @@ -55,8 +55,8 @@ class QWinRTAbstractVideoRendererControl : public QVideoRendererControl { Q_OBJECT public: - explicit QWinRTAbstractVideoRendererControl(const QSize &size, QObject *parent = 0); - ~QWinRTAbstractVideoRendererControl(); + explicit QWinRTAbstractVideoRendererControl(const QSize &size, QObject *parent = nullptr); + ~QWinRTAbstractVideoRendererControl() override; enum BlitMode { DirectVideo, diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp index 164a958ff..c00f65624 100644 --- a/src/plugins/winrt/qwinrtcameracontrol.cpp +++ b/src/plugins/winrt/qwinrtcameracontrol.cpp @@ -54,7 +54,7 @@ #include <functional> #include <mfapi.h> -#include <mferror.h> +#include <Mferror.h> #include <mfidl.h> #include <wrl.h> #include <windows.devices.enumeration.h> @@ -103,7 +103,7 @@ HRESULT getMediaStreamResolutions(IMediaDeviceController *device, quint32 listSize; hr = (*propertiesList)->get_Size(&listSize); Q_ASSERT_SUCCEEDED(hr); - resolutions->reserve(listSize); + resolutions->reserve(int(listSize)); for (quint32 index = 0; index < listSize; ++index) { ComPtr<IMediaEncodingProperties> properties; hr = (*propertiesList)->GetAt(index, &properties); @@ -123,7 +123,7 @@ HRESULT getMediaStreamResolutions(IMediaDeviceController *device, Q_ASSERT_SUCCEEDED(hr); hr = videoProperties->get_Height(&height); Q_ASSERT_SUCCEEDED(hr); - resolutions->append(QSize(width, height)); + resolutions->append(QSize(int(width), int(height))); } else if (propertyType == imageRef) { ComPtr<IImageEncodingProperties> imageProperties; hr = properties.As(&imageProperties); @@ -133,7 +133,7 @@ HRESULT getMediaStreamResolutions(IMediaDeviceController *device, Q_ASSERT_SUCCEEDED(hr); hr = imageProperties->get_Height(&height); Q_ASSERT_SUCCEEDED(hr); - resolutions->append(QSize(width, height)); + resolutions->append(QSize(int(width), int(height))); } } return resolutions->isEmpty() ? MF_E_INVALID_FORMAT : hr; @@ -237,7 +237,7 @@ public: Q_ASSERT_SUCCEEDED(hr); } - ~MediaStream() + ~MediaStream() override { QMutexLocker locker(&m_mutex); m_eventQueue->Shutdown(); @@ -399,9 +399,7 @@ public: m_stream = Make<MediaStream>(videoType.Get(), this, videoRenderer); } - ~MediaSink() - { - } + ~MediaSink() override = default; HRESULT RequestSample() { @@ -591,7 +589,7 @@ QWinRTCameraControl::QWinRTCameraControl(QObject *parent) d->cameraFocusControl = new QWinRTCameraFocusControl(this); d->cameraLocksControl = new QWinRTCameraLocksControl(this); - d->initializationCompleteEvent = CreateEvent(NULL, false, false, NULL); + d->initializationCompleteEvent = CreateEvent(nullptr, false, false, nullptr); if (qGuiApp) { connect(qGuiApp, &QGuiApplication::applicationStateChanged, @@ -954,13 +952,12 @@ HRESULT QWinRTCameraControl::initialize() return E_FAIL; } - const QCamera::Position position = d->videoDeviceSelector->cameraPosition(deviceName); d->videoRenderer->setScanLineDirection(QVideoSurfaceFormat::TopToBottom); ComPtr<IMediaCaptureInitializationSettings> settings; hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(), &settings); Q_ASSERT_SUCCEEDED(hr); - HStringReference deviceId(reinterpret_cast<LPCWSTR>(deviceName.utf16()), deviceName.length()); + HStringReference deviceId(reinterpret_cast<LPCWSTR>(deviceName.utf16()), uint(deviceName.length())); hr = settings->put_VideoDeviceId(deviceId.Get()); Q_ASSERT_SUCCEEDED(hr); @@ -992,7 +989,7 @@ HRESULT QWinRTCameraControl::initializeFocus() ComPtr<IVectorView<enum FocusMode>> focusModes; hr = focusControl2->get_SupportedFocusModes(&focusModes); if (FAILED(hr)) { - d->cameraFocusControl->setSupportedFocusMode(0); + d->cameraFocusControl->setSupportedFocusMode(nullptr); d->cameraFocusControl->setSupportedFocusPointMode(QSet<QCameraFocus::FocusPointMode>()); qErrnoWarning(hr, "Failed to get camera supported focus mode list"); return hr; @@ -1000,7 +997,7 @@ HRESULT QWinRTCameraControl::initializeFocus() quint32 size; hr = focusModes->get_Size(&size); Q_ASSERT_SUCCEEDED(hr); - QCameraFocus::FocusModes supportedModeFlag = 0; + QCameraFocus::FocusModes supportedModeFlag = nullptr; for (quint32 i = 0; i < size; ++i) { FocusMode mode; hr = focusModes->GetAt(i, &mode); @@ -1122,19 +1119,21 @@ bool QWinRTCameraControl::setFocus(QCameraFocus::FocusModes modes) bool QWinRTCameraControl::setFocusPoint(const QPointF &focusPoint) { Q_D(QWinRTCameraControl); - if (focusPoint.x() < FOCUS_RECT_POSITION_MIN || focusPoint.x() > FOCUS_RECT_BOUNDARY) { + if (focusPoint.x() < double(FOCUS_RECT_POSITION_MIN) + || focusPoint.x() > double(FOCUS_RECT_BOUNDARY)) { emit error(QCamera::CameraError, QStringLiteral("Focus horizontal location should be between 0.0 and 1.0.")); return false; } - if (focusPoint.y() < FOCUS_RECT_POSITION_MIN || focusPoint.y() > FOCUS_RECT_BOUNDARY) { + if (focusPoint.y() < double(FOCUS_RECT_POSITION_MIN) + || focusPoint.y() > double(FOCUS_RECT_BOUNDARY)) { emit error(QCamera::CameraError, QStringLiteral("Focus vertical location should be between 0.0 and 1.0.")); return false; } ABI::Windows::Foundation::Rect rect; - rect.X = qBound<float>(FOCUS_RECT_POSITION_MIN, focusPoint.x() - FOCUS_RECT_HALF_SIZE, FOCUS_RECT_POSITION_MAX); - rect.Y = qBound<float>(FOCUS_RECT_POSITION_MIN, focusPoint.y() - FOCUS_RECT_HALF_SIZE, FOCUS_RECT_POSITION_MAX); + rect.X = qBound<float>(FOCUS_RECT_POSITION_MIN, float(focusPoint.x() - double(FOCUS_RECT_HALF_SIZE)), FOCUS_RECT_POSITION_MAX); + rect.Y = qBound<float>(FOCUS_RECT_POSITION_MIN, float(focusPoint.y() - double(FOCUS_RECT_HALF_SIZE)), FOCUS_RECT_POSITION_MAX); rect.Width = (rect.X + FOCUS_RECT_SIZE) < FOCUS_RECT_BOUNDARY ? FOCUS_RECT_SIZE : FOCUS_RECT_BOUNDARY - rect.X; rect.Height = (rect.Y + FOCUS_RECT_SIZE) < FOCUS_RECT_BOUNDARY ? FOCUS_RECT_SIZE : FOCUS_RECT_BOUNDARY - rect.Y; @@ -1328,7 +1327,7 @@ HRESULT QWinRTCameraControl::onCaptureFailed(IMediaCapture *, IMediaCaptureFaile RETURN_HR_IF_FAILED("Failed to get error message"); quint32 messageLength; const wchar_t *messageBuffer = message.GetRawBuffer(&messageLength); - emit error(QCamera::CameraError, QString::fromWCharArray(messageBuffer, messageLength)); + emit error(QCamera::CameraError, QString::fromWCharArray(messageBuffer, int(messageLength))); setState(QCamera::LoadedState); return S_OK; } @@ -1402,7 +1401,7 @@ HRESULT QWinRTCameraControl::onInitializationCompleted(IAsyncAction *, AsyncStat // Set capture resolutions. d->imageEncoderControl->setSupportedResolutionsList(captureResolutions.toList()); const QSize captureResolution = d->imageEncoderControl->imageSettings().resolution(); - const quint32 captureResolutionIndex = captureResolutions.indexOf(captureResolution); + const quint32 captureResolutionIndex = quint32(captureResolutions.indexOf(captureResolution)); ComPtr<IMediaEncodingProperties> captureProperties; hr = capturePropertiesList->GetAt(captureResolutionIndex, &captureProperties); Q_ASSERT_SUCCEEDED(hr); @@ -1424,7 +1423,7 @@ HRESULT QWinRTCameraControl::onInitializationCompleted(IAsyncAction *, AsyncStat [](QSize size1, QSize size2) { return size1.width() * size1.height() < size2.width() * size2.height(); }); const QSize &viewfinderResolution = filtered.first(); - const quint32 viewfinderResolutionIndex = previewResolutions.indexOf(viewfinderResolution); + const quint32 viewfinderResolutionIndex = quint32(previewResolutions.indexOf(viewfinderResolution)); hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(), &d->encodingProfile); Q_ASSERT_SUCCEEDED(hr); diff --git a/src/plugins/winrt/qwinrtcameracontrol.h b/src/plugins/winrt/qwinrtcameracontrol.h index c46921a9c..3a2125f5b 100644 --- a/src/plugins/winrt/qwinrtcameracontrol.h +++ b/src/plugins/winrt/qwinrtcameracontrol.h @@ -78,8 +78,8 @@ class QWinRTCameraControl : public QCameraControl { Q_OBJECT public: - explicit QWinRTCameraControl(QObject *parent = 0); - ~QWinRTCameraControl(); + explicit QWinRTCameraControl(QObject *parent = nullptr); + ~QWinRTCameraControl() override; QCamera::State state() const override; void setState(QCamera::State state) override; diff --git a/src/plugins/winrt/qwinrtcamerafocuscontrol.cpp b/src/plugins/winrt/qwinrtcamerafocuscontrol.cpp index aeefc9241..afe7017d7 100644 --- a/src/plugins/winrt/qwinrtcamerafocuscontrol.cpp +++ b/src/plugins/winrt/qwinrtcamerafocuscontrol.cpp @@ -200,7 +200,7 @@ void QWinRTCameraFocusControl::setSupportedFocusMode(QCameraFocus::FocusModes mo d->focusModeInitialized = true; if (isFocusModeSupported(d->focusModes)) return; - d->focusModes = 0; + d->focusModes = nullptr; if (!modes) { emit focusModeChanged(d->focusModes); return; diff --git a/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp index f4903c5a1..4ed208feb 100644 --- a/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp +++ b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp @@ -170,7 +170,8 @@ int QWinRTCameraImageCaptureControl::capture(const QString &fileName) CaptureRequest request = { d->currentCaptureId, d->location.generateFileName(fileName, QMediaStorageLocation::Pictures, QStringLiteral("IMG_"), - fileName.isEmpty() ? QStringLiteral("jpg") : QFileInfo(fileName).suffix()) + fileName.isEmpty() ? QStringLiteral("jpg") : QFileInfo(fileName).suffix()), + nullptr, nullptr, nullptr }; HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d, capture, &request]() { @@ -183,9 +184,9 @@ int QWinRTCameraImageCaptureControl::capture(const QString &fileName) Q_ASSERT_SUCCEEDED(hr); const QSize imageSize = static_cast<QWinRTImageEncoderControl*>(d->cameraControl->imageEncoderControl())->imageSettings().resolution(); - hr = request.imageFormat->put_Width(imageSize.width()); + hr = request.imageFormat->put_Width(UINT32(imageSize.width())); Q_ASSERT_SUCCEEDED(hr); - hr = request.imageFormat->put_Height(imageSize.height()); + hr = request.imageFormat->put_Height(UINT32(imageSize.height())); Q_ASSERT_SUCCEEDED(hr); hr = capture->CapturePhotoToStreamAsync(request.imageFormat.Get(), request.stream.Get(), &request.op); @@ -301,7 +302,8 @@ HRESULT QWinRTCameraImageCaptureControl::onCaptureCompleted(IAsyncAction *asyncI UINT32 pixelWidth; hr = frame->get_PixelWidth(&pixelWidth); Q_ASSERT_SUCCEEDED(hr); - const QImage image(pixelData, pixelWidth, pixelHeight, QImage::Format_RGBA8888, + const QImage image(pixelData, int(pixelWidth), int(pixelHeight), + QImage::Format_RGBA8888, reinterpret_cast<QImageCleanupFunction>(&freeImageData), pixelData); emit imageCaptured(request.id, image); diff --git a/src/plugins/winrt/qwinrtcamerainfocontrol.h b/src/plugins/winrt/qwinrtcamerainfocontrol.h index 031ed2720..0f49ba244 100644 --- a/src/plugins/winrt/qwinrtcamerainfocontrol.h +++ b/src/plugins/winrt/qwinrtcamerainfocontrol.h @@ -48,7 +48,7 @@ class QWinRTCameraInfoControl : public QCameraInfoControl { Q_OBJECT public: - explicit QWinRTCameraInfoControl(QObject *parent = 0); + explicit QWinRTCameraInfoControl(QObject *parent = nullptr); QCamera::Position cameraPosition(const QString &deviceName) const override; int cameraOrientation(const QString &deviceName) const override; diff --git a/src/plugins/winrt/qwinrtcameraservice.h b/src/plugins/winrt/qwinrtcameraservice.h index 6fa4d5fce..b2d213b87 100644 --- a/src/plugins/winrt/qwinrtcameraservice.h +++ b/src/plugins/winrt/qwinrtcameraservice.h @@ -49,7 +49,7 @@ class QWinRTCameraService : public QMediaService { Q_OBJECT public: - explicit QWinRTCameraService(QObject *parent = 0); + explicit QWinRTCameraService(QObject *parent = nullptr); QMediaControl *requestControl(const char *name) override; void releaseControl(QMediaControl *control) override; diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp index 6c5e3dbf9..8b757b467 100644 --- a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp +++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp @@ -46,14 +46,14 @@ #include <QVideoFrame> #include <d3d11.h> -#include <D3D11_1.h> +#include <d3d11_1.h> #include <mfapi.h> #include <wrl.h> #include "qwinrtcameracontrol.h" #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -#include <Windows.Security.ExchangeActiveSyncProvisioning.h> +#include <windows.security.exchangeactivesyncprovisioning.h> using namespace ABI::Windows::Security::ExchangeActiveSyncProvisioning; #endif @@ -77,15 +77,15 @@ class QWinRTCameraVideoBuffer : public QAbstractVideoBuffer public: QWinRTCameraVideoBuffer(IMF2DBuffer *buffer, int size, QWinRTCameraControl *control) : QAbstractVideoBuffer(NoHandle) - , currentMode(NotMapped) , buffer(buffer) + , currentMode(NotMapped) , size(size) , control(control) { Q_ASSERT(control); } - ~QWinRTCameraVideoBuffer() + ~QWinRTCameraVideoBuffer() override { unmap(); } @@ -97,13 +97,13 @@ public: uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override { - if (currentMode != NotMapped || mode == NotMapped || control && control->state() != QCamera::ActiveState) + if (currentMode != NotMapped || mode == NotMapped || (control && control->state() != QCamera::ActiveState)) return nullptr; BYTE *bytes; LONG stride; HRESULT hr = buffer->Lock2D(&bytes, &stride); - RETURN_IF_FAILED("Failed to lock camera frame buffer", nullptr); + RETURN_IF_FAILED("Failed to lock camera frame buffer", return nullptr); control->frameMapped(); if (bytesPerLine) @@ -164,8 +164,8 @@ public: if (!m_videoEnumerator) { D3D11_VIDEO_PROCESSOR_CONTENT_DESC videoProcessorDesc = { D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE, - { 0 }, desc.Width, desc.Height, - { 0 }, desc.Width, desc.Height, + { 0, 0}, desc.Width, desc.Height, + { 0, 0}, desc.Width, desc.Height, D3D11_VIDEO_USAGE_OPTIMAL_SPEED }; hr = m_videoDevice->CreateVideoProcessorEnumerator(&videoProcessorDesc, &m_videoEnumerator); @@ -178,7 +178,7 @@ public: } if (!m_outputView) { - D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D }; + D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D, {{ 0 }} }; hr = m_videoDevice->CreateVideoProcessorOutputView( m_target, m_videoEnumerator.Get(), &outputDesc, &m_outputView); RETURN_VOID_IF_FAILED("Failed to create video output view"); @@ -187,8 +187,8 @@ public: ComPtr<IDXGIResource1> sourceResource; hr = texture->QueryInterface(IID_PPV_ARGS(&sourceResource)); RETURN_VOID_IF_FAILED("Failed to query interface IDXGIResource1"); - HANDLE sharedHandle = NULL; - hr = sourceResource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle); + HANDLE sharedHandle = nullptr; + hr = sourceResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &sharedHandle); RETURN_VOID_IF_FAILED("Failed to create shared handle"); ComPtr<ID3D11Device1> dev; hr = m_d3dDevice.As(&dev); @@ -212,7 +212,9 @@ public: hr = context.As(&videoContext); RETURN_VOID_IF_FAILED("Failed to get video context"); - D3D11_VIDEO_PROCESSOR_STREAM stream = { TRUE }; + D3D11_VIDEO_PROCESSOR_STREAM stream = { TRUE, 0, 0, 0, 0, nullptr, + nullptr, nullptr, nullptr, + nullptr, nullptr}; stream.pInputSurface = inputView.Get(); hr = videoContext->VideoProcessorBlt( m_videoProcessor.Get(), m_outputView.Get(), 0, 1, &stream); @@ -282,7 +284,7 @@ bool QWinRTCameraVideoRendererControlPrivate::getCameraSampleInfo(const ComPtr<I DWORD pcbLength; hr = buffer->GetContiguousLength(&pcbLength); Q_ASSERT_SUCCEEDED(hr); - cameraSampleSize = pcbLength; + cameraSampleSize = int(pcbLength); return true; } diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.h b/src/plugins/winrt/qwinrtcameravideorenderercontrol.h index 2f98e70f4..e50bcd2e6 100644 --- a/src/plugins/winrt/qwinrtcameravideorenderercontrol.h +++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.h @@ -56,7 +56,7 @@ class QWinRTCameraVideoRendererControl : public QWinRTAbstractVideoRendererContr Q_OBJECT public: explicit QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent); - ~QWinRTCameraVideoRendererControl(); + ~QWinRTCameraVideoRendererControl() override; bool render(ID3D11Texture2D *texture) override; bool dequeueFrame(QVideoFrame *frame) override; diff --git a/src/plugins/winrt/qwinrtimageencodercontrol.h b/src/plugins/winrt/qwinrtimageencodercontrol.h index dbeac2384..711e550c7 100644 --- a/src/plugins/winrt/qwinrtimageencodercontrol.h +++ b/src/plugins/winrt/qwinrtimageencodercontrol.h @@ -49,11 +49,11 @@ class QWinRTImageEncoderControl : public QImageEncoderControl { Q_OBJECT public: - explicit QWinRTImageEncoderControl(QObject *parent = 0); + explicit QWinRTImageEncoderControl(QObject *parent = nullptr); QStringList supportedImageCodecs() const override; QString imageCodecDescription(const QString &codecName) const override; - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const override; + QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = nullptr) const override; QImageEncoderSettings imageSettings() const override; void setImageSettings(const QImageEncoderSettings &settings) override; diff --git a/src/plugins/winrt/qwinrtmediaplayercontrol.cpp b/src/plugins/winrt/qwinrtmediaplayercontrol.cpp index fae8e6bf0..7991f435b 100644 --- a/src/plugins/winrt/qwinrtmediaplayercontrol.cpp +++ b/src/plugins/winrt/qwinrtmediaplayercontrol.cpp @@ -50,7 +50,7 @@ #include <QtConcurrent/QtConcurrentRun> #include <dxgi.h> -#include <oleauto.h> +#include <OleAuto.h> #include <mfapi.h> #include <mfmediaengine.h> @@ -138,7 +138,7 @@ public: hr = d->engine->GetNativeVideoSize(&width, &height); if (FAILED(hr)) break; - d->videoRenderer->setSize(QSize(width, height)); + d->videoRenderer->setSize(QSize(int(width), int(height))); } newStatus = QMediaPlayer::LoadedMedia; @@ -177,7 +177,7 @@ public: // If the media is already loaded, the playing event may not occur after stop if (d->mediaStatus != QMediaPlayer::LoadedMedia) break; - // fall through + Q_FALLTHROUGH(); } case MF_MEDIA_ENGINE_EVENT_PLAYING: { newState = QMediaPlayer::PlayingState; @@ -206,7 +206,7 @@ public: case MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE: { double duration = d->engine->GetDuration() * 1000; if (!qFuzzyCompare(d->duration, duration)) { - d->duration = duration; + d->duration = qint64(duration); emit q->durationChanged(d->duration); } break; @@ -214,7 +214,7 @@ public: case MF_MEDIA_ENGINE_EVENT_TIMEUPDATE: { double position = d->engine->GetCurrentTime() * 1000; if (!qFuzzyCompare(d->position, position)) { - d->position = position; + d->position = qint64(position); emit q->positionChanged(d->position); } // Stopped state: paused at beginning @@ -238,7 +238,7 @@ public: default: case MF_MEDIA_ENGINE_ERR_NOERROR: newStatus = QMediaPlayer::UnknownMediaStatus; - emit q->error(QMediaPlayer::ResourceError, qt_error_string(param2)); + emit q->error(QMediaPlayer::ResourceError, qt_error_string(int(param2))); break; case MF_MEDIA_ENGINE_ERR_ABORTED: if (d->mediaStatus == QMediaPlayer::StalledMedia || d->mediaStatus == QMediaPlayer::BufferingMedia) @@ -299,19 +299,19 @@ public: DWORD __stdcall GetLength() { - return d->media.resources().length(); + return DWORD(d->media.resources().length()); } HRESULT __stdcall GetURL(DWORD index, BSTR *url) { - const QString resourceUrl = d->media.resources().value(index).url().toString(); + const QString resourceUrl = d->media.resources().value(int(index)).url().toString(); *url = SysAllocString((const OLECHAR *)resourceUrl.utf16()); return S_OK; } HRESULT __stdcall GetType(DWORD index, BSTR *type) { - const QString resourceType = d->media.resources().value(index).mimeType(); + const QString resourceType = d->media.resources().value(int(index)).mimeType(); *type = SysAllocString((const OLECHAR *)resourceType.utf16()); return S_OK; } @@ -319,7 +319,7 @@ public: HRESULT __stdcall GetMedia(DWORD index, BSTR *media) { Q_UNUSED(index); - *media = NULL; + *media = nullptr; return S_OK; } @@ -348,7 +348,7 @@ public: void read(QIODevice *device) { - bytesRead = device->read(reinterpret_cast<char *>(bytes), maxLength); + bytesRead = ULONG(device->read(reinterpret_cast<char *>(bytes), maxLength)); } BYTE *bytes; @@ -359,8 +359,8 @@ public: class MediaEngineByteStream : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFByteStream> { public: - MediaEngineByteStream(QWinRTMediaPlayerControl *q_ptr, QWinRTMediaPlayerControlPrivate *d_ptr) - : q(q_ptr), d(d_ptr) + MediaEngineByteStream(QWinRTMediaPlayerControlPrivate *d_ptr) + : d(d_ptr) { } @@ -392,7 +392,7 @@ public: HRESULT __stdcall SetCurrentPosition(QWORD position) { - qint64 pos(position); + const qint64 pos = qint64(position); if (pos >= d->stream->size()) { // MSDN states we should return E_INVALIDARG, but that immediately // stops playback and does not play remaining buffers in the queue. @@ -413,7 +413,7 @@ public: HRESULT __stdcall Read(BYTE *bytes, ULONG maxlen, ULONG *bytesRead) { - *bytesRead = d->stream->read(reinterpret_cast<char *>(bytes), maxlen); + *bytesRead = ULONG(d->stream->read(reinterpret_cast<char *>(bytes), maxlen)); return S_OK; } @@ -508,7 +508,6 @@ public: } private: - QWinRTMediaPlayerControl *q; QWinRTMediaPlayerControlPrivate *d; ComPtr<IMFAsyncResult> asyncResult; @@ -570,11 +569,7 @@ QWinRTMediaPlayerControl::QWinRTMediaPlayerControl(IMFMediaEngineClassFactory *f hr = d->engine->SetSourceElements(d->sources.Get()); Q_ASSERT_SUCCEEDED(hr); - d->streamProvider = Make<MediaEngineByteStream>(this, d); -} - -QWinRTMediaPlayerControl::~QWinRTMediaPlayerControl() -{ + d->streamProvider = Make<MediaEngineByteStream>(d); } QMediaPlayer::State QWinRTMediaPlayerControl::state() const diff --git a/src/plugins/winrt/qwinrtmediaplayercontrol.h b/src/plugins/winrt/qwinrtmediaplayercontrol.h index 174ba664b..0075cc954 100644 --- a/src/plugins/winrt/qwinrtmediaplayercontrol.h +++ b/src/plugins/winrt/qwinrtmediaplayercontrol.h @@ -53,8 +53,8 @@ class QWinRTMediaPlayerControl : public QMediaPlayerControl { Q_OBJECT public: - QWinRTMediaPlayerControl(IMFMediaEngineClassFactory *factory, QObject *parent = 0); - ~QWinRTMediaPlayerControl(); + QWinRTMediaPlayerControl(IMFMediaEngineClassFactory *factory, QObject *parent = nullptr); + ~QWinRTMediaPlayerControl() override = default; QMediaPlayer::State state() const override; QMediaPlayer::MediaStatus mediaStatus() const override; diff --git a/src/plugins/winrt/qwinrtmediaplayerservice.cpp b/src/plugins/winrt/qwinrtmediaplayerservice.cpp index 3253ed188..208e7625b 100644 --- a/src/plugins/winrt/qwinrtmediaplayerservice.cpp +++ b/src/plugins/winrt/qwinrtmediaplayerservice.cpp @@ -70,9 +70,9 @@ QWinRTMediaPlayerService::QWinRTMediaPlayerService(QObject *parent) HRESULT hr = MFStartup(MF_VERSION); Q_ASSERT(SUCCEEDED(hr)); - MULTI_QI results = { &IID_IUnknown, NULL, 0 }; - hr = CoCreateInstanceFromApp(CLSID_MFMediaEngineClassFactory, NULL, - CLSCTX_INPROC_SERVER, NULL, 1, &results); + MULTI_QI results = { &IID_IUnknown, nullptr, 0 }; + hr = CoCreateInstanceFromApp(CLSID_MFMediaEngineClassFactory, nullptr, + CLSCTX_INPROC_SERVER, nullptr, 1, &results); Q_ASSERT(SUCCEEDED(hr)); hr = results.pItf->QueryInterface(d->factory.GetAddressOf()); diff --git a/src/plugins/winrt/qwinrtplayerrenderercontrol.cpp b/src/plugins/winrt/qwinrtplayerrenderercontrol.cpp index ef8c4f21e..5952aa638 100644 --- a/src/plugins/winrt/qwinrtplayerrenderercontrol.cpp +++ b/src/plugins/winrt/qwinrtplayerrenderercontrol.cpp @@ -100,7 +100,7 @@ QWinRTPlayerRendererControl::QWinRTPlayerRendererControl(IMFMediaEngineEx *engin d->engine = engine; d->manager = manager; d->resetToken = resetToken; - d->deviceHandle = 0; + d->deviceHandle = nullptr; } QWinRTPlayerRendererControl::~QWinRTPlayerRendererControl() diff --git a/src/plugins/winrt/qwinrtplayerrenderercontrol.h b/src/plugins/winrt/qwinrtplayerrenderercontrol.h index 70f3c4af2..7653db46f 100644 --- a/src/plugins/winrt/qwinrtplayerrenderercontrol.h +++ b/src/plugins/winrt/qwinrtplayerrenderercontrol.h @@ -54,7 +54,7 @@ class QWinRTPlayerRendererControl : public QWinRTAbstractVideoRendererControl Q_OBJECT public: explicit QWinRTPlayerRendererControl(IMFMediaEngineEx *engine, IMFDXGIDeviceManager *manager, quint32 resetToken, QObject *parent); - ~QWinRTPlayerRendererControl(); + ~QWinRTPlayerRendererControl() override; bool ensureReady(); diff --git a/src/plugins/winrt/qwinrtserviceplugin.h b/src/plugins/winrt/qwinrtserviceplugin.h index 30a76022d..b0a4e5973 100644 --- a/src/plugins/winrt/qwinrtserviceplugin.h +++ b/src/plugins/winrt/qwinrtserviceplugin.h @@ -57,10 +57,10 @@ class QWinRTServicePlugin : public QMediaServiceProviderPlugin Q_INTERFACES(QMediaServiceDefaultDeviceInterface) Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "winrt.json") public: - QMediaService *create(QString const &key); - void release(QMediaService *service); + QMediaService *create(QString const &key) override; + void release(QMediaService *service) override; - QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const; + QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const override; QCamera::Position cameraPosition(const QByteArray &device) const override; int cameraOrientation(const QByteArray &device) const override; diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp index 1095cd92f..59aa91b03 100644 --- a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp +++ b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp @@ -68,7 +68,7 @@ static QString deviceName(IDeviceInformation *device) Q_ASSERT_SUCCEEDED(hr); quint32 length; const wchar_t *buffer = id.GetRawBuffer(&length); - return QString::fromWCharArray(buffer, length); + return QString::fromWCharArray(buffer, int(length)); } static QString deviceDescription(IDeviceInformation *device) @@ -79,7 +79,7 @@ static QString deviceDescription(IDeviceInformation *device) Q_ASSERT_SUCCEEDED(hr); quint32 length; const wchar_t *buffer = name.GetRawBuffer(&length); - return QString::fromWCharArray(buffer, length); + return QString::fromWCharArray(buffer, int(length)); } struct QWinRTVideoDeviceSelectorControlGlobal @@ -179,7 +179,7 @@ private: Q_ASSERT_SUCCEEDED(hr); quint32 nameLength; const wchar_t *nameString = name.GetRawBuffer(&nameLength); - const int index = deviceIndex.take(QString::fromWCharArray(nameString, nameLength)); + const int index = deviceIndex.take(QString::fromWCharArray(nameString, int(nameLength))); if (index >= 0) devices.remove(index); @@ -356,7 +356,7 @@ int QWinRTVideoDeviceSelectorControl::cameraOrientation(const QString &deviceNam quint32 rotation; hr = enclosure2->get_RotationAngleInDegreesClockwise(&rotation); RETURN_IF_FAILED("Failed to get camera rotation angle", return 0); - return rotation; + return int(rotation); } QList<QByteArray> QWinRTVideoDeviceSelectorControl::deviceNames() diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h index 3beb9782a..a9ddaf9fd 100644 --- a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h +++ b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h @@ -62,8 +62,8 @@ class QWinRTVideoDeviceSelectorControl : public QVideoDeviceSelectorControl { Q_OBJECT public: - explicit QWinRTVideoDeviceSelectorControl(QObject *parent = 0); - ~QWinRTVideoDeviceSelectorControl(); + explicit QWinRTVideoDeviceSelectorControl(QObject *parent = nullptr); + ~QWinRTVideoDeviceSelectorControl() override; int deviceCount() const override; diff --git a/src/plugins/winrt/qwinrtvideoprobecontrol.h b/src/plugins/winrt/qwinrtvideoprobecontrol.h index 972720c96..2a79cb91d 100644 --- a/src/plugins/winrt/qwinrtvideoprobecontrol.h +++ b/src/plugins/winrt/qwinrtvideoprobecontrol.h @@ -49,7 +49,7 @@ class QWinRTVideoProbeControl : public QMediaVideoProbeControl Q_OBJECT public: explicit QWinRTVideoProbeControl(QWinRTCameraVideoRendererControl *parent); - ~QWinRTVideoProbeControl(); + ~QWinRTVideoProbeControl() override; }; QT_END_NAMESPACE |