File indexing completed on 2024-03-24 04:54:33
0001 /* 0002 SPDX-FileCopyrightText: 2012 Till Theato <root@ttill.de> 0003 SPDX-FileCopyrightText: 2014 Jean-Baptiste Mardelle <jb@kdenlive.org> 0004 This file is part of Kdenlive. See www.kdenlive.org. 0005 0006 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 */ 0008 0009 #pragma once 0010 0011 #include "definitions.h" 0012 #include "undohelper.hpp" 0013 0014 #include <QDateTime> 0015 #include <QDir> 0016 #include <QMutex> 0017 #include <QString> 0018 #include <QReadWriteLock> 0019 #include <memory> 0020 #include <mlt++/Mlt.h> 0021 0022 class QPixmap; 0023 class Bin; 0024 class AudioStreamInfo; 0025 class EffectStackModel; 0026 class MarkerListModel; 0027 class MarkerSortModel; 0028 0029 /** @class ClipController 0030 * @brief Provides a convenience wrapper around the project Bin clip producers. 0031 * It also holds a QList of track producers for the 'master' producer in case we 0032 * need to update or replace them 0033 */ 0034 class ClipController 0035 { 0036 public: 0037 friend class Bin; 0038 /** 0039 * @brief Constructor. 0040 The constructor is protected because you should call the static Construct instead 0041 * @param bincontroller reference to the bincontroller 0042 * @param producer producer to create reference to 0043 */ 0044 explicit ClipController(const QString &id, const std::shared_ptr<Mlt::Producer> &producer = nullptr); 0045 0046 public: 0047 virtual ~ClipController(); 0048 0049 QMutex producerMutex; 0050 0051 /** @brief Returns true if the master producer is valid */ 0052 bool isValid(); 0053 0054 /** @brief Returns true if the source file exists */ 0055 bool sourceExists() const; 0056 0057 /** @brief Stores the file's creation time */ 0058 QDateTime date; 0059 0060 /** @brief Replaces the master producer and (TODO) the track producers with an updated producer, for example a proxy */ 0061 void updateProducer(const std::shared_ptr<Mlt::Producer> &producer); 0062 static const QString producerXml(Mlt::Producer producer, bool includeMeta, bool includeProfile); 0063 0064 void getProducerXML(QDomDocument &document, bool includeMeta = false, bool includeProfile = true); 0065 0066 /** @brief Returns a clone of our master producer. Delete after use! */ 0067 Mlt::Producer *masterProducer(); 0068 0069 /** @brief Returns the clip's MLT resource */ 0070 const QString clipUrl() const; 0071 0072 /** @brief Returns the clip's type as defined in definitions.h */ 0073 ClipType::ProducerType clipType() const; 0074 0075 /** @brief Returns the MLT's producer id */ 0076 const QString binId() const; 0077 0078 /** @brief Returns this clip's producer. */ 0079 virtual std::unique_ptr<Mlt::Producer> getThumbProducer() = 0; 0080 0081 virtual void reloadProducer(bool refreshOnly = false, bool isProxy = false, bool forceAudioReload = false) = 0; 0082 0083 /** @brief Rename an audio stream. */ 0084 virtual void renameAudioStream(int id, const QString &name) = 0; 0085 0086 /** @brief Add an audio effect on a specific audio stream for this clip. */ 0087 virtual void requestAddStreamEffect(int streamIndex, const QString effectName) = 0; 0088 /** @brief Remove an audio effect on a specific audio stream for this clip. */ 0089 virtual void requestRemoveStreamEffect(int streamIndex, const QString effectName) = 0; 0090 virtual QStringList getAudioStreamEffect(int streamIndex) const = 0; 0091 0092 /** @brief Returns the clip's duration */ 0093 GenTime getPlaytime() const; 0094 int getFramePlaytime() const; 0095 /** 0096 * @brief Sets a property. 0097 * @param name name of the property 0098 * @param value the new value 0099 */ 0100 void setProducerProperty(const QString &name, const QString &value); 0101 void setProducerProperty(const QString &name, int value); 0102 void setProducerProperty(const QString &name, double value); 0103 /** @brief Reset a property on the MLT producer (=delete the property). */ 0104 void resetProducerProperty(const QString &name); 0105 0106 /** 0107 * @brief Returns the list of all properties starting with prefix. For subclips, the list is of this type: 0108 * { subclip name , subclip in/out } where the subclip in/ou value is a semi-colon separated in/out value, like "25;220" 0109 */ 0110 QMap<QString, QString> getPropertiesFromPrefix(const QString &prefix, bool withPrefix = false); 0111 0112 /** 0113 * @brief Returns the value of a property. 0114 * @param name name o the property 0115 */ 0116 QMap<QString, QString> currentProperties(const QMap<QString, QString> &props); 0117 bool hasProducerProperty(const QString &name) const; 0118 QString getProducerProperty(const QString &key) const; 0119 int getProducerIntProperty(const QString &key) const; 0120 qint64 getProducerInt64Property(const QString &key) const; 0121 QColor getProducerColorProperty(const QString &key) const; 0122 double getProducerDoubleProperty(const QString &key) const; 0123 0124 double originalFps() const; 0125 QString videoCodecProperty(const QString &property) const; 0126 const QString codec(bool audioCodec) const; 0127 const QString getClipHash() const; 0128 const QSize getFrameSize() const; 0129 /** @brief Returns the clip duration as a string like 00:00:02:01. */ 0130 const QString getStringDuration(); 0131 int getProducerDuration() const; 0132 char *framesToTime(int frames) const; 0133 0134 /** @brief Returns the MLT producer's service. */ 0135 QString serviceName() const; 0136 0137 /** @brief Returns the original master producer. */ 0138 std::shared_ptr<Mlt::Producer> originalProducer(); 0139 0140 /** @brief Holds index of currently selected master clip effect. */ 0141 int selectedEffectIndex; 0142 0143 /** @brief Sets the master producer for this clip when we build the controller without master clip. */ 0144 void addMasterProducer(const std::shared_ptr<Mlt::Producer> &producer); 0145 0146 /** @brief Returns the marker model associated with this clip */ 0147 std::shared_ptr<MarkerListModel> getMarkerModel() const; 0148 std::shared_ptr<MarkerSortModel> getFilteredMarkerModel() const; 0149 0150 void setZone(const QPoint &zone); 0151 bool hasLimitedDuration() const; 0152 void forceLimitedDuration(); 0153 Mlt::Properties &properties(); 0154 void mirrorOriginalProperties(std::shared_ptr<Mlt::Properties> props); 0155 bool copyEffect(const std::shared_ptr<EffectStackModel> &stackModel, int rowId); 0156 /** @brief Returns true if the bin clip has effects */ 0157 bool hasEffects() const; 0158 /** @brief Returns true if the clip contains at least one audio stream */ 0159 bool hasAudio() const; 0160 /** @brief Returns true if the clip contains at least one video stream */ 0161 bool hasVideo() const; 0162 /** @brief Returns the default state a clip should be in. If the clips contains both video and audio, this defaults to video */ 0163 PlaylistState::ClipState defaultState() const; 0164 /** @brief Returns info about clip audio */ 0165 const std::unique_ptr<AudioStreamInfo> &audioInfo() const; 0166 /** @brief Returns true if audio thumbnails for this clip are cached */ 0167 bool m_audioThumbCreated; 0168 /** @brief When replacing a producer, it is important that we keep some properties, for example force_ stuff and url for proxies 0169 * this method returns a list of properties that we want to keep when replacing a producer . */ 0170 static const char *getPassPropertiesList(bool passLength = true); 0171 /** @brief Disable all Kdenlive effects on this clip */ 0172 void setBinEffectsEnabled(bool enabled); 0173 /** @brief Returns the number of Kdenlive added effects for this bin clip */ 0174 int effectsCount(); 0175 /** @brief Returns all urls of external files used by effects on this bin clip (e.g. LUTs)*/ 0176 QStringList filesUsedByEffects(); 0177 0178 /** @brief This is the producer that serves as a placeholder while a clip is being loaded. It is created in Core at startup */ 0179 static std::shared_ptr<Mlt::Producer> mediaUnavailable; 0180 0181 /** @brief Returns a ptr to the effetstack associated with this element */ 0182 std::shared_ptr<EffectStackModel> getEffectStack() const; 0183 0184 /** @brief Append an effect to this producer's effect list */ 0185 bool addEffect(const QString &effectId, stringMap params = {}); 0186 0187 /** @brief Returns the list of all audio streams indexes for this clip */ 0188 QMap <int, QString> audioStreams() const; 0189 /** @brief Returns the absolute audio stream index (usable for MLT's astream property) */ 0190 int audioStreamIndex(int stream) const; 0191 /** @brief Returns the number of channels per audio stream. */ 0192 QList <int> activeStreamChannels() const; 0193 /** @brief Returns the list of active audio streams indexes for this clip */ 0194 QMap <int, QString> activeStreams() const; 0195 /** @brief Returns the list of active audio streams ffmpeg indexes for this clip */ 0196 QVector<int> activeFfmpegStreams() const; 0197 /** @brief Returns the count of audio streams for this clip */ 0198 int audioStreamsCount() const; 0199 /** @brief Get the path to the original clip url (in case it is proxied) */ 0200 const QString getOriginalUrl(); 0201 /** @brief Returns true if we are using a proxy for this clip. */ 0202 bool hasProxy() const; 0203 /** @brief Delete or re-assign all markers in a category. */ 0204 bool removeMarkerCategories(QList<int> toRemove, const QMap<int, int> remapCategories, Fun &undo, Fun &redo); 0205 // This is the helper function that checks if the clip has audio and video and stores the result 0206 void checkAudioVideo(); 0207 bool isFullRange() const; 0208 0209 protected: 0210 /** @brief Mutex to protect the producer properties on read/write */ 0211 mutable QReadWriteLock m_producerLock; 0212 virtual void connectEffectStack(){}; 0213 0214 // Update audio stream info 0215 void refreshAudioInfo(); 0216 void backupOriginalProperties(); 0217 void clearBackupProperties(); 0218 0219 std::shared_ptr<Mlt::Producer> m_masterProducer; 0220 Mlt::Properties *m_properties; 0221 bool m_usesProxy; 0222 std::unique_ptr<AudioStreamInfo> m_audioInfo; 0223 QString m_service; 0224 QString m_path; 0225 int m_videoIndex; 0226 ClipType::ProducerType m_clipType; 0227 bool m_forceLimitedDuration; 0228 bool m_hasMultipleVideoStreams; 0229 QMutex m_effectMutex; 0230 void getInfoForProducer(); 0231 // void rebuildEffectList(ProfileInfo info); 0232 std::shared_ptr<EffectStackModel> m_effectStack; 0233 std::shared_ptr<MarkerListModel> m_markerModel; 0234 std::shared_ptr<MarkerSortModel> m_markerFilterModel; 0235 bool m_hasAudio; 0236 bool m_hasVideo; 0237 QMap<int, QStringList> m_streamEffects; 0238 /** @brief Store clip url temporarily while the clip controller has not been created. */ 0239 QString m_temporaryUrl; 0240 0241 private: 0242 /** @brief Temporarily store clip properties until producer is available */ 0243 QMap <QString, QVariant> m_tempProps; 0244 QString m_controllerBinId; 0245 /** @brief Build the audio info object */ 0246 void buildAudioInfo(int audioIndex); 0247 };