Skip to content

Commit

Permalink
Prevent stranded clips from appearing in the top level stack. (#440)
Browse files Browse the repository at this point in the history
* Add more unit tests specifically around simplifying specific structures.
* Ensure that the resulting AAF doesn't have any orphaned clips in the top level stack.
  • Loading branch information
ssteinbach committed Mar 6, 2019
1 parent 88089b1 commit e164549
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 20 deletions.
17 changes: 17 additions & 0 deletions opentimelineio_contrib/adapters/advanced_authoring_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,8 @@ def _simplify(thing):
isinstance(child, otio.schema.Track)
and len(child) == 1
and isinstance(child[0], otio.schema.Stack)
and child[0]
and isinstance(child[0][0], otio.schema.Track)
)
)
):
Expand Down Expand Up @@ -783,6 +785,21 @@ def _simplify(thing):
)
return result

# if thing is the top level stack, all of its children must be in tracks
if isinstance(thing, otio.schema.Stack) and thing.parent() is None:
children_needing_tracks = []
for child in thing:
if isinstance(child, otio.schema.Track):
continue
children_needing_tracks.append(child)

for child in children_needing_tracks:
orig_index = thing.index(child)
del thing[orig_index]
new_track = otio.schema.Track()
new_track.append(child)
thing.insert(orig_index, new_track)

return thing


Expand Down
107 changes: 87 additions & 20 deletions opentimelineio_contrib/adapters/tests/test_aaf_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,26 +762,6 @@ def test_essence_group(self):
timeline.duration()
)

def test_simplify_top_level_track(self):
"""Test for cases where a track has a single item but should not be
collapsed because it is the the last track in the stack ie:
TL
tracks Stack
track1
clip
in this case, track1 should not be pruned.
"""

# get the simplified form of the clip
tl = otio.adapters.read_from_file(ONE_AUDIO_CLIP_PATH, simplify=True)

# ensure that we end up with a track that contains a clip
self.assertEqual(type(tl.tracks[0]), otio.schema.Track)
self.assertEqual(tl.tracks[0].kind, otio.schema.TrackKind.Audio)
self.assertEqual(type(tl.tracks[0][0]), otio.schema.Clip)

def test_aaf_writer_simple(self):
aaf_path = SIMPLE_EXAMPLE_PATH
timeline = otio.adapters.read_from_file(aaf_path, simplify=True)
Expand Down Expand Up @@ -1100,5 +1080,92 @@ def test_aaf_writer_transitions(self):
# self.assertEqual(len(track), 5)


class SimplifyTests(unittest.TestCase):
def test_simplify_top_level_track(self):
"""Test for cases where a track has a single item but should not be
collapsed because it is the the last track in the stack ie:
TL
tracks Stack
track1
clip
in this case, track1 should not be pruned.
"""

# get the simplified form of the clip
tl = otio.adapters.read_from_file(ONE_AUDIO_CLIP_PATH, simplify=True)

# ensure that we end up with a track that contains a clip
self.assertEqual(type(tl.tracks[0]), otio.schema.Track)
self.assertEqual(tl.tracks[0].kind, otio.schema.TrackKind.Audio)
self.assertEqual(type(tl.tracks[0][0]), otio.schema.Clip)

def test_simplify_track_stack_track(self):
tl = otio.schema.Timeline()
tl.tracks.append(otio.schema.Track())
tl.tracks[0].append(otio.schema.Stack())
tl.tracks[0][0].append(otio.schema.Track())
tl.tracks[0][0][0].append(otio.schema.Clip())

from opentimelineio_contrib.adapters import advanced_authoring_format
simple_tl = advanced_authoring_format._simplify(tl)

self.assertEqual(
type(simple_tl.tracks[0][0]), otio.schema.Clip
)

tl = otio.schema.Timeline()
tl.tracks.append(otio.schema.Track())
tl.tracks[0].append(otio.schema.Stack())
tl.tracks[0][0].append(otio.schema.Track())
tl.tracks[0][0][0].append(otio.schema.Track())
tl.tracks[0][0][0][0].append(otio.schema.Clip())

from opentimelineio_contrib.adapters import advanced_authoring_format
simple_tl = advanced_authoring_format._simplify(tl)

# top level thing should not be a clip
self.assertEqual(
type(simple_tl.tracks[0]), otio.schema.Track
)
self.assertEqual(
type(simple_tl.tracks[0][0]), otio.schema.Clip
)

def test_simplify_stack_clip_clip(self):
tl = otio.schema.Timeline()
tl.tracks.append(otio.schema.Track())
tl.tracks[0].append(otio.schema.Stack())
tl.tracks[0][0].append(otio.schema.Clip())
tl.tracks[0][0].append(otio.schema.Clip())

from opentimelineio_contrib.adapters import advanced_authoring_format
simple_tl = advanced_authoring_format._simplify(tl)

self.assertNotEqual(
type(simple_tl.tracks[0]), otio.schema.Clip
)
self.assertEqual(
type(simple_tl.tracks[0][0]), otio.schema.Stack
)

def test_simplify_stack_track_clip(self):
tl = otio.schema.Timeline()
tl.tracks.append(otio.schema.Track())
tl.tracks[0].append(otio.schema.Stack())
tl.tracks[0][0].append(otio.schema.Track())
tl.tracks[0][0][0].append(otio.schema.Clip())
tl.tracks[0][0].append(otio.schema.Track())
tl.tracks[0][0][1].append(otio.schema.Clip())

from opentimelineio_contrib.adapters import advanced_authoring_format
simple_tl = advanced_authoring_format._simplify(tl)

# None of the things in the top level stack should be a clip
for i in simple_tl.tracks:
self.assertNotEqual(type(i), otio.schema.Clip)


if __name__ == '__main__':
unittest.main()

0 comments on commit e164549

Please sign in to comment.