#include "kdenlivesettings.h"
#include "kthumb.h"
#include "definitions.h"
+#include "slideshowclip.h"
#include <mlt++/Mlt.h>
{
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);
}
#ifdef Q_WS_MAC
self->showFrame(frame);
#endif
-
+ self->showAudio(frame);
self->emitFrameNumber(mlt_frame_get_position(frame_ptr));
- if (frame_ptr->convert_image)
+ if (self->sendFrameForAnalysis && frame_ptr->convert_image) {
self->emitFrameUpdated(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) {
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),
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;
//m_mltConsumer->set("fullscreen", 1);
#ifdef Q_WS_MAC
- m_mltConsumer = new Mlt::Consumer(*m_mltProfile , "sdl_audio");
+ 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");
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview");
#endif
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;
+ m_mltConsumer->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData());
// FIXME: the event object returned by the listen gets leaked...
m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
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;
- }
+ if (!audioDriver.isEmpty())
+ m_mltConsumer->set("audio_driver", audioDriver.toUtf8().constData());
int volume = KdenliveSettings::volume();
m_mltConsumer->set("volume", (float)volume / 100);
m_mltConsumer->set("audio_buffer", 1024);
m_mltConsumer->set("frequency", 48000);
- m_blackClip = new Mlt::Producer(*m_mltProfile , "colour", "black");
+ 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;
}
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)
-{
- /*QCString fn = QFile::encodeName(str);
- char *t = new char[fn.length() + 1];
- strcpy(t, (const char *)fn);*/
-
- return (char *) qstrdup(str.toUtf8().data()); //toLatin1
-}
-
//static
/*QPixmap Render::frameThumbnail(Mlt::Frame *frame, int width, int height, bool border) {
QPixmap pix(width, height);
return pix;
}
*/
+int Render::frameRenderWidth() const
+{
+ return m_mltProfile->width();
+}
+
int Render::renderWidth() const
{
return (int)(m_mltProfile->height() * m_mltProfile->dar() + 0.5);
//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;
+ Mlt::Producer m_producer(*prof, file.toUtf8().constData());
if (m_producer.is_blank()) {
pix.fill(Qt::black);
return pix;
/*
void Render::getImage(KUrl url, int frame_position, QPoint size)
{
- char *tmp = decodedString(url.path());
- Mlt::Producer m_producer(tmp);
- delete[] tmp;
+ Mlt::Producer m_producer(url.path().toUtf8().constData());
if (m_producer.is_blank()) {
return;
}
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;
}*/
if (xml.attribute("type").toInt() == COLOR) {
- char *tmp = decodedString("colour:" + xml.attribute("colour"));
- producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
- delete[] tmp;
+ producer = new Mlt::Producer(*m_mltProfile, 0, ("colour:" + xml.attribute("colour")).toUtf8().constData());
} 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;
- }
+ 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 (aindex != 0) producer->set("audio_index", aindex);
}
- // setup length here as otherwise default length (currently 15000 frames in MLT) will be taken although outpoint is larger
+ // 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)
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")) {
// Clip already has all properties
Mlt::Frame *frame = producer->get_frame();
if (xml.attribute("type").toInt() == SLIDESHOW) {
- if (xml.hasAttribute("ttl")) producer->set("ttl", xml.attribute("ttl").toInt());
+ int ttl = xml.hasAttribute("ttl") ? xml.attribute("ttl").toInt() : 0;
+ if (ttl) producer->set("ttl", ttl);
+ if (!xml.attribute("animation").isEmpty()) {
+ Mlt::Filter *filter = new Mlt::Filter(*m_mltProfile, "affine");
+ if (filter && filter->is_valid()) {
+ int cycle = ttl;
+ QString geometry = SlideshowClip::animationToGeometry(xml.attribute("animation"), cycle);
+ if (!geometry.isEmpty()) {
+ if (xml.attribute("animation").contains("low-pass")) {
+ Mlt::Filter *blur = new Mlt::Filter(*m_mltProfile, "boxblur");
+ if (blur && blur->is_valid())
+ producer->attach(*blur);
+ }
+ filter->set("transition.geometry", geometry.toUtf8().data());
+ filter->set("transition.cycle", cycle);
+ producer->attach(*filter);
+ }
+ }
+ }
if (xml.attribute("fade") == "1") {
// user wants a fade effect to slideshow
Mlt::Filter *filter = new Mlt::Filter(*m_mltProfile, "luma");
if (filter && filter->is_valid()) {
- if (xml.hasAttribute("ttl")) filter->set("period", xml.attribute("ttl").toInt() - 1);
- if (xml.hasAttribute("luma_duration") && !xml.attribute("luma_duration").isEmpty()) filter->set("luma.out", xml.attribute("luma_duration").toInt());
+ 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);
}
}
- Mlt::Service clipService(producer->get_service());
- clipService.attach(*filter);
+ producer->attach(*filter);
}
}
if (xml.attribute("crop") == "1") {
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()) {
}
blockSignals(true);
- char *tmp = decodedString(playlist);
- m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", tmp);
+ 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;
m_mltProducer->optimise();
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::Consumer xmlConsumer(*m_mltProfile, "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);
}
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);
}
#endif
+void Render::showAudio(Mlt::Frame& frame)
+{
+ mlt_audio_format audio_format=mlt_audio_pcm;
+ int freq,num_channels,samples;
+ uint8_t* data=(uint8_t*)frame.get_audio(audio_format,freq,num_channels,samples);
+ if (!data)
+ return;
+ int value=0;
+ QByteArray channels;
+
+ for (int i=0;i<num_channels;i++){
+ /* switch (audio_format)
+ {
+ case 0:
+ value=( ( (uint8_t*)data) [i] );
+ break;
+ case 1:
+ value=( ( (uint16_t*)data) [i] >> 8 );
+ break;
+ case 2:
+ value=( ((uint32_t*)data) [i] >> 16 );
+ break;
+ case 3:
+ value=( ((float*)data) [i]*255);
+ break;
+ default:
+ value=0;
+ }
+ */
+ long val=0;
+ int num_samples=20;
+ for (int s=0;s<samples;s+=samples/num_samples){
+ val+=(data[i+s*num_channels]- 127);
+ }
+ channels.append(val/num_samples);
+ }
+
+
+ if (samples>0)
+ emit showAudioSignal(channels);
+}
+
/*
* 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;
int ct = 0;
Mlt::Filter *filter = sourceService.filter(ct);
while (filter) {
- if (filter->get("kdenlive_ix") != 0) {
+ if (filter->get_int("kdenlive_ix") != 0) {
filtersList.append(filter);
}
ct++;
int ct = 0;
Mlt::Filter *filter = sourceService.filter(ct);
while (filter) {
- if (filter->get("kdenlive_ix") != 0) {
+ if (filter->get_int("kdenlive_ix") != 0) {
sourceService.detach(*filter);
destService.attach(*filter);
} else ct++;
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 (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);
bool Render::mltRemoveTrackEffect(int track, QString index, bool updateIndex)
{
- kDebug() << "REMOVE TK EFF: " << track << ", IX: " << index;
Mlt::Service service(m_mltProducer->parent().get_service());
bool success = false;
Mlt::Tractor tractor(service);
Mlt::Service clipService(trackPlaylist.get_service());
m_isBlocked = true;
+ mlt_service_lock(service.get_service());
int ct = 0;
Mlt::Filter *filter = clipService.filter(ct);
while (filter) {
- if ((index == "-1" && strcmp(filter->get("kdenlive_id"), "")) || filter->get("kdenlive_ix") == index) {
+ if ((index == "-1" && strcmp(filter->get("kdenlive_id"), "")) || filter->get_int("kdenlive_ix") == index.toInt()) {
if (clipService.detach(*filter) == 0) success = true;
} else if (updateIndex) {
// Adjust the other effects index
- if (QString(filter->get("kdenlive_ix")).toInt() > index.toInt()) filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() - 1);
+ if (filter->get_int("kdenlive_ix") > index.toInt()) filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") - 1);
ct++;
} else ct++;
filter = clipService.filter(ct);
}
m_isBlocked = false;
+ mlt_service_unlock(service.get_service());
refresh();
return success;
}
// if (tag.startsWith("ladspa")) tag = "ladspa";
m_isBlocked = true;
+ mlt_service_lock(service.get_service());
int ct = 0;
Mlt::Filter *filter = clipService.filter(ct);
while (filter) {
- if ((index == "-1" && strcmp(filter->get("kdenlive_id"), "")) || filter->get("kdenlive_ix") == index) {// && filter->get("kdenlive_id") == id) {
+ if ((index == "-1" && strcmp(filter->get("kdenlive_id"), "")) || filter->get_int("kdenlive_ix") == index.toInt()) {// && filter->get("kdenlive_id") == id) {
if (clipService.detach(*filter) == 0) success = true;
//kDebug()<<"Deleted filter id:"<<filter->get("kdenlive_id")<<", ix:"<<filter->get("kdenlive_ix")<<", SERVICE:"<<filter->get("mlt_service");
} else if (updateIndex) {
// Adjust the other effects index
- if (QString(filter->get("kdenlive_ix")).toInt() > index.toInt()) filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() - 1);
+ if (filter->get_int("kdenlive_ix") > index.toInt()) filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") - 1);
ct++;
} else ct++;
filter = clipService.filter(ct);
}
m_isBlocked = false;
+ mlt_service_unlock(service.get_service());
if (doRefresh) refresh();
return success;
}
}
Mlt::Service clipService(clip->get_service());
- m_isBlocked = true;
int duration = clip->get_playtime();
if (doRefresh) {
// Check if clip is visible in monitor
const int filter_ix = params.paramValue("kdenlive_ix").toInt();
const QString region = params.paramValue("region");
int ct = 0;
+ m_isBlocked = true;
+ mlt_service_lock(service.get_service());
+
Mlt::Filter *filter = service.filter(ct);
while (filter) {
- if (QString(filter->get("kdenlive_ix")).toInt() == filter_ix) {
+ if (filter->get_int("kdenlive_ix") == filter_ix) {
// A filter at that position already existed, so we will increase all indexes later
updateIndex = true;
break;
ct = 0;
filter = service.filter(ct);
while (filter) {
- if (QString(filter->get("kdenlive_ix")).toInt() >= filter_ix) {
- if (updateIndex) filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() + 1);
+ if (filter->get_int("kdenlive_ix") >= filter_ix) {
+ if (updateIndex) filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") + 1);
}
ct++;
filter = service.filter(ct);
}
m_isBlocked = false;
+ mlt_service_unlock(service.get_service());
if (doRefresh) refresh();
return true;
}
ct = 0;
filter = service.filter(ct);
while (filter) {
- if (QString(filter->get("kdenlive_ix")).toInt() >= filter_ix) {
+ if (filter->get_int("kdenlive_ix") >= filter_ix) {
filtersList.append(filter);
service.detach(*filter);
} else ct++;
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");
} else {
kDebug() << "filter is NULL";
m_isBlocked = false;
+ mlt_service_unlock(service.get_service());
return false;
}
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") {
for (int i = 0; i < filtersList.count(); i++) {
Mlt::Filter *filter = filtersList.at(i);
if (updateIndex)
- filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() + 1);
+ filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") + 1);
service.attach(*filter);
}
m_isBlocked = false;
+ mlt_service_unlock(service.get_service());
if (doRefresh) refresh();
return true;
}
bool Render::mltEditTrackEffect(int track, EffectsParameterList params)
{
- kDebug() << "EDIT TK, FILTER: " << track;
Mlt::Service service(m_mltProducer->parent().get_service());
Mlt::Tractor tractor(service);
Mlt::Producer trackProducer(tractor.track(track));
Mlt::Filter *filter = clipService.filter(ct);
while (filter) {
- if (filter->get("kdenlive_ix") == index) {
+ if (filter->get_int("kdenlive_ix") == index.toInt()) {
break;
}
ct++;
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 (!params.paramValue("keyframes").isEmpty() || /*it.key().startsWith("#") || */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.
- mltRemoveEffect(track, position, index, false);
- bool success = mltAddEffect(track, position, params);
+ bool success = mltRemoveEffect(track, position, index, false);
+ if (!success) kDebug() << "// ERROR Removing effect : " << index;
+ if (position < GenTime()) success = mltAddTrackEffect(track, params);
+ else success = mltAddEffect(track, position, params);
+ if (!success) kDebug() << "// ERROR Adding effect : " << index;
return success;
}
if (position < GenTime()) {
Mlt::Filter *filter = clipService.filter(ct);
while (filter) {
- if (filter->get("kdenlive_ix") == index) {
+ if (filter->get_int("kdenlive_ix") == index.toInt()) {
break;
}
ct++;
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 ct = 0;
Mlt::Filter *filter = clipService.filter(ct);
while (filter) {
- int pos = QString(filter->get("kdenlive_ix")).toInt();
+ int pos = filter->get_int("kdenlive_ix");
if (pos == oldPos) {
filter->set("kdenlive_ix", newPos);
} else ct++;
bool found = false;
if (newPos > oldPos) {
while (filter) {
- if (!found && QString(filter->get("kdenlive_ix")).toInt() == oldPos) {
+ if (!found && filter->get_int("kdenlive_ix") == oldPos) {
filter->set("kdenlive_ix", newPos);
filtersList.append(filter);
clipService.detach(*filter);
filter = clipService.filter(ct);
- while (filter && QString(filter->get("kdenlive_ix")).toInt() <= newPos) {
- filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() - 1);
+ while (filter && filter->get_int("kdenlive_ix") <= newPos) {
+ filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") - 1);
ct++;
filter = clipService.filter(ct);
}
found = true;
}
- if (filter && QString(filter->get("kdenlive_ix")).toInt() > newPos) {
+ if (filter && filter->get_int("kdenlive_ix") > newPos) {
filtersList.append(filter);
clipService.detach(*filter);
} else ct++;
}
} else {
while (filter) {
- if (QString(filter->get("kdenlive_ix")).toInt() == oldPos) {
+ if (filter->get_int("kdenlive_ix") == oldPos) {
filter->set("kdenlive_ix", newPos);
filtersList.append(filter);
clipService.detach(*filter);
ct = 0;
filter = clipService.filter(ct);
while (filter) {
- int pos = QString(filter->get("kdenlive_ix")).toInt();
+ int pos = filter->get_int("kdenlive_ix");
if (pos >= newPos) {
if (pos < oldPos) filter->set("kdenlive_ix", pos + 1);
filtersList.append(filter);
bool found = false;
if (newPos > oldPos) {
while (filter) {
- if (!found && QString(filter->get("kdenlive_ix")).toInt() == oldPos) {
+ if (!found && filter->get_int("kdenlive_ix") == oldPos) {
filter->set("kdenlive_ix", newPos);
filtersList.append(filter);
clipService.detach(*filter);
filter = clipService.filter(ct);
- while (filter && QString(filter->get("kdenlive_ix")).toInt() <= newPos) {
- filter->set("kdenlive_ix", QString(filter->get("kdenlive_ix")).toInt() - 1);
+ while (filter && filter->get_int("kdenlive_ix") <= newPos) {
+ filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") - 1);
ct++;
filter = clipService.filter(ct);
}
found = true;
}
- if (filter && QString(filter->get("kdenlive_ix")).toInt() > newPos) {
+ if (filter && filter->get_int("kdenlive_ix") > newPos) {
filtersList.append(filter);
clipService.detach(*filter);
} else ct++;
}
} else {
while (filter) {
- if (QString(filter->get("kdenlive_ix")).toInt() == oldPos) {
+ if (filter->get_int("kdenlive_ix") == oldPos) {
filter->set("kdenlive_ix", newPos);
filtersList.append(filter);
clipService.detach(*filter);
ct = 0;
filter = clipService.filter(ct);
while (filter) {
- int pos = QString(filter->get("kdenlive_ix")).toInt();
+ int pos = filter->get_int("kdenlive_ix");
if (pos >= newPos) {
if (pos < oldPos) filter->set("kdenlive_ix", pos + 1);
filtersList.append(filter);
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;
+ if (info.cropStart < GenTime())
+ currentOut = newDuration - info.cropStart.frames(m_fps);
+ else
+ 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);
}
int previousStart = clip->get_in();
int previousOut = clip->get_out();
- delete clip;
+
m_isBlocked = true;
previousStart += moveFrame;
if (previousStart < 0) {
previousOut -= previousStart;
previousStart = 0;
}
+
+ int length = previousOut + 1;
+ if (length > clip->get_length()) {
+ clip->parent().set("length", length + 1);
+ clip->parent().set("out", length);
+ clip->set("length", length + 1);
+ }
+ delete clip;
+
// kDebug() << "RESIZE, new start: " << previousStart << ", " << previousOut;
trackPlaylist.resize_clip(clipIndex, previousStart, previousOut);
- if (moveFrame > 0) trackPlaylist.insert_blank(clipIndex, moveFrame - 1);
- else {
+ if (moveFrame > 0) {
+ trackPlaylist.insert_blank(clipIndex, moveFrame - 1);
+ } else {
//int midpos = info.startPos.frames(m_fps) + moveFrame - 1;
int blankIndex = clipIndex - 1;
int blankLength = trackPlaylist.clip_length(blankIndex);
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);
mltAddTransition(tag, a_track, b_track, in, out, xml, false);
}
- if (m_mltProducer->position() > in.frames(m_fps) && m_mltProducer->position() < out.frames(m_fps)) refresh();
+ if (m_mltProducer->position() >= in.frames(m_fps) && m_mltProducer->position() <= out.frames(m_fps)) refresh();
}
void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml)
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
mltPlantTransition(field, *transition, a_track, b_track);
// field->plant_transition(*transition, a_track, b_track);
- delete[] transId;
if (do_refresh) refresh();
return true;
}
return doc.toString();
}
+
+void Render::sendFrameUpdate()
+{
+ if (m_mltProducer) {
+ Mlt::Frame * frame = m_mltProducer->get_frame();
+ emitFrameUpdated(*frame);
+ delete frame;
+ }
+}
+
+
#include "renderer.moc"