1 /*** 2 3 Olive - Non-Linear Video Editor 4 Copyright (C) 2019 Olive Team 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19 ***/ 20 21 #ifndef EFFECT_H 22 #define EFFECT_H 23 24 #include <memory> 25 #include <QObject> 26 #include <QString> 27 #include <QVector> 28 #include <QColor> 29 #include <QOpenGLFunctions> 30 #include <QOpenGLShaderProgram> 31 #include <QOpenGLTexture> 32 #include <QMutex> 33 #include <QThread> 34 #include <QLabel> 35 #include <QWidget> 36 #include <QGridLayout> 37 #include <QPushButton> 38 #include <QMouseEvent> 39 #include <QXmlStreamReader> 40 #include <QXmlStreamWriter> 41 #include <random> 42 43 #include "ui/collapsiblewidget.h" 44 #include "effectrow.h" 45 #include "effectgizmo.h" 46 47 class Clip; 48 49 class Effect; 50 using EffectPtr = std::shared_ptr<Effect>; 51 52 struct EffectMeta { 53 QString name; 54 QString category; 55 QString filename; 56 QString path; 57 QString tooltip; 58 int internal; 59 int type; 60 int subtype; 61 }; 62 extern QVector<EffectMeta> effects; 63 64 double log_volume(double linear); 65 66 enum EffectType { 67 EFFECT_TYPE_INVALID, 68 EFFECT_TYPE_VIDEO, 69 EFFECT_TYPE_AUDIO, 70 EFFECT_TYPE_EFFECT, 71 EFFECT_TYPE_TRANSITION 72 }; 73 74 enum EffectKeyframeType { 75 EFFECT_KEYFRAME_LINEAR, 76 EFFECT_KEYFRAME_BEZIER, 77 EFFECT_KEYFRAME_HOLD 78 }; 79 80 enum EffectInternal { 81 EFFECT_INTERNAL_TRANSFORM, 82 EFFECT_INTERNAL_TEXT, 83 EFFECT_INTERNAL_SOLID, 84 EFFECT_INTERNAL_NOISE, 85 EFFECT_INTERNAL_VOLUME, 86 EFFECT_INTERNAL_PAN, 87 EFFECT_INTERNAL_TONE, 88 EFFECT_INTERNAL_SHAKE, 89 EFFECT_INTERNAL_TIMECODE, 90 EFFECT_INTERNAL_MASK, 91 EFFECT_INTERNAL_FILLLEFTRIGHT, 92 EFFECT_INTERNAL_VST, 93 EFFECT_INTERNAL_CORNERPIN, 94 EFFECT_INTERNAL_FREI0R, 95 EFFECT_INTERNAL_RICHTEXT, 96 EFFECT_INTERNAL_COUNT 97 }; 98 99 struct GLTextureCoords { 100 int grid_size; 101 102 int vertexTopLeftX; 103 int vertexTopLeftY; 104 int vertexTopLeftZ; 105 int vertexTopRightX; 106 int vertexTopRightY; 107 int vertexTopRightZ; 108 int vertexBottomLeftX; 109 int vertexBottomLeftY; 110 int vertexBottomLeftZ; 111 int vertexBottomRightX; 112 int vertexBottomRightY; 113 int vertexBottomRightZ; 114 115 float textureTopLeftX; 116 float textureTopLeftY; 117 float textureTopLeftQ; 118 float textureTopRightX; 119 float textureTopRightY; 120 float textureTopRightQ; 121 float textureBottomRightX; 122 float textureBottomRightY; 123 float textureBottomRightQ; 124 float textureBottomLeftX; 125 float textureBottomLeftY; 126 float textureBottomLeftQ; 127 128 int blendmode; 129 float opacity; 130 }; 131 132 const EffectMeta* get_meta_from_name(const QString& input); 133 134 qint16 mix_audio_sample(qint16 a, qint16 b); 135 136 class Effect : public QObject { 137 Q_OBJECT 138 public: 139 Effect(Clip *c, const EffectMeta* em); 140 ~Effect(); 141 142 Clip* parent_clip; 143 const EffectMeta* meta; 144 int id; 145 QString name; 146 147 void AddRow(EffectRow* row); 148 149 EffectRow* row(int i); 150 int row_count(); 151 152 EffectGizmo* add_gizmo(int type); 153 EffectGizmo* gizmo(int i); 154 int gizmo_count(); 155 156 bool IsEnabled(); 157 bool IsExpanded(); 158 159 virtual void refresh(); 160 161 virtual EffectPtr copy(Clip* c); 162 void copy_field_keyframes(EffectPtr e); 163 164 virtual void load(QXmlStreamReader& stream); 165 virtual void custom_load(QXmlStreamReader& stream); 166 virtual void save(QXmlStreamWriter& stream); 167 168 void load_from_string(const QByteArray &s); 169 QByteArray save_to_string(); 170 171 // glsl handling 172 bool is_open(); 173 void open(); 174 void close(); 175 bool is_glsl_linked(); 176 virtual void startEffect(); 177 virtual void endEffect(); 178 179 enum VideoEffectFlags { 180 ShaderFlag = 0x1, 181 CoordsFlag = 0x2, 182 SuperimposeFlag = 0x4, 183 ImageFlag = 0x8 184 }; 185 int Flags(); 186 void SetFlags(int flags); 187 188 int getIterations(); 189 void setIterations(int i); 190 191 const char* ffmpeg_filter; 192 193 virtual void process_image(double timecode, uint8_t* input, uint8_t* output, int size); 194 virtual void process_shader(double timecode, GLTextureCoords&, int iteration); 195 virtual void process_coords(double timecode, GLTextureCoords& coords, int data); 196 virtual GLuint process_superimpose(double timecode); 197 virtual void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); 198 199 virtual void gizmo_draw(double timecode, GLTextureCoords& coords); 200 void gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode, bool done); 201 void gizmo_world_to_screen(); 202 bool are_gizmos_enabled(); 203 204 template <typename T> randomNumber()205 T randomNumber() 206 { 207 static std::random_device device; 208 static std::mt19937 generator(device()); 209 static std::uniform_int_distribution<> distribution(std::numeric_limits<T>::min(), std::numeric_limits<T>::max()); 210 return distribution(generator); 211 } 212 213 static EffectPtr Create(Clip *c, const EffectMeta *em); 214 static const EffectMeta* GetInternalMeta(int internal_id, int type); 215 public slots: 216 void FieldChanged(); 217 void SetEnabled(bool b); 218 void SetExpanded(bool e); 219 signals: 220 void EnabledChanged(bool); 221 private slots: 222 void delete_self(); 223 void move_up(); 224 void move_down(); 225 void save_to_file(); 226 void load_from_file(); 227 protected: 228 // glsl effect 229 QOpenGLShaderProgram* glslProgram; 230 QString vertPath; 231 QString fragPath; 232 233 // superimpose effect 234 QImage img; 235 QOpenGLTexture* texture; 236 237 // enable effect to update constantly 238 virtual bool AlwaysUpdate(); 239 240 private: 241 bool isOpen; 242 QVector<EffectRow*> rows; 243 QVector<EffectGizmo*> gizmos; 244 bool bound; 245 int iterations; 246 247 bool enabled_; 248 bool expanded_; 249 250 int flags_; 251 252 QVector<KeyframeDataChange*> gizmo_dragging_actions_; 253 254 // superimpose functions 255 virtual void redraw(double timecode); 256 bool valueHasChanged(double timecode); 257 QVector<QVariant> cachedValues; 258 void delete_texture(); 259 void validate_meta_path(); 260 }; 261 262 #endif // EFFECT_H 263