[pitivi] render: Pick the default encoder from a list
- From: Alexandru Băluț <alexbalut src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] render: Pick the default encoder from a list
- Date: Mon, 1 Aug 2016 17:09:06 +0000 (UTC)
commit b15312eb9c3982c4bd6fff9ba0e4ddaa9c3287b4
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Sun Jul 10 00:22:30 2016 +0200
render: Pick the default encoder from a list
Reviewed-by: Thibault Saunier <tsaunier gnome org>
Differential Revision: https://phabricator.freedesktop.org/D1167
data/renderpresets/Blu-ray.json | 2 +-
pitivi/project.py | 14 +++-----
pitivi/render.py | 77 +++++++++++++++++++++++++++++++++++++--
tests/test_render.py | 45 +++++++++++++++++++++++
4 files changed, 124 insertions(+), 14 deletions(-)
---
diff --git a/data/renderpresets/Blu-ray.json b/data/renderpresets/Blu-ray.json
index e1c4b1b..8098d8a 100644
--- a/data/renderpresets/Blu-ray.json
+++ b/data/renderpresets/Blu-ray.json
@@ -9,5 +9,5 @@
"framerate-denom": 1001.0,
"width": 0,
"depth": 16,
- "acodec": "faac"
+ "acodec": "voaacenc"
}
diff --git a/pitivi/project.py b/pitivi/project.py
index f710a3d..e3587d7 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -59,9 +59,6 @@ from pitivi.utils.widgets import FractionWidget
DEFAULT_NAME = _("New Project")
-DEFAULT_MUXER = "oggmux"
-DEFAULT_VIDEO_ENCODER = "theoraenc"
-DEFAULT_AUDIO_ENCODER = "vorbisenc"
class ProjectManager(GObject.Object, Loggable):
@@ -671,8 +668,7 @@ class Project(Loggable, GES.Project):
self.container_profile = \
GstPbutils.EncodingContainerProfile.new("pitivi-profile",
_("Pitivi encoding profile"),
- Gst.Caps(
- "application/ogg"),
+ Gst.Caps("application/ogg"),
None)
self.video_profile = GstPbutils.EncodingVideoProfile.new(
Gst.Caps("video/x-theora"), None, Gst.Caps("video/x-raw"), 0)
@@ -682,9 +678,9 @@ class Project(Loggable, GES.Project):
self.container_profile.add_profile(self.audio_profile)
self.add_encoding_profile(self.container_profile)
- self.muxer = DEFAULT_MUXER
- self.vencoder = DEFAULT_VIDEO_ENCODER
- self.aencoder = DEFAULT_AUDIO_ENCODER
+ self.muxer = Encoders().default_muxer
+ self.vencoder = Encoders().default_video_encoder
+ self.aencoder = Encoders().default_audio_encoder
self._ensureAudioRestrictions()
self._ensureVideoRestrictions()
has_default_settings = not bool(uri) and not bool(scenario)
@@ -1141,7 +1137,7 @@ class Project(Loggable, GES.Project):
self.muxer = self._getElementFactoryName(
Encoders().muxers, container_profile)
if self.muxer is None:
- self.muxer = DEFAULT_MUXER
+ self.muxer = Encoders().default_muxer
for profile in container_profile.get_profiles():
if isinstance(profile, GstPbutils.EncodingVideoProfile):
self.video_profile = profile
diff --git a/pitivi/render.py b/pitivi/render.py
index 603a731..8cb99cb 100644
--- a/pitivi/render.py
+++ b/pitivi/render.py
@@ -44,7 +44,7 @@ from pitivi.utils.ui import set_combo_value
from pitivi.utils.widgets import GstElementSettingsDialog
-class Encoders(object):
+class Encoders(Loggable):
"""Registry of avalaible Muxers, Audio encoders and Video encoders.
Also keeps the avalaible combinations of those.
@@ -59,6 +59,45 @@ class Encoders(object):
compatible audio encoders ordered by rank.
compatible_video_encoders (dict): Maps each muxer name to a list of
compatible video encoders ordered by rank.
+ default_muxer (str): The factory name of the default muxer.
+ default_audio_encoder (str): The factory name of the default audio
+ encoder.
+ default_video_encoder (str): The factory name of the default video
+ encoder.
+ """
+
+ OGG = "oggmux"
+ MKV = "matroskamux"
+ MP4 = "mp4mux"
+ QUICKTIME = "qtmux"
+ WEBM = "webmmux"
+
+ AAC = "voaacenc"
+ AC3 = "avenc_ac3_fixed"
+ OPUS = "opusenc"
+ VORBIS = "vorbisenc"
+
+ JPEG = "jpegenc"
+ THEORA = "theoraenc"
+ VP8 = "vp8enc"
+ X264 = "x264enc"
+
+ SUPPORTED_ENCODERS_COMBINATIONS = [
+ (OGG, VORBIS, THEORA),
+ (OGG, OPUS, THEORA),
+ (WEBM, VORBIS, VP8),
+ (WEBM, OPUS, VP8),
+ (MP4, AAC, X264),
+ (MP4, AC3, X264),
+ (QUICKTIME, AAC, JPEG),
+ (MKV, OPUS, X264),
+ (MKV, VORBIS, X264),
+ (MKV, OPUS, JPEG),
+ (MKV, VORBIS, JPEG)]
+ """The combinations of muxers and encoders which are supported.
+
+ Mirror of GES_ENCODING_TARGET_COMBINATIONS from
+ https://cgit.freedesktop.org/gstreamer/gst-editing-services/tree/tests/validate/geslaunch.py
"""
_instance = None
@@ -67,6 +106,9 @@ class Encoders(object):
"""Returns the singleton instance."""
if not cls._instance:
cls._instance = super(Encoders, cls).__new__(cls, *args, **kwargs)
+ # We have to initialize the instance here, otherwise
+ # __init__ is called every time we use Encoders().
+ Loggable.__init__(cls._instance)
Gst.Registry.get().connect(
"feature-added", cls._instance._registry_feature_added_cb)
cls._instance._load_encoders()
@@ -108,6 +150,10 @@ class Encoders(object):
for muxer in useless_muxers:
self.muxers.remove(muxer)
+ self.default_muxer, \
+ self.default_audio_encoder, \
+ self.default_video_encoder = self._pick_defaults()
+
def _find_compatible_encoders(self, encoders, muxer):
"""Returns the list of encoders compatible with the specified muxer."""
res = []
@@ -130,6 +176,25 @@ class Encoders(object):
return True
return False
+ def _pick_defaults(self):
+ """Picks the defaults for new projects.
+
+ Returns:
+ (str, str, str): The muxer, audio encoder, video encoder.
+ """
+ muxer_names = [fact.get_name() for fact in self.muxers]
+ aencoder_names = [fact.get_name() for fact in self.aencoders]
+ vencoder_names = [fact.get_name() for fact in self.vencoders]
+ for muxer, audio, video in self.SUPPORTED_ENCODERS_COMBINATIONS:
+ if muxer not in muxer_names or \
+ audio not in aencoder_names or \
+ video not in vencoder_names:
+ continue
+ self.info("Default encoders: %s, %s, %s", muxer, audio, video)
+ return muxer, audio, video
+ self.warning("No good combination of container and encoders available.")
+ return Encoders.OGG, Encoders.VORBIS, Encoders.THEORA
+
def _registry_feature_added_cb(self, registry, feature):
# TODO Check what feature has been added and update our lists
pass
@@ -155,8 +220,12 @@ def beautify_factoryname(factory):
return " ".join(word for word in name.split())
-def extension_for_muxer(muxer):
- """Returns the file extension appropriate for the specified muxer."""
+def extension_for_muxer(muxer_name):
+ """Returns the file extension appropriate for the specified muxer.
+
+ Args:
+ muxer_name (str): The name of the muxer factory.
+ """
exts = {
"asfmux": "asf",
"avimux": "avi",
@@ -185,7 +254,7 @@ def extension_for_muxer(muxer):
"oggmux": "ogv",
"qtmux": "mov",
"webmmux": "webm"}
- return exts.get(muxer)
+ return exts.get(muxer_name)
def factorylist(factories):
diff --git a/tests/test_render.py b/tests/test_render.py
new file mode 100644
index 0000000..da3d789
--- /dev/null
+++ b/tests/test_render.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+# Pitivi video editor
+# Copyright (c) 2016, Alex Băluț <alexandru balut gmail com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+"""Tests for the render module."""
+from unittest import mock
+from unittest import TestCase
+
+from pitivi.preset import RenderPresetManager
+from pitivi.render import Encoders
+from pitivi.render import extension_for_muxer
+
+
+class TestRender(TestCase):
+ """Tests for functions."""
+
+ def test_extensions_supported(self):
+ """Checks we associate file extensions to the well supported muxers."""
+ for muxer, unused_audio, unused_video in Encoders.SUPPORTED_ENCODERS_COMBINATIONS:
+ self.assertIsNotNone(extension_for_muxer(muxer), muxer)
+
+ def test_extensions_presets(self):
+ """Checks we associate file extensions to the muxers of the presets."""
+ with mock.patch("pitivi.preset.xdg_data_home") as xdg_data_home:
+ xdg_data_home.return_value = "/pitivi-dir-which-does-not-exist"
+ preset_manager = RenderPresetManager(system=None)
+ preset_manager.loadAll()
+ self.assertTrue(preset_manager.presets)
+ for unused_name, preset in preset_manager.presets.items():
+ muxer = preset["container"]
+ self.assertIsNotNone(extension_for_muxer(muxer), preset)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]