mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
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:
commit
42dee673c6
5 changed files with 95 additions and 65 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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:],
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue