]> git.sesse.net Git - kdenlive/blobdiff - src/docclipbase.cpp
Fix crash on clip deletion, fix issues with placeholder clips
[kdenlive] / src / docclipbase.cpp
index 8b83045f76d6faf3c0b9acf77022084835ef239b..7b55fa5f3beba4fd871deb908d158fa4cebbd29f 100644 (file)
@@ -34,6 +34,8 @@
 
 #include <QCryptographicHash>
 
+#include <cstdio>
+
 DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id) :
         QObject(),
         m_audioFrameCache(),
@@ -41,7 +43,7 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin
         m_baseTrackProducers(),
         m_audioTrackProducers(),
         m_videoOnlyProducer(NULL),
-        m_snapMarkers(),
+        m_snapMarkers(QList < CommentedTime >()),
         m_duration(),
         m_audioTimer(NULL),
         m_thumbProd(NULL),
@@ -62,7 +64,7 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin
         QStringList cuts = xml.attribute("cutzones").split(";", QString::SkipEmptyParts);
         for (int i = 0; i < cuts.count(); i++) {
             QString z = cuts.at(i);
-            addCutZone(z.section('-', 0, 0).toInt(), z.section('-', 1, 1).toInt());
+            addCutZone(z.section('-', 0, 0).toInt(), z.section('-', 1, 1).toInt(), z.section('-', 2, 2));
         }
     }
 
@@ -273,7 +275,8 @@ QDomElement DocClipBase::toXML() const
     if (!m_cutZones.isEmpty()) {
         QStringList cuts;
         for (int i = 0; i < m_cutZones.size(); i++) {
-            cuts << QString::number(m_cutZones.at(i).x()) + "-" + QString::number(m_cutZones.at(i).y());
+            CutZoneInfo info = m_cutZones.at(i);
+            cuts << QString::number(info.zone.x()) + "-" + QString::number(info.zone.y()) + "-" + info.description;
         }
         clip.setAttribute("cutzones", cuts.join(";"));
     }
@@ -300,7 +303,7 @@ const QPixmap & DocClipBase::thumbnail() const
 
 void DocClipBase::updateAudioThumbnail(QMap<int, QMap<int, QByteArray> > data)
 {
-    //kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************";
+    //kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************";
     m_audioFrameCache = data;
     m_audioThumbCreated = true;
     emit gotAudioData();
@@ -322,10 +325,6 @@ QList < CommentedTime > DocClipBase::commentedSnapMarkers() const
     return m_snapMarkers;
 }
 
-void DocClipBase::setSnapMarkers(QList < CommentedTime > markers)
-{
-    m_snapMarkers = markers;
-}
 
 void DocClipBase::addSnapMarker(const GenTime & time, QString comment)
 {
@@ -459,7 +458,7 @@ void DocClipBase::deleteProducers()
 
 void DocClipBase::setProducer(Mlt::Producer *producer, bool reset)
 {
-    if (producer == NULL) return;
+    if (producer == NULL || m_placeHolder) return;
     if (reset) {
         // Clear all previous producers
         kDebug() << "/+++++++++++++++   DELETE ALL PRODS " << producer->get("id");
@@ -509,6 +508,8 @@ Mlt::Producer *DocClipBase::audioProducer(int track)
         Mlt::Producer *base = producer();
         m_audioTrackProducers[track] = new Mlt::Producer(*(base->profile()), base->get("resource"));
         if (m_properties.contains("force_aspect_ratio")) m_audioTrackProducers.at(track)->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+        if (m_properties.contains("force_fps")) m_audioTrackProducers.at(track)->set("force_fps", m_properties.value("force_fps").toDouble());
+        if (m_properties.contains("force_progressive")) m_audioTrackProducers.at(track)->set("force_progressive", m_properties.value("force_progressive").toInt());
         if (m_properties.contains("threads")) m_audioTrackProducers.at(track)->set("threads", m_properties.value("threads").toInt());
         m_audioTrackProducers.at(track)->set("video_index", -1);
         if (m_properties.contains("audio_index")) m_audioTrackProducers.at(track)->set("audio_index", m_properties.value("audio_index").toInt());
@@ -528,6 +529,8 @@ Mlt::Producer *DocClipBase::videoProducer()
         if (i >= m_baseTrackProducers.count()) return NULL;
         m_videoOnlyProducer = new Mlt::Producer(*m_baseTrackProducers.at(i)->profile(), m_baseTrackProducers.at(i)->get("resource"));
         if (m_properties.contains("force_aspect_ratio")) m_videoOnlyProducer->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+        if (m_properties.contains("force_fps")) m_videoOnlyProducer->set("force_fps", m_properties.value("force_fps").toDouble());
+        if (m_properties.contains("force_progressive")) m_videoOnlyProducer->set("force_progressive", m_properties.value("force_progressive").toInt());
         if (m_properties.contains("threads")) m_videoOnlyProducer->set("threads", m_properties.value("threads").toInt());
         m_videoOnlyProducer->set("audio_index", -1);
         if (m_properties.contains("video_index")) m_videoOnlyProducer->set("video_index", m_properties.value("video_index").toInt());
@@ -571,6 +574,8 @@ Mlt::Producer *DocClipBase::producer(int track)
         }
 
         if (m_properties.contains("force_aspect_ratio")) m_baseTrackProducers[track]->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+        if (m_properties.contains("force_fps")) m_baseTrackProducers[track]->set("force_fps", m_properties.value("force_fps").toDouble());
+        if (m_properties.contains("force_progressive")) m_baseTrackProducers[track]->set("force_progressive", m_properties.value("force_progressive").toInt());
         if (m_properties.contains("threads")) m_baseTrackProducers[track]->set("threads", m_properties.value("threads").toInt());
         if (m_properties.contains("video_index")) m_baseTrackProducers[track]->set("video_index", m_properties.value("video_index").toInt());
         if (m_properties.contains("audio_index")) m_baseTrackProducers[track]->set("audio_index", m_properties.value("audio_index").toInt());
@@ -609,6 +614,14 @@ void DocClipBase::setProducerProperty(const char *name, const char *data)
     }
 }
 
