From c0056b6c3c91d7ea7099cbaac75248564d5f9131 Mon Sep 17 00:00:00 2001 From: Javanaut Date: Mon, 22 Jun 2026 13:58:55 +0200 Subject: [PATCH] Extending deinterlace subparams to hex range --- src/ffx/cli.py | 5 +++-- src/ffx/filter/deinterlace_filter.py | 9 +++++---- tests/unit/test_deinterlace_filter.py | 27 ++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/ffx/cli.py b/src/ffx/cli.py index da1aefb..5749ff1 100755 --- a/src/ffx/cli.py +++ b/src/ffx/cli.py @@ -1217,8 +1217,9 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor): show_default=True, callback=normalizeDeinterlaceOption, help=( - "Deinterlace with bwdif followed by ordered upN, downN, and tempNNNN " - "components, for example up2_temp3366_down2." + "Deinterlace with bwdif followed by ordered upN, downN, and tempHHHH " + "components. Scale factors N range from 2 to 8; H is hexadecimal. " + "For example: up2_temp3366_down2." ), ) diff --git a/src/ffx/filter/deinterlace_filter.py b/src/ffx/filter/deinterlace_filter.py index 1552d77..b38a56c 100644 --- a/src/ffx/filter/deinterlace_filter.py +++ b/src/ffx/filter/deinterlace_filter.py @@ -12,7 +12,7 @@ class DeinterlaceFilter(Filter): DEFAULT_SCALE_FACTOR = 2 MIN_SCALE_FACTOR = 2 - MAX_SCALE_FACTOR = 4 + MAX_SCALE_FACTOR = 8 DEFAULT_TEMP_PARAMETERS = '3366' # DEFAULT_STRENGTH: float = 2.8 @@ -156,7 +156,7 @@ class DeinterlaceFilter(Filter): ) continue - tempMatch = re.fullmatch(r'temp(\d*)', component) + tempMatch = re.fullmatch(r'temp([0-9a-fA-F]*)', component) if tempMatch: parameters = ( tempMatch.group(1) @@ -164,9 +164,10 @@ class DeinterlaceFilter(Filter): ) if len(parameters) != 4: raise ValueError( - f"Temporal parameters in '{component}' must contain four digits" + f"Temporal parameters in '{component}' must contain " + + "four hexadecimal digits" ) - strengths = [f"{int(digit) / 2:g}" for digit in parameters] + strengths = [f"{int(digit, 16) / 2:g}" for digit in parameters] tokens.append(f"hqdn3d={':'.join(strengths)}") continue diff --git a/tests/unit/test_deinterlace_filter.py b/tests/unit/test_deinterlace_filter.py index d1b0c58..28486a9 100644 --- a/tests/unit/test_deinterlace_filter.py +++ b/tests/unit/test_deinterlace_filter.py @@ -84,6 +84,31 @@ class DeinterlaceFilterTest(unittest.TestCase): payload['tokens'], ) + def test_temporal_parameters_accept_hexadecimal_digits(self): + lowerPayload = self.getPayload('temp00ff') + mixedPayload = self.getPayload('tempFf33') + + self.assertEqual( + ['bwdif=mode=1', 'hqdn3d=0:0:7.5:7.5'], + lowerPayload['tokens'], + ) + self.assertEqual( + ['bwdif=mode=1', 'hqdn3d=7.5:7.5:1.5:1.5'], + mixedPayload['tokens'], + ) + + def test_scale_factors_accept_boundaries_from_two_to_eight(self): + payload = self.getPayload('up8_down2') + + self.assertEqual( + [ + 'bwdif=mode=1', + 'scale=iw*8:ih*8:flags=lanczos', + 'scale=iw/2:ih/2:flags=lanczos', + ], + payload['tokens'], + ) + def test_each_component_uses_its_default_when_parameters_are_omitted(self): payload = self.getPayload('up_temp_down') @@ -105,7 +130,7 @@ class DeinterlaceFilterTest(unittest.TestCase): DeinterlaceFilter(mode='other') def test_invalid_parameters_are_rejected(self): - invalidModes = ('up0', 'down5', 'temp123', 'up__down') + invalidModes = ('up1', 'down9', 'temp123', 'temp00gg', 'up__down') for mode in invalidModes: with self.subTest(mode=mode), self.assertRaises(ValueError):