bool TransitionHandler::addTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml) { if (in >= out) return false; double fps = m_tractor->get_fps(); QMap<QString, QString> args = getTransitionParamsFromXml(xml); QScopedPointer<Mlt::Field> field(m_tractor->field()); Mlt::Transition transition(*m_tractor->profile(), tag.toUtf8().constData()); if (!transition.is_valid()) return false; if (out != GenTime()) transition.set_in_and_out((int) in.frames(fps), (int) out.frames(fps) - 1); QMap<QString, QString>::Iterator it; QString key; if (xml.attribute(QStringLiteral("automatic")) == QLatin1String("1")) transition.set("automatic", 1); ////qDebug() << " ------ ADDING TRANSITION PARAMs: " << args.count(); if (xml.hasAttribute(QStringLiteral("id"))) transition.set("kdenlive_id", xml.attribute(QStringLiteral("id")).toUtf8().constData()); if (xml.hasAttribute(QStringLiteral("force_track"))) transition.set("force_track", xml.attribute(QStringLiteral("force_track")).toInt()); for (it = args.begin(); it != args.end(); ++it) { key = it.key(); if (!it.value().isEmpty()) transition.set(key.toUtf8().constData(), it.value().toUtf8().constData()); ////qDebug() << " ------ ADDING TRANS PARAM: " << key << ": " << it.value(); } // attach transition m_tractor->lock(); plantTransition(field.data(), transition, a_track, b_track); // field->plant_transition(*transition, a_track, b_track); m_tractor->unlock(); return true; }
bool TransitionHandler::moveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) { double fps = m_tractor->get_fps(); int new_in = (int)newIn.frames(fps); int new_out = (int)newOut.frames(fps) - 1; if (new_in >= new_out) return false; int old_in = (int)oldIn.frames(fps); int old_out = (int)oldOut.frames(fps) - 1; bool doRefresh = true; // Check if clip is visible in monitor int position = mlt_producer_position(m_tractor->get_producer()); int diff = old_out - position; if (diff < 0 || diff > old_out - old_in) doRefresh = false; if (doRefresh) { diff = new_out - position; if (diff < 0 || diff > new_out - new_in) doRefresh = false; } QScopedPointer<Mlt::Field> field(m_tractor->field()); field->lock(); mlt_service nextservice = mlt_service_get_producer(field->get_service()); mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); QString resource = mlt_properties_get(properties, "mlt_service"); int old_pos = (int)(old_in + old_out) / 2; bool found = false; mlt_service_type mlt_type = mlt_service_identify( nextservice ); while (mlt_type == transition_type) { Mlt::Transition transition((mlt_transition) nextservice); nextservice = mlt_service_producer(nextservice); int currentTrack = transition.get_b_track(); int currentIn = (int) transition.get_in(); int currentOut = (int) transition.get_out(); if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) { found = true; if (newTrack - startTrack != 0) { Mlt::Properties trans_props(transition.get_properties()); Mlt::Transition new_transition(*m_tractor->profile(), transition.get("mlt_service")); Mlt::Properties new_trans_props(new_transition.get_properties()); // We cannot use MLT's property inherit because it also clones internal values like _unique_id which messes up the playlist cloneProperties(new_trans_props, trans_props); new_transition.set_in_and_out(new_in, new_out); field->disconnect_service(transition); plantTransition(field.data(), new_transition, newTransitionTrack, newTrack); } else transition.set_in_and_out(new_in, new_out); break; } if (nextservice == NULL) break; properties = MLT_SERVICE_PROPERTIES(nextservice); mlt_type = mlt_service_identify( nextservice ); resource = mlt_properties_get(properties, "mlt_service"); } field->unlock(); if (doRefresh) refresh(); //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1); return found; }
// adds the transition by keeping the instance order from topmost track down to background void TransitionHandler::plantTransition(Mlt::Transition &tr, int a_track, int b_track) { QScopedPointer<Mlt::Field> field(m_tractor->field()); plantTransition(field.data(), tr, a_track, b_track); }