File indexing completed on 2024-05-19 04:29:18
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2022 Emmet O'Neill <emmetoneill.pdx@gmail.com> 0003 SPDX-FileCopyrightText: 2022 Eoin O'Neill <eoinoneill1991@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KISPLAYBACKENGINEMLT_H 0009 #define KISPLAYBACKENGINEMLT_H 0010 0011 #include <QObject> 0012 #include "KoCanvasObserverBase.h" 0013 #include "KisPlaybackEngine.h" 0014 #include <kritaui_export.h> 0015 0016 #include <QScopedPointer> 0017 #include <QFileInfo> 0018 #include <boost/optional.hpp> 0019 0020 0021 enum PlaybackMode { 0022 PLAYBACK_PUSH, // MLT is being pushed to, used during pause and stop state for scrubbing. 0023 PLAYBACK_PULL // MLT is updating itself, we are getting regular updates from it about when we need to show our next frame. 0024 }; 0025 0026 /** 0027 * @brief The KisPlaybackEngineMLT class is an implementation of KisPlaybackEngine 0028 * that uses MLT (Media Lovin' Toolkit) to drive image frame changes and animation audio 0029 * with (hopefully) close to frame-perfect synchronization. 0030 * 0031 * If MLT is unavailable or unwanted, Krita can instead use KisPlaybackEngineQT 0032 * which may be simpler but has different characteristics and is not designed with 0033 * audio-video synchronization in mind. 0034 */ 0035 class KRITAUI_EXPORT KisPlaybackEngineMLT : public KisPlaybackEngine 0036 { 0037 Q_OBJECT 0038 public: 0039 explicit KisPlaybackEngineMLT(QObject *parent = nullptr); 0040 ~KisPlaybackEngineMLT(); 0041 0042 Q_SIGNALS: 0043 void sigChangeActiveCanvasFrame(int p_frame); 0044 0045 public Q_SLOTS: 0046 void seek(int frameIndex, SeekOptionFlags flags = SEEK_FINALIZE | SEEK_PUSH_AUDIO) override; 0047 0048 void setMute(bool val) override; 0049 bool isMute() override; 0050 0051 bool supportsAudio() override { return true; } 0052 bool supportsVariablePlaybackSpeed() override { return true; } 0053 0054 void setDropFramesMode(bool value) override; 0055 0056 PlaybackStats playbackStatistics() const override; 0057 0058 protected Q_SLOTS: 0059 void setCanvas(KoCanvasBase* canvas) override; 0060 void unsetCanvas() override; 0061 void canvasDestroyed(QObject *canvas); 0062 0063 /** 0064 * @brief throttledShowFrame 0065 * @param frame 0066 * 0067 * In order to throttle calls from MLT to respect our 0068 * playback mode, we need to redirect `showFrame` calls 0069 * to this thread and enforce that we only allow MLT to 0070 * show frames when we are in PULL mode. 0071 */ 0072 void throttledShowFrame(const int frame); 0073 0074 /** 0075 * @brief throttledSetSpeed 0076 * @param speed 0077 * 0078 * Because MLT needs to be stopped and restarted to change playback speed 0079 * we use this function to limit the frequency of speed change requests. 0080 */ 0081 void throttledSetSpeed(const double speed); 0082 0083 0084 /** 0085 * @brief setAudioVolume 0086 * @param volume (normalized) 0087 */ 0088 void setAudioVolume(qreal volumeNormalized); 0089 0090 public: 0091 struct FrameWaitingInterface; 0092 FrameWaitingInterface* frameWaitingInterface(); 0093 0094 private: 0095 /** 0096 * @brief Sets up an MLT::Producer object in response to audio being 0097 * added to a Krita document or when canvas changes. 0098 * @param file: An optional file to be loaded by MLT. 0099 */ 0100 void setupProducer(boost::optional<QFileInfo> file); 0101 0102 struct Private; 0103 struct StopAndResume; 0104 QScopedPointer<Private> m_d; 0105 }; 0106 0107 #endif // KISPLAYBACKENGINEMLT_H