Merge pull request #1109 from ynput/bugfix/tw_first_frame_offset

Apply frame offset to timewarp to handle source frame offset.
This commit is contained in:
Robin De Lillo 2025-02-03 14:47:56 +01:00 committed by GitHub
commit 42dee673c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 95 additions and 65 deletions

View file

@ -441,6 +441,15 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
in_frame += time_scalar
frame_range.append(in_frame)
# Different editorial DCC might have different TimeWarp logic.
# The following logic assumes that the "lookup" list values are
# frame offsets relative to the current source frame number.
#
# media_source_range |______1_____|______2______|______3______|
#
# media_retimed_range |______2_____|______2______|______3______|
#
# TimeWarp lookup +1 0 0
for tw_idx, tw in enumerate(time_warp_nodes):
for idx, frame_number in enumerate(frame_range):
# First timewarp, apply on media range
@ -467,9 +476,32 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
)
# adjust range if needed
media_in_trimmed_before_tw = media_in_trimmed
media_in_trimmed = max(min(frame_range), media_in)
media_out_trimmed = min(max(frame_range), media_out)
# If TimeWarp changes the first frame of the soure range,
# we need to offset the first TimeWarp values accordingly.
#
# expected_range |______2_____|______2______|______3______|
#
# EDITORIAL
# media_source_range |______1_____|______2______|______3______|
#
# TimeWarp lookup +1 0 0
#
# EXTRACTED PLATE
# plate_range |______2_____|______3______|_ _ _ _ _ _ _|
#
# expected TimeWarp 0 -1 -1
if media_in_trimmed != media_in_trimmed_before_tw:
offset = media_in_trimmed_before_tw - media_in_trimmed
offset *= 1.0 / time_scalar
time_warp_nodes[0]["lookup"] = [
value + offset
for value in time_warp_nodes[0]["lookup"]
]
# adjust available handles if needed
if (media_in_trimmed - media_in) < handle_start:
handle_start = max(0, media_in_trimmed - media_in)

View file

@ -36,6 +36,16 @@ class CollectOtioReview(pyblish.api.InstancePlugin):
# optionally get `reviewTrack`
review_track_name = instance.data.get("reviewTrack")
# [clip_media] setting:
# Extract current clip source range as reviewable.
# Flag review content from otio_clip.
if not review_track_name and "review" in instance.data["families"]:
otio_review_clips = [otio_clip]
# skip if no review track available
elif not review_track_name:
return
# generate range in parent
otio_tl_range = otio_clip.range_in_parent()
@ -43,12 +53,14 @@ class CollectOtioReview(pyblish.api.InstancePlugin):
clip_frame_end = int(
otio_tl_range.start_time.value + otio_tl_range.duration.value)
# skip if no review track available
if not review_track_name:
return
# loop all tracks and match with name in `reviewTrack`
for track in otio_timeline.tracks:
# No review track defined, skip the loop
if review_track_name is None:
break
# Not current review track, skip it.
if review_track_name != track.name:
continue

View file

@ -195,13 +195,6 @@ class CollectOtioSubsetResources(
repre = self._create_representation(
frame_start, frame_end, file=filename)
if (
not instance.data.get("otioReviewClips")
and "review" in instance.data["families"]
):
review_repre = self._create_representation(
frame_start, frame_end, collection=collection,
delete=True, review=True)
else:
_trim = False
@ -217,13 +210,6 @@ class CollectOtioSubsetResources(
repre = self._create_representation(
frame_start, frame_end, file=filename, trim=_trim)
if (
not instance.data.get("otioReviewClips")
and "review" in instance.data["families"]
):
review_repre = self._create_representation(
frame_start, frame_end,
file=filename, delete=True, review=True)
instance.data["originalDirname"] = self.staging_dir
@ -236,9 +222,6 @@ class CollectOtioSubsetResources(
instance.data["representations"].append(repre)
# add review representation to instance data
if review_repre:
instance.data["representations"].append(review_repre)
self.log.debug(instance.data)

View file

@ -320,6 +320,9 @@ class ExtractOTIOReview(
end = max(collection.indexes)
files = [f for f in collection]
# single frame sequence
if len(files) == 1:
files = files[0]
ext = collection.format("{tail}")
representation_data.update({
"name": ext[1:],

View file

@ -231,17 +231,17 @@ def test_movie_timewarp():
'Class': 'TimeWarp',
'length': 4.0,
'lookup': [
2.0,
1.8959999809265136,
1.767999971389771,
1.59199997138977,
1.3439999809265135,
1.0,
0.5440000181198119,
-0.007999974250793684,
-0.6319999756813051,
-1.3039999847412114,
-2.0
0.0,
-0.10400001907348644,
-0.23200002861022906,
-0.4080000286102301,
-0.6560000190734865,
-1.0,
-1.455999981880188,
-2.0079999742507937,
-2.631999975681305,
-3.3039999847412114,
-4.0
],
'name': 'TimeWarp2'
}
@ -581,17 +581,17 @@ def test_img_sequence_timewarp_beyond_range():
'Class': 'TimeWarp',
'length': 1.0,
'lookup': [
-5.0,
-3.9440000305175777,
-2.852000034332275,
-1.6880000228881844,
-0.4160000076293944,
1.0,
2.5839999923706056,
4.311999977111817,
6.147999965667726,
8.055999969482421,
10.0
0.0,
1.0559999694824223,
2.147999965667725,
3.3119999771118156,
4.583999992370606,
6.0,
7.583999992370606,
9.311999977111817,
11.147999965667726,
13.055999969482421,
15.0
],
'name': 'TimeWarp3'
}
@ -632,17 +632,17 @@ def test_img_sequence_2X_speed_timewarp():
'Class': 'TimeWarp',
'length': 4.0,
'lookup': [
2.0,
1.7039999923706055,
1.431999991416931,
1.2079999942779531,
1.055999998092652,
1.0,
1.056000007629395,
1.208000022888184,
1.432000034332276,
1.7040000305175766,
2.0
0.0,
-0.2960000076293945,
-0.568000008583069,
-0.7920000057220469,
-0.944000001907348,
-1.0,
-0.9439999923706051,
-0.791999977111816,
-0.5679999656677239,
-0.29599996948242335,
0.0
],
'name': 'TimeWarp6'
}
@ -682,17 +682,17 @@ def test_img_sequence_multiple_timewarps():
'Class': 'TimeWarp',
'length': 1.0,
'lookup': [
-5.0,
-3.9440000305175777,
-2.852000034332275,
-1.6880000228881844,
-0.4160000076293944,
1.0,
2.5839999923706056,
4.311999977111817,
6.147999965667726,
8.055999969482421,
10.0
0.0,
1.0559999694824223,
2.147999965667725,
3.3119999771118156,
4.583999992370606,
6.0,
7.583999992370606,
9.311999977111817,
11.147999965667726,
13.055999969482421,
15.0
],
'name': 'TimeWarp3'
},