From: Jean-Baptiste Mardelle Date: Fri, 21 Oct 2011 17:10:46 +0000 (+0000) Subject: Fix freeze on split audio and other stuff (bad service locking) X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=492d385f45df2bb1c67dcac7d7c541fa1b52a125;p=kdenlive Fix freeze on split audio and other stuff (bad service locking) svn path=/trunk/kdenlive/; revision=5975 --- diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index ebe5144d..428612df 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -2663,7 +2663,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) m_selectionGroup->translate(0, m_tracksHeight); // adjust track number - m_document->renderer()->lock(); + Mlt::Tractor *tractor = m_document->renderer()->lockService(); QList children = m_selectionGroup->childItems(); for (int i = 0; i < children.count(); i++) { if (children.at(i)->type() == GROUPWIDGET) { @@ -2681,7 +2681,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) // We add a move clip command so that we get the correct producer for new track number if (clip->clipType() == AV || clip->clipType() == AUDIO) { Mlt::Producer *prod = clip->getProducer(clipinfo.track); - if (m_document->renderer()->mltUpdateClipProducer((int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), prod) == false) { + if (m_document->renderer()->mltUpdateClipProducer(tractor, (int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), prod) == false) { // problem updating clip emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", clipinfo.startPos.frames(m_document->fps()), clipinfo.track), ErrorMessage); } @@ -2695,7 +2695,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) } } resetSelectionGroup(false); - m_document->renderer()->unlock(); + m_document->renderer()->unlockService(tractor); } int maxHeight = m_tracksHeight * m_document->tracksCount() * matrix().m22(); @@ -2737,7 +2737,7 @@ void CustomTrackView::removeTrack(int ix) // Move graphic items qreal ydiff = 0 - (int) m_tracksHeight; m_selectionGroup->translate(0, ydiff); - m_document->renderer()->lock(); + Mlt::Tractor *tractor = m_document->renderer()->lockService(); // adjust track number QList children = m_selectionGroup->childItems(); @@ -2755,7 +2755,7 @@ void CustomTrackView::removeTrack(int ix) // We add a move clip command so that we get the correct producer for new track number if (clip->clipType() == AV || clip->clipType() == AUDIO || clip->clipType() == PLAYLIST) { Mlt::Producer *prod = clip->getProducer(clipinfo.track); - if (prod == NULL || !m_document->renderer()->mltUpdateClipProducer((int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), prod)) { + if (prod == NULL || !m_document->renderer()->mltUpdateClipProducer(tractor, (int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), prod)) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", clipinfo.startPos.frames(m_document->fps()), clipinfo.track), ErrorMessage); } } @@ -2770,7 +2770,7 @@ void CustomTrackView::removeTrack(int ix) } } resetSelectionGroup(false); - m_document->renderer()->unlock(); + m_document->renderer()->unlockService(tractor); int maxHeight = m_tracksHeight * m_document->tracksCount() * matrix().m22(); for (int i = 0; i < m_guides.count(); i++) { @@ -4180,7 +4180,7 @@ void CustomTrackView::slotUpdateClip(const QString &clipId, bool reload) QList clipList; ClipItem *clip = NULL; DocClipBase *baseClip = NULL; - m_document->renderer()->lock(); + Mlt::Tractor *tractor = m_document->renderer()->lockService(); for (int i = 0; i < list.size(); ++i) { if (list.at(i)->type() == AVWIDGET) { clip = static_cast (list.at(i)); @@ -4193,14 +4193,14 @@ void CustomTrackView::slotUpdateClip(const QString &clipId, bool reload) if (clip->isAudioOnly()) prod = baseClip->audioProducer(info.track); else if (clip->isVideoOnly()) prod = baseClip->videoProducer(); else prod = baseClip->getProducer(info.track); - if (reload && !m_document->renderer()->mltUpdateClip(info, clip->xml(), prod)) { + if (reload && !m_document->renderer()->mltUpdateClip(tractor, info, clip->xml(), prod)) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", info.startPos.frames(m_document->fps()), info.track), ErrorMessage); } else clipList.append(clip); } } } - m_document->renderer()->unlock(); + m_document->renderer()->unlockService(tractor); for (int i = 0; i < clipList.count(); i++) clipList.at(i)->refreshClip(true, true); if (baseClip) { @@ -6009,15 +6009,15 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, EffectsList ef clip->setSelected(true); ClipItem *audioClip = getClipItemAt(start, info.track); if (audioClip) { - m_document->renderer()->lock(); + Mlt::Tractor *tractor = m_document->renderer()->lockService(); clip->setVideoOnly(true); - if (m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->videoProducer()) == false) { + if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - track, start, clip->baseClip()->videoProducer()) == false) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, track), ErrorMessage); } - if (m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - info.track, start, clip->baseClip()->audioProducer(info.track)) == false) { + if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - info.track, start, clip->baseClip()->audioProducer(info.track)) == false) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, info.track), ErrorMessage); } - m_document->renderer()->unlock(); + m_document->renderer()->unlockService(tractor); audioClip->setSelected(true); audioClip->setAudioOnly(true); @@ -6055,11 +6055,11 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, EffectsList ef ItemInfo info = clip->info(); deleteClip(clp->info()); clip->setVideoOnly(false); - m_document->renderer()->lock(); - if (!m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - info.track, info.startPos.frames(m_document->fps()), clip->baseClip()->getProducer(info.track))) { + Mlt::Tractor *tractor = m_document->renderer()->lockService(); + if (!m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - info.track, info.startPos.frames(m_document->fps()), clip->baseClip()->getProducer(info.track))) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", info.startPos.frames(m_document->fps()), info.track), ErrorMessage); } - m_document->renderer()->unlock(); + m_document->renderer()->unlockService(tractor); // re-add audio effects for (int i = 0; i < effects.count(); ++i) { @@ -6159,32 +6159,30 @@ void CustomTrackView::doChangeClipType(const GenTime &pos, int track, bool video kDebug() << "// Cannot find clip to split!!!"; return; } + Mlt::Tractor *tractor = m_document->renderer()->lockService(); if (videoOnly) { int start = pos.frames(m_document->fps()); clip->setVideoOnly(true); clip->setAudioOnly(false); - m_document->renderer()->lock(); - if (m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->videoProducer()) == false) { + if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - track, start, clip->baseClip()->videoProducer()) == false) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, track), ErrorMessage); } - m_document->renderer()->unlock(); } else if (audioOnly) { int start = pos.frames(m_document->fps()); clip->setAudioOnly(true); clip->setVideoOnly(false); - m_document->renderer()->lock(); - if (m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->audioProducer(track)) == false) { + if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - track, start, clip->baseClip()->audioProducer(track)) == false) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, track), ErrorMessage); } - m_document->renderer()->unlock(); } else { int start = pos.frames(m_document->fps()); clip->setAudioOnly(false); clip->setVideoOnly(false); - if (m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->getProducer(track)) == false) { + if (m_document->renderer()->mltUpdateClipProducer(tractor, m_document->tracksCount() - track, start, clip->baseClip()->getProducer(track)) == false) { emit displayMessage(i18n("Cannot update clip (time: %1, track: %2)", start, track), ErrorMessage); } } + m_document->renderer()->unlockService(tractor); clip->update(); setDocumentModified(); } diff --git a/src/renderer.cpp b/src/renderer.cpp index 1b7fdbec..16078ff1 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1812,19 +1812,22 @@ void Render::mltCutClip(int track, GenTime position) } -void Render::lock() +Mlt::Tractor *Render::lockService() { - if (!m_mltProducer) return; + if (!m_mltProducer) return NULL; Mlt::Service service(m_mltProducer->parent().get_service()); if (service.type() != tractor_type) { kWarning() << "// TRACTOR PROBLEM"; - return; + return NULL; } service.lock(); + return new Mlt::Tractor(service); + } -void Render::unlock() +void Render::unlockService(Mlt::Tractor *tractor) { + if (tractor) delete tractor; if (!m_mltProducer) return; Mlt::Service service(m_mltProducer->parent().get_service()); if (service.type() != tractor_type) { @@ -1834,21 +1837,15 @@ void Render::unlock() service.unlock(); } -bool Render::mltUpdateClip(ItemInfo info, QDomElement element, Mlt::Producer *prod) +bool Render::mltUpdateClip(Mlt::Tractor *tractor, ItemInfo info, QDomElement element, Mlt::Producer *prod) { // TODO: optimize - if (prod == NULL) { + if (prod == NULL || tractor == NULL) { kDebug() << "Cannot update clip with null producer //////"; return false; } - Mlt::Service service(m_mltProducer->parent().get_service()); - if (service.type() != tractor_type) { - kWarning() << "// TRACTOR PROBLEM"; - return false; - } - Mlt::Tractor tractor(service); - Mlt::Producer trackProducer(tractor.track(tractor.count() - 1 - info.track)); + Mlt::Producer trackProducer(tractor->track(tractor->count() - 1 - info.track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); int startPos = info.startPos.frames(m_fps); int clipIndex = trackPlaylist.get_clip_index_at(startPos); @@ -3164,35 +3161,26 @@ bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTim } -bool Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod) +bool Render::mltUpdateClipProducer(Mlt::Tractor *tractor, int track, int pos, Mlt::Producer *prod) { - if (prod == NULL || !prod->is_valid()) { + if (prod == NULL || !prod->is_valid() || tractor == NULL || !tractor->is_valid()) { kDebug() << "// Warning, CLIP on track " << track << ", at: " << pos << " is invalid, cannot update it!!!"; return false; } - //kDebug() << "// TRYING TO UPDATE CLIP at: " << pos << ", TK: " << track; - Mlt::Service service(m_mltProducer->parent().get_service()); - if (service.type() != tractor_type) { - kWarning() << "// TRACTOR PROBLEM"; - return false; - } - service.lock(); - Mlt::Tractor tractor(service); - Mlt::Producer trackProducer(tractor.track(track)); + + Mlt::Producer trackProducer(tractor->track(track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); int clipIndex = trackPlaylist.get_clip_index_at(pos); Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex); if (clipProducer == NULL || clipProducer->is_blank()) { kDebug() << "// ERROR UPDATING CLIP PROD"; delete clipProducer; - service.unlock(); return false; } Mlt::Producer *clip = prod->cut(clipProducer->get_in(), clipProducer->get_out()); if (!clip || !clip->is_valid()) { if (clip) delete clip; delete clipProducer; - service.unlock(); return false; } // move all effects to the correct producer @@ -3200,7 +3188,6 @@ bool Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod) trackPlaylist.insert_at(pos, clip, 1); delete clip; delete clipProducer; - service.unlock(); return true; } diff --git a/src/renderer.h b/src/renderer.h index d93b579d..f6298504 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -201,7 +201,7 @@ Q_OBJECT public: */ Mlt::Producer *checkSlowMotionProducer(Mlt::Producer *prod, QDomElement element); int mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *prod, bool overwrite = false, bool push = false); - bool mltUpdateClip(ItemInfo info, QDomElement element, Mlt::Producer *prod); + bool mltUpdateClip(Mlt::Tractor *tractor, ItemInfo info, QDomElement element, Mlt::Producer *prod); void mltCutClip(int track, GenTime position); void mltInsertSpace(QMap trackClipStartList, QMap trackTransitionStartList, int track, const GenTime &duration, const GenTime &timeOffset); int mltGetSpaceLength(const GenTime &pos, int track, bool fromBlankStart); @@ -252,7 +252,7 @@ Q_OBJECT public: void mltResizeTransparency(int oldStart, int newStart, int newEnd, int track, int id); void mltInsertTrack(int ix, bool videoTrack); void mltDeleteTrack(int ix); - bool mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod); + bool mltUpdateClipProducer(Mlt::Tractor *tractor, int track, int pos, Mlt::Producer *prod); void mltPlantTransition(Mlt::Field *field, Mlt::Transition &tr, int a_track, int b_track); Mlt::Producer *invalidProducer(const QString &id); @@ -294,9 +294,9 @@ Q_OBJECT public: void getFileProperties(const QDomElement &xml, const QString &clipId, int imageHeight, bool replaceProducer = true); /** @brief Lock the MLT service */ - void lock(); + Mlt::Tractor *lockService(); /** @brief Unlock the MLT service */ - void unlock(); + void unlockService(Mlt::Tractor *tractor); private: