Commit c9293d18 authored by Alexandru Băluț's avatar Alexandru Băluț

render: Fix clips size restoring after scaled rendering

Fixes https://phabricator.freedesktop.org/T7809

Differential Revision: https://phabricator.freedesktop.org/D1928
parent 4baf57c3
......@@ -872,11 +872,11 @@ class RenderDialog(Loggable):
self._rendering_is_paused = False
self._time_spent_paused = 0
self._pipeline.set_state(Gst.State.NULL)
self.project.set_rendering(False)
self.__useProxyAssets()
self._disconnectFromGst()
self._pipeline.set_mode(GES.PipelineFlags.FULL_PREVIEW)
self._pipeline.set_state(Gst.State.PAUSED)
self.project.set_rendering(False)
def _pauseRender(self, unused_progress):
self._rendering_is_paused = self.progress.play_pause_button.get_active(
......@@ -926,7 +926,7 @@ class RenderDialog(Loggable):
self.debug("Rendering from proxies, not replacing assets")
return
for layer in self.app.gui.timeline_ui.ges_timeline.get_layers():
for layer in self.app.project_manager.current_project.ges_timeline.get_layers():
for clip in layer.get_clips():
if not isinstance(clip, GES.UriClip):
continue
......@@ -934,29 +934,34 @@ class RenderDialog(Loggable):
asset = clip.get_asset()
asset_target = asset.get_proxy_target()
if not asset_target:
# The asset is not a proxy.
continue
if self.__automatically_use_proxies.get_active():
if self.app.proxy_manager.isAssetFormatWellSupported(
if not self.app.proxy_manager.isAssetFormatWellSupported(
asset_target):
self.info("Asset %s format well supported, "
"rendering from real asset.",
asset_target.props.id)
else:
self.info("Asset %s format not well supported, "
self.info("Original asset %s format not well supported, "
"rendering from proxy.",
asset_target.props.id)
continue
if not asset_target.get_error():
clip.set_asset(asset_target)
self.error("Using %s as an asset (instead of %s)",
asset_target.get_id(),
asset.get_id())
self.__unproxiedClips[clip] = asset
self.info("Original asset %s format well supported, "
"rendering from real asset.",
asset_target.props.id)
if asset_target.get_error():
# The original asset cannot be used.
continue
clip.set_asset(asset_target)
self.info("Using original asset %s (instead of proxy %s)",
asset_target.get_id(),
asset.get_id())
self.__unproxiedClips[clip] = asset
def __useProxyAssets(self):
for clip, asset in self.__unproxiedClips.items():
self.info("Reverting to using proxy asset %s", asset)
clip.set_asset(asset)
self.__unproxiedClips = {}
......
......@@ -439,7 +439,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
def setProject(self, project):
"""Connects to the GES.Timeline holding the project."""
# Avoid starting/closing preview generation like crazy while tearing down project
with Previewer.manager.paused(True):
with Previewer.manager.paused(interrupt=True):
if self.ges_timeline is not None:
self.disconnect_by_func(self._button_press_event_cb)
self.disconnect_by_func(self._button_release_event_cb)
......
......@@ -27,7 +27,6 @@ import tempfile
import unittest
from unittest import mock
from gi.repository import GES
from gi.repository import GLib
from gi.repository import Gst
from gi.repository import Gtk
......@@ -72,6 +71,10 @@ def create_pitivi_mock(**settings):
app.settings = __create_settings(**settings)
app.proxy_manager = ProxyManager(app)
# TODO: Get rid of Zoomable.app.
from pitivi.utils.timeline import Zoomable
Zoomable.app = app
return app
......@@ -91,6 +94,12 @@ def create_pitivi(**settings):
def create_timeline_container():
# TODO: Get rid of Previewer.manager.
from pitivi.timeline.previewers import Previewer
from pitivi.timeline.previewers import PreviewGeneratorManager
assert hasattr(Previewer, "manager")
Previewer.manager = PreviewGeneratorManager()
app = create_pitivi_mock()
project_manager = ProjectManager(app)
project_manager.newBlankProject()
......@@ -118,10 +127,12 @@ def create_main_loop():
timed_out = True
mainloop.quit()
def run(timeout_seconds=5):
def run(timeout_seconds=5, until_empty=False):
source = GLib.timeout_source_new_seconds(timeout_seconds)
source.set_callback(timeout_cb)
source.attach()
if until_empty:
GLib.idle_add(mainloop.quit)
GLib.MainLoop.run(mainloop)
source.destroy()
if timed_out:
......@@ -249,29 +260,28 @@ def created_project_file(asset_uri):
os.remove(xges_path)
def get_sample_uri(sample, tests_dir=None):
if not tests_dir:
def get_sample_uri(sample, samples_dir=None):
if not samples_dir:
tests_dir = os.path.dirname(os.path.abspath(__file__))
tests_dir = os.path.join(tests_dir, "samples")
return Gst.filename_to_uri(os.path.join(tests_dir, sample))
samples_dir = os.path.join(tests_dir, "samples")
return Gst.filename_to_uri(os.path.join(samples_dir, sample))
@contextlib.contextmanager
def cloned_sample(*samples):
"""Gets a context manager which commits the transaction at the end."""
tmpdir = tempfile.mkdtemp(suffix="pitivi_cloned_samples")
module = globals()
original_get_sample_uri = module["get_sample_uri"]
module["get_sample_uri"] = lambda sample: original_get_sample_uri(sample, tests_dir=tmpdir)
for sample in samples:
sample_path = path_from_uri(original_get_sample_uri(sample))
clone_path = path_from_uri(get_sample_uri(sample))
shutil.copyfile(sample_path, clone_path)
try:
yield tmpdir
finally:
module["get_sample_uri"] = original_get_sample_uri
shutil.rmtree(tmpdir)
with tempfile.TemporaryDirectory() as tmpdir:
module = globals()
original_get_sample_uri = module["get_sample_uri"]
module["get_sample_uri"] = lambda sample: original_get_sample_uri(sample, samples_dir=tmpdir)
try:
for sample in samples:
sample_path = path_from_uri(original_get_sample_uri(sample))
clone_path = path_from_uri(get_sample_uri(sample))
shutil.copyfile(sample_path, clone_path)
yield tmpdir
finally:
module["get_sample_uri"] = original_get_sample_uri
def get_clip_children(ges_clip, *track_types, recursive=False):
......
......@@ -32,9 +32,11 @@ from gi.repository import Gtk
from pitivi.preset import EncodingTargetManager
from pitivi.render import Encoders
from pitivi.render import extension_for_muxer
from pitivi.timeline.timeline import TimelineContainer
from pitivi.utils.ui import get_combo_value
from pitivi.utils.ui import set_combo_value
from tests import common
from tests.test_media_library import BaseTestMediaLibrary
def factory_exists(*factories):
......@@ -63,7 +65,7 @@ def find_preset_row_index(combo, name):
return None
class TestRender(common.TestCase):
class TestRender(BaseTestMediaLibrary):
"""Tests for functions."""
def test_extensions_supported(self):
......@@ -104,8 +106,8 @@ class TestRender(common.TestCase):
mainloop.run()
layer, = project.ges_timeline.get_layers()
layer.add_asset(project.list_assets(GES.UriClip)[0],
0, 0, Gst.CLOCK_TIME_NONE, GES.TrackType.UNKNOWN)
asset, = project.list_assets(GES.UriClip)
layer.add_asset(asset, 0, 0, Gst.CLOCK_TIME_NONE, GES.TrackType.UNKNOWN)
return project
......@@ -263,7 +265,9 @@ class TestRender(common.TestCase):
def check_simple_rendering_profile(self, profile_name):
"""Checks that rendering with the specified profile works."""
# TODO: Get rid of Zoomable._instances.
from pitivi.utils.timeline import Zoomable
del Zoomable._instances[:]
project = self.create_simple_project()
dialog = self.create_rendering_dialog(project)
......@@ -290,18 +294,55 @@ class TestRender(common.TestCase):
message = dialog._pipeline.get_bus().timed_pop_filtered(
10 * Gst.SECOND,
Gst.MessageType.EOS | Gst.MessageType.ERROR)
self.assertIsNotNone(message)
Gst.debug_bin_to_dot_file_with_ts(
dialog._pipeline, Gst.DebugGraphDetails.ALL,
"test_rendering_with_profile.dot")
result_file = Gst.filename_to_uri(os.path.join(temp_dir, "outfile"))
struct = message.get_structure() if message else None
struct = message.get_structure()
self.assertEqual(message.type, Gst.MessageType.EOS,
struct.to_string() if struct else message)
asset = GES.UriClipAsset.request_sync(result_file)
# FIXME Check more things?
self.assertIsNotNone(asset)
if message:
dialog._pipeline.get_bus().post(message)
def test_rendering_with_scale(self):
"""Tests rendering with a smaller scale."""
sample_name = "30fps_numeroted_frames_red.mkv"
with common.cloned_sample(sample_name):
self.check_import([sample_name])
project = self.app.project_manager.current_project
timeline_container = TimelineContainer(self.app)
timeline_container.setProject(project)
assets = project.list_assets(GES.UriClip)
asset, = [a for a in assets if "proxy" in a.props.id]
layer, = project.ges_timeline.get_layers()
clip = asset.extract()
layer.add_clip(clip)
video_source = clip.find_track_element(None, GES.VideoUriSource)
self.assertEqual(video_source.get_child_property("width")[1], 320)
self.assertEqual(video_source.get_child_property("height")[1], 240)
dialog = self.create_rendering_dialog(project)
# Simulate setting the scale to 10%.
with mock.patch.object(dialog.scale_spinbutton, "get_value",
return_value=10):
dialog._scaleSpinbuttonChangedCb(None)
self.render(dialog)
self.mainloop.run(until_empty=True)
video_source = clip.find_track_element(None, GES.VideoUriSource)
self.assertEqual(video_source.get_child_property("width")[1], 320)
self.assertEqual(video_source.get_child_property("height")[1], 240)
@skipUnless(*encoding_target_exists("youtube"))
# pylint: disable=invalid-name
def test_rendering_with_youtube_profile(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment