Skip to content

Commit 8ac81b7

Browse files
authored
More benchmark refactoring, more benchmarks. (#337)
1 parent 42fa254 commit 8ac81b7

5 files changed

+235
-174
lines changed

benchmarks/decoders/benchmark_decoders.py

+73-46
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,56 @@
77
import argparse
88
import importlib.resources
99
import os
10+
import typing
11+
from dataclasses import dataclass, field
1012
from pathlib import Path
1113

1214
from benchmark_decoders_library import (
13-
DecordNonBatchDecoderAccurateSeek,
15+
AbstractDecoder,
16+
DecordAccurate,
17+
DecordAccurateBatch,
1418
plot_data,
1519
run_benchmarks,
1620
TorchAudioDecoder,
1721
TorchCodecCore,
1822
TorchCodecCoreBatch,
1923
TorchCodecCoreCompiled,
24+
TorchCodecCoreNonBatch,
2025
TorchCodecPublic,
2126
TorchVision,
2227
)
2328

2429

30+
@dataclass
31+
class DecoderKind:
32+
display_name: str
33+
kind: typing.Type[AbstractDecoder]
34+
default_options: dict[str, str] = field(default_factory=dict)
35+
36+
37+
decoder_registry = {
38+
"decord": DecoderKind("DecordAccurate", DecordAccurate),
39+
"decord_batch": DecoderKind("DecordAccurateBatch", DecordAccurateBatch),
40+
"torchcodec_core": DecoderKind("TorchCodecCore", TorchCodecCore),
41+
"torchcodec_core_batch": DecoderKind("TorchCodecCoreBatch", TorchCodecCoreBatch),
42+
"torchcodec_core_nonbatch": DecoderKind(
43+
"TorchCodecCoreNonBatch", TorchCodecCoreNonBatch
44+
),
45+
"torchcodec_core_compiled": DecoderKind(
46+
"TorchCodecCoreCompiled", TorchCodecCoreCompiled
47+
),
48+
"torchcodec_public": DecoderKind("TorchCodecPublic", TorchCodecPublic),
49+
"torchvision": DecoderKind(
50+
# We don't compare against TorchVision's "pyav" backend because it doesn't support
51+
# accurate seeks.
52+
"TorchVision[backend=video_reader]",
53+
TorchVision,
54+
{"backend": "video_reader"},
55+
),
56+
"torchaudio": DecoderKind("TorchAudio", TorchAudioDecoder),
57+
}
58+
59+
2560
def in_fbcode() -> bool:
2661
return "FB_PAR_RUNTIME_FILES" in os.environ
2762

@@ -35,6 +70,16 @@ def get_test_resource_path(filename: str) -> str:
3570
return str(Path(__file__).parent / f"../../test/resources/{filename}")
3671

3772

73+
def parse_options_code(options_code: str) -> dict[str, str]:
74+
options = {}
75+
for item in options_code.split("+"):
76+
if item.strip() == "":
77+
continue
78+
k, v = item.split("=")
79+
options[k] = v
80+
return options
81+
82+
3883
def main() -> None:
3984
"""Benchmarks the performance of a few video decoders"""
4085

@@ -67,11 +112,18 @@ def main() -> None:
67112
"--decoders",
68113
help=(
69114
"Comma-separated list of decoders to benchmark. "
70-
"Choices are torchcodec, torchaudio, torchvision, decord, tcoptions:num_threads=1+color_conversion_library=filtergraph, torchcodec_compiled"
71-
"For torchcodec, you can specify options with tcoptions:<plus-separated-options>. "
115+
"Choices are: " + ", ".join(decoder_registry.keys()) + ". "
116+
"To specify options, append a ':' and then value pairs seperated by a '+'. "
117+
"For example, torchcodec_core:num_threads=1+color_conversion_library=filtergraph."
72118
),
73119
type=str,
74-
default="decord,tcoptions:,torchvision,torchaudio,torchcodec_compiled,torchcodec_public,tcoptions:num_threads=1,tcbatchoptions:",
120+
default=(
121+
"decord,decord_batch,"
122+
"torchvision,"
123+
"torchaudio,"
124+
"torchcodec_core,torchcodec_core:num_threads=1,torchcodec_core_batch,torchcodec_core_nonbatch,"
125+
"torchcodec_public"
126+
),
75127
)
76128
parser.add_argument(
77129
"--bm_video_dir",
@@ -87,51 +139,26 @@ def main() -> None:
87139
)
88140