+void DocClipBase::resetProducerProperty(const char *name)
+{
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i) != NULL)
+            m_baseTrackProducers[i]->set(name, (const char*) NULL);
+    }
+}
+
 const char *DocClipBase::producerProperty(const char *name) const
 {
     for (int i = 0; i < m_baseTrackProducers.count(); i++) {
@@ -807,9 +820,18 @@ void DocClipBase::setProperty(const QString &key, const QString &value)
     } else if (key == "force_aspect_ratio") {
         if (value.isEmpty()) {
             m_properties.remove("force_aspect_ratio");
-            //TODO: find a was to remove the "force_aspect_ratio" property from producer, currently does not work
-            setProducerProperty("force_aspect_ratio", 0);
+            resetProducerProperty("force_aspect_ratio");
         } else setProducerProperty("force_aspect_ratio", value.toDouble());
+    } else if (key == "force_fps") {
+        if (value.isEmpty()) {
+            m_properties.remove("force_fps");
+            resetProducerProperty("force_fps");
+        } else setProducerProperty("force_fps", value.toDouble());
+    } else if (key == "force_progressive") {
+        if (value.isEmpty()) {
+            m_properties.remove("force_progressive");
+            resetProducerProperty("force_progressive");
+        } else setProducerProperty("force_progressive", value.toInt());
     } else if (key == "threads") {
         if (value.isEmpty()) {
             m_properties.remove("threads");
@@ -855,37 +877,88 @@ bool DocClipBase::isPlaceHolder() const
     return m_placeHolder;
 }
 
-void DocClipBase::addCutZone(int in, int out)
+void DocClipBase::addCutZone(int in, int out, QString desc)
 {
-    if (!m_cutZones.contains(QPoint(in, out))) {
-        m_cutZones.append(QPoint(in, out));
-    }
+    CutZoneInfo info;
+    info.zone = QPoint(in, out);
+    info.description = desc;
+    for (int i = 0; i < m_cutZones.count(); i++)
+        if (m_cutZones.at(i).zone == info.zone) {
+            return;
+        }
+    m_cutZones.append(info);
 }
 
 bool DocClipBase::hasCutZone(QPoint p) const
 {
-    return m_cutZones.contains(p);
+    for (int i = 0; i < m_cutZones.count(); i++)
+        if (m_cutZones.at(i).zone == p) return true;
+    return false;
 }
 
 
 void DocClipBase::removeCutZone(int in, int out)
 {
-    m_cutZones.removeAll(QPoint(in, out));
+    QPoint p(in, out);
+    for (int i = 0; i < m_cutZones.count(); i++) {
+        if (m_cutZones.at(i).zone == p) {
+            m_cutZones.removeAt(i);
+            i--;
+        }
+    }
 }
 
-void DocClipBase::updateCutZone(int oldin, int oldout, int in, int out)
+void DocClipBase::updateCutZone(int oldin, int oldout, int in, int out, QString desc)
 {
     QPoint old(oldin, oldout);
     for (int i = 0; i < m_cutZones.size(); ++i) {
-        if (m_cutZones.at(i) == old) {
-            m_cutZones.replace(i, QPoint(in, out));
+        if (m_cutZones.at(i).zone == old) {
+            CutZoneInfo info;
+            info.zone = QPoint(in, out);
+            info.description = desc;
+            m_cutZones.replace(i, info);
             break;
         }
     }
 }
 
-QList <QPoint> DocClipBase::cutZones() const
+QList <CutZoneInfo> DocClipBase::cutZones() const
 {
     return m_cutZones;
 }
 
+bool DocClipBase::hasVideoCodec(const QString &codec) const
+{
+    Mlt::Producer *prod = NULL;
+    if (m_baseTrackProducers.count() == 0) return false;
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i) != NULL) {
+            prod = m_baseTrackProducers.at(i);
+            break;
+        }
+    }
+
+    if (!prod) return false;
+    int default_video = prod->get_int("video_index");
+    char property[200];
+    snprintf(property, sizeof(property), "meta.media.%d.codec.name", default_video);
+    return prod->get(property) == codec;
+}
+
+bool DocClipBase::hasAudioCodec(const QString &codec) const
+{
+    Mlt::Producer *prod = NULL;
+    if (m_baseTrackProducers.count() == 0) return false;
+    for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+        if (m_baseTrackProducers.at(i) != NULL) {
+            prod = m_baseTrackProducers.at(i);
+            break;
+        }
+    }
+    if (!prod) return false;
+    int default_video = prod->get_int("audio_index");
+    char property[200];
+    snprintf(property, sizeof(property), "meta.media.%d.codec.name", default_video);
+    return prod->get(property) == codec;
+}
+