Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Cleanup creation of clipcontroller, fix multiple freeze and crash on document close/open

parent b2be79f3
......@@ -1984,6 +1984,9 @@ void Bin::slotProducerReady(const requestClipInfo &info, std::shared_ptr<Mlt::Pr
std::shared_ptr<ProjectClip> clip = m_itemModel->getClipByBinID(info.clipId);
if (clip) {
if ((producer == nullptr || clip->setProducer(producer, info.replaceProducer)) && !clip->hasProxy()) {
if (producer) {
pCore->binController()->replaceBinPlaylistClip(info.clipId, producer);
}
emit producerReady(info.clipId);
// Check for file modifications
ClipType t = clip->clipType();
......@@ -2012,15 +2015,21 @@ void Bin::slotProducerReady(const requestClipInfo &info, std::shared_ptr<Mlt::Pr
if (currentClip.isEmpty()) {
// No clip displayed in monitor, check if item is selected
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
for (const QModelIndex &ix : indexes) {
if (!ix.isValid() || ix.column() != 0) {
continue;
}
std::shared_ptr<AbstractProjectItem> item = m_itemModel->getBinItemByIndex(m_proxyModel->mapToSource(ix));
if ((item != nullptr) && item->clipId() == info.clipId) {
// Item was selected, show it in monitor
setCurrent(item);
break;
if (indexes.isEmpty()) {
// No clip selected, focus this new one
emit openClip(std::shared_ptr<ProjectClip>());
setCurrent(clip);
} else {
for (const QModelIndex &ix : indexes) {
if (!ix.isValid() || ix.column() != 0) {
continue;
}
std::shared_ptr<AbstractProjectItem> item = m_itemModel->getBinItemByIndex(m_proxyModel->mapToSource(ix));
if ((item != nullptr) && item->clipId() == info.clipId) {
// Item was selected, show it in monitor
setCurrent(item);
break;
}
}
}
} else if (currentClip == info.clipId) {
......
......@@ -56,7 +56,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, std::shared_ptr<ProjectItemModel> model, std::shared_ptr<Mlt::Producer> producer)
: AbstractProjectItem(AbstractProjectItem::ClipItem, id, model)
, ClipController(pCore->binController(), producer)
, ClipController(id, pCore->binController(), producer)
, m_abortAudioThumb(false)
, m_thumbsProducer(nullptr)
{
......@@ -95,14 +95,13 @@ std::shared_ptr<ProjectClip> ProjectClip::construct(const QString &id, const QIc
ProjectClip::ProjectClip(const QDomElement &description, const QIcon &thumb, std::shared_ptr<ProjectItemModel> model)
: AbstractProjectItem(AbstractProjectItem::ClipItem, description, model)
, ClipController(pCore->binController())
, ClipController(description.attribute(QStringLiteral("id")), pCore->binController())
, m_abortAudioThumb(false)
, m_thumbsProducer(nullptr)
{
Q_ASSERT(description.hasAttribute(QStringLiteral("id")));
m_clipStatus = StatusWaiting;
m_thumbnail = thumb;
m_markerModel = std::make_shared<MarkerListModel>(description.attribute(QStringLiteral("id")), pCore->projectManager()->current()->commandStack());
m_markerModel = std::make_shared<MarkerListModel>(m_binId, pCore->projectManager()->current()->commandStack());
if (description.hasAttribute(QStringLiteral("type"))) {
m_clipType = (ClipType)description.attribute(QStringLiteral("type")).toInt();
if (m_clipType == Audio) {
......@@ -126,6 +125,7 @@ std::shared_ptr<ProjectClip> ProjectClip::construct(const QDomElement &descripti
{
std::shared_ptr<ProjectClip> self(new ProjectClip(description, thumb, model));
baseFinishConstruct(self);
pCore->binController()->addClipToBin(description.attribute(QStringLiteral("id")), self, true);
return self;
}
......@@ -325,7 +325,6 @@ QPixmap ProjectClip::thumbnail(int width, int height)
bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool replaceProducer)
{
Q_UNUSED(replaceProducer);
updateProducer(std::move(producer));
// Update info
......
......@@ -218,7 +218,7 @@ void EffectStackView2::slotClipItemSelected(ClipItem *c, Monitor *m, bool reload
void EffectStackView2::slotRefreshMasterClipEffects(ClipController *c, Monitor *m)
{
if ((c != nullptr) && m_status == MASTER_CLIP && (m_masterclipref != nullptr) && m_masterclipref->clipId() == c->clipId()) {
if ((c != nullptr) && m_status == MASTER_CLIP && (m_masterclipref != nullptr) && m_masterclipref->binId() == c->binId()) {
slotMasterClipItemSelected(c, m);
}
}
......@@ -625,7 +625,7 @@ void EffectStackView2::slotUpdateEffectState(bool disable, int index, MonitorSce
emit changeEffectState(nullptr, m_trackindex, QList<int>() << index, disable);
break;
case MASTER_CLIP:
emit changeMasterEffectState(m_masterclipref->clipId(), QList<int>() << index, disable);
emit changeMasterEffectState(m_masterclipref->binId(), QList<int>() << index, disable);
break;
default:
// timeline clip effect
......@@ -729,7 +729,7 @@ void EffectStackView2::slotCheckAll(int state)
} else if (m_status == TIMELINE_CLIP) {
emit changeEffectState(m_clipref, -1, indexes, disabled);
} else if (m_status == MASTER_CLIP) {
emit changeMasterEffectState(m_masterclipref->clipId(), indexes, disabled);
emit changeMasterEffectState(m_masterclipref->binId(), indexes, disabled);
}
}
......@@ -791,7 +791,7 @@ void EffectStackView2::slotUpdateEffectParams(const QDomElement &old, const QDom
// Make sure the changed effect is currently displayed
slotSetCurrentEffect(ix);
} else if (m_status == MASTER_CLIP) {
emit updateMasterEffect(m_masterclipref->clipId(), old, e, ix);
emit updateMasterEffect(m_masterclipref->binId(), old, e, ix);
}
m_scrollTimer.start();
}
......@@ -856,14 +856,14 @@ void EffectStackView2::slotDeleteEffect(const QDomElement &effect)
emit removeEffect(m_clipref, -1, effect);
}
if (m_status == MASTER_CLIP) {
emit removeMasterEffect(m_masterclipref->clipId(), effect);
emit removeMasterEffect(m_masterclipref->binId(), effect);
}
}
void EffectStackView2::slotAddEffect(const QDomElement &effect)
{
if (m_status == MASTER_CLIP) {
emit addMasterEffect(m_masterclipref->clipId(), effect);
emit addMasterEffect(m_masterclipref->binId(), effect);
} else {
emit addEffect(m_clipref, effect, m_trackindex);
}
......@@ -888,7 +888,7 @@ void EffectStackView2::slotMoveEffectUp(const QList<int> &indexes, bool up)
} else if (m_status == TIMELINE_CLIP) {
emit changeEffectPosition(m_clipref, -1, indexes, endPos);
} else if (m_status == MASTER_CLIP) {
emit changeEffectPosition(m_masterclipref->clipId(), indexes, endPos);
emit changeEffectPosition(m_masterclipref->binId(), indexes, endPos);
}
}
......@@ -922,7 +922,7 @@ void EffectStackView2::slotStartFilterJob(QMap<QString, QString> &filterParams,
emit startFilterJob(m_clipref->info(), m_clipref->getBinId(), filterParams, consumerParams, extraParams);
} else if (m_status == MASTER_CLIP && (m_masterclipref != nullptr)) {
ItemInfo info;
emit startFilterJob(info, m_masterclipref->clipId(), filterParams, consumerParams, extraParams);
emit startFilterJob(info, m_masterclipref->binId(), filterParams, consumerParams, extraParams);
}
}
......@@ -964,7 +964,7 @@ void EffectStackView2::slotResetEffect(int ix)
emit updateEffect(m_clipref, -1, old, dom, ix, true);
} else if (m_status == MASTER_CLIP) {
m_masterclipref->initEffect(m_effectMetaInfo.monitor->profileInfo(), dom);
emit updateMasterEffect(m_masterclipref->clipId(), old, dom, ix, true);
emit updateMasterEffect(m_masterclipref->binId(), old, dom, ix, true);
}
}
......
......@@ -726,7 +726,6 @@ void MainWindow::slotReloadTheme()
MainWindow::~MainWindow()
{
ClipController::mediaUnavailable.reset();
delete m_audioSpectrum;
if (m_projectMonitor) {
m_projectMonitor->stop();
......@@ -734,6 +733,7 @@ MainWindow::~MainWindow()
if (m_clipMonitor) {
m_clipMonitor->stop();
}
ClipController::mediaUnavailable.reset();
delete m_projectMonitor;
delete m_clipMonitor;
delete m_shortcutRemoveFocus;
......
......@@ -46,11 +46,11 @@ Mlt::Profile *BinController::profile()
void BinController::destroyBin()
{
if (m_binPlaylist) {
//m_binPlaylist.release();
m_binPlaylist->clear();
}
qDeleteAll(m_extraClipList);
m_extraClipList.clear();
m_clipList.clear();
}
......@@ -122,7 +122,7 @@ void BinController::initializeBin(Mlt::Playlist playlist)
qDebug() << "producer is not valid or blank";
continue;
}
QString id = producer->get("id");
QString id = qstrdup(producer->get("kdenlive:id"));
qDebug() << "clip id" << id;
if (id.contains(QLatin1Char('_'))) {
// This is a track producer
......@@ -155,7 +155,7 @@ void BinController::initializeBin(Mlt::Playlist playlist)
requestClipInfo info;
info.imageHeight = 0;
info.clipId = id;
info.replaceProducer = true;
info.replaceProducer = false;
emit slotProducerReady(info, producer);
}
}
......@@ -264,7 +264,9 @@ void BinController::replaceProducer(const requestClipInfo &info, const std::shar
return;
}
std::shared_ptr<ClipController> ctrl = m_clipList.value(info.clipId);
pasteEffects(info.clipId, producer);
if (ctrl->isValid()) {
pasteEffects(info.clipId, producer);
}
ctrl->updateProducer(producer);
replaceBinPlaylistClip(info.clipId, producer);
producer->set("id", info.clipId.toUtf8().constData());
......@@ -284,7 +286,7 @@ void BinController::addClipToBin(const QString &id, const std::shared_ptr<ClipCo
producer.attach(f);
*/
// append or replace clip in MLT's retain playlist
if (!fromPlaylist) {
if (!fromPlaylist && controller->isValid()) {
replaceBinPlaylistClip(id, controller->originalProducer());
}
if (!m_clipList.contains(id)) {
......@@ -300,14 +302,9 @@ void BinController::replaceBinPlaylistClip(const QString &id, const std::shared_
void BinController::pasteEffects(const QString &id, const std::shared_ptr<Mlt::Producer> &producer)
{
int size = m_binPlaylist->count();
for (int i = 0; i < size; i++) {
QScopedPointer<Mlt::Producer> prod(m_binPlaylist->get_clip(i));
QString prodId = prod->parent().get("id");
if (prodId == id) {
duplicateFilters(prod->parent(), *producer.get());
break;
}
std::shared_ptr<ClipController> ctrl = getController(id);
if (ctrl) {
duplicateFilters(ctrl->originalProducer(), *producer.get());
}
}
......@@ -316,7 +313,7 @@ void BinController::removeBinPlaylistClip(const QString &id)
int size = m_binPlaylist->count();
for (int i = 0; i < size; i++) {
QScopedPointer<Mlt::Producer> prod(m_binPlaylist->get_clip(i));
QString prodId = prod->parent().get("id");
QString prodId = prod->parent().get("kdenlive:id");
if (prodId == id) {
m_binPlaylist->remove(i);
break;
......@@ -372,9 +369,9 @@ Mlt::Producer *BinController::getBinVideoProducer(const QString &id)
return m_extraClipList.value(videoId);
}
void BinController::duplicateFilters(Mlt::Producer original, Mlt::Producer clone)
void BinController::duplicateFilters(std::shared_ptr<Mlt::Producer> original, Mlt::Producer clone)
{
Mlt::Service clipService(original.get_service());
Mlt::Service clipService(original->get_service());
Mlt::Service dupService(clone.get_service());
for (int ix = 0; ix < clipService.filter_count(); ++ix) {
QScopedPointer<Mlt::Filter> filter(clipService.filter(ix));
......@@ -386,7 +383,7 @@ void BinController::duplicateFilters(Mlt::Producer original, Mlt::Producer clone
}
// looks like there is no easy way to duplicate a filter,
// so we will create a new one and duplicate its properties
auto *dup = new Mlt::Filter(*original.profile(), filter->get("mlt_service"));
auto *dup = new Mlt::Filter(*original->profile(), filter->get("mlt_service"));
if ((dup != nullptr) && dup->is_valid()) {
for (int i = 0; i < filter->count(); ++i) {
QString paramName = filter->get_name(i);
......@@ -499,7 +496,7 @@ void BinController::checkThumbnails(const QDir &thumbFolder)
if (!ctrl->getClipHash().isEmpty()) {
QImage img(thumbFolder.absoluteFilePath(ctrl->getClipHash() + QStringLiteral(".png")));
if (!img.isNull()) {
emit loadThumb(ctrl->clipId(), img, true);
emit loadThumb(ctrl->binId(), img, true);
foundFile = true;
}
}
......@@ -510,7 +507,7 @@ void BinController::checkThumbnails(const QDir &thumbFolder)
QDomElement xml = doc.documentElement().firstChildElement(QStringLiteral("producer"));
if (!xml.isNull()) {
xml.setAttribute(QStringLiteral("thumbnailOnly"), 1);
emit createThumb(xml, ctrl->clipId(), 150);
emit createThumb(xml, ctrl->binId(), 150);
}
}
}
......@@ -525,7 +522,7 @@ void BinController::checkAudioThumbs()
if (!ctrl->m_audioThumbCreated) {
if (KdenliveSettings::audiothumbnails()) {
// We want audio thumbnails
emit requestAudioThumb(ctrl->clipId());
emit requestAudioThumb(ctrl->binId());
} else {
// Abort all pending thumb creation
emit abortAudioThumbs();
......
......@@ -182,7 +182,7 @@ private:
QString m_activeProfile;
/** @brief Can be used to copy filters from a clip to another */
void duplicateFilters(Mlt::Producer original, Mlt::Producer clone);
void duplicateFilters(std::shared_ptr<Mlt::Producer> original, Mlt::Producer clone);
/** @brief This list holds all producer controllers for the playlist, indexed by id */
QMap<QString, std::shared_ptr<ClipController>> m_clipList;
......
......@@ -40,11 +40,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
std::shared_ptr<Mlt::Producer> ClipController::mediaUnavailable;
ClipController::ClipController(std::shared_ptr<BinController> bincontroller, std::shared_ptr<Mlt::Producer> producer)
ClipController::ClipController(const QString clipId, std::shared_ptr<BinController> bincontroller, std::shared_ptr<Mlt::Producer> producer)
: selectedEffectIndex(1)
, m_audioThumbCreated(false)
, m_masterProducer(producer)
, m_properties(new Mlt::Properties(producer->get_properties()))
, m_properties(producer ? new Mlt::Properties(producer->get_properties()) : nullptr)
, m_usesProxy(false)
, m_audioInfo(nullptr)
, m_audioIndex(0)
......@@ -53,59 +53,46 @@ ClipController::ClipController(std::shared_ptr<BinController> bincontroller, std
, m_hasLimitedDuration(true)
, m_binController(bincontroller)
, m_snapMarkers(QList<CommentedTime>())
, m_effectStack(EffectStackModel::construct(producer, {ObjectType::BinClip, m_properties->get_int("kdenlive:id")}, pCore->undoStack()))
, m_effectStack(producer ? EffectStackModel::construct(producer, {ObjectType::BinClip, clipId.toInt()}, pCore->undoStack()) : nullptr)
, m_controllerBinId(clipId)
{
if (!m_masterProducer->is_valid()) {
if (m_masterProducer && !m_masterProducer->is_valid()) {
qCDebug(KDENLIVE_LOG) << "// WARNING, USING INVALID PRODUCER";
return;
}
m_service = m_properties->get("mlt_service");
QString proxy = m_properties->get("kdenlive:proxy");
QString path = m_properties->get("resource");
if (proxy.length() > 2) {
// This is a proxy producer, read original url from kdenlive property
path = m_properties->get("kdenlive:originalurl");
if (QFileInfo(path).isRelative()) {
if (m_properties) {
m_service = m_properties->get("mlt_service");
QString proxy = m_properties->get("kdenlive:proxy");
QString path = m_properties->get("resource");
if (proxy.length() > 2) {
// This is a proxy producer, read original url from kdenlive property
path = m_properties->get("kdenlive:originalurl");
if (QFileInfo(path).isRelative()) {
path.prepend(bincontroller->documentRoot());
}
m_usesProxy = true;
} else if (m_service != QLatin1String("color") && m_service != QLatin1String("colour") && QFileInfo(path).isRelative()) {
path.prepend(bincontroller->documentRoot());
}
m_usesProxy = true;
} else if (m_service != QLatin1String("color") && m_service != QLatin1String("colour") && QFileInfo(path).isRelative()) {
path.prepend(bincontroller->documentRoot());
m_path = QFileInfo(path).absoluteFilePath();
getInfoForProducer();
} else {
m_producerLock.lock();
}
m_path = QFileInfo(path).absoluteFilePath();
getInfoForProducer();
}
ClipController::ClipController(std::shared_ptr<BinController> bincontroller)
: selectedEffectIndex(1)
, m_audioThumbCreated(false)
, m_masterProducer(nullptr) // ClipController::mediaUnavailable)
, m_properties(nullptr)
, m_usesProxy(false)
, m_audioInfo(nullptr)
, m_audioIndex(0)
, m_videoIndex(0)
, m_clipType(Unknown)
, m_hasLimitedDuration(true)
, m_binController(bincontroller)
, m_snapMarkers(QList<CommentedTime>())
, m_effectStack(nullptr)
ClipController::~ClipController()
{
m_producerLock.lock();
delete m_properties;
m_masterProducer.reset();
delete m_audioInfo;
}
// static
std::shared_ptr<ClipController> ClipController::construct(const std::shared_ptr<BinController> &binController, std::shared_ptr<Mlt::Producer> producer)
const QString ClipController::binId() const
{
std::shared_ptr<ClipController> ptr(new ClipController(binController, producer));
return ptr;
return m_controllerBinId;
}
ClipController::~ClipController()
{
delete m_properties;
delete m_audioInfo;
}
AudioStreamInfo *ClipController::audioInfo() const
{
......@@ -115,6 +102,9 @@ AudioStreamInfo *ClipController::audioInfo() const
void ClipController::addMasterProducer(const std::shared_ptr<Mlt::Producer> &producer)
{
QString documentRoot;
if (auto ptr = m_binController.lock()) {
documentRoot = ptr->documentRoot();
}
m_masterProducer = producer;
m_properties = new Mlt::Properties(m_masterProducer->get_properties());
m_effectStack = EffectStackModel::construct(producer, {ObjectType::BinClip, m_properties->get_int("kdenlive:id")}, pCore->undoStack());
......@@ -141,13 +131,6 @@ void ClipController::addMasterProducer(const std::shared_ptr<Mlt::Producer> &pro
m_path = QFileInfo(path).absoluteFilePath();
getInfoForProducer();
}
if (auto ptr = m_binController.lock()) {
documentRoot = ptr->documentRoot();
// insert controller in bin
ptr->addClipToBin(clipId(), static_cast<std::shared_ptr<ClipController>>(this));
} else {
qDebug() << "Error: impossible to add master producer because bincontroller is not available";
}
}
void ClipController::getProducerXML(QDomDocument &document, bool includeMeta)
......@@ -242,14 +225,6 @@ bool ClipController::isValid()
return m_masterProducer->is_valid();
}
const QString ClipController::clipId()
{
if (m_masterProducer == nullptr) {
return QString();
}
return getProducerProperty(QStringLiteral("kdenlive:id"));
}
// static
const char *ClipController::getPassPropertiesList(bool passLength)
{
......@@ -305,7 +280,7 @@ void ClipController::updateProducer(const std::shared_ptr<Mlt::Producer> &produc
}
*/
}
qDebug() << "// replace finished: " << clipId() << " : " << m_masterProducer->get("resource");
qDebug() << "// replace finished: " << binId() << " : " << m_masterProducer->get("resource");
}
Mlt::Producer *ClipController::getTrackProducer(const QString &trackName, PlaylistState::ClipState clipState, double speed)
......@@ -593,7 +568,7 @@ void ClipController::addSnapMarker(const CommentedTime &marker)
}
m_snapMarkers.append(marker);
QLocale locale;
QString markerId = clipId() + QLatin1Char(':') + locale.toString(marker.time().seconds());
QString markerId = m_controllerBinId + QLatin1Char(':') + locale.toString(marker.time().seconds());
if (auto ptr = m_binController.lock()) ptr->storeMarker(markerId, marker.hash());
qSort(m_snapMarkers);
}
......@@ -608,7 +583,7 @@ void ClipController::editSnapMarker(const GenTime &time, const QString &comment)
}
m_snapMarkers[ix].setComment(comment);
QLocale locale;
QString markerId = clipId() + QLatin1Char(':') + locale.toString(time.seconds());
QString markerId = m_controllerBinId + QLatin1Char(':') + locale.toString(time.seconds());
if (auto ptr = m_binController.lock()) ptr->storeMarker(markerId, QString());
}
......@@ -623,7 +598,7 @@ QString ClipController::deleteSnapMarker(const GenTime &time)
QString result = m_snapMarkers.at(ix).comment();
m_snapMarkers.removeAt(ix);
QLocale locale;
QString markerId = clipId() + QLatin1Char(':') + locale.toString(time.seconds());
QString markerId = m_controllerBinId + QLatin1Char(':') + locale.toString(time.seconds());
if (auto ptr = m_binController.lock()) ptr->storeMarker(markerId, QString());
return result;
}
......@@ -742,7 +717,7 @@ void ClipController::addEffect(const ProfileInfo &pInfo, QDomElement &xml)
EffectsParameterList params = EffectsController::getEffectArgs(pInfo, xml);
EffectManager effect(service);
effect.addEffect(params, getPlaytime().frames(pCore->getCurrentFps()));
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(clipId());
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(m_controllerBinId);
}
void ClipController::removeEffect(int effectIndex, bool delayRefresh)
......@@ -752,7 +727,7 @@ void ClipController::removeEffect(int effectIndex, bool delayRefresh)
EffectManager effect(service);
effect.removeEffect(effectIndex, true);
if (!delayRefresh) {
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(clipId());
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(m_controllerBinId);
}
}
......@@ -771,7 +746,7 @@ void ClipController::moveEffect(int oldPos, int newPos)
void ClipController::reloadTrackProducers()
{
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(clipId());
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(m_controllerBinId);
}
int ClipController::effectsCount()
......@@ -822,7 +797,7 @@ void ClipController::changeEffectState(const QList<int> &indexes, bool disable)
effect->set("disable", (int)disable);
}
}
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(clipId());
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(m_controllerBinId);
}
void ClipController::updateEffect(const ProfileInfo &pInfo, const QDomElement &e, int ix)
......@@ -854,7 +829,7 @@ void ClipController::updateEffect(const ProfileInfo &pInfo, const QDomElement &e
}
service.unlock();
}
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(clipId());
if (auto ptr = m_binController.lock()) ptr->updateTrackProducer(m_controllerBinId);
// slotRefreshTracks();
}
......
......@@ -51,29 +51,13 @@ class ClipController
{
public:
friend class Bin;
/**
@brief Constructs a clipController and returns a ptr to it.
* It also take care of registration to the BinController
* @param bincontroller reference to the bincontroller
* @param producer producer to create reference to
* @param loadingFromBinPlaylist if true, we are loading the clip from bin playlist, so no need to insert it here
*/
static std::shared_ptr<ClipController> construct(const std::shared_ptr<BinController> &bincontroller, std::shared_ptr<Mlt::Producer> producer);
protected:
/**
* @brief Constructor.
The constructor is protected because you should call the static Construct instead
* @param bincontroller reference to the bincontroller
* @param producer producer to create reference to
*/
explicit ClipController(std::shared_ptr<BinController> bincontroller, std::shared_ptr<Mlt::Producer> producer);
/**
* @brief Constructor used when opening a document and encountering a
The constructor is protected because you should call the static Construct instead
* @param bincontroller reference to the bincontroller
*/
explicit ClipController(std::shared_ptr<BinController> bincontroller);
explicit ClipController(const QString id, std::shared_ptr<BinController> bincontroller, std::shared_ptr<Mlt::Producer> producer = nullptr);
public:
virtual ~ClipController();
......@@ -92,9 +76,6 @@ public:
/** @brief Returns a clone of our master producer. Delete after use! */
Mlt::Producer *masterProducer();
/** @brief Returns the MLT's producer id */
const QString clipId();
/** @brief Returns the clip name (usually file name) */
QString clipName() const;
......@@ -107,6 +88,9 @@ public:
/** @brief Returns the clip's type as defined in definitions.h */
ClipType clipType() const;
/** @brief Returns the MLT's producer id */
const QString binId() const;
/** @brief Returns the clip's duration */
GenTime getPlaytime() const;
/**
......@@ -249,6 +233,7 @@ protected:
private:
QMutex m_producerLock;
QString m_controllerBinId;
};
#endif
......@@ -159,7 +159,7 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
: QWidget(parent)
, m_controller(controller)
, m_tc(Timecode(Timecode::HH_MM_SS_HH, pCore->getCurrentFps()))
, m_id(controller->clipId())
, m_id(controller->binId())
, m_type(controller->clipType())
, m_properties(controller->properties())
, m_textEdit(nullptr)
......
......@@ -828,13 +828,7 @@ void ProducerQueue::processFileProperties()
}
}
producer->seek(0);
if (m_binController->hasClip(info.clipId)) {
// If controller already exists, we just want to update the producer
QMetaObject::invokeMethod(m_binController.get(), "replaceProducer", Qt::QueuedConnection, Q_ARG(const requestClipInfo &, info),
Q_ARG(const std::shared_ptr<Mlt::Producer> &, producer));
} else {
emit gotFileProperties(info, producer);
}
emit gotFileProperties(info, producer);
m_processingClipId.removeAll(info.clipId);
}
}
......
......@@ -837,12 +837,12 @@ void GLWidget::slotSwitchAudioOverlay(bool enable)
}
}
int GLWidget::setProducer(Mlt::Producer *producer, int position)
int GLWidget::setProducer(Mlt::Producer *producer, bool isActive, int position)
{
int error = 0;
QString currentId;
int consumerPosition = 0;
currentId = m_producer->get("kdenlive:id");
currentId = m_producer->parent().get("kdenlive:id");
if (producer != nullptr) {
m_producer = producer;
} else {
......@@ -895,14 +895,15 @@ int GLWidget::setProducer(Mlt::Producer *producer, int position)
} else if (KdenliveSettings::displayAudioOverlay()) {
createAudioOverlay(false);
}
if (position == -1 && m_producer->get("kdenlive:id") == currentId) {
if (position == -1 && m_producer->parent().get("kdenlive:id") == currentId) {
position = consumerPosition;
}
if (position != -1) {
m_producer->seek(position);
}
//if (isActive) {
startConsumer();
if (isActive) {
startConsumer();
}
// emit durationChanged(m_producer->get_length() - 1, m_producer->get_in());
position = m_producer->position();
rootObject()->setProperty("consumerPosition", position);
......@@ -1772,57 +1773,6 @@ void GLWidget::setRulerInfo(int duration, std::shared_ptr<MarkerListModel> model
}
}
bool GLWidget::replaceProducer(Mlt::Producer *producer, int position, bool isActive)
{
m_refreshTimer.stop();
m_proxy->setSeekPosition(SEEK_INACTIVE);
QMutexLocker locker(&m_mutex);
QString currentId;
int consumerPosition = 0;
if ((producer == nullptr) && (m_producer != nullptr) && m_producer->parent().get("kdenlive:id") == QLatin1String("black")) {
// Black clip already displayed no need to refresh
return true;
}
if (m_producer) {
currentId = m_producer->get("kdenlive:id");
m_producer->set_speed(0);
if (QString(m_producer->get("resource")) == QLatin1String("<tractor>")) {
// We need to make some cleanup
Mlt::Tractor trac(*m_producer);
for (int i = 0; i < trac.count(); i++) {
trac.set_track(*new Mlt::Producer(*m_blackClip), i);