Commit ab676e76 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Merge branch 'refactoring_timeline'

parents 5b9fc490 2601108c
Pipeline #1430 failed with stage
in 19 minutes and 57 seconds
...@@ -534,31 +534,35 @@ void ProjectClip::createDisabledMasterProducer() ...@@ -534,31 +534,35 @@ void ProjectClip::createDisabledMasterProducer()
m_effectStack->addService(m_disabledProducer); m_effectStack->addService(m_disabledProducer);
} }
} }
std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int clipId, PlaylistState::ClipState state, double speed)
std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int trackId, int clipId, PlaylistState::ClipState state, double speed)
{ {
if (!m_masterProducer) { if (!m_masterProducer) {
return nullptr; return nullptr;
} }
if (qFuzzyCompare(speed, 1.0)) { if (qFuzzyCompare(speed, 1.0)) {
// we are requesting a normal speed producer // we are requesting a normal speed producer
// We can first cleen the speed producers we have for the current id if (trackId == -1) {
// Temporary copy, return clone of master
return std::shared_ptr<Mlt::Producer>(m_masterProducer->cut());
}
if (m_timewarpProducers.count(clipId) > 0) { if (m_timewarpProducers.count(clipId) > 0) {
m_effectStack->removeService(m_timewarpProducers[clipId]); m_effectStack->removeService(m_timewarpProducers[clipId]);
m_timewarpProducers.erase(clipId); m_timewarpProducers.erase(clipId);
} }
if (state == PlaylistState::AudioOnly) { if (state == PlaylistState::AudioOnly) {
// We need to get an audio producer, if none exists // We need to get an audio producer, if none exists
if (m_audioProducers.count(clipId) == 0) { if (m_audioProducers.count(trackId) == 0) {
m_audioProducers[clipId] = cloneProducer(true); m_audioProducers[trackId] = cloneProducer(true);
m_audioProducers[clipId]->set("set.test_audio", 0); m_audioProducers[trackId]->set("set.test_audio", 0);
m_audioProducers[clipId]->set("set.test_image", 1); m_audioProducers[trackId]->set("set.test_image", 1);
m_effectStack->addService(m_audioProducers[clipId]); m_effectStack->addService(m_audioProducers[trackId]);
} }
return std::shared_ptr<Mlt::Producer>(m_audioProducers[clipId]->cut()); return std::shared_ptr<Mlt::Producer>(m_audioProducers[trackId]->cut());
} }
if (m_audioProducers.count(clipId) > 0) { if (m_audioProducers.count(trackId) > 0) {
m_effectStack->removeService(m_audioProducers[clipId]); m_effectStack->removeService(m_audioProducers[trackId]);
m_audioProducers.erase(clipId); m_audioProducers.erase(trackId);
} }
if (state == PlaylistState::VideoOnly) { if (state == PlaylistState::VideoOnly) {
// we return the video producer // we return the video producer
...@@ -567,18 +571,18 @@ std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int clipId, Play ...@@ -567,18 +571,18 @@ std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int clipId, Play
int duration = m_masterProducer->time_to_frames(m_masterProducer->get("kdenlive:duration")); int duration = m_masterProducer->time_to_frames(m_masterProducer->get("kdenlive:duration"));
return std::shared_ptr<Mlt::Producer>(m_masterProducer->cut(-1, duration > 0 ? duration : -1)); return std::shared_ptr<Mlt::Producer>(m_masterProducer->cut(-1, duration > 0 ? duration : -1));
} }
if (m_videoProducers.count(clipId) == 0) { if (m_videoProducers.count(trackId) == 0) {
m_videoProducers[clipId] = cloneProducer(true); m_videoProducers[trackId] = cloneProducer(true);
m_videoProducers[clipId]->set("set.test_audio", 1); m_videoProducers[trackId]->set("set.test_audio", 1);
m_videoProducers[clipId]->set("set.test_image", 0); m_videoProducers[trackId]->set("set.test_image", 0);
m_effectStack->addService(m_videoProducers[clipId]); m_effectStack->addService(m_videoProducers[trackId]);
} }
int duration = m_masterProducer->time_to_frames(m_masterProducer->get("kdenlive:duration")); int duration = m_masterProducer->time_to_frames(m_masterProducer->get("kdenlive:duration"));
return std::shared_ptr<Mlt::Producer>(m_videoProducers[clipId]->cut(-1, duration > 0 ? duration : -1)); return std::shared_ptr<Mlt::Producer>(m_videoProducers[trackId]->cut(-1, duration > 0 ? duration : -1));
} }
if (m_videoProducers.count(clipId) > 0) { if (m_videoProducers.count(trackId) > 0) {
m_effectStack->removeService(m_videoProducers[clipId]); m_effectStack->removeService(m_videoProducers[trackId]);
m_videoProducers.erase(clipId); m_videoProducers.erase(trackId);
} }
Q_ASSERT(state == PlaylistState::Disabled); Q_ASSERT(state == PlaylistState::Disabled);
createDisabledMasterProducer(); createDisabledMasterProducer();
...@@ -586,16 +590,7 @@ std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int clipId, Play ...@@ -586,16 +590,7 @@ std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int clipId, Play
return std::shared_ptr<Mlt::Producer>(m_disabledProducer->cut(-1, duration > 0 ? duration : -1)); return std::shared_ptr<Mlt::Producer>(m_disabledProducer->cut(-1, duration > 0 ? duration : -1));
} }
// in that case, we need to create a warp producer, if we don't have one // For timewarp clips, we keep one separate producer for each clip.
if (m_audioProducers.count(clipId) > 0) {
m_effectStack->removeService(m_audioProducers[clipId]);
m_audioProducers.erase(clipId);
}
if (m_videoProducers.count(clipId) > 0) {
m_effectStack->removeService(m_videoProducers[clipId]);
m_videoProducers.erase(clipId);
}
std::shared_ptr<Mlt::Producer> warpProducer; std::shared_ptr<Mlt::Producer> warpProducer;
if (m_timewarpProducers.count(clipId) > 0) { if (m_timewarpProducers.count(clipId) > 0) {
// remove in all cases, we add it unconditionally anyways // remove in all cases, we add it unconditionally anyways
...@@ -656,7 +651,7 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim ...@@ -656,7 +651,7 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim
if (state != PlaylistState::Disabled || timeWarp) { if (state != PlaylistState::Disabled || timeWarp) {
// In that case, we must create copies // In that case, we must create copies
std::shared_ptr<Mlt::Producer> prod(getTimelineProducer(clipId, state, speed)->cut(in, out)); std::shared_ptr<Mlt::Producer> prod(getTimelineProducer(-1, clipId, state, speed)->cut(in, out));
return {prod, false}; return {prod, false};
} }
if (state == PlaylistState::Disabled && !m_disabledProducer) { if (state == PlaylistState::Disabled && !m_disabledProducer) {
...@@ -704,7 +699,7 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim ...@@ -704,7 +699,7 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim
if (QString::fromUtf8(master->parent().get("mlt_service")) == QLatin1String("timewarp")) { if (QString::fromUtf8(master->parent().get("mlt_service")) == QLatin1String("timewarp")) {
speed = master->get_double("warp_speed"); speed = master->get_double("warp_speed");
} }
return {getTimelineProducer(clipId, state, speed), false}; return {getTimelineProducer(-1, clipId, state, speed), false};
} }
// we have a problem // we have a problem
return {std::shared_ptr<Mlt::Producer>(ClipController::mediaUnavailable->cut()), false}; return {std::shared_ptr<Mlt::Producer>(ClipController::mediaUnavailable->cut()), false};
......
...@@ -202,7 +202,7 @@ public: ...@@ -202,7 +202,7 @@ public:
/** @brief This function returns a cut to the master producer associated to the timeline clip with given ID. /** @brief This function returns a cut to the master producer associated to the timeline clip with given ID.
Each clip must have a different master producer (see comment of the class) Each clip must have a different master producer (see comment of the class)
*/ */
std::shared_ptr<Mlt::Producer> getTimelineProducer(int clipId, PlaylistState::ClipState st, double speed = 1.0); std::shared_ptr<Mlt::Producer> getTimelineProducer(int trackId, int clipId, PlaylistState::ClipState st, double speed = 1.0);
/* @brief This function should only be used at loading. It takes a producer that was read from mlt, and checks whether the master producer is already in /* @brief This function should only be used at loading. It takes a producer that was read from mlt, and checks whether the master producer is already in
use. If yes, then we must create a new one, because of the mixing bug. In any case, we return a cut of the master that can be used in the timeline The use. If yes, then we must create a new one, because of the mixing bug. In any case, we return a cut of the master that can be used in the timeline The
......
...@@ -75,7 +75,7 @@ int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QSt ...@@ -75,7 +75,7 @@ int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QSt
videoAudio.first = videoAudio.first && binClip->hasVideo(); videoAudio.first = videoAudio.first && binClip->hasVideo();
videoAudio.second = videoAudio.second && binClip->hasAudio(); videoAudio.second = videoAudio.second && binClip->hasAudio();
state = stateFromBool(videoAudio); state = stateFromBool(videoAudio);
std::shared_ptr<Mlt::Producer> cutProducer = binClip->getTimelineProducer(id, state, speed); std::shared_ptr<Mlt::Producer> cutProducer = binClip->getTimelineProducer(-1, id, state, speed);
std::shared_ptr<ClipModel> clip(new ClipModel(parent, cutProducer, binClipId, id, state, speed)); std::shared_ptr<ClipModel> clip(new ClipModel(parent, cutProducer, binClipId, id, state, speed));
clip->setClipState_lambda(state)(); clip->setClipState_lambda(state)();
parent->registerClip(clip); parent->registerClip(clip);
...@@ -379,7 +379,7 @@ void ClipModel::refreshProducerFromBin(PlaylistState::ClipState state, double sp ...@@ -379,7 +379,7 @@ void ClipModel::refreshProducerFromBin(PlaylistState::ClipState state, double sp
qDebug() << "changing speed" << in << out << m_speed; qDebug() << "changing speed" << in << out << m_speed;
} }
std::shared_ptr<ProjectClip> binClip = pCore->projectItemModel()->getClipByBinID(m_binClipId); std::shared_ptr<ProjectClip> binClip = pCore->projectItemModel()->getClipByBinID(m_binClipId);
std::shared_ptr<Mlt::Producer> binProducer = binClip->getTimelineProducer(m_id, state, m_speed); std::shared_ptr<Mlt::Producer> binProducer = binClip->getTimelineProducer(m_currentTrackId, m_id, state, m_speed);
m_producer = std::move(binProducer); m_producer = std::move(binProducer);
m_producer->set_in_and_out(in, out); m_producer->set_in_and_out(in, out);
// replant effect stack in updated service // replant effect stack in updated service
...@@ -510,6 +510,17 @@ void ClipModel::setShowKeyframes(bool show) ...@@ -510,6 +510,17 @@ void ClipModel::setShowKeyframes(bool show)
service()->set("kdenlive:hide_keyframes", (int)!show); service()->set("kdenlive:hide_keyframes", (int)!show);
} }
void ClipModel::setCurrentTrackId(int tid, bool finalMove)
{
if (tid == m_currentTrackId) {
return;
}
MoveableItem::setCurrentTrackId(tid, finalMove);
if (finalMove) {
refreshProducerFromBin(m_currentState);
}
}
Fun ClipModel::setClipState_lambda(PlaylistState::ClipState state) Fun ClipModel::setClipState_lambda(PlaylistState::ClipState state)
{ {
QWriteLocker locker(&m_lock); QWriteLocker locker(&m_lock);
......
...@@ -157,6 +157,8 @@ protected: ...@@ -157,6 +157,8 @@ protected:
*/ */
bool requestResize(int size, bool right, Fun &undo, Fun &redo, bool logUndo = true) override; bool requestResize(int size, bool right, Fun &undo, Fun &redo, bool logUndo = true) override;
void setCurrentTrackId(int tid, bool finalMove = true) override;
/* @brief This function change the global (timeline-wise) enabled state of the effects /* @brief This function change the global (timeline-wise) enabled state of the effects
*/ */
void setTimelineEffectsEnabled(bool enabled); void setTimelineEffectsEnabled(bool enabled);
......
...@@ -244,8 +244,9 @@ void CompositionModel::setInOut(int in, int out) ...@@ -244,8 +244,9 @@ void CompositionModel::setInOut(int in, int out)
setPosition(in); setPosition(in);
} }
void CompositionModel::setCurrentTrackId(int tid) void CompositionModel::setCurrentTrackId(int tid, bool finalMove)
{ {
Q_UNUSED(finalMove);
MoveableItem::setCurrentTrackId(tid); MoveableItem::setCurrentTrackId(tid);
} }
......
...@@ -99,7 +99,7 @@ public: ...@@ -99,7 +99,7 @@ public:
protected: protected:
Mlt::Transition *service() const override; Mlt::Transition *service() const override;
void setInOut(int in, int out) override; void setInOut(int in, int out) override;
void setCurrentTrackId(int tid) override; void setCurrentTrackId(int tid, bool finalMove = true) override;
int getOut() const override; int getOut() const override;
int getIn() const override; int getIn() const override;
......
...@@ -105,7 +105,7 @@ protected: ...@@ -105,7 +105,7 @@ protected:
If you wish to actually change the track the item, use the slot in the timeline If you wish to actually change the track the item, use the slot in the timeline
slot. slot.
*/ */
virtual void setCurrentTrackId(int tid); virtual void setCurrentTrackId(int tid, bool finalMove = true);
/* Set in and out of service */ /* Set in and out of service */
virtual void setInOut(int in, int out); virtual void setInOut(int in, int out);
......
...@@ -81,8 +81,9 @@ template <typename Service> void MoveableItem<Service>::setPosition(int pos) ...@@ -81,8 +81,9 @@ template <typename Service> void MoveableItem<Service>::setPosition(int pos)
m_position = pos; m_position = pos;
} }
template <typename Service> void MoveableItem<Service>::setCurrentTrackId(int tid) template <typename Service> void MoveableItem<Service>::setCurrentTrackId(int tid, bool finalMove)
{ {
Q_UNUSED(finalMove);
QWriteLocker locker(&m_lock); QWriteLocker locker(&m_lock);
m_currentTrackId = tid; m_currentTrackId = tid;
} }
......
...@@ -2682,9 +2682,9 @@ void TimelineModel::requestClipReload(int clipId) ...@@ -2682,9 +2682,9 @@ void TimelineModel::requestClipReload(int clipId)
bool refreshView = oldOut > (int)binClip->frameDuration(); bool refreshView = oldOut > (int)binClip->frameDuration();
if (old_trackId != -1) { if (old_trackId != -1) {
getTrackById(old_trackId)->requestClipDeletion(clipId, refreshView, true, local_undo, local_redo); getTrackById(old_trackId)->requestClipDeletion(clipId, refreshView, true, local_undo, local_redo);
} }
m_allClips[clipId]->refreshProducerFromBin();
if (old_trackId != -1) { if (old_trackId != -1) {
m_allClips[clipId]->refreshProducerFromBin();
getTrackById(old_trackId)->requestClipInsertion(clipId, oldPos, refreshView, true, local_undo, local_redo); getTrackById(old_trackId)->requestClipInsertion(clipId, oldPos, refreshView, true, local_undo, local_redo);
} }
} }
......
...@@ -134,7 +134,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat ...@@ -134,7 +134,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
m_allClips[clip->getId()] = clip; // store clip m_allClips[clip->getId()] = clip; // store clip
// update clip position and track // update clip position and track
clip->setPosition(position); clip->setPosition(position);
clip->setCurrentTrackId(m_id); clip->setCurrentTrackId(m_id, finalMove);
int new_in = clip->getPosition(); int new_in = clip->getPosition();
int new_out = new_in + clip->getPlaytime(); int new_out = new_in + clip->getPlaytime();
ptr->m_snaps->addPoint(new_in); ptr->m_snaps->addPoint(new_in);
...@@ -164,6 +164,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat ...@@ -164,6 +164,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
// Lock MLT playlist so that we don't end up with an invalid frame being displayed // Lock MLT playlist so that we don't end up with an invalid frame being displayed
m_playlists[0].lock(); m_playlists[0].lock();
std::shared_ptr<ClipModel> clip = ptr->getClipPtr(clipId); std::shared_ptr<ClipModel> clip = ptr->getClipPtr(clipId);
clip->setCurrentTrackId(m_id, finalMove);
int index = m_playlists[0].insert_at(position, *clip, 1); int index = m_playlists[0].insert_at(position, *clip, 1);
m_playlists[0].consolidate_blanks(); m_playlists[0].consolidate_blanks();
m_playlists[0].unlock(); m_playlists[0].unlock();
...@@ -189,6 +190,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat ...@@ -189,6 +190,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
// Lock MLT playlist so that we don't end up with an invalid frame being displayed // Lock MLT playlist so that we don't end up with an invalid frame being displayed
m_playlists[0].lock(); m_playlists[0].lock();
std::shared_ptr<ClipModel> clip = ptr->getClipPtr(clipId); std::shared_ptr<ClipModel> clip = ptr->getClipPtr(clipId);
clip->setCurrentTrackId(m_id);
int index = m_playlists[0].insert_at(position, *clip, 1); int index = m_playlists[0].insert_at(position, *clip, 1);
m_playlists[0].consolidate_blanks(); m_playlists[0].consolidate_blanks();
m_playlists[0].unlock(); m_playlists[0].unlock();
......
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