Skip to content

Commit e58cf39

Browse files
author
Molly Xu
committed
add cpp tests
1 parent 868e23e commit e58cf39

File tree

2 files changed

+231
-0
lines changed

2 files changed

+231
-0
lines changed

test/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,22 @@ target_link_libraries(
3434

3535
include(GoogleTest)
3636
gtest_discover_tests(VideoDecoderTest)
37+
38+
39+
add_executable(
40+
MetadataTest
41+
MetadataTest.cpp
42+
)
43+
44+
target_include_directories(MetadataTest SYSTEM PRIVATE ${TORCH_INCLUDE_DIRS})
45+
target_include_directories(MetadataTest SYSTEM PRIVATE ${libav_include_dirs})
46+
target_include_directories(MetadataTest PRIVATE ../)
47+
48+
target_link_libraries(
49+
MetadataTest
50+
${libtorchcodec_library_name}
51+
${libtorchcodec_custom_ops_name}
52+
GTest::gtest_main
53+
)
54+
55+
gtest_discover_tests(MetadataTest)

test/MetadataTest.cpp

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
// Copyright (c) Meta Platforms, Inc. and affiliates.
2+
// All rights reserved.
3+
//
4+
// This source code is licensed under the BSD-style license found in the
5+
// LICENSE file in the root directory of this source tree.
6+
7+
#include "src/torchcodec/_core/Metadata.h"
8+
9+
#include <gtest/gtest.h>
10+
11+
namespace facebook::torchcodec {
12+
13+
// Test that num_frames_from_content always has priority when accessing
14+
// getNumFrames()
15+
TEST(MetadataTest, NumFramesFallbackPriority) {
16+
// in exact mode, both header and content available
17+
{
18+
StreamMetadata metadata;
19+
metadata.numFramesFromHeader = 10;
20+
metadata.numFramesFromContent = 20;
21+
metadata.durationSecondsFromHeader = 4.0;
22+
metadata.averageFpsFromHeader = 30.0;
23+
24+
EXPECT_EQ(metadata.getNumFrames(SeekMode::exact), 20);
25+
}
26+
27+
// in exact mode, only content available
28+
{
29+
StreamMetadata metadata;
30+
metadata.numFramesFromHeader = std::nullopt;
31+
metadata.numFramesFromContent = 10;
32+
metadata.durationSecondsFromHeader = 4.0;
33+
metadata.averageFpsFromHeader = 30.0;
34+
35+
EXPECT_EQ(metadata.getNumFrames(SeekMode::exact), 10);
36+
}
37+
38+
// in approximate mode, header should be used
39+
{
40+
StreamMetadata metadata;
41+
metadata.numFramesFromHeader = 10;
42+
metadata.numFramesFromContent = std::nullopt;
43+
metadata.durationSecondsFromHeader = 4.0;
44+
metadata.averageFpsFromHeader = 30.0;
45+
46+
EXPECT_EQ(metadata.getNumFrames(SeekMode::approximate), 10);
47+
}
48+
}
49+
50+
// Test that if num_frames_from_content and num_frames_from_header are missing,
51+
// getNumFrames() is calculated using average_fps_from_header and
52+
// duration_seconds_from_header in approximate mode
53+
TEST(MetadataTest, CalculateNumFramesUsingFpsAndDuration) {
54+
// both fps and duration available
55+
{
56+
StreamMetadata metadata;
57+
metadata.numFramesFromHeader = std::nullopt;
58+
metadata.numFramesFromContent = std::nullopt;
59+
metadata.averageFpsFromHeader = 60.0;
60+
metadata.durationSecondsFromHeader = 10.0;
61+
62+
EXPECT_EQ(metadata.getNumFrames(SeekMode::approximate), 600);
63+
}
64+
65+
// fps available but duration missing
66+
{
67+
StreamMetadata metadata;
68+
metadata.numFramesFromHeader = std::nullopt;
69+
metadata.numFramesFromContent = std::nullopt;
70+
metadata.averageFpsFromHeader = 60.0;
71+
metadata.durationSecondsFromHeader = std::nullopt;
72+
73+
EXPECT_EQ(metadata.getNumFrames(SeekMode::approximate), std::nullopt);
74+
}
75+
76+
// duration available but fps missing
77+
{
78+
StreamMetadata metadata;
79+
metadata.numFramesFromHeader = std::nullopt;
80+
metadata.numFramesFromContent = std::nullopt;
81+
metadata.averageFpsFromHeader = std::nullopt;
82+
metadata.durationSecondsFromHeader = 10.0;
83+
84+
EXPECT_EQ(metadata.getNumFrames(SeekMode::approximate), std::nullopt);
85+
}
86+
87+
// both missing
88+
{
89+
StreamMetadata metadata;
90+
metadata.numFramesFromHeader = std::nullopt;
91+
metadata.numFramesFromContent = std::nullopt;
92+
metadata.averageFpsFromHeader = std::nullopt;
93+
metadata.durationSecondsFromHeader = std::nullopt;
94+
95+
EXPECT_EQ(metadata.getNumFrames(SeekMode::approximate), std::nullopt);
96+
}
97+
}
98+
99+
// Test that using begin_stream_seconds_from_content and
100+
// end_stream_seconds_from_content to calculate getDurationSeconds() has
101+
// priority. If either value is missing, duration_seconds_from_header is used.
102+
TEST(MetadataTest, DurationSecondsFallback) {
103+
// in exact mode, both begin and end content available, should calculate from
104+
// them
105+
{
106+
StreamMetadata metadata;
107+
metadata.durationSecondsFromHeader = 60.0;
108+
metadata.beginStreamPtsSecondsFromContent = 5.0;
109+
metadata.endStreamPtsSecondsFromContent = 20.0;
110+
111+
EXPECT_NEAR(
112+
metadata.getDurationSeconds(SeekMode::exact).value(), 15.0, 1e-6);
113+
}
114+
115+
// in exact mode, begin content available but end missing, should fall back to
116+
// header
117+
{
118+
StreamMetadata metadata;
119+
metadata.durationSecondsFromHeader = 60.0;
120+
metadata.beginStreamPtsSecondsFromContent = 1.0;
121+
metadata.endStreamPtsSecondsFromContent = std::nullopt;
122+
123+
EXPECT_EQ(metadata.getDurationSeconds(SeekMode::exact), std::nullopt);
124+
}
125+
126+
// Test case 3: end content available but begin missing, should fall back
127+
{
128+
StreamMetadata metadata;
129+
metadata.durationSecondsFromHeader = 60.0;
130+
metadata.beginStreamPtsSecondsFromContent = std::nullopt;
131+
metadata.endStreamPtsSecondsFromContent = 1.0;
132+
133+
EXPECT_EQ(metadata.getDurationSeconds(SeekMode::exact), std::nullopt);
134+
}
135+
136+
// in exact mode, only content values, no header
137+
{
138+
StreamMetadata metadata;
139+
metadata.durationSecondsFromHeader = std::nullopt;
140+
metadata.beginStreamPtsSecondsFromContent = 0.0;
141+
metadata.endStreamPtsSecondsFromContent = 10.0;
142+
143+
EXPECT_NEAR(
144+
metadata.getDurationSeconds(SeekMode::exact).value(), 10.0, 1e-6);
145+
}
146+
147+
// in approximate mode, header value takes priority (ignores content)
148+
{
149+
StreamMetadata metadata;
150+
metadata.durationSecondsFromHeader = 60.0;
151+
metadata.beginStreamPtsSecondsFromContent = 5.0;
152+
metadata.endStreamPtsSecondsFromContent = 20.0;
153+
154+
EXPECT_NEAR(
155+
metadata.getDurationSeconds(SeekMode::approximate).value(), 60.0, 1e-6);
156+
}
157+
}
158+
159+
// Test that duration_seconds is calculated using average_fps_from_header and
160+
// num_frames_from_header if duration_seconds_from_header is missing.
161+
TEST(MetadataTest, CalculateDurationSecondsUsingFpsAndNumFrames) {
162+
// in approximate mode, both num_frames and fps available
163+
{
164+
StreamMetadata metadata;
165+
metadata.durationSecondsFromHeader = std::nullopt;
166+
metadata.numFramesFromHeader = 100;
167+
metadata.averageFpsFromHeader = 10.0;
168+
metadata.beginStreamPtsSecondsFromContent = std::nullopt;
169+
metadata.endStreamPtsSecondsFromContent = std::nullopt;
170+
171+
EXPECT_NEAR(
172+
metadata.getDurationSeconds(SeekMode::approximate).value(), 10.0, 1e-6);
173+
}
174+
175+
// in approximate mode, num_frames available but fps missing
176+
{
177+
StreamMetadata metadata;
178+
metadata.durationSecondsFromHeader = std::nullopt;
179+
metadata.numFramesFromHeader = 100;
180+
metadata.averageFpsFromHeader = std::nullopt;
181+
metadata.beginStreamPtsSecondsFromContent = std::nullopt;
182+
metadata.endStreamPtsSecondsFromContent = std::nullopt;
183+
184+
EXPECT_EQ(metadata.getDurationSeconds(SeekMode::approximate), std::nullopt);
185+
}
186+
187+
// in approximate mode, fps available but num_frames missing
188+
{
189+
StreamMetadata metadata;
190+
metadata.durationSecondsFromHeader = std::nullopt;
191+
metadata.numFramesFromHeader = std::nullopt;
192+
metadata.averageFpsFromHeader = 10.0;
193+
metadata.beginStreamPtsSecondsFromContent = std::nullopt;
194+
metadata.endStreamPtsSecondsFromContent = std::nullopt;
195+
196+
EXPECT_EQ(metadata.getDurationSeconds(SeekMode::approximate), std::nullopt);
197+
}
198+
199+
// in approximate mode, both missing
200+
{
201+
StreamMetadata metadata;
202+
metadata.durationSecondsFromHeader = std::nullopt;
203+
metadata.numFramesFromHeader = std::nullopt;
204+
metadata.averageFpsFromHeader = std::nullopt;
205+
metadata.beginStreamPtsSecondsFromContent = std::nullopt;
206+
metadata.endStreamPtsSecondsFromContent = std::nullopt;
207+
208+
EXPECT_EQ(metadata.getDurationSeconds(SeekMode::approximate), std::nullopt);
209+
}
210+
}
211+
212+
} // namespace facebook::torchcodec

0 commit comments

Comments
 (0)