Skip to content

[T5.3] A clip entering Program cold-starts with a placeholder flash (hand the warmed cue decoder to Program) #449

Description

@iamfatness

Backlog item T5.3 (tier 5) in docs/BACKLOG.md.

A clip entering Program cold-starts with a placeholder flash (hand the warmed cue decoder to Program)

Clause / size / why: 3 | M

Order lives in BACKLOG.md; status lives here.

Activity

  1. iamfatness commented on Sep 10, 2026

    @iamfatness
    OwnerAuthor

    Owner observation, live, 2026-09-10 (build e26a0e9, test meeting): "Media playout of a video is not smooth from preview to program. It takes a moment to display and it displays a color until the video loads. That is not ideal."

    This confirms the gap on air. The solid colour is the compositor's placeholder slab for a media: layer with no decoded frame yet. It goes out on Program, so the virtual camera, recordings and streams all carry it. Cause, as recorded in CLAUDE.md "Media is a persistent source": the Preview cue poster (preview:media:<id>) and the rolling Program source (media:<id>:live:<n>) are different decoders, so going live opens a fresh one.

    Competitor bar: vMix, Ecamm and mimoLive preroll the clip, so the first on-air frame is the clip's first frame, with no gap or colour.

    Two layers of fix:

    1. Never put a placeholder on Program for a media layer. Hold the outgoing Program picture until the clip's first real frame arrives (the take completes when the frame exists). This is small and independent of the rearch.
    2. Hand the warmed cue decoder to Program (the original T5.3 scope), so there is no wait at all.
  2. iamfatness commented on Sep 12, 2026

    @iamfatness
    OwnerAuthor

    Reopening: only step 2 shipped.

    PR #492 said "Closes #449 (step 2)" and GitHub closed the whole issue on merge. That was my bookkeeping error — the parenthetical doesn't scope the keyword.

    Done (#492, merged aac2d981, live-checked on beta-2026-09-12-aac2d98): step 2, handing the warmed cue decoder to Program. A clip cued in Preview no longer flashes a placeholder when taken.

    Still open — step 1: a clip taken to Program that was never cued in Preview has no warm decoder to adopt and still cold-starts. The fix is to hold the outgoing picture until its first real frame, bounded by a timeout.

    docs/BACKLOG.md lists this as T1.11, still at the top of the open Tier 1 order, sized S.

  3. iamfatness commented on Sep 12, 2026

    @iamfatness
    OwnerAuthor

    Status 2026-09-12. Step 2 is shipped; step 1 is the only work left and it needs an owner ruling.

    Step 2 (hand the warmed cue decoder to Program) — DONE in #492, live-checked
    on beta-2026-09-12-aac2d98. A clip CUED in Preview no longer flashes:
    OwnedMediaFrameSource::adoptCuedDecoders re-keys the cue's entry onto the live
    request instead of retiring it, gated by the pure modules/MediaCueHandoff.h
    (same asset id AND path, same loop flag, preview: prefix match, generation
    exactly +1, and — the load-bearing one — the cue NEVER ROLLED).

    (For the record: this issue auto-closed on that merge because the commit said
    "Closes #449 (step 2)" — a parenthetical does not scope the keyword. Reopened.)

    Step 1 (hold the outgoing picture until the first real frame) is NOT done, and
    deliberately so.
    A clip cut to Program that was never cued in Preview still has
    no warm decoder to adopt, and for the ticks before its first frame resolveLayers
    paints colorFromParticipantId over PROGRAM.

    The reason it was not shipped unreviewed: a plain cut goes through
    load-scene-graph and never captures the outgoing scene
    , so "hold the outgoing
    picture" is a change to the Take path itself, beside the take record and
    SourceContinuityLedger (which already carries a documented race). That is not a
    change to make on air without a ruling.

    The fork, owner's call:

    1. Defer the cut until the clip's first frame, bounded (adds latency to the Take).
    2. Render a cold clip's layer transparent instead of a coloured slab (no latency,
      but a beat of nothing rather than a beat of wrong).
    3. Leave [T5.3] A clip entering Program cold-starts with a placeholder flash (hand the warmed cue decoder to Program) #449 at step 2 and accept the cold-start flash for un-cued clips.
  4. iamfatness commented on Sep 20, 2026

    @iamfatness
    OwnerAuthor

    Owner ruling 2026-09-19 (step 1, Take semantics): on a cut into a scene that contains a clip, the clip restarts from 0 on the cut (vMix/OBS default; the cued Preview shows the poster at frame 0 and the cut rolls it; a clip already on Program keeps rolling). Source dropout mid-show is a per-source operator choice on the Sources page: hold last frame or go black (default: hold last frame, broadcast norm). This unblocks #535 slice 3b.

  5. added a commit that references this issue on Sep 21, 2026
  6. iamfatness commented on Sep 21, 2026

    @iamfatness
    OwnerAuthor

    Backlog reconciliation corrects the closed status: step 2/core-owned cue transport is shipped (#492, #567), but I could not substantiate completion of step 1 (hold the outgoing Program picture until a never-cued clip has its first frame, bounded by timeout). On main 793c452, MediaCore::loadSceneGraph immediately replaces sceneId_/sceneRoutes_; D3D11CompositorAdapter resolves absent content to the warming slate. The late-first-frame test checks eventual playback and avoids a false ended state; it does not assert retention of the outgoing picture. PR #567's recorded oracle tests the cued path. The issue was closed on 2026-09-12, before #567, rather than by demonstrated step-1 acceptance. Reopening for the outstanding cold-Take acceptance; the 2026-09-19 owner ruling already resolves restart-from-zero semantics. No fresh live reproduction is claimed by this code audit.

  7. added 2 commits that reference this issue on Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions