X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fdocclipbase.cpp;h=5d41cc04cdf22899b8b9b004ea0520c663853ddc;hb=0bcde0245381a4e565bec8a17177290850151a56;hp=693e4ecca2f2829fc62d73add95782907d46fb70;hpb=4191df91ef00b8e1ea8f5cf627da46eb53246302;p=kdenlive diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 693e4ecc..5d41cc04 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -32,16 +32,19 @@ #include #include +#include #include #include #include #include +#include DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id) : QObject(), - m_audioFrameCache(), + lastSeekPosition(0), + audioFrameCache(), m_refcount(0), m_baseTrackProducers(), m_videoTrackProducers(), @@ -73,6 +76,12 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin } } + if (xml.hasAttribute("analysisdata")) { + QStringList adata = xml.attribute("analysisdata").split('#', QString::SkipEmptyParts); + for (int i = 0; i < adata.count(); i++) + m_analysisdata.insert(adata.at(i).section('?', 0, 0), adata.at(i).section('?', 1, 1)); + } + KUrl url = KUrl(xml.attribute("resource")); if (!m_properties.contains("file_hash") && !url.isEmpty()) getFileHash(url.path()); @@ -131,7 +140,7 @@ bool DocClipBase::hasAudioThumb() const void DocClipBase::slotClearAudioCache() { - m_audioFrameCache.clear(); + audioFrameCache.clear(); m_audioThumbCreated = false; } @@ -255,6 +264,16 @@ QDomElement DocClipBase::toXML(bool hideTemporaryProperties) const } clip.setAttribute("cutzones", cuts.join(";")); } + QString adata; + if (!m_analysisdata.isEmpty()) { + QMapIterator i(m_analysisdata); + while (i.hasNext()) { + i.next(); + //WARNING: a ? and # separator is not a good idea + adata.append(i.key() + "?" + i.value() + "#"); + } + } + clip.setAttribute("analysisdata", adata); //kDebug() << "/// CLIP XML: " << doc.toString(); return doc.documentElement(); } @@ -268,7 +287,7 @@ void DocClipBase::setAudioThumbCreated(bool isDone) void DocClipBase::updateAudioThumbnail(const audioByteArray& data) { //kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************"; - m_audioFrameCache = data; + audioFrameCache = data; m_audioThumbCreated = true; emit gotAudioData(); } @@ -1259,10 +1278,56 @@ QImage DocClipBase::extractImage(int frame, int width, int height) return m_thumbProd->extractImage(frame, width, height); } -void DocClipBase::setAnalysisData(const QString &name, const QString &data) +void DocClipBase::setAnalysisData(const QString &name, const QString &data, int offset) { if (data.isEmpty()) m_analysisdata.remove(name); - else m_analysisdata.insert(name, data); + else { + if (m_analysisdata.contains(name)) { + if (KMessageBox::questionYesNo(kapp->activeWindow(), i18n("Clip already contains analysis data %1", name), QString(), KGuiItem(i18n("Merge")), KGuiItem(i18n("Add"))) == KMessageBox::Yes) { + // Merge data + Mlt::Profile *profile = m_baseTrackProducers.at(0)->profile(); + Mlt::Geometry geometry(m_analysisdata.value(name).toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::Geometry newGeometry(data.toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::GeometryItem item; + int pos = 0; + while (!newGeometry.next_key(&item, pos)) { + pos = item.frame(); + item.frame(pos + offset); + pos++; + geometry.insert(item); + } + m_analysisdata.insert(name, geometry.serialise()); + } + else { + // Add data with another name + int i = 1; + QString newname = name + " " + QString::number(i); + while (m_analysisdata.contains(newname)) { + i++; + newname = name + " " + QString::number(i); + } + m_analysisdata.insert(newname, geometryWithOffset(data, offset)); + } + } + else m_analysisdata.insert(name, geometryWithOffset(data, offset)); + } +} + +const QString DocClipBase::geometryWithOffset(QString data, int offset) +{ + if (offset == 0) return data; + Mlt::Profile *profile = m_baseTrackProducers.at(0)->profile(); + Mlt::Geometry geometry(data.toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::Geometry newgeometry("", m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::GeometryItem item; + int pos = 0; + while (!geometry.next_key(&item, pos)) { + pos = item.frame(); + item.frame(pos + offset); + pos++; + newgeometry.insert(item); + } + return newgeometry.serialise(); } QMap DocClipBase::analysisData() const