Fix change speed on split clip

parent 10cc2f1c
......@@ -483,12 +483,14 @@ void Core::displayMessage(const QString &message, MessageType type, int timeout)
void Core::clearAssetPanel(int itemId)
{
if (m_guiConstructed) m_mainWindow->clearAssetPanel(itemId);
if (m_guiConstructed)
m_mainWindow->clearAssetPanel(itemId);
}
void Core::adjustAssetRange(int itemId, int in, int out)
{
m_mainWindow->adjustAssetPanelRange(itemId, in, out);
if (m_guiConstructed)
m_mainWindow->adjustAssetPanelRange(itemId, in, out);
}
std::shared_ptr<EffectStackModel> Core::getItemEffectStack(int itemType, int itemId)
......
......@@ -110,11 +110,11 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
QString id(t.get("kdenlive_id"));
QString internal(t.get("internal_added"));
if (internal.isEmpty()) {
compositions << new Mlt::Transition(t);
if (id.isEmpty()) {
qDebug() << "// Warning, this should not happen, transition without id: " << t.get("id") << " = " << t.get("mlt_service");
id = t.get("mlt_service");
t.set("kdenlive_id", t.get("mlt_service"));
}
compositions << new Mlt::Transition(t);
}
}
service.reset(service->producer());
......
......@@ -215,6 +215,29 @@ bool GroupsModel::isInGroup(int id) const
return getRootId(id) != id;
}
int GroupsModel::getSplitPartner(int id) const
{
READ_LOCK();
Q_ASSERT(m_downLink.count(id) > 0);
int groupId = m_upLink.at(id);
if (groupId == -1 || getType(groupId) != GroupType::AVSplit) {
// clip does not have an AV split partner
return -1;
}
std::unordered_set<int> leaves = getDirectChildren(groupId);
if (leaves.size() != 2) {
// clip does not have an AV split partner
qDebug()<<"WRONG SPLIT GROUP SIZE: "<<leaves.size();
return -1;
}
for (const int &child : leaves) {
if (child != id) {
return child;
}
}
return -1;
}
std::unordered_set<int> GroupsModel::getSubtree(int id) const
{
READ_LOCK();
......
......@@ -149,6 +149,7 @@ public:
*/
const QString toJson() const;
bool fromJson(const QString &data);
int getSplitPartner(int id) const;
protected:
/* @brief Destruct a groupItem in the hierarchy.
......
......@@ -2065,39 +2065,69 @@ void TimelineModel::requestClipUpdate(int clipId, const QVector<int> &roles)
notifyChange(modelIndex, modelIndex, roles);
}
bool TimelineModel::requestClipTimeWarp(int clipId, double speed, Fun &undo, Fun &redo)
bool TimelineModel::requestClipTimeWarp(int clipId, int trackId, int blankSpace, double speed, Fun &undo, Fun &redo)
{
QWriteLocker locker(&m_lock);
std::function<bool(void)> local_undo = []() { return true; };
std::function<bool(void)> local_redo = []() { return true; };
qDebug() << "// CHANGING SPEED TO: " << speed;
// in order to make the producer change effective, we need to unplant / replant the clip in int track
int old_trackId = getClipTrackId(clipId);
int oldPos = getClipPosition(clipId);
if (old_trackId != -1) {
int blankSpace = getTrackById(old_trackId)->getBlankSizeNearClip(clipId, true);
qDebug() << "// FOUND BLANK AFTER CLIP: " << blankSpace;
getTrackById(old_trackId)->requestClipDeletion(clipId, true, local_undo, local_redo);
m_allClips[clipId]->useTimewarpProducer(speed, blankSpace, local_undo, local_redo);
getTrackById(old_trackId)->requestClipInsertion(clipId, oldPos, true, local_undo, local_redo);
} else {
m_allClips[clipId]->useTimewarpProducer(speed, -1, local_undo, local_redo);
// in order to make the producer change effective, we need to unplant / replant the clip in int track
bool success = true;
success = getTrackById(trackId)->requestClipDeletion(clipId, true, local_undo, local_redo);
if (success) {
success = m_allClips[clipId]->useTimewarpProducer(speed, blankSpace, local_undo, local_redo);
}
QModelIndex modelIndex = makeClipIndexFromID(clipId);
QVector<int> roles;
roles.push_back(SpeedRole);
notifyChange(modelIndex, modelIndex, roles);
UPDATE_UNDO_REDO(local_redo, local_undo, undo, redo);
return true;
if (success) {
success = getTrackById(trackId)->requestClipInsertion(clipId, oldPos, true, local_undo, local_redo);
}
PUSH_LAMBDA(local_undo, undo);
PUSH_LAMBDA(local_redo, redo);
return success;
}
bool TimelineModel::changeItemSpeed(int clipId, int speed)
{
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool res = requestClipTimeWarp(clipId, speed / 100.0, undo, redo);
if (res) {
// Get main clip info
int trackId = getClipTrackId(clipId);
int splitId = -1;
// Check if clip has a split partner
bool result = true;
if (trackId != -1) {
int blankSpace = getTrackById(trackId)->getBlankSizeNearClip(clipId, true);
splitId = m_groups->getSplitPartner(clipId);
bool success = true;
if (splitId > -1) {
int split_trackId = getClipTrackId(splitId);
blankSpace = qMin(blankSpace, getTrackById(split_trackId)->getBlankSizeNearClip(splitId, true));
result = requestClipTimeWarp(splitId, split_trackId, blankSpace, speed / 100.0, undo, redo);
}
if (result) {
result = requestClipTimeWarp(clipId, trackId, blankSpace, speed / 100.0, undo, redo);
}
} else {
m_allClips[clipId]->useTimewarpProducer(speed, -1, undo, redo);
}
if (result) {
QVector<int> roles;
roles.push_back(SpeedRole);
Fun update_model = [clipId, roles, this]() {
QModelIndex modelIndex = makeClipIndexFromID(clipId);
notifyChange(modelIndex, modelIndex, roles);
return true;
};
PUSH_LAMBDA(update_model, undo);
PUSH_LAMBDA(update_model, redo);
if (splitId > -1) {
Fun update_model2 = [splitId, roles, this]() {
QModelIndex modelIndex = makeClipIndexFromID(splitId);
notifyChange(modelIndex, modelIndex, roles);
return true;
};
PUSH_LAMBDA(update_model2, undo);
PUSH_LAMBDA(update_model2, redo);
}
PUSH_UNDO(undo, redo, i18n("Change clip speed"));
return true;
}
......
......@@ -497,7 +497,7 @@ public:
std::shared_ptr<EffectStackModel> getTrackEffectStackModel(int trackId);
/** @brief Add slowmotion effect to clip in timeline. */
bool requestClipTimeWarp(int clipId, double speed, Fun &undo, Fun &redo);
bool requestClipTimeWarp(int clipId, int trackId, int blankSpace, double speed, Fun &undo, Fun &redo);
bool changeItemSpeed(int clipId, int speed);
void replugClip(int clipId);
......
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