static void consumer_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?
+ self->emitFrameNumber();
Mlt::Frame frame(frame_ptr);
if (!frame.is_valid()) return;
- self->emitFrameNumber(mlt_frame_get_position(frame_ptr));
if (self->sendFrameForAnalysis && frame_ptr->convert_image) {
self->emitFrameUpdated(frame);
}
m_mltConsumer(NULL),
m_mltProducer(NULL),
m_mltProfile(NULL),
- m_framePosition(0),
+ m_showFrameEvent(NULL),
+ m_pauseEvent(NULL),
m_externalConsumer(false),
m_isZoneMode(false),
m_isLoopMode(false),
m_mltProducer = m_blackClip->cut(0, 1);
m_mltConsumer->connect(*m_mltProducer);
m_mltProducer->set_speed(0.0);
+ m_refreshTimer.setSingleShot(true);
+ m_refreshTimer.setInterval(50);
+ connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
}
Render::~Render()
//delete m_osdTimer;
m_requestList.clear();
m_infoThread.waitForFinished();
+ if (m_showFrameEvent) delete m_showFrameEvent;
+ if (m_pauseEvent) delete m_pauseEvent;
if (m_mltConsumer) delete m_mltConsumer;
if (m_mltProducer) delete m_mltProducer;
/*if (m_mltProducer) {
setenv("MLT_PROFILE", tmp, 1);
m_mltProfile = new Mlt::Profile(tmp);
m_mltProfile->set_explicit(true);
- kDebug()<<"// ********* PROFILE AR: "<<m_mltProfile->dar();
delete[] tmp;
m_blackClip = new Mlt::Producer(*m_mltProfile, "colour", "black");
delete[] tmp;
if (m_mltConsumer->is_valid()) {
m_externalConsumer = true;
- m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+ m_showFrameEvent = 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");
m_mltConsumer->set("real_time", KdenliveSettings::mltthreads());
mlt_log_set_callback(kdenlive_callback);
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);
+ m_showFrameEvent = 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->listen("consumer-sdl-paused", this, (mlt_listener) consumer_paused);
+ m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+ m_pauseEvent = m_mltConsumer->listen("consumer-sdl-paused", this, (mlt_listener) consumer_paused);
m_mltConsumer->set("window_id", m_winid);
}
m_mltConsumer->set("resize", 1);
return clip;
}
+bool Render::hasProfile(const QString &profileName) const
+{
+ return m_activeProfile == profileName;
+}
+
int Render::resetProfile(const QString &profileName, bool dropSceneList)
{
- QString scene;
- if (!dropSceneList) scene = sceneList();
+ m_refreshTimer.stop();
if (m_mltConsumer) {
if (m_externalConsumer == KdenliveSettings::external_display()) {
if (KdenliveSettings::external_display() && m_activeProfile == profileName) return 1;
if (m_isSplitView) slotSplitView(false);
if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
m_mltConsumer->purge();
+ if (m_showFrameEvent) delete m_showFrameEvent;
+ m_showFrameEvent = NULL;
+ if (m_pauseEvent) delete m_pauseEvent;
+ m_pauseEvent = NULL;
delete m_mltConsumer;
m_mltConsumer = NULL;
}
+ QString scene;
+ if (!dropSceneList) scene = sceneList();
int pos = 0;
double current_fps = m_mltProfile->fps();
double current_dar = m_mltProfile->dar();
{
if (!m_mltProducer)
return;
+
m_mltProducer->seek((int)(time.frames(m_fps)));
- refresh();
+ if (m_mltProducer->get_speed() == 0) {
+ refresh();
+ }
}
void Render::seek(int time)
{
if (!m_mltProducer)
return;
+
m_mltProducer->seek(time);
- refresh();
+ if (m_mltProducer->get_speed() == 0) {
+ refresh();
+ }
}
//static
info.imageHeight = imageHeight;
info.replaceProducer = replaceProducer;
// Make sure we don't request the info for same clip twice
+ m_infoMutex.lock();
m_requestList.removeAll(info);
m_requestList.append(info);
+ m_infoMutex.unlock();
if (!m_infoThread.isRunning())
m_infoThread = QtConcurrent::run(this, &Render::processFileProperties);
}
m_infoMutex.unlock();
}
-int Render::processingItems() const
+int Render::processingItems()
{
+ m_infoMutex.lock();
int count = m_requestList.count();
- if (m_infoThread.isRunning()) count++;
+ if (!m_processingClipId.isEmpty()) {
+ // one clip is currently processed
+ count++;
+ }
+ m_infoMutex.unlock();
return count;
}
+bool Render::isProcessing(const QString &id)
+{
+ if (m_processingClipId == id) return true;
+ m_infoMutex.lock();
+ for (int i = 0; i < m_requestList.count(); i++) {
+ requestClipInfo info = m_requestList.at(i);
+ if (info.clipId == id) {
+ m_infoMutex.unlock();
+ return true;
+ }
+ }
+ m_infoMutex.unlock();
+ return false;
+}
+
void Render::processFileProperties()
{
requestClipInfo info;
m_infoMutex.lock();
info = m_requestList.takeFirst();
m_infoMutex.unlock();
- if (info.replaceProducer) emit blockClipMonitor(info.clipId);
+ m_processingClipId = info.clipId;
QString path;
bool proxyProducer;
if (info.xml.hasAttribute("proxy") && info.xml.attribute("proxy") != "-") {
if (producer == NULL || producer->is_blank() || !producer->is_valid()) {
kDebug() << " / / / / / / / / ERROR / / / / // CANNOT LOAD PRODUCER: "<<path;
+ m_processingClipId.clear();
if (proxyProducer) {
// Proxy file is corrupted
emit removeInvalidProxy(info.clipId, false);
producer->set("out", info.xml.attribute("proxy_out").toInt());
if (producer->get_out() != info.xml.attribute("proxy_out").toInt()) {
// Proxy file length is different than original clip length, this will corrupt project so disable this proxy clip
+ m_processingClipId.clear();
emit removeInvalidProxy(info.clipId, true);
delete producer;
continue;
if (info.xml.hasAttribute("templatetext"))
producer->set("templatetext", info.xml.attribute("templatetext").toUtf8().constData());
+
+ int imageWidth = (int)((double) info.imageHeight * m_mltProfile->width() / m_mltProfile->height() + 0.5);
+ int fullWidth = (int)((double) info.imageHeight * m_mltProfile->dar() + 0.5);
+ int frameNumber = info.xml.attribute("thumbnail", "-1").toInt();
if ((!info.replaceProducer && info.xml.hasAttribute("file_hash")) || proxyProducer) {
// Clip already has all properties
- emit replyGetFileProperties(info.clipId, producer, stringMap(), stringMap(), info.replaceProducer, true);
+ if (proxyProducer) {
+ // Recreate clip thumb
+ if (frameNumber > 0) producer->seek(frameNumber);
+ Mlt::Frame *frame = producer->get_frame();
+ if (frame && frame->is_valid()) {
+ QImage img = KThumb::getFrame(frame, imageWidth, fullWidth, info.imageHeight);
+ delete frame;
+ emit replyGetImage(info.clipId, img);
+ }
+ }
+ m_processingClipId.clear();
+ emit replyGetFileProperties(info.clipId, producer, stringMap(), stringMap(), info.replaceProducer);
continue;
}
- int imageWidth = (int)((double) info.imageHeight * m_mltProfile->width() / m_mltProfile->height() + 0.5);
- int fullWidth = (int)((double) info.imageHeight * m_mltProfile->dar() + 0.5);
stringMap filePropertyMap;
stringMap metadataPropertyMap;
-
- int frameNumber = info.xml.attribute("thumbnail", "-1").toInt();
+ char property[200];
+
if (frameNumber > 0) producer->seek(frameNumber);
duration = duration > 0 ? duration : producer->get_playtime();
}
}
}
+
+ // Get frame rate
+ int vindex = producer->get_int("video_index");
+ if (vindex > -1) {
+ snprintf(property, sizeof(property), "meta.media.%d.stream.frame_rate", vindex);
+ if (producer->get(property))
+ filePropertyMap["fps"] = producer->get(property);
+ }
- if (producer->get_double("meta.media.frame_rate_den") > 0) {
- filePropertyMap["fps"] = locale.toString(producer->get_double("meta.media.frame_rate_num") / producer->get_double("meta.media.frame_rate_den"));
- } else filePropertyMap["fps"] = producer->get("source_fps");
+ if (!filePropertyMap.contains("fps")) {
+ if (producer->get_double("meta.media.frame_rate_den") > 0) {
+ filePropertyMap["fps"] = locale.toString(producer->get_double("meta.media.frame_rate_num") / producer->get_double("meta.media.frame_rate_den"));
+ } else filePropertyMap["fps"] = producer->get("source_fps");
+ }
Mlt::Frame *frame = producer->get_frame();
if (frame && frame->is_valid()) {
variance = -1;
}
} while (variance == -1);
- if (frameNumber > -1) filePropertyMap["thumbnail"] = frameNumber;
+ delete frame;
+ if (frameNumber > -1) filePropertyMap["thumbnail"] = QString::number(frameNumber);
emit replyGetImage(info.clipId, img);
} else if (frame->get_int("test_audio") == 0) {
emit replyGetImage(info.clipId, "audio-x-generic", fullWidth, info.imageHeight);
filePropertyMap["type"] = "audio";
}
}
- delete frame;
// Retrieve audio / video codec name
-
// If there is a
- char property[200];
- if (producer->get_int("video_index") > -1) {
+
+ if (vindex > -1) {
/*if (context->duration == AV_NOPTS_VALUE) {
kDebug() << " / / / / / / / /ERROR / / / CLIP HAS UNKNOWN DURATION";
emit removeInvalidClip(clipId);
return;
}*/
// Get the video_index
- int default_video = producer->get_int("video_index");
int video_max = 0;
int default_audio = producer->get_int("audio_index");
int audio_max = 0;
else if (type == "audio")
audio_max = ix;
}
- filePropertyMap["default_video"] = QString::number(default_video);
+ filePropertyMap["default_video"] = QString::number(vindex);
filePropertyMap["video_max"] = QString::number(video_max);
filePropertyMap["default_audio"] = QString::number(default_audio);
filePropertyMap["audio_max"] = QString::number(audio_max);
- snprintf(property, sizeof(property), "meta.media.%d.codec.long_name", default_video);
+ snprintf(property, sizeof(property), "meta.media.%d.codec.long_name", vindex);
if (producer->get(property)) {
filePropertyMap["videocodec"] = producer->get(property);
} else {
- snprintf(property, sizeof(property), "meta.media.%d.codec.name", default_video);
+ snprintf(property, sizeof(property), "meta.media.%d.codec.name", vindex);
if (producer->get(property))
filePropertyMap["videocodec"] = producer->get(property);
}
QString query;
- query = QString("meta.media.%1.codec.pix_fmt").arg(default_video);
+ query = QString("meta.media.%1.codec.pix_fmt").arg(vindex);
filePropertyMap["pix_fmt"] = producer->get(query.toUtf8().constData());
filePropertyMap["colorspace"] = producer->get("meta.media.colorspace");
metadataPropertyMap[ name.section('.', 0, -2)] = value;
}
producer->seek(0);
+ m_processingClipId.clear();
emit replyGetFileProperties(info.clipId, producer, filePropertyMap, metadataPropertyMap, info.replaceProducer);
}
+ m_processingClipId.clear();
}
int Render::setProducer(Mlt::Producer *producer, int position)
{
- kDebug()<<"//////////\n SET CLIP PRODUCER \n//////////";
+ m_refreshTimer.stop();
QMutexLocker locker(&m_mutex);
- if (m_winid == -1) return -1;
- if (m_mltConsumer) {
- if (!m_mltConsumer->is_stopped()) {
- m_mltConsumer->stop();
- m_mltConsumer->purge();
- }
- m_mltConsumer->set("refresh", 0);
- }
- else {
+ QString currentId;
+ int consumerPosition = 0;
+ if (m_winid == -1 || !m_mltConsumer) {
+ kDebug()<<" / / / / WARNING, MONITOR NOT READY";
+ if (producer) delete producer;
return -1;
}
-
- if (m_mltProducer) {
- m_mltProducer->set_speed(0);
- delete m_mltProducer;
- m_mltProducer = NULL;
- emit stopped();
+ m_mltConsumer->set("refresh", 0);
+ if (!m_mltConsumer->is_stopped()) {
+ m_mltConsumer->stop();
}
+ m_mltConsumer->purge();
+ consumerPosition = m_mltConsumer->position();
+
+
blockSignals(true);
- if (producer && producer->is_valid()) {
- m_mltProducer = new Mlt::Producer(producer->get_producer());
- } else m_mltProducer = m_blackClip->cut(0, 1);
+ if (!producer || !producer->is_valid()) {
+ if (producer) delete producer;
+ producer = m_blackClip->cut(0, 1);
+ }
- if (!m_mltProducer || !m_mltProducer->is_valid()) {
+ if (!producer || !producer->is_valid()) {
kDebug() << " WARNING - - - - -INVALID PLAYLIST: ";
return -1;
}
+ if (m_mltProducer) currentId = m_mltProducer->get("id");
+ emit stopped();
+ if (position == -1 && producer->get("id") == currentId) position = consumerPosition;
+ if (position != -1) producer->seek(position);
int volume = KdenliveSettings::volume();
- m_mltProducer->set("meta.volume", (double)volume / 100);
- m_fps = m_mltProducer->get_fps();
+ producer->set("meta.volume", (double)volume / 100);
+ m_fps = producer->get_fps();
blockSignals(false);
- int error = connectPlaylist();
- if (producer == NULL) {
- return error;
+ m_mltConsumer->connect(*producer);
+
+ if (m_mltProducer) {
+ m_mltProducer->set_speed(0);
+ delete m_mltProducer;
+ m_mltProducer = NULL;
+ }
+ m_mltProducer = producer;
+ m_mltProducer->set_speed(0);
+ emit durationChanged(m_mltProducer->get_playtime());
+ if (m_mltConsumer->start() == -1) {
+ // ARGH CONSUMER BROKEN!!!!
+ KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
+ if (m_showFrameEvent) delete m_showFrameEvent;
+ m_showFrameEvent = NULL;
+ if (m_pauseEvent) delete m_pauseEvent;
+ m_pauseEvent = NULL;
+ delete m_mltConsumer;
+ m_mltConsumer = NULL;
+ return -1;
}
- if (position != -1) {
- m_mltProducer->seek(position);
- emit rendererPosition(position);
- } else emit rendererPosition((int) m_mltProducer->position());
- return error;
+ position = m_mltProducer->position();
+ m_mltConsumer->set("refresh", 1);
+ // Make sure the first frame is displayed, otherwise if we change producer too fast
+ // We can crash the avformat producer
+ Mlt::Event *ev = m_mltConsumer->setup_wait_for("consumer-frame-show");
+ m_mltConsumer->wait_for(ev);
+ delete ev;
+ emit rendererPosition(position);
+ return 0;
}
int Render::setSceneList(QDomDocument list, int position)
int Render::setSceneList(QString playlist, int position)
{
+ m_refreshTimer.stop();
+ QMutexLocker locker(&m_mutex);
if (m_winid == -1) return -1;
int error = 0;
}
kDebug() << "// NEW SCENE LIST DURATION SET TO: " << m_mltProducer->get_playtime();
- if (error == 0) error = connectPlaylist();
- else connectPlaylist();
+ m_mltConsumer->connect(*m_mltProducer);
+ m_mltProducer->set_speed(0);
fillSlowMotionProducers();
blockSignals(false);
+ emit durationChanged(m_mltProducer->get_playtime());
return error;
//kDebug()<<"// SETSCN LST, POS: "<<position;
return m_fps;
}
-int Render::connectPlaylist()
-{
- if (!m_mltConsumer) return -1;
- //m_mltConsumer->set("refresh", "0");
- m_mltConsumer->connect(*m_mltProducer);
- m_mltProducer->set_speed(0);
- if (m_mltConsumer->start() == -1) {
- // ARGH CONSUMER BROKEN!!!!
- KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
- delete m_mltConsumer;
- m_mltConsumer = NULL;
- return -1;
- }
- emit durationChanged(m_mltProducer->get_playtime());
- return 0;
- //refresh();
-}
-
-void Render::refreshDisplay()
-{
-
- if (!m_mltProducer) return;
- //m_mltConsumer->set("refresh", 0);
-
- //mlt_properties properties = MLT_PRODUCER_PROPERTIES(m_mltProducer->get_producer());
- /*if (KdenliveSettings::osdtimecode()) {
- mlt_properties_set_int( properties, "meta.attr.timecode", 1);
- mlt_properties_set( properties, "meta.attr.timecode.markup", "#timecode#");
- m_osdInfo->set("dynamic", "1");
- m_mltProducer->attach(*m_osdInfo);
- }
- else {
- m_mltProducer->detach(*m_osdInfo);
- m_osdInfo->set("dynamic", "0");
- }*/
- refresh();
-}
-
int Render::volume() const
{
if (!m_mltConsumer || !m_mltProducer) return -1;
void Render::start()
{
+ m_refreshTimer.stop();
+ QMutexLocker locker(&m_mutex);
if (m_winid == -1) {
kDebug() << "----- BROKEN MONITOR: " << m_name << ", RESTART";
return;
}
- if (m_mltConsumer && m_mltConsumer->is_stopped()) {
+ if (!m_mltConsumer) return;
+ if (m_mltConsumer->is_stopped()) {
if (m_mltConsumer->start() == -1) {
//KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
kDebug(QtWarningMsg) << "/ / / / CANNOT START MONITOR";
} else {
- refresh();
+ m_mltConsumer->purge();
+ m_mltConsumer->set("refresh", 1);
}
}
}
void Render::stop()
{
+ m_refreshTimer.stop();
+ QMutexLocker locker(&m_mutex);
if (m_mltProducer == NULL) return;
if (m_mltConsumer && !m_mltConsumer->is_stopped()) {
- //kDebug() << "///////////// RENDER STOPPED: " << m_name;
- //m_mltConsumer->set("refresh", 0);
m_mltConsumer->stop();
- // delete m_mltConsumer;
- // m_mltConsumer = NULL;
+ m_mltConsumer->purge();
}
if (m_mltProducer) {
if (m_isZoneMode) resetZoneMode();
m_mltProducer->set_speed(0.0);
- //m_mltProducer->set("out", m_mltProducer->get_length() - 1);
- //kDebug() << m_mltProducer->get_length();
}
}
void Render::stop(const GenTime & startTime)
{
+ m_refreshTimer.stop();
+ QMutexLocker locker(&m_mutex);
if (m_mltProducer) {
if (m_isZoneMode) resetZoneMode();
m_mltProducer->set_speed(0.0);
if (m_isZoneMode) resetZoneMode();
m_mltConsumer->set("refresh", 0);
m_mltProducer->set_speed(0.0);
- /*
- The 2 lines below create a flicker loop
- emit rendererPosition(m_framePosition);
- m_mltProducer->seek(m_framePosition);*/
m_mltConsumer->purge();
}
void Render::switchPlay(bool play)
{
+ QMutexLocker locker(&m_mutex);
if (!m_mltProducer || !m_mltConsumer)
return;
if (m_isZoneMode) resetZoneMode();
if (play && m_mltProducer->get_speed() == 0.0) {
- if (m_name == "clip" && m_framePosition == (int) m_mltProducer->get_out()) m_mltProducer->seek(0);
+ if (m_name == "clip" && m_mltConsumer->position() == m_mltProducer->get_out()) m_mltProducer->seek(0);
+ if (m_mltConsumer->is_stopped()) {
+ m_mltConsumer->start();
+ }
m_mltProducer->set_speed(1.0);
- m_mltConsumer->set("refresh", 1);
- if (m_mltConsumer->is_stopped()) m_mltConsumer->start();
+ m_mltConsumer->set("refresh", "1");
} else if (!play) {
- stop();
- m_mltConsumer->set("refresh", "0");
- m_framePosition++;
- m_mltProducer->seek(m_framePosition);
+ m_mltProducer->set_speed(0.0);
+ m_mltConsumer->set("refresh", 0);
+ m_mltProducer->seek(m_mltConsumer->position());
+ if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
+ if (m_isZoneMode) resetZoneMode();
+
+ //emitConsumerStopped();
/*m_mltConsumer->set("refresh", 0);
m_mltConsumer->stop();
m_mltConsumer->purge();
{
if (!m_mltProducer)
return;
+
resetZoneMode();
m_mltProducer->seek(pos);
- refresh();
+ if (m_mltProducer->get_speed() == 0) {
+ refresh();
+ }
}
void Render::seekToFrameDiff(int diff)
void Render::doRefresh()
{
- // Use a Timer so that we don't refresh too much
- if (m_mltConsumer) {
- if (m_mltConsumer->is_stopped()) m_mltConsumer->start();
- m_mltConsumer->set("refresh", 1);
- }
+ if (m_mltProducer && m_mltProducer->get_speed() == 0) m_refreshTimer.start();
}
void Render::refresh()
{
+ QMutexLocker locker(&m_mutex);
if (!m_mltProducer)
return;
if (m_mltConsumer) {
- m_mltConsumer->set("refresh", 1);
if (m_mltConsumer->is_stopped()) m_mltConsumer->start();
+ m_mltConsumer->purge();
+ m_mltConsumer->set("refresh", 1);
}
}
void Render::setDropFrames(bool show)
{
+ QMutexLocker locker(&m_mutex);
if (m_mltConsumer) {
int dropFrames = KdenliveSettings::mltthreads();
if (show == false) dropFrames = -dropFrames;
}
}
-double Render::playSpeed()
+double Render::playSpeed() const
{
if (m_mltProducer) return m_mltProducer->get_speed();
return 0.0;
int Render::seekFramePosition() const
{
- if (m_mltProducer) return (int) m_mltProducer->position();
+ //if (m_mltProducer) return (int) m_mltProducer->position();
+ if (m_mltConsumer) return (int) m_mltConsumer->position();
return 0;
}
emit frameUpdated(qimage);
}
-void Render::emitFrameNumber(double position)
+void Render::emitFrameNumber()
{
- m_framePosition = position;
- emit rendererPosition((int) position);
+ if (m_mltConsumer) emit rendererPosition((int) m_mltConsumer->position());
}
void Render::emitConsumerStopped()
void Render::showFrame(Mlt::Frame& frame)
{
- m_framePosition = qMax(frame.get_int("_position"), 0);
- emit rendererPosition((int) m_framePosition);
+ emit rendererPosition((int) m_mltConsumer->position());
mlt_image_format format = mlt_image_rgb24a;
int width = 0;
int height = 0;
}
-void Render::lock()
+Mlt::Tractor *Render::lockService()
{
- if (!m_mltProducer) return;
+ // we are going to replace some clips, purge consumer
+ QMutexLocker locker(&m_mutex);
+ if (!m_mltProducer) return NULL;
+ if (m_mltConsumer) {
+ if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
+ m_mltConsumer->purge();
+ }
Mlt::Service service(m_mltProducer->parent().get_service());
if (service.type() != tractor_type) {
kWarning() << "// TRACTOR PROBLEM";
- return;
+ return NULL;
}
service.lock();
+ return new Mlt::Tractor(service);
+
}
-void Render::unlock()
+void Render::unlockService(Mlt::Tractor *tractor)
{
+ if (tractor) {
+ delete tractor;
+ }
if (!m_mltProducer) return;
Mlt::Service service(m_mltProducer->parent().get_service());
if (service.type() != tractor_type) {
service.unlock();
}
-bool Render::mltUpdateClip(ItemInfo info, QDomElement element, Mlt::Producer *prod)
+bool Render::mltUpdateClip(Mlt::Tractor *tractor, ItemInfo info, QDomElement element, Mlt::Producer *prod)
{
// TODO: optimize
- if (prod == NULL) {
+ if (prod == NULL || tractor == NULL) {
kDebug() << "Cannot update clip with null producer //////";
return false;
}
- Mlt::Service service(m_mltProducer->parent().get_service());
- if (service.type() != tractor_type) {
- kWarning() << "// TRACTOR PROBLEM";
- return false;
- }
- Mlt::Tractor tractor(service);
- Mlt::Producer trackProducer(tractor.track(tractor.count() - 1 - info.track));
+ Mlt::Producer trackProducer(tractor->track(tractor->count() - 1 - info.track));
Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
int startPos = info.startPos.frames(m_fps);
int clipIndex = trackPlaylist.get_clip_index_at(startPos);
}
-bool Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod)
+bool Render::mltUpdateClipProducer(Mlt::Tractor *tractor, int track, int pos, Mlt::Producer *prod)
{
- if (prod == NULL || !prod->is_valid()) {
+ if (prod == NULL || !prod->is_valid() || tractor == NULL || !tractor->is_valid()) {
kDebug() << "// Warning, CLIP on track " << track << ", at: " << pos << " is invalid, cannot update it!!!";
return false;
}
- //kDebug() << "// TRYING TO UPDATE CLIP at: " << pos << ", TK: " << track;
- Mlt::Service service(m_mltProducer->parent().get_service());
- if (service.type() != tractor_type) {
- kWarning() << "// TRACTOR PROBLEM";
- return false;
- }
- service.lock();
- Mlt::Tractor tractor(service);
- Mlt::Producer trackProducer(tractor.track(track));
+
+ Mlt::Producer trackProducer(tractor->track(track));
Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
int clipIndex = trackPlaylist.get_clip_index_at(pos);
Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
if (clipProducer == NULL || clipProducer->is_blank()) {
kDebug() << "// ERROR UPDATING CLIP PROD";
delete clipProducer;
- service.unlock();
return false;
}
Mlt::Producer *clip = prod->cut(clipProducer->get_in(), clipProducer->get_out());
if (!clip || !clip->is_valid()) {
if (clip) delete clip;
delete clipProducer;
- service.unlock();
return false;
}
// move all effects to the correct producer
trackPlaylist.insert_at(pos, clip, 1);
delete clip;
delete clipProducer;
- service.unlock();
return true;
}
}
tractor.removeChild(track);
//kDebug() << "/////////// RESULT SCENE: \n" << doc.toString();
- setSceneList(doc.toString(), m_framePosition);
+ setSceneList(doc.toString(), m_mltConsumer->position());
emit refreshDocumentProducers(false, false);
}
kDebug() << "////// RESTARTING CONSUMER";
if (!m_mltConsumer || !m_mltProducer) return;
if (m_mltProducer->get_playtime() == 0) return;
+ QMutexLocker locker(&m_mutex);
Mlt::Service service(m_mltProducer->parent().get_service());
if (service.type() != tractor_type) return;