X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Frenderer.cpp;h=9ddfd753a69540cc9545ca7c18f83bb52ef1bc37;hb=548782dfe8b4ec1edc0c15f0062f5a976f1c6ee3;hp=59c87c9e275aa27e6194e04183379cd23f9f0ae0;hpb=db2025fcae30800f798975dedc94c951c7b51a93;p=kdenlive diff --git a/src/renderer.cpp b/src/renderer.cpp index 59c87c9e..9ddfd753 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -49,7 +49,6 @@ #include - static void kdenlive_callback(void* /*ptr*/, int level, const char* fmt, va_list vl) { if (level > MLT_LOG_ERROR) return; @@ -69,7 +68,9 @@ static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr if (self->sendFrameForAnalysis && frame_ptr->convert_image) { self->emitFrameUpdated(frame); } - if (self->analyseAudio) self->showAudio(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) { @@ -95,8 +96,8 @@ static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ Render::Render(const QString & rendererName, int winid, QString profile, QWidget *parent) : QObject(parent), m_isBlocked(0), - sendFrameForAnalysis(false), analyseAudio(KdenliveSettings::monitor_audio()), + sendFrameForAnalysis(false), m_name(rendererName), m_mltConsumer(NULL), m_mltProducer(NULL), @@ -198,10 +199,12 @@ void Render::buildConsumer(const QString profileName) tmp = qstrdup(decklink.toUtf8().constData()); m_mltConsumer = new Mlt::Consumer(*m_mltProfile, tmp); delete[] tmp; - if (m_mltConsumer) { + 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; @@ -352,6 +355,15 @@ void Render::seek(GenTime time) refresh(); } +void Render::seek(int time) +{ + if (!m_mltProducer) + return; + m_isBlocked = false; + m_mltProducer->seek(time); + refresh(); +} + //static /*QPixmap Render::frameThumbnail(Mlt::Frame *frame, int width, int height, bool border) { QPixmap pix(width, height); @@ -451,6 +463,10 @@ double Render::dar() const return m_mltProfile->dar(); } +double Render::sar() const +{ + return m_mltProfile->sar(); +} void Render::slotSplitView(bool doit) { @@ -517,12 +533,14 @@ void Render::slotSplitView(bool 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); @@ -605,8 +623,12 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int } // setup length here as otherwise default length (currently 15000 frames in MLT) will be taken even if outpoint is larger - if (type == COLOR || type == TEXT || type == IMAGE || type == SLIDESHOW) - producer->set("length", xml.attribute("out").toInt() - xml.attribute("in").toInt() + 1); + if (type == COLOR || type == TEXT || type == IMAGE || type == SLIDESHOW) { + int length; + if (xml.hasAttribute("length")) length = xml.attribute("length").toInt(); + else length = xml.attribute("out").toInt() - xml.attribute("in").toInt(); + producer->set("length", length); + } if (xml.hasAttribute("out")) producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt()); @@ -616,9 +638,9 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int 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; } @@ -794,7 +816,7 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int metadataPropertyMap[ name.section('.', 0, -2)] = value; } producer->seek(0); - 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; } @@ -888,6 +910,13 @@ int Render::setSceneList(QString playlist, int position) //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_mltConsumer->stop(); @@ -902,7 +931,6 @@ int Render::setSceneList(QString playlist, int position) 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()); @@ -943,7 +971,6 @@ int Render::setSceneList(QString playlist, int position) } blockSignals(true); - // TODO: Better way to do this if (KdenliveSettings::projectloading_avformatnovalidate()) playlist.replace(">avformat", ">avformat-novalidate"); @@ -951,7 +978,6 @@ int Render::setSceneList(QString playlist, int position) playlist.replace(">avformat-novalidate", ">avformat"); m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", playlist.toUtf8().constData()); - if (!m_mltProducer || !m_mltProducer->is_valid()) { kDebug() << " WARNING - - - - -INVALID PLAYLIST: " << playlist.toUtf8().constData(); m_mltProducer = m_blackClip->cut(0, 50); @@ -1467,39 +1493,26 @@ void Render::showFrame(Mlt::Frame& frame) void Render::showAudio(Mlt::Frame& frame) { - if (!frame.is_valid() || frame.get_int("test_audio") != 0) return; + 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); - QVector sampleVector(samples); - memcpy(sampleVector.data(), data, samples*sizeof(int16_t)); - qDebug() << samples << " samples. Freq=" << freq << ", channels=" << num_channels; - qDebug() << sizeof(char) << " (c) " << sizeof(int16_t) << " (int16_t)"; - qDebug() << sampleVector.at(0); - - if (!data) + if (!data) { return; - int num_samples = samples > 200 ? 200 : samples; - - - QByteArray channels; - for (int i = 0; i < num_channels; i++) { - long val = 0; - for (int s = 0; s < num_samples; s ++) { - val += abs(data[i+s*num_channels] / 128); - } - channels.append(val / num_samples); } - qDebug() << channels.size() << ": size."; + // 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 sampleVector(samples*num_channels); + memcpy(sampleVector.data(), data, samples*num_channels*sizeof(int16_t)); + if (samples > 0) { - emit showAudioSignal(channels); emit audioSamplesSignal(sampleVector, freq, num_channels, samples); - } else { - emit showAudioSignal(QByteArray()); } } @@ -1776,7 +1789,8 @@ bool Render::mltUpdateClip(ItemInfo info, QDomElement element, Mlt::Producer *pr 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; @@ -1931,10 +1945,9 @@ void Render::mltInsertSpace(QMap trackClipStartList, QMap } 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); } @@ -2318,7 +2331,7 @@ bool Render::mltAddTrackEffect(int track, EffectsParameterList params) 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); } @@ -3000,6 +3013,12 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) m_isBlocked = true; previousStart += moveFrame; + if (previousStart < 0) { + // this is possible for images and color clips + previousOut -= previousStart; + previousStart = 0; + } + int length = previousOut + 1; if (length > clip->get_length()) { clip->parent().set("length", length + 1); @@ -3330,12 +3349,11 @@ void Render::mltPlantTransition(Mlt::Field *field, Mlt::Transition &tr, int a_tr 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: "<get_a_track()<<", "<get_b_track(); + for (int i = trList.count() - 1; i >= 0; i--) { + //kDebug()<< "REPLANT ON TK: "<get_a_track()<<", "<get_b_track(); field->plant_transition(*trList.at(i), trList.at(i)->get_a_track(), trList.at(i)->get_b_track()); } } @@ -3344,6 +3362,7 @@ void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b { if (oldTag == tag && !force) mltUpdateTransitionParams(tag, a_track, b_track, in, out, xml); else { + kDebug()<<"// DELETING TRANS: "<plant_transition(*transition, a_track, b_track); + mlt_service_unlock(service.get_service()); + m_isBlocked--; if (do_refresh) refresh(); return true; }