Turnover¶
A turnover creates and updates shots in the production backend (Kitsu) from a published edit timeline. Editors run it as a publish pipeline:
- Blender:
blender_edit_turnover("Timeline Turnover") publishes the Sequencer's OTIO file and turns it over. - Standalone publisher:
publisher_turnoverturns over anedit_timelinethat's already published, so the turnover doesn't depend on a DCC.
The work is done by two actions, ExtractTurnoverPlan and IntegrateTurnover (see the Action Reference). The rules live in kpipe.turnover.
Only the K-Pipe shot tags of the timeline are read. A timeline from any editor works once its export is tagged.
Where to publish from¶
Publish the turnover from the main edit file. Sequence files linked into it come along as nested timelines, and every shot gets its range in edit frames, wherever it sits.
A timeline published from a sequence file's own layer still works, but its ranges are that file's frames, so the turnover warns about it.
What a turnover writes¶
| Shot | Written |
|---|---|
| New | Created with the timeline's range, local_in and handles from [attributes], and the default tasks ([turnover] tasks) with the status [turnover] task_status (a Kitsu short name, default todo). A new sequence is created first. |
| Existing, in the timeline | The range, depending on the shot's state (see below), plus any missing default tasks |
| In the backend but missing from the timeline | Reported as omitted. With Mark omitted shots it gets the flag omitted. It's never deleted. Only sequences the timeline contains, and that are entirely selected, are checked. |
| Canceled in the backend but back in the timeline | Skipped. Reinstate it in Kitsu. |
Running the same timeline again changes nothing, so a turnover that partly failed can simply be repeated. A dry run only reports.
Only selected shots (Blender: the selected shot strips, or every shot inside a selected linked sequence strip) and Only shots (the publisher: e.g. sq010 sq020_sh030) limit what's written. Everything else is counted as "not selected".
Conform flags¶
Every shot of the timeline gets a flag, stored on the shot together with the published timeline it came from:
| Flag | When |
|---|---|
new |
The shot was created |
moved |
It sits elsewhere in the edit, with the same length and content |
retimed |
Its length or content changed. The summary says which end changed and whether the change stays within the handles. |
reinstated |
It was omitted and is back |
unchanged |
Nothing changed |
omitted |
Missing from the timeline (with Mark omitted shots) |
The flags of a timeline stay until a newer timeline version is turned over.
Which end changed¶
The cut is an edit decision: which frames of its media a strip shows. It belongs to the timeline (the clips' source ranges), not to the shot, and nothing of it is stored in Kitsu. local_in is the shot's own frame numbering, that of its workfiles and renders.
To tell which end of a retimed shot changed, the turnover compares its cut with the one in the timeline last turned over for it (named by conform_source).
Exact comparison works when:
- the media is the same (e.g. the same scene), or
- both media number their frames as the shot's local frames:
- shot slots (empty: an empty video whose frame number is the local frame; filled: the loaded media's frame numbers)
- videos loaded through K-Pipe (the product's recorded frame-start)
- image sequences (the frame numbers in the file names)
Otherwise, e.g. an animatic scene replaced by a render, or with no earlier timeline, the change is only known when one end stayed in place. If it isn't, it counts as beyond the handles, and the summary says "check local in". The shot's state then decides what happens (see below).
Blender's export gives source frames from the media's start. The timeline publish adds each strip's first media frame number and records what the media is (source_offset, source_media, source_local).
Shot states and rules¶
Every shot has an edit state: open → blocking → locked → final.
- Where it's stored: the shot's Kitsu field
edit_state. Unset counts as open. - Who sets it: production steps it with ◀ / ▶ in Blender's Active Shot panel (state buttons under Set / Unmark), which needs write access to Kitsu. The first change adds the field to Kitsu as a column.
- Not from tasks: task statuses don't set the state.
The state decides the response to a move or a retime:
| State | Moved | Retimed within the handles | Beyond the handles, or ambiguous |
|---|---|---|---|
| open | apply | apply | apply |
| blocking | review | apply | review |
| locked | block | review | block |
| final | block | block | block |
- apply: write the range.
- review: write the range and set the flag status
review. - block: don't write the range. The flag gets the status
blocked. To let the change through, step the shot's state back to one that allows it. The next turnover then applies it with that state's response.
The actions a state change triggers (handles, Kitsu comments, task statuses) are still to come.
Override single cells per state:
Update changed ranges off, and ranges with a timing warning (e.g. a retimed strip, whose timing the export loses), are always blocked.
Local frames and handles¶
- Open shots follow the edit one to one:
local_instays, and the length changes at the end. - Shots that have been started keep their work range, meaning the local range plus the handles:
local_inmoves with the head of the cut, so local frames keep showing the same content.- The handles absorb the change.
Example: a blocking shot with local_in 1001 and 6-frame handles gets 3 frames longer at the head. It ends up with local_in 998 and a head handle of 3. An extension past the handles is "beyond", and the handle stays at 0.
Sequence states¶
A sequence's edit_state (a Kitsu sequence metadata field) locks parts of the edit:
| State | Breaks the lock |
|---|---|
| fluid (empty) | Nothing |
cut_locked |
A new or omitted shot, a changed order, a changed length |
timing_locked |
The same as cut-locked, plus any move |
When a lock is broken, every change of that sequence is blocked, and the summary names the reason.
Previews in Blender¶
The Sequencer shows what a turnover would do before anyone publishes:
- Pending changes: kpipe_blender/shot_status.py runs plan_turnover as a preview, without writing anything, on the shots the timeline would export (shot_model.timeline_shots, which mirrors read_shots of the OTIO export). It reports a shot as pending (⇄) when the turnover would move or retime it.
- In the main edit, moves and retimes both count.
- In a sequence file, only retimes count, because its frames aren't the edit's.
- Flags: the stored flag and its status come from the production cache. A review status shows as ⚑.
- Where it shows: strip colors (shot_colors.py), marks at the right end of the strips (shot_overlay.py), and the Shots, Active Shot, Linked Shots and Workfile Sequence panels.
Kitsu setup¶
The turnover writes these shot data fields:
- conform, conform_status and conform_source
- edit_state, when production changes it in Blender. Its metadata descriptor (a list of the four states) is added the first time, if Kitsu's rights allow it.
Older turnovers also stored cut_in and cut_out. They're ignored now.
It reads the sequence field edit_state. Kitsu keeps all of them. To show them as columns, create metadata descriptors with these names for shots, and edit_state for sequences.
Creating shots needs a personal Kitsu login (kpipe-manage login), and Kitsu's own rights apply: Production or Studio Managers.