Skip to content

Commit 36a2c41

Browse files
committed
add codec_options test, generalize ffprobe function to reuse there
1 parent 5629e6e commit 36a2c41

File tree

1 file changed

+50
-53
lines changed

1 file changed

+50
-53
lines changed

test/test_encoders.py

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,8 @@ class TestVideoEncoder:
572572
def decode(self, source=None) -> torch.Tensor:
573573
return VideoDecoder(source).get_frames_in_range(start=0, stop=60)
574574

575-
def _get_codec_spec(self, file_path):
576-
"""Helper function to get codec name from a video file using ffprobe."""
575+
def _get_video_metadata(self, file_path, fields):
576+
"""Helper function to get video metadata from a file using ffprobe."""
577577
result = subprocess.run(
578578
[
579579
"ffprobe",
@@ -582,16 +582,21 @@ def _get_codec_spec(self, file_path):
582582
"-select_streams",
583583
"v:0",
584584
"-show_entries",
585-
"stream=codec_name",
585+
f"stream={','.join(fields)}",
586586
"-of",
587-
"default=noprint_wrappers=1:nokey=1",
587+
"default=noprint_wrappers=1",
588588
str(file_path),
589589
],
590590
capture_output=True,
591591
check=True,
592592
text=True,
593593
)
594-
return result.stdout.strip()
594+
metadata = {}
595+
for line in result.stdout.strip().split("\n"):
596+
if "=" in line:
597+
key, value = line.split("=", 1)
598+
metadata[key] = value
599+
return metadata
595600

596601
@pytest.mark.parametrize("method", ("to_file", "to_tensor", "to_file_like"))
597602
def test_bad_input_parameterized(self, tmp_path, method):
@@ -1087,7 +1092,9 @@ def test_codec_parameter_utilized(self, tmp_path, format, codec_spec):
10871092
dest = str(tmp_path / f"output.{format}")
10881093

10891094
VideoEncoder(frames=frames, frame_rate=30).to_file(dest=dest, codec=codec_spec)
1090-
actual_codec_spec = self._get_codec_spec(dest)
1095+
actual_codec_spec = self._get_video_metadata(dest, fields=["codec_name"]).get(
1096+
"codec_name"
1097+
)
10911098
assert actual_codec_spec == codec_spec
10921099

10931100
@pytest.mark.skipif(
@@ -1123,61 +1130,51 @@ def test_codec_spec_vs_impl_equivalence(self, tmp_path, codec_spec, codec_impl):
11231130
dest=impl_output, codec=codec_impl
11241131
)
11251132

1126-
assert self._get_codec_spec(spec_output) == codec_spec
1127-
assert self._get_codec_spec(impl_output) == codec_spec
1133+
assert (
1134+
self._get_video_metadata(spec_output, fields=["codec_name"]).get(
1135+
"codec_name"
1136+
)
1137+
== codec_spec
1138+
)
1139+
assert (
1140+
self._get_video_metadata(impl_output, fields=["codec_name"]).get(
1141+
"codec_name"
1142+
)
1143+
== codec_spec
1144+
)
11281145

11291146
frames_spec = self.decode(spec_output).data
11301147
frames_impl = self.decode(impl_output).data
11311148
torch.testing.assert_close(frames_spec, frames_impl, rtol=0, atol=0)
11321149

1133-
def get_video_metadata_from_file(self, file_path):
1134-
"""Helper function to get video metadata from a file using ffprobe.
1135-
1136-
Returns a dict with codec_name, profile, pix_fmt, etc.
1137-
"""
1138-
result = subprocess.run(
1139-
[
1140-
"ffprobe",
1141-
"-v",
1142-
"error",
1143-
"-select_streams",
1144-
"v:0",
1145-
"-show_entries",
1146-
"stream=codec_name,profile,pix_fmt",
1147-
"-of",
1148-
"default=noprint_wrappers=1",
1149-
str(file_path),
1150-
],
1151-
check=True,
1152-
capture_output=True,
1153-
text=True,
1154-
)
1155-
# Parse output like "codec_name=h264\nprofile=Baseline\npix_fmt=yuv420p"
1156-
metadata = {}
1157-
for line in result.stdout.strip().split("\n"):
1158-
if "=" in line:
1159-
key, value = line.split("=", 1)
1160-
metadata[key] = value
1161-
return metadata
1162-
11631150
@pytest.mark.skipif(in_fbcode(), reason="ffprobe not available")
1164-
def test_codec_options_profile(self, tmp_path):
1165-
# Test that we can set the H.264 profile via codec_options
1166-
# and validate it was used by checking with ffprobe.
1151+
@pytest.mark.parametrize(
1152+
"profile,colorspace,color_range",
1153+
[
1154+
("baseline", "bt709", "tv"),
1155+
("main", "bt470bg", "pc"),
1156+
("high", "fcc", "pc"),
1157+
],
1158+
)
1159+
def test_codec_options_utilized(self, tmp_path, profile, colorspace, color_range):
1160+
# Test setting profile, colorspace, and color_range via codec_options is utilized
11671161
source_frames = torch.zeros((5, 3, 64, 64), dtype=torch.uint8)
11681162
encoder = VideoEncoder(frames=source_frames, frame_rate=30)
11691163

1170-
# Encode with baseline profile (explicitly specified via codec_options)
1171-
output_path = tmp_path / "output_baseline.mp4"
1164+
output_path = str(tmp_path / "output.mp4")
11721165
encoder.to_file(
1173-
dest=str(output_path),
1174-
codec_options={"profile": "baseline"},
1166+
dest=output_path,
1167+
codec_options={
1168+
"profile": profile,
1169+
"colorspace": colorspace,
1170+
"color_range": color_range,
1171+
},
11751172
)
1176-
1177-
# Validate the profile was used
1178-
metadata = self.get_video_metadata_from_file(output_path)
1179-
assert metadata.get("codec_name") == "h264"
1180-
assert metadata.get("profile") in (
1181-
"Baseline",
1182-
"Constrained Baseline",
1183-
), f"Expected Baseline profile, got {metadata.get('profile')}"
1173+
metadata = self._get_video_metadata(
1174+
output_path,
1175+
fields=["profile", "color_space", "color_range"],
1176+
)
1177+
# Validate profile (case-insensitive, baseline is reported as "Constrained Baseline")
1178+
assert profile in metadata.get("profile", "").lower()
1179+
assert metadata.get("color_space") == colorspace
1180+
assert metadata.get("color_range") == color_range

0 commit comments

Comments
 (0)