Skip to content

Commit 2988f31

Browse files
committed
WIP
1 parent 721c315 commit 2988f31

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/torchcodec/_core/_metadata.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,16 @@ def __repr__(self):
4646

4747
@dataclass
4848
class VideoStreamMetadata(StreamMetadata):
49-
"""Metadata of a single video stream."""
49+
"""Metadata of a single video stream.
50+
51+
.. note::
52+
In general the ``*from_content`` metadata are more accurate than their
53+
``*from_header`` counterparts, since headers may sometime be incorrect.
54+
In some rare cases however, e.g. when a video is incorrectly encoded
55+
with wrong packet :term:`pts` values, it's possible for the
56+
``*from_content`` metadata to be misleading.
57+
58+
"""
5059

5160
begin_stream_seconds_from_content: Optional[float]
5261
"""Beginning of the stream, in seconds (float or None).
@@ -142,6 +151,9 @@ def average_fps(self) -> Optional[float]:
142151
self.end_stream_seconds_from_content is None
143152
or self.begin_stream_seconds_from_content is None
144153
or self.num_frames is None
154+
# Avoid ZeroDivisionError
155+
or self.end_stream_seconds_from_content
156+
== self.begin_stream_seconds_from_content
145157
):
146158
return self.average_fps_from_header
147159
return self.num_frames / (

test/test_decoders.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,31 @@ def get_some_frames(decoder):
986986
assert_frames_equal(ref_frame3, frames[1].data)
987987
assert_frames_equal(ref_frame5, frames[2].data)
988988

989+
def test_video_with_bad_packet_pts_metadata(self):
990+
path = "/home/nicolashug/Downloads/sample_video_2.avi"
991+
992+
approx_metadata = VideoDecoder(path, seek_mode="approximate").metadata
993+
exact_metadata = VideoDecoder(path, seek_mode="exact").metadata
994+
995+
INT64_MIN_SECONDS = -3.0830212936561926e17
996+
997+
assert approx_metadata.duration_seconds_from_header == 9.02507
998+
assert approx_metadata.duration_seconds == 9.02507
999+
assert exact_metadata.duration_seconds_from_header == 9.02507
1000+
assert exact_metadata.duration_seconds == 0
1001+
1002+
assert approx_metadata.begin_stream_seconds_from_header == 0
1003+
assert approx_metadata.begin_stream_seconds_from_content is None
1004+
assert approx_metadata.begin_stream_seconds == 0
1005+
assert exact_metadata.begin_stream_seconds_from_header == 0
1006+
assert exact_metadata.begin_stream_seconds_from_content == INT64_MIN_SECONDS
1007+
assert exact_metadata.begin_stream_seconds == INT64_MIN_SECONDS
1008+
1009+
assert approx_metadata.end_stream_seconds_from_content is None
1010+
assert approx_metadata.end_stream_seconds == 9.02507
1011+
assert exact_metadata.end_stream_seconds_from_content == INT64_MIN_SECONDS
1012+
assert exact_metadata.end_stream_seconds == INT64_MIN_SECONDS
1013+
9891014

9901015
class TestAudioDecoder:
9911016
@pytest.mark.parametrize("asset", (NASA_AUDIO, NASA_AUDIO_MP3, SINE_MONO_S32))

0 commit comments

Comments
 (0)