File indexing completed on 2024-05-19 04:29:17
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 KISPLAYBACKENGINE_H 0009 #define KISPLAYBACKENGINE_H 0010 0011 #include "KoCanvasObserverBase.h" 0012 #include <QObject> 0013 0014 #include <kritaui_export.h> 0015 0016 /** 0017 * @brief The SeekOption enum represents additional behaviors associated with seeking to a new frame. 0018 * For example, sometimes you want to push audio when seeking, and other times you might want to reload the image without using the cache. 0019 * Other optional, uncommon or specialized seeking behaviors might make sense to add here. 0020 */ 0021 enum SeekOption { 0022 SEEK_NONE = 0, 0023 SEEK_PUSH_AUDIO = 1, // Whether we should be pushing audio or not. Used to prevent double-takes on scrubbing. 0024 SEEK_FINALIZE = 1 << 1 // Force reload of KisImage to specific frame, ignore caching ability. 0025 }; 0026 0027 Q_DECLARE_FLAGS(SeekOptionFlags, SeekOption) 0028 Q_DECLARE_OPERATORS_FOR_FLAGS(SeekOptionFlags) 0029 0030 0031 /** @brief Krita's base animation playback engine for producing image frame changes and associated audio. 0032 * 0033 * Krita stores a main playback engine in KisPart (a singleton) to be used by the active document's canvas. 0034 * It can be thought of as being just below the GUI layer of Krita's animation system, 0035 * responding to various GUI events, controlling transport controls (play, stop, next, etc.), 0036 * and generally driving the playback of animation within Krita. 0037 * 0038 * It's implemented by KisPlaybackEngineQT and KisPlaybackEngineMLT, one of which is typically selected 0039 * at compile time depending on available dependencies. Specific implementations may or may not support 0040 * certain features (audio, speed, dropping frames, etc.) and have other different characteristics. 0041 */ 0042 class KRITAUI_EXPORT KisPlaybackEngine : public QObject, public KoCanvasObserverBase 0043 { 0044 Q_OBJECT 0045 public: 0046 KisPlaybackEngine(QObject* parent = nullptr); 0047 ~KisPlaybackEngine(); 0048 0049 struct PlaybackStats { 0050 qreal expectedFps {0.0}; 0051 qreal realFps {0.0}; 0052 qreal droppedFramesPortion {0.0}; 0053 }; 0054 0055 public Q_SLOTS: 0056 // Basic transport controls... 0057 virtual void play(); 0058 virtual void pause(); 0059 virtual void playPause(); 0060 virtual void stop(); 0061 0062 virtual void seek( int frameIndex, SeekOptionFlags options = SEEK_FINALIZE | SEEK_PUSH_AUDIO ) = 0; 0063 virtual void previousFrame(); 0064 virtual void nextFrame(); 0065 virtual void previousKeyframe(); 0066 virtual void nextKeyframe(); 0067 virtual void firstFrame(); 0068 virtual void lastFrame(); 0069 0070 /** 0071 * @brief previousMatchingKeyframe && nextMatchingKeyframe 0072 * Navigate to the next keyframe that has the same color-label 0073 * as the current keyframe. Useful to quickly navigate to user-specified 0074 * 'similar' keyframes. E.g. Contact points in an animation might have 0075 * a specific color to specify importance and be quickly swapped between. 0076 */ 0077 virtual void previousMatchingKeyframe(); 0078 virtual void nextMatchingKeyframe(); 0079 0080 /** 0081 * @brief previousUnfilteredKeyframe && nextUnfilteredKeyframe 0082 * Navigate to keyframes based on the current onion skin filtration. 0083 * This lets users easily navigate to the next visible "onion-skinned" 0084 * keyframe on the active layer. 0085 */ 0086 virtual void previousUnfilteredKeyframe(); 0087 virtual void nextUnfilteredKeyframe(); 0088 0089 // Audio controls... 0090 virtual void setMute(bool val) = 0; 0091 virtual bool isMute() = 0; 0092 0093 virtual void setDropFramesMode(bool value); 0094 bool dropFrames() const; 0095 0096 virtual bool supportsAudio() = 0; 0097 virtual bool supportsVariablePlaybackSpeed() = 0; 0098 0099 virtual PlaybackStats playbackStatistics() const = 0; 0100 0101 Q_SIGNALS: 0102 void sigDropFramesModeChanged(bool value); 0103 0104 protected: 0105 class KisCanvas2* activeCanvas() const; 0106 int frameWrap(int frame, int startFrame, int endFrame); 0107 0108 protected Q_SLOTS: 0109 virtual void setCanvas(KoCanvasBase* p_canvas) override; 0110 virtual void unsetCanvas() override; 0111 0112 private: 0113 /** 0114 * @brief Move the active frame of the animation player forwards or backwards by some number of frames. 0115 * @param The signed number of frames to move. Negative frames move backwards in time (left on a left-to-right system). 0116 */ 0117 void moveActiveFrameBy(int frames); 0118 0119 // Used by previous/next unfiltered keyframe functions... 0120 void nextKeyframeWithColor(int color); 0121 void nextKeyframeWithColor(const QSet<int> &validColors); 0122 void previousKeyframeWithColor(int color); 0123 void previousKeyframeWithColor(const QSet<int> &validColors); 0124 0125 private: 0126 struct Private; 0127 QScopedPointer<Private> m_d; 0128 }; 0129 0130 #endif // KISPLAYBACKENGINE_H