]> git.sesse.net Git - kdenlive/commitdiff
start documenting the rotoscoping code
authorTill Theato <root@ttill.de>
Sat, 19 Mar 2011 23:12:57 +0000 (23:12 +0000)
committerTill Theato <root@ttill.de>
Sat, 19 Mar 2011 23:12:57 +0000 (23:12 +0000)
svn path=/trunk/kdenlive/; revision=5506

effects/README
src/rotoscoping/rotowidget.cpp
src/rotoscoping/rotowidget.h

index b36ba564787bc8586c5464c91608048a375e059d..fc72060322f8203e7d3d08bbc67c6c5a6dcaae33 100644 (file)
@@ -29,7 +29,7 @@ The basic structure of a XML filter description:
 --------------------------------------------------------------------------------------
 
 Line 1:
-    - required to make strings in the effect translatable
+    - required to make strings used in the effect translatable
 Line 2:
     - tag: MLT ("mlt_service") name of the effect
     - id: internal kdenlive id, can be anything, but must be unique for each effect
index 937116951d7c714ca40994198a0d51bb49bbea22..abfef3dd819f7986779c822d25141e238b487f95 100644 (file)
@@ -58,6 +58,9 @@ RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode
 
     
     if (m_data.canConvert(QVariant::Map)) {
+        /*
+         * pass keyframe data to keyframe timeline
+         */
         QList <int> keyframes;
         QMap <QString, QVariant> map = m_data.toMap();
         QMap <QString, QVariant>::const_iterator i = map.constBegin();
@@ -76,6 +79,7 @@ RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode
         }
         m_data = QVariant(map);
     } else {
+        // static (only one keyframe)
         m_keyframeWidget->setKeyframes(QList <int>() << 0);
     }
 
@@ -137,6 +141,9 @@ void RotoWidget::slotUpdateData(int pos, bool editing)
     int width = m_monitor->render->frameRenderWidth();
     int height = m_monitor->render->renderHeight();
 
+    /*
+     * use the position of the on-monitor points to create a storable list
+     */
     QList <BPoint> spline = m_item->getPoints();
     QList <QVariant> vlist;
     foreach (const BPoint &point, spline) {
@@ -148,6 +155,8 @@ void RotoWidget::slotUpdateData(int pos, bool editing)
 
     if (m_data.canConvert(QVariant::Map)) {
         QMap <QString, QVariant> map = m_data.toMap();
+        // replace or insert at position
+        // we have to fill with 0s to maintain the correct order
         map[QString::number((pos < 0 ? m_keyframeWidget->getPosition() : pos) + m_in).rightJustified(qRound(log10((double)m_out)), '0')] = QVariant(vlist);
         m_data = QVariant(map);
     } else {
@@ -170,6 +179,7 @@ QString RotoWidget::getSpline()
 
 void RotoWidget::slotPositionChanged(int pos, bool seek)
 {
+    // do not update while the spline is being edited (points are being dragged)
     if (m_item->editing())
         return;
 
@@ -184,16 +194,22 @@ void RotoWidget::slotPositionChanged(int pos, bool seek)
         QMap <QString, QVariant>::const_iterator i = map.constBegin();
         int keyframe1, keyframe2;
         keyframe1 = keyframe2 = i.key().toInt();
+        // find keyframes next to pos
         while (i.key().toInt() < pos && ++i != map.constEnd()) {
             keyframe1 = keyframe2;
             keyframe2 = i.key().toInt();
         }
 
         if (keyframe1 != keyframe2 && pos < keyframe2) {
+            /*
+             * in between two keyframes
+             * -> interpolate
+             */
             QList <BPoint> p1 = getPoints(keyframe1);
             QList <BPoint> p2 = getPoints(keyframe2);
             qreal relPos = (pos - keyframe1) / (qreal)(keyframe2 - keyframe1 + 1);
 
+            // additionaly points are ignored (same behavior as MLT filter)
             int count = qMin(p1.count(), p2.count());
             for (int i = 0; i < count; ++i) {
                 BPoint bp;
@@ -280,8 +296,10 @@ void RotoWidget::slotRemoveKeyframe(int pos)
     map.remove(QString::number(pos + m_in).rightJustified(qRound(log10((double)m_out)), '0'));
     m_data = QVariant(map);
 
-    if (m_data.toMap().count() == 1)
+    if (m_data.toMap().count() == 1) {
+        // only one keyframe -> switch from map to list again
         m_data = m_data.toMap().begin().value();
+    }
 
     slotPositionChanged(m_keyframeWidget->getPosition(), false);
     emit valueChanged();
index dc385f673e062c4cc7fedf0b9f3b14a03726b15d..93dddbecdf81645f06d0e2bb90480cf73250bff3 100644 (file)
@@ -37,7 +37,10 @@ public:
     RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode t, QWidget* parent = 0);
     virtual ~RotoWidget();
 
+    /** @brief Returns the spline(s) in the JSON format used by filter_rotoscoping (MLT). */
     QString getSpline();
+
+    /** @brief Passed on to the keyframe timeline. Switches between frames and hh:mm:ss:ff timecode. */
     void updateTimecodeFormat();
 
 public slots:
@@ -62,6 +65,10 @@ private:
     int m_in;
     int m_out;
 
+    /** @brief Returns the list of cubic Bézier points that form the spline at position @param keyframe.
+     * The points are brought from the range [0, 1] into project resolution space.
+     * This function does not do any interpolation and therfore will only return a list when a keyframe at the given postion exists.
+     * Set @param keyframe to -1 if only one keyframe currently exists. */
     QList <BPoint> getPoints(int keyframe);
 
 private slots:
@@ -69,9 +76,12 @@ private slots:
     * @param renderPos Postion of the Monitor / Timeline cursor */
     void slotCheckMonitorPosition(int renderPos);
 
+    /** @brief Updates/Creates the spline at @param pos based on the on-monitor items. */
     void slotUpdateData(int pos = -1, bool editing = false);
+    /** @brief Updates/Creates the spline at the current timeline position based on the on-monitor items. */
     void slotUpdateData(bool editing);
 
+    /** @brief Updates the on-monitor items to fit the spline at position @param pos. */
     void slotPositionChanged(int pos, bool seek = true);
 
     void slotAddKeyframe(int pos = -1);