]> git.sesse.net Git - kdenlive/blobdiff - src/renderer.cpp
Fix crash on clip cut introduced in recent coverity fix:
[kdenlive] / src / renderer.cpp
index 037bedc8b78865d74362bcddb7450327dd83afcf..a506e4ef39cb815d950f7dcbfbe523823508a9d9 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <QDebug>
 
+#define SEEK_INACTIVE (-1)
 
 static void kdenlive_callback(void* /*ptr*/, int level, const char* fmt, va_list vl)
 {
@@ -105,6 +106,7 @@ static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_
 
 Render::Render(Kdenlive::MONITORID rendererName, int winid, QString profile, QWidget *parent) :
     AbstractRender(rendererName, parent),
+    requestedSeekPosition(SEEK_INACTIVE),
     m_name(rendererName),
     m_mltConsumer(NULL),
     m_mltProducer(NULL),
@@ -174,7 +176,7 @@ void Render::closeMlt()
         service.unlock();
     }*/
 
-    kDebug() << "// // // CLOSE RENDERER " << m_name;
+    //kDebug() << "// // // CLOSE RENDERER " << m_name;
     if (m_blackClip) delete m_blackClip;
     //delete m_osdInfo;
 }
@@ -285,7 +287,7 @@ void Render::buildConsumer(const QString &profileName)
 Mlt::Producer *Render::invalidProducer(const QString &id)
 {
     Mlt::Producer *clip;
-    QString txt = "+" + i18n("Missing clip") + ".txt";
+    QString txt = '+' + i18n("Missing clip") + ".txt";
     char *tmp = qstrdup(txt.toUtf8().constData());
     clip = new Mlt::Producer(*m_mltProfile, tmp);
     delete[] tmp;
@@ -376,24 +378,21 @@ int Render::resetProfile(const QString &profileName, bool dropSceneList)
 
 void Render::seek(GenTime time)
 {
-    if (!m_mltProducer)
-        return;
-
-    m_mltProducer->seek((int)(time.frames(m_fps)));
-    if (m_mltProducer->get_speed() == 0) {
-        refresh();
-    }
+    int pos = time.frames(m_fps);
+    seek(pos);
 }
 
 void Render::seek(int time)
 {
     if (!m_mltProducer)
         return;
-
-    m_mltProducer->seek(time);
-    if (m_mltProducer->get_speed() == 0) {
-        refresh();
+    if (requestedSeekPosition == SEEK_INACTIVE) {
+       m_mltProducer->seek(time);
+       if (m_mltProducer->get_speed() == 0) {
+           refresh();
+       }
     }
+    requestedSeekPosition = time;
 }
 
 //static
@@ -1032,6 +1031,7 @@ void Render::initSceneList()
 int Render::setProducer(Mlt::Producer *producer, int position)
 {
     m_refreshTimer.stop();
+    requestedSeekPosition = SEEK_INACTIVE;
     QMutexLocker locker(&m_mutex);
     QString currentId;
     int consumerPosition = 0;
@@ -1106,6 +1106,7 @@ int Render::setSceneList(QDomDocument list, int position)
 
 int Render::setSceneList(QString playlist, int position)
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     m_refreshTimer.stop();
     QMutexLocker locker(&m_mutex);
     if (m_winid == -1) return -1;
@@ -1412,6 +1413,7 @@ void Render::start()
 
 void Render::stop()
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     m_refreshTimer.stop();
     QMutexLocker locker(&m_mutex);
     if (m_mltProducer == NULL) return;
@@ -1428,6 +1430,7 @@ void Render::stop()
 
 void Render::stop(const GenTime & startTime)
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     m_refreshTimer.stop();
     QMutexLocker locker(&m_mutex);
     if (m_mltProducer) {
@@ -1440,6 +1443,7 @@ void Render::stop(const GenTime & startTime)
 
 void Render::pause()
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     if (!m_mltProducer || !m_mltConsumer)
         return;
     if (m_mltProducer->get_speed() == 0.0) return;
@@ -1452,6 +1456,7 @@ void Render::pause()
 void Render::switchPlay(bool play)
 {
     QMutexLocker locker(&m_mutex);
+    requestedSeekPosition = SEEK_INACTIVE;
     if (!m_mltProducer || !m_mltConsumer)
         return;
     if (m_isZoneMode) resetZoneMode();
@@ -1482,6 +1487,7 @@ void Render::switchPlay(bool play)
 
 void Render::play(double speed)
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     if (!m_mltProducer)
         return;
     // if (speed == 0.0) m_mltProducer->set("out", m_mltProducer->get_length() - 1);
@@ -1495,6 +1501,7 @@ void Render::play(double speed)
 
 void Render::play(const GenTime & startTime)
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     if (!m_mltProducer || !m_mltConsumer)
         return;
     m_mltProducer->seek((int)(startTime.frames(m_fps)));
@@ -1504,6 +1511,7 @@ void Render::play(const GenTime & startTime)
 
 void Render::loopZone(const GenTime & startTime, const GenTime & stopTime)
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     if (!m_mltProducer || !m_mltConsumer)
         return;
     //m_mltProducer->set("eof", "loop");
@@ -1514,6 +1522,7 @@ void Render::loopZone(const GenTime & startTime, const GenTime & stopTime)
 
 void Render::playZone(const GenTime & startTime, const GenTime & stopTime)
 {
+    requestedSeekPosition = SEEK_INACTIVE;
     if (!m_mltProducer || !m_mltConsumer)
         return;
     if (!m_isZoneMode) m_originalOut = m_mltProducer->get_playtime() - 1;
@@ -1527,7 +1536,7 @@ void Render::playZone(const GenTime & startTime, const GenTime & stopTime)
 
 void Render::resetZoneMode()
 {
-    if (!m_isZoneMode && !m_isLoopMode) return;
+    if (!m_mltProducer || (!m_isZoneMode && !m_isLoopMode)) return;
     m_mltProducer->set("out", m_originalOut);
     //m_mltProducer->set("eof", "pause");
     m_isZoneMode = false;
@@ -1536,22 +1545,16 @@ void Render::resetZoneMode()
 
 void Render::seekToFrame(int pos)
 {
-    if (!m_mltProducer)
-        return;
     resetZoneMode();
-    m_mltProducer->seek(pos);
-    if (m_mltProducer->get_speed() == 0) {
-        refresh();
-    }
+    seek(pos);
 }
 
 void Render::seekToFrameDiff(int diff)
 {
-    if (!m_mltProducer)
-        return;
     resetZoneMode();
-    m_mltProducer->seek(m_mltProducer->position() + diff);
-    refresh();
+    if (requestedSeekPosition == SEEK_INACTIVE)
+       seek(m_mltProducer->position() + diff);
+    else seek(requestedSeekPosition + diff);
 }
 
 void Render::doRefresh()
@@ -1629,7 +1632,15 @@ void Render::emitFrameUpdated(Mlt::Frame& frame)
 
 void Render::emitFrameNumber()
 {
-    if (m_mltConsumer) emit rendererPosition((int) m_mltConsumer->position());
+    int currentPos = m_mltConsumer->position();
+    if (currentPos == requestedSeekPosition) requestedSeekPosition = SEEK_INACTIVE;
+    emit rendererPosition(currentPos);
+    if (requestedSeekPosition != SEEK_INACTIVE) {
+       m_mltProducer->seek(requestedSeekPosition);
+       if (m_mltProducer->get_speed() == 0) {
+           refresh();
+       }
+    }
 }
 
 void Render::emitConsumerStopped()
@@ -1707,8 +1718,9 @@ void Render::showAudio(Mlt::Frame& frame)
         return;
     }
     mlt_audio_format audio_format = mlt_audio_s16;
-    int freq = 0;
-    int num_channels = 0;
+    //FIXME: should not be hardcoded..
+    int freq = 48000;
+    int num_channels = 2;
     int samples = 0;
     int16_t* data = (int16_t*)frame.get_audio(audio_format, freq, num_channels, samples);
 
@@ -1874,12 +1886,12 @@ int Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pro
 }
 
 
-void Render::mltCutClip(int track, GenTime position)
+bool Render::mltCutClip(int track, GenTime position)
 {
     Mlt::Service service(m_mltProducer->parent().get_service());
     if (service.type() != tractor_type) {
         kWarning() << "// TRACTOR PROBLEM";
-        return;
+        return false;
     }
 
     Mlt::Tractor tractor(service);
@@ -1902,7 +1914,7 @@ void Render::mltCutClip(int track, GenTime position)
     int clipIndex = trackPlaylist.get_clip_index_at(cutPos);
     if (trackPlaylist.is_blank(clipIndex)) {
         kDebug() << "// WARNING, TRYING TO CUT A BLANK";
-        return;
+        return false;
     }
     service.lock();
     int clipStart = trackPlaylist.clip_start(clipIndex);
@@ -1912,12 +1924,16 @@ void Render::mltCutClip(int track, GenTime position)
     // duplicate effects
     Mlt::Producer *original = trackPlaylist.get_clip_at(clipStart);
     Mlt::Producer *clip = trackPlaylist.get_clip_at(cutPos);
-
+    
     if (original == NULL || clip == NULL) {
         kDebug() << "// ERROR GRABBING CLIP AFTER SPLIT";
+       return false;
     }
+
     Mlt::Service clipService(original->get_service());
     Mlt::Service dupService(clip->get_service());
+
+
     delete original;
     delete clip;
     int ct = 0;
@@ -1939,7 +1955,7 @@ void Render::mltCutClip(int track, GenTime position)
         ct++;
         filter = clipService.filter(ct);
     }
-
+    return true;
     /* // Display playlist info
     kDebug()<<"////////////  AFTER";
     for (int i = 0; i < trackPlaylist.count(); i++) {
@@ -2870,7 +2886,7 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
     }
 
     for (int j = 0; j < params.count(); j++) {
-        filter->set((params.at(j).name()).toUtf8().constData(), params.at(j).value().toUtf8().constData());
+        filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData());
     }
     
     for (int j = 0; j < filtersList.count(); j++) {
@@ -3288,10 +3304,10 @@ void Render::fixAudioMixing(Mlt::Tractor tractor)
     mlt_service_unlock(serv);
 }
 
-bool Render::mltResizeClipCrop(ItemInfo info, GenTime diff)
+bool Render::mltResizeClipCrop(ItemInfo info, GenTime newCropStart)
 {
     Mlt::Service service(m_mltProducer->parent().get_service());
-    int frameOffset = (int) diff.frames(m_fps);
+    int newCropFrame = (int) newCropStart.frames(m_fps);
     Mlt::Tractor tractor(service);
     Mlt::Producer trackProducer(tractor.track(info.track));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
@@ -3310,7 +3326,13 @@ bool Render::mltResizeClipCrop(ItemInfo info, GenTime diff)
     int previousStart = clip->get_in();
     int previousOut = clip->get_out();
     delete clip;
-    trackPlaylist.resize_clip(clipIndex, previousStart + frameOffset, previousOut + frameOffset);
+    if (previousStart == newCropFrame) {
+       kDebug() << "////////  No ReSIZING Required";
+        service.unlock();
+        return true;
+    }
+    int frameOffset = newCropFrame - previousStart;
+    trackPlaylist.resize_clip(clipIndex, newCropFrame, previousOut + frameOffset);
     service.unlock();
     m_mltConsumer->set("refresh", 1);
     return true;
@@ -4397,6 +4419,7 @@ const QString Render::activeClipId()
 //static 
 bool Render::getBlackMagicDeviceList(KComboBox *devicelist)
 {
+    if (!KdenliveSettings::decklink_device_found()) return false;
     Mlt::Profile profile;
     Mlt::Producer bm(profile, "decklink");
     int found_devices = 0;
@@ -4404,6 +4427,7 @@ bool Render::getBlackMagicDeviceList(KComboBox *devicelist)
        bm.set("list_devices", 1);
        found_devices = bm.get_int("devices");
     }
+    else KdenliveSettings::setDecklink_device_found(false);
     if (found_devices <= 0) {
        devicelist->setEnabled(false);
        return false;
@@ -4418,6 +4442,7 @@ bool Render::getBlackMagicDeviceList(KComboBox *devicelist)
 
 bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist)
 {
+    if (!KdenliveSettings::decklink_device_found()) return false;
     Mlt::Profile profile;
     Mlt::Consumer bm(profile, "decklink");
     int found_devices = 0;
@@ -4425,6 +4450,7 @@ bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist)
        bm.set("list_devices", 1);
        found_devices = bm.get_int("devices");
     }
+    else KdenliveSettings::setDecklink_device_found(false);
     if (found_devices <= 0) {
        devicelist->setEnabled(false);
        return false;
@@ -4437,5 +4463,7 @@ bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist)
     return true;
 }
 
+
+
 #include "renderer.moc"