You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.2 KiB
74 lines
2.2 KiB
from decimal import Decimal
|
|
|
|
from knowit.core import Rule
|
|
|
|
|
|
class ResolutionRule(Rule):
|
|
"""Resolution rule."""
|
|
|
|
standard_resolutions = (
|
|
480,
|
|
720,
|
|
1080,
|
|
2160,
|
|
4320,
|
|
)
|
|
uncommon_resolutions = (
|
|
240,
|
|
288,
|
|
360,
|
|
576,
|
|
)
|
|
resolutions = list(sorted(standard_resolutions + uncommon_resolutions))
|
|
square = 4. / 3
|
|
wide = 16. / 9
|
|
|
|
def execute(self, props, pv_props, context):
|
|
"""Return the resolution for the video.
|
|
|
|
The resolution is based on a widescreen TV (16:9)
|
|
1920x800 will be considered 1080p since the TV will use 1920x1080 with vertical black bars
|
|
1426x1080 is considered 1080p since the TV will use 1920x1080 with horizontal black bars
|
|
|
|
The calculation considers the display aspect ratio and the pixel aspect ratio (not only width and height).
|
|
The upper resolution is selected if there's no perfect match with the following list of resolutions:
|
|
240, 288, 360, 480, 576, 720, 1080, 2160, 4320
|
|
If no interlaced information is available, resolution will be considered Progressive.
|
|
"""
|
|
width = props.get('width')
|
|
height = props.get('height')
|
|
if not width or not height:
|
|
return
|
|
|
|
try:
|
|
width = width.magnitude
|
|
height = height.magnitude
|
|
except AttributeError:
|
|
pass
|
|
|
|
dar = props.get('aspect_ratio', Decimal(width) / height)
|
|
par = props.get('pixel_aspect_ratio', 1)
|
|
scan_type = props.get('scan_type', 'p')[0].lower()
|
|
|
|
# selected DAR must be between 4:3 and 16:9
|
|
selected_dar = max(min(dar, self.wide), self.square)
|
|
|
|
# mod-16
|
|
stretched_width = int(round(width * par / 16)) * 16
|
|
|
|
# mod-8
|
|
calculated_height = int(round(stretched_width / selected_dar / 8)) * 8
|
|
|
|
selected_resolution = None
|
|
for r in reversed(self.resolutions):
|
|
if r < calculated_height:
|
|
break
|
|
|
|
selected_resolution = r
|
|
|
|
if selected_resolution:
|
|
return f'{selected_resolution}{scan_type}'
|
|
|
|
msg = f'{width}x{height} - scan_type: {scan_type}, aspect_ratio: {dar}, pixel_aspect_ratio: {par}'
|
|
self.report(msg, context)
|