Detect: Add NVidia decoders data

This commit is contained in:
Ross Patterson 2019-08-10 17:24:15 -07:00
parent 8982e9fff2
commit 9f00ffd995
2 changed files with 5285 additions and 2191 deletions

View File

@ -38,7 +38,11 @@ API_TO_HWACCEL = {
NVIDIA_GPU_MATRIX_URL = ( NVIDIA_GPU_MATRIX_URL = (
'https://developer.nvidia.com/video-encode-decode-gpu-support-matrix') 'https://developer.nvidia.com/video-encode-decode-gpu-support-matrix')
NVIDIA_LINE_SUFFIXES = {'geforce': ['gtx titan', 'gtx', 'gt', 'rtx']} NVIDIA_LINE_SUFFIXES = {'geforce': ['gtx titan', 'gtx', 'gt', 'rtx']}
NVIDIA_CODEC_COLUMN_PREFIXES = {'h.264': 'h264', 'h.265': 'hevc'} NVIDIA_CODEC_COLUMN_PREFIXES = {
'mpeg-1': 'mpeg1video', 'mpeg-2': 'mpeg2video',
'vc-1': 'vc1',
'vp8': 'vp8', 'vp9': 'vp9',
'h.264': 'h264', 'h.265': 'hevc'}
def get_hwaccel_data(): def get_hwaccel_data():
@ -75,14 +79,18 @@ def get_nvidia_data():
( (
nvenc_recent, nvenc_consumer, nvenc_workstation, nvenc_virt, nvenc_recent, nvenc_consumer, nvenc_workstation, nvenc_virt,
nvdec_recent, nvdec_consumer, nvdec_workstation, nvdec_virt) = tables nvdec_recent, nvdec_consumer, nvdec_workstation, nvdec_virt) = tables
nvidia = collections.OrderedDict( nv_coders = dict(
lines=[], model_lines=collections.OrderedDict(), encoders=(
boards=collections.OrderedDict()) nvenc_recent, nvenc_consumer, nvenc_workstation, nvenc_virt),
decoders=(
nvdec_recent, nvdec_consumer, nvdec_workstation, nvdec_virt))
nvidia = collections.OrderedDict(lines=[])
# Compile aggregate data needed to parse individual rows # Compile aggregate data needed to parse individual rows
for nvenc_table in ( for nv_coder_table in tables:
nvenc_recent, nvenc_consumer, nvenc_workstation, nvenc_virt): for board in nv_coder_table['BOARD']:
for board in nvenc_table['BOARD']: if board == 'BOARD':
continue
line = board.replace('\xa0', ' ').split(None, 1)[0].lower() line = board.replace('\xa0', ' ').split(None, 1)[0].lower()
if line not in nvidia['lines']: if line not in nvidia['lines']:
nvidia['lines'].append(line) nvidia['lines'].append(line)
@ -90,62 +98,79 @@ def get_nvidia_data():
for line_suffix in reversed(line_suffixes): for line_suffix in reversed(line_suffixes):
nvidia['lines'].insert(0, ' '.join((line, line_suffix))) nvidia['lines'].insert(0, ' '.join((line, line_suffix)))
for nvenc_table in ( for coder_type, nv_coder_tables in nv_coders.items():
nvenc_recent, nvenc_consumer, nvenc_workstation, nvenc_virt): coder_data = nvidia[coder_type] = collections.OrderedDict(
for nvenc_row_idx, nvenc_row in nvenc_table.iterrows(): model_lines=collections.OrderedDict(),
nvenc_row_values = { boards=collections.OrderedDict())
idx: cell for idx, cell in enumerate(nvenc_row[1:]) if ( for nv_coder_table in nv_coder_tables:
cell and for nv_coder_row_idx, nv_coder_row in nv_coder_table.iterrows():
not (isinstance(cell, float) and math.isnan(cell)))} nv_coder_row_values = {
if not nvenc_row_values: idx: cell for idx, cell in enumerate(nv_coder_row[1:]) if (
# Divider row cell and
continue not (isinstance(cell, float) and math.isnan(cell)))}
if not nv_coder_row_values:
# Divider row
continue
# Assemble the data for this row to use for each model or range # Assemble the data for this row to use for each model or range
model_data = collections.OrderedDict() model_data = collections.OrderedDict()
for key, value in nvenc_row.items(): for key, value in nv_coder_row.items():
if value in {'YES', 'NO'}: if isinstance(key, tuple):
model_data[key] = value == 'YES' if key[0] == key[1]:
else: key = key[0]
model_data[key] = value else:
model_data['BOARD'] = model_data['BOARD'].replace('\xa0', ' ') key = ' '.join(key)
# Add keys for the data for the ffmpeg codec names for fast lookup if value in {'YES', 'NO'}:
for codec_prefix, codec in NVIDIA_CODEC_COLUMN_PREFIXES.items(): model_data[key] = value == 'YES'
for column_idx, column in enumerate(nvenc_row.keys()): else:
if column.lower().startswith(codec_prefix): model_data[key] = value
model_data[codec] = nvenc_row[column_idx] == 'YES' model_data['BOARD'] = model_data['BOARD'].replace('\xa0', ' ')
break # Add keys for the ffmpeg codec names for fast lookup
nvidia['boards'][model_data['BOARD']] = model_data for codec_prefix, codec in (
NVIDIA_CODEC_COLUMN_PREFIXES.items()):
for column_idx, column in enumerate(nv_coder_row.keys()):
if isinstance(column, tuple):
if column[0] == column[1]:
column = column[0]
else:
column = ' '.join(column)
if column.lower().startswith(codec_prefix):
model_data[codec] = nv_coder_row[
column_idx] == 'YES'
break
coder_data['boards'][model_data['BOARD']] = model_data
_detect._parse_models( _detect._parse_models(
model_lines=nvidia['lines'], model_lines=nvidia['lines'],
boards=model_data['BOARD'].lower(), boards=model_data['BOARD'].lower(),
model_data=model_data['BOARD'], model_data=model_data['BOARD'],
model_lines_data=nvidia['model_lines']) model_lines_data=coder_data['model_lines'])
# Clean up some annoying clashes between the titan model line and GeForce # Cleanup any deviations from the convention where models from
# GTX model numbers # multiple lines are in the same BOARD cell
for model_line, model_line_suffixes in NVIDIA_LINE_SUFFIXES.items(): for model_line, model_line_data in coder_data['model_lines'].items():
models_data = nvidia['model_lines'][model_line]['models'] for line, line_suffixes in NVIDIA_LINE_SUFFIXES.items():
for model_num in list(models_data): if not model_line.startswith(line):
for model_line_suffix in model_line_suffixes: continue
if model_num.startswith(model_line_suffix + ' '): for model_num, boards in list(
models_data[model_num[ model_line_data['models'].items()):
len(model_line_suffix + ' '):]] = models_data.pop( for line_suffix in line_suffixes:
model_num) if not model_num.startswith(line_suffix + ' '):
for titan_model_num in {'black', 'xp'}: continue
nvidia['model_lines']['geforce gtx']['models'][ coder_data['model_lines'][
'titan ' + titan_model_num] = nvidia['model_lines'][ ' '.join((line, line_suffix))]['models'][
'titan']['models'].pop(titan_model_num) model_num[len(line_suffix + ' '):]
for titan_model_num in list(nvidia['model_lines'][ ] = model_line_data['models'].pop(model_num)
'geforce gtx titan']['models'].keys()): # Clean up some annoying clashes between the titan model line and
nvidia['model_lines']['geforce gtx']['models'][ # GeForce GTX model numbers
'titan ' + titan_model_num] = nvidia['model_lines'][ del coder_data['model_lines']['geforce gtx titan']['models']['']
'geforce gtx titan']['models'].pop(titan_model_num) coder_data['model_lines']['geforce gtx titan']['models'][
nvidia['model_lines']['geforce gtx']['models']['titan'] = nvidia[ 'xp'] = coder_data['model_lines']['titan']['models'].pop('xp')
'model_lines']['geforce gtx']['models']['titan black'] coder_data['model_lines']['geforce gtx titan']['models'][
del nvidia['model_lines']['geforce gtx']['models']['titan '] 'black'] = titan_black = coder_data['model_lines'][
del nvidia['model_lines']['geforce gtx titan'] 'titan']['models'].pop('black')
coder_data['model_lines']['geforce gtx']['models'][
'titan'] = titan_black
return nvidia return nvidia

File diff suppressed because it is too large Load Diff