From: Jean-Baptiste M. <jb...@kd...> - 2015-07-27 10:44:11
|
Git commit 24be50011402e8c839adc6bdcdbb838ae35bb235 by Jean-Baptiste Mardelle. Committed on 27/07/2015 at 10:43. Pushed by mardelle into branch 'master'. Fix bin effects when reloading a clip M +20 -6 src/mltcontroller/bincontroller.cpp M +5 -2 src/mltcontroller/bincontroller.h M +13 -7 src/mltcontroller/clipcontroller.cpp M +4 -4 src/mltcontroller/clipcontroller.h M +17 -9 src/renderer.cpp M +7 -4 src/timeline/timeline.cpp M +2 -1 src/timeline/timeline.h http://commits.kde.org/kdenlive/24be50011402e8c839adc6bdcdbb838ae35bb235 diff --git a/src/mltcontroller/bincontroller.cpp b/src/mltcontroller/bincontroller.cpp index a391ef7..6fcee11 100644 --- a/src/mltcontroller/bincontroller.cpp +++ b/src/mltcontroller/bincontroller.cpp @@ -74,7 +74,7 @@ void BinController::loadExtraProducer(const QString &id, Mlt::Producer *prod) m_extraClipList.insert(id, prod); } -void BinController::initializeBin(Mlt::Playlist playlist) +void BinController::initializeBin(Mlt::Playlist playlist, ProfileInfo info) { // Load folders Mlt::Properties folderProperties; @@ -113,11 +113,11 @@ void BinController::initializeBin(Mlt::Playlist playlist) else { if (m_clipList.contains(id)) { //Controller was already added by a track producer, add master now - m_clipList.value(id)->addMasterProducer(producer->parent()); + m_clipList.value(id)->addMasterProducer(producer->parent(), info); } else { // Controller has not been created yet - ClipController *controller = new ClipController(this, producer->parent()); + ClipController *controller = new ClipController(this, producer->parent(), info); // fix MLT somehow adding root to color producer's resource (report upstream) if (strcmp(producer->parent().get("mlt_service"), "color") == 0) { QString color = producer->parent().get("resource"); @@ -214,14 +214,15 @@ int BinController::clipCount() const return m_clipList.size(); } -void BinController::replaceProducer(const QString &id, Mlt::Producer &producer) +void BinController::replaceProducer(const QString &id, Mlt::Producer &producer, ProfileInfo info) { ClipController *ctrl = m_clipList.value(id); if (!ctrl) { qDebug()<<" / // error controller not found, crashing"; return; } - ctrl->updateProducer(id, &producer); + pasteEffects(id, producer); + ctrl->updateProducer(id, &producer, info); emit prepareTimelineReplacement(id); replaceBinPlaylistClip(id, producer); producer.set("id", id.toUtf8().constData()); @@ -256,6 +257,19 @@ void BinController::replaceBinPlaylistClip(const QString &id, Mlt::Producer &pro m_binPlaylist->append(producer); } +void BinController::pasteEffects(const QString &id, Mlt::Producer &producer) +{ + int size = m_binPlaylist->count(); + for (int i = 0; i < size; i++) { + Mlt::Producer *prod = m_binPlaylist->get_clip(i); + QString prodId = prod->parent().get("id"); + if (prodId == id) { + duplicateFilters(prod->parent(), producer); + break; + } + } +} + void BinController::removeBinPlaylistClip(const QString &id) { int size = m_binPlaylist->count(); @@ -338,7 +352,7 @@ void BinController::duplicateFilters(Mlt::Producer original, Mlt::Producer clone Mlt::Filter *filter = clipService.filter(ct); while (filter) { // Only duplicate Kdenlive filters, and skip the fade in effects - fprintf(stderr, "CHKNG FILTER: %s\n", filter->get("kdenlive_id")); + //fprintf(stderr, "CHKNG FILTER: %s\n", filter->get("kdenlive_id")); if (filter->is_valid()/* && strcmp(filter->get("kdenlive_id"), "") && strcmp(filter->get("kdenlive_id"), "fadein") && strcmp(filter->get("kdenlive_id"), "fade_from_black")*/) { // looks like there is no easy way to duplicate a filter, // so we will create a new one and duplicate its properties diff --git a/src/mltcontroller/bincontroller.h b/src/mltcontroller/bincontroller.h index ffea410..c198c1f 100644 --- a/src/mltcontroller/bincontroller.h +++ b/src/mltcontroller/bincontroller.h @@ -85,7 +85,7 @@ public: /** @brief Initialize the bin's playlist from MLT's data * @param playlist The MLT playlist containing our bin's clips */ - void initializeBin(Mlt::Playlist playlist); + void initializeBin(Mlt::Playlist playlist, ProfileInfo info); /** @brief If our bin's playlist does not exist, create a new one */ void createIfNeeded(Mlt::Profile *profile); @@ -134,7 +134,7 @@ public: /** @brief Get the list of ids whose clip have the resource indicated by @param url */ const QStringList getBinIdsByResource(const QUrl &url) const; - void replaceProducer(const QString &id, Mlt::Producer &producer); + void replaceProducer(const QString &id, Mlt::Producer &producer, ProfileInfo info); void storeMarker(const QString &markerId, const QString &markerHash); QMap<double,QString> takeGuidesData(); @@ -184,6 +184,9 @@ private: /** @brief Remove a clip from MLT's special bin playlist */ void removeBinPlaylistClip(const QString &id); + + /** @brief Duplicate effects from stored producer */ + void pasteEffects(const QString &id, Mlt::Producer &producer); signals: void loadFolders(QMap<QString,QString>); diff --git a/src/mltcontroller/clipcontroller.cpp b/src/mltcontroller/clipcontroller.cpp index 69b8629..474925f 100644 --- a/src/mltcontroller/clipcontroller.cpp +++ b/src/mltcontroller/clipcontroller.cpp @@ -34,7 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <KLocalizedString> -ClipController::ClipController(BinController *bincontroller, Mlt::Producer& producer) : QObject() +ClipController::ClipController(BinController *bincontroller, Mlt::Producer& producer, ProfileInfo info) : QObject() , selectedEffectIndex(1) , audioThumbCreated(false) , m_properties(new Mlt::Properties(producer.get_properties())) @@ -58,7 +58,7 @@ ClipController::ClipController(BinController *bincontroller, Mlt::Producer& prod else m_url = QUrl::fromLocalFile(m_properties->get("resource")); m_service = m_properties->get("mlt_service"); getInfoForProducer(); - rebuildEffectList(); + rebuildEffectList(info); } } @@ -90,7 +90,7 @@ AudioStreamInfo *ClipController::audioInfo() const return m_audioInfo; } -void ClipController::addMasterProducer(Mlt::Producer &producer) +void ClipController::addMasterProducer(Mlt::Producer &producer, ProfileInfo info) { m_properties = new Mlt::Properties(producer.get_properties()); m_masterProducer = &producer; @@ -104,7 +104,7 @@ void ClipController::addMasterProducer(Mlt::Producer &producer) else m_url = QUrl::fromLocalFile(m_properties->get("resource")); m_service = m_properties->get("mlt_service"); getInfoForProducer(); - rebuildEffectList(); + rebuildEffectList(info); } } @@ -210,7 +210,7 @@ QMap <QString, QString> ClipController::getPropertiesFromPrefix(const QString &p } -void ClipController::updateProducer(const QString &id, Mlt::Producer* producer) +void ClipController::updateProducer(const QString &id, Mlt::Producer* producer, ProfileInfo info) { //TODO replace all track producers Mlt::Properties passProperties; @@ -230,7 +230,7 @@ void ClipController::updateProducer(const QString &id, Mlt::Producer* producer) m_name = m_url.fileName(); } */ - rebuildEffectList(); + rebuildEffectList(info); } } @@ -626,7 +626,7 @@ EffectsList ClipController::effectList() return m_effectList; } -void ClipController::rebuildEffectList() +void ClipController::rebuildEffectList(ProfileInfo info) { m_effectList.clearList(); int ix = 0; @@ -635,6 +635,12 @@ void ClipController::rebuildEffectList() Mlt::Filter *effect = service.filter(ix); QDomElement clipeffect = Timeline::getEffectByTag(effect->get("tag"), effect->get("kdenlive_id")); QDomElement currenteffect = clipeffect.cloneNode().toElement(); + // recover effect parameters + QDomNodeList params = currenteffect.elementsByTagName("parameter"); + for (int i = 0; i < params.count(); ++i) { + QDomElement param = params.item(i).toElement(); + Timeline::setParam(info, param, effect->get(param.attribute("name").toUtf8().constData())); + } m_effectList.append(currenteffect); } } diff --git a/src/mltcontroller/clipcontroller.h b/src/mltcontroller/clipcontroller.h index f3fba35..2f3ea70 100644 --- a/src/mltcontroller/clipcontroller.h +++ b/src/mltcontroller/clipcontroller.h @@ -51,7 +51,7 @@ public: * @param bincontroller reference to the bincontroller * @param producer producer to create reference to */ - ClipController(BinController *bincontroller, Mlt::Producer &producer); + ClipController(BinController *bincontroller, Mlt::Producer &producer, ProfileInfo info); /** * @brief Constructor used when opening a document and encountering a * track producer before the master producer. The masterProducer MUST be set afterwards @@ -67,7 +67,7 @@ public: QDateTime date; /** @brief Replaces the master producer and (TODO) the track producers with an updated producer, for example a proxy */ - void updateProducer(const QString &id, Mlt::Producer *producer); + void updateProducer(const QString &id, Mlt::Producer *producer, ProfileInfo info); void getProducerXML(QDomDocument& document); @@ -150,7 +150,7 @@ public: Q_DECL_DEPRECATED Mlt::Producer *getTrackProducer(const QString trackName, PlaylistState::ClipState clipState = PlaylistState::Original, double speed = 1.0); /** @brief Sets the master producer for this clip when we build the controller without master clip. */ - void addMasterProducer(Mlt::Producer &producer); + void addMasterProducer(Mlt::Producer &producer, ProfileInfo info); QList < CommentedTime > commentedSnapMarkers() const; GenTime findNextSnapMarker(const GenTime & currTime); @@ -198,7 +198,7 @@ private: /** @brief A list of snap markers; these markers are added to a clips snap-to points, and are displayed as necessary. */ QList < CommentedTime > m_snapMarkers; void getInfoForProducer(); - void rebuildEffectList(); + void rebuildEffectList(ProfileInfo info); }; #endif diff --git a/src/renderer.cpp b/src/renderer.cpp index b8e2abb..c69fefa 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -556,10 +556,11 @@ ClipType Render::getTypeForService(const QString &id, const QString &path) const void Render::processProducerProperties(Mlt::Producer *prod, QDomElement xml) { + //TODO: there is some duplication with clipcontroller > updateproducer that alsa copies properties QString value; QStringList internalProperties; internalProperties << "bypassDuplicate" << "resource" << "mlt_service"; - QDomNodeList props = xml.elementsByTagName("property"); + QDomNodeList props = xml.firstChildElement("producer").elementsByTagName("property"); for (int i = 0; i < props.count(); ++i) { QString propertyName = props.at(i).toElement().attribute("name"); if (!internalProperties.contains(propertyName)) { @@ -574,6 +575,9 @@ void Render::processFileProperties() requestClipInfo info; QLocale locale; locale.setNumberOptions(QLocale::OmitGroupSeparator); + ProfileInfo profileinfo; + profileinfo.profileSize = QSize(frameRenderWidth(), renderHeight()); + profileinfo.profileFps = m_fps; while (!m_requestList.isEmpty()) { m_infoMutex.lock(); @@ -808,7 +812,7 @@ void Render::processFileProperties() // replace clip //qDebug()<<" / / /CREATED PROD: "<<producer->get("resource"); m_processingClipId.removeAll(info.clipId); - m_binController->replaceProducer(info.clipId, *producer); + m_binController->replaceProducer(info.clipId, *producer, profileinfo); emit gotFileProperties(info, NULL); continue; } @@ -867,7 +871,6 @@ void Render::processFileProperties() } } } - int vindex = -1; const QString mltService = producer->get("mlt_service"); if (mltService == "xml" || mltService == "consumer") { @@ -1056,7 +1059,6 @@ void Render::processFileProperties() } producer->set("mlt_service", "avformat-novalidate"); } - // metadata Mlt::Properties metadata; metadata.pass_values(*producer, "meta.attr."); @@ -1070,12 +1072,12 @@ void Render::processFileProperties() producer->seek(0); if (m_binController->hasClip(info.clipId)) { // If controller already exists, we just want to update the producer - m_binController->replaceProducer(info.clipId, *producer); + m_binController->replaceProducer(info.clipId, *producer, profileinfo); emit gotFileProperties(info, NULL); } else { // Create the controller - ClipController *controller = new ClipController(m_binController, *producer); + ClipController *controller = new ClipController(m_binController, *producer, profileinfo); m_binController->addClipToBin(info.clipId, controller); emit gotFileProperties(info, controller); } @@ -1318,10 +1320,13 @@ int Render::setSceneList(QString playlist, int position) Mlt::Tractor tractor(service); Mlt::Properties retainList((mlt_properties) tractor.get_data("xml_retain")); if (retainList.is_valid() && retainList.get_data(m_binController->binPlaylistId().toUtf8().constData())) { + ProfileInfo info; + info.profileSize = QSize(frameRenderWidth(), renderHeight()); + info.profileFps = m_fps; Mlt::Playlist playlist((mlt_playlist) retainList.get_data(m_binController->binPlaylistId().toUtf8().constData())); if (playlist.is_valid() && playlist.type() == playlist_type) { // Load bin clips - m_binController->initializeBin(playlist); + m_binController->initializeBin(playlist, info); } } // No Playlist found, create new one @@ -1349,8 +1354,8 @@ int Render::setSceneList(QString playlist, int position) //m_blackClip = &original->parent(); } else { - requestClipInfo info; // pass basic info, the others (folder, etc) will be taken from the producer itself + requestClipInfo info; info.clipId = id; info.replaceProducer = true; emit gotFileProperties(info, m_binController->getController(id)); @@ -1430,7 +1435,10 @@ int Render::reloadSceneList(QString playlist, int position) Mlt::Playlist playlist((mlt_playlist) retainList.get_data(m_binController->binPlaylistId().toUtf8().constData())); if (playlist.is_valid() && playlist.type() == playlist_type) { // Load bin clips - m_binController->initializeBin(playlist); + ProfileInfo info; + info.profileSize = QSize(frameRenderWidth(), renderHeight()); + info.profileFps = m_fps; + m_binController->initializeBin(playlist, info); } } // No Playlist found, create new one diff --git a/src/timeline/timeline.cpp b/src/timeline/timeline.cpp index 9c3b71d..eb15e3b 100644 --- a/src/timeline/timeline.cpp +++ b/src/timeline/timeline.cpp @@ -866,10 +866,11 @@ void Timeline::getEffects(Mlt::Service &service, ClipItem *clip, int track) { QDomNodeList clipeffectparams = currenteffect.childNodes(); QDomNodeList params = currenteffect.elementsByTagName("parameter"); + ProfileInfo info = m_doc->getProfileInfo(); for (int i = 0; i < params.count(); ++i) { QDomElement e = params.item(i).toElement(); if (e.attribute("type") == "keyframe") e.setAttribute("keyframes", getKeyframes(service, ix, e)); - else setParam(e, effect->get(e.attribute("name").toUtf8().constData())); + else setParam(info, e, effect->get(e.attribute("name").toUtf8().constData())); } if (effect->get_out()) { // no keyframes but in/out points @@ -930,15 +931,17 @@ void Timeline::getSubfilters(Mlt::Filter *effect, QDomElement ¤teffect) { subclipeffect.setAttribute("region_ix", i); //get effect parameters (prefixed by subfilter name) QDomNodeList params = subclipeffect.elementsByTagName("parameter"); + ProfileInfo info = m_doc->getProfileInfo(); for (int i = 0; i < params.count(); ++i) { QDomElement param = params.item(i).toElement(); - setParam(param, effect->get((name + "." + param.attribute("name")).toUtf8().constData())); + setParam(info, param, effect->get((name + "." + param.attribute("name")).toUtf8().constData())); } currenteffect.appendChild(currenteffect.ownerDocument().importNode(subclipeffect, true)); } } -void Timeline::setParam(QDomElement param, QString value) { +//static +void Timeline::setParam(ProfileInfo info, QDomElement param, QString value) { QLocale locale; locale.setNumberOptions(QLocale::OmitGroupSeparator); //get Kdenlive scaling parameters @@ -946,7 +949,7 @@ void Timeline::setParam(QDomElement param, QString value) { double fact; QString factor = param.attribute("factor", "1"); if (factor.contains('%')) { - fact = EffectsController::getStringEval(m_doc->getProfileInfo(), factor); + fact = EffectsController::getStringEval(info, factor); } else { fact = factor.toDouble(); } diff --git a/src/timeline/timeline.h b/src/timeline/timeline.h index e19b620..bfae7f5 100644 --- a/src/timeline/timeline.h +++ b/src/timeline/timeline.h @@ -115,6 +115,8 @@ public: int getTrackSpaceLength(int trackIndex, int pos, bool fromBlankStart); void updateClipProperties(const QString &id, QMap <QString, QString> properties); int changeClipSpeed(ItemInfo info, ItemInfo speedIndependantInfo, double speed, int strobe, Mlt::Producer *originalProd, bool needsDuplicate); + /** @brief Set an effect's XML accordingly to MLT::filter values. */ + static void setParam(ProfileInfo info, QDomElement param, QString value); int getTracks(); void getTransitions(); void refreshTractor(); @@ -156,7 +158,6 @@ private: void getEffects(Mlt::Service &service, ClipItem *clip, int track = 0); QString getKeyframes(Mlt::Service service, int &ix, QDomElement e); void getSubfilters(Mlt::Filter *effect, QDomElement ¤teffect); - void setParam(QDomElement param, QString value); bool isSlide(QString geometry); void adjustDouble(QDomElement &e, double value); |