89141
args = parser.parse_args()
90-
decoders = set(args.decoders.split(","))
142+
specified_decoders = set(args.decoders.split(","))
91143

92144
# These are the PTS values we want to extract from the small video.
93145
num_uniform_samples = 10
94146

95-
decoder_dict = {}
96-
for decoder in decoders:
97-
if decoder == "decord":
98-
decoder_dict["DecordNonBatchDecoderAccurateSeek"] = (
99-
DecordNonBatchDecoderAccurateSeek()
100-
)
101-
elif decoder == "torchcodec":
102-
decoder_dict["TorchCodecCore:"] = TorchCodecCore()
103-
elif decoder == "torchcodec_compiled":
104-
decoder_dict["TorchCodecCoreCompiled"] = TorchCodecCoreCompiled()
105-
elif decoder == "torchcodec_public":
106-
decoder_dict["TorchCodecPublic"] = TorchCodecPublic()
107-
elif decoder == "torchvision":
108-
decoder_dict["TorchVision[backend=video_reader]"] = (
109-
# We don't compare TorchVision's "pyav" backend because it doesn't support
110-
# accurate seeks.
111-
TorchVision("video_reader")
112-
)
113-
elif decoder == "torchaudio":
114-
decoder_dict["TorchAudioDecoder"] = TorchAudioDecoder()
115-
elif decoder.startswith("tcbatchoptions:"):
116-
options = decoder[len("tcbatchoptions:") :]
117-
kwargs_dict = {}
118-
for item in options.split("+"):
119-
if item.strip() == "":
120-
continue
121-
k, v = item.split("=")
122-
kwargs_dict[k] = v
123-
decoder_dict["TorchCodecCoreBatch" + options] = TorchCodecCoreBatch(
124-
**kwargs_dict
125-
)
126-
elif decoder.startswith("tcoptions:"):
127-
options = decoder[len("tcoptions:") :]
128-
kwargs_dict = {}
129-
for item in options.split("+"):
130-
if item.strip() == "":
131-
continue
132-
k, v = item.split("=")
133-
kwargs_dict[k] = v
134-
decoder_dict["TorchCodecCore:" + options] = TorchCodecCore(**kwargs_dict)
147+
decoders_to_run = {}
148+
for decoder in specified_decoders:
149+
if ":" in decoder:
150+
decoder, _, options_code = decoder.partition(":")
151+
assert decoder in decoder_registry, f"Unknown decoder: {decoder}"
152+
display = decoder_registry[decoder].display_name + ":" + options_code
153+
options = parse_options_code(options_code)
154+
else:
155+
assert decoder in decoder_registry, f"Unknown decoder: {decoder}"
156+
display = decoder_registry[decoder].display_name
157+
options = decoder_registry[decoder].default_options
158+
159+
kind = decoder_registry[decoder].kind
160+
decoders_to_run[display] = kind(**options)
161+
135162
video_paths = args.bm_video_paths.split(",")
136163
if args.bm_video_dir:
137164
video_paths = []
@@ -140,7 +167,7 @@ def main() -> None:
140167
video_paths.append(entry.path)
141168

142169
df_data = run_benchmarks(
143-
decoder_dict,
170+
decoders_to_run,
144171
video_paths,
145172
num_uniform_samples,
146173
num_sequential_frames_from_start=[1, 10, 100],

0 commit comments

Comments
 (0)