CuteLogger
Fast and simple logging solution for Qt based applications
mltcontroller.h
1 /*
2  * Copyright (c) 2011-2025 Meltytech, LLC
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MLTCONTROLLER_H
19 #define MLTCONTROLLER_H
20 
21 #include "transportcontrol.h"
22 
23 #include <Mlt.h>
24 #include <QImage>
25 #include <QMutex>
26 #include <QScopedPointer>
27 #include <QString>
28 #include <QTemporaryFile>
29 #include <QUuid>
30 
31 #define MLT_LC_CATEGORY LC_ALL
32 #define MLT_LC_NAME "LC_ALL"
33 
34 #if LIBMLT_VERSION_INT >= ((7 << 16) + (19 << 8))
35 #define kAudioIndexProperty "astream"
36 #define kVideoIndexProperty "vstream"
37 #else
38 #define kAudioIndexProperty "audio_index"
39 #define kVideoIndexProperty "video_index"
40 #endif
41 
42 namespace Mlt {
43 
44 const int kMaxImageDurationSecs = 3600 * 4;
45 extern const QString XmlMimeType;
46 
47 class TransportControl : public TransportControllable
48 {
49  Q_OBJECT
50 public slots:
51  void play(double speed = 1.0) override;
52  void pause(int position = -1) override;
53  void stop() override;
54  void seek(int position) override;
55  void rewind(bool forceChangeDirection) override;
56  void fastForward(bool forceChangeDirection) override;
57  void previous(int currentPosition) override;
58  void next(int currentPosition) override;
59  void setIn(int) override;
60  void setOut(int) override;
61 };
62 
63 class Controller
64 {
65 protected:
66  Controller();
67  virtual int reconfigure(bool isMulti) = 0;
68 
69 public:
70  enum {
71  FILTER_INDEX_ALL = -1,
72  FILTER_INDEX_ENABLED = -2,
73  };
74 
75  static Controller &singleton(QObject *parent = nullptr);
76  virtual ~Controller();
77  static void destroy();
78 
79  virtual QObject *videoWidget() = 0;
80  virtual int setProducer(Mlt::Producer *, bool isMulti = false);
81  virtual int open(const QString &url, const QString &urlToSave, bool skipConvert = false);
82  bool openXML(const QString &filename);
83  virtual void close();
84  virtual int displayWidth() const = 0;
85  virtual int displayHeight() const = 0;
86 
87  void closeConsumer();
88  virtual void play(double speed = 1.0);
89  bool isPaused() const;
90  virtual void pause(int position = -1);
91  void stop();
92  bool enableJack(bool enable = true);
93  void setVolume(double volume, bool muteOnPause = true);
94  double volume() const;
95  void onWindowResize();
96  virtual void seek(int position);
97  virtual void refreshConsumer(bool scrubAudio = false);
98  bool saveXML(const QString &filename,
99  Service *service = nullptr,
100  bool withRelativePaths = true,
101  QTemporaryFile *tempFile = nullptr,
102  bool proxy = false,
103  QString projectNote = QString());
104  QString XML(Service *service = nullptr, bool withProfile = false, bool withMetadata = true);
105  int consumerChanged();
106  void setProfile(const QString &profile_name);
107  void setAudioChannels(int audioChannels);
108  QString resource() const;
109  bool isSeekable(Mlt::Producer *p = nullptr) const;
110  int maxFrameCount() const;
111  bool isLiveProducer(Mlt::Producer *p = nullptr) const;
112  bool isClip() const;
113  bool isClosedClip(Producer *producer = nullptr) const;
114  bool isSeekableClip();
115  bool isPlaylist() const;
116  bool isMultitrack() const;
117  bool isImageProducer(Service *service) const;
118  bool isFileProducer(Service *service) const;
119  void rewind(bool forceChangeDirection);
120  void fastForward(bool forceChangeDirection);
121  void previous(int currentPosition);
122  void next(int currentPosition);
123  void setIn(int);
124  void setOut(int);
125  void fixLengthProperties(Service &service);
126  void restart(const QString &xml = "");
127  void resetURL();
128  QImage image(Frame *frame, int width, int height);
129  QImage image(Mlt::Producer &producer, int frameNumber, int width, int height);
130  void updateAvformatCaching(int trackCount);
131  bool isAudioFilter(const QString &name);
132  int realTime() const;
133  void setImageDurationFromDefault(Service *service) const;
134  void setDurationFromDefault(Producer *service) const;
135  void lockCreationTime(Producer *producer) const;
136  Producer *setupNewProducer(Producer *newProducer) const;
137  QUuid uuid(Mlt::Properties &properties) const;
138  void setUuid(Mlt::Properties &properties, QUuid uid) const;
139  QUuid ensureHasUuid(Mlt::Properties &properties) const;
140  static void copyFilters(Mlt::Producer &fromProducer,
141  Mlt::Producer &toProducer,
142  bool fromClipboard = false,
143  int filterIndex = FILTER_INDEX_ENABLED);
144  void copyFilters(Mlt::Producer *producer = nullptr, int filterIndex = FILTER_INDEX_ENABLED);
145  void pasteFilters(Mlt::Producer *producer = nullptr, Mlt::Producer *fromProducer = nullptr);
146  static void adjustFilters(Mlt::Producer &producer, int startIndex = 0);
147  static void adjustFilter(
148  Mlt::Filter *filter, int in, int out, int inDelta, int outDelta, int keyframeDelta);
149  static void adjustClipFilters(
150  Mlt::Producer &producer, int in, int out, int inDelta, int outDelta, int keyframeDelta);
151  bool hasFiltersOnClipboard() const
152  {
153  return m_filtersClipboard->is_valid() && m_filtersClipboard->filter_count() > 0;
154  }
155  QString filtersClipboardXML() { return XML(m_filtersClipboard.get()); }
156 
157  int audioChannels() const { return m_audioChannels; }
158  Mlt::Repository *repository() const { return m_repo; }
159  Mlt::Profile &profile() { return m_profile; }
160  Mlt::Profile &previewProfile() { return m_previewProfile; }
161  Mlt::Producer *producer() const { return m_producer.data(); }
162  Mlt::Consumer *consumer() const { return m_consumer.data(); }
163  const QString &URL() const { return m_url; }
164  const TransportControllable *transportControl() const { return &m_transportControl; }
165  Mlt::Producer *savedProducer() const { return m_savedProducer.data(); }
166  void setSavedProducer(Mlt::Producer *producer);
167  static Mlt::Filter *getFilter(const QString &name, Mlt::Service *service);
168  static Mlt::Link *getLink(const QString &name, Mlt::Service *service);
169  QString projectFolder() const { return m_projectFolder; }
170  void setProjectFolder(const QString &folderName);
171  QChar decimalPoint();
172  static void resetLocale();
173  static int filterIn(Mlt::Playlist &playlist, int clipIndex);
174  static int filterOut(Mlt::Playlist &playlist, int clipIndex);
175  void setPreviewScale(int scale);
176  void updatePreviewProfile();
177  static void purgeMemoryPool();
178  static bool fullRange(Mlt::Producer &producer);
179  static bool isMltXml(const QString &s) { return s.contains("<mlt "); }
180  static bool isTrackProducer(Mlt::Producer &producer);
181  static int checkFile(const QString &path);
182  bool blockRefresh(bool block);
183 
184  class RefreshBlocker
185  {
186  public:
187  RefreshBlocker() { singleton().blockRefresh(true); }
188  ~RefreshBlocker() { singleton().blockRefresh(false); }
189  };
190 
191 protected:
192  Mlt::Repository *m_repo;
193  QScopedPointer<Mlt::Producer> m_producer;
194  QScopedPointer<Mlt::FilteredConsumer> m_consumer;
195 
196 private:
197  Mlt::Profile m_profile;
198  Mlt::Profile m_previewProfile;
199  int m_audioChannels{2};
200  QScopedPointer<Mlt::Filter> m_jackFilter;
201  QString m_url;
202  double m_volume{1.0};
203  TransportControl m_transportControl;
204  QScopedPointer<Mlt::Producer> m_savedProducer;
205  QScopedPointer<Mlt::Producer> m_filtersClipboard;
206  unsigned m_skipJackEvents{0};
207  QString m_projectFolder;
208  QMutex m_saveXmlMutex;
209  bool m_blockRefresh;
210 
211  static void on_jack_started(mlt_properties owner, void *object, mlt_event_data data);
212  void onJackStarted(int position);
213  static void on_jack_stopped(mlt_properties owner, void *object, mlt_event_data data);
214  void onJackStopped(int position);
215  void stopJack();
216  void initFiltersClipboard();
217 };
218 
219 } // namespace Mlt
220 
221 #define MLT Mlt::Controller::singleton()
222 
223 #endif // MLTCONTROLLER_H