From 0707b107f2a039720f5b774402056fc9a78dbe5f Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Mon, 21 Jul 2008 23:30:09 +0000 Subject: [PATCH] start implementing image / title transparency svn path=/branches/KDE4/; revision=2339 --- src/clipmanager.cpp | 1 + src/clipproperties.cpp | 25 ++++- src/customtrackview.cpp | 6 +- src/docclipbase.cpp | 7 ++ src/docclipbase.h | 2 + src/renderer.cpp | 183 +++++++++++++++++++++++++++++-- src/renderer.h | 5 +- src/widgets/clipproperties_ui.ui | 80 +++++++++----- 8 files changed, 271 insertions(+), 38 deletions(-) diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index c5494d25..232b311c 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -171,6 +171,7 @@ void ClipManager::slotAddTextClipFile(const QString path, const QString xml, con prod.setAttribute("groupid", groupId); } prod.setAttribute("type", (int) TEXT); + prod.setAttribute("transparency", "1"); prod.setAttribute("in", "0"); prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1); AddClipCommand *command = new AddClipCommand(m_doc, prod, id, true); diff --git a/src/clipproperties.cpp b/src/clipproperties.cpp index f631d06f..67bd0f2d 100644 --- a/src/clipproperties.cpp +++ b/src/clipproperties.cpp @@ -32,7 +32,9 @@ #define AUDIOTAB 1 #define COLORTAB 2 #define SLIDETAB 3 -#define ADVANCEDTAB 4 +#define IMAGETAB 4 +#define MARKERTAB 5 +#define ADVANCEDTAB 6 #define TYPE_JPEG 0 #define TYPE_PNG 1 @@ -55,8 +57,18 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg m_view.clip_channels->setText(props.value("channels")); CLIPTYPE t = m_clip->clipType(); - if (t == COLOR) { + if (t == IMAGE) { + m_view.tabWidget->removeTab(SLIDETAB); + m_view.tabWidget->removeTab(COLORTAB); + m_view.tabWidget->removeTab(AUDIOTAB); + m_view.tabWidget->removeTab(VIDEOTAB); + if (props.contains("frame_size")) + m_view.image_size->setText(props.value("frame_size")); + if (props.contains("transparency")) + m_view.image_transparency->setChecked(props.value("transparency").toInt()); + } else if (t == COLOR) { m_view.clip_path->setEnabled(false); + m_view.tabWidget->removeTab(IMAGETAB); m_view.tabWidget->removeTab(SLIDETAB); m_view.tabWidget->removeTab(AUDIOTAB); m_view.tabWidget->removeTab(VIDEOTAB); @@ -64,6 +76,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg m_view.clip_color->setColor(QColor("#" + props.value("colour").right(8).left(6))); } else if (t == SLIDESHOW) { m_view.clip_path->setText(url.directory()); + m_view.tabWidget->removeTab(IMAGETAB); m_view.tabWidget->removeTab(COLORTAB); m_view.tabWidget->removeTab(AUDIOTAB); m_view.tabWidget->removeTab(VIDEOTAB); @@ -106,6 +119,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg connect(m_view.image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(parseFolder())); } else if (t != AUDIO) { + m_view.tabWidget->removeTab(IMAGETAB); m_view.tabWidget->removeTab(SLIDETAB); m_view.tabWidget->removeTab(COLORTAB); if (props.contains("frame_size")) @@ -121,6 +135,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg m_view.clip_thumb->setPixmap(pix); if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(AUDIOTAB); } else { + m_view.tabWidget->removeTab(IMAGETAB); m_view.tabWidget->removeTab(SLIDETAB); m_view.tabWidget->removeTab(COLORTAB); m_view.tabWidget->removeTab(VIDEOTAB); @@ -208,6 +223,12 @@ QMap ClipProperties::properties() { m_clipNeedsRefresh = true; props["colour"] = "0x" + new_color.right(6) + "ff"; } + } else if (t == IMAGE) { + QMap old_props = m_clip->properties(); + if ((int) m_view.image_transparency->isChecked() != old_props.value("transparency").toInt()) { + props["transparency"] = QString::number((int)m_view.image_transparency->isChecked()); + m_clipNeedsRefresh = true; + } } else if (t == SLIDESHOW) { QMap old_props = m_clip->properties(); QString value = QString::number((int) m_view.slide_loop->isChecked()); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index ca3ea93f..cff74840 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -900,7 +900,7 @@ void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) { info.startPos = GenTime((int)(mapToScene(pos).x() / m_scale), m_document->fps()); info.endPos = info.startPos + clip->duration(); info.track = (int)(pos.y() / m_tracksHeight); - //kDebug()<<"------------ ADDING CLIP ITEM----: "<fps()); scene()->addItem(m_dropItem); } @@ -936,8 +936,10 @@ void CustomTrackView::dropEvent(QDropEvent * event) { ItemInfo info; info = m_dropItem->info(); info.track = m_tracksList.count() - m_dropItem->track(); - // kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<track(); + //kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<track(); m_document->renderer()->mltInsertClip(info, m_dropItem->xml(), m_dropItem->baseClip()->producer()); + //if (m_dropItem->baseClip()->isTransparent()) m_document->renderer()->mltAddClipTransparency(info, getPreviousVideoTrack(m_dropItem->track()), m_dropItem->baseClip()->getId()); + m_dropItem = NULL; m_document->setModified(true); } else QGraphicsView::dropEvent(event); m_dropItem = NULL; diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 0dc9b1a8..1ddf523b 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -139,6 +139,10 @@ const QString DocClipBase::description() const { return m_properties.value("description"); } +bool DocClipBase::isTransparent() const { + return (m_properties.value("transparency") == "1"); +} + const QString DocClipBase::getProperty(const QString prop) const { return m_properties.value(prop); } @@ -358,6 +362,7 @@ QString DocClipBase::markerComment(GenTime t) { void DocClipBase::setProducer(Mlt::Producer *producer) { m_clipProducer = producer; + m_clipProducer->set("transparency", m_properties.value("transparency").toInt()); if (m_thumbProd) m_thumbProd->setProducer(producer); } @@ -445,6 +450,7 @@ void DocClipBase::setProperties(QMap properties) { if (i.key() == "resource") m_thumbProd->updateClipUrl(KUrl(i.value())); else if (i.key() == "out") setDuration(GenTime(i.value().toInt(), KdenliveSettings::project_fps())); else if (m_clipType == SLIDESHOW && keys.contains(i.key())) refreshProducer = true; + else if (i.key() == "transparency") m_clipProducer->set("transparency", i.value().toInt()); } if (refreshProducer) slotRefreshProducer(); } @@ -453,6 +459,7 @@ void DocClipBase::setProperty(QString key, QString value) { m_properties.insert(key, value); if (key == "resource") m_thumbProd->updateClipUrl(KUrl(value)); else if (key == "out") setDuration(GenTime(value.toInt(), KdenliveSettings::project_fps())); + else if (key == "transparency") m_clipProducer->set("transparency", value.toInt()); } QMap DocClipBase::properties() const { diff --git a/src/docclipbase.h b/src/docclipbase.h index cd77e06d..2e9817ec 100644 --- a/src/docclipbase.h +++ b/src/docclipbase.h @@ -66,6 +66,8 @@ Q_OBJECT public: /** Returns the description of this clip. */ const QString description() const; + /** Does this clip need a transparent background (e.g. for titles). */ + bool isTransparent() const; /** Returns any property of this clip. */ const QString getProperty(const QString prop) const; diff --git a/src/renderer.cpp b/src/renderer.cpp index 48f12330..07b5349a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1204,6 +1204,9 @@ void Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pr Mlt::Producer *clip = prod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1); trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1); + if (QString(prod->get("transparency")).toInt() == 1) + mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt()); + mlt_service_unlock(service.get_service()); if (info.track != 0) mltCheckLength(); @@ -1255,6 +1258,9 @@ void Render::mltRemoveClip(int track, GenTime position) { Mlt::Producer trackProducer(tractor.track(track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); int clipIndex = trackPlaylist.get_clip_index_at((int) position.frames(m_fps)); + Mlt::Producer clip(trackPlaylist.get_clip(clipIndex)); + if (QString(clip.parent().get("transparency")).toInt() == 1) + mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt()); trackPlaylist.replace_with_blank(clipIndex); trackPlaylist.consolidate_blanks(0); if (track != 0) mltCheckLength(); @@ -1539,11 +1545,10 @@ void Render::mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out) { if (trackPlaylist.is_blank_at((int) pos.frames(m_fps) + 1)) kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; int clipIndex = trackPlaylist.get_clip_index_at((int) pos.frames(m_fps) + 1); - + Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex); + int previousStart = trackPlaylist.clip_start(clipIndex); int previousDuration = trackPlaylist.clip_length(clipIndex) - 1; int newDuration = (int) out.frames(m_fps) - 1; - - kDebug() << " ** RESIZING CLIP END:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", in: " << in.frames(25) << ", out: " << out.frames(25) << ", PREVIOUS duration: " << previousDuration; trackPlaylist.resize_clip(clipIndex, (int) in.frames(m_fps), newDuration); trackPlaylist.consolidate_blanks(0); if (previousDuration < newDuration) { @@ -1555,9 +1560,19 @@ void Render::mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out) { } else trackPlaylist.insert_blank(clipIndex + 1, previousDuration - newDuration - 1); trackPlaylist.consolidate_blanks(0); - tractor.multitrack()->refresh(); - tractor.refresh(); + + //tractor.multitrack()->refresh(); + //tractor.refresh(); if (track != 0) mltCheckLength(); + if (QString(clip->parent().get("transparency")).toInt() == 1) { + //mltResizeTransparency(previousStart, previousStart, previousStart + newDuration, track, QString(clip->parent().get("id")).toInt()); + mltDeleteTransparency(previousStart, track, QString(clip->parent().get("id")).toInt()); + ItemInfo info; + info.startPos = pos; + info.endPos = pos + out - in; + info.track = track; + mltAddClipTransparency(info, info.track - 1, QString(clip->parent().get("id")).toInt()); + } m_isBlocked = false; } @@ -1592,8 +1607,9 @@ void Render::mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime if (trackPlaylist.is_blank_at((int) pos.frames(m_fps) - 1)) kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; int clipIndex = trackPlaylist.get_clip_index_at((int) pos.frames(m_fps) - 1); - kDebug() << " ** RESIZING CLIP START:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", moving: " << moveFrame << ", in: " << in.frames(25) << ", out: " << out.frames(25); - + int previousStart = trackPlaylist.clip_start(clipIndex); + //kDebug() << " ** RESIZING CLIP START:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", moving: " << moveFrame << ", in: " << in.frames(25) << ", out: " << out.frames(25); + Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex); trackPlaylist.resize_clip(clipIndex, (int) in.frames(m_fps), (int) out.frames(m_fps)); if (moveFrame > 0) trackPlaylist.insert_blank(clipIndex, moveFrame - 1); else { @@ -1607,6 +1623,15 @@ void Render::mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1); } trackPlaylist.consolidate_blanks(0); + if (QString(clip->parent().get("transparency")).toInt() == 1) { + //mltResizeTransparency(previousStart, (int) moveEnd.frames(m_fps), (int) (moveEnd + out - in).frames(m_fps), track, QString(clip->parent().get("id")).toInt()); + mltDeleteTransparency(previousStart, track, QString(clip->parent().get("id")).toInt()); + ItemInfo info; + info.startPos = moveEnd; + info.endPos = moveEnd + out - in; + info.track = track; + mltAddClipTransparency(info, info.track - 1, QString(clip->parent().get("id")).toInt()); + } m_isBlocked = false; } @@ -1635,13 +1660,16 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn if (!trackPlaylist.is_blank_at(moveEnd)) { // error, destination is not empty //int ix = trackPlaylist.get_clip_index_at(moveEnd); - kDebug()<<"// ERROR MOVING CLIP TO : "<get_service()); m_isBlocked = false; return false; } else { trackPlaylist.insert_at(moveEnd, clipProducer, 1); trackPlaylist.consolidate_blanks(0); + if (QString(clipProducer.parent().get("transparency")).toInt() == 1) { + mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt()); + } } //mlt_service_unlock(service.get_service()); } else { @@ -1658,6 +1686,10 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn destTrackPlaylist.consolidate_blanks(1); destTrackPlaylist.insert_at(moveEnd, clipProducer, 1); destTrackPlaylist.consolidate_blanks(0); + if (QString(clipProducer.parent().get("transparency")).toInt() == 1) { + kDebug() << "//////// moving clip transparency"; + mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt()); + } } } mltCheckLength(); @@ -1852,6 +1884,141 @@ QMap Render::mltGetTransitionParamsFromXml(QDomElement xml) { return map; } +void Render::mltAddClipTransparency(ItemInfo info, int transitiontrack, int id) { + kDebug() << "///////// ADDING CLIP TRANSPARENCY AT: " << info.startPos.frames(25); + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); + + Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, "composite"); + transition->set_in_and_out((int) info.startPos.frames(m_fps), (int) info.endPos.frames(m_fps) - 1); + transition->set("transparency", id); + transition->set("fill", 1); + transition->set("internal_added", 237); + field->plant_transition(*transition, transitiontrack, info.track); + refresh(); +} + +void Render::mltDeleteTransparency(int pos, int track, int id) { + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); + + //if (do_refresh) m_mltConsumer->set("refresh", 0); + mlt_service serv = m_mltProducer->parent().get_service(); + + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + int transitionId = QString(mlt_properties_get(properties, "transparency")).toInt(); + kDebug() << "// FOUND EXISTING TRANS, IN: " << currentIn << ", OUT: " << currentOut << ", TRACK: " << currentTrack; + + if (resource == "composite" && track == currentTrack && currentIn == pos && transitionId == id) { + //kDebug() << " / / / / /DELETE TRANS DOOOMNE"; + mlt_field_disconnect_service(field->get_field(), nextservice); + break; + } + nextservice = mlt_service_producer(nextservice); + if (nextservice == NULL) break; + properties = MLT_SERVICE_PROPERTIES(nextservice); + mlt_type = mlt_properties_get(properties, "mlt_type"); + resource = mlt_properties_get(properties, "mlt_service"); + } + //if (do_refresh) m_mltConsumer->set("refresh", 1); +} + +void Render::mltResizeTransparency(int oldStart, int newStart, int newEnd, int track, int id) { + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); + + mlt_service_lock(service.get_service()); + m_mltConsumer->set("refresh", 0); + m_isBlocked = true; + + mlt_service serv = m_mltProducer->parent().get_service(); + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + kDebug() << "// resize transpar from: " << oldStart << ", TO: " << newStart << "x" << newEnd << ", " << track << ", " << id; + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + //mlt_properties props = MLT_TRANSITION_PROPERTIES(tr); + int transitionId = QString(mlt_properties_get(properties, "transparency")).toInt(); + kDebug() << "// resize transpar current in: " << currentIn << ", Track: " << currentTrack << ", id: " << id << "x" << transitionId ; + if (resource == "composite" && track == currentTrack && currentIn == oldStart && transitionId == id) { + kDebug() << " / / / / /RESIZE TRANS TO: " << newStart << "x" << newEnd; + mlt_transition_set_in_and_out(tr, newStart, newEnd); + break; + } + nextservice = mlt_service_producer(nextservice); + if (nextservice == NULL) break; + properties = MLT_SERVICE_PROPERTIES(nextservice); + mlt_type = mlt_properties_get(properties, "mlt_type"); + resource = mlt_properties_get(properties, "mlt_service"); + } + m_isBlocked = false; + mlt_service_unlock(service.get_service()); + m_mltConsumer->set("refresh", 1); + +} + +void Render::mltMoveTransparency(int startTime, int endTime, int startTrack, int endTrack, int id) { + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); + + mlt_service_lock(service.get_service()); + m_mltConsumer->set("refresh", 0); + m_isBlocked = true; + + mlt_service serv = m_mltProducer->parent().get_service(); + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentaTrack = mlt_transition_get_a_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + //mlt_properties properties = MLT_TRANSITION_PROPERTIES(tr); + int transitionId = QString(mlt_properties_get(properties, "transparency")).toInt(); + //kDebug()<<" + TRANSITION "<set("refresh", 1); +} + + void Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh) { QMap args = mltGetTransitionParamsFromXml(xml); diff --git a/src/renderer.h b/src/renderer.h index 4e483d87..6c4443a1 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -166,7 +166,10 @@ Q_OBJECT public: void mltDeleteTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool refresh = true); void mltUpdateTransition(QString oldTag, QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml); void mltUpdateTransitionParams(QString type, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml); - + void mltAddClipTransparency(ItemInfo info, int transitiontrack, int id); + void mltMoveTransparency(int startTime, int endTime, int startTrack, int endTrack, int id); + void mltDeleteTransparency(int pos, int track, int id); + void mltResizeTransparency(int oldStart, int newStart, int newEnd, int track, int id); private: // Private attributes & methods /** The name of this renderer - useful to identify the renderes by what they do - e.g. background rendering, workspace monitor, etc... */ diff --git a/src/widgets/clipproperties_ui.ui b/src/widgets/clipproperties_ui.ui index 2aded4a9..0c5d0352 100644 --- a/src/widgets/clipproperties_ui.ui +++ b/src/widgets/clipproperties_ui.ui @@ -13,6 +13,19 @@ Clip Properties + + + + Qt::Vertical + + + + 20 + 17 + + + + @@ -75,19 +88,6 @@ - - - - Qt::Vertical - - - - 20 - 17 - - - - @@ -101,7 +101,7 @@ - 3 + 4 @@ -409,6 +409,47 @@ + + + Image + + + + + + Image size + + + + + + + true + + + + + + + Transparent background + + + + + + + Qt::Vertical + + + + 20 + 151 + + + + + + @@ -573,17 +614,6 @@ - clip_thumb - label_5 - clip_path - label_3 - clip_description - clip_filesize_2 - clip_duration - clip_filesize_3 - clip_filesize - buttonBox - tabWidget -- 2.39.2