mirror of
https://github.com/kkroening/ffmpeg-python.git
synced 2025-08-10 13:10:03 +08:00
Build: Include coders specific to hwaccell APIs
This commit is contained in:
parent
ca427cb904
commit
130457ffe1
@ -40,6 +40,8 @@ CODEC_DESCRIPTION_RE = re.compile(
|
|||||||
CODEC_CODERS_RE = re.compile(
|
CODEC_CODERS_RE = re.compile(
|
||||||
r' \((?P<type>(de|en)coders): (?P<coders>[^)]+) \)')
|
r' \((?P<type>(de|en)coders): (?P<coders>[^)]+) \)')
|
||||||
|
|
||||||
|
HWACCEL_SYNONYMS = dict(cuvid=['nvenc', 'nvdec', 'cuda'])
|
||||||
|
|
||||||
FILTER_RE = re.compile(
|
FILTER_RE = re.compile(
|
||||||
r'^ (?P<timeline>[T.])(?P<slice>[S.])(?P<command>[C.]) '
|
r'^ (?P<timeline>[T.])(?P<slice>[S.])(?P<command>[C.]) '
|
||||||
r'(?P<name>[^ ]+) +(?P<io>[^ ]+) +(?P<description>.+)$',
|
r'(?P<name>[^ ]+) +(?P<io>[^ ]+) +(?P<description>.+)$',
|
||||||
@ -248,22 +250,53 @@ def get_hw_devices(cmd='ffmpeg'):
|
|||||||
|
|
||||||
def get_hwaccels(cmd='ffmpeg'):
|
def get_hwaccels(cmd='ffmpeg'):
|
||||||
"""
|
"""
|
||||||
Extract the hwaccels of the ffmpeg build.
|
Extract the hwaccels of the ffmpeg build, including specific codecs.
|
||||||
|
|
||||||
|
Return all the hardware acceleration APIs supported by this build
|
||||||
|
including all the codecs that are specific to the API.
|
||||||
"""
|
"""
|
||||||
|
data = dict(codecs=get_codecs(cmd=cmd), hwaccels=[])
|
||||||
|
|
||||||
stdout = _run([cmd, '-hwaccels'])
|
stdout = _run([cmd, '-hwaccels'])
|
||||||
return stdout.split('\n')[1:-2]
|
hwaccel_names = stdout.split('\n')[1:-2]
|
||||||
|
|
||||||
|
for hwaccel_name in hwaccel_names:
|
||||||
|
hwaccel = dict(name=hwaccel_name)
|
||||||
|
data['hwaccels'].append(hwaccel)
|
||||||
|
hwaccel['codecs'] = hwaccel_codecs = {}
|
||||||
|
for codec_name, codec in data['codecs'].items():
|
||||||
|
hwaccel_codec = {}
|
||||||
|
for coders_key in ('decoders', 'encoders'):
|
||||||
|
matching_coders = []
|
||||||
|
for coder in codec.get(coders_key, []):
|
||||||
|
for synonym in (
|
||||||
|
[hwaccel_name] +
|
||||||
|
HWACCEL_SYNONYMS.get(hwaccel_name, [])):
|
||||||
|
if (
|
||||||
|
coder == synonym or
|
||||||
|
'_' + synonym in coder or
|
||||||
|
synonym + '_' in coder):
|
||||||
|
matching_coders.append(coder)
|
||||||
|
break
|
||||||
|
if matching_coders:
|
||||||
|
hwaccel_codec[coders_key] = matching_coders
|
||||||
|
if hwaccel_codec:
|
||||||
|
hwaccel_codecs[codec_name] = hwaccel_codec
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_build_data(cmd='ffmpeg'):
|
def get_build_data(cmd='ffmpeg'):
|
||||||
"""
|
"""
|
||||||
Extract details about the ffmpeg build.
|
Extract details about the ffmpeg build.
|
||||||
"""
|
"""
|
||||||
|
hwaccels_data = get_hwaccels(cmd=cmd)
|
||||||
return dict(
|
return dict(
|
||||||
version=get_version(cmd=cmd),
|
version=get_version(cmd=cmd),
|
||||||
formats=get_formats(cmd=cmd),
|
formats=get_formats(cmd=cmd),
|
||||||
demuxers=get_demuxers(cmd=cmd),
|
demuxers=get_demuxers(cmd=cmd),
|
||||||
muxers=get_muxers(cmd=cmd),
|
muxers=get_muxers(cmd=cmd),
|
||||||
codecs=get_codecs(cmd=cmd),
|
codecs=hwaccels_data['codecs'],
|
||||||
bsfs=get_bsfs(cmd=cmd),
|
bsfs=get_bsfs(cmd=cmd),
|
||||||
protocols=get_protocols(cmd=cmd),
|
protocols=get_protocols(cmd=cmd),
|
||||||
filters=get_filters(cmd=cmd),
|
filters=get_filters(cmd=cmd),
|
||||||
@ -273,7 +306,7 @@ def get_build_data(cmd='ffmpeg'):
|
|||||||
colors=get_colors(cmd=cmd),
|
colors=get_colors(cmd=cmd),
|
||||||
devices=get_devices(cmd=cmd),
|
devices=get_devices(cmd=cmd),
|
||||||
hw_devices=get_hw_devices(cmd=cmd),
|
hw_devices=get_hw_devices(cmd=cmd),
|
||||||
hwaccels=get_hwaccels(cmd=cmd))
|
hwaccels=hwaccels_data['hwaccels'])
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'get_build_data',
|
'get_build_data',
|
||||||
|
@ -43,10 +43,6 @@ HWACCELS_BY_PERFORMANCE = [
|
|||||||
'qsv', 'd3d11va', 'dxva2', 'vaapi', 'drm']
|
'qsv', 'd3d11va', 'dxva2', 'vaapi', 'drm']
|
||||||
# Loaded from JSON
|
# Loaded from JSON
|
||||||
DATA = None
|
DATA = None
|
||||||
# Some accelerated codecs use a different prefix than the base codec
|
|
||||||
CODEC_SYNONYMS = {
|
|
||||||
'mpeg1video': 'mpeg1',
|
|
||||||
'mpeg2video': 'mpeg2'}
|
|
||||||
|
|
||||||
|
|
||||||
def detect_gpu():
|
def detect_gpu():
|
||||||
@ -67,14 +63,15 @@ def detect_hwaccels(hwaccels=None, cmd='ffmpeg'):
|
|||||||
Extract details about the ffmpeg build.
|
Extract details about the ffmpeg build.
|
||||||
"""
|
"""
|
||||||
# Filter against what's available in the ffmpeg build
|
# Filter against what's available in the ffmpeg build
|
||||||
build_hwaccels = ffmpeg.get_hwaccels(cmd=cmd)
|
hwaccels_data = ffmpeg.get_hwaccels(cmd=cmd)
|
||||||
if hwaccels is None:
|
if hwaccels is None:
|
||||||
# Consider all the available hwaccels
|
# Consider all the available hwaccels
|
||||||
hwaccels = build_hwaccels
|
hwaccels = hwaccels_data['hwaccels']
|
||||||
else:
|
else:
|
||||||
# Support passing in a restricted set of hwaccels
|
# Support passing in a restricted set of hwaccels
|
||||||
hwaccels = [
|
hwaccels = [
|
||||||
hwaccel for hwaccel in hwaccels if hwaccel in build_hwaccels]
|
hwaccel for hwaccel in hwaccels_data['hwaccels']
|
||||||
|
if hwaccel['name'] in hwaccels]
|
||||||
|
|
||||||
# Filter against which APIs are available on this OS+GPU
|
# Filter against which APIs are available on this OS+GPU
|
||||||
data = _get_data()
|
data = _get_data()
|
||||||
@ -82,16 +79,18 @@ def detect_hwaccels(hwaccels=None, cmd='ffmpeg'):
|
|||||||
gpu = detect_gpu()
|
gpu = detect_gpu()
|
||||||
api_avail = data['hwaccels']['api_avail'][plat_sys][
|
api_avail = data['hwaccels']['api_avail'][plat_sys][
|
||||||
gpu['vendor'].replace(' Corporation', '')]
|
gpu['vendor'].replace(' Corporation', '')]
|
||||||
hwaccels = [hwaccel for hwaccel in hwaccels if hwaccel in api_avail]
|
hwaccels = [
|
||||||
|
hwaccel for hwaccel in hwaccels if hwaccel['name'] in api_avail]
|
||||||
|
|
||||||
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 not in HWACCELS_BY_PERFORMANCE,
|
hwaccel['name'] in HWACCELS_BY_PERFORMANCE and 1 or 0,
|
||||||
(
|
(
|
||||||
# Sort ranked hwaccels per the constant
|
# Sort ranked hwaccels per the constant
|
||||||
hwaccel in HWACCELS_BY_PERFORMANCE and
|
hwaccel['name'] in HWACCELS_BY_PERFORMANCE and
|
||||||
HWACCELS_BY_PERFORMANCE.index(hwaccel))))
|
HWACCELS_BY_PERFORMANCE.index(hwaccel['name']))))
|
||||||
return hwaccels
|
hwaccels_data['hwaccels'] = hwaccels
|
||||||
|
return hwaccels_data
|
||||||
|
|
||||||
|
|
||||||
def detect_coder(
|
def detect_coder(
|
||||||
|
@ -727,7 +727,16 @@ def test__build_data():
|
|||||||
|
|
||||||
assert isinstance(data['version'], str)
|
assert isinstance(data['version'], str)
|
||||||
|
|
||||||
for fields_key in {'formats', 'demuxers', 'muxers', 'codecs', 'filters'}:
|
assert isinstance(data['codecs'], dict)
|
||||||
|
for codec, coders in data['codecs'].items():
|
||||||
|
assert isinstance(codec, str)
|
||||||
|
assert isinstance(coders, dict)
|
||||||
|
assert isinstance(data['hwaccels'], list)
|
||||||
|
for hwaccel in data['hwaccels']:
|
||||||
|
assert isinstance(hwaccel, dict)
|
||||||
|
assert 'name' in hwaccel
|
||||||
|
|
||||||
|
for fields_key in {'formats', 'demuxers', 'muxers', 'filters'}:
|
||||||
assert isinstance(data[fields_key], dict)
|
assert isinstance(data[fields_key], dict)
|
||||||
|
|
||||||
list_keys = {'bsfs'}
|
list_keys = {'bsfs'}
|
||||||
@ -741,10 +750,13 @@ def test__build_data():
|
|||||||
|
|
||||||
|
|
||||||
def test__detect():
|
def test__detect():
|
||||||
for hwaccels in [
|
for hwaccels_data in [
|
||||||
ffmpeg.detect_hwaccels(),
|
ffmpeg.detect_hwaccels(),
|
||||||
ffmpeg.detect_hwaccels(['foohwaccel'])]:
|
ffmpeg.detect_hwaccels(['foohwaccel'])]:
|
||||||
assert isinstance(hwaccels, list)
|
assert isinstance(hwaccels_data['hwaccels'], list)
|
||||||
|
for hwaccel in hwaccels_data['hwaccels']:
|
||||||
|
assert isinstance(hwaccel, dict)
|
||||||
|
assert 'name' in hwaccel
|
||||||
|
|
||||||
for codecs in [
|
for codecs in [
|
||||||
ffmpeg.detect_codecs('h264', 'h264'),
|
ffmpeg.detect_codecs('h264', 'h264'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user