[pitivi] transformation: Handle rotation with the videoflip element



commit d08dc443411b1d40b8c97e9c95998caad5d24499
Author: Thibault Saunier <tsaunier gnome org>
Date:   Wed Aug 3 15:22:28 2016 -0400

    transformation: Handle rotation with the videoflip element
    
    Take into account rotation to compute size of the video when
    the videoflip element is used.
    
    We only handle 90° rotations as this is the only important case
    for that element. We still do not handle arbitrary rotations done
    by the videorotate element.
    
    Differential Revision: https://phabricator.freedesktop.org/D1244

 pitivi/clipproperties.py        |    2 +-
 pitivi/timeline/elements.py     |   51 ++++++++++++++++++++++++++++++++++++--
 tests/test_timeline_elements.py |   44 +++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+), 4 deletions(-)
---
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index d06ea43..57ac1e9 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -450,7 +450,7 @@ class EffectProperties(Gtk.Expander, Loggable):
         _iter = self.storemodel.get_iter(path)
         tck_effect = self.storemodel.get_value(_iter, COL_TRACK_EFFECT)
         with self.app.action_log.started("change active state"):
-            tck_effect.set_active(not tck_effect.is_active())
+            tck_effect.props.active = not tck_effect.props.active
             cellrenderertoggle.set_active(tck_effect.is_active())
             self._updateTreeview()
             self._project.ges_timeline.commit()
diff --git a/pitivi/timeline/elements.py b/pitivi/timeline/elements.py
index 73f5e31..4732d01 100644
--- a/pitivi/timeline/elements.py
+++ b/pitivi/timeline/elements.py
@@ -634,12 +634,34 @@ class VideoSource(TimelineElement):
         project.connect("video-size-changed",
                         self._project_video_size_changed_cb)
 
+        self.__videoflip = None
         self.__retrieve_project_size()
         self.default_position = self._get_default_position()
 
         if project.loaded:
             self.__apply_default_position()
 
+        parent = element.get_parent()
+        parent.connect("child-added", self.__parent_child_added_cb)
+        parent.connect("child-removed", self.__parent_child_removed_cb)
+
+    def __parent_child_added_cb(self, parent, child):
+        project = self.timeline.app.project_manager.current_project
+        self.__apply_new_size_if_needed(project)
+
+    def __parent_child_removed_cb(self, parent, child):
+        project = self.timeline.app.project_manager.current_project
+        if child == self.__videoflip:
+            self.__videoflip = None
+            self.__apply_new_size_if_needed(project)
+            misc.disconnectAllByFunc(child, self.__videoflip_changed_cb)
+
+    def __videoflip_changed_cb(self, unused_child=None,
+                               unused_element=None,
+                               unused_pspec=None):
+        project = self.timeline.app.project_manager.current_project
+        self.__apply_new_size_if_needed(project)
+
     def __retrieve_project_size(self):
         project = self.timeline.app.project_manager.current_project
 
@@ -647,6 +669,9 @@ class VideoSource(TimelineElement):
         self._project_height = project.videoheight
 
     def _project_video_size_changed_cb(self, project):
+        self.__apply_new_size_if_needed(project)
+
+    def __apply_new_size_if_needed(self, project):
         using_defaults = True
         for name, default_value in self.default_position.items():
             res, value = self._ges_elem.get_child_property(name)
@@ -672,6 +697,29 @@ class VideoSource(TimelineElement):
         video_source = self._ges_elem
         sinfo = video_source.get_asset().get_stream_info()
 
+        asset_width = sinfo.get_width()
+        asset_height = sinfo.get_height()
+        parent = video_source.get_parent()
+        if not self.__videoflip:
+            for track_element in parent.find_track_elements(
+                    None, GES.TrackType.VIDEO, GES.BaseEffect):
+
+                res, videoflip, unused_pspec = track_element.lookup_child(
+                    "GstVideoFlip::method")
+                if res:
+                    self.__videoflip = track_element
+                    track_element.connect("deep-notify",
+                                          self.__videoflip_changed_cb)
+                    track_element.connect("notify::active",
+                                          self.__videoflip_changed_cb)
+
+        if self.__videoflip:
+            res, method = self.__videoflip.get_child_property("method")
+            assert res
+            if "clockwise" in method.value_nick and self.__videoflip.props.active:
+                asset_width = sinfo.get_height()
+                asset_height = sinfo.get_width()
+
         # Find the biggest size of the video inside the
         # final view (project size) keeping the aspect ratio
         scale = max(self._project_width / asset_width,
@@ -682,9 +730,6 @@ class VideoSource(TimelineElement):
             scale = min(self._project_width / asset_width,
                         self._project_height / asset_height)
 
-        asset_width = sinfo.get_width()
-        asset_height = sinfo.get_height()
-
         width = asset_width * scale
         height = asset_height * scale
         x = max(0, (self._project_width - width) / 2)
diff --git a/tests/test_timeline_elements.py b/tests/test_timeline_elements.py
index fe15138..0e804ee 100644
--- a/tests/test_timeline_elements.py
+++ b/tests/test_timeline_elements.py
@@ -145,3 +145,47 @@ class TestVideoSourceScaling(BaseTestTimeline):
             "posy": 140}
         self.assertEqual(video_source.ui.default_position,
                          expected_default_position)
+
+    def test_rotation(self):
+        timeline = self.createTimeline()
+        project = timeline.app.project_manager.current_project
+
+        clip = self.addClipsSimple(timeline, 1)[0]
+
+        video_source = clip.find_track_element(None, GES.VideoUriSource)
+        sinfo = video_source.get_asset().get_stream_info()
+
+        width = video_source.get_child_property("width")[1]
+        height = video_source.get_child_property("height")[1]
+        self.assertEqual(sinfo.get_width(), 960)
+        self.assertEqual(sinfo.get_height(), 400)
+        self.assertEqual(width, 960)
+        self.assertEqual(height, 400)
+
+        videoflip = GES.Effect.new("videoflip")
+        videoflip.set_child_property("method", 1)  # clockwise
+
+        clip.add(videoflip)
+        # The video is flipped 90 degrees
+        width = video_source.get_child_property("width")[1]
+        height = video_source.get_child_property("height")[1]
+        self.assertEqual(width, 167)
+        self.assertEqual(height, 400)
+
+        videoflip.props.active = False
+        width = video_source.get_child_property("width")[1]
+        height = video_source.get_child_property("height")[1]
+        self.assertEqual(width, 960)
+        self.assertEqual(height, 400)
+
+        videoflip.props.active = True
+        width = video_source.get_child_property("width")[1]
+        height = video_source.get_child_property("height")[1]
+        self.assertEqual(width, 167)
+        self.assertEqual(height, 400)
+
+        clip.remove(videoflip)
+        width = video_source.get_child_property("width")[1]
+        height = video_source.get_child_property("height")[1]
+        self.assertEqual(width, 960)
+        self.assertEqual(height, 400)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]