From 0d49f5a8dfda7b2b3b5189befbdf4ac34388c5e4 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Oct 2025 11:14:10 +0200 Subject: [PATCH 1/3] Fixes: Corrects file sequence frame offset Corrects the calculation of the frame offset for file sequences in editorial workflows. - Ensures accurate frame mapping. - Resolves issues with incorrect frame ranges. --- client/ayon_core/pipeline/editorial.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/pipeline/editorial.py b/client/ayon_core/pipeline/editorial.py index b553fae3fb..716035aa1c 100644 --- a/client/ayon_core/pipeline/editorial.py +++ b/client/ayon_core/pipeline/editorial.py @@ -202,7 +202,8 @@ def is_clip_from_media_sequence(otio_clip): def remap_range_on_file_sequence(otio_clip, otio_range): - """ + """ Remap the provided range on a file sequence clip. + Args: otio_clip (otio.schema.Clip): The OTIO clip to check. otio_range (otio.schema.TimeRange): The trim range to apply. @@ -256,10 +257,14 @@ def remap_range_on_file_sequence(otio_clip, otio_range): ) src_offset_in = otio_range.start_time - media_in - frame_in = otio.opentime.RationalTime.from_frames( - media_ref.start_frame + src_offset_in.to_frames(), + # make sure that only if any offset is present + if media_ref.start_frame == src_offset_in.to_frames(): + frame_in = src_offset_in.to_frames() + else: + frame_in = otio.opentime.RationalTime.from_frames( + media_ref.start_frame + src_offset_in.to_frames(), rate=available_range_rate, - ).to_frames() + ).to_frames() # e.g.: # duration = 10 frames at 24fps From b3dbee7664f23289f8507a375fe8fae063817800 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Wed, 29 Oct 2025 16:43:38 -0400 Subject: [PATCH 2/3] Fix legacy OTIO clips detection on range remap. --- client/ayon_core/pipeline/editorial.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/pipeline/editorial.py b/client/ayon_core/pipeline/editorial.py index 716035aa1c..a53f1b5ae5 100644 --- a/client/ayon_core/pipeline/editorial.py +++ b/client/ayon_core/pipeline/editorial.py @@ -250,21 +250,17 @@ def remap_range_on_file_sequence(otio_clip, otio_range): if ( is_clip_from_media_sequence(otio_clip) and available_range_start_frame == media_ref.start_frame - and conformed_src_in.to_frames() < media_ref.start_frame + and round(conformed_src_in.value) < media_ref.start_frame ): media_in = otio.opentime.RationalTime( 0, rate=available_range_rate ) src_offset_in = otio_range.start_time - media_in - # make sure that only if any offset is present - if media_ref.start_frame == src_offset_in.to_frames(): - frame_in = src_offset_in.to_frames() - else: - frame_in = otio.opentime.RationalTime.from_frames( - media_ref.start_frame + src_offset_in.to_frames(), + frame_in = otio.opentime.RationalTime.from_frames( + media_ref.start_frame + src_offset_in.to_frames(), rate=available_range_rate, - ).to_frames() + ).to_frames() # e.g.: # duration = 10 frames at 24fps From 9eef269aafa5d3e79e94b69e4938375b55805f53 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Wed, 29 Oct 2025 16:57:49 -0400 Subject: [PATCH 3/3] Add comment. --- client/ayon_core/pipeline/editorial.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/ayon_core/pipeline/editorial.py b/client/ayon_core/pipeline/editorial.py index a53f1b5ae5..21468e6ddd 100644 --- a/client/ayon_core/pipeline/editorial.py +++ b/client/ayon_core/pipeline/editorial.py @@ -250,6 +250,10 @@ def remap_range_on_file_sequence(otio_clip, otio_range): if ( is_clip_from_media_sequence(otio_clip) and available_range_start_frame == media_ref.start_frame + + # source range should be included in available range from media + # using round instead of conformed_src_in.to_frames() to avoid + # any precision issue with frame rate. and round(conformed_src_in.value) < media_ref.start_frame ): media_in = otio.opentime.RationalTime(