Commit b75772bb authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix loading projects with corrupted mix (remove mix and broken clip). Related to #1499

parent 0bae6322
Pipeline #215208 failed with stage
in 5 minutes and 43 seconds
......@@ -196,7 +196,9 @@ void NotesWidget::createMarkers()
void NotesWidget::addProjectNote()
{
if (!textCursor().atBlockStart()) {
textCursor().movePosition(QTextCursor::EndOfBlock);
QTextCursor cur = textCursor();
cur.movePosition(QTextCursor::EndOfBlock);
setTextCursor(cur);
insertPlainText(QStringLiteral("\n"));
}
emit insertNotesTimecode();
......@@ -204,9 +206,10 @@ void NotesWidget::addProjectNote()
void NotesWidget::addTextNote(const QString &text)
{
if (!textCursor().atBlockStart()) {
textCursor().movePosition(QTextCursor::EndOfBlock);
insertPlainText(QStringLiteral("\n"));
if (!textCursor().atEnd()) {
QTextCursor cur = textCursor();
cur.movePosition(QTextCursor::End);
setTextCursor(cur);
}
emit insertTextNote(text);
}
......
......@@ -341,7 +341,36 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
}
// Load same track mixes
for (auto compo : qAsConst(compositions)) {
timeline->plantMix(tid, compo);
if (!timeline->plantMix(tid, compo)) {
// There is an error with a mix, we have overlapping clips
int in = compo->get_in();
int out = compo->get_out() - 1;
bool reverse = compo->get_int("reverse") == 1;
int cid1 = timeline->getClipByPosition(tid, in, reverse ? 1 : 0);
int cid2 = timeline->getClipByPosition(tid, out, reverse ? 0 : 1);
if (cid1 > 0 && cid2 > 0) {
if (timeline->getClipSubPlaylistIndex(cid1) == 1) {
// Delete clip
QString tcInfo = QString("<a href=\"%1?%2\">%3 %4</a>")
.arg(QString::number(in), QString::number(timeline->getTrackPosition(tid) + 1), timeline->getTrackTagById(tid),
pCore->timecode().getTimecodeFromFrames(timeline->getClipPosition(cid1)));
m_notesLog << i18n("Incorrect Mix, clip %1 was removed at %2.", timeline->getClipName(cid1), tcInfo);
m_errorMessage << i18n("Incorrect mix found on track %1 at %2, clip %3 removed.", timeline->getTrackTagById(tid),
pCore->timecode().getTimecodeFromFrames(timeline->getClipPosition(cid1)), timeline->getClipName(cid1));
timeline->requestItemDeletion(cid1, false);
} else if (timeline->getClipSubPlaylistIndex(cid2) == 1) {
// Delete clip
QString tcInfo = QString("<a href=\"%1?%2\">%3 %4</a>")
.arg(QString::number(in), QString::number(timeline->getTrackPosition(tid) + 1), timeline->getTrackTagById(tid),
pCore->timecode().getTimecodeFromFrames(timeline->getClipPosition(cid2)));
m_notesLog << i18n("Incorrect Mix, clip %1 was removed at %2.", timeline->getClipName(cid2), tcInfo);
m_errorMessage << i18n("Incorrect mix found at track %1 at %2, clip %3 removed.", timeline->getTrackTagById(tid),
pCore->timecode().getTimecodeFromFrames(timeline->getClipPosition(cid2)), timeline->getClipName(cid2));
timeline->requestItemDeletion(cid2, false);
}
}
}
}
std::shared_ptr<Mlt::Service> serv = std::make_shared<Mlt::Service>(track.get_service());
timeline->importTrackEffects(tid, serv);
......
......@@ -362,11 +362,11 @@ int TimelineModel::getClipByStartPosition(int trackId, int position) const
return getTrackById_const(trackId)->getClipByStartPosition(position);
}
int TimelineModel::getClipByPosition(int trackId, int position) const
int TimelineModel::getClipByPosition(int trackId, int position, int playlist) const
{
READ_LOCK();
Q_ASSERT(isTrack(trackId));
return getTrackById_const(trackId)->getClipByPosition(position);
return getTrackById_const(trackId)->getClipByPosition(position, playlist);
}
int TimelineModel::getCompositionByPosition(int trackId, int position) const
......@@ -4885,6 +4885,18 @@ int TimelineModel::getItemPosition(int itemId) const
return -1;
}
int TimelineModel::getClipSubPlaylistIndex(int cid) const
{
Q_ASSERT(isClip(cid));
return m_allClips.at(cid)->getSubPlaylistIndex();
}
const QString TimelineModel::getClipName(int cid) const
{
Q_ASSERT(isClip(cid));
return m_allClips.at(cid)->clipName();
}
int TimelineModel::getItemPlaytime(int itemId) const
{
if (isClip(itemId)) {
......@@ -6150,13 +6162,14 @@ void TimelineModel::switchComposition(int cid, const QString &compoId)
}
}
void TimelineModel::plantMix(int tid, Mlt::Transition *t)
bool TimelineModel::plantMix(int tid, Mlt::Transition *t)
{
if (getTrackById_const(tid)->hasClipStart(t->get_in())) {
getTrackById_const(tid)->getTrackService()->plant_transition(*t, 0, 1);
getTrackById_const(tid)->loadMix(t);
return getTrackById_const(tid)->loadMix(t);
} else {
qDebug() << "=== INVALID MIX FOUND AT: " << t->get_in() << " - " << t->get("mlt_service");
return false;
}
}
......@@ -6364,11 +6377,16 @@ void TimelineModel::requestResizeMix(int cid, int duration, MixAlignment align,
}
int deltaLeft = m_allClips.at(clipToResize)->getPosition() + updatedDurationLeft - cutPos;
int deltaRight = cutPos - (m_allClips.at(cid)->getPosition() + m_allClips.at(cid)->getPlaytime() - updatedDurationRight);
if (deltaRight) {
requestItemResize(cid, updatedDurationRight, false, true, undo, redo);
if (!requestItemResize(cid, updatedDurationRight, false, true, undo, redo)) {
qDebug() << ":::: ERROR RESIZING CID1\n\nAAAAAAAAAAAAAAAAAAAA";
}
}
if (deltaLeft > 0) {
requestItemResize(clipToResize, updatedDurationLeft, true, true, undo, redo);
if (!requestItemResize(clipToResize, updatedDurationLeft, true, true, undo, redo)) {
qDebug() << ":::: ERROR RESIZING clipToResize\n\nAAAAAAAAAAAAAAAAAAAA";
}
}
int mixCutPos = m_allClips.at(clipToResize)->getPosition() + m_allClips.at(clipToResize)->getPlaytime() - cutPos;
if (mixCutPos > updatedDuration) {
......
......@@ -219,6 +219,11 @@ public:
/** @brief Returns an item duration, item can be clip or composition */
int getItemPlaytime(int itemId) const;
/** @brief Returns the subplaylist index of a clip in a track */
int getClipSubPlaylistIndex(int cid) const;
/** @brief Returns the name of a timeline clip */
const QString getClipName(int cid) const;
/** @brief Returns the current speed of a clip */
double getClipSpeed(int clipId) const;
......@@ -441,7 +446,7 @@ public:
void switchComposition(int cid, const QString &compoId);
/** @brief Plant a same track composition in track tid
*/
void plantMix(int tid, Mlt::Transition *t);
bool plantMix(int tid, Mlt::Transition *t);
bool removeMixWithUndo(int cid, Fun &undo, Fun &redo);
bool removeMix(int cid);
/** @brief Returns a list of the master effects zones
......@@ -684,7 +689,7 @@ public:
/** @brief Get a timeline clip id by its position or -1 if not found
*/
int getClipByPosition(int trackId, int position) const;
int getClipByPosition(int trackId, int position, int playlist = -1) const;
int getClipByStartPosition(int trackId, int position) const;
/** @brief Get a timeline composition id by its starting position or -1 if not found
......
......@@ -2499,8 +2499,20 @@ bool TrackModel::loadMix(Mlt::Transition *t)
} else {
int firstClipIn = m_allClips[cid1]->getPosition();
if (in == firstClipIn && in != m_allClips[cid2]->getPosition()) {
// Incorrecty detected revert mix
std::swap(cid1, cid2);
qDebug() << "/// SWAPPING CLIPS";
if (m_allClips[cid1]->getPosition() > m_allClips[cid2]->getPosition()) {
// Incorrecty detected revert mix
std::swap(cid1, cid2);
}
}
if (m_allClips[cid1]->getPosition() > m_allClips[cid2]->getPosition() ||
(m_allClips[cid1]->getPosition() + m_allClips[cid1]->getPlaytime()) > (m_allClips[cid2]->getPosition() + m_allClips[cid2]->getPlaytime())) {
// Impossible mix, remove
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
field->disconnect_service(*t);
field->unlock();
return false;
}
}
// Ensure in/out points are in sync with the clips
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment