clipcontroller.h 9.04 KB
Newer Older
1 2
/*
Copyright (C) 2012  Till Theato <root@ttill.de>
3 4
Copyright (C) 2014  Jean-Baptiste Mardelle <jb@kdenlive.org>
This file is part of Kdenlive. See www.kdenlive.org.
5

6 7 8 9 10
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
Laurent Montel's avatar
Laurent Montel committed
11
by the membership of KDE e.V.), which shall act as a proxy
12 13 14 15 16 17 18 19 20
defined in Section 14 of version 3 of the license.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 22 23 24 25 26 27
*/

#ifndef CLIPCONTROLLER_H
#define CLIPCONTROLLER_H

#include "definitions.h"

28
#include <QDateTime>
29
#include <QDir>
Nicolas Carion's avatar
Nicolas Carion committed
30 31 32
#include <QMutex>
#include <QObject>
#include <QString>
33
#include <memory>
Nicolas Carion's avatar
Nicolas Carion committed
34
#include <mlt++/Mlt.h>
35 36

class QPixmap;
37
class Bin;
38
class AudioStreamInfo;
39
class EffectStackModel;
40
class MarkerListModel;
41 42 43 44 45 46 47 48

/**
 * @class ClipController
 * @brief Provides a convenience wrapper around the project Bin clip producers.
 * It also holds a QList of track producers for the 'master' producer in case we
 * need to update or replace them
 */

