Various fixes for composition length calculation. Related to #427

parent 72c1fab0
Pipeline #10107 passed with stage
in 24 minutes and 44 seconds
......@@ -398,22 +398,44 @@ int TrackModel::suggestCompositionLength(int position)
if (other_index < m_playlists[other_track].count()) {
end_pos = std::min(end_pos, m_playlists[other_track].clip_start(other_index) + m_playlists[other_track].clip_length(other_index));
}
int min = -1;
std::unordered_set<int> existing = getCompositionsInRange(position, end_pos);
if (existing.size() > 0) {
return end_pos - position;
}
QPair <int, int> TrackModel::validateCompositionLength(int pos, int offset, int duration, int endPos)
{
int startPos = pos;
bool startingFromOffset = false;
if (duration < offset) {
startPos += offset;
startingFromOffset = true;
if (startPos + duration > endPos) {
startPos = endPos - duration;
}
}
int compsitionEnd = startPos + duration;
std::unordered_set<int> existing;
if (startingFromOffset) {
existing = getCompositionsInRange(startPos, compsitionEnd);
for (int id : existing) {
if (min < 0) {
min = m_allCompositions[id]->getPosition();
} else {
min = qMin(min, m_allCompositions[id]->getPosition());
if (m_allCompositions[id]->getPosition() < startPos) {
int end = m_allCompositions[id]->getPosition() + m_allCompositions[id]->getPlaytime();
startPos = qMax(startPos, end);
}
}
} else if (offset > 0) {
existing = getCompositionsInRange(startPos, startPos + offset);
for (int id : existing) {
int end = m_allCompositions[id]->getPosition() + m_allCompositions[id]->getPlaytime();
startPos = qMax(startPos, end);
}
}
if (min >= 0) {
// An existing composition is limiting the space
end_pos = min;
existing = getCompositionsInRange(startPos, compsitionEnd);
for (int id : existing) {
int start = m_allCompositions[id]->getPosition();
compsitionEnd = qMin(compsitionEnd, start);
}
return end_pos - position;
return {startPos, compsitionEnd - startPos};
}
int TrackModel::getBlankSizeNearClip(int clipId, bool after)
......@@ -727,6 +749,7 @@ std::unordered_set<int> TrackModel::getCompositionsInRange(int position, int end
continue;
}
if (pos >= position || pos + length - 1 >= position) {
ids.insert(compo.first);
}
}
......
......@@ -190,6 +190,8 @@ protected:
/*@brief Returns the best composition duration depending on clips on the track */
int suggestCompositionLength(int position);
/*@brief Returns the best composition duration depending on compositions on the track */
QPair <int, int> validateCompositionLength(int pos, int offset, int duration, int endPos);
/*@brief Returns the (unique) construction id of the track*/
int getId() const;
......
......@@ -351,65 +351,54 @@ int TimelineController::insertNewComposition(int tid, int position, const QStrin
int TimelineController::insertNewComposition(int tid, int clipId, int offset, const QString &transitionId, bool logUndo)
{
int id;
int minimum = m_model->getClipPosition(clipId);
int minimumPos = m_model->getClipPosition(clipId);
int clip_duration = m_model->getClipPlaytime(clipId);
int position = minimum;
bool adjustOffset = false;
if (offset > clip_duration / 2) {
position += offset;
adjustOffset = true;
} else {
// Check if we have a composition at beginning
std::unordered_set<int> existing = m_model->getTrackById_const(tid)->getCompositionsInRange(minimum, minimum + offset);
if (existing.size() > 0) {
position += offset;
}
}
position = qMin(minimum + clip_duration - 1, position);
int endPos = minimumPos + clip_duration;
int position = minimumPos;
int duration = qMin(pCore->currentDoc()->getFramePos(KdenliveSettings::transition_duration()), m_model->getTrackById_const(tid)->suggestCompositionLength(position));
int lowerVideoTrackId = m_model->getPreviousVideoTrackIndex(tid);
bool revert = offset > clip_duration / 2;
if (lowerVideoTrackId > 0) {
int bottomId = m_model->getTrackById_const(lowerVideoTrackId)->getClipByPosition(position);
int bottomId = m_model->getTrackById_const(lowerVideoTrackId)->getClipByPosition(position + offset);
if (bottomId > 0) {
QPair<int, int> bottom(m_model->m_allClips[bottomId]->getPosition(), m_model->m_allClips[bottomId]->getPlaytime());
if (bottom.first > minimum) {
if (bottom.first > minimumPos) {
// Lower clip is after top clip
if (position > bottom.first) {
if (position + offset > bottom.first) {
int test_duration = m_model->getTrackById_const(tid)->suggestCompositionLength(bottom.first);
if (test_duration > 0) {
offset -= (bottom.first - position);
position = bottom.first;
duration = test_duration;
revert = position > minimum;
revert = position > minimumPos;
}
}
} else if (position >= bottom.first) {
if (adjustOffset) {
position -= offset;
}
// Lower clip is before or at same pos as top clip
int test_duration = m_model->getTrackById_const(lowerVideoTrackId)->suggestCompositionLength(position);
if (test_duration > 0) {
duration = qMin(test_duration, clip_duration);
}
}
} else if (!adjustOffset) {
// No clip below, keep original drop position
position += offset;
}
int duration2 = m_model->getTrackById_const(lowerVideoTrackId)->suggestCompositionLength(position);
if (duration2 > 0) {
duration = (duration > 0) ? qMin(duration, duration2) : duration2;
} else {
qDebug()<<"///// NO CLIP FOUND BELOW!!!";
}
} else {
qDebug()<<"///// NO TRACK FOUND BELOW!!!";
}
if (duration < 0) {
duration = pCore->currentDoc()->getFramePos(KdenliveSettings::transition_duration());
} else if (duration <= 1) {
// if suggested composition duration is lower than 4 frames, use default
duration = pCore->currentDoc()->getFramePos(KdenliveSettings::transition_duration());
if (minimum + clip_duration - position < 3) {
position = minimum + clip_duration - duration;
if (minimumPos + clip_duration - position < 3) {
position = minimumPos + clip_duration - duration;
}
}
QPair<int, int> finalPos = m_model->getTrackById_const(tid)->validateCompositionLength(position, offset, duration, endPos);
position = finalPos.first;
duration = finalPos.second;
std::unique_ptr<Mlt::Properties> props(nullptr);
if (revert) {
props = std::make_unique<Mlt::Properties>();
......
Markdown is supported
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