[pitivi] render: Handle encoder from encoding target not available
- From: Alexandru Băluț <alexbalut src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] render: Handle encoder from encoding target not available
- Date: Sun, 11 Oct 2020 23:20:36 +0000 (UTC)
commit f77154e6ae72ec12006d6ce3b8c2256f7de48c6c
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Fri Oct 2 01:11:33 2020 +0200
render: Handle encoder from encoding target not available
Fixes #2513
pitivi/project.py | 32 +++++++++++++++---------------
pitivi/render.py | 56 ++++++++++++++++++++++++++++++----------------------
tests/test_render.py | 28 ++++++++++++++++++++++++++
3 files changed, 76 insertions(+), 40 deletions(-)
---
diff --git a/pitivi/project.py b/pitivi/project.py
index 593200cf7..71c811705 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -1513,7 +1513,7 @@ class Project(Loggable, GES.Project):
if container_profile == self.container_profile:
return True
- muxer = self._get_element_factory_name(container_profile)
+ muxer = self.get_element_factory_name(container_profile)
if muxer is None:
muxer = Encoders().default_muxer
container_profile.set_preset_name(muxer)
@@ -1531,7 +1531,7 @@ class Project(Loggable, GES.Project):
if not self._ensure_video_restrictions(profile):
return False
- vencoder = self._get_element_factory_name(profile)
+ vencoder = self.get_element_factory_name(profile)
if vencoder:
profile.set_preset_name(vencoder)
elif isinstance(profile, GstPbutils.EncodingAudioProfile):
@@ -1542,7 +1542,7 @@ class Project(Loggable, GES.Project):
if not self._ensure_audio_restrictions(profile):
return False
- aencoder = self._get_element_factory_name(profile)
+ aencoder = self.get_element_factory_name(profile)
if aencoder:
profile.set_preset_name(aencoder)
else:
@@ -1563,7 +1563,7 @@ class Project(Loggable, GES.Project):
return True
def is_profile_subset(self, profile, superset):
- return self._get_element_factory_name(profile) == self._get_element_factory_name(superset)
+ return self.get_element_factory_name(profile) == self.get_element_factory_name(superset)
def matches_container_profile(self, container_profile):
if not self.is_profile_subset(container_profile, self.container_profile):
@@ -2151,7 +2151,7 @@ class Project(Loggable, GES.Project):
self.emit("rendering-settings-changed", key)
self.set_modification_state(True)
- def _get_element_factory_name(self, profile):
+ def get_element_factory_name(self, profile):
"""Finds a factory for an element compatible with the specified profile.
Args:
@@ -2174,17 +2174,17 @@ class Project(Loggable, GES.Project):
# The element does not need to support a specific preset.
# Return the compatible factory with the highest rank.
return factories[0].get_name()
-
- # Make sure that if a #Gst.Preset is set we find an
- # element that can handle that preset.
- for factory in factories:
- elem = factory.create()
- if isinstance(elem, Gst.Preset):
- if elem.load_preset(preset):
- return factory.get_name()
-
- self.error("Could not find any element with preset %s", preset)
- return None
+ else:
+ # Make sure that if a #Gst.Preset is set we find an
+ # element that can handle that preset.
+ for factory in factories:
+ elem = factory.create()
+ if isinstance(elem, Gst.Preset):
+ if elem.load_preset(preset):
+ return factory.get_name()
+
+ self.error("Could not find any element with preset %s", preset)
+ return None
@staticmethod
def __factories_compatible_with_profile(profile):
diff --git a/pitivi/render.py b/pitivi/render.py
index 1a8e1e87d..7d090890c 100644
--- a/pitivi/render.py
+++ b/pitivi/render.py
@@ -277,6 +277,13 @@ class PresetsManager(GObject.Object, Loggable):
if len(encoding_target.get_profiles()) != 1 and profile.get_name().lower() != "default":
name += "_" + profile.get_name()
+ # Check the GStreamer elements are available.
+ profiles = [profile] + profile.get_profiles()
+ if not all([self.project.get_element_factory_name(p)
+ for p in profiles]):
+ self.warning("unusable preset: %s", name)
+ continue
+
preset_item = PresetItem(name, encoding_target, profile)
self.model.insert_sorted(preset_item, PresetItem.compare_func)
preset_items.append(preset_item)
@@ -320,27 +327,32 @@ class PresetsManager(GObject.Object, Loggable):
"""
self.cur_preset_item = preset_item
writable = bool(preset_item) and \
- len(preset_item.target.get_profiles()) == 1 and \
- os.access(preset_item.target.get_path(), os.W_OK)
+ len(preset_item.target.get_profiles()) == 1 and \
+ os.access(preset_item.target.get_path(), os.W_OK)
self.action_remove.set_enabled(writable)
self.action_save.set_enabled(writable)
- def select_default_preset(self):
- """Selects the default hardcoded preset."""
- for item in self.model:
- if item.name == "youtube":
- self.select_preset(item)
- break
+ def initial_preset(self):
+ """Returns the initial preset to be displayed."""
+ has_vcodecsettings = bool(self.project.vcodecsettings)
+ if has_vcodecsettings:
+ # It's a project with previous render settings, see what matches.
+ return self.matching_preset()
+ else:
+ # It's a new project.
+ for item in self.model:
+ if item.name == "youtube":
+ return item
+
+ return None
- def select_matching_preset(self):
- """Selects the first preset matching the project's encoders settings."""
+ def matching_preset(self):
+ """Returns the first preset matching the project's encoding profile."""
for item in self.model:
if self.project.matches_container_profile(item.profile):
- self.select_preset(item)
- return
-
- self.select_preset(None)
+ return item
+ return None
class Encoders(Loggable):
@@ -834,16 +846,11 @@ class RenderDialog(Loggable):
self.presets_manager.connect("profile-updated", self._presets_manager_profile_updated_cb)
- has_vcodecsettings = bool(self.project.vcodecsettings)
- if has_vcodecsettings:
- self.presets_manager.select_matching_preset()
- else:
- self.presets_manager.select_default_preset()
- cur_preset_item = self.presets_manager.cur_preset_item
- if cur_preset_item and self.apply_preset(cur_preset_item):
+ preset_item = self.presets_manager.initial_preset()
+ if preset_item:
+ if self.apply_preset(preset_item):
self.apply_vcodecsettings_quality(Quality.MEDIUM)
- else:
- self.presets_manager.select_preset(None)
+ self.presets_manager.select_preset(preset_item)
set_icon_and_title(self.preset_icon, self.preset_label, self.presets_manager.cur_preset_item)
self._update_quality_scale()
@@ -1751,7 +1758,8 @@ class RenderDialog(Loggable):
if self._setting_encoding_profile:
return
- self.presets_manager.select_matching_preset()
+ preset_item = self.presets_manager.matching_preset()
+ self.presets_manager.select_preset(preset_item)
def _update_quality_scale(self):
encoder = get_combo_value(self.video_encoder_combo)
diff --git a/tests/test_render.py b/tests/test_render.py
index 138d38ca2..47aac4dde 100644
--- a/tests/test_render.py
+++ b/tests/test_render.py
@@ -79,6 +79,34 @@ def setup_render_presets(*profiles):
return setup_wrapper
+class TestPresetsManager(common.TestCase):
+
+ @skipUnless(*encoding_target_exists("youtube"))
+ @skipUnless(*factory_exists("x264enc"))
+ def test_initial_preset(self):
+ project = common.create_project()
+ manager = PresetsManager(project)
+
+ self.assertEqual(manager.initial_preset().name, "youtube")
+
+ def test_missing_x264(self):
+ # Simulate no encoder being available for the profile's format.
+ targets = GstPbutils.encoding_list_all_targets()
+ for target in targets:
+ for profile in target.get_profiles():
+ for sub_profile in profile.get_profiles():
+ raw_caps = "audio/non_existing_whatever_it_s_true"
+ sub_profile.get_format = mock.Mock(return_value=raw_caps)
+
+ with mock.patch.object(GstPbutils, "encoding_list_all_targets") as encoding_list_all_targets:
+ encoding_list_all_targets.return_value = targets
+
+ project = common.create_project()
+ manager = PresetsManager(project)
+
+ self.assertIsNone(manager.initial_preset())
+
+
class TestQualityAdapter(common.TestCase):
"""Tests for the QualityAdapter class."""
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]