#include "kthumb.h"
#include "definitions.h"
#include "slideshowclip.h"
+#include "profilesdialog.h"
+#include "blackmagic/devices.h"
#include <mlt++/Mlt.h>
#include <cstdlib>
#include <cstdarg>
-
+#include <QDebug>
static void kdenlive_callback(void* /*ptr*/, int level, const char* fmt, va_list vl)
{
if (level > MLT_LOG_ERROR) return;
QString error;
- QApplication::postEvent(qApp->activeWindow() , new MltErrorEvent(error.vsprintf(fmt, vl).simplified()));
+ QApplication::postEvent(qApp->activeWindow(), new MltErrorEvent(error.vsprintf(fmt, vl).simplified()));
va_end(vl);
}
// detect if the producer has finished playing. Is there a better way to do it?
if (self->m_isBlocked) return;
Mlt::Frame frame(frame_ptr);
-#ifdef Q_WS_MAC
- self->showFrame(frame);
-#endif
-
+ if (!frame.is_valid()) return;
self->emitFrameNumber(mlt_frame_get_position(frame_ptr));
if (self->sendFrameForAnalysis && frame_ptr->convert_image) {
self->emitFrameUpdated(frame);
}
+ if (self->analyseAudio) {
+ self->showAudio(frame);
+ }
if (frame.get_double("_speed") == 0.0) {
self->emitConsumerStopped();
} else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) {
}
}
+static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr)
+{
+ // detect if the producer has finished playing. Is there a better way to do it?
+ if (self->m_isBlocked) return;
+ Mlt::Frame frame(frame_ptr);
+ self->showFrame(frame);
+ if (frame.get_double("_speed") == 0.0) {
+ self->emitConsumerStopped();
+ } else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) {
+ self->pause();
+ self->emitConsumerStopped();
+ }
+}
-Render::Render(const QString & rendererName, int winid, int /* extid */, QString profile, QWidget *parent) :
- QObject(parent),
- m_isBlocked(0),
- sendFrameForAnalysis(false),
- m_name(rendererName),
- m_mltConsumer(NULL),
- m_mltProducer(NULL),
- m_mltProfile(NULL),
- m_framePosition(0),
- m_isZoneMode(false),
- m_isLoopMode(false),
- m_isSplitView(false),
- m_blackClip(NULL),
- m_winid(winid)
-#ifdef Q_WS_MAC
- , m_glWidget(0)
-#endif
+Render::Render(const QString & rendererName, int winid, QString profile, QWidget *parent) :
+ QObject(parent),
+ m_isBlocked(0),
+ analyseAudio(KdenliveSettings::monitor_audio()),
+ sendFrameForAnalysis(false),
+ m_name(rendererName),
+ m_mltConsumer(NULL),
+ m_mltProducer(NULL),
+ m_mltProfile(NULL),
+ m_framePosition(0),
+ m_externalConsumer(false),
+ m_isZoneMode(false),
+ m_isLoopMode(false),
+ m_isSplitView(false),
+ m_blackClip(NULL),
+ m_winid(winid)
{
- /*if (rendererName == "project") m_monitorId = 10000;
- else m_monitorId = 10001;*/
- /*m_osdTimer = new QTimer(this);
- connect(m_osdTimer, SIGNAL(timeout()), this, SLOT(slotOsdTimeout()));*/
if (profile.isEmpty()) profile = KdenliveSettings::current_profile();
buildConsumer(profile);
void Render::buildConsumer(const QString profileName)
{
- char *tmp;
m_activeProfile = profileName;
- tmp = decodedString(m_activeProfile);
+ char *tmp = qstrdup(m_activeProfile.toUtf8().constData());
setenv("MLT_PROFILE", tmp, 1);
delete m_blackClip;
m_blackClip = NULL;
//TODO: uncomment following line when everything is clean
//if (m_mltProfile) delete m_mltProfile;
m_mltProfile = new Mlt::Profile(tmp);
+ m_mltProfile->get_profile()->is_explicit = 1;
delete[] tmp;
+ m_blackClip = new Mlt::Producer(*m_mltProfile, "colour", "black");
+ m_blackClip->set("id", "black");
+ m_blackClip->set("mlt_type", "producer");
+
+ if (KdenliveSettings::external_display() && m_name != "clip") {
+ // Use blackmagic card for video output
+ QMap< QString, QString > profileProperties = ProfilesDialog::getSettingsFromFile(profileName);
+ if (BMInterface::isSupportedProfile(KdenliveSettings::blackmagic_output_device(), profileProperties)) {
+ QString decklink = "decklink:" + QString::number(KdenliveSettings::blackmagic_output_device());
+ tmp = qstrdup(decklink.toUtf8().constData());
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, tmp);
+ delete[] tmp;
+ if (m_mltConsumer->is_valid()) {
+ m_externalConsumer = true;
+ m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+ m_mltConsumer->set("terminate_on_pause", 0);
+ m_mltConsumer->set("buffer", 12);
+ m_mltConsumer->set("deinterlace_method", "onefield");
+ mlt_log_set_callback(kdenlive_callback);
+ }
+ if (m_mltConsumer && m_mltConsumer->is_valid()) return;
+ } else KMessageBox::informationList(qApp->activeWindow(), i18n("Your project's profile %1 is not compatible with the blackmagic output card. Please see supported profiles below. Switching to normal video display.", m_mltProfile->description()), BMInterface::supportedModes(KdenliveSettings::blackmagic_output_device()));
+ }
+ m_externalConsumer = false;
QString videoDriver = KdenliveSettings::videodrivername();
if (!videoDriver.isEmpty()) {
if (videoDriver == "x11_noaccel") {
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
//m_mltConsumer->set("fullscreen", 1);
-#ifdef Q_WS_MAC
- m_mltConsumer = new Mlt::Consumer(*m_mltProfile , "sdl_audio");
- m_mltConsumer->set("preview_off", 1);
- m_mltConsumer->set("preview_format", mlt_image_rgb24a);
-#else
- m_mltConsumer = new Mlt::Consumer(*m_mltProfile , "sdl_preview");
-#endif
+ if (m_winid == 0) {
+ // OpenGL monitor
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio");
+ m_mltConsumer->set("preview_off", 1);
+ m_mltConsumer->set("preview_format", mlt_image_rgb24a);
+ m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show);
+ } else {
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview");
+ // FIXME: the event object returned by the listen gets leaked...
+ m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+ m_mltConsumer->set("window_id", m_winid);
+ }
m_mltConsumer->set("resize", 1);
- m_mltConsumer->set("window_id", m_winid);
m_mltConsumer->set("terminate_on_pause", 1);
- tmp = decodedString(KdenliveSettings::window_background().name());
- m_mltConsumer->set("window_background", tmp);
- delete [] tmp;
-
- // FIXME: the event object returned by the listen gets leaked...
- m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+ m_mltConsumer->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData());
m_mltConsumer->set("rescale", "nearest");
mlt_log_set_callback(kdenlive_callback);
QString audioDevice = KdenliveSettings::audiodevicename();
- if (!audioDevice.isEmpty()) {
- tmp = decodedString(audioDevice);
- m_mltConsumer->set("audio_device", tmp);
- delete[] tmp;
- }
+ if (!audioDevice.isEmpty())
+ m_mltConsumer->set("audio_device", audioDevice.toUtf8().constData());
- if (!videoDriver.isEmpty()) {
- tmp = decodedString(videoDriver);
- m_mltConsumer->set("video_driver", tmp);
- delete[] tmp;
- }
+ if (!videoDriver.isEmpty())
+ m_mltConsumer->set("video_driver", videoDriver.toUtf8().constData());
QString audioDriver = KdenliveSettings::audiodrivername();
audioDriver = KdenliveSettings::autoaudiodrivername();
*/
- if (!audioDriver.isEmpty()) {
- tmp = decodedString(audioDriver);
- m_mltConsumer->set("audio_driver", tmp);
- delete[] tmp;
- }
-
- int volume = KdenliveSettings::volume();
- m_mltConsumer->set("volume", (float)volume / 100);
+ if (!audioDriver.isEmpty())
+ m_mltConsumer->set("audio_driver", audioDriver.toUtf8().constData());
m_mltConsumer->set("progressive", 1);
m_mltConsumer->set("audio_buffer", 1024);
m_mltConsumer->set("frequency", 48000);
-
- m_blackClip = new Mlt::Producer(*m_mltProfile , "colour", "black");
- m_blackClip->set("id", "black");
- m_blackClip->set("mlt_type", "producer");
-
}
Mlt::Producer *Render::invalidProducer(const QString &id)
{
- Mlt::Producer *clip = new Mlt::Producer(*m_mltProfile , "colour", "red");
- char *tmp = decodedString(id);
- clip->set("id", tmp);
- delete[] tmp;
+ Mlt::Producer *clip = new Mlt::Producer(*m_mltProfile, "colour", "red");
+ clip->set("id", id.toUtf8().constData());
clip->set("mlt_type", "producer");
return clip;
}
int Render::resetProfile(const QString profileName)
{
if (m_mltConsumer) {
- QString videoDriver = KdenliveSettings::videodrivername();
- QString currentDriver = m_mltConsumer->get("video_driver");
- if (getenv("SDL_VIDEO_YUV_HWACCEL") != NULL && currentDriver == "x11") currentDriver = "x11_noaccel";
- QString background = KdenliveSettings::window_background().name();
- QString currentBackground = m_mltConsumer->get("window_background");
- int volume = KdenliveSettings::volume();
- int currentVolume = (int)(QString(m_mltConsumer->get("volume")).toDouble() * 100.0);
- if (m_activeProfile == profileName && currentDriver == videoDriver && volume == currentVolume && background == currentBackground) {
- kDebug() << "reset to same profile, nothing to do";
- return 1;
+ if (m_externalConsumer == KdenliveSettings::external_display()) {
+ if (KdenliveSettings::external_display() && m_activeProfile == profileName) return 1;
+ QString videoDriver = KdenliveSettings::videodrivername();
+ QString currentDriver = m_mltConsumer->get("video_driver");
+ if (getenv("SDL_VIDEO_YUV_HWACCEL") != NULL && currentDriver == "x11") currentDriver = "x11_noaccel";
+ QString background = KdenliveSettings::window_background().name();
+ QString currentBackground = m_mltConsumer->get("window_background");
+ if (m_activeProfile == profileName && currentDriver == videoDriver && background == currentBackground) {
+ kDebug() << "reset to same profile, nothing to do";
+ return 1;
+ }
}
if (m_isSplitView) slotSplitView(false);
delete m_mltProducer;
}
m_mltProducer = NULL;
-
buildConsumer(profileName);
double new_fps = m_mltProfile->fps();
if (current_fps != new_fps) {
setSceneList(scene, pos);
// producers have changed (different profile), so reset them...
emit refreshDocumentProducers();
- /*char *tmp = decodedString(scene);
- Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "xml-string", tmp);
- delete[] tmp;
+ /*Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "xml-string", scene.toUtf8().constData());
m_mltProducer = producer;
m_blackClip = new Mlt::Producer(*m_mltProfile , "colour", "black");
m_mltProducer->optimise();
refresh();
}
-//static
-char *Render::decodedString(QString str)
+void Render::seek(int time)
{
- /*QCString fn = QFile::encodeName(str);
- char *t = new char[fn.length() + 1];
- strcpy(t, (const char *)fn);*/
-
- return (char *) qstrdup(str.toUtf8().data()); //toLatin1
+ if (!m_mltProducer)
+ return;
+ m_isBlocked = false;
+ m_mltProducer->seek(time);
+ refresh();
}
//static
//pixmap = im.scaled(width, height);
return pixmap;
}
-/*
-//static
-QPixmap Render::getVideoThumbnail(char *profile, QString file, int frame_position, int width, int height) {
- QPixmap pix(width, height);
- char *tmp = decodedString(file);
- Mlt::Profile *prof = new Mlt::Profile(profile);
- Mlt::Producer m_producer(*prof, tmp);
- delete[] tmp;
- if (m_producer.is_blank()) {
- pix.fill(Qt::black);
- return pix;
- }
-
- Mlt::Filter m_convert(*prof, "avcolour_space");
- m_convert.set("forced", mlt_image_rgb24a);
- m_producer.attach(m_convert);
- m_producer.seek(frame_position);
- Mlt::Frame * frame = m_producer.get_frame();
- if (frame) {
- pix = frameThumbnail(frame, width, height, true);
- delete frame;
- }
- if (prof) delete prof;
- return pix;
-}
-*/
-/*
-void Render::getImage(KUrl url, int frame_position, QPoint size)
-{
- char *tmp = decodedString(url.path());
- Mlt::Producer m_producer(tmp);
- delete[] tmp;
- if (m_producer.is_blank()) {
- return;
- }
- Mlt::Filter m_convert("avcolour_space");
- m_convert.set("forced", mlt_image_rgb24a);
- m_producer.attach(m_convert);
- m_producer.seek(frame_position);
-
- Mlt::Frame * frame = m_producer.get_frame();
-
- if (frame) {
- QPixmap pix = frameThumbnail(frame, size.x(), size.y(), true);
- delete frame;
- emit replyGetImage(url, frame_position, pix, size.x(), size.y());
- }
-}*/
-
-/* Create thumbnail for color */
-/*void Render::getImage(int id, QString color, QPoint size)
-{
- QPixmap pixmap(size.x() - 2, size.y() - 2);
- color = color.replace(0, 2, "#");
- color = color.left(7);
- pixmap.fill(QColor(color));
- QPixmap result(size.x(), size.y());
- result.fill(Qt::black);
- //copyBlt(&result, 1, 1, &pixmap, 0, 0, size.x() - 2, size.y() - 2);
- emit replyGetImage(id, result, size.x(), size.y());
-
-}*/
-
-/* Create thumbnail for image */
-/*void Render::getImage(KUrl url, QPoint size)
-{
- QImage im;
- QPixmap pixmap;
- if (url.fileName().startsWith(".all.")) { // check for slideshow
- QString fileType = url.fileName().right(3);
- QStringList more;
- QStringList::Iterator it;
-
- QDir dir( url.directory() );
- more = dir.entryList( QDir::Files );
- for ( it = more.begin() ; it != more.end() ; ++it ) {
- if ((*it).endsWith("."+fileType, Qt::CaseInsensitive)) {
- if (!im.load(url.directory() + '/' + *it))
- kDebug()<<"++ ERROR LOADIN IMAGE: "<<url.directory() + '/' + *it;
- break;
- }
- }
- }
- else im.load(url.path());
-
- //pixmap = im.smoothScale(size.x() - 2, size.y() - 2);
- QPixmap result(size.x(), size.y());
- result.fill(Qt::black);
- //copyBlt(&result, 1, 1, &pixmap, 0, 0, size.x() - 2, size.y() - 2);
- emit replyGetImage(url, 1, result, size.x(), size.y());
-}*/
-
double Render::consumerRatio() const
{
bool Render::isValid(KUrl url)
{
- char *tmp = decodedString(url.path());
- Mlt::Producer producer(*m_mltProfile, tmp);
- delete[] tmp;
+ Mlt::Producer producer(*m_mltProfile, url.path().toUtf8().constData());
if (producer.is_blank())
return false;
return m_mltProfile->dar();
}
+double Render::sar() const
+{
+ return m_mltProfile->sar();
+}
+
void Render::slotSplitView(bool doit)
{
m_isSplitView = doit;
}
}
-void Render::getFileProperties(const QDomElement xml, const QString &clipId, int imageHeight, bool replaceProducer)
+void Render::getFileProperties(const QDomElement xml, const QString &clipId, int imageHeight, bool replaceProducer, bool selectClip)
{
- KUrl url = KUrl(xml.attribute("resource", QString()));
+ QString path;
+ if (xml.hasAttribute("proxy")) path = xml.attribute("proxy");
+ else path = xml.attribute("resource");
+ KUrl url = KUrl(path);
Mlt::Producer *producer = NULL;
+ CLIPTYPE type = (CLIPTYPE)xml.attribute("type").toInt();
//kDebug() << "PROFILE WIDT: "<< xml.attribute("mlt_service") << ": "<< m_mltProfile->width() << "\n...................\n\n";
/*if (xml.attribute("type").toInt() == TEXT && !QFile::exists(url.path())) {
emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer);
return;
}*/
- if (xml.attribute("type").toInt() == COLOR) {
- char *tmp = decodedString("colour:" + xml.attribute("colour"));
- producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
- delete[] tmp;
- } else if (xml.attribute("type").toInt() == TEXT) {
- char *tmp = decodedString("kdenlivetitle:" + xml.attribute("resource"));
- producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
- delete[] tmp;
- if (producer && xml.hasAttribute("xmldata")) {
- tmp = decodedString(xml.attribute("xmldata"));
- producer->set("xmldata", tmp);
- delete[] tmp;
- }
+
+ if (type == COLOR) {
+ producer = new Mlt::Producer(*m_mltProfile, 0, ("colour:" + xml.attribute("colour")).toUtf8().constData());
+ } else if (type == TEXT) {
+ producer = new Mlt::Producer(*m_mltProfile, 0, ("kdenlivetitle:" + xml.attribute("resource")).toUtf8().constData());
+ if (producer && producer->is_valid() && xml.hasAttribute("xmldata"))
+ producer->set("xmldata", xml.attribute("xmldata").toUtf8().constData());
} else if (url.isEmpty()) {
QDomDocument doc;
QDomElement mlt = doc.createElement("mlt");
doc.appendChild(mlt);
mlt.appendChild(play);
play.appendChild(doc.importNode(xml, true));
- char *tmp = decodedString(doc.toString());
- producer = new Mlt::Producer(*m_mltProfile, "xml-string", tmp);
- delete[] tmp;
+ producer = new Mlt::Producer(*m_mltProfile, "xml-string", doc.toString().toUtf8().constData());
} else {
- char *tmp = decodedString(url.path());
- producer = new Mlt::Producer(*m_mltProfile, tmp);
- delete[] tmp;
+ producer = new Mlt::Producer(*m_mltProfile, url.path().toUtf8().constData());
}
if (producer == NULL || producer->is_blank() || !producer->is_valid()) {
if (aspect > 0) producer->set("force_aspect_ratio", aspect);
}
+ if (xml.hasAttribute("force_aspect_num") && xml.hasAttribute("force_aspect_den")) {
+ int width = xml.attribute("frame_size").section('x', 0, 0).toInt();
+ int height = xml.attribute("frame_size").section('x', 1, 1).toInt();
+ int aspectNumerator = xml.attribute("force_aspect_num").toInt();
+ int aspectDenominator = xml.attribute("force_aspect_den").toInt();
+ if (aspectDenominator != 0 && width != 0)
+ producer->set("force_aspect_ratio", double(height) * aspectNumerator / aspectDenominator / width);
+ }
+
if (xml.hasAttribute("force_fps")) {
double fps = xml.attribute("force_fps").toDouble();
if (fps > 0) producer->set("force_fps", fps);
int progressive = xml.attribute("force_progressive").toInt(&ok);
if (ok) producer->set("force_progressive", progressive);
}
+ if (xml.hasAttribute("force_tff")) {
+ bool ok;
+ int fieldOrder = xml.attribute("force_tff").toInt(&ok);
+ if (ok) producer->set("force_tff", fieldOrder);
+ }
if (xml.hasAttribute("threads")) {
int threads = xml.attribute("threads").toInt();
if (threads != 1) producer->set("threads", threads);
int aindex = xml.attribute("audio_index").toInt();
if (aindex != 0) producer->set("audio_index", aindex);
}
+ if (xml.hasAttribute("force_colorspace")) {
+ int colorspace = xml.attribute("force_colorspace").toInt();
+ if (colorspace != 0) producer->set("force_colorspace", colorspace);
+ }
+ if (xml.hasAttribute("full_luma")) {
+ int full_luma = xml.attribute("full_luma").toInt();
+ if (full_luma != 0) producer->set("set.force_full_luma", full_luma);
+ }
// setup length here as otherwise default length (currently 15000 frames in MLT) will be taken even if outpoint is larger
- if (xml.attribute("type").toInt() == COLOR || xml.attribute("type").toInt() == TEXT
- || xml.attribute("type").toInt() == IMAGE || xml.attribute("type").toInt() == SLIDESHOW)
+ if (type == COLOR || type == TEXT || type == IMAGE || type == SLIDESHOW)
producer->set("length", xml.attribute("out").toInt() - xml.attribute("in").toInt() + 1);
- if (xml.hasAttribute("out")) producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt());
+ if (xml.hasAttribute("out"))
+ producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt());
- char *tmp = decodedString(clipId);
- producer->set("id", tmp);
- delete[] tmp;
+ producer->set("id", clipId.toUtf8().constData());
- if (xml.hasAttribute("templatetext")) {
- char *tmp = decodedString(xml.attribute("templatetext"));
- producer->set("templatetext", tmp);
- delete[] tmp;
- }
+ if (xml.hasAttribute("templatetext"))
+ producer->set("templatetext", xml.attribute("templatetext").toUtf8().constData());
- if (!replaceProducer && xml.hasAttribute("file_hash")) {
+ if ((!replaceProducer && xml.hasAttribute("file_hash")) || xml.hasAttribute("proxy")) {
// Clip already has all properties
- emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer);
+ emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer, selectClip);
return;
}
Mlt::Frame *frame = producer->get_frame();
- if (xml.attribute("type").toInt() == SLIDESHOW) {
+ if (type == SLIDESHOW) {
int ttl = xml.hasAttribute("ttl") ? xml.attribute("ttl").toInt() : 0;
if (ttl) producer->set("ttl", ttl);
if (!xml.attribute("animation").isEmpty()) {
if (ttl) filter->set("cycle", ttl);
if (xml.hasAttribute("luma_duration") && !xml.attribute("luma_duration").isEmpty()) filter->set("duration", xml.attribute("luma_duration").toInt());
if (xml.hasAttribute("luma_file") && !xml.attribute("luma_file").isEmpty()) {
- char *tmp = decodedString(xml.attribute("luma_file"));
- filter->set("luma.resource", tmp);
- delete[] tmp;
+ filter->set("luma.resource", xml.attribute("luma_file").toUtf8().constData());
if (xml.hasAttribute("softness")) {
int soft = xml.attribute("softness").toInt();
filter->set("luma.softness", (double) soft / 100.0);
}
}
-
- filePropertyMap["fps"] = producer->get("source_fps");
+ if (producer->get_double("meta.media.frame_rate_den") > 0) {
+ filePropertyMap["fps"] = QString::number(producer->get_double("meta.media.frame_rate_num") / producer->get_double("meta.media.frame_rate_den"));
+ } else filePropertyMap["fps"] = producer->get("source_fps");
if (frame && frame->is_valid()) {
filePropertyMap["frame_size"] = QString::number(frame->get_int("width")) + 'x' + QString::number(frame->get_int("height"));
int frame_width = width;
int frame_height = imageHeight;
uint8_t *data = frame->get_image(format, frame_width, frame_height, 0);
- QImage image((uchar *)data, frame_width, frame_height, QImage::Format_ARGB32);
+ QImage image((uchar *)data, frame_width, frame_height, QImage::Format_ARGB32_Premultiplied);
QPixmap pix;
if (!image.isNull()) {
if (producer->get(property))
filePropertyMap["videocodec"] = producer->get(property);
}
-
- if (KdenliveSettings::dropbframes()) {
- kDebug() << "// LOOKING FOR H264 on: " << default_video;
- snprintf(property, sizeof(property), "meta.media.%d.codec.name", default_video);
- kDebug() << "PROP: " << property << " = " << producer->get(property);
- if (producer->get(property) && strcmp(producer->get(property), "h264") == 0) {
- kDebug() << "// GOT H264 CLIP, SETTING FAST PROPS";
- producer->set("skip_loop_filter", "all");
- producer->set("skip_frame", "bidir");
- }
- }
+ QString query;
+ query = QString("meta.media.%1.codec.pix_fmt").arg(default_video);
+ filePropertyMap["pix_fmt"] = producer->get(query.toUtf8().constData());
+ filePropertyMap["colorspace"] = producer->get("meta.media.colorspace");
} else kDebug() << " / / / / /WARNING, VIDEO CONTEXT IS NULL!!!!!!!!!!!!!!";
if (producer->get_int("audio_index") > -1) {
metadataPropertyMap[ name.section('.', 0, -2)] = value;
}
producer->seek(0);
- kDebug() << "REquested fuile info for: " << url.path();
- emit replyGetFileProperties(clipId, producer, filePropertyMap, metadataPropertyMap, replaceProducer);
+ emit replyGetFileProperties(clipId, producer, filePropertyMap, metadataPropertyMap, replaceProducer, selectClip);
// FIXME: should delete this to avoid a leak...
//delete producer;
}
} else return -1;
m_mltConsumer->purge();
-
m_isBlocked = true;
if (m_mltProducer) {
m_mltProducer->set_speed(0);
if (producer) {
m_mltProducer = new Mlt::Producer(producer->get_producer());
} else m_mltProducer = m_blackClip->cut(0, 50);
- /*if (KdenliveSettings::dropbframes()) {
- m_mltProducer->set("skip_loop_filter", "all");
- m_mltProducer->set("skip_frame", "bidir");
- }*/
+
if (!m_mltProducer || !m_mltProducer->is_valid()) {
kDebug() << " WARNING - - - - -INVALID PLAYLIST: ";
return -1;
}
-
+ int volume = KdenliveSettings::volume();
+ m_mltProducer->set("meta.volume", (double)volume / 100);
m_fps = m_mltProducer->get_fps();
int error = connectPlaylist();
m_isBlocked = true;
int error = 0;
- kDebug() << "////// RENDER, SET SCENE LIST: " << playlist;
+ //kDebug() << "////// RENDER, SET SCENE LIST: " << playlist;
+
+ // Remove previous profile info
+ QDomDocument doc;
+ doc.setContent(playlist);
+ QDomElement profile = doc.documentElement().firstChildElement("profile");
+ doc.documentElement().removeChild(profile);
+ playlist = doc.toString();
if (m_mltConsumer) {
if (!m_mltConsumer->is_stopped()) {
m_mltProducer->set_speed(0);
//if (KdenliveSettings::osdtimecode() && m_osdInfo) m_mltProducer->detach(*m_osdInfo);
-
Mlt::Service service(m_mltProducer->parent().get_service());
mlt_service_lock(service.get_service());
}
blockSignals(true);
- char *tmp = decodedString(playlist);
- m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", tmp);
+ // TODO: Better way to do this
+ if (KdenliveSettings::projectloading_avformatnovalidate())
+ playlist.replace(">avformat</property>", ">avformat-novalidate</property>");
+ else
+ playlist.replace(">avformat-novalidate</property>", ">avformat</property>");
+ m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", playlist.toUtf8().constData());
if (!m_mltProducer || !m_mltProducer->is_valid()) {
- kDebug() << " WARNING - - - - -INVALID PLAYLIST: " << tmp;
+ kDebug() << " WARNING - - - - -INVALID PLAYLIST: " << playlist.toUtf8().constData();
m_mltProducer = m_blackClip->cut(0, 50);
error = -1;
}
- delete[] tmp;
-
+ int volume = KdenliveSettings::volume();
+ m_mltProducer->set("meta.volume", (double)volume / 100);
m_mltProducer->optimise();
/*if (KdenliveSettings::osdtimecode()) {
mlt_filter_close( filter );
m_osdInfo = new Mlt::Filter("data_show");
- tmp = decodedString(m_osdProfile);
- m_osdInfo->set("resource", tmp);
- delete[] tmp;
+ m_osdInfo->set("resource", m_osdProfile.toUtf8().constData());
mlt_properties properties = MLT_PRODUCER_PROPERTIES(m_mltProducer->get_producer());
mlt_properties_set_int( properties, "meta.attr.timecode", 1);
mlt_properties_set( properties, "meta.attr.timecode.markup", "#timecode#");
const QString Render::sceneList()
{
QString playlist;
- Mlt::Consumer xmlConsumer(*m_mltProfile , "xml:kdenlive_playlist");
+ Mlt::Profile profile((mlt_profile) 0);
+ Mlt::Consumer xmlConsumer(profile, "xml:kdenlive_playlist");
m_mltProducer->optimise();
xmlConsumer.set("terminate_on_pause", 1);
Mlt::Producer prod(m_mltProducer->get_producer());
void Render::saveZone(KUrl url, QString desc, QPoint zone)
{
kDebug() << "// SAVING CLIP ZONE, RENDER: " << m_name;
- char *tmppath = decodedString("xml:" + url.path());
- Mlt::Consumer xmlConsumer(*m_mltProfile , tmppath);
+ Mlt::Consumer xmlConsumer(*m_mltProfile, ("xml:" + url.path()).toUtf8().constData());
m_mltProducer->optimise();
- delete[] tmppath;
xmlConsumer.set("terminate_on_pause", 1);
if (m_name == "clip") {
Mlt::Producer *prod = m_mltProducer->cut(zone.x(), zone.y());
- tmppath = decodedString(desc);
Mlt::Playlist list;
list.insert_at(0, prod, 0);
delete prod;
- list.set("title", tmppath);
- delete[] tmppath;
+ list.set("title", desc.toUtf8().constData());
xmlConsumer.connect(list);
} else {
if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM";*/
//Mlt::Producer *prod = p1->cut(zone.x(), zone.y());
- tmppath = decodedString(desc);
- //prod->set("title", tmppath);
- delete[] tmppath;
+ //prod->set("title", desc.toUtf8().constData());
xmlConsumer.connect(*p1); //list);
}
refresh();
}
-void Render::setVolume(double /*volume*/)
+int Render::volume() const
+{
+ if (!m_mltConsumer || !m_mltProducer) return -1;
+ return ((int) 100 * m_mltProducer->get_double("meta.volume"));
+}
+
+void Render::slotSetVolume(int volume)
{
if (!m_mltConsumer || !m_mltProducer) return;
+ m_mltProducer->set("meta.volume", (double)volume / 100.0);
+ return;
/*osdTimer->stop();
m_mltConsumer->set("refresh", 0);
// Attach filter for on screen display of timecode
int dropFrames = 1;
if (show == false) dropFrames = 0;
m_mltConsumer->stop();
-#ifdef Q_WS_MAC
- m_mltConsumer->set("real_time", dropFrames);
-#else
- m_mltConsumer->set("play.real_time", dropFrames);
-#endif
+ if (m_winid == 0)
+ m_mltConsumer->set("real_time", dropFrames);
+ else
+ m_mltConsumer->set("play.real_time", dropFrames);
+
if (m_mltConsumer->start() == -1) {
kDebug(QtWarningMsg) << "ERROR, Cannot start monitor";
}
if (m_isLoopMode) play(m_loopStart);
else if (m_isZoneMode) resetZoneMode();
emit rendererStopped((int) pos);
- //if (qApp->activeWindow()) QApplication::postEvent(qApp->activeWindow(), new PositionChangeEvent(GenTime((int) pos, m_fps), m_monitorId + 100));
- //new QCustomEvent(10002));
}
}
//if (notify) QApplication::postEvent(qApp->activeWindow(), new UrlEvent(url, 10003));
}
-#ifdef Q_WS_MAC
+
void Render::showFrame(Mlt::Frame& frame)
{
+ m_framePosition = qMax(frame.get_int("_position"), 0);
+ emit rendererPosition((int) m_framePosition);
mlt_image_format format = mlt_image_rgb24a;
int width = 0;
int height = 0;
const uchar* image = frame.get_image(format, width, height);
- QImage qimage(width, height, QImage::Format_ARGB32);
+ QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied);
memcpy(qimage.scanLine(0), image, width * height * 4);
emit showImageSignal(qimage);
+ if (analyseAudio) showAudio(frame);
+ if (sendFrameForAnalysis && frame.get_frame()->convert_image) {
+ emit frameUpdated(qimage.rgbSwapped());
+ }
}
-#endif
+void Render::showAudio(Mlt::Frame& frame)
+{
+ if (!frame.is_valid() || frame.get_int("test_audio") != 0) {
+ return;
+ }
+ mlt_audio_format audio_format = mlt_audio_s16;
+ int freq = 0;
+ int num_channels = 0;
+ int samples = 0;
+ int16_t* data = (int16_t*)frame.get_audio(audio_format, freq, num_channels, samples);
+
+ if (!data) {
+ return;
+ }
+
+ // Data format: [ c00 c10 c01 c11 c02 c12 c03 c13 ... c0{samples-1} c1{samples-1} for 2 channels.
+ // So the vector is of size samples*channels.
+ QVector<int16_t> sampleVector(samples*num_channels);
+ memcpy(sampleVector.data(), data, samples*num_channels*sizeof(int16_t));
+
+ if (samples > 0) {
+ emit audioSamplesSignal(sampleVector, freq, num_channels, samples);
+ }
+}
/*
* MLT playlist direct manipulation.
if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
if (!slowprod || slowprod->get_producer() == NULL) {
- char *tmp = decodedString(url);
- slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
+ slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", url.toUtf8().constData());
if (strobe > 1) slowprod->set("strobe", strobe);
- delete[] tmp;
QString id = prod->get("id");
if (id.contains('_')) id = id.section('_', 0, 0);
QString producerid = "slowmotion:" + id + ':' + QString::number(speed);
if (strobe > 1) producerid.append(':' + QString::number(strobe));
- tmp = decodedString(producerid);
- slowprod->set("id", tmp);
- delete[] tmp;
+ slowprod->set("id", producerid.toUtf8().constData());
m_slowmotionProducers.insert(url, slowprod);
}
return slowprod;
mlt_service_unlock(service.get_service());
return false;
}
- Mlt::Producer *clip2 = prod->cut(info.cropStart.frames(m_fps), (info.cropDuration + info.cropStart).frames(m_fps));
+
+ Mlt::Producer *clip2 = prod->cut(info.cropStart.frames(m_fps), (info.cropDuration + info.cropStart).frames(m_fps) - 1);
trackPlaylist.insert_at(info.startPos.frames(m_fps), clip2, 1);
delete clip2;
}
int position = trackPlaylist.clip_start(clipIndex);
int blankDuration = trackPlaylist.clip_length(clipIndex);
- diff = -diff;
- if (blankDuration - diff == 0) {
+ if (blankDuration + diff == 0) {
trackPlaylist.remove(clipIndex);
- } else trackPlaylist.remove_region(position, diff);
+ } else trackPlaylist.remove_region(position, -diff);
}
trackPlaylist.consolidate_blanks(0);
}
QString id = clipparent.get("id");
if (speed <= 0 && speed > -1) speed = 1.0;
//kDebug() << "CLIP SERVICE: " << serv;
- if (serv == "avformat" && (speed != 1.0 || strobe > 1)) {
+ if ((serv == "avformat" || serv == "avformat-novalidate") && (speed != 1.0 || strobe > 1)) {
mlt_service_lock(service.get_service());
QString url = QString::fromUtf8(clipparent.get("resource"));
url.append('?' + QString::number(speed));
if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
if (!slowprod || slowprod->get_producer() == NULL) {
- char *tmp = decodedString("framebuffer:" + url);
- slowprod = new Mlt::Producer(*m_mltProfile, 0, tmp);
+ slowprod = new Mlt::Producer(*m_mltProfile, 0, ("framebuffer:" + url).toUtf8().constData());
if (strobe > 1) slowprod->set("strobe", strobe);
- delete[] tmp;
QString producerid = "slowmotion:" + id + ':' + QString::number(speed);
if (strobe > 1) producerid.append(':' + QString::number(strobe));
- tmp = decodedString(producerid);
- slowprod->set("id", tmp);
- delete[] tmp;
+ slowprod->set("id", producerid.toUtf8().constData());
// copy producer props
double ar = original->parent().get_double("force_aspect_ratio");
if (ar != 0.0) slowprod->set("force_aspect_ratio", ar);
if (threads != 0) slowprod->set("threads", threads);
if (original->parent().get("force_progressive"))
slowprod->set("force_progressive", original->parent().get_int("force_progressive"));
+ if (original->parent().get("force_tff"))
+ slowprod->set("force_tff", original->parent().get_int("force_tff"));
int ix = original->parent().get_int("video_index");
if (ix != 0) slowprod->set("video_index", ix);
+ int colorspace = original->parent().get_int("force_colorspace");
+ if (colorspace != 0) slowprod->set("force_colorspace", colorspace);
+ int full_luma = original->parent().get_int("set.force_full_luma");
+ if (full_luma != 0) slowprod->set("set.force_full_luma", full_luma);
m_slowmotionProducers.insert(url, slowprod);
}
Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
if (!slowprod || slowprod->get_producer() == NULL) {
- char *tmp = decodedString("framebuffer:" + url);
- slowprod = new Mlt::Producer(*m_mltProfile, 0, tmp);
- delete[] tmp;
+ slowprod = new Mlt::Producer(*m_mltProfile, 0, ("framebuffer:" + url).toUtf8().constData());
slowprod->set("strobe", strobe);
QString producerid = "slowmotion:" + id.section(':', 1, 1) + ':' + QString::number(speed);
if (strobe > 1) producerid.append(':' + QString::number(strobe));
- tmp = decodedString(producerid);
- slowprod->set("id", tmp);
- delete[] tmp;
+ slowprod->set("id", producerid.toUtf8().constData());
// copy producer props
double ar = original->parent().get_double("force_aspect_ratio");
if (ar != 0.0) slowprod->set("force_aspect_ratio", ar);
if (fps != 0.0) slowprod->set("force_fps", fps);
if (original->parent().get("force_progressive"))
slowprod->set("force_progressive", original->parent().get_int("force_progressive"));
+ if (original->parent().get("force_tff"))
+ slowprod->set("force_tff", original->parent().get_int("force_tff"));
int threads = original->parent().get_int("threads");
if (threads != 0) slowprod->set("threads", threads);
int ix = original->parent().get_int("video_index");
if (ix != 0) slowprod->set("video_index", ix);
+ int colorspace = original->parent().get_int("force_colorspace");
+ if (colorspace != 0) slowprod->set("force_colorspace", colorspace);
+ int full_luma = original->parent().get_int("set.force_full_luma");
+ if (full_luma != 0) slowprod->set("set.force_full_luma", full_luma);
m_slowmotionProducers.insert(url, slowprod);
}
Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
Mlt::Producer trackProducer(tractor.track(track));
Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
Mlt::Service trackService(trackProducer.get_service()); //trackPlaylist
- return mltAddEffect(trackService, params, 15000, true);
+ return mltAddEffect(trackService, params, trackProducer.get_playtime() - 1, true);
}
QString tag = params.paramValue("tag");
kDebug() << " / / INSERTING EFFECT: " << tag << ", REGI: " << region;
if (tag.startsWith("ladspa")) tag = "ladspa";
- char *filterTag = decodedString(tag);
- char *filterId = decodedString(params.paramValue("id"));
+ char *filterTag = qstrdup(tag.toUtf8().constData());
+ char *filterId = qstrdup(params.paramValue("id").toUtf8().constData());
QHash<QString, QString>::Iterator it;
QString kfr = params.paramValue("keyframes");
if (!kfr.isEmpty()) {
QStringList keyFrames = kfr.split(';', QString::SkipEmptyParts);
kDebug() << "// ADDING KEYFRAME EFFECT: " << params.paramValue("keyframes");
- char *starttag = decodedString(params.paramValue("starttag", "start"));
- char *endtag = decodedString(params.paramValue("endtag", "end"));
+ char *starttag = qstrdup(params.paramValue("starttag", "start").toUtf8().constData());
+ char *endtag = qstrdup(params.paramValue("endtag", "end").toUtf8().constData());
kDebug() << "// ADDING KEYFRAME TAGS: " << starttag << ", " << endtag;
//double max = params.paramValue("max").toDouble();
double min = params.paramValue("min").toDouble();
int x1 = keyFrames.at(0).section(':', 0, 0).toInt();
double y1 = keyFrames.at(0).section(':', 1, 1).toDouble();
for (int j = 0; j < params.count(); j++) {
- char *name = decodedString(params.at(j).name());
- char *value = decodedString(params.at(j).value());
- filter->set(name, value);
- delete[] name;
- delete[] value;
+ filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData());
}
filter->set("in", x1);
//kDebug() << "// ADDING KEYFRAME vals: " << min<<" / "<<max<<", "<<y1<<", factor: "<<factor;
if (x2 == -1) x2 = duration;
for (int j = 0; j < params.count(); j++) {
- char *name = decodedString(params.at(j).name());
- char *value = decodedString(params.at(j).value());
- filter->set(name, value);
- delete[] name;
- delete[] value;
+ filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData());
}
filter->set("in", x1);
if (filter && filter->is_valid()) {
filter->set("kdenlive_id", filterId);
if (!region.isEmpty()) {
- char *tmp = decodedString(region);
- filter->set("resource", tmp);
- tmp = decodedString(params.paramValue("kdenlive_ix"));
- filter->set("kdenlive_ix", tmp);
+ filter->set("resource", region.toUtf8().constData());
+ filter->set("kdenlive_ix", params.paramValue("kdenlive_ix").toUtf8().constData());
filter->set("filter0", filterTag);
prefix = "filter0.";
- delete[] tmp;
params.removeParam("id");
params.removeParam("region");
params.removeParam("kdenlive_ix");
params.removeParam("kdenlive_id");
for (int j = 0; j < params.count(); j++) {
- char *name = decodedString(prefix + params.at(j).name());
- char *value = decodedString(params.at(j).value());
- filter->set(name, value);
- delete[] name;
- delete[] value;
+ filter->set((prefix + params.at(j).name()).toUtf8().constData(), params.at(j).value().toUtf8().constData());
}
if (tag == "sox") {
effectArgs.append(' ' + params.at(j).value());
}
//kDebug() << "SOX EFFECTS: " << effectArgs.simplified();
- char *value = decodedString(effectArgs.simplified());
- filter->set("effect", value);
- delete[] value;
+ filter->set("effect", effectArgs.simplified().toUtf8().constData());
}
if (params.paramValue("id") == "pan_zoom") {
if (ser == "region") prefix = "filter0.";
mlt_service_lock(service.get_service());
for (int j = 0; j < params.count(); j++) {
- char *name = decodedString(prefix + params.at(j).name());
- char *value = decodedString(params.at(j).value());
- filter->set(name, value);
- delete[] name;
- delete[] value;
+ filter->set((prefix + params.at(j).name()).toUtf8().constData(), params.at(j).value().toUtf8().constData());
}
mlt_service_unlock(service.get_service());
if (ser == "region") prefix = "filter0.";
mlt_service_lock(service.get_service());
for (int j = 0; j < params.count(); j++) {
- char *name = decodedString(prefix + params.at(j).name());
- char *value = decodedString(params.at(j).value());
- filter->set(name, value);
- delete[] name;
- delete[] value;
+ filter->set((prefix + params.at(j).name()).toUtf8().constData(), params.at(j).value().toUtf8().constData());
}
mlt_service_unlock(service.get_service());
int clipIndex = trackPlaylist.get_clip_index_at((int) info.startPos.frames(m_fps));
//kDebug() << "// SELECTED CLIP START: " << trackPlaylist.clip_start(clipIndex);
Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex);
+
int previousStart = clip->get_in();
int newDuration = (int) clipDuration.frames(m_fps) - 1;
- int currentOut = (int)(info.cropStart + info.cropDuration).frames(m_fps) - 1;
int diff = newDuration - (trackPlaylist.clip_length(clipIndex) - 1);
+
+ int currentOut = newDuration + previousStart;
if (currentOut > clip->get_length()) {
clip->parent().set("length", currentOut + 1);
clip->parent().set("out", currentOut);
clip->set("length", currentOut + 1);
}
+
/*if (newDuration > clip->get_out()) {
clip->parent().set_in_and_out(0, newDuration + 1);
clip->set_in_and_out(0, newDuration + 1);
m_isBlocked = true;
previousStart += moveFrame;
+
if (previousStart < 0) {
- // special case, in point becoming negative (resizing images)
+ // this is possible for images and color clips
previousOut -= previousStart;
previousStart = 0;
}
if (! trackPlaylist.is_blank(blankIndex)) {
kDebug() << "WARNING, CLIP TO RESIZE IS NOT BLANK";
}
- if (blankLength + moveFrame == 0) trackPlaylist.remove(blankIndex);
- else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1);
+ if (blankLength + moveFrame == 0)
+ trackPlaylist.remove(blankIndex);
+ else
+ trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1);
}
trackPlaylist.consolidate_blanks(0);
/*if (QString(clip->parent().get("transparency")).toInt() == 1) {
found = true;
if (newTrack - startTrack != 0) {
Mlt::Properties trans_props(transition.get_properties());
- char *tmp = decodedString(transition.get("mlt_service"));
- Mlt::Transition new_transition(*m_mltProfile, tmp);
- delete[] tmp;
+ Mlt::Transition new_transition(*m_mltProfile, transition.get("mlt_service"));
Mlt::Properties new_trans_props(new_transition.get_properties());
new_trans_props.inherit(trans_props);
new_transition.set_in_and_out(new_in, new_out);
int bTrack = transition.get_b_track();
if (resource != "mix" && (aTrack < a_track || (aTrack == a_track && bTrack > b_track))) {
Mlt::Properties trans_props(transition.get_properties());
- char *tmp = decodedString(transition.get("mlt_service"));
- Mlt::Transition *cp = new Mlt::Transition(*m_mltProfile, tmp);
- delete[] tmp;
+ 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);
trList.append(cp);
mlt_type = mlt_properties_get(properties, "mlt_type");
resource = mlt_properties_get(properties, "mlt_service");
}
-
field->plant_transition(tr, a_track, b_track);
// re-add upper transitions
- for (int i = 0; i < trList.count(); i++) {
- // kDebug()<< "REPLANT ON TK: "<<trList.at(i)->get_a_track()<<", "<<trList.at(i)->get_b_track();
+ for (int i = trList.count() - 1; i >= 0; i--) {
+ //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());
}
}
{
if (oldTag == tag && !force) mltUpdateTransitionParams(tag, a_track, b_track, in, out, xml);
else {
+ kDebug()<<"// DELETING TRANS: "<<a_track<<"-"<<b_track;
mltDeleteTransition(oldTag, a_track, b_track, in, out, xml, false);
mltAddTransition(tag, a_track, b_track, in, out, xml, false);
}
QString currentId = mlt_properties_get(transproperties, "kdenlive_id");
if (currentId != xml.attribute("id")) {
// The transition ID is not the same, so reset all properties
- char *tmp = decodedString(xml.attribute("id"));
- mlt_properties_set(transproperties, "kdenlive_id", tmp);
- delete[] tmp;
+ mlt_properties_set(transproperties, "kdenlive_id", xml.attribute("id").toUtf8().constData());
// Cleanup previous properties
QStringList permanentProps;
permanentProps << "factory" << "kdenlive_id" << "mlt_service" << "mlt_type" << "in";
for (int i = 0; i < mlt_properties_count(transproperties); i++) {
QString propName = mlt_properties_get_name(transproperties, i);
if (!propName.startsWith('_') && ! permanentProps.contains(propName)) {
- tmp = decodedString(propName);
- mlt_properties_set(transproperties, tmp, "");
- delete[] tmp;
+ mlt_properties_set(transproperties, propName.toUtf8().constData(), "");
}
}
}
}
for (it = map.begin(); it != map.end(); ++it) {
key = it.key();
- char *name = decodedString(key);
- char *value = decodedString(it.value());
- mlt_properties_set(transproperties, name, value);
- //kDebug() << " ------ UPDATING TRANS PARAM: " << name << ": " << value;
+ mlt_properties_set(transproperties, key.toUtf8().constData(), it.value().toUtf8().constData());
+ //kDebug() << " ------ UPDATING TRANS PARAM: " << key.toUtf8().constData() << ": " << it.value().toUtf8().constData();
//filter->set("kdenlive_id", id);
- delete[] name;
- delete[] value;
}
break;
}
Mlt::Tractor tractor(service);
Mlt::Field *field = tractor.field();
- char *transId = decodedString(tag);
- Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, transId);
+ Mlt::Transition *transition = new Mlt::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);
for (it = args.begin(); it != args.end(); ++it) {
key = it.key();
- char *name = decodedString(key);
- char *value = decodedString(it.value());
- if (it.value().isEmpty() == false) transition->set(name, value);
- //kDebug() << " ------ ADDING TRANS PARAM: " << name << ": " << value;
- delete[] name;
- delete[] value;
+ if (!it.value().isEmpty())
+ transition->set(key.toUtf8().constData(), it.value().toUtf8().constData());
+ //kDebug() << " ------ ADDING TRANS PARAM: " << key << ": " << it.value();
}
// attach transition
+ m_isBlocked++;
+ mlt_service_lock(service.get_service());
mltPlantTransition(field, *transition, a_track, b_track);
// field->plant_transition(*transition, a_track, b_track);
- delete[] transId;
+ mlt_service_unlock(service.get_service());
+ m_isBlocked--;
if (do_refresh) refresh();
return true;
}