3
3
4
4
namespace opentimelineio { namespace OPENTIMELINEIO_VERSION {
5
5
6
+ char constexpr Clip::default_media_key[];
7
+
6
8
Clip::Clip (
7
9
std::string const & name,
8
10
MediaReference* media_reference,
9
11
optional<TimeRange> const & source_range,
10
- AnyDictionary const & metadata)
12
+ AnyDictionary const & metadata,
13
+ std::string const & active_media_reference_key)
11
14
: Parent{ name, source_range, metadata }
15
+ , _active_media_reference_key(active_media_reference_key)
12
16
{
13
17
set_media_reference (media_reference);
14
18
}
@@ -19,33 +23,136 @@ Clip::~Clip()
19
23
MediaReference*
20
24
Clip::media_reference () const noexcept
21
25
{
22
- return _media_reference;
26
+ auto active = _media_references.find (_active_media_reference_key);
27
+ return active == _media_references.end () || !active->second
28
+ ? nullptr
29
+ : active->second ;
30
+ }
31
+
32
+ Clip::MediaReferences
33
+ Clip::media_references () const noexcept
34
+ {
35
+ MediaReferences result;
36
+ for (auto const & m: _media_references)
37
+ {
38
+ result.insert (
39
+ { m.first , dynamic_retainer_cast<MediaReference>(m.second ) });
40
+ }
41
+ return result;
42
+ }
43
+
44
+ template <typename MediaRefMap>
45
+ bool
46
+ Clip::check_for_valid_media_reference_key (
47
+ std::string const & caller,
48
+ std::string const & key,
49
+ MediaRefMap const & media_references,
50
+ ErrorStatus* error_status)
51
+ {
52
+ auto empty_key = media_references.find (" " );
53
+ if (empty_key != media_references.end ())
54
+ {
55
+ if (error_status)
56
+ {
57
+ *error_status = ErrorStatus (
58
+ ErrorStatus::MEDIA_REFERENCES_CONTAIN_EMPTY_KEY,
59
+ caller +
60
+ " failed because the media references contain an empty string key" ,
61
+ this );
62
+ }
63
+ return false ;
64
+ }
65
+
66
+ auto found = media_references.find (key);
67
+ if (found == media_references.end ())
68
+ {
69
+ if (error_status)
70
+ {
71
+ *error_status = ErrorStatus (
72
+ ErrorStatus::MEDIA_REFERENCES_DO_NOT_CONTAIN_ACTIVE_KEY,
73
+ caller +
74
+ " failed because the media references do not contain the active key" ,
75
+ this );
76
+ }
77
+ return false ;
78
+ }
79
+ return true ;
80
+ }
81
+
82
+ void
83
+ Clip::set_media_references (
84
+ MediaReferences const & media_references,
85
+ std::string const & new_active_key,
86
+ ErrorStatus* error_status) noexcept
87
+ {
88
+ if (!check_for_valid_media_reference_key (
89
+ " set_media_references" ,
90
+ new_active_key,
91
+ media_references,
92
+ error_status))
93
+ {
94
+ return ;
95
+ }
96
+
97
+ _media_references.clear ();
98
+ for (auto const & m: media_references)
99
+ {
100
+ _media_references[m.first ] = m.second ? m.second : new MissingReference;
101
+ }
102
+
103
+ _active_media_reference_key = new_active_key;
104
+ }
105
+
106
+ std::string
107
+ Clip::active_media_reference_key () const noexcept
108
+ {
109
+ return _active_media_reference_key;
110
+ }
111
+
112
+ void
113
+ Clip::set_active_media_reference_key (
114
+ std::string const & new_active_key, ErrorStatus* error_status) noexcept
115
+ {
116
+ if (!check_for_valid_media_reference_key (
117
+ " set_active_media_reference_key" ,
118
+ new_active_key,
119
+ _media_references,
120
+ error_status))
121
+ {
122
+ return ;
123
+ }
124
+ _active_media_reference_key = new_active_key;
23
125
}
24
126
25
127
void
26
128
Clip::set_media_reference (MediaReference* media_reference)
27
129
{
28
- _media_reference = media_reference ? media_reference : new MissingReference;
130
+ _media_references[_active_media_reference_key] =
131
+ media_reference ? media_reference : new MissingReference;
29
132
}
30
133
31
134
bool
32
135
Clip::read_from (Reader& reader)
33
136
{
34
- return reader.read (" media_reference" , &_media_reference) &&
137
+ return reader.read (" media_references" , &_media_references) &&
138
+ reader.read (
139
+ " active_media_reference_key" , &_active_media_reference_key) &&
35
140
Parent::read_from (reader);
36
141
}
37
142
38
143
void
39
144
Clip::write_to (Writer& writer) const
40
145
{
41
146
Parent::write_to (writer);
42
- writer.write (" media_reference" , _media_reference);
147
+ writer.write (" media_references" , _media_references);
148
+ writer.write (" active_media_reference_key" , _active_media_reference_key);
43
149
}
44
150
45
151
TimeRange
46
152
Clip::available_range (ErrorStatus* error_status) const
47
153
{
48
- if (!_media_reference)
154
+ auto active_media = media_reference ();
155
+ if (!active_media)
49
156
{
50
157
if (error_status)
51
158
{
@@ -57,7 +164,7 @@ Clip::available_range(ErrorStatus* error_status) const
57
164
return TimeRange ();
58
165
}
59
166
60
- if (!_media_reference ->available_range ())
167
+ if (!active_media ->available_range ())
61
168
{
62
169
if (error_status)
63
170
{
@@ -69,13 +176,14 @@ Clip::available_range(ErrorStatus* error_status) const
69
176
return TimeRange ();
70
177
}
71
178
72
- return _media_reference ->available_range ().value ();
179
+ return active_media ->available_range ().value ();
73
180
}
74
181
75
182
optional<Imath::Box2d>
76
183
Clip::available_image_bounds (ErrorStatus* error_status) const
77
184
{
78
- if (!_media_reference)
185
+ auto active_media = media_reference ();
186
+ if (!active_media)
79
187
{
80
188
*error_status = ErrorStatus (
81
189
ErrorStatus::CANNOT_COMPUTE_BOUNDS,
@@ -84,7 +192,7 @@ Clip::available_image_bounds(ErrorStatus* error_status) const
84
192
return optional<Imath::Box2d>();
85
193
}
86
194
87
- if (!_media_reference. value ->available_image_bounds ())
195
+ if (!active_media ->available_image_bounds ())
88
196
{
89
197
*error_status = ErrorStatus (
90
198
ErrorStatus::CANNOT_COMPUTE_BOUNDS,
@@ -93,7 +201,7 @@ Clip::available_image_bounds(ErrorStatus* error_status) const
93
201
return optional<Imath::Box2d>();
94
202
}
95
203
96
- return _media_reference. value ->available_image_bounds ();
204
+ return active_media ->available_image_bounds ();
97
205
}
98
206
99
207
}} // namespace opentimelineio::OPENTIMELINEIO_VERSION
0 commit comments