Skip to content

Commit 1ffc01c

Browse files
committed
Add args: --verbose and upgrade version to v0.1.0
1 parent 682ed78 commit 1ffc01c

File tree

3 files changed

+60
-24
lines changed

3 files changed

+60
-24
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.10
1+
0.1.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "HwCodecDetect"
7-
version = "0.0.10"
7+
version = "0.1.0"
88
authors = [
99
{ name="whyb", email="whyber@outlook.com" },
1010
]

src/HwCodecDetect/run_tests.py

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,27 @@
134134
CONCURRENT_ENCODER_COUNT = 8
135135
CONCURRENT_DECODER_COUNT = 16
136136

137-
def _run_ffmpeg_command(command):
137+
def _run_ffmpeg_command(command, verbose):
138138
"""Executes an FFmpeg command and returns True on success, False on failure."""
139139
try:
140+
stdout = subprocess.PIPE if verbose else subprocess.DEVNULL
141+
stderr = subprocess.PIPE if verbose else subprocess.DEVNULL
140142
result = subprocess.run(
141143
command,
142144
check=True,
143-
stdout=subprocess.DEVNULL,
144-
stderr=subprocess.DEVNULL,
145+
stdout=stdout,
146+
stderr=stderr,
147+
text=True
145148
)
146-
return result.returncode == 0
147-
except (subprocess.CalledProcessError, FileNotFoundError):
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")
149154

150155
def _run_encoder_test_single(test_data):
151156
"""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
153158
file_ext = ".webm" if codec in ["vp8", "vp9"] else ".mp4"
154159
output_file = os.path.join(test_dir, f"{encoder}_{res_name}{file_ext}")
155160

@@ -170,11 +175,24 @@ def _run_encoder_test_single(test_data):
170175
command.insert(9, "-dual_gfx")
171176
command.insert(10, "0")
172177

173-
status = "succeeded" if _run_ffmpeg_command(command) else "failed"
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+
174191
title = ENCODER_TITLES.get((encoder, codec), f"{encoder.upper()} Encoder:")
175192
return title, res_name, status
176193

177-
def _run_encoder_tests(test_dir, max_workers):
194+
195+
def _run_encoder_tests(test_dir, max_workers, verbose):
178196
"""Runs hardware encoder tests using a thread pool."""
179197
results = defaultdict(dict)
180198

@@ -184,7 +202,7 @@ def _run_encoder_tests(test_dir, max_workers):
184202
for codec, info in ENCODERS.items():
185203
for encoder in info['hw_encoders']:
186204
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))
188206

189207
with ThreadPoolExecutor(max_workers=max_workers) as executor:
190208
futures = [executor.submit(_run_encoder_test_single, task) for task in tasks]
@@ -197,7 +215,7 @@ def _run_encoder_tests(test_dir, max_workers):
197215

198216
def _run_decoder_test_single(test_data):
199217
"""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
201219
file_ext = ".webm" if codec in ["vp8", "vp9"] else ".mp4"
202220
test_file_path = os.path.join(test_dir, f"{codec}_{res_name}{file_ext}")
203221

@@ -216,7 +234,7 @@ def _run_decoder_test_single(test_data):
216234
"-frames:v", "1", "-c:v", cpu_lib, "-pixel_format", "yuv420p",
217235
test_file_path,
218236
]
219-
if not _run_ffmpeg_command(command):
237+
if not _run_ffmpeg_command(command, verbose):
220238
title = DECODER_TITLES.get((hw_decoder, codec), f"{hw_decoder.upper()} Decoder:")
221239
return title, res_name, "skipped"
222240

@@ -250,13 +268,25 @@ def _run_decoder_test_single(test_data):
250268
"-c:v", "libx264", "-preset", "ultrafast",
251269
"-f", "null", "null",
252270
]
253-
254-
status = "succeeded" if _run_ffmpeg_command(command) else "failed"
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+
255285
title = DECODER_TITLES.get((hw_decoder, codec), f"{hw_decoder.upper()} Decoder:")
256286
return title, res_name, status
257287

258288

259-
def _run_decoder_tests(test_dir, max_workers):
289+
def _run_decoder_tests(test_dir, max_workers, verbose):
260290
"""Runs hardware decoder tests using a thread pool."""
261291
results = defaultdict(dict)
262292

@@ -266,8 +296,8 @@ def _run_decoder_tests(test_dir, max_workers):
266296
for codec, info in DECODERS.items():
267297
for hw_decoder in info['hw_decoders']:
268298
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+
271301
with ThreadPoolExecutor(max_workers=max_workers) as executor:
272302
futures = [executor.submit(_run_decoder_test_single, task) for task in tasks]
273303

@@ -297,7 +327,7 @@ def _print_summary_table(results):
297327

298328
res_width = max(len(res) for res in resolutions)
299329
row_header_width = max([_get_display_width(t) for t in results.keys()] + [20, _get_display_width("Decoder"), _get_display_width("Encoder")])
300-
330+
301331
if decoder_titles:
302332
print("\n" + "-" * (row_header_width + 3 + (res_width + 3) * len(resolutions)))
303333
header_text = "Decoder"
@@ -308,7 +338,7 @@ def _print_summary_table(results):
308338
header_row += f" {res.center(res_width)} |"
309339
print(header_row)
310340
print("-" * (row_header_width + 3 + (res_width + 3) * len(resolutions)))
311-
341+
312342
for title in decoder_titles:
313343
padding_needed = row_header_width - _get_display_width(title)
314344
row_string = f"| {title}{' ' * padding_needed} |"
@@ -332,7 +362,7 @@ def _print_summary_table(results):
332362
header_row += f" {res.center(res_width)} |"
333363
print(header_row)
334364
print("-" * (row_header_width + 3 + (res_width + 3) * len(resolutions)))
335-
365+
336366
for title in encoder_titles:
337367
padding_needed = row_header_width - _get_display_width(title)
338368
row_string = f"| {title}{' ' * padding_needed} |"
@@ -361,8 +391,8 @@ def run_all_tests(args):
361391
shutil.rmtree(temp_dir)
362392
os.makedirs(temp_dir)
363393

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)
366396

367397
all_results = {}
368398
all_results.update(encoder_results)
@@ -424,6 +454,12 @@ def main():
424454
help="Show program's version number and exit."
425455
)
426456

457+
parser.add_argument(
458+
'--verbose',
459+
action='store_true',
460+
help='Print detailed information for each test'
461+
)
462+
427463
args = parser.parse_args()
428464
run_all_tests(args)
429465

0 commit comments

Comments
 (0)