49
class ClipController
50 51
{
public:
52
    friend class Bin;
53 54
    /**
     * @brief Constructor.
55
     The constructor is protected because you should call the static Construct instead
56 57 58
     * @param bincontroller reference to the bincontroller
     * @param producer producer to create reference to
     */
Nicolas Carion's avatar
Nicolas Carion committed
59
    explicit ClipController(const QString &id, const std::shared_ptr<Mlt::Producer> &producer = nullptr);
60 61

public:
62
    virtual ~ClipController();
Laurent Montel's avatar
Laurent Montel committed
63

64 65
    QMutex producerMutex;

66 67
    /** @brief Returns true if the master producer is valid */
    bool isValid();
Laurent Montel's avatar
Laurent Montel committed
68

69 70
    /** @brief Stores the file's creation time */
    QDateTime date;
71

72
    /** @brief Replaces the master producer and (TODO) the track producers with an updated producer, for example a proxy */
Nicolas Carion's avatar
Nicolas Carion committed
73
    void updateProducer(const std::shared_ptr<Mlt::Producer> &producer);
74

75
    void getProducerXML(QDomDocument &document, bool includeMeta = false, bool includeProfile = true);
76

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
77
    /** @brief Returns a clone of our master producer. Delete after use! */
78
    Mlt::Producer *masterProducer();
79

80 81
    /** @brief Returns the clip name (usually file name) */
    QString clipName() const;
82 83 84 85

    /** @brief Returns the clip's description or metadata comment */
    QString description() const;

86
    /** @brief Returns the clip's MLT resource */
87
    const QString clipUrl() const;
88

89
    /** @brief Returns the clip's type as defined in definitions.h */
90
    ClipType::ProducerType clipType() const;
91

92 93 94
    /** @brief Returns the MLT's producer id */
    const QString binId() const;

95 96
    /** @brief Returns the clip's duration */
    GenTime getPlaytime() const;
97
    int getFramePlaytime() const;
98 99 100 101 102
    /**
     * @brief Sets a property.
     * @param name name of the property
     * @param value the new value
     */
Nicolas Carion's avatar
Nicolas Carion committed
103 104 105
    void setProducerProperty(const QString &name, const QString &value);
    void setProducerProperty(const QString &name, int value);
    void setProducerProperty(const QString &name, double value);
106 107
    /** @brief Reset a property on the MLT producer (=delete the property). */
    void resetProducerProperty(const QString &name);
Laurent Montel's avatar
Laurent Montel committed
108

109
    /**
110
     * @brief Returns the list of all properties starting with prefix. For subclips, the list is of this type:
111 112
     * { subclip name , subclip in/out } where the subclip in/ou value is a semi-colon separated in/out value, like "25;220"
     */
Laurent Montel's avatar
Laurent Montel committed
113
    QMap<QString, QString> getPropertiesFromPrefix(const QString &prefix, bool withPrefix = false);
Laurent Montel's avatar
Laurent Montel committed
114

115 116 117 118
    /**
     * @brief Returns the value of a property.
     * @param name name o the property
     */
119 120 121 122 123 124
    QMap<QString, QString> currentProperties(const QMap<QString, QString> &props);
    QString getProducerProperty(const QString &key) const;
    int getProducerIntProperty(const QString &key) const;
    qint64 getProducerInt64Property(const QString &key) const;
    QColor getProducerColorProperty(const QString &key) const;
    double getProducerDoubleProperty(const QString &key) const;
125 126

    double originalFps() const;
127
    QString videoCodecProperty(const QString &property) const;
128
    const QString codec(bool audioCodec) const;
129
    const QString getClipHash() const;
130
    const QSize getFrameSize() const;
131 132
    /** @brief Returns the clip duration as a string like 00:00:02:01. */
    const QString getStringDuration();
133
    int getProducerDuration() const;
134
    char *framesToTime(int frames) const;
135 136 137 138 139 140 141 142 143 144 145

    /**
     * @brief Returns a pixmap created from a frame of the producer.
     * @param position frame position
     * @param width width of the pixmap (only a guidance)
     * @param height height of the pixmap (only a guidance)
     */
    QPixmap pixmap(int position = 0, int width = 0, int height = 0);

    /** @brief Returns the MLT producer's service. */
    QString serviceName() const;
Laurent Montel's avatar
Laurent Montel committed
146

147
    /** @brief Returns the original master producer. */
148
    std::shared_ptr<Mlt::Producer> originalProducer();
Laurent Montel's avatar
Laurent Montel committed
149

150 151
    /** @brief Holds index of currently selected master clip effect. */
    int selectedEffectIndex;
Laurent Montel's avatar
Laurent Montel committed
152

153
    /** @brief Sets the master producer for this clip when we build the controller without master clip. */
Nicolas Carion's avatar
Nicolas Carion committed
154
    void addMasterProducer(const std::shared_ptr<Mlt::Producer> &producer);
Laurent Montel's avatar
Laurent Montel committed
155

156 157 158
    /* @brief Returns the marker model associated with this clip */
    std::shared_ptr<MarkerListModel> getMarkerModel() const;

159 160
    void setZone(const QPoint &zone);
    QPoint zone() const;
161
    bool hasLimitedDuration() const;
Nicolas Carion's avatar
Nicolas Carion committed
162
    void forceLimitedDuration();
163
    Mlt::Properties &properties();
164
    void mirrorOriginalProperties(Mlt::Properties &props);
165
    void addEffect(QDomElement &xml);
Nicolas Carion's avatar
Nicolas Carion committed
166
    bool copyEffect(const std::shared_ptr<EffectStackModel> &stackModel, int rowId);
167
    void removeEffect(int effectIndex, bool delayRefresh = false);
168
    /** @brief Enable/disable an effect. */
Laurent Montel's avatar
Laurent Montel committed
169
    void changeEffectState(const QList<int> &indexes, bool disable);
170
    void updateEffect(const QDomElement &e, int ix);
171
    /** @brief Returns true if the bin clip has effects */
172
    bool hasEffects() const;
173 174
    /** @brief Returns true if the clip contains at least one audio stream */
    bool hasAudio() const;
175 176 177
    /** @brief Returns true if the clip contains at least one video stream */
    bool hasVideo() const;
    /** @brief Returns the default state a clip should be in. If the clips contains both video and audio, this defaults to video */
178
    PlaylistState::ClipState defaultState() const;
179
    /** @brief Returns info about clip audio */
Nicolas Carion's avatar
Nicolas Carion committed
180
    const std::unique_ptr<AudioStreamInfo> &audioInfo() const;
181
    /** @brief Returns true if audio thumbnails for this clip are cached */
182
    bool m_audioThumbCreated;
183
    /** @brief When replacing a producer, it is important that we keep some properties, for example force_ stuff and url for proxies
184
     * this method returns a list of properties that we want to keep when replacing a producer . */
185
    static const char *getPassPropertiesList(bool passLength = true);
186
    /** @brief Disable all Kdenlive effects on this clip */
187
    void setBinEffectsEnabled(bool enabled);
188 189 190 191
    /** @brief Returns the number of Kdenlive added effects for this bin clip */
    int effectsCount();
    /** @brief Move an effect in stack for this bin clip */
    void moveEffect(int oldPos, int newPos);
192
    /** @brief Save an xml playlist of current clip with in/out points as zone.x()/y() */
Laurent Montel's avatar
Laurent Montel committed
193
    void saveZone(QPoint zone, const QDir &dir);
194

195 196 197 198 199 200 201
    /* @brief This is the producer that serves as a placeholder while a clip is being loaded. It is created in Core at startup */
    static std::shared_ptr<Mlt::Producer> mediaUnavailable;

    /** @brief Returns a ptr to the effetstack associated with this element */
    std::shared_ptr<EffectStackModel> getEffectStack() const;

    /** @brief Append an effect to this producer's effect list */
202
    bool addEffect(const QString &effectId);
203 204

protected:
Nicolas Carion's avatar
Nicolas Carion committed
205
    virtual void emitProducerChanged(const QString & /*unused*/, const std::shared_ptr<Mlt::Producer> & /*unused*/){};
Nicolas Carion's avatar
Nicolas Carion committed
206
    virtual void connectEffectStack(){};
207

208 209
    // This is the helper function that checks if the clip has audio and video and stores the result
    void checkAudioVideo();
210 211
    // Update audio stream info
    void refreshAudioInfo();
212

213
    std::shared_ptr<Mlt::Producer> m_masterProducer;
214
    Mlt::Properties *m_properties;
215
    bool m_usesProxy;
216
    std::unique_ptr<AudioStreamInfo> m_audioInfo;
217
    QString m_service;
218
    QString m_path;
219
    int m_videoIndex;
220
    ClipType::ProducerType m_clipType;
221
    bool m_hasLimitedDuration;
222
    QMutex m_effectMutex;
223
    void getInfoForProducer();
Nicolas Carion's avatar
Nicolas Carion committed
224
    // void rebuildEffectList(ProfileInfo info);
225
    std::shared_ptr<EffectStackModel> m_effectStack;
226
    std::shared_ptr<MarkerListModel> m_markerModel;
227
    bool m_hasAudio;
228
    bool m_hasVideo;
229 230 231

private:
    QMutex m_producerLock;
232
    QString m_controllerBinId;
233 234 235
};

#endif