}
}
-Render::Render(const QString & rendererName, int winid, QString profile, QWidget *parent) :
+Render::Render(Kdenlive::MONITORID rendererName, int winid, QString profile, QWidget *parent) :
AbstractRender(rendererName, parent),
m_name(rendererName),
m_mltConsumer(NULL),
m_mltConsumer->connect(*m_mltProducer);
m_mltProducer->set_speed(0.0);
m_refreshTimer.setSingleShot(true);
- m_refreshTimer.setInterval(50);
+ m_refreshTimer.setInterval(70);
connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
}
mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
QString mlt_type = mlt_properties_get(properties, "mlt_type");
QString resource = mlt_properties_get(properties, "mlt_service");
+ mlt_service nextservicetodisconnect;
while (mlt_type == "transition") {
QString added = mlt_properties_get(MLT_SERVICE_PROPERTIES(nextservice), "internal_added");
if (added == "200") {
- mlt_field_disconnect_service(field->get_field(), nextservice);
+ nextservicetodisconnect = nextservice;
+ nextservice = mlt_service_producer(nextservice);
+ mlt_field_disconnect_service(field->get_field(), nextservicetodisconnect);
}
- nextservice = mlt_service_producer(nextservice);
+ else nextservice = mlt_service_producer(nextservice);
if (nextservice == NULL) break;
properties = MLT_SERVICE_PROPERTIES(nextservice);
mlt_type = mlt_properties_get(properties, "mlt_type");
return 0;
}
-const QString & Render::rendererName() const
-{
- return m_name;
-}
-
void Render::emitFrameUpdated(Mlt::Frame& frame)
{
mlt_image_format format = mlt_image_rgb24a;
const uchar* image = frame.get_image(format, width, height);
QImage qimage(width, height, QImage::Format_RGB888);
memcpy(qimage.bits(), image, width * height * 3);*/
- emit frameUpdated(qimage);
+ emit frameUpdated(qimage.rgbSwapped());
}
void Render::emitFrameNumber()
int index = params.paramValue("kdenlive_ix").toInt();
QString tag = params.paramValue("tag");
- if (!params.paramValue("keyframes").isEmpty() || /*it.key().startsWith("#") || */tag.startsWith("ladspa") || tag == "sox" || tag == "autotrack_rectangle" || params.hasParam("region")) {
+ if (!params.paramValue("keyframes").isEmpty() || (tag == "affine" && params.hasParam("background")) || tag.startsWith("ladspa") || tag == "sox" || tag == "autotrack_rectangle" || params.hasParam("region")) {
// This is a keyframe effect, to edit it, we remove it and re-add it.
bool success = mltRemoveEffect(track, position, index, false);
// if (!success) kDebug() << "// ERROR Removing effect : " << index;
while (mlt_type == "transition") {
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();
} else transition.set_in_and_out(new_in, new_out);
break;
}
- nextservice = mlt_service_producer(nextservice);
if (nextservice == NULL) break;
properties = MLT_SERVICE_PROPERTIES(nextservice);
mlt_type = mlt_properties_get(properties, "mlt_type");
QString mlt_type = mlt_properties_get(properties, "mlt_type");
QString resource = mlt_properties_get(properties, "mlt_service");
QList <Mlt::Transition *> trList;
+ mlt_properties insertproperties = tr.get_properties();
+ QString insertresource = mlt_properties_get(insertproperties, "mlt_service");
+ bool isMixTransition = insertresource == "mix";
while (mlt_type == "transition") {
Mlt::Transition transition((mlt_transition) nextservice);
+ nextservice = mlt_service_producer(nextservice);
int aTrack = transition.get_a_track();
int bTrack = transition.get_b_track();
- if (resource != "mix" && (aTrack < a_track || (aTrack == a_track && bTrack > b_track))) {
+ if ((isMixTransition || resource != "mix") && (aTrack < a_track || (aTrack == a_track && bTrack > b_track))) {
Mlt::Properties trans_props(transition.get_properties());
Mlt::Transition *cp = new Mlt::Transition(*m_mltProfile, transition.get("mlt_service"));
Mlt::Properties new_trans_props(cp->get_properties());
}
//else kDebug() << "// FOUND TRANS OK, "<<resource<< ", A_: " << aTrack << ", B_ "<<bTrack;
- nextservice = mlt_service_producer(nextservice);
if (nextservice == NULL) break;
properties = MLT_SERVICE_PROPERTIES(nextservice);
mlt_type = mlt_properties_get(properties, "mlt_type");
//kDebug()<< "REPLANT ON TK: "<<trList.at(i)->get_a_track()<<", "<<trList.at(i)->get_b_track();
field->plant_transition(*trList.at(i), trList.at(i)->get_a_track(), trList.at(i)->get_b_track());
}
+ qDeleteAll(trList);
}
void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool force)
Mlt::Tractor tractor(service);
Mlt::Field *field = tractor.field();
- Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, tag.toUtf8().constData());
+ Mlt::Transition transition(*m_mltProfile, tag.toUtf8().constData());
if (out != GenTime())
- transition->set_in_and_out((int) in.frames(m_fps), (int) out.frames(m_fps) - 1);
+ transition.set_in_and_out((int) in.frames(m_fps), (int) out.frames(m_fps) - 1);
if (do_refresh && (m_mltProducer->position() < in.frames(m_fps) || m_mltProducer->position() > out.frames(m_fps))) do_refresh = false;
QMap<QString, QString>::Iterator it;
QString key;
- if (xml.attribute("automatic") == "1") transition->set("automatic", 1);
+ if (xml.attribute("automatic") == "1") transition.set("automatic", 1);
//kDebug() << " ------ ADDING TRANSITION PARAMs: " << args.count();
if (xml.hasAttribute("id"))
- transition->set("kdenlive_id", xml.attribute("id").toUtf8().constData());
+ transition.set("kdenlive_id", xml.attribute("id").toUtf8().constData());
if (xml.hasAttribute("force_track"))
- transition->set("force_track", xml.attribute("force_track").toInt());
+ transition.set("force_track", xml.attribute("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());
+ transition.set(key.toUtf8().constData(), it.value().toUtf8().constData());
//kDebug() << " ------ ADDING TRANS PARAM: " << key << ": " << it.value();
}
// attach transition
service.lock();
- mltPlantTransition(field, *transition, a_track, b_track);
+ mltPlantTransition(field, transition, a_track, b_track);
// field->plant_transition(*transition, a_track, b_track);
service.unlock();
if (do_refresh) refresh();
}
}
-void Render::mltInsertTrack(int ix, bool videoTrack)
+QList <TransitionInfo> Render::mltInsertTrack(int ix, bool videoTrack)
{
- blockSignals(true);
-
Mlt::Service service(m_mltProducer->parent().get_service());
- service.lock();
if (service.type() != tractor_type) {
kWarning() << "// TRACTOR PROBLEM";
- return;
+ return QList <TransitionInfo> ();
}
-
+ blockSignals(true);
+ service.lock();
Mlt::Tractor tractor(service);
-
+ QList <TransitionInfo> transitionInfos;
Mlt::Playlist playlist;
int ct = tractor.count();
if (ix > ct) {
mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
QString mlt_type = mlt_properties_get(properties, "mlt_type");
QString resource = mlt_properties_get(properties, "mlt_service");
+ Mlt::Field *field = tractor.field();
+ QList <Mlt::Transition *> trList;
while (mlt_type == "transition") {
if (resource != "mix") {
- mlt_transition tr = (mlt_transition) nextservice;
- int currentTrack = mlt_transition_get_b_track(tr);
- int currentaTrack = mlt_transition_get_a_track(tr);
- mlt_properties properties = MLT_TRANSITION_PROPERTIES(tr);
-
- if (currentTrack >= ix) {
- mlt_properties_set_int(properties, "b_track", currentTrack + 1);
- mlt_properties_set_int(properties, "a_track", currentaTrack + 1);
- }
+ Mlt::Transition transition((mlt_transition) nextservice);
+ nextservice = mlt_service_producer(nextservice);
+ int currentbTrack = transition.get_b_track();
+ int currentaTrack = transition.get_a_track();
+ bool trackChanged = false;
+ bool forceTransitionTrack = false;
+ if (currentbTrack >= ix) {
+ if (currentbTrack == ix && currentaTrack < ix) forceTransitionTrack = true;
+ currentbTrack++;
+ trackChanged = true;
+ }
+ if (currentaTrack >= ix) {
+ currentaTrack++;
+ trackChanged = true;
+ }
+ kDebug()<<"// Newtrans: "<<currentaTrack<<"/"<<currentbTrack;
+
+ // disconnect all transitions
+ Mlt::Properties trans_props(transition.get_properties());
+ Mlt::Transition *cp = new Mlt::Transition(*m_mltProfile, transition.get("mlt_service"));
+ Mlt::Properties new_trans_props(cp->get_properties());
+ new_trans_props.inherit(trans_props);
+
+ if (trackChanged) {
+ // Transition track needs to be adjusted
+ cp->set("a_track", currentaTrack);
+ cp->set("b_track", currentbTrack);
+ // Check if transition track was changed and needs to be forced
+ if (forceTransitionTrack) cp->set("force_track", 1);
+ TransitionInfo trInfo;
+ trInfo.startPos = GenTime(transition.get_in(), m_fps);
+ trInfo.a_track = currentaTrack;
+ trInfo.b_track = currentbTrack;
+ trInfo.forceTrack = cp->get_int("force_track");
+ transitionInfos.append(trInfo);
+ }
+ trList.append(cp);
+ field->disconnect_service(transition);
}
- nextservice = mlt_service_producer(nextservice);
+ else nextservice = mlt_service_producer(nextservice);
if (nextservice == NULL) break;
properties = MLT_SERVICE_PROPERTIES(nextservice);
mlt_type = mlt_properties_get(properties, "mlt_type");
}
// Add audio mix transition to last track
- Mlt::Field *field = tractor.field();
- Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, "mix");
- transition->set("a_track", 1);
- transition->set("b_track", ct);
- transition->set("always_active", 1);
- transition->set("internal_added", 237);
- transition->set("combine", 1);
- field->plant_transition(*transition, 1, ct);
- //mlt_service_unlock(m_mltConsumer->get_service());
+ Mlt::Transition transition(*m_mltProfile, "mix");
+ transition.set("a_track", 1);
+ transition.set("b_track", ct);
+ transition.set("always_active", 1);
+ transition.set("internal_added", 237);
+ transition.set("combine", 1);
+ mltPlantTransition(field, transition, 1, ct);
+
+ // re-add transitions
+ for (int i = trList.count() - 1; i >= 0; i--) {
+ field->plant_transition(*trList.at(i), trList.at(i)->get_a_track(), trList.at(i)->get_b_track());
+ }
+ qDeleteAll(trList);
+
service.unlock();
- //tractor.multitrack()->refresh();
- //tractor.refresh();
blockSignals(false);
+ return transitionInfos;
}
return QString();
}
+//static
+bool Render::getBlackMagicDeviceList(KComboBox *devicelist)
+{
+ Mlt::Profile profile;
+ Mlt::Producer bm(profile, "decklink");
+ int found_devices = 0;
+ if (bm.is_valid()) {
+ bm.set("list_devices", 1);
+ found_devices = bm.get_int("devices");
+ }
+ if (found_devices <= 0) {
+ devicelist->setEnabled(false);
+ return false;
+ }
+ for (int i = 0; i < found_devices; i++) {
+ char *tmp = qstrdup(QString("device.%1").arg(i).toUtf8().constData());
+ devicelist->addItem(bm.get(tmp));
+ delete[] tmp;
+ }
+ return true;
+}
+
+bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist)
+{
+ Mlt::Profile profile;
+ Mlt::Consumer bm(profile, "decklink");
+ int found_devices = 0;
+ if (bm.is_valid()) {
+ bm.set("list_devices", 1);
+ found_devices = bm.get_int("devices");
+ }
+ if (found_devices <= 0) {
+ devicelist->setEnabled(false);
+ return false;
+ }
+ for (int i = 0; i < found_devices; i++) {
+ char *tmp = qstrdup(QString("device.%1").arg(i).toUtf8().constData());
+ devicelist->addItem(bm.get(tmp));
+ delete[] tmp;
+ }
+ return true;
+}
+
#include "renderer.moc"