Switch to only one producer for all video only clips, let clipmodel handle...

Switch to only one producer for all video only clips, let clipmodel handle disabled state, fix audio clip length corruption on opening
parent 88caaf92
......@@ -421,11 +421,12 @@ std::shared_ptr<Mlt::Producer> ProjectClip::thumbProducer()
void ProjectClip::createVideoMasterProducer()
{
if (!m_videoProducer) {
m_videoProducer = cloneProducer(&pCore->getCurrentProfile()->profile());
// disable audio but activate video
m_videoProducer->set("set.test_audio", 1);
m_videoProducer->set("set.test_image", 0);
m_effectStack->addService(m_videoProducer);
m_videoProducer = std::shared_ptr<Mlt::Producer>(m_masterProducer->cut());
if (hasAudio()) {
// disable audio but activate video
m_videoProducer->set("set.test_audio", 1);
m_videoProducer->set("set.test_image", 0);
}
}
}
......@@ -518,12 +519,13 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim
speed = master->parent().get_double("warp_speed");
timeWarp = true;
}
if (master->parent().get_int("loaded") == 1) {
if (master->parent().get_int("_loaded") == 1) {
// we already have a clip that shares the same master
if (state == PlaylistState::AudioOnly || timeWarp) {
// In that case, we must create copies
return {getTimelineProducer(clipId, state, speed), false};
std::shared_ptr<Mlt::Producer> prod(getTimelineProducer(clipId, state, speed)->cut(in, out));
return {prod, false};
}
// if it's a video or disabled clip, we must make sure that its master clip matches our video master
if (state == PlaylistState::VideoOnly && !m_videoProducer) {
......@@ -547,7 +549,7 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim
// We have a good id, this clip can be used
return {master, true};
} else {
master->parent().set("loaded", 1);
master->parent().set("_loaded", 1);
if (state == PlaylistState::AudioOnly) {
m_audioProducers[clipId] = std::shared_ptr<Mlt::Producer>(&master->parent());
m_effectStack->addService(m_audioProducers[clipId]);
......@@ -576,6 +578,7 @@ std::pair<std::shared_ptr<Mlt::Producer>, bool> ProjectClip::giveMasterAndGetTim
} else if (master->is_valid()) {
// in that case, we have a master
qDebug() << "Warning: weird, we received a master clip in lieue of a cut";
exit(1);
double speed = 1.0;
if (QString::fromUtf8(master->get("mlt_service")) == QLatin1String("timewarp")) {
speed = master->get_double("warp_speed");
......
......@@ -51,6 +51,8 @@ ClipController::ClipController(const QString clipId, std::shared_ptr<Mlt::Produc
, m_hasLimitedDuration(true)
, m_effectStack(producer ? EffectStackModel::construct(producer, {ObjectType::BinClip, clipId.toInt()}, pCore->undoStack()) : nullptr)
, m_controllerBinId(clipId)
, m_hasVideo(false)
, m_hasAudio(false)
{
if (m_masterProducer && !m_masterProducer->is_valid()) {
qCDebug(KDENLIVE_LOG) << "// WARNING, USING INVALID PRODUCER";
......@@ -537,7 +539,7 @@ bool ClipController::hasAudio() const
void ClipController::checkAudioVideo()
{
m_masterProducer->seek(0);
Mlt::Frame *frame = m_masterProducer->get_frame();
QScopedPointer<Mlt::Frame> frame(m_masterProducer->get_frame());
// test_audio returns 1 if there is NO audio (strange but true at the time this code is written)
m_hasAudio = frame->get_int("test_audio") == 0;
m_hasVideo = frame->get_int("test_image") == 0;
......
......@@ -102,7 +102,6 @@ int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QSt
clip->m_effectStack->importEffects(producer, result.second);
clip->setClipState_lambda(state)();
parent->registerClip(clip);
return id;
}
......@@ -450,7 +449,21 @@ Fun ClipModel::setClipState_lambda(PlaylistState::ClipState state)
QWriteLocker locker(&m_lock);
return [this, state]() {
if (auto ptr = m_parent.lock()) {
refreshProducerFromBin(state);
switch (state) {
case PlaylistState::Disabled:
m_producer->set("set.test_audio", 1);
m_producer->set("set.test_image", 1);
break;
case PlaylistState::VideoOnly:
m_producer->set("set.test_image", 0);
break;
case PlaylistState::AudioOnly:
m_producer->set("set.test_audio", 0);
break;
default:
//error
break;
}
m_currentState = state;
if (ptr->isClip(m_id)) { // if this is false, the clip is being created. Don't update model in that case
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
......
......@@ -431,22 +431,6 @@ bool TimelineFunctions::changeClipState(std::shared_ptr<TimelineItemModel> timel
Fun local_undo = []() { return true; };
Fun local_redo = []() { return true; };
bool result = timeline->m_allClips[clipId]->setClipState(status, local_undo, local_redo);
Fun operation = [timeline, clipId]() {
int trackId = timeline->getClipTrackId(clipId);
// in order to make the producer change effective, we need to unplant / replant the clip in int track
if (trackId != -1) {
timeline->getTrackById(trackId)->replugClip(clipId);
}
return true;
};
result = result && operation();
if (!result) {
bool undone = local_undo();
Q_ASSERT(undone);
return false;
}
auto reverse = operation;
UPDATE_UNDO_REDO_NOLOCK(operation, reverse, local_undo, local_redo);
UPDATE_UNDO_REDO_NOLOCK(local_redo, local_undo, undo, redo);
return result;
}
......
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