Skip to content

Commit cb7ff17

Browse files
committed
small fixes, reuse _get_video_metadata
1 parent bcc8949 commit cb7ff17

File tree

3 files changed

+13
-30
lines changed

3 files changed

+13
-30
lines changed

src/torchcodec/_core/Encoder.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,11 @@ void sortCodecOptions(
644644
}
645645

646646
void validateFrameRate(int frameRate) {
647-
TORCH_CHECK(frameRate > 0, "frame_rate=", frameRate, " must be > 0.");
647+
TORCH_CHECK(
648+
frameRate > 0,
649+
"Invalid frame_rate: ",
650+
frameRate,
651+
". Frame rate must be a positive integer.");
648652
}
649653
} // namespace
650654

@@ -796,7 +800,6 @@ void VideoEncoder::initializeEncoder(
796800
avCodecContext_->width = outWidth_;
797801
avCodecContext_->height = outHeight_;
798802
avCodecContext_->pix_fmt = outPixelFormat_;
799-
// TODO-VideoEncoder: Verify that frame_rate and time_base are correct
800803
avCodecContext_->time_base = {1, outFrameRate_};
801804
avCodecContext_->framerate = {outFrameRate_, 1};
802805

src/torchcodec/encoders/_video_encoder.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def to_file(
6767
encoder options to pass, e.g. ``{"qp": 5, "tune": "film"}``.
6868
Values will be converted to strings before passing to the encoder.
6969
frame_rate (int, optional): The frame rate of the output video. If not specified,
70-
uses the frame rate provided to the VideoEncoder constructor.
70+
uses the frame rate of the input ``frames``.
7171
"""
7272
preset = str(preset) if isinstance(preset, int) else preset
7373
_core.encode_video_to_file(
@@ -116,7 +116,7 @@ def to_tensor(
116116
encoder options to pass, e.g. ``{"qp": 5, "tune": "film"}``.
117117
Values will be converted to strings before passing to the encoder.
118118
frame_rate (int, optional): The frame rate of the output video. If not specified,
119-
uses the frame rate provided to the VideoEncoder constructor.
119+
uses the frame rate of the input ``frames``.
120120
121121
Returns:
122122
Tensor: The raw encoded bytes as 1D uint8 Tensor.
@@ -174,7 +174,7 @@ def to_file_like(
174174
encoder options to pass, e.g. ``{"qp": 5, "tune": "film"}``.
175175
Values will be converted to strings before passing to the encoder.
176176
frame_rate (int, optional): The frame rate of the output video. If not specified,
177-
uses the frame rate provided to the VideoEncoder constructor.
177+
uses the frame rate of the input ``frames``.
178178
"""
179179
preset = str(preset) if isinstance(preset, int) else preset
180180
_core.encode_video_to_file_like(

test/test_encoders.py

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def test_bad_input_parameterized(self, tmp_path, method):
659659
):
660660
encoder.to_tensor(format="mp4", preset="fake_preset")
661661

662-
with pytest.raises(RuntimeError, match=r"frame_rate"):
662+
with pytest.raises(RuntimeError, match="Invalid frame_rate: "):
663663
encoder = VideoEncoder(
664664
frames=torch.zeros((5, 3, 64, 64), dtype=torch.uint8),
665665
frame_rate=30,
@@ -1191,29 +1191,6 @@ def test_extra_options_utilized(self, tmp_path, profile, colorspace, color_range
11911191
@pytest.mark.parametrize("output_frame_rate", [10, 60, None])
11921192
def test_frame_rate_parameter(self, tmp_path, method, output_frame_rate):
11931193

1194-
# Use ffprobe to get frame rate
1195-
def get_frame_rate(file_path):
1196-
result = subprocess.run(
1197-
[
1198-
"ffprobe",
1199-
"-v",
1200-
"error",
1201-
"-select_streams",
1202-
"v:0",
1203-
"-show_entries",
1204-
"stream=r_frame_rate",
1205-
"-of",
1206-
"default=noprint_wrappers=1:nokey=1",
1207-
str(file_path),
1208-
],
1209-
capture_output=True,
1210-
check=True,
1211-
text=True,
1212-
)
1213-
# Frame rate is returned as a fraction like "60/1"
1214-
numerator, denominator = result.stdout.strip().split("/")
1215-
return int(numerator) / int(denominator)
1216-
12171194
frames = (
12181195
VideoDecoder(TEST_SRC_2_720P.path)
12191196
.get_frames_in_range(start=0, stop=60)
@@ -1245,7 +1222,10 @@ def get_frame_rate(file_path):
12451222
else:
12461223
raise ValueError(f"Unknown method: {method}")
12471224

1248-
actual_frame_rate = get_frame_rate(output_path)
1225+
metadata = self._get_video_metadata(output_path, ["r_frame_rate"])
1226+
# Frame rate is returned as a fraction like "60/1"
1227+
numerator, denominator = metadata["r_frame_rate"].split("/")
1228+
actual_frame_rate = int(numerator) / int(denominator)
12491229
# Ensure frame_rate=None uses the input_frame_rate
12501230
if output_frame_rate is None:
12511231
output_frame_rate = input_frame_rate

0 commit comments

Comments
 (0)