Build/Detect: Clarify constants organization

This commit is contained in:
Ross Patterson 2019-08-12 13:50:11 -07:00
parent aba5a5781c
commit 94b8333ddd
2 changed files with 77 additions and 68 deletions

View File

@ -17,45 +17,51 @@ parser.add_argument(
help='The path to the ffmpeg execuatble') help='The path to the ffmpeg execuatble')
VERSION_RE = re.compile(r' version (?P<version>[^ ]+) ') VERSION = dict(
RE=re.compile(r' version (?P<version>[^ ]+) '))
MUXER_RE = re.compile( MUXER = dict(
r'^ (?P<demuxing>[D ])(?P<muxing>[E ]) ' RE=re.compile(
r'(?P<name>[^ ]+) +(?P<description>.+)$', r'^ (?P<demuxing>[D ])(?P<muxing>[E ]) '
re.M) r'(?P<name>[^ ]+) +(?P<description>.+)$',
MUXER_FLAGS = dict(demuxing='D', muxing='E') re.M),
FLAGS=dict(demuxing='D', muxing='E'))
CODEC_RE = re.compile( CODEC = dict(
r'^ (?P<decoding>[D.])(?P<encoding>[E.])' RE=re.compile(
r'(?P<stream>[VAS.])(?P<intra_frame>[I.])' r'^ (?P<decoding>[D.])(?P<encoding>[E.])'
r'(?P<lossy>[L.])(?P<lossless>[S.]) ' r'(?P<stream>[VAS.])(?P<intra_frame>[I.])'
r'(?P<name>[^ ]+) +(?P<description>.+)$', r'(?P<lossy>[L.])(?P<lossless>[S.]) '
re.M) r'(?P<name>[^ ]+) +(?P<description>.+)$',
CODEC_FLAGS = dict( re.M),
decoding='D', encoding='E', FLAGS=dict(
stream=dict(video='V', audio='A', subtitle='S'), decoding='D', encoding='E',
intra_frame='I', lossy='L', lossless='S') stream=dict(video='V', audio='A', subtitle='S'),
CODEC_DESCRIPTION_RE = re.compile( intra_frame='I', lossy='L', lossless='S'),
r'^(?P<description>.+?) \((de|en)coders: [^)]+ \)') DESCRIPTION_RE=re.compile(
CODEC_CODERS_RE = re.compile( r'^(?P<description>.+?) \((de|en)coders: [^)]+ \)'),
r' \((?P<type>(de|en)coders): (?P<coders>[^)]+) \)') CODERS_RE=re.compile(
r' \((?P<type>(de|en)coders): (?P<coders>[^)]+) \)'))
HWACCEL_SYNONYMS = dict(cuvid=['nvenc', 'nvdec', 'cuda']) HWACCEL = dict(
SYNONYMS=dict(cuvid=['nvenc', 'nvdec', 'cuda']))
FILTER_RE = re.compile( FILTER = dict(
r'^ (?P<timeline>[T.])(?P<slice>[S.])(?P<command>[C.]) ' RE=re.compile(
r'(?P<name>[^ ]+) +(?P<io>[^ ]+) +(?P<description>.+)$', r'^ (?P<timeline>[T.])(?P<slice>[S.])(?P<command>[C.]) '
re.M) r'(?P<name>[^ ]+) +(?P<io>[^ ]+) +(?P<description>.+)$',
FILTER_FLAGS = dict(timeline='T', slice='S', command='C') re.M),
FLAGS=dict(timeline='T', slice='S', command='C'))
PIX_FMT_RE = re.compile( PIX_FMT = dict(
r'^(?P<input>[I.])(?P<output>[O.])(?P<accelerated>[H.])' RE=re.compile(
r'(?P<palleted>[P.])(?P<bitstream>[B.]) ' r'^(?P<input>[I.])(?P<output>[O.])(?P<accelerated>[H.])'
r'(?P<name>[^ ]+) +(?P<components>[0-9]+) +(?P<bits>[0-9]+)$', r'(?P<palleted>[P.])(?P<bitstream>[B.]) '
re.M) r'(?P<name>[^ ]+) +(?P<components>[0-9]+) +(?P<bits>[0-9]+)$',
PIX_FMT_FLAGS = dict( re.M),
input='I', output='O', accelerated='H', palleted='P', bitstream='B') FLAGS=dict(
PIX_FMT_INT_FIELDS = {'components', 'bits'} input='I', output='O', accelerated='H', palleted='P', bitstream='B'),
INT_FIELDS={'components', 'bits'})
def _run(args): def _run(args):
@ -107,7 +113,7 @@ def get_version(cmd='ffmpeg'):
Extract the version of the ffmpeg build. Extract the version of the ffmpeg build.
""" """
stdout = _run([cmd, '-version']) stdout = _run([cmd, '-version'])
match = VERSION_RE.search(stdout.split('\n')[0]) match = VERSION['RE'].search(stdout.split('\n')[0])
return match.group('version') return match.group('version')
@ -116,7 +122,7 @@ def get_formats(cmd='ffmpeg'):
Extract the formats of the ffmpeg build. Extract the formats of the ffmpeg build.
""" """
stdout = _run([cmd, '-formats']) stdout = _run([cmd, '-formats'])
return _get_line_fields(stdout, 4, MUXER_RE, MUXER_FLAGS) return _get_line_fields(stdout, 4, MUXER['RE'], MUXER['FLAGS'])
def get_demuxers(cmd='ffmpeg'): def get_demuxers(cmd='ffmpeg'):
@ -124,7 +130,7 @@ def get_demuxers(cmd='ffmpeg'):
Extract the demuxers of the ffmpeg build. Extract the demuxers of the ffmpeg build.
""" """
stdout = _run([cmd, '-demuxers']) stdout = _run([cmd, '-demuxers'])
return _get_line_fields(stdout, 4, MUXER_RE, MUXER_FLAGS) return _get_line_fields(stdout, 4, MUXER['RE'], MUXER['FLAGS'])
def get_muxers(cmd='ffmpeg'): def get_muxers(cmd='ffmpeg'):
@ -132,7 +138,7 @@ def get_muxers(cmd='ffmpeg'):
Extract the muxers of the ffmpeg build. Extract the muxers of the ffmpeg build.
""" """
stdout = _run([cmd, '-muxers']) stdout = _run([cmd, '-muxers'])
return _get_line_fields(stdout, 4, MUXER_RE, MUXER_FLAGS) return _get_line_fields(stdout, 4, MUXER['RE'], MUXER['FLAGS'])
def get_codecs(cmd='ffmpeg'): def get_codecs(cmd='ffmpeg'):
@ -140,13 +146,14 @@ def get_codecs(cmd='ffmpeg'):
Extract the codecs of the ffmpeg build. Extract the codecs of the ffmpeg build.
""" """
stdout = _run([cmd, '-codecs']) stdout = _run([cmd, '-codecs'])
codecs = _get_line_fields(stdout, 10, CODEC_RE, CODEC_FLAGS) codecs = _get_line_fields(stdout, 10, CODEC['RE'], CODEC['FLAGS'])
for codec in codecs.values(): for codec in codecs.values():
for coders_match in CODEC_CODERS_RE.finditer(codec['description']): for coders_match in CODEC['CODERS_RE'].finditer(codec['description']):
coders = coders_match.group(3).split() coders = coders_match.group(3).split()
if coders: if coders:
codec[coders_match.group(1)] = coders codec[coders_match.group(1)] = coders
description_match = CODEC_DESCRIPTION_RE.search(codec['description']) description_match = CODEC['DESCRIPTION_RE'].search(
codec['description'])
if description_match is not None: if description_match is not None:
codec['description'] = description_match.group('description') codec['description'] = description_match.group('description')
return codecs return codecs
@ -179,7 +186,7 @@ def get_filters(cmd='ffmpeg'):
Extract the filters of the ffmpeg build. Extract the filters of the ffmpeg build.
""" """
stdout = _run([cmd, '-filters']) stdout = _run([cmd, '-filters'])
return _get_line_fields(stdout, 8, FILTER_RE, FILTER_FLAGS) return _get_line_fields(stdout, 8, FILTER['RE'], FILTER['FLAGS'])
def get_pix_fmts(cmd='ffmpeg'): def get_pix_fmts(cmd='ffmpeg'):
@ -188,7 +195,7 @@ def get_pix_fmts(cmd='ffmpeg'):
""" """
stdout = _run([cmd, '-pix_fmts']) stdout = _run([cmd, '-pix_fmts'])
return _get_line_fields( return _get_line_fields(
stdout, 8, PIX_FMT_RE, PIX_FMT_FLAGS, PIX_FMT_INT_FIELDS) stdout, 8, PIX_FMT['RE'], PIX_FMT['FLAGS'], PIX_FMT['INT_FIELDS'])
def get_sample_fmts(cmd='ffmpeg'): def get_sample_fmts(cmd='ffmpeg'):
@ -238,7 +245,7 @@ def get_devices(cmd='ffmpeg'):
Extract the devices of the ffmpeg build. Extract the devices of the ffmpeg build.
""" """
stdout = _run([cmd, '-devices']) stdout = _run([cmd, '-devices'])
return _get_line_fields(stdout, 4, MUXER_RE, MUXER_FLAGS) return _get_line_fields(stdout, 4, MUXER['RE'], MUXER['FLAGS'])
def get_hw_devices(cmd='ffmpeg'): def get_hw_devices(cmd='ffmpeg'):
@ -272,7 +279,7 @@ def get_hwaccels(cmd='ffmpeg'):
for coder in codec.get(coders_key, []): for coder in codec.get(coders_key, []):
for synonym in ( for synonym in (
[hwaccel_name] + [hwaccel_name] +
HWACCEL_SYNONYMS.get(hwaccel_name, [])): HWACCEL['SYNONYMS'].get(hwaccel_name, [])):
if ( if (
coder == synonym or coder == synonym or
'_' + synonym in coder or '_' + synonym in coder or

View File

@ -43,23 +43,25 @@ parser.add_argument(
# Separators to divide a range of models within a line # Separators to divide a range of models within a line
MODEL_RANGE_SEPARATORS = ['-', '>'] MODEL_RANGE_SEPARATORS = ['-', '>']
# List `hwaccel` options by order of expected performance when available. HWACCEL = dict(
HWACCELS_BY_PERFORMANCE = [ # List `hwaccel` options by order of expected performance when available.
# NVidia BY_PERFORMANCE=[
'nvdec', 'cuvid', 'cuda', # NVidia
# AMD 'nvdec', 'cuvid', 'cuda',
'amf', # AMD
# Windows 'amf',
'qsv', 'd3d11va', 'dxva2', # Windows
# Linux 'qsv', 'd3d11va', 'dxva2',
'vaapi', 'vdpau', 'drm'] # Linux
HWACCEL_OUTPUT_FORMATS = { 'vaapi', 'vdpau', 'drm'],
'nvdec': 'cuda', OUTPUT_FORMATS={
'vaapi': 'vaapi'} 'nvdec': 'cuda',
'vaapi': 'vaapi'})
GPU_PRODUCT_RE = re.compile(r'(?P<chip>[^[]+)(\[(?P<board>[^]]+)\]|)') GPU = dict(
GPU_WMI_PROPERTIES = collections.OrderedDict( PRODUCT_RE=re.compile(r'(?P<chip>[^[]+)(\[(?P<board>[^]]+)\]|)'),
vendor='AdapterCompatibility', board='VideoProcessor') WMI_PROPERTIES=collections.OrderedDict(
vendor='AdapterCompatibility', board='VideoProcessor'))
# Loaded from JSON # Loaded from JSON
DATA = None DATA = None
@ -88,7 +90,7 @@ def detect_gpus():
# TODO get multiple GPUs from lshw # TODO get multiple GPUs from lshw
gpus.append(gpu) gpus.append(gpu)
product_match = GPU_PRODUCT_RE.search(display_data['product']) product_match = GPU['PRODUCT_RE'].search(display_data['product'])
if product_match: if product_match:
gpu.update(**product_match.groupdict()) gpu.update(**product_match.groupdict())
if not gpu['board']: if not gpu['board']:
@ -98,7 +100,7 @@ def detect_gpus():
import wmi import wmi
for controller in wmi.WMI().Win32_VideoController(): for controller in wmi.WMI().Win32_VideoController():
gpu = collections.OrderedDict() gpu = collections.OrderedDict()
for key, wmi_prop in GPU_WMI_PROPERTIES.items(): for key, wmi_prop in GPU['WMI_PROPERTIES'].items():
value = controller.wmi_property(wmi_prop).value value = controller.wmi_property(wmi_prop).value
if value: if value:
gpu[key] = value gpu[key] = value
@ -192,11 +194,11 @@ def detect_hwaccels(hwaccels=None, cmd='ffmpeg'):
hwaccels.sort(key=lambda hwaccel: ( hwaccels.sort(key=lambda hwaccel: (
# Sort unranked hwaccels last, but in the order given by ffmpeg # Sort unranked hwaccels last, but in the order given by ffmpeg
hwaccel['name'] in HWACCELS_BY_PERFORMANCE and 1 or 0, hwaccel['name'] in HWACCEL['BY_PERFORMANCE'] and 1 or 0,
( (
# Sort ranked hwaccels per the constant # Sort ranked hwaccels per the constant
hwaccel['name'] in HWACCELS_BY_PERFORMANCE and hwaccel['name'] in HWACCEL['BY_PERFORMANCE'] and
HWACCELS_BY_PERFORMANCE.index(hwaccel['name'])))) HWACCEL['BY_PERFORMANCE'].index(hwaccel['name']))))
hwaccels_data['hwaccels'] = hwaccels hwaccels_data['hwaccels'] = hwaccels
return hwaccels_data return hwaccels_data
@ -230,9 +232,9 @@ def detect_codecs(decoder, encoder, hwaccels=None, cmd='ffmpeg'):
hwaccel_kwargs = collections.OrderedDict( hwaccel_kwargs = collections.OrderedDict(
input=collections.OrderedDict(hwaccel=hwaccel['name']), input=collections.OrderedDict(hwaccel=hwaccel['name']),
output=collections.OrderedDict(codec=hwaccel_encoder)) output=collections.OrderedDict(codec=hwaccel_encoder))
if hwaccel['name'] in HWACCEL_OUTPUT_FORMATS: if hwaccel['name'] in HWACCEL['OUTPUT_FORMATS']:
hwaccel_kwargs['input']['hwaccel_output_format'] = ( hwaccel_kwargs['input']['hwaccel_output_format'] = (
HWACCEL_OUTPUT_FORMATS[hwaccel['name']]) HWACCEL['OUTPUT_FORMATS'][hwaccel['name']])
codecs_kwargs.append(hwaccel_kwargs) codecs_kwargs.append(hwaccel_kwargs)
for hwaccel_decoder in hwaccel['codecs'].get( for hwaccel_decoder in hwaccel['codecs'].get(
decoder, {}).get('decoders', []): decoder, {}).get('decoders', []):