@@ -15,22 +15,26 @@ namespace otime = opentime::OPENTIME_VERSION;
15
15
using otime::RationalTime;
16
16
using otime::TimeRange;
17
17
18
- std::ostream& operator << (std::ostream& os, const RationalTime& value)
18
+ namespace opentimelineio { namespace OPENTIMELINEIO_VERSION { namespace algo {
19
+
20
+
21
+ namespace
19
22
{
20
- os << std::fixed << value.value () << " /" << value.rate ();
21
- return os;
22
- }
23
23
24
- std::ostream& operator << (std::ostream& os, const TimeRange& value)
24
+ std::vector<SerializableObject::Retainer<Item> >
25
+ find_items_in_composition (
26
+ Composition* composition,
27
+ RationalTime const & time,
28
+ ErrorStatus* error_status)
25
29
{
26
- os << std::fixed << value.start_time ().value () << " /" <<
27
- value.duration ().value () << " /" <<
28
- value.duration ().rate ();
29
- return os;
30
+ // Find the item to slice.
31
+ TimeRange search_range (time, RationalTime (1.0 , time.rate ()));
32
+ return composition->find_children <Item>(error_status, search_range, true );
30
33
}
31
34
32
- namespace opentimelineio { namespace OPENTIMELINEIO_VERSION { namespace algo {
33
-
35
+ } // namespace
36
+
37
+
34
38
void
35
39
overwrite (
36
40
Item* item,
@@ -65,26 +69,37 @@ overwrite(
65
69
composition->find_children <Item>(error_status, range, true );
66
70
TimeRange item_range =
67
71
composition->trimmed_range_of_child (items.front ()).value ();
68
- if (1 == items.size () && item_range.contains (range))
72
+ if (1 == items.size () && item_range.contains (range, 0.0 ))
69
73
{
70
74
// The item overwrites a portion inside an item.
71
75
const RationalTime first_duration =
72
76
range.start_time () - item_range.start_time ();
73
77
const RationalTime second_duration =
74
78
item_range.duration () - range.duration () - first_duration;
75
- auto second_item = dynamic_cast <Item*>(items.front ()->clone ());
76
79
int insert_index = composition->index_of_child (items.front ()) + 1 ;
77
80
TimeRange trimmed_range = items.front ()->trimmed_range ();
78
81
TimeRange source_range (trimmed_range.start_time (), first_duration);
79
- items.front ()->set_source_range (source_range);
80
- ++insert_index;
82
+ if (first_duration.value () <= 0.0 )
83
+ {
84
+ --insert_index;
85
+ composition->remove_child (insert_index);
86
+ }
87
+ else
88
+ {
89
+ items.front ()->set_source_range (source_range);
90
+ ++insert_index;
91
+ }
81
92
composition->insert_child (insert_index, item);
82
- ++insert_index;
83
- trimmed_range = second_item->trimmed_range ();
84
- source_range =
85
- TimeRange (trimmed_range.start_time (), second_duration);
86
- second_item->set_source_range (source_range);
87
- composition->insert_child (insert_index, second_item);
93
+ if (second_duration.value () > 0.0 )
94
+ {
95
+ auto second_item = dynamic_cast <Item*>(items.front ()->clone ());
96
+ trimmed_range = second_item->trimmed_range ();
97
+ source_range =
98
+ TimeRange (trimmed_range.start_time (), second_duration);
99
+ ++insert_index;
100
+ second_item->set_source_range (source_range);
101
+ composition->insert_child (insert_index, second_item);
102
+ }
88
103
}
89
104
else
90
105
{
@@ -160,10 +175,9 @@ insert(
160
175
Item* fill_template,
161
176
ErrorStatus* error_status)
162
177
{
163
- // Find the item to insert into (will be split).
164
- auto item = dynamic_retainer_cast<Item>(
165
- composition->child_at_time (time, error_status, true ));
166
- if (!item)
178
+ // Find the item to insert into.
179
+ auto items = find_items_in_composition (composition, time, error_status);
180
+ if (items.empty ())
167
181
{
168
182
const TimeRange composition_range = composition->trimmed_range ();
169
183
if (time >= composition_range.end_time_exclusive ())
@@ -188,6 +202,13 @@ insert(
188
202
composition->insert_child (0 , insert_item);
189
203
return ;
190
204
}
205
+ if (items.size () > 1 )
206
+ {
207
+ if (error_status)
208
+ *error_status = ErrorStatus::INTERNAL_ERROR;
209
+ return ;
210
+ }
211
+ auto item = items.front ();
191
212
192
213
const int index = composition->index_of_child (item);
193
214
const TimeRange range = composition->trimmed_range_of_child_at_index (index);
@@ -208,7 +229,7 @@ insert(
208
229
composition->insert_child (insert_index, insert_item);
209
230
const TimeRange insert_range = composition->trimmed_range_of_child_at_index (insert_index);
210
231
211
- // Second item from splittin item
232
+ // Second item from splitting item
212
233
if (split)
213
234
{
214
235
const TimeRange second_source_range (
@@ -301,9 +322,7 @@ slice(
301
322
bool const remove_transitions,
302
323
ErrorStatus* error_status)
303
324
{
304
- // Find the item to slice.
305
- TimeRange search_range (time, RationalTime (1.0 , time.rate ()));
306
- auto items = composition->find_children <Item>(error_status, search_range, true );
325
+ auto items = find_items_in_composition (composition, time, error_status);
307
326
if (items.empty ())
308
327
{
309
328
if (error_status)
@@ -316,8 +335,8 @@ slice(
316
335
*error_status = ErrorStatus::INTERNAL_ERROR;
317
336
return ;
318
337
}
319
- auto item = items[ 0 ] ;
320
-
338
+ auto item = items. front () ;
339
+
321
340
const int index = composition->index_of_child (item);
322
341
const TimeRange range = composition->trimmed_range_of_child_at_index (index);
323
342
@@ -597,52 +616,59 @@ fill(
597
616
ReferencePoint const reference_point,
598
617
ErrorStatus* error_status)
599
618
{
600
- // Find the item to insert/overwrite/fit .
619
+ // Find the gap to replace .
601
620
auto gap = dynamic_retainer_cast<Gap>(
602
621
track->child_at_time (track_time, error_status, true ));
603
622
if (!gap)
604
623
{
605
624
if (error_status)
606
- *error_status = ErrorStatus::NOT_AN_ITEM ;
625
+ *error_status = ErrorStatus::NOT_A_GAP ;
607
626
return ;
608
627
}
609
628
610
- const TimeRange clip_range = item->trimmed_range ();
611
- const TimeRange gap_range = gap->trimmed_range ();
612
- const TimeRange gap_track_range =
613
- track-> trimmed_range_of_child (gap). value ();
629
+ const TimeRange clip_range = item->trimmed_range ();
630
+ const TimeRange gap_range = gap->trimmed_range ();
631
+ TimeRange gap_track_range = track-> trimmed_range_of_child (gap). value ();
632
+ RationalTime duration = clip_range. duration ();
614
633
615
634
switch (reference_point)
616
635
{
617
636
case ReferencePoint::Sequence: {
618
637
RationalTime start_time = clip_range.start_time ();
619
- RationalTime duration = clip_range. duration ();
638
+ const RationalTime gap_start_time = gap_range. start_time ();
620
639
auto track_item = dynamic_cast <Item*>(item->clone ());
621
640
622
641
// Check if start time is less than gap's start time (trim it if so)
623
- if (start_time < gap_range. start_time () )
642
+ if (start_time < gap_start_time )
624
643
{
625
- start_time = gap_range.start_time ();
644
+ duration -= gap_start_time - start_time;
645
+ start_time = gap_start_time;
626
646
}
627
647
628
- // Check if duration is longer (trim it if it is)
629
- if (clip_range.end_time_exclusive () >
630
- gap_range.end_time_exclusive ())
648
+ // Check if end time is longer (trim it if it is)
649
+ if (clip_range.end_time_exclusive ()
650
+ > gap_range.end_time_exclusive ())
631
651
{
632
652
duration = gap_range.end_time_exclusive () - start_time;
633
653
}
634
654
const TimeRange new_clip_range (start_time, duration);
635
655
track_item->set_source_range (new_clip_range);
636
- const TimeRange time_range (
637
- track_time,
638
- gap_track_range.end_time_exclusive () - track_time);
656
+
657
+ if (duration
658
+ > gap_track_range.end_time_exclusive () - track_time)
659
+ {
660
+ duration =
661
+ gap_track_range.end_time_exclusive () - track_time;
662
+ }
663
+
664
+ const TimeRange time_range (track_time, duration);
639
665
overwrite (track_item, track, time_range, nullptr , error_status);
640
666
return ;
641
667
}
642
668
643
669
case ReferencePoint::Fit: {
644
670
const double pct = gap_range.duration ().to_seconds ()
645
- / clip_range. duration () .to_seconds ();
671
+ / duration.to_seconds ();
646
672
const std::string& name = item->name ();
647
673
LinearTimeWarp* timeWarp =
648
674
new LinearTimeWarp (name, name + " _timeWarp" , pct);
@@ -658,9 +684,7 @@ fill(
658
684
659
685
case ReferencePoint::Source:
660
686
default : {
661
- const TimeRange time_range (
662
- track_time,
663
- track_time + clip_range.duration () - clip_range.start_time ());
687
+ const TimeRange time_range (track_time, duration);
664
688
overwrite (item, track, time_range, nullptr , error_status);
665
689
return ;
666
690
}
0 commit comments