Skip to content

Commit

Permalink
Add backward-compatibility for relative source ranges.
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-ynput committed Oct 1, 2024
1 parent 3a75ebc commit d69edc6
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 9 deletions.
33 changes: 24 additions & 9 deletions client/ayon_core/pipeline/editorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,30 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
available_range = otio_clip.available_range()
available_range_rate = available_range.start_time.rate

# If media source is an image sequence, returned
# mediaIn/mediaOut have to correspond
# to frame numbers from source sequence.
media_ref = otio_clip.media_reference
is_input_sequence = (
hasattr(otio.schema, "ImageSequenceReference")
and isinstance(media_ref, otio.schema.ImageSequenceReference)
)

# Temporary.
# Some AYON custom OTIO exporter were implemented with relative
# source range for image sequence. Following code maintain
# backward-compatibility by adjusting available range
# while we are updating those.
if (
is_input_sequence
and available_range.start_time.to_frames() == media_ref.start_frame
and source_range.start_time.to_frames() < media_ref.start_frame
):
available_range = _ot.TimeRange(
_ot.RationalTime(0, rate=available_range_rate),
available_range.duration,
)

# Conform source range bounds to available range rate
# .e.g. embedded TC of (3600 sec/ 1h), duration 100 frames
#
Expand Down Expand Up @@ -272,15 +296,6 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
media_in = available_range.start_time.value
media_out = available_range.end_time_inclusive().value

# If media source is an image sequence, returned
# mediaIn/mediaOut have to correspond
# to frame numbers from source sequence.
media_ref = otio_clip.media_reference
is_input_sequence = (
hasattr(otio.schema, "ImageSequenceReference")
and isinstance(media_ref, otio.schema.ImageSequenceReference)
)

if is_input_sequence:
# preserve discrete frame numbers
media_in_trimmed = otio.opentime.RationalTime.from_frames(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {},
"name": "output.[1000-1100].exr",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 104.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"effects": [],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"clip_index": "18b19490-21ea-4533-9e0c-03f434c66f14",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "18b19490-21ea-4533-9e0c-03f434c66f14",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq_old_otio/sh010 shot",
"vSyncOn": true,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "/shots/sq_old_otio/sh010",
"folderPath": "/shots/sq_old_otio/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq_old_otio",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq_old_otio",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "d27c5f77-7218-44ca-8061-5b6d33f96116",
"label": "/shots/sq_old_otio/sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "24792946-9ac4-4c8d-922f-80a83dea4be1",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq_old_otio",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video 1",
"sequence": "sq_old_otio",
"shot": "sh###",
"sourceResolution": false,
"task": null,
"track": "{_track_}",
"uuid": "dec1a40b-7ce8-43cd-94b8-08a53056a171",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "18b19490-21ea-4533-9e0c-03f434c66f14",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 104,
"clipIn": 90000,
"clipOut": 90104,
"fps": "from_selection",
"frameEnd": 1105,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 104,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "/shots/sq_old_otio/sh010",
"folderPath": "/shots/sq_old_otio/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq_old_otio",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq_old_otio",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "24792946-9ac4-4c8d-922f-80a83dea4be1",
"label": "/shots/sq_old_otio/sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq_old_otio",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video 1",
"sequence": "sq_old_otio",
"shot": "sh###",
"sourceResolution": false,
"task": null,
"track": "{_track_}",
"uuid": "dec1a40b-7ce8-43cd-94b8-08a53056a171",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AYONData",
"color": "MINT",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 52.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {
"height": 720,
"isSequence": true,
"padding": 4,
"pixelAspect": 1.0,
"width": 956
},
"name": "",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1000.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\legacy\\",
"name_prefix": "output.",
"name_suffix": ".exr",
"start_frame": 1000,
"frame_step": 1,
"rate": 24.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,23 @@ def test_img_sequence_with_embedded_tc_and_handles():
"img_seq_embedded_tc.json",
expected_data
)


def test_img_sequence_relative_source_range():
"""
Img sequence clip (embedded timecode 1h)
available files = 1000-1100
source_range = fps
"""
expected_data = {
'mediaIn': 1000,
'mediaOut': 1098,
'handleStart': 0,
'handleEnd': 2,
'speed': 1.0
}

_check_expected_retimed_values(
"legacy_img_sequence.json",
expected_data
)

0 comments on commit d69edc6

Please sign in to comment.