]> git.sesse.net Git - kdenlive/blobdiff - src/docclipbase.cpp
Hide the "avformat-novalidate" trick for faster loading, caused crash:
[kdenlive] / src / docclipbase.cpp
index 1246683e044d4ed3838e60aba814b104a989b957..6004a1300d25e9d810501aeb785aac3c7880f473 100644 (file)
@@ -87,35 +87,17 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin
 
     if (!m_properties.contains("name")) m_properties.insert("name", url.fileName());
 
-    //if (!url.isEmpty() && QFile::exists(url.path()))
-    {
-        m_thumbProd = new KThumb(clipManager, url, m_id, m_properties.value("file_hash"));
-        if (m_clipType == AV || m_clipType == AUDIO || m_clipType == PLAYLIST) slotCreateAudioTimer();
-    }
-    //kDebug() << "type is video" << (m_clipType == AV) << " " << m_clipType;
-}
-
-/*DocClipBase & DocClipBase::operator=(const DocClipBase & clip) {
-    DocClipBase::operator=(clip);
-    m_id = clip.getId();
-    m_clipType = clip.clipType();
-    m_name = clip.name();
-    m_duration = clip.duration();
-    m_audioThumbCreated = clip.audioThumbCreated();
-    m_properties = clip.properties();
-    return *this;
-}*/
+    m_thumbProd = new KThumb(clipManager, url, m_id, m_properties.value("file_hash"));
+    if (m_clipType == AV || m_clipType == AUDIO || m_clipType == PLAYLIST) slotCreateAudioTimer();
+}
 
 DocClipBase::~DocClipBase()
 {
-    kDebug() << "CLIP " << m_id << " DELETED******************************";
     delete m_thumbProd;
     if (m_audioTimer) {
         m_audioTimer->stop();
         delete m_audioTimer;
     }
-    /*kDebug() <<" * * *CNT "<<m_baseTrackProducers.count();
-    if (m_baseTrackProducers.count() > 0) kDebug()<<"YOYO: "<<m_baseTrackProducers.at(0)->get_out()<<", CUT: "<<m_baseTrackProducers.at(0)->is_cut();*/
     qDeleteAll(m_baseTrackProducers);
     m_baseTrackProducers.clear();
     qDeleteAll(m_audioTrackProducers);
@@ -449,21 +431,31 @@ void DocClipBase::setValid()
 
 void DocClipBase::setProducer(Mlt::Producer *producer, bool reset, bool readPropertiesFromProducer)
 {
-    if (m_placeHolder && producer) {
+    if (producer == NULL) return;
+    if (reset) QMutexLocker locker(&m_producerMutex);
+    if (m_placeHolder || !producer->is_valid()) {
         char *tmp = qstrdup(i18n("Missing clip").toUtf8().constData());
         producer->set("markup", tmp);
         producer->set("bgcolour", "0xff0000ff");
         producer->set("pad", "10");
         delete[] tmp;
     }
-    if (producer == NULL /*|| (m_placeHolder && !reset)*/) return;
-    if (m_thumbProd && (reset || !m_thumbProd->hasProducer())) m_thumbProd->setProducer(producer);
+    QString id = producer->get("id");
+    if (m_thumbProd) {
+        if (reset) m_thumbProd->setProducer(NULL);
+        if (!m_thumbProd->hasProducer()) {
+            if (m_clipType != AUDIO) {
+                if (!id.endsWith("_audio"))
+                    m_thumbProd->setProducer(producer);
+            }
+            else m_thumbProd->setProducer(producer);
+        }
+    }
     if (reset) {
         // Clear all previous producers
         kDebug() << "/+++++++++++++++   DELETE ALL PRODS " << producer->get("id");
         deleteProducers(false);
     }
-    QString id = producer->get("id");
     bool updated = false;
     if (id.contains('_')) {
         // this is a subtrack producer, insert it at correct place
@@ -524,6 +516,7 @@ static double getPixelAspect(QMap<QString, QString>& props) {
 
 Mlt::Producer *DocClipBase::audioProducer(int track)
 {
+    QMutexLocker locker(&m_producerMutex);
     if (m_audioTrackProducers.count() <= track) {
         while (m_audioTrackProducers.count() - 1 < track) {
             m_audioTrackProducers.append(NULL);
@@ -533,12 +526,17 @@ Mlt::Producer *DocClipBase::audioProducer(int track)
         int i;
         for (i = 0; i < m_audioTrackProducers.count(); i++)
             if (m_audioTrackProducers.at(i) != NULL) break;
-        if (i < m_audioTrackProducers.count()) {
-            // Could not find a valid producer for that clip, check in 
-            return m_audioTrackProducers.at(i);
+        Mlt::Producer *base;
+        if (i >= m_audioTrackProducers.count()) {
+            // Could not find a valid producer for that clip
+            locker.unlock();
+            base = producer();
+            if (base == NULL) {
+                return NULL;
+            }
+            locker.relock();
         }
-            
-        Mlt::Producer *base = producer();
+        else base = m_audioTrackProducers.at(i);
         m_audioTrackProducers[track] = cloneProducer(base);
         adjustProducerProperties(m_audioTrackProducers.at(track), QString(getId() + '_' + QString::number(track) + "_audio"), false, true);
     }
@@ -571,6 +569,7 @@ void DocClipBase::adjustProducerProperties(Mlt::Producer *prod, const QString &i
 
 Mlt::Producer *DocClipBase::videoProducer()
 {
+    QMutexLocker locker(&m_producerMutex);
     if (m_videoOnlyProducer == NULL) {
         int i;
         for (i = 0; i < m_baseTrackProducers.count(); i++)
@@ -584,11 +583,15 @@ Mlt::Producer *DocClipBase::videoProducer()
 
 Mlt::Producer *DocClipBase::producer(int track)
 {
+    QMutexLocker locker(&m_producerMutex);
     if (track == -1 || (m_clipType != AUDIO && m_clipType != AV && m_clipType != PLAYLIST)) {
-        if (m_baseTrackProducers.count() == 0) return NULL;
+        if (m_baseTrackProducers.count() == 0) {
+            return NULL;
+        }
         for (int i = 0; i < m_baseTrackProducers.count(); i++) {
-            if (m_baseTrackProducers.at(i) != NULL)
+            if (m_baseTrackProducers.at(i) != NULL) {
                 return m_baseTrackProducers.at(i);
+            }
         }
         return NULL;
     }
@@ -616,16 +619,19 @@ Mlt::Producer *DocClipBase::producer(int track)
 Mlt::Producer *DocClipBase::cloneProducer(Mlt::Producer *source)
 {
     Mlt::Producer *result = NULL;
-    if (KIO::NetAccess::exists(KUrl(source->get("resource")), KIO::NetAccess::SourceSide, 0)) {
-        result = new Mlt::Producer(*source->profile(), source->get("resource"));
+    QString url = source->get("resource");
+    if (KIO::NetAccess::exists(KUrl(url), KIO::NetAccess::SourceSide, 0)) {
+        char *tmp = qstrdup(url.toUtf8().constData());
+        result = new Mlt::Producer(*source->profile(), tmp);
+        delete[] tmp;
     }
-    if (result == NULL) {
+    if (result == NULL || !result->is_valid()) {
         // placeholder clip
         QString txt = "+" + i18n("Missing clip") + ".txt";
         char *tmp = qstrdup(txt.toUtf8().constData());
         result = new Mlt::Producer(*source->profile(), tmp);
         delete[] tmp;
-        if (result == NULL)
+        if (result == NULL || !result->is_valid())
             result = new Mlt::Producer(*source->profile(), "colour:red");
         else {
             result->set("bgcolour", "0xff0000ff");
@@ -820,11 +826,23 @@ void DocClipBase::setProperties(QMap <QString, QString> properties)
     bool refreshProducer = false;
     QStringList keys;
     keys << "luma_duration" << "luma_file" << "fade" << "ttl" << "softness" << "crop" << "animation";
+    QString oldProxy = m_properties.value("proxy");
     while (i.hasNext()) {
         i.next();
         setProperty(i.key(), i.value());
         if (m_clipType == SLIDESHOW && keys.contains(i.key())) refreshProducer = true;
     }
+    if (properties.contains("proxy")) {
+        QString value = properties.value("proxy");
+        // If value is "-", that means user manually disabled proxy on this clip
+        if (value.isEmpty() || value == "-") {
+            // reset proxy
+            emit abortProxy(m_id, oldProxy);
+        }
+        else {
+            emit createProxy(m_id);
+        }
+    }
     if (refreshProducer) slotRefreshProducer();
 }
 
@@ -891,7 +909,7 @@ QString DocClipBase::getClipHash() const
     else if (m_clipType == TEXT) hash = QCryptographicHash::hash(QString("title" + getId() + m_properties.value("xmldata")).toUtf8().data(), QCryptographicHash::Md5).toHex();
     else {
         if (m_properties.contains("file_hash")) hash = m_properties.value("file_hash");
-        else hash = getHash(fileURL().path());
+        if (hash.isEmpty()) hash = getHash(fileURL().path());
         
     }
     return hash;
@@ -997,16 +1015,6 @@ void DocClipBase::setProperty(const QString &key, const QString &value)
             resetProducerProperty("set.force_full_luma");
         } else setProducerProperty("set.force_full_luma", value.toInt());
     }
-    else if (key == "proxy") {
-        // If value is "-", that means user manually disabled proxy on this clip
-        if (value.isEmpty() || value == "-") {
-            // reset proxy
-            emit abortProxy(m_id);
-        }
-        else {
-            emit createProxy(m_id);
-        }
-    }
 }
 
 QMap <QString, QString> DocClipBase::properties() const
@@ -1122,4 +1130,18 @@ bool DocClipBase::hasAudioCodec(const QString &codec) const
 }
 
 
+void DocClipBase::slotExtractImage(int frame, int frame2)
+{
+    if (m_thumbProd == NULL) return;
+    m_thumbProd->extractImage(frame, frame2);
+}
+
+QPixmap DocClipBase::extractImage(int frame, int width, int height)
+{
+    if (m_thumbProd == NULL) return QPixmap(width, height);
+    QMutexLocker locker(&m_producerMutex);
+    QPixmap p = m_thumbProd->extractImage(frame, width, height);
+    return p;
+}
+