AcademySoftwareFoundation / OpenTimelineIO

Open Source API and interchange format for editorial timeline information.
http://opentimeline.io
Apache License 2.0
1.44k stars 282 forks source link

AAF Reader: TimeEffect on clip causing nested scope / potential structure issue? #481

Open andrewmoore-nz opened 5 years ago

andrewmoore-nz commented 5 years ago

Investigating how motion effect information is coming through in the OTIO structure, I have just come across a few things that raise some questions on our end - possibly something that may be intentional; maybe something that hasn't been spotted yet.

As a baseline test, exporting an AAF from Premiere with a single clip on a single track with no motion effect applied gives us the OTIO structure we would expect:

"OTIO_SCHEMA": "Timeline.1", 
...
"tracks": {
    "OTIO_SCHEMA": "Stack.1", 
    "children": [
        {
            "OTIO_SCHEMA": "Track.1", 
            "children": [
                {
                    "OTIO_SCHEMA": "Clip.1", 
                    "name": "CLIP_1_NoMotionEffect", 
                    ...

When another clip is added on to the second track ("V2") and has a motion effect applied to it (Clip Speed at 50%), the resulting OTIO structure looks like this:

"OTIO_SCHEMA": "Timeline.1", 
...
"tracks": {
    "OTIO_SCHEMA": "Stack.1", 
    "children": [
        {
            "OTIO_SCHEMA": "Track.1", 
            "children": [
                {
                    "OTIO_SCHEMA": "Stack.1", 
                    "children": [
                        {
                            "OTIO_SCHEMA": "Clip.1", 
                            "name": "CLIP_1_NoMotionEffect", 
                            ...
                        }, 
                        {
                            "OTIO_SCHEMA": "Track.1", 
                            "children": [
                                {
                                    "OTIO_SCHEMA": "Gap.1", 
                                    "name": "Filler", 
                                     ...
                                }, 
                                {
                                    "OTIO_SCHEMA": "Clip.1", 
                                    "name": "CLIP_2_WithMotionEffect_50%", 
                                    ...

The first real question here is: should this be respecting (what seems to be) the intended structure of Stack -> Track -> Clip? There are a few cases now that I've come across where this hierarchy isn't respected when importing AAFs and you end up with a Stack -> Clip relationship. The second, ultimately more important, questions is: is it intentional that this kind of structure can and should exist, or should it always be following the Stack -> Track -> Clip hierarchy?

You can see here that there is no nesting happening that should indicate for this first clip to be included inside a nester scope:

Screen Shot 2019-04-08 at 4 53 16 PM

Would this be the result of how the information is packaged when exported to AAF, or of how PyAAF/OTIO are interpreting the information?

When the same sequence is exported to XML, it is working exactly like we would expect - following the normal structure with no nested scopes, so we would hope to be able to get consistent results between the two.

Zip attached with a copy of the AAF and XML for you to check out:

NewSpeedChange_MstrSeq_Examples_190408.zip

As always, just let me know if there's any further info I can provide. Now that we are able to start testing AAFs with nested sequences, I have come across a few other issues that potentially fall in to a similar category, but will create a separate issue for them.

freesonluxo commented 5 years ago

Can confirm that I can repro this.

Just to confirm, this is a problem with the structure of the generated OTIO right? So, the fix is just to get the structure right? (This is not, for example, a data loss or corruption problem?)

For context, what are the effects of the structure being wrong?

jminor commented 5 years ago

I think I see what is happening here. This is a flaw in our strategy for simplifying the AAF structure as we transcribe it into OTIO. We've had some push/pull with how aggressive the simplification is - and this appears to be another case of it being too aggressive.

If you want to see what's going on you can compare otioview my.aaf to otioview my.aaf -a simplify=False (or same for otiocat). By turning off AAF simplification, you'll get a direct 1-to-1 transcription of the AAF structure into OTIO. Normally the AAF reader does a post-process to remove extraneous levels of nesting, like Tracks or Stacks with only one thing in them. This is an attempt to make the resulting OTIO look closer to what you see in the UI of your editing program, rather than the raw structure of the AAF itself.

This two-pass strategy has been working pretty well as we flesh out the features of the AAF reader, but in the long run there might be a better solution, especially as we level up our expertise of AAF. I would expect, for example, these details to vary for AAFs that come from Media Composer, Premiere, Resolve, ProTools, etc.

andrewmoore-nz commented 5 years ago

Ah ha... okay, that's making more sense then. Thanks very much for the info, @jminor. I've been able to test the AAFs that are giving us the structural issues we have been seeing using the simplify=False flag.

This is actually a combination of two issues. This was initially prompted by the small test case of seeing how the different time effects are coming through in to OTIO. However, it was also addressing the greater issue of what looked like structural abnormalities where there would be the hierarchy didn't appear to be consistent.

To provide some greater context, the AAFs that we're working with are real-world film reels that are very complicated, quite large (upwards of 200MB, taking several minutes to even read), and generating a serialised OTIO text file with over 500,000 lines. There are many nested scopes holding VFX shot histories, where there are many tracks, all with one clip on them, that are stacked in the order of the shot version number. The simplification process is causing all of the tracks to be ignored, and putting the clip objects as children of the stack. This currently does not work properly with the parser we have written for getting OTIOs in to our model (which is totally solvable, but I wanted to make sure we were solving the right problem first ) but, more importantly though, the tracks do provide a clear indication of how those clips should be displayed on the timeline, as without them one could easily assume that the clips are in series, as the clip's source_range does not provide a master start/end time for placement within it's parent stack.

As you say, Josh, this is appears to be a situation of the simplification method being a bit too aggressive. Looks at the output using the simplified=False flag, I can certainly see why it is being done, but does look like it needs a bit of fine tuning to find the right balance of simplifying the structure without loosing the necessary information.

andrewmoore-nz commented 5 years ago

Hey @jminor

Curious to get your thoughts on what might be the best approach for dealing with this scenario? Is a change to the current simplification process on the cards at the moment? As I mentioned in my previous message, we're wanting to make sure we're solving the right problem here. We could change our parser to handle this over-simplification, but if it is a situation where it's quite clearly being too aggressive, then that doesn't really seem like the best solution.