1+ // SPDX-License-Identifier: Apache-2.0
2+ // Copyright Contributors to the OpenTimelineIO project
3+
4+ #include " opentime/timeRange.h"
5+ #include " utils.h"
6+
7+ #include < opentimelineio/clip.h>
8+ #include < opentimelineio/stack.h>
9+ #include < opentimelineio/track.h>
10+ #include < opentimelineio/stackAlgorithm.h>
11+
12+ #include < iostream>
13+
14+ namespace otime = opentime::OPENTIME_VERSION;
15+ namespace otio = opentimelineio::OPENTIMELINEIO_VERSION;
16+
17+ int
18+ main (int argc, char ** argv)
19+ {
20+ Tests tests;
21+
22+ tests.add_test (
23+ " test_flatten_stack_01" , [] {
24+ using namespace otio ;
25+
26+ otio::RationalTime rt_0_24{0 , 24 };
27+ otio::RationalTime rt_150_24{150 , 24 };
28+ otio::TimeRange tr_0_150_24{rt_0_24, rt_150_24};
29+
30+ // all three clips are identical, but placed such that A is over B and
31+ // has no gap or end over C
32+ // 0 150 300
33+ // [ A ]
34+ // [ B | C ]
35+ //
36+ // should flatten to:
37+ // [ A | C ]
38+
39+ otio::SerializableObject::Retainer<otio::Clip> cl_A =
40+ new otio::Clip (" track1_A" , nullptr , tr_0_150_24);
41+ otio::SerializableObject::Retainer<otio::Clip> cl_B =
42+ new otio::Clip (" track1_B" , nullptr , tr_0_150_24);
43+ otio::SerializableObject::Retainer<otio::Clip> cl_C =
44+ new otio::Clip (" track1_C" , nullptr , tr_0_150_24);
45+
46+ otio::SerializableObject::Retainer<otio::Track> tr_over =
47+ new otio::Track ();
48+ tr_over->append_child (cl_A);
49+
50+ otio::SerializableObject::Retainer<otio::Track> tr_under =
51+ new otio::Track ();
52+ tr_under->append_child (cl_B);
53+ tr_under->append_child (cl_C);
54+
55+ otio::SerializableObject::Retainer<otio::Stack> st =
56+ new otio::Stack ();
57+ st->append_child (tr_under);
58+ st->append_child (tr_over);
59+
60+ auto result = flatten_stack (st);
61+
62+ assertEqual (result->children ()[0 ]->name (), std::string (" track1_A" ));
63+ assertEqual (result->children ().size (), 2 );
64+ assertEqual (result->duration ().value (), 300 );
65+ });
66+
67+ tests.add_test (
68+ " test_flatten_stack_02" , [] {
69+ using namespace otio ;
70+
71+ otio::RationalTime rt_0_24{0 , 24 };
72+ otio::RationalTime rt_150_24{150 , 24 };
73+ otio::TimeRange tr_0_150_24{rt_0_24, rt_150_24};
74+
75+ // all four clips are identical, but placed such that A is over B and
76+ // has no gap or end over C. The bottom track is also shorter.
77+ // 0 150 300
78+ // [ A ]
79+ // [ B | C ]
80+ // [ D ]
81+ //
82+ // should flatten to:
83+ // [ A | C ]
84+
85+ otio::SerializableObject::Retainer<otio::Clip> cl_A =
86+ new otio::Clip (" track1_A" , nullptr , tr_0_150_24);
87+ otio::SerializableObject::Retainer<otio::Clip> cl_B =
88+ new otio::Clip (" track1_B" , nullptr , tr_0_150_24);
89+ otio::SerializableObject::Retainer<otio::Clip> cl_C =
90+ new otio::Clip (" track1_C" , nullptr , tr_0_150_24);
91+ otio::SerializableObject::Retainer<otio::Clip> cl_D =
92+ new otio::Clip (" track1_D" , nullptr , tr_0_150_24);
93+
94+ otio::SerializableObject::Retainer<otio::Track> tr_top =
95+ new otio::Track ();
96+ tr_top->append_child (cl_A);
97+
98+ otio::SerializableObject::Retainer<otio::Track> tr_middle =
99+ new otio::Track ();
100+ tr_middle->append_child (cl_B);
101+ tr_middle->append_child (cl_C);
102+
103+ otio::SerializableObject::Retainer<otio::Track> tr_bottom =
104+ new otio::Track ();
105+
106+ tr_bottom->append_child (cl_D);
107+
108+ otio::SerializableObject::Retainer<otio::Stack> st =
109+ new otio::Stack ();
110+ st->append_child (tr_bottom);
111+ st->append_child (tr_middle);
112+ st->append_child (tr_top);
113+
114+ auto result = flatten_stack (st);
115+
116+ assertEqual (result->children ()[0 ]->name (), std::string (" track1_A" ));
117+ assertEqual (result->children ().size (), 2 );
118+ assertEqual (result->duration ().value (), 300 );
119+ });
120+
121+ tests.add_test (
122+ " test_flatten_stack_03" , [] {
123+ using namespace otio ;
124+
125+ otio::RationalTime rt_0_24{0 , 24 };
126+ otio::RationalTime rt_150_24{150 , 24 };
127+ otio::TimeRange tr_0_150_24{rt_0_24, rt_150_24};
128+
129+ // all three clips are identical but the middle track is empty
130+ // 0 150 300
131+ // [ A ]
132+ // []
133+ // [ B | C ]
134+ //
135+ // should flatten to:
136+ // [ A | C ]
137+
138+ otio::SerializableObject::Retainer<otio::Clip> cl_A =
139+ new otio::Clip (" track1_A" , nullptr , tr_0_150_24);
140+ otio::SerializableObject::Retainer<otio::Clip> cl_B =
141+ new otio::Clip (" track1_B" , nullptr , tr_0_150_24);
142+ otio::SerializableObject::Retainer<otio::Clip> cl_C =
143+ new otio::Clip (" track1_C" , nullptr , tr_0_150_24);
144+
145+ otio::SerializableObject::Retainer<otio::Track> tr_top =
146+ new otio::Track ();
147+ tr_top->append_child (cl_A);
148+
149+ otio::SerializableObject::Retainer<otio::Track> tr_middle =
150+ new otio::Track ();
151+
152+ otio::SerializableObject::Retainer<otio::Track> tr_bottom =
153+ new otio::Track ();
154+
155+ tr_bottom->append_child (cl_B);
156+ tr_bottom->append_child (cl_C);
157+
158+
159+ otio::SerializableObject::Retainer<otio::Stack> st =
160+ new otio::Stack ();
161+ st->append_child (tr_bottom);
162+ st->append_child (tr_middle);
163+ st->append_child (tr_top);
164+
165+ auto result = flatten_stack (st);
166+
167+ assertEqual (result->children ()[0 ]->name (), std::string (" track1_A" ));
168+ assertEqual (result->children ().size (), 2 );
169+ assertEqual (result->duration ().value (), 300 );
170+ });
171+
172+ tests.add_test (
173+ " test_flatten_vector_01" , [] {
174+ using namespace otio ;
175+
176+ otio::RationalTime rt_0_24{0 , 24 };
177+ otio::RationalTime rt_150_24{150 , 24 };
178+ otio::TimeRange tr_0_150_24{rt_0_24, rt_150_24};
179+
180+ // all three clips are identical, but placed such that A is over B and
181+ // has no gap or end over C, tests vector version
182+ // 0 150 300
183+ // [ A ]
184+ // [ B | C ]
185+ //
186+ // should flatten to:
187+ // [ A | C ]
188+
189+ otio::SerializableObject::Retainer<otio::Clip> cl_A =
190+ new otio::Clip (" track1_A" , nullptr , tr_0_150_24);
191+ otio::SerializableObject::Retainer<otio::Clip> cl_B =
192+ new otio::Clip (" track1_B" , nullptr , tr_0_150_24);
193+ otio::SerializableObject::Retainer<otio::Clip> cl_C =
194+ new otio::Clip (" track1_C" , nullptr , tr_0_150_24);
195+
196+ otio::SerializableObject::Retainer<otio::Track> tr_over =
197+ new otio::Track ();
198+ tr_over->append_child (cl_A);
199+
200+ otio::SerializableObject::Retainer<otio::Track> tr_under =
201+ new otio::Track ();
202+ tr_under->append_child (cl_B);
203+ tr_under->append_child (cl_C);
204+
205+ std::vector<Track *> st;
206+ st.push_back (tr_under);
207+ st.push_back (tr_over);
208+
209+ auto result = flatten_stack (st);
210+
211+ assertEqual (result->children ()[0 ]->name (), std::string (" track1_A" ));
212+ assertEqual (result->children ().size (), 2 );
213+ assertEqual (result->duration ().value (), 300 );
214+ });
215+
216+ tests.run (argc, argv);
217+ return 0 ;
218+ }
0 commit comments