HwCodecDetect 0.0.9__tar.gz → 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hwcodecdetect-0.0.9/src/HwCodecDetect.egg-info → hwcodecdetect-0.1.0}/PKG-INFO +35 -13
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/README.md +34 -12
- hwcodecdetect-0.1.0/VERSION +1 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/pyproject.toml +2 -2
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/setup.py +1 -1
- hwcodecdetect-0.1.0/src/HwCodecDetect/__init__.py +17 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect/run_tests.py +59 -23
- hwcodecdetect-0.1.0/src/HwCodecDetect/version.py +1 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0/src/HwCodecDetect.egg-info}/PKG-INFO +35 -13
- hwcodecdetect-0.1.0/src/HwCodecDetect.egg-info/entry_points.txt +2 -0
- hwcodecdetect-0.0.9/VERSION +0 -1
- hwcodecdetect-0.0.9/src/HwCodecDetect/__init__.py +0 -9
- hwcodecdetect-0.0.9/src/HwCodecDetect/version.py +0 -1
- hwcodecdetect-0.0.9/src/HwCodecDetect.egg-info/entry_points.txt +0 -2
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/LICENSE +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/MANIFEST.in +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/setup.cfg +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect/install_ffmpeg_if_needed.py +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect.egg-info/SOURCES.txt +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect.egg-info/dependency_links.txt +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect.egg-info/requires.txt +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect.egg-info/top_level.txt +0 -0
- {hwcodecdetect-0.0.9 → hwcodecdetect-0.1.0}/src/HwCodecDetect.egg-info/zip-safe +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: HwCodecDetect
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: A cross-platform tool to automatically detect and test hardware video decoders/encoders using FFmpeg.
|
|
5
5
|
Home-page: https://github.com/whyb/HwCodecDetect
|
|
6
6
|
Author: whyb
|
|
@@ -25,6 +25,9 @@ Dynamic: requires-python
|
|
|
25
25
|
|
|
26
26
|
# FFmpeg Hardware Codec Test Script(HwCodecDetect)
|
|
27
27
|
<p align="center">
|
|
28
|
+
<a href="https://github.com/whyb/HwCodecDetect/actions/workflows/run-test.yml">
|
|
29
|
+
<img src="https://github.com/whyb/HwCodecDetect/actions/workflows/run-test.yml/badge.svg" />
|
|
30
|
+
</a>
|
|
28
31
|
<a href="https://pypi.org/project/hwcodecdetect">
|
|
29
32
|
<img src="https://badgen.net/pypi/v/hwcodecdetect?color=yellow" />
|
|
30
33
|
</a>
|
|
@@ -35,7 +38,7 @@ Dynamic: requires-python
|
|
|
35
38
|
|
|
36
39
|
[中文版](https://github.com/whyb/HwCodecDetect/blob/main/README.zh.md)
|
|
37
40
|
|
|
38
|
-
Today's hardware-accelerated video codec landscape is a "field of a hundred schools of thought." To leverage the immense power of GPUs, hardware manufacturers have introduced their own acceleration frameworks and encoding standards, such as NVIDIA's NVEnc/NVDec, Intel's QSV, and AMD's AMF. Additionally, operating systems provide universal APIs like Microsoft's Media Foundation,
|
|
41
|
+
Today's hardware-accelerated video codec landscape is a "field of a hundred schools of thought." To leverage the immense power of GPUs, hardware manufacturers have introduced their own acceleration frameworks and encoding standards, such as NVIDIA's NVEnc/NVDec, Intel's QSV, and AMD's AMF. Additionally, operating systems provide universal APIs like Microsoft's Media Foundation, DXVA2, and D3D12VA, while the open-source community has developed cross-platform standards like VAAPI and Vulkan.
|
|
39
42
|
|
|
40
43
|
While this diversity drives technological progress, it also presents a challenge for users and developers. Due to historical issues and compatibility quirks, a single piece of hardware might support multiple encoders, but they can differ significantly in performance, supported formats, and resolutions. As a result, when using FFmpeg for hardware acceleration, it's not always clear which encoder is best suited for a specific device.
|
|
41
44
|
|
|
@@ -69,20 +72,39 @@ The script automatically tests and reports on the following major hardware decod
|
|
|
69
72
|
|
|
70
73
|
|
|
71
74
|
## How to Use
|
|
75
|
+
You can install and use HwCodecDetect in two ways.
|
|
76
|
+
### Method 1: Install via PyPI (Recommended)
|
|
77
|
+
This is the easiest method if you just want to use the tool quickly.
|
|
78
|
+
|
|
79
|
+
1. Install: Use pip to install HwCodecDetect from the official PyPI repository.
|
|
80
|
+
```bash
|
|
81
|
+
pip install HwCodecDetect
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. Run: After installation, run the HwCodecDetect command directly from your terminal.
|
|
85
|
+
```bash
|
|
86
|
+
HwCodecDetect
|
|
87
|
+
```
|
|
72
88
|
|
|
73
|
-
###
|
|
74
|
-
|
|
75
|
-
pip install HwCodecDetect
|
|
76
|
-
```
|
|
89
|
+
### Method 2: Install from Source
|
|
90
|
+
Use this method if you have cloned the project source code from GitHub and want to run it locally.
|
|
77
91
|
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
HwCodecDetect
|
|
81
|
-
```
|
|
92
|
+
1. Clone the repository: First, clone the project source code to your local machine.
|
|
93
|
+
```bash
|
|
94
|
+
git clone https://github.com/whyb/HwCodecDetect.git
|
|
95
|
+
```
|
|
82
96
|
|
|
97
|
+
2. Install dependencies: Navigate into the project's root directory and use pip to install the required dependencies.
|
|
98
|
+
```bash
|
|
99
|
+
cd HwCodecDetect
|
|
100
|
+
pip install .
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. Run: After the installation is complete, run the HwCodecDetect command directly.
|
|
104
|
+
```bash
|
|
105
|
+
HwCodecDetect
|
|
106
|
+
```
|
|
83
107
|
|
|
84
108
|
## Demo
|
|
85
109
|
Here are some possible results from a local test run:
|
|
86
|
-

|
|
110
|
+

|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# FFmpeg Hardware Codec Test Script(HwCodecDetect)
|
|
2
2
|
<p align="center">
|
|
3
|
+
<a href="https://github.com/whyb/HwCodecDetect/actions/workflows/run-test.yml">
|
|
4
|
+
<img src="https://github.com/whyb/HwCodecDetect/actions/workflows/run-test.yml/badge.svg" />
|
|
5
|
+
</a>
|
|
3
6
|
<a href="https://pypi.org/project/hwcodecdetect">
|
|
4
7
|
<img src="https://badgen.net/pypi/v/hwcodecdetect?color=yellow" />
|
|
5
8
|
</a>
|
|
@@ -10,7 +13,7 @@
|
|
|
10
13
|
|
|
11
14
|
[中文版](https://github.com/whyb/HwCodecDetect/blob/main/README.zh.md)
|
|
12
15
|
|
|
13
|
-
Today's hardware-accelerated video codec landscape is a "field of a hundred schools of thought." To leverage the immense power of GPUs, hardware manufacturers have introduced their own acceleration frameworks and encoding standards, such as NVIDIA's NVEnc/NVDec, Intel's QSV, and AMD's AMF. Additionally, operating systems provide universal APIs like Microsoft's Media Foundation,
|
|
16
|
+
Today's hardware-accelerated video codec landscape is a "field of a hundred schools of thought." To leverage the immense power of GPUs, hardware manufacturers have introduced their own acceleration frameworks and encoding standards, such as NVIDIA's NVEnc/NVDec, Intel's QSV, and AMD's AMF. Additionally, operating systems provide universal APIs like Microsoft's Media Foundation, DXVA2, and D3D12VA, while the open-source community has developed cross-platform standards like VAAPI and Vulkan.
|
|
14
17
|
|
|
15
18
|
While this diversity drives technological progress, it also presents a challenge for users and developers. Due to historical issues and compatibility quirks, a single piece of hardware might support multiple encoders, but they can differ significantly in performance, supported formats, and resolutions. As a result, when using FFmpeg for hardware acceleration, it's not always clear which encoder is best suited for a specific device.
|
|
16
19
|
|
|
@@ -44,20 +47,39 @@ The script automatically tests and reports on the following major hardware decod
|
|
|
44
47
|
|
|
45
48
|
|
|
46
49
|
## How to Use
|
|
50
|
+
You can install and use HwCodecDetect in two ways.
|
|
51
|
+
### Method 1: Install via PyPI (Recommended)
|
|
52
|
+
This is the easiest method if you just want to use the tool quickly.
|
|
53
|
+
|
|
54
|
+
1. Install: Use pip to install HwCodecDetect from the official PyPI repository.
|
|
55
|
+
```bash
|
|
56
|
+
pip install HwCodecDetect
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
2. Run: After installation, run the HwCodecDetect command directly from your terminal.
|
|
60
|
+
```bash
|
|
61
|
+
HwCodecDetect
|
|
62
|
+
```
|
|
47
63
|
|
|
48
|
-
###
|
|
49
|
-
|
|
50
|
-
pip install HwCodecDetect
|
|
51
|
-
```
|
|
64
|
+
### Method 2: Install from Source
|
|
65
|
+
Use this method if you have cloned the project source code from GitHub and want to run it locally.
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
HwCodecDetect
|
|
56
|
-
```
|
|
67
|
+
1. Clone the repository: First, clone the project source code to your local machine.
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/whyb/HwCodecDetect.git
|
|
70
|
+
```
|
|
57
71
|
|
|
72
|
+
2. Install dependencies: Navigate into the project's root directory and use pip to install the required dependencies.
|
|
73
|
+
```bash
|
|
74
|
+
cd HwCodecDetect
|
|
75
|
+
pip install .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
3. Run: After the installation is complete, run the HwCodecDetect command directly.
|
|
79
|
+
```bash
|
|
80
|
+
HwCodecDetect
|
|
81
|
+
```
|
|
58
82
|
|
|
59
83
|
## Demo
|
|
60
84
|
Here are some possible results from a local test run:
|
|
61
|
-

|
|
85
|
+

|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "HwCodecDetect"
|
|
7
|
-
version = "0.0
|
|
7
|
+
version = "0.1.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="whyb", email="whyber@outlook.com" },
|
|
10
10
|
]
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[project.scripts]
|
|
31
|
-
hwcodecdetect = "HwCodecDetect.run_tests:
|
|
31
|
+
hwcodecdetect = "HwCodecDetect.run_tests:main"
|
|
32
32
|
|
|
33
33
|
[project.urls]
|
|
34
34
|
Homepage = "https://github.com/whyb/HwCodecDetect"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# HwCodecDetect/__init__.py
|
|
2
|
+
import os
|
|
3
|
+
from .install_ffmpeg_if_needed import install_ffmpeg_if_needed
|
|
4
|
+
|
|
5
|
+
def _read_version():
|
|
6
|
+
try:
|
|
7
|
+
version_path = os.path.join(os.path.dirname(__file__), '..', '..', 'VERSION')
|
|
8
|
+
with open(version_path, encoding='utf-8') as f:
|
|
9
|
+
return f.read().strip()
|
|
10
|
+
except Exception:
|
|
11
|
+
return "0.0.0"
|
|
12
|
+
|
|
13
|
+
__version__ = _read_version()
|
|
14
|
+
__author__ = "whyb"
|
|
15
|
+
__email__ = "whyber@outlook.com"
|
|
16
|
+
__license__ = "BSD-3-Clause"
|
|
17
|
+
__url__ = "https://github.com/whyb/HwCodecDetect"
|
|
@@ -60,7 +60,7 @@ DECODER_TITLES = {
|
|
|
60
60
|
("d3d11va", "mpeg1"): "Microsoft Direct3D 11 Video Acceleration MPEG-1 Decoder(D3D11VA)",
|
|
61
61
|
("d3d11va", "mpeg2"): "Microsoft Direct3D 11 Video Acceleration MPEG-2 Decoder(D3D11VA)",
|
|
62
62
|
("d3d11va", "mpeg4"): "Microsoft Direct3D 11 Video Acceleration MPEG-4 Decoder(D3D11VA)",
|
|
63
|
-
("d3d11va", "vp8"): "Microsoft Direct3D 11 Video Acceleration VP8 Decoder(
|
|
63
|
+
("d3d11va", "vp8"): "Microsoft Direct3D 11 Video Acceleration VP8 Decoder(D3D11VA)",
|
|
64
64
|
("d3d11va", "vp9"): "Microsoft Direct3D 11 Video Acceleration VP9 Decoder(D3D11VA)",
|
|
65
65
|
("vulkan", "h264"): "Vulkan Hardware H264 Decoder(Vulkan)",
|
|
66
66
|
("vulkan", "h265"): "Vulkan Hardware H265 Decoder(Vulkan)",
|
|
@@ -134,22 +134,27 @@ ALL_CODECS = {
|
|
|
134
134
|
CONCURRENT_ENCODER_COUNT = 8
|
|
135
135
|
CONCURRENT_DECODER_COUNT = 16
|
|
136
136
|
|
|
137
|
-
def _run_ffmpeg_command(command):
|
|
137
|
+
def _run_ffmpeg_command(command, verbose):
|
|
138
138
|
"""Executes an FFmpeg command and returns True on success, False on failure."""
|
|
139
139
|
try:
|
|
140
|
+
stdout = subprocess.PIPE if verbose else subprocess.DEVNULL
|
|
141
|
+
stderr = subprocess.PIPE if verbose else subprocess.DEVNULL
|
|
140
142
|
result = subprocess.run(
|
|
141
143
|
command,
|
|
142
144
|
check=True,
|
|
143
|
-
stdout=
|
|
144
|
-
stderr=
|
|
145
|
+
stdout=stdout,
|
|
146
|
+
stderr=stderr,
|
|
147
|
+
text=True
|
|
145
148
|
)
|
|
146
|
-
return result.returncode == 0
|
|
147
|
-
except
|
|
148
|
-
return False
|
|
149
|
+
return (result.returncode == 0, result.stdout, result.stderr)
|
|
150
|
+
except subprocess.CalledProcessError as e:
|
|
151
|
+
return (False, e.stdout, e.stderr)
|
|
152
|
+
except FileNotFoundError:
|
|
153
|
+
return (False, "", "FFmpeg executable not found")
|
|
149
154
|
|
|
150
155
|
def _run_encoder_test_single(test_data):
|
|
151
156
|
"""Runs a single encoder test and returns the result."""
|
|
152
|
-
codec, encoder, res_name, res_size, test_dir = test_data
|
|
157
|
+
codec, encoder, res_name, res_size, test_dir, verbose = test_data
|
|
153
158
|
file_ext = ".webm" if codec in ["vp8", "vp9"] else ".mp4"
|
|
154
159
|
output_file = os.path.join(test_dir, f"{encoder}_{res_name}{file_ext}")
|
|
155
160
|
|
|
@@ -170,11 +175,24 @@ def _run_encoder_test_single(test_data):
|
|
|
170
175
|
command.insert(9, "-dual_gfx")
|
|
171
176
|
command.insert(10, "0")
|
|
172
177
|
|
|
173
|
-
|
|
178
|
+
if verbose: # if verbose then replace loglevel to verbose
|
|
179
|
+
command[2] = "error"
|
|
180
|
+
|
|
181
|
+
success, stdout, stderr = _run_ffmpeg_command(command, verbose)
|
|
182
|
+
status = "succeeded" if success else "failed"
|
|
183
|
+
|
|
184
|
+
if verbose:
|
|
185
|
+
if stdout:
|
|
186
|
+
print(f"Output:\n{stdout}")
|
|
187
|
+
if stderr:
|
|
188
|
+
print(f"Error Output:\n{stderr}")
|
|
189
|
+
print(f"Test Result: {status}")
|
|
190
|
+
|
|
174
191
|
title = ENCODER_TITLES.get((encoder, codec), f"{encoder.upper()} Encoder:")
|
|
175
192
|
return title, res_name, status
|
|
176
193
|
|
|
177
|
-
|
|
194
|
+
|
|
195
|
+
def _run_encoder_tests(test_dir, max_workers, verbose):
|
|
178
196
|
"""Runs hardware encoder tests using a thread pool."""
|
|
179
197
|
results = defaultdict(dict)
|
|
180
198
|
|
|
@@ -184,7 +202,7 @@ def _run_encoder_tests(test_dir, max_workers):
|
|
|
184
202
|
for codec, info in ENCODERS.items():
|
|
185
203
|
for encoder in info['hw_encoders']:
|
|
186
204
|
for res_name, res_size in RESOLUTIONS.items():
|
|
187
|
-
tasks.append((codec, encoder, res_name, res_size, test_dir))
|
|
205
|
+
tasks.append((codec, encoder, res_name, res_size, test_dir, verbose))
|
|
188
206
|
|
|
189
207
|
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
190
208
|
futures = [executor.submit(_run_encoder_test_single, task) for task in tasks]
|
|
@@ -197,7 +215,7 @@ def _run_encoder_tests(test_dir, max_workers):
|
|
|
197
215
|
|
|
198
216
|
def _run_decoder_test_single(test_data):
|
|
199
217
|
"""Runs a single decoder test and returns the result."""
|
|
200
|
-
codec, hw_decoder, res_name, res_size, test_dir = test_data
|
|
218
|
+
codec, hw_decoder, res_name, res_size, test_dir, verbose = test_data
|
|
201
219
|
file_ext = ".webm" if codec in ["vp8", "vp9"] else ".mp4"
|
|
202
220
|
test_file_path = os.path.join(test_dir, f"{codec}_{res_name}{file_ext}")
|
|
203
221
|
|
|
@@ -216,7 +234,7 @@ def _run_decoder_test_single(test_data):
|
|
|
216
234
|
"-frames:v", "1", "-c:v", cpu_lib, "-pixel_format", "yuv420p",
|
|
217
235
|
test_file_path,
|
|
218
236
|
]
|
|
219
|
-
if not _run_ffmpeg_command(command):
|
|
237
|
+
if not _run_ffmpeg_command(command, verbose):
|
|
220
238
|
title = DECODER_TITLES.get((hw_decoder, codec), f"{hw_decoder.upper()} Decoder:")
|
|
221
239
|
return title, res_name, "skipped"
|
|
222
240
|
|
|
@@ -250,13 +268,25 @@ def _run_decoder_test_single(test_data):
|
|
|
250
268
|
"-c:v", "libx264", "-preset", "ultrafast",
|
|
251
269
|
"-f", "null", "null",
|
|
252
270
|
]
|
|
253
|
-
|
|
254
|
-
|
|
271
|
+
|
|
272
|
+
if verbose: # if verbose then replace loglevel to verbose
|
|
273
|
+
command[2] = "error"
|
|
274
|
+
|
|
275
|
+
success, stdout, stderr = _run_ffmpeg_command(command, verbose)
|
|
276
|
+
status = "succeeded" if success else "failed"
|
|
277
|
+
|
|
278
|
+
if verbose:
|
|
279
|
+
if stdout:
|
|
280
|
+
print(f"Output:\n{stdout}")
|
|
281
|
+
if stderr:
|
|
282
|
+
print(f"Error Output:\n{stderr}")
|
|
283
|
+
print(f"Test Result: {status}")
|
|
284
|
+
|
|
255
285
|
title = DECODER_TITLES.get((hw_decoder, codec), f"{hw_decoder.upper()} Decoder:")
|
|
256
286
|
return title, res_name, status
|
|
257
287
|
|
|
258
288
|
|
|
259
|
-
def _run_decoder_tests(test_dir, max_workers):
|
|
289
|
+
def _run_decoder_tests(test_dir, max_workers, verbose):
|
|
260
290
|
"""Runs hardware decoder tests using a thread pool."""
|
|
261
291
|
results = defaultdict(dict)
|
|
262
292
|
|
|
@@ -266,8 +296,8 @@ def _run_decoder_tests(test_dir, max_workers):
|
|
|
266
296
|
for codec, info in DECODERS.items():
|
|
267
297
|
for hw_decoder in info['hw_decoders']:
|
|
268
298
|
for res_name, res_size in RESOLUTIONS.items():
|
|
269
|
-
tasks.append((codec, hw_decoder, res_name, res_size, test_dir))
|
|
270
|
-
|
|
299
|
+
tasks.append((codec, hw_decoder, res_name, res_size, test_dir, verbose))
|
|
300
|
+
|
|
271
301
|
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
272
302
|
futures = [executor.submit(_run_decoder_test_single, task) for task in tasks]
|
|
273
303
|
|
|
@@ -297,7 +327,7 @@ def _print_summary_table(results):
|
|
|
297
327
|
|
|
298
328
|
res_width = max(len(res) for res in resolutions)
|
|
299
329
|
row_header_width = max([_get_display_width(t) for t in results.keys()] + [20, _get_display_width("Decoder"), _get_display_width("Encoder")])
|
|
300
|
-
|
|
330
|
+
|
|
301
331
|
if decoder_titles:
|
|
302
332
|
print("\n" + "-" * (row_header_width + 3 + (res_width + 3) * len(resolutions)))
|
|
303
333
|
header_text = "Decoder"
|
|
@@ -308,7 +338,7 @@ def _print_summary_table(results):
|
|
|
308
338
|
header_row += f" {res.center(res_width)} |"
|
|
309
339
|
print(header_row)
|
|
310
340
|
print("-" * (row_header_width + 3 + (res_width + 3) * len(resolutions)))
|
|
311
|
-
|
|
341
|
+
|
|
312
342
|
for title in decoder_titles:
|
|
313
343
|
padding_needed = row_header_width - _get_display_width(title)
|
|
314
344
|
row_string = f"| {title}{' ' * padding_needed} |"
|
|
@@ -332,7 +362,7 @@ def _print_summary_table(results):
|
|
|
332
362
|
header_row += f" {res.center(res_width)} |"
|
|
333
363
|
print(header_row)
|
|
334
364
|
print("-" * (row_header_width + 3 + (res_width + 3) * len(resolutions)))
|
|
335
|
-
|
|
365
|
+
|
|
336
366
|
for title in encoder_titles:
|
|
337
367
|
padding_needed = row_header_width - _get_display_width(title)
|
|
338
368
|
row_string = f"| {title}{' ' * padding_needed} |"
|
|
@@ -361,8 +391,8 @@ def run_all_tests(args):
|
|
|
361
391
|
shutil.rmtree(temp_dir)
|
|
362
392
|
os.makedirs(temp_dir)
|
|
363
393
|
|
|
364
|
-
encoder_results = _run_encoder_tests(temp_dir, args.encoder_count)
|
|
365
|
-
decoder_results = _run_decoder_tests(temp_dir, args.decoder_count)
|
|
394
|
+
encoder_results = _run_encoder_tests(temp_dir, args.encoder_count, args.verbose)
|
|
395
|
+
decoder_results = _run_decoder_tests(temp_dir, args.decoder_count, args.verbose)
|
|
366
396
|
|
|
367
397
|
all_results = {}
|
|
368
398
|
all_results.update(encoder_results)
|
|
@@ -424,6 +454,12 @@ def main():
|
|
|
424
454
|
help="Show program's version number and exit."
|
|
425
455
|
)
|
|
426
456
|
|
|
457
|
+
parser.add_argument(
|
|
458
|
+
'--verbose',
|
|
459
|
+
action='store_true',
|
|
460
|
+
help='Print detailed information for each test'
|
|
461
|
+
)
|
|
462
|
+
|
|
427
463
|
args = parser.parse_args()
|
|
428
464
|
run_all_tests(args)
|
|
429
465
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: HwCodecDetect
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: A cross-platform tool to automatically detect and test hardware video decoders/encoders using FFmpeg.
|
|
5
5
|
Home-page: https://github.com/whyb/HwCodecDetect
|
|
6
6
|
Author: whyb
|
|
@@ -25,6 +25,9 @@ Dynamic: requires-python
|
|
|
25
25
|
|
|
26
26
|
# FFmpeg Hardware Codec Test Script(HwCodecDetect)
|
|
27
27
|
<p align="center">
|
|
28
|
+
<a href="https://github.com/whyb/HwCodecDetect/actions/workflows/run-test.yml">
|
|
29
|
+
<img src="https://github.com/whyb/HwCodecDetect/actions/workflows/run-test.yml/badge.svg" />
|
|
30
|
+
</a>
|
|
28
31
|
<a href="https://pypi.org/project/hwcodecdetect">
|
|
29
32
|
<img src="https://badgen.net/pypi/v/hwcodecdetect?color=yellow" />
|
|
30
33
|
</a>
|
|
@@ -35,7 +38,7 @@ Dynamic: requires-python
|
|
|
35
38
|
|
|
36
39
|
[中文版](https://github.com/whyb/HwCodecDetect/blob/main/README.zh.md)
|
|
37
40
|
|
|
38
|
-
Today's hardware-accelerated video codec landscape is a "field of a hundred schools of thought." To leverage the immense power of GPUs, hardware manufacturers have introduced their own acceleration frameworks and encoding standards, such as NVIDIA's NVEnc/NVDec, Intel's QSV, and AMD's AMF. Additionally, operating systems provide universal APIs like Microsoft's Media Foundation,
|
|
41
|
+
Today's hardware-accelerated video codec landscape is a "field of a hundred schools of thought." To leverage the immense power of GPUs, hardware manufacturers have introduced their own acceleration frameworks and encoding standards, such as NVIDIA's NVEnc/NVDec, Intel's QSV, and AMD's AMF. Additionally, operating systems provide universal APIs like Microsoft's Media Foundation, DXVA2, and D3D12VA, while the open-source community has developed cross-platform standards like VAAPI and Vulkan.
|
|
39
42
|
|
|
40
43
|
While this diversity drives technological progress, it also presents a challenge for users and developers. Due to historical issues and compatibility quirks, a single piece of hardware might support multiple encoders, but they can differ significantly in performance, supported formats, and resolutions. As a result, when using FFmpeg for hardware acceleration, it's not always clear which encoder is best suited for a specific device.
|
|
41
44
|
|
|
@@ -69,20 +72,39 @@ The script automatically tests and reports on the following major hardware decod
|
|
|
69
72
|
|
|
70
73
|
|
|
71
74
|
## How to Use
|
|
75
|
+
You can install and use HwCodecDetect in two ways.
|
|
76
|
+
### Method 1: Install via PyPI (Recommended)
|
|
77
|
+
This is the easiest method if you just want to use the tool quickly.
|
|
78
|
+
|
|
79
|
+
1. Install: Use pip to install HwCodecDetect from the official PyPI repository.
|
|
80
|
+
```bash
|
|
81
|
+
pip install HwCodecDetect
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. Run: After installation, run the HwCodecDetect command directly from your terminal.
|
|
85
|
+
```bash
|
|
86
|
+
HwCodecDetect
|
|
87
|
+
```
|
|
72
88
|
|
|
73
|
-
###
|
|
74
|
-
|
|
75
|
-
pip install HwCodecDetect
|
|
76
|
-
```
|
|
89
|
+
### Method 2: Install from Source
|
|
90
|
+
Use this method if you have cloned the project source code from GitHub and want to run it locally.
|
|
77
91
|
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
HwCodecDetect
|
|
81
|
-
```
|
|
92
|
+
1. Clone the repository: First, clone the project source code to your local machine.
|
|
93
|
+
```bash
|
|
94
|
+
git clone https://github.com/whyb/HwCodecDetect.git
|
|
95
|
+
```
|
|
82
96
|
|
|
97
|
+
2. Install dependencies: Navigate into the project's root directory and use pip to install the required dependencies.
|
|
98
|
+
```bash
|
|
99
|
+
cd HwCodecDetect
|
|
100
|
+
pip install .
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. Run: After the installation is complete, run the HwCodecDetect command directly.
|
|
104
|
+
```bash
|
|
105
|
+
HwCodecDetect
|
|
106
|
+
```
|
|
83
107
|
|
|
84
108
|
## Demo
|
|
85
109
|
Here are some possible results from a local test run:
|
|
86
|
-

|
|
110
|
+

|
hwcodecdetect-0.0.9/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.0.9
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# HwCodecDetect/__init__.py
|
|
2
|
-
|
|
3
|
-
from .install_ffmpeg_if_needed import install_ffmpeg_if_needed
|
|
4
|
-
from .version import __version__
|
|
5
|
-
|
|
6
|
-
__author__ = "whyb"
|
|
7
|
-
__email__ = "whyber@outlook.com"
|
|
8
|
-
__license__ = "BSD-3-Clause"
|
|
9
|
-
__url__ = "https://github.com/whyb/HwCodecDetect"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|