Skip to content

Commit 1e44ca2

Browse files
authored
Add nearest_valid_timecode_rate (#1181)
Added useful nearest_valid_timecode_rate in lieu of access to the list in Python.
1 parent a79bc1e commit 1e44ca2

File tree

4 files changed

+62
-15
lines changed

4 files changed

+62
-15
lines changed

src/opentime/rationalTime.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,19 @@ static constexpr std::array<double, 4> dropframe_timecode_rates{ {
2121
60000.0 / 1001.0,
2222
} };
2323

24-
// currently unused:
25-
/*
26-
static constexpr std::array<double, 10> non_dropframe_timecode_rates
27-
{{ 1,
28-
12,
29-
23.976,
30-
23.98,
31-
24,
32-
25,
33-
30,
34-
48,
35-
50,
36-
60
37-
}};
38-
*/
24+
static constexpr std::array<double, 11> smpte_timecode_rates{
25+
{ 1.0,
26+
12.0,
27+
24000.0 / 1001.0,
28+
24.0,
29+
25.0,
30+
30000.0 / 1001.0,
31+
30.0,
32+
48.0,
33+
50.0,
34+
60000.0 / 1001.0,
35+
60.0 }
36+
};
3937

4038
static constexpr std::array<double, 16> valid_timecode_rates{
4139
{ 1.0,
@@ -63,6 +61,28 @@ RationalTime::is_valid_timecode_rate(double fps)
6361
return std::find(b, e, fps) != e;
6462
}
6563

64+
double
65+
RationalTime::nearest_valid_timecode_rate(double rate)
66+
{
67+
double nearest_rate = 0;
68+
double min_diff = std::numeric_limits<double>::max();
69+
for (auto valid_rate : smpte_timecode_rates)
70+
{
71+
if (valid_rate == rate)
72+
{
73+
return rate;
74+
}
75+
auto diff = std::abs(rate - valid_rate);
76+
if (diff >= min_diff)
77+
{
78+
continue;
79+
}
80+
min_diff = diff;
81+
nearest_rate = valid_rate;
82+
}
83+
return nearest_rate;
84+
}
85+
6686
static bool
6787
is_dropframe_rate(double rate)
6888
{

src/opentime/rationalTime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ class RationalTime
101101

102102
static bool is_valid_timecode_rate(double rate);
103103

104+
static double nearest_valid_timecode_rate(double rate);
105+
104106
static constexpr RationalTime
105107
from_frames(double frame, double rate) noexcept
106108
{

src/py-opentimelineio/opentime-bindings/opentime_rationalTime.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ void opentime_rationalTime_bindings(py::module m) {
8282
.def_static("duration_from_start_end_time_inclusive", &RationalTime::duration_from_start_end_time_inclusive,
8383
"start_time"_a, "end_time_inclusive"_a)
8484
.def_static("is_valid_timecode_rate", &RationalTime::is_valid_timecode_rate, "rate"_a)
85+
.def_static("nearest_valid_timecode_rate", &RationalTime::nearest_valid_timecode_rate, "rate"_a,
86+
R"docstring(Returns the first valid timecode rate that has the least difference from the given value.)docstring")
8587
.def_static("from_frames", &RationalTime::from_frames, "frame"_a, "rate"_a)
8688
.def_static("from_seconds", static_cast<RationalTime (*)(double, double)> (&RationalTime::from_seconds), "seconds"_a, "rate"_a)
8789
.def_static("from_seconds", static_cast<RationalTime (*)(double)> (&RationalTime::from_seconds), "seconds"_a)

tests/test_opentime.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,29 @@ def test_passing_ndf_tc_at_df_rate(self):
685685
t2 = otio.opentime.from_timecode(NDF_TC, 29.97)
686686
self.assertEqual(t2.value, frames)
687687

688+
def test_nearest_valid_timecode_rate(self):
689+
invalid_valid_rates = (
690+
(23.97602397602397, 24000.0 / 1001.0),
691+
(23.97, 24000.0 / 1001.0),
692+
(23.976, 24000.0 / 1001.0),
693+
(23.98, 24000.0 / 1001.0),
694+
(29.97, 30000.0 / 1001.0),
695+
(59.94, 60000.0 / 1001.0),
696+
)
697+
698+
for invalid_rate, nearest_valid_rate in invalid_valid_rates:
699+
self.assertTrue(
700+
otio.opentime.RationalTime.is_valid_timecode_rate(
701+
nearest_valid_rate
702+
)
703+
)
704+
self.assertEqual(
705+
otio.opentime.RationalTime.nearest_valid_timecode_rate(
706+
invalid_rate
707+
),
708+
nearest_valid_rate,
709+
)
710+
688711

689712
class TestTimeTransform(unittest.TestCase):
690713

0 commit comments

Comments
 (0)