/**************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** 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. ** ** $QT_END_LICENSE$ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ****************************************************************************/ #ifndef VIDEOSURFACEFILTER_H #define VIDEOSURFACEFILTER_H #include "directshowbasefilter.h" #include #include #include #include #include QT_BEGIN_NAMESPACE class QAbstractVideoSurface; class DirectShowEventLoop; class VideoSurfaceInputPin; class VideoSurfaceFilter : public QObject , public DirectShowBaseFilter , public IAMFilterMiscFlags { Q_OBJECT COM_REF_MIXIN public: VideoSurfaceFilter(QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent = nullptr); ~VideoSurfaceFilter(); STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override; // DirectShowBaseFilter QList pins() override; // IPersist STDMETHODIMP GetClassID(CLSID *pClassID) override; // IMediaFilter STDMETHODIMP Run(REFERENCE_TIME tStart) override; STDMETHODIMP Pause() override; STDMETHODIMP Stop() override; // IAMFilterMiscFlags STDMETHODIMP_(ULONG) GetMiscFlags() override; // DirectShowPin (delegate) bool isMediaTypeSupported(const AM_MEDIA_TYPE *type); bool setMediaType(const AM_MEDIA_TYPE *type); HRESULT completeConnection(IPin *pin); HRESULT connectionEnded(); // IPin (delegate) HRESULT EndOfStream(); HRESULT BeginFlush(); HRESULT EndFlush(); // IMemInputPin (delegate) HRESULT Receive(IMediaSample *pMediaSample); private Q_SLOTS: void supportedFormatsChanged(); void checkEOS(); private: enum Events { StartSurface = QEvent::User, StopSurface = QEvent::User + 1, RestartSurface = QEvent::User + 2, FlushSurface = QEvent::User + 3, RenderSample = QEvent::User + 4 }; bool event(QEvent *) override; bool startSurface(); void stopSurface(); bool restartSurface(); void flushSurface(); bool scheduleSample(IMediaSample *sample); void unscheduleSample(); void renderPendingSample(); void clearPendingSample(); void notifyEOS(); void resetEOS(); void resetEOSTimer(); void onEOSTimerTimeout(); friend void QT_WIN_CALLBACK EOSTimerCallback(UINT, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR); QMutex m_mutex; DirectShowEventLoop *m_loop; VideoSurfaceInputPin *m_pin = nullptr; QWaitCondition m_waitSurface; QAbstractVideoSurface *m_surface; QVideoSurfaceFormat m_surfaceFormat; int m_bytesPerLine = 0; bool m_surfaceStarted = false; QList m_supportedTypes; QReadWriteLock m_typesLock; QRecursiveMutex m_renderMutex; bool m_running = false; IMediaSample *m_pendingSample = nullptr; REFERENCE_TIME m_pendingSampleEndTime = 0; HANDLE m_renderEvent; HANDLE m_flushEvent; DWORD_PTR m_adviseCookie = 0; bool m_EOS = false; bool m_EOSDelivered = false; UINT m_EOSTimer = 0; friend class VideoSurfaceInputPin; }; QT_END_NAMESPACE #endif