X2Pro5 writes inaccurate, self-contradicting source timecode into embedded AAF

› Forums › X2Pro5 forum › X2Pro5 writes inaccurate, self-contradicting source timecode into embedded AAF

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #1577
    Cinexpert
    Participant

      X2Pro5 5.0.53: embedded AAF source timecode is rounded to whole seconds and the embedded WAV slices keep the whole take’s BWF time stamp — Pro Tools cannot conform to production audio

      Environment:
      X2Pro5 5.0.53 (build 83), Mac App Store
      Source: Final Cut Pro FCPXML 1.13 (.fcpxmld), 1080p25 NDF, 48 kHz
      Production audio: Sound Devices Scorpio poly BWF, 6–9 channels, 24-bit 48 kHz, bext + iXML
      X2Pro settings: embedded media, 4 s handles, dialogue roles, 24-bit
      Result: 546 assets in, 321 embedded portions (MasterMobs), ~6 GB AAF

      The same FCPXML converted with X2Pro 4.5 conforms correctly in Pro Tools.

      Impact:
      Pro Tools imports the AAF and it plays in sync, but the Field Recorder workflow (Match Alternates / Expand to New Tracks) cannot conform any clip to the original poly WAVs. Isolation tests (below) show the failure is caused by finding 2 in combination with finding 4. Finding 1 would still leave every conform up to 12 frames out even if the others were fixed.

      Finding 1:
      Tape SourceMob timecode is rounded to the nearest whole second.
      Each embedded portion gets a tape SourceMob with a 25 fps Timecode component. In all 321 portions Timecode.Start is a multiple of 25 frames, i.e. it lands on frame :00. The FCPXML clip in-points are frame-accurate and the portion start is in-point minus the 4 s handle (the composition SourceClip.StartTime is exactly 4000 ms in all 321 cases, so the offset is not compensated elsewhere).

      Comparing expected portion start against the written value for 190 portions that could be matched unambiguously: errors are spread evenly from −12 to +12 frames and only 8 of 190 are correct. This is round-to-nearest-second behaviour.

      Examples (clip in-point from FCPXML / expected portion TC = in-point minus 4 s / what X2Pro wrote / error):
      – Portion A.1: in 14:54:06:06, expected 14:54:02:06, written 14:54:02:00 (Start=1341050), error -6 frames
      – Portion B.1: in 12:49:44:14, expected 12:49:40:14, written 12:49:41:00 (Start=1154525), error +11 frames
      – Portion C.1: in 15:06:38:13, expected 15:06:34:13, written 15:06:35:00 (Start=1359875), error +12 frames
      – Portion D.1: in 10:57:38:09, expected 10:57:34:09, written 10:57:34:00, error -9 frames
      – Portion E.1: in 15:42:41:23, expected 15:42:37:23, written 15:42:38:00, error +2 frames

      FCPXML asset for take A: start=”2569920001/48000s” (14:52:20:00 + 1 sample, the usual FCP representation of a BWF time reference), duration=”140s”. The portion offset into the file is 102.24 s; X2Pro wrote 102 s.
      Expected: Timecode.Start = the portion’s true start rounded to the nearest frame (here 14:54:02:06 = 1341056).

      Finding 2:
      Embedded WAV slices keep the whole take’s BWF and iXML time stamp and identity.
      Each portion’s essence is a complete RIFF/WAVE (bext, iXML, fmt, data) and WAVEDescriptor.Summary holds the same header. bext and iXML are copied verbatim from the original poly file, so a 13.64 s slice that starts 102 s into the take is stamped with the take’s start.
      For slice A.1:
      – bext TimeReference: written 2569920001 (14:52:20:00).
      Should be about 2574827520 (14:54:02:06, the slice start).
      – iXML TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO: written 2569920001.
      Should equal the corrected bext value.
      – iXML FILE_UID and bext OriginatorReference: the original file’s UID, identical for every slice cut from the same take.
      Should be a new UID per slice, or a PARENT_UID pointing at the original.
      – AAF tape mob Timecode.Start for the same slice: 14:54:02:00 (should be 14:54:02:06).
      So the AAF chain and the BWF stamp inside the same essence disagree by 102 s (a different amount for every portion).
      Pro Tools extracts embedded essence to WAV files on import, and the BWF stamp is what the Field Recorder matcher reads.
      Expected: rewrite TimeReference and the iXML timestamp to the slice’s actual start, or strip bext/iXML from the slice and rely on the tape mob timecode. Both variants were verified to conform in Pro Tools (see tests). Scene, take, TAPE and TRACK_LIST should be kept.

      FINDING 3: Timecode length written in milliseconds inside a 25 fps slot.
      The tape mob timecode slot (slot 17 “TC1”) has EditRate 25/1, but Timecode.Length is 13640 for a 13.64 s portion, i.e. the millisecond count; in frames it should be 341. TapeDescriptor.Length is also 13640.

      FINDING 4: all sound slots use EditRate 1000/1.
      MasterMob, file SourceMob, tape SourceMob and CompositionMob sound slots all use EditRate 1000/1 (milliseconds), where Avid, Resolve and Premiere use the sample rate (48000/1) or the frame rate. Alone this does not break Pro Tools, but combined with finding 2 it does: the same clip rebuilt with 48000/1 and 25/1 edit rates and the unchanged BWF stamp conforms correctly. Millisecond positions also cannot express sample-accurate cuts (1 ms = 48 samples).

      Expected: sample-rate edit rates on file/master slots and frame-rate edit rate on the tape mob, as X2Pro 4.5 does.

      FINDING 5: compound-file header FAT sector count disagrees with the DIFAT.
      The header declares 92742 FAT sectors while the DIFAT chain contains 92819 (pyaaf2 warns “fat sector count mismatch difat: 92819 header: 92742”). Files still open, but the writer is inconsistent.

      STRUCTURE OF ONE PORTION (names generalised)
      MasterMob ‘<take>.1’, UserComments: TAPE=<tape> Scene=<scene> Take=<take> FILENAME=<original file>.wav TRK1..6=…
      slots 1-6: EditRate 1000/1, Sequence[SourceClip start=0 len=13640] -> file SourceMob
      file SourceMob (six of them, one per channel): WAVEDescriptor, ContainerFormat=AAF, SampleRate=48000, Length=654720
      Summary = RIFF header including bext (TimeReference 2569920001) + iXML + fmt
      slot 1: EditRate 1000/1, SourceClip start=0 len=13640 -> tape SourceMob slot n
      tape SourceMob ‘<tape name from bext TAPE>’: TapeDescriptor Length=13640
      slots 1-16: EditRate 1000/1, Sequence[SourceClip null] len=13640
      slot 17 ‘TC1’: EditRate 25/1, Sequence[Timecode start=1341050 (14:54:02:00) fps=25 len=13640]
      CompositionMob slot ‘A1 (dialogue)’: EditRate 1000/1
      at 940200 ms: SourceClip start=4000 len=3040 -> ‘<take>.1’
      EssenceData = complete RIFF/WAVE (bext 858 bytes, iXML 5190 bytes, fmt, data 1964160 bytes)

      PRO TOOLS ISOLATION TESTS
      Five single-clip AAFs were generated from the same slice A.1 (channel 1). Each reproduces or changes one of X2Pro5’s structural choices, but all five carry the correct, frame-accurate tape timecode (14:54:02:06) instead of the rounded value X2Pro wrote (14:54:02:00). All five were imported into Pro Tools and conformed against the original poly file with the Field Recorder workflow.
      – T1, faithful X2Pro replica: edit rates 1000/1, WAVEDescriptor + RIFF essence, whole-take BWF/iXML stamp kept, Sequence-wrapped timecode on slot 17 with length in ms. Conform passes.
      – T2, stamp stripped: edit rates 1000/1, WAVEDescriptor + RIFF essence with only fmt + data. Conform passes.
      – T3, stamp corrected: edit rates 1000/1, WAVEDescriptor + RIFF essence, bext/iXML timestamp set to the slice start. Conform passes.
      – T4, conventional rates: edit rates 48000/1 with tape at 25/1, WAVEDescriptor + RIFF essence, whole-take stamp kept as X2Pro writes it. Conform passes.
      – T5, Avid style: edit rates 48000/1 with tape at 25/1, PCMDescriptor + raw PCM, no stamp. Conform passes.
      All five conform with no drift, including T1, which replicates X2Pro5’s structure in every respect except the timecode value. This shows that Pro Tools reads the source timecode from the AAF tape SourceMob (the BWF stamp inside the slice is ignored, see T4) and tolerates the 1000/1 edit rates, the Sequence-wrapped timecode and the length in ms units. The only difference left between the passing replica and the failing X2Pro5 export is the whole-second rounding of Timecode.Start (finding 1). Findings 2 to 5 are inconsistencies that should still be corrected, but they are not what breaks the conform.

      STEPS TO REPRODUCE
      1. Cut a Sound Devices poly BWF (bext + iXML, TimeReference on a frame boundary) into a 25 fps FCP project so a clip starts at a non-zero frame, e.g. 14:54:06:06.
      2. Export FCPXML 1.13; confirm the asset has a frame-accurate start and the clip a frame-accurate in-point.
      3. Convert with X2Pro5 5.0.53, embedded media, 4 s handles.
      4. Read the tape SourceMob’s Timecode.Start (pyaaf2 or AAF SDK): it is on frame :00. Extract the essence stream: its bext TimeReference equals the original file’s, not the slice’s.
      5. Import into Pro Tools, set the guide track as Field Recorder guide, run Match Alternates against the original poly file: no usable match or severe drift. Repeat with X2Pro 4.5: matches, no drifts.

      REQUESTED CHANGES
      – Write Timecode.Start from the sample-accurate portion start rounded to the nearest frame, not the nearest second.
      – Rewrite bext TimeReference and iXML TIMESTAMP_SAMPLES_SINCE_MIDNIGHT in every embedded slice to the slice’s start (or omit the chunks), and give each slice its own FILE_UID.
      – Write Timecode.Length and TapeDescriptor.Length in the slot’s own edit-rate units.
      – Use sample-rate and frame-rate edit rates on sound and tape slots rather than 1000/1.
      – Make the compound-file header FAT sector count match the DIFAT.

      The project files cannot be shared publicly. The defects reproduce from any Sound Devices poly BWF cut in at a non-zero frame (steps above). Inspection was done with pyaaf2 1.7.1.

      #1578
      James Carrick
      Keymaster

        Dear Cinexpert,

        There is a known discrepancy between a FCPXMLD in fractions and a ProTools AAF in thousandths of a second. We do not round up to the nearest second, it is the nearest .001. Will write you a mail outside of the forum as there is just too much to unpack in a single thread.

        Yours Sincerely

        James.

        #1579
        Cinexpert
        Participant

          Thanks.

          Maybe it’s a bug then but we definitely see the very same amount of drift in Pro Tools and the only rational explanation we could come up with is the nearest-second roundup. Once again, no issues with v4.5

          #1580
          James Carrick
          Keymaster

            Dear Cinexpert

            Have sent you a mail outside of the forum, as we need the XML, log and screen shots highlighting the difference you are seeing between the project in FCP against the project in ProTools, has to be outside the forum so no one else see’s your XML.

            Yours Sincerely

            James.

            #1581
            James Carrick
            Keymaster

              Just an update for everyone to see what is going on, as we have been talking to Cinexpert directly.

              We looked at the XML and yes there is a difference between what is seen in FCP and what is seen in ProTools. The reason for this is that some of the media files have different lengths for their Video and Audio. i.e. clip 1, the audio was 5 frames shorter than the video. clip 2, the audio started 2 frames after the video started. The media is unusual but should not be considered exceptional. In a FCPXML it copes with these discrepancies by leaving holes. An AAF by contrast must be continuous so we should be padding these holes in the AAF, we are but instead of using the calculated filler duration we are only applying a 1ms pad. We are working on a fix for this and will advise shortly.

              Yours sincerely

              James.

            Viewing 5 posts - 1 through 5 (of 5 total)
            • You must be logged in to reply to this topic.
            Scroll to top