Skip to content

Commit 44243bf

Browse files
author
rameshm
committed
Merge remote-tracking branch 'origin' into 1635_fix_flatten_issue
2 parents 3510ade + 68d891a commit 44243bf

File tree

18 files changed

+235
-94
lines changed

18 files changed

+235
-94
lines changed

ADOPTERS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# OpenTimelineIO Adopters
2+
3+
Below is a partial list of organizations and projects that are using OpenTimelineIO. If you would like to be added to this list, please submit a pull request to this file.
4+
5+
| Name | Description |
6+
|------|------------------------------------------------------------------------------------------------------------------------------------------------|
7+
| [Adobe Premiere Pro](https://www.adobe.com/products/premiere.html) | [Timeline import/export](https://community.adobe.com/t5/premiere-pro-beta-discussions/new-in-beta-otio-import-and-export/td-p/14937493) (beta) |
8+
| [AVID Media Composer](https://www.avid.com/media-composer) | Timeline export (preview) |
9+
| [Black Magic Design DaVinci Resolve](https://www.blackmagicdesign.com/products/davinciresolve/) | Timeline import/export |
10+
| [CineSync](https://www.backlight.co/product/cinesync) | Timeline viewing | |
11+
| [ColorFront Transkoder](https://colorfront.com/index.php?page=SOFTWARE&spage=Transkoder) | Timeline import |
12+
| [Nuke Studio](https://www.foundry.com/products/nuke) | Timeline import/export with full timeline round-tripping |
13+
| [Hiero](https://www.foundry.com/products/nuke-family/hiero) | Timeline import/export |
14+
| [OpenRV](https://github.com/AcademySoftwareFoundation/OpenRV) | Timeline import and viewing |

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ exclude readthedocs-conda.yml
1212
exclude .codecov.yml
1313
exclude .gitlab-ci.yml
1414
exclude *.pdf
15+
exclude ADOPTERS.md
1516
exclude CODE_OF_CONDUCT.md
1617
exclude CONTRIBUTING.md
1718
exclude CONTRIBUTORS.md

docs/conf.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@
100100
r'cxx/cxx'
101101
]
102102

103+
# For some reason this URL gives 403 Forbidden when running in github actions
104+
linkcheck_ignore = [r'https://opensource.org/licenses/MIT']
105+
103106
# -- Options for MySt-Parser -----------------------------------------------------------
104107
# https://myst-parser.readthedocs.io/en/latest/sphinx/reference.html
105108

src/opentime/errorStatus.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ ErrorStatus::outcome_to_string(Outcome o)
1313
case OK:
1414
return std::string();
1515
case INVALID_TIMECODE_RATE:
16-
return "invalid timecode rate";
16+
return "SMPTE timecode does not support this rate";
1717
case INVALID_TIMECODE_STRING:
18-
return "string is not a valid timecode string";
18+
return "string is not a SMPTE timecode string";
1919
case TIMECODE_RATE_MISMATCH:
2020
return "timecode specifies a frame higher than its rate";
2121
case INVALID_TIME_STRING:

src/opentime/rationalTime.cpp

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,68 @@ namespace opentime { namespace OPENTIME_VERSION {
1313

1414
RationalTime RationalTime::_invalid_time{ 0, RationalTime::_invalid_rate };
1515

16-
static constexpr std::array<double, 4> dropframe_timecode_rates{ {
17-
// 23.976,
18-
// 23.98,
19-
// 23.97,
20-
// 24000.0/1001.0,
21-
29.97,
16+
static constexpr std::array<double, 2> dropframe_timecode_rates{ {
2217
30000.0 / 1001.0,
23-
59.94,
2418
60000.0 / 1001.0,
2519
} };
2620

21+
// See the official source of these numbers here:
22+
// ST 12-1:2014 - SMPTE Standard - Time and Control Code
23+
// https://ieeexplore.ieee.org/document/7291029
24+
//
2725
static constexpr std::array<double, 11> smpte_timecode_rates{
28-
{ 1.0,
29-
12.0,
30-
24000.0 / 1001.0,
26+
{ 24000.0 / 1001.0,
3127
24.0,
3228
25.0,
3329
30000.0 / 1001.0,
3430
30.0,
31+
48000.0 / 1001.0,
3532
48.0,
3633
50.0,
3734
60000.0 / 1001.0,
38-
60.0 }
39-
};
40-
41-
static constexpr std::array<double, 16> valid_timecode_rates{
42-
{ 1.0,
43-
12.0,
44-
23.97,
45-
23.976,
46-
23.98,
47-
24000.0 / 1001.0,
48-
24.0,
49-
25.0,
50-
29.97,
51-
30000.0 / 1001.0,
52-
30.0,
53-
48.0,
54-
50.0,
55-
59.94,
56-
60000.0 / 1001.0,
57-
60.0 }
35+
60.0
36+
}
5837
};
5938

39+
// deprecated in favor of `is_smpte_timecode_rate`
6040
bool
6141
RationalTime::is_valid_timecode_rate(double fps)
6242
{
63-
auto b = valid_timecode_rates.begin(), e = valid_timecode_rates.end();
43+
return is_smpte_timecode_rate(fps);
44+
}
45+
46+
bool
47+
RationalTime::is_smpte_timecode_rate(double fps)
48+
{
49+
auto b = smpte_timecode_rates.begin(), e = smpte_timecode_rates.end();
6450
return std::find(b, e, fps) != e;
6551
}
6652

53+
// deprecated in favor of `is_smpte_timecode_rate`
6754
double
6855
RationalTime::nearest_valid_timecode_rate(double rate)
56+
{
57+
return nearest_smpte_timecode_rate(rate);
58+
}
59+
60+
double
61+
RationalTime::nearest_smpte_timecode_rate(double rate)
6962
{
7063
double nearest_rate = 0;
7164
double min_diff = std::numeric_limits<double>::max();
72-
for (auto valid_rate: smpte_timecode_rates)
65+
for (auto smpte_rate: smpte_timecode_rates)
7366
{
74-
if (valid_rate == rate)
67+
if (smpte_rate == rate)
7568
{
7669
return rate;
7770
}
78-
auto diff = std::abs(rate - valid_rate);
71+
auto diff = std::abs(rate - smpte_rate);
7972
if (diff >= min_diff)
8073
{
8174
continue;
8275
}
8376
min_diff = diff;
84-
nearest_rate = valid_rate;
77+
nearest_rate = smpte_rate;
8578
}
8679
return nearest_rate;
8780
}
@@ -200,7 +193,7 @@ RationalTime::from_timecode(
200193
double rate,
201194
ErrorStatus* error_status)
202195
{
203-
if (!RationalTime::is_valid_timecode_rate(rate))
196+
if (!RationalTime::is_smpte_timecode_rate(rate))
204197
{
205198
if (error_status)
206199
{
@@ -331,7 +324,7 @@ RationalTime::from_time_string(
331324
double rate,
332325
ErrorStatus* error_status)
333326
{
334-
if (!RationalTime::is_valid_timecode_rate(rate))
327+
if (!RationalTime::is_smpte_timecode_rate(rate))
335328
{
336329
set_error(
337330
time_string,
@@ -460,7 +453,12 @@ RationalTime::to_timecode(
460453
return std::string();
461454
}
462455

463-
if (!is_valid_timecode_rate(rate))
456+
// It is common practice to use truncated or rounded values
457+
// like 29.97 instead of exact SMPTE rates like 30000/1001
458+
// so as a convenience we will snap the rate to the nearest
459+
// SMPTE rate if it is close enough.
460+
double nearest_smpte_rate = nearest_smpte_timecode_rate(rate);
461+
if (abs(nearest_smpte_rate - rate) > 0.1)
464462
{
465463
if (error_status)
466464
{
@@ -469,6 +467,9 @@ RationalTime::to_timecode(
469467
return std::string();
470468
}
471469

470+
// Let's assume this is the rate instead of the given rate.
471+
rate = nearest_smpte_rate;
472+
472473
bool rate_is_dropframe = is_dropframe_rate(rate);
473474
if (drop_frame == IsDropFrameRate::ForceYes and not rate_is_dropframe)
474475
{
@@ -504,11 +505,11 @@ RationalTime::to_timecode(
504505
}
505506
else
506507
{
507-
if ((rate == 29.97) or (rate == 30000 / 1001.0))
508+
if (rate == 30000 / 1001.0)
508509
{
509510
dropframes = 2;
510511
}
511-
else if (rate == 59.94)
512+
else if (rate == 60000 / 1001.0)
512513
{
513514
dropframes = 4;
514515
}
@@ -582,7 +583,7 @@ RationalTime::to_nearest_timecode(
582583
{
583584
*error_status = ErrorStatus();
584585

585-
double nearest_rate = nearest_valid_timecode_rate(rate);
586+
double nearest_rate = nearest_smpte_timecode_rate(rate);
586587

587588
return to_timecode(nearest_rate, drop_frame, error_status);
588589
}

src/opentime/rationalTime.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,20 @@ class RationalTime
171171
start_time._rate };
172172
}
173173

174-
/// @brief Returns true if the rate is valid for use with timecode.
174+
/// @brief Returns true is the rate is supported by SMPTE timecode.
175+
[[deprecated("Use is_smpte_timecode_rate() instead")]]
175176
static bool is_valid_timecode_rate(double rate);
176177

177-
/// @brief Returns the first valid timecode rate that has the least
178-
/// difference from rate.
178+
/// @brief Returns true is the rate is supported by SMPTE timecode.
179+
static bool is_smpte_timecode_rate(double rate);
180+
181+
/// @brief Returns the SMPTE timecode rate nearest to the given rate.
182+
[[deprecated("Use nearest_smpte_timecode_rate() instead")]]
179183
static double nearest_valid_timecode_rate(double rate);
180184

185+
/// @brief Returns the SMPTE timecode rate nearest to the given rate.
186+
static double nearest_smpte_timecode_rate(double rate);
187+
181188
/// @brief Convert a frame number and rate into a time.
182189
static constexpr RationalTime
183190
from_frames(double frame, double rate) noexcept

src/opentimelineio/clip.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ Clip::Clip(
1313
MediaReference* media_reference,
1414
std::optional<TimeRange> const& source_range,
1515
AnyDictionary const& metadata,
16+
std::vector<Effect*> const& effects,
17+
std::vector<Marker*> const& markers,
1618
std::string const& active_media_reference_key)
17-
: Parent{ name, source_range, metadata }
19+
: Parent{ name, source_range, metadata, effects, markers }
1820
, _active_media_reference_key(active_media_reference_key)
1921
{
2022
set_media_reference(media_reference);

src/opentimelineio/clip.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class Clip : public Item
2727
MediaReference* media_reference = nullptr,
2828
std::optional<TimeRange> const& source_range = std::nullopt,
2929
AnyDictionary const& metadata = AnyDictionary(),
30+
std::vector<Effect*> const& effects = std::vector<Effect*>(),
31+
std::vector<Marker*> const& markers = std::vector<Marker*>(),
3032
std::string const& active_media_reference_key = default_media_key);
3133

3234
void set_media_reference(MediaReference* media_reference);

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,22 @@ Compute the duration of samples from first to last (including last). This is not
102102
103103
For example, the duration of a clip from frame 10 to frame 15 is 6 frames. Result will be in the rate of start_time.
104104
)docstring")
105-
.def_static("is_valid_timecode_rate", &RationalTime::is_valid_timecode_rate, "rate"_a, "Returns true if the rate is valid for use with timecode.")
105+
.def_static("is_valid_timecode_rate", &RationalTime::is_valid_timecode_rate, "rate"_a,
106+
"Deprecated. Please use `is_smpte_timecode_rate` instead. This function will be removed in a future release.")
107+
.def_static("is_smpte_timecode_rate", &RationalTime::is_smpte_timecode_rate, "rate"_a,
108+
"Returns true if the rate is valid for use with SMPTE timecode.")
106109
.def_static("nearest_valid_timecode_rate", &RationalTime::nearest_valid_timecode_rate, "rate"_a,
107-
"Returns the first valid timecode rate that has the least difference from the given value.")
108-
.def_static("from_frames", &RationalTime::from_frames, "frame"_a, "rate"_a, "Turn a frame number and rate into a :class:`~RationalTime` object.")
110+
"Deprecated. Please use `nearest_smpte_timecode_rate` instead. This function will be removed in a future release.")
111+
.def_static("nearest_smpte_timecode_rate", &RationalTime::nearest_smpte_timecode_rate, "rate"_a,
112+
"Returns the first SMPTE timecode rate that has the least difference from the given value.")
113+
.def_static("from_frames", &RationalTime::from_frames, "frame"_a, "rate"_a,
114+
"Turn a frame number and rate into a :class:`~RationalTime` object.")
109115
.def_static("from_seconds", static_cast<RationalTime (*)(double, double)> (&RationalTime::from_seconds), "seconds"_a, "rate"_a)
110116
.def_static("from_seconds", static_cast<RationalTime (*)(double)> (&RationalTime::from_seconds), "seconds"_a)
111-
.def("to_frames", (int (RationalTime::*)() const) &RationalTime::to_frames, "Returns the frame number based on the current rate.")
112-
.def("to_frames", (int (RationalTime::*)(double) const) &RationalTime::to_frames, "rate"_a, "Returns the frame number based on the given rate.")
117+
.def("to_frames", (int (RationalTime::*)() const) &RationalTime::to_frames,
118+
"Returns the frame number based on the current rate.")
119+
.def("to_frames", (int (RationalTime::*)(double) const) &RationalTime::to_frames, "rate"_a,
120+
"Returns the frame number based on the given rate.")
113121
.def("to_seconds", &RationalTime::to_seconds)
114122
.def("to_timecode", [](RationalTime rt, double rate, std::optional<bool> drop_frame) {
115123
return rt.to_timecode(

src/py-opentimelineio/opentimelineio-bindings/otio_bindings.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "opentimelineio/typeRegistry.h"
1515
#include "opentimelineio/stackAlgorithm.h"
1616

17+
#include <ImathBox.h>
18+
1719
namespace py = pybind11;
1820
using namespace pybind11::literals;
1921

@@ -270,6 +272,8 @@ PYBIND11_MODULE(_otio, m) {
270272
.def(py::init([](RationalTime rt) { return new PyAny(rt); }))
271273
.def(py::init([](TimeRange tr) { return new PyAny(tr); }))
272274
.def(py::init([](TimeTransform tt) { return new PyAny(tt); }))
275+
.def(py::init([](IMATH_NAMESPACE::V2d v2d) { return new PyAny(v2d); }))
276+
.def(py::init([](IMATH_NAMESPACE::Box2d box2d) { return new PyAny(box2d); }))
273277
.def(py::init([](AnyVectorProxy* p) { return new PyAny(p->fetch_any_vector()); }))
274278
.def(py::init([](AnyDictionaryProxy* p) { return new PyAny(p->fetch_any_dictionary()); }))
275279
;

0 commit comments

Comments
 (0)