[pitivi] project: Set the audiorate only when decent



commit 5c1f9d4a88249fc4fb7a3c5bacd71a34604ffbf9
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Tue May 25 22:24:30 2021 +0200

    project: Set the audiorate only when decent
    
    If the first imported audio asset has a small audio rate and other
    assets have a higher audio rate, we risk some audio quality will be
    lost.

 pitivi/project.py     | 33 +++++++++++++++++++++++++--------
 tests/test_project.py | 23 +++++++++++++++--------
 tests/test_render.py  | 12 ++++++++++++
 3 files changed, 52 insertions(+), 16 deletions(-)
---
diff --git a/pitivi/project.py b/pitivi/project.py
index e8840ff47..334addfac 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -77,8 +77,13 @@ for i in range(2, GLib.MAXINT):
 # Properties of encoders that should be ignored when saving/loading
 # a project.
 IGNORED_PROPS = ["name", "parent"]
+
+# Caps used as the default project settings.
 DEFAULT_VIDEO_SETTINGS = "video/x-raw,width=1920,height=1080,framerate=(GstFraction)30/1"
-DEFAULT_AUDIO_SETTINGS = "audio/x-raw,channels=2,rate=48000"
+DEFAULT_AUDIO_SETTINGS = "audio/x-raw,channels=2,rate=96000"
+
+# The minimum value for a decent audio rate.
+DECENT_AUDIORATE = 44100
 
 # Default values for the safe areas.
 DEFAULT_TITLE_AREA_VERTICAL = 0.8
@@ -710,7 +715,11 @@ class Project(Loggable, GES.Project):
             Gst.Caps("audio/x-vorbis"), None, Gst.Caps(asettings), 0)
         self.container_profile.add_profile(self.video_profile)
         self.container_profile.add_profile(self.audio_profile)
-        self.add_encoding_profile(self.container_profile)
+
+        # Add the container profile to the project so it is saved
+        # as part of the project.
+        res = self.add_encoding_profile(self.container_profile)
+        assert res
 
         self.muxer = Encoders().default_muxer
         self.vencoder = Encoders().default_video_encoder
@@ -988,6 +997,7 @@ class Project(Loggable, GES.Project):
         return True
 
     def _set_video_restriction(self, name, value):
+        """Updates the video profile and the corresponding project settings."""
         res = Project._set_restriction(self.video_profile, name, value)
         if res:
             self.emit("video-size-changed")
@@ -995,6 +1005,7 @@ class Project(Loggable, GES.Project):
         return res
 
     def _set_audio_restriction(self, name, value):
+        """Updates the audio profile and the corresponding project settings."""
         res = Project._set_restriction(self.audio_profile, name, value)
         if res:
             self._has_default_audio_settings = False
@@ -1800,10 +1811,15 @@ class Project(Loggable, GES.Project):
         return True
 
     def update_restriction_caps(self):
+        """Syncs the project settings from the render profile.
+
+        The project settings reside in the restriction caps of the audio and
+        video tracks of the timeline. They are updated to match the render
+        profile stored as the first (and only) encoding profile of the project.
+        """
+        videocaps = Gst.Caps.new_empty_simple("video/x-raw")
         # Get the height/width without rendering settings applied
         width, height = self.get_video_width_and_height()
-        videocaps = Gst.Caps.new_empty_simple("video/x-raw")
-
         videocaps.set_value("width", width)
         videocaps.set_value("height", height)
         videocaps.set_value("framerate", self.videorate)
@@ -2128,10 +2144,11 @@ class Project(Loggable, GES.Project):
         audio_streams = info.get_audio_streams()
         if audio_streams and self._has_default_audio_settings:
             audio = audio_streams[0]
-            self.audiochannels = audio.get_channels()
-            self.audiorate = audio.get_sample_rate()
-            self._has_default_audio_settings = False
-            emit = True
+            if audio.get_sample_rate() >= DECENT_AUDIORATE:
+                self.audiochannels = audio.get_channels()
+                self.audiorate = audio.get_sample_rate()
+                self._has_default_audio_settings = False
+                emit = True
         if emit:
             self.emit("settings-set-from-imported-asset", asset)
 
diff --git a/tests/test_project.py b/tests/test_project.py
index 7b021e7bf..087c292f2 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -533,19 +533,26 @@ class TestProjectSettings(common.TestCase):
 
     def test_audio(self):
         project = common.create_project()
-        project.audiochannels = 2
-        self.assertEqual(2, project.audiochannels)
+        self.assertEqual(project.audiochannels, 2)
+        self.assertEqual(project.audiorate, 96000)
+
+        project.audiochannels = 6
+        self.assertEqual(project.audiochannels, 6)
         project.audiorate = 44100
-        self.assertEqual(44100, project.audiorate)
+        self.assertEqual(project.audiorate, 44100)
 
     def test_video(self):
         project = common.create_project()
-        project.videowidth = 1920
-        self.assertEqual(1920, project.videowidth)
-        project.videoheight = 1080
-        self.assertEqual(1080, project.videoheight)
+        self.assertEqual(project.videowidth, 1920)
+        self.assertEqual(project.videoheight, 1080)
+        self.assertEqual(project.videorate, Gst.Fraction(30, 1))
+
+        project.videowidth = 3840
+        self.assertEqual(project.videowidth, 3840)
+        project.videoheight = 2160
+        self.assertEqual(project.videoheight, 2160)
         project.videorate = Gst.Fraction(50, 7)
-        self.assertEqual(Gst.Fraction(50, 7), project.videorate)
+        self.assertEqual(project.videorate, Gst.Fraction(50, 7))
 
     def test_set_audio_prop(self):
         timeline = common.create_timeline_container()
diff --git a/tests/test_render.py b/tests/test_render.py
index 6dd98425a..2c2d274ef 100644
--- a/tests/test_render.py
+++ b/tests/test_render.py
@@ -641,3 +641,15 @@ class TestRender(BaseTestMediaLibrary):
                                   vencoder="x264enc", vcodecsettings=None,
                                   preset="youtube",
                                   sensitive=True, value=Quality.MEDIUM)
+
+    def test_project_audiorate(self):
+        """Checks the project audiorate when opening the Render dialog."""
+        project = self.create_simple_project()
+        # This is the audiorate from tears_of_steel.webm.
+        self.assertEqual(project.audiorate, 44100)
+
+        unused_dialog = self.create_rendering_dialog(project)
+
+        # The audio rate is changed because the default render preset
+        # has an audio encoder which does not support 44100.
+        self.assertEqual(project.audiorate, 48000)


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