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
42namespace Mlt {
43
44const int kMaxImageDurationSecs = 3600 * 4;
45extern const QString XmlMimeType;
46
47class TransportControl : public TransportControllable
48{
49 Q_OBJECT
50public 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
63class Controller
64{
65protected:
66 Controller();
67 virtual int reconfigure(bool isMulti) = 0;
68
69public:
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
191protected:
192 Mlt::Repository *m_repo;
193 QScopedPointer<Mlt::Producer> m_producer;
194 QScopedPointer<Mlt::FilteredConsumer> m_consumer;
195
196private:
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