1 · Quick start#

  1. Open a file: ⌘O, drag it onto the window, or pass a path on the command line. Encoded files (MP4 / MOV / QuickTime) and y4m open directly; headerless raw files go through the parameter sheet.
  2. Check the interpretation in the info panel (⌘I): Matrix, Range, and Transfer are live pills. Amber means your selection differs from what the file declares.
  3. Step frames with /, play with Space, zoom with ⌘+/⌘−, hover for per-pixel values.
  4. Toggle analyzers with ⌃1 through ⌃9; pop any of them into its own window with ⌃⌥ and the same number.

No file to hand? ⌘G writes one: the signal generator makes bars, ramps, PLUGE, PQ stairs and temporal fixtures with nothing open (section 15).


2 · Opening files#

2.1 · Encoded video#

MP4, MOV, and QuickTime files decode through the system decoder: HEVC, H.264, and ProRes, with frame-exact random access and edit-list handling. Files that carry their parameter sets in-band (hev1 / avc3 sample entries) decode through Videre's own VideoToolbox path, so they open even where the system player refuses them.

2.2 · Raw / headerless files#

A raw YUV or RGB dump carries no header, so Videre asks. The parameter sheet covers:

  • Pixel format: planar YUV at 8, 10, 12, and 16 bit (4:2:0 / 4:2:2 / 4:4:4), semi-planar NV12 / NV21 / P010 / NV16 / P210 / NV24 / P410, packed YUYV / UYVY / v210, grayscale, and RGB orders. Layout and bit depth are separate controls: pick the plane arrangement, then the depth within it (MSB/LE alignment shown where 16-bit words are involved). Switching layout keeps the depth when the new layout has it.
  • Dimensions and frame rate, with a size guesser that ranks candidate geometries from the file size: a candidate that divides the file into a whole number of frames with no leftover bytes is probably right. Rank by decoding goes further: it decodes the first frame under each fitting candidate and re-sorts the list by how much the result looks like an image, which separates the true layout from the ones that merely divide the file size. Formats that cannot divide the file at the current dimensions are marked in the format picker.
  • Live preview: the first frame decodes under the declaration as you edit it, with a plausibility score. A wrong width or stride shears the picture, a wrong byte order reads as noise, a wrong channel count combs; all of it is visible before you open.
  • Filename hints: 1920x1080, p010, bt709 and similar tokens in the name pre-fill the sheet and re-rank the guesser.
  • Per-plane strides for padded buffers; defaults are tight.
  • Matrix / range / transfer / chroma siting starting values.
  • Presets: save the whole declaration under a name (format, dimensions, rate, strides, color) and apply it from the Presets menu next time. The same presets work on the command line: preset:NAME anywhere a raw spec goes. Manage Presets… in the same menu renames and deletes: a rename keeps the saved declaration untouched, refuses a name another preset already uses, and the new name resolves on the command line immediately.

Declarations are also remembered per file, so reopening a raw file never asks again; ⌘F re-opens the sheet when the declaration needs changing.

Wrong guess? ⌘F (Reinterpret Raw) re-opens the sheet pre-filled with the active parameters. Applying keeps the frame position, zoom, and any compare session, unless the dimensions change.

Videre's parameter sheet for a headerless raw file: pixel format, dimensions, strides, the size-guesser candidate list, and the live decode preview with its plausibility badge.
The parameter sheet. The guesser ranks geometries that divide the file cleanly; the preview decodes the first frame as you edit.

2.3 · y4m#

YUV4MPEG2 streams open directly, including 10-bit variants. Header tags map to the interpretation: the colorspace tag sets chroma siting, and COLORRANGE=FULL sets the range.


3 · The interpretation#

Everything Videre shows and measures is computed from the pixels through one interpretation: the Matrix (BT.601 / BT.709 / BT.2020), the Range (video / full), and the Transfer (sRGB / gamma 2.2 / gamma 2.4 / PQ / HLG). The info panel (⌘I) holds the three pill controls; changes re-render live.

  • Tagged files: the file's own declaration seeds the pills. When your selection diverges, the changed pill turns amber and a tagged reset appears in the section header; one click returns to the declaration. For raw files there is no declaration, so the reset returns to what you chose in the parameter sheet.
  • Untagged encoded video defaults to a resolution-based matrix (SD → 601, HD → 709, UHD → 2020) and the BT.1886 display assumption (gamma 2.4). The assumed SDR curve is a setting (Settings › Analysis): sRGB, gamma 2.2, or gamma 2.4, applied to untagged MP4/MOV and y4m files as they open. A transfer tag always wins, and the command line keeps the BT.1886 default so scripted output stays reproducible.
  • SDR transfer choice matters for measurements: the sRGB curve and the pure power laws diverge in the shadows. The choice affects chromaticity, light levels, and every ICtCp-based number; SDR display itself stays signal pass-through.
  • Chroma siting (left / center / top-left) affects the smooth-chroma display path and the carriage stress simulation.
Videre's info panel: Matrix, Range, and Transfer pills with an amber diverged selection and the tagged reset.
The interpretation pills. Amber = your selection differs from the file's declaration.

4 · Display and navigation#

  • Modes: inspecting is the default, and six modes sit on top of it: Edit (⌘1, section 10), Compare (⌘2, section 9), Measure (⌘3, section 11), Conform (⌘4, section 12), Scenes (⌘5, section 13), and Metadata (⌘6, section 8). Switch from the Mode menu or the selector in the transport bar; pressing the active mode's shortcut again leaves it and returns to plain inspection. Every mode needs an open file.
  • Transport: Space plays and pauses at source rate, / step one frame, ⌘←/⌘→ jump to the first and last frame. The counter shows timecode and frame number together, one above the other; click it to flip which is prominent (the ruler's TC / fr chip is the same switch). ⌘J focuses the jump field, which accepts a typed frame number. Playback follows each frame's own duration from the container, so a variable-frame-rate file (an iPhone low-light capture, a screen recording) plays with its true cadence; the transport and the File section then read VFR with the measured average rate, and the tooltip gives the duration range. Decode order paces at the nominal rate (coded layout, not a temporal timeline). Playback holds real time: when a frame cannot be presented inside its own duration (a heavy 4K HDR master on a busy machine), late frames are dropped rather than stretching the clip into slow motion, and an orange → N readout beside the rate shows the presented rate while it happens. Every frame is still decoded and stepping is exact. Settings › Playback can flip this to present every frame instead - the walk you want when hunting a single-frame glitch by eye - at the price of running slower than real time. Open scope panels refresh a few times a second while the video runs, so heavy analysis never drags playback down; the moment you pause or step, every scope measures the exact frame on screen at full precision.
  • Loop playback (⌘L, or the repeat button in the transport): play wraps at the end instead of stopping. ⌥I / ⌥O mark a loop in and out point at the playhead, ⌥⌘L clears the range, and -dragging on the time ruler paints one directly (a plain -click clears it). The range draws as a teal band on the ruler. With a range set, play enters it: starting from outside repositions the playhead to the in point.
  • Hold Play Start (Frame menu, sticky): stopping returns the playhead to where play started, and so does reaching the end - the review habit from audio editors, for watching the same join twice. Off, the playhead stays where playback stopped.
  • Frame order: a Display / Decode switch in the transport bar, shown for encoded sources and enabled when the two orders actually differ. Display is the true temporal timeline. Decode makes the whole app walk the CODED order instead: stepping, playback, the counter, the jump field, and the scrubber all follow how the frames are laid out in the stream, so you can watch reference frames arrive before the frames that depend on them. The order comes from the file's composition times, and when a remux has written flat timestamps over a reordered stream (a real defect: such files play visibly shuffled in every player that trusts the container), the display order is derived from the stream's own picture order counts instead, so Videre plays the true order even though the container lies. The switch hides while a comparison is open (two files can have different structures). The current frame stays put when switching, and exports always act on the frame shown.
  • Zoom: ⌘+ / ⌘−, ⌘0 fits the window, ⌥⌘1 shows actual size. At 8× and beyond a pixel grid draws. The status bar shows the zoom (100% is one image pixel per point, orange while zoomed); double-click the readout to fit the window.
  • Text size (Settings › Layout): scales the info panel, the pixel-readout strip, the scope panels, the transport readouts (counter, jump field, fps), and every mode selector and scope toggle to Default, Large, or Extra Large, including scopes popped out into their own windows; the faintest labels also honor the system Increase Contrast setting. The same tab chooses which scopes open with a session's first file and switches the Liquid Glass chrome. Analysis holds the untagged-SDR tone response choice (section 3). Acknowledgements holds the open-source license text.
  • Readout: hover any pixel for its raw code values and converted RGB; HDR interpretations add the luminance in nits.
  • Loupe (M): a magnifier following the cursor, rendered through the exact readout conversion. It magnifies what is on screen, so a rotated clip magnifies the rotated picture. Settings › Layout chooses where it sits: centered on the cursor (the crosshair pixel stays under the mouse, like a lens) or beside it.
  • Channel isolation (Display › Channel): Y, Cb, Cr, R, G, B, alpha as grayscale; the ICtCp components I, Ct, Cp; and an ICtCp composite. V / ⇧V cycle through the classic set (All, Y, Cb, Cr, R, G, B); the ICtCp views are picked from the menu. See section 14.
  • Smooth chroma (Display menu): siting-aware bilinear chroma upsampling for display. Default is nearest: no filtering between the data and your eyes.
  • Rotation: ⌘R / ⌥⌘R rotate the view in 90° steps; container rotation metadata is applied automatically. Rotation is display-only and never changes the stored pixels or the measurements.
  • Copy Frame (⌥⌘C) and Save Frame As PNG (⇧⌘S) export the current frame through the display conversion.

5 · HDR display#

PQ and HLG interpretations render through the display's extended dynamic range. The info panel gains a Display section:

  • Headroom shows the display's current EDR multiple. Content brighter than it clips on screen (not in the numbers).
  • Exposure: ±6 EV display-only gain for reading into highlights or shadows. [ and ] nudge it by half a stop, \ resets it. Never affects readout or measurements.
  • tone map (T): a preview that scales 1,000 nits to SDR white; a plain exposure scale, not a look.
  • clipping (C): highlights pixels brighter than the display can show.

5.1 · The Environment section#

The bottom of the info panel reports what the current screen can do, so you know whether to trust what you're seeing:

  • Screen, Gamut (Display P3 or sRGB class), and Refresh.
  • EDR now: the headroom above SDR white macOS has granted. The OS grants headroom only while EDR content is on screen, so with an SDR interpretation the row reads ×1.0 · not engaged regardless of the brightness slider; flip Transfer to PQ or HLG and the granted value follows the slider (turning brightness up eats headroom; ×1.0 · no headroom means the slider is at max). It updates when you move the window to another display. Where the screen has reference modes, a Reference row shows their pinned headroom and whether the live value currently matches it; matching a reference mode is what makes viewing conditions repeatable. The clipping highlight uses the same live number.
  • HDR: via EDR · ×N max or no · SDR only. macOS renders HDR by compositing above the current SDR white (EDR) on any panel with brightness headroom, so this row reports the rendering ceiling, not a panel classification: a 600-nit SDR panel at half brightness legitimately reads ×2.0, while reference-grade HDR panels reach ×8 to ×16. Panel nits are never exposed to apps; absolute values are only pinned in a reference mode (HDR Video: 100-nit SDR white, 1,000-nit peak).
  • Night Shift and True Tone: amber when the OS is shifting color under you: Night Shift warms the white point, True Tone drifts it with ambient light. Either one invalidates color judgments until disabled. Both states are read through system interfaces with no public API; when a state can't be read, its row is absent rather than wrong.
  • Ambient: approximate lux at the built-in light sensor, the number True Tone and auto-brightness react to. Appears only on machines with a host-readable sensor (laptops, iMacs); external displays keep their sensor internal, so desktops driving a Studio Display show no row.
  • The settings link opens System Settings › Displays. Reference modes and presets can only be switched there; apps have no API for it.
Videre's Display section on a PQ interpretation: EDR headroom, exposure slider, tone map and clipping toggles.
HDR display management. Display-only; the numbers never move.

6 · Scopes#

Analyzers stack in the right-hand inspector and toggle from the top-bar capsule, the Display menu, or the keyboard:

KeysScope
⌃1Gamut (2D chromaticity / 3D cloud, ICtCp border check)
⌃2Levels: per-channel histograms
⌃3Waveform monitor
⌃4Vectorscope
⌃5Light levels (MaxCLL / MaxFALL)
⌃6QC checks
⌃7HDR10+ metadata (when present)
⌃8Bitstream / container inspector
⌃9Carriage stress

The last two rows are documented in sections of their own: the bitstream and container inspector in section 7, and carriage stress in section 14.3, alongside the ΔE ITP scale its heatmap is measured on.

⌃⌥ + the same number extracts the analyzer into its own resizable window; press again to close it. A popped-out scope stays live even with its inspector section hidden. ⌥⌘I hides the whole inspector and brings it back with the same scopes open.

Timeline strips. Every time-aligned graph runs as a full-width strip under the viewer rather than inside its panel: light levels, HDR10+ brightness, QC SI / TI, and the GOP / bitrate chart (section 7). Each strip shares the playhead with the seek bar, dragging it scrubs the viewer, and several strips stack. Panels keep the readouts plus a toggle row for their strip; the on-demand measurements (light levels, QC) open theirs when the pass finishes. A strip closes from its x button or the panel row.

6.1 · Gamut (⌃1)#

CIE 1931 chromaticity with the frame's pixel density cloud, the active space's gamut triangle, and out-of-gamut / outside-P3 stats. Hover the diagram and matching pixels highlight in the image; hover the image and a marker shows that pixel on the diagram.

The 3D mode plots chromaticity against luminance in nits: a rotatable point cloud with gamut-volume outlines, a Display P3 reference, selectable height scales (linear / log / PQ), and a MaxCLL reference plane. Drag to orbit, scroll to zoom.

The ICtCp border row is covered in section 14.

Videre's 2D gamut scope: the CIE 1931 horseshoe with the BT.2020 triangle, the Display P3 reference dashed inside it, the D65 marker, and the frame's pixel cloud.
2D. The pixel cloud on the CIE 1931 diagram, BT.2020 solid and Display P3 dashed.
Videre's 3D gamut scope on the same frame: a rotatable point cloud plotting chromaticity against luminance in nits, with gamut-volume outlines and the MaxCLL reference plane.
3D, same frame. Chromaticity on the floor, nits up the axis, MaxCLL as the flat plane.

6.2 · Levels (⌃2)#

Per-channel histograms with min / max / mean, sub-black and super-white percentages, and a hover bin readout.

Videre's Levels panel: Y, Cb and Cr histograms, each with min, max and mean and its under-range and over-range percentages, with the video-range guides marked on the plots.
Levels. One histogram per channel, with the video-range guides drawn on each plot. Footage: Big Buck Bunny (CC) Blender Foundation.

6.3 · Waveform (⌃3) and Vectorscope (⌃4)#

Luma and per-channel waveform; chroma vectorscope.

Videre's Waveform panel: the Luma and RGB parade tabs above a luma waveform trace with the video-range graticule lines.
Waveform. The luma trace against the video-range graticule; RGB parade is the other tab.
Videre's Vectorscope panel: the frame's chroma trace with the R, Mg, B, Cy, G and Yl target boxes.
Vectorscope. Chroma against the primary and secondary target boxes.

6.4 · The clip analysis (⇧⌘A)#

Whole-clip measurements come from one analysis: Analyze (⇧⌘A, the transport-bar button, or a panel's Analyze button) decodes every frame once and fills the light levels, the QC checks, and the Scenes shot list together. Find Scenes in ⌘5 runs the same analysis. When the interpretation changes afterwards, every panel that reads the analysis shows the same notice, and the notice carries its own Analyze again button - one re-run refreshes them all. Opening a different file clears them all.

Analyze new files on open (Settings › Analysis, off by default) runs the analysis as soon as a file opens, so the panels are filled by the time you look. A size guard skips files over a limit you pick, and a running analysis cancels from any of its progress bars.

6.5 · Light levels (⌃5)#

Measured MaxCLL and MaxFALL over the clip, side by side with the values the file declares. The per-frame nits graph (max and average, with the declared CLL as a dashed rule) opens as a timeline strip when the analysis finishes.

Videre's Light levels panel: measured MaxCLL and MaxFALL in nits with the frame each one peaks on, then the container's declared values and the percentage the measurement differs by.
Light levels. Measured beside declared, and by how much they disagree. This clip is tagged 400 nits and measures 756.

6.6 · QC checks (⌃6)#

From the same analysis: black frames, freeze runs (mean-absolute-difference based, matching the common detector conventions), letterbox bounds, and ITU-T P.910 SI / TI spatial and temporal information. The per-frame SI / TI graph opens as a timeline strip when the analysis finishes.

File-level delivery checks live in Conform mode's File integrity section (section 12); the QC panel is the content instrument.

Videre's QC panel: letterbox, black frames and freeze rows, the maximum SI and TI values for the clip, and the SI / TI graph toggle.
QC checks. Letterbox, black frames and freeze runs over the whole clip, with P.910 SI and TI. Frame ranges list against a row when the pass finds any.

6.7 · HDR10+ (⌃7)#

ST 2094-40 per-scene metadata with a tone-curve knee readout. The per-frame MaxSCL / average graph is a timeline strip, toggled from the panel.

Videre's HDR10+ panel: frames with metadata, target display, MaxSCL per component in nits, percentiles, and the tone-curve knee.
The HDR10+ readout. ST 2094-40 metadata in nits, knee and anchors included.

7 · Bitstream and container inspector (⌃8)#

7.1 · Bitstream#

Header-level parsing of H.264, H.265, and AV1: parameter sets in full, SEI and metadata OBUs (including HDR metadata), and slice / frame headers, grouped into per-frame access units. The view follows the playhead and shows the current frame's units; JSON export keeps every frame.

  • Field search: type a field name (chroma suggests chroma_format_idc and friends) and the tree filters to the units carrying it, unfolded to the match. Scope the search to the current frame or the whole stream.
  • Change highlight: step frames with the toggle on and any field that differs from the previous frame renders amber with its old value.
  • Field names are the exact spec syntax-element names, so results line up with the standard documents.
Videre's bitstream inspector: a whole-stream search for pic_order filtering the tree to the SPS, PPS and slice headers that carry it, each match highlighted with its value.
Field search. Type a syntax-element name; the tree filters to units carrying it.

7.2 · GOP / bitrate structure#

Opening the panel's GOP / bitrate section shows the stats in the panel and runs the frame-size chart as a timeline strip under the viewer (section 6), sharing the playhead: the current-frame marker follows as you step or play, keyframe cadence is visible at a glance, and clicking a bar jumps the viewer to that frame. The stats give the keyframe count, the interval between keyframes (minimum to maximum with the average), per-type frame-size averages, and the stream bitrate (from the declared timing; when a stream declares none, the row says so instead of guessing). Sizes are the stored sample sizes.

The strip carries the same Display / Decode switch as the transport bar (section 4); it is one app-wide setting, not a chart option. In decode order the chart shows the coded structure (reference frames as spikes with their dependent frames following), the playhead marker is the decode position, and a bar click lands exactly; in display order the bars line up with the playback timeline and clicks are exact there too. The switch appears when the stream actually reorders frames. The stats always use the decode-order definitions. This is a header-level view of stream structure; it makes no claims about encoding quality. The same numbers come from videre bitstream file.mp4 --frames as a frames_summary block in the JSON.

7.3 · Container#

For MP4 / MOV / HEIF sources the same scope gains a Container mode: the ISO base media box tree with decoded fields for the movie and track headers, edit lists, sample tables, color boxes (colr, clli, mdcv), codec configuration records, HEIF item structure, encryption signalling, and DASH indexes. The file is memory-mapped, so multi-gigabyte files open instantly. The same field search works here.

Entropy-coded slice and tile data is out of scope; that is a decoder's job, and Videre is an inspector.


8 · Metadata mode (⌘6)#

Metadata mode fixes color and HDR signalling on an MP4/MOV without re-encoding, in both places it lives: the container boxes (the tags a demuxer reads) and the coded stream itself (the signalling a decoder reads, which wins in most players). The everyday save: a deliverable bounced for a wrong or missing color tag, and a re-encode would cost hours and a generation.

Enter with ⌘6 (or ⇧⌘M). The mode pairs with the Bitstream / Container view (⌃8), which opens with it: the view shows what the file says, the mode's toolbar holds the fixes. Files the engine cannot edit - encrypted, HEIF stills, audio-only, or sources with no container at all - say so in the toolbar instead of offering dead controls; raw elementary streams are edited through videre retag on the command line.

Edits stage first and write once. Each staged edit appears in the plan (the count on the toolbar opens the list: delete one, or Revert All), ⌘Z/⇧⌘Z walk every staging, deletion, and revert, and the ⌃8 trees show each staged value inline next to the file's current one with an EDITED badge - current on the left, staged on the right, in every layer the fix writes. The plan keeps one entry per field: staging a color fix twice, or a guided color fix on top of a hand-edited colour_primaries, replaces the earlier entry rather than queueing two answers to one question. Write Metadata Copy… then writes the whole plan to one new, verified file; nothing touches the original at any point, staged or written.

Color signalling lives in two layers, and they can disagree. When they do, the Color row shows both values. Every fix has a scope control: container, bitstream, or both. Both is the default, so the layers always agree after a repair.

The guided fixes (toolbar buttons, each opening its option row - configure the fix, then the row's own Stage button commits it, one undo step per row). Set values open prefilled with what the file declares - the coded stream's own messages first, the container box as fallback - so declaring, say, a corrected MaxCLL starts from the current declaration, not from zero:

  • Color description: keep, set, or remove. Presets fill the common targets (BT.709, BT.2020 PQ, BT.2020 HLG); the fields accept any H.273 code point, so unusual tags are not a dead end. Removing deletes the colr box; the coded stream has no removable color block, so its code points are set to unspecified (2/2/2), the bitstream's way of saying "not signalled".
  • Chroma siting (the Chromaloc row, x265/ffmpeg's name for it): left, center, or top-left. This lives only in the coded stream (plain MP4 has no box for it). AV1 cannot express center siting, and the write refuses instead of writing a wrong value.
  • Content light level (MaxCLL/MaxFALL) and mastering display (SMPTE ST 2086): set or remove, in the container box and the coded stream's own messages. Mastering display values are entered in raw carriage units, the same integers x265's master-display string uses; the row shows the derived chromaticities and cd/m² beside them.
  • HLG compatibility: adds the alternative-transfer-characteristics signal (18, HLG), with a checkbox for the broadcast pattern that also sets the transfer to 14 so legacy receivers see SDR.
  • Sample aspect ratio: fix a wrong declared pixel shape in both layers. Under container or both scope the pasp box and the track's display width are written from the same value as the coded stream's aspect ratio, so players that read either agree.
  • Frame rate signalling: fix a wrong declared rate in the coded stream. The fix repairs the signalling only; the real container timing is untouched, so it never retimes the video.
  • Strip dynamic HDR metadata: removes HDR10+ metadata from every carrier it uses, for a plain HDR10 deliverable. Captions are never collateral: HDR metadata is matched by its registered provider, not by message type.
  • Make QuickTime-compatible: shown when the open file signals its decoder setup in-band (hev1 or avc3), a form QuickTime, Safari, and the system decoder refuse even though the video is valid. The fix moves the parameter sets into the configuration record (hvc1 or avc1) with the video untouched: every output frame is verified identical to the input, and the repaired file is proven to open on the system decoder before the save succeeds. Nothing else on macOS does this without a remux.
  • Fast start: moves the index (moov) before the media data so the file starts playing before it finishes downloading. Every chunk offset is repointed and every sample byte is verified at its new position.
  • Repair broken edit list: shown when the file carries a known remux defect, an edit list claiming exactly one second of pre-roll that stalls playback in players that honor it. The repair derives the real decoder delay from the file's own sample timing (never a constant) and verifies every frame decodes in order afterward.

Safety, on every path:

  • The original file is never modified. The repaired copy goes to a new file, and every write is verified before it succeeds. When only the container changes, the video and audio data must be byte-identical. When the coded stream changes, every frame of the output is decoded and compared to the input, plane by plane; the coded picture data itself is never touched. If any check fails the output is deleted and the error says why.
  • Edits apply to every video track; the command line has a --track flag for multi-track files.

8.1 · The field editor (click a field in the tree)#

In Metadata mode the ⌃8 tree is the selection source: click any field and it loads into the toolbar's field editor with its current value. Fields with self-contained semantics - the color code points, range, chroma siting, aspect ratio, and timing - take a new value and stage it; at write time every copy of the field (in-band parameter sets and the configuration record) is updated together. The level field stages only behind an explicit acknowledgement, because it changes what devices will accept the file. Structural fields (dimensions, profile, parameter-set IDs, anything that shapes how the rest of the stream parses) stay read-only, and selecting one states the specific reason instead of just refusing.

Click a unit's header row and the toolbar offers its message operations: edit the serializable message types (mastering display, content light level, alternative transfer characteristics, ambient viewing environment) prefilled with the decoded values, add a new message, or remove one (HDR10+ metadata by provider, or a specific message type). Setting a message replaces every existing copy and lands on every keyframe, so a stream never carries two disagreeing versions.

The Container tree is a selection source too, in three classes. The boxes a guided fix writes - colr, clli, mdcv, pasp, and elst - carry a small tag marker, and clicking one of their fields opens the guided-fix row that writes that box, prefilled from the file (container tags are written whole, so there is no per-field editor for them). Boxes with directly editable fields - mvhd, mdhd, tkhd, ftyp, and the sample-table headers - carry a pencil marker, and clicking a field there loads the container field editor, in two tiers:

  • Repair fields (movie and media creation times, the media language) stage plainly and write with the full repair promise.
  • Everything else the editor covers is test authoring: a deliberate way to make non-conforming files for player and pipeline testing - a sample count that lies, a timescale that cannot be real, a wrong brand. These stage only behind an explicit acknowledgement, and the write verifies the splice alone: the changed bytes are exactly the requested fields and everything else is byte-identical, but the file is not asserted to conform or play, and the save panel (-authored), the result line, and the op list (AUTHOR) all say so.

Before any field is staged, its byte location is proven against the parser's own reading of the file; a field the editor cannot prove refuses rather than guessing. Everything unmarked is the container's own bookkeeping (offsets, sizes, table contents): the writers recompute it, and clicking such a field says so.

The guided fixes cover what the tree cannot: anything the stream is missing entirely, such as an absent chroma siting, has no row to click, and the guided fix inserts it.

8.2 · The command line#

Same engine, plus raw elementary streams (.h264/.h265/.ivf), which the app does not open:

videre retag graded.mov -o graded-fixed.mov --colr bt2020-pq \
    --cll 1000,400 \
    --master-display "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)"

videre retag master.hevc -o master-fixed.hevc --chromaloc topleft
videre retag hdr.mp4 -o hdr10.mp4 --strip-dynamic-hdr
videre retag odd.mp4 -o fixed.mp4 --edit chroma_sample_loc_type_top_field=2
videre retag inband.mp4 -o compatible.mp4 --make-compatible
videre retag upload.mp4 -o streamable.mp4 --faststart
videre retag remuxed.mp4 -o repaired.mp4 --fix-edit-list
videre retag wrong-lang.mp4 -o fixed.mp4 --box mdhd.language=pol
videre retag good.mp4 -o broken.mp4 --box stsd.entry_count=7 --ack-nonconforming

videre retag --help lists everything: the fix flags (--chromaloc, --sar, --fps, --hlg-compat, --strip-dynamic-hdr, --make-compatible, --faststart, --fix-edit-list), the remove flags, --scope container|bitstream|both, the expert flags (--edit FIELD=VALUE, --remove-sei, --ack-level-change for level changes), the container field edits (--box BOX.FIELD=VALUE, with --ack-nonconforming for the test-authoring fields; the JSON summary carries conformance_asserted so a pipeline can tell a repair from a deliberately broken test file), and --json for a machine-readable summary. The file-level operations and --box each run on their own pass; combining them with other edits is refused. Run them as two passes instead.

Videre's Metadata mode: the guided-fix toolbar over the container tree, with staged values shown inline next to the file's current ones and the op list counting the plan.
Metadata mode. Stage fixes against what the file declares; one verified write for the whole plan.

9 · Compare and metrics#

Compare is a mode (⌘2). Open a second file with ⇧⌘O (or drag it onto the compare control) and the app enters it; the compare controls sit in the mode's toolbar under the seek row. Each side converts under its own interpretation, so cross-format and cross-transfer comparisons are well-defined. Switching to another mode keeps the session loaded but inactive; ⌘2 brings it back exactly as it was, and Close Comparison discards it from any mode.

  • Views: side-by-side, flip (X swaps A/B), wipe with a draggable divider, and difference with channel, heatmap, and binary styles.
  • Temporal offset lines up clips that start on different frames. ⌥↑ / ⌥↓ nudge it, ⌥⌘0 resets it. Measured frames are kept per offset, so checking another alignment and coming back costs nothing.
  • Run Metrics (⇧⌘R) measures the sequence: PSNR (matching the ffmpeg filter's conventions exactly), SSIM and MS-SSIM (canonical definitions), VMAF and CAMBI (Netflix's libvmaf), ΔE2000, and ΔE ITP (BT.2124). Per-frame chart, sequence aggregates, a jump-to-worst-frame button, and JSON / CSV export with a frozen schema. The run is progressive: each frame's numbers land in the panel the moment they are measured, and the frame you are looking at is measured next rather than waiting its turn in file order. Cancelling keeps everything measured so far, and a later run picks up where it left off instead of recomputing. VMAF and CAMBI compare frames in sequence by definition, so they appear when a full pass completes.
  • Measure Frame measures just the pair in front of you, and the sticky Auto toggle measures every frame you step to; both feed the same per-frame store the full run fills. The chart draws lines only between consecutively measured frames, so isolated measurements read as points, and the aggregates belong to a completed run.
Videre's compare mode: a wipe between reference and encode with the per-frame metrics chart below.
Wipe and measure. The divider for the eyes, the chart for the report. Footage: Big Buck Bunny (CC) Blender Foundation.

10 · Edit mode#

Edit mode (⌘1) is surgical, measurable repair of raw video: a scope finds the defect, an edit fixes exactly that finding, and the same scopes prove the result. It is not a grading tool - every operation writes exact code values, and the original file is never touched.

Edits collect in a stack shown in the toolbar under the seek row. The toolbar's Legalize, Channels, and Patch buttons each open a persistent options row beneath it - set the parameters there and Add to Stack; the row stays open for the next operation. The viewer, the pixel readout, the loupe, and every scope show the frame through the stack, so the Levels panel that flagged super-white reads zero after the legalize that fixed it. Undo (⌘Z) removes the last operation, redo (⇧⌘Z) restores it; nothing is written until you export. Opening a new file starts a fresh stack.

Click the op count in the toolbar for the op list: every operation in order, with its own label ("Legalize luma 16-235, frames 3-9"). Drag a row to reorder, click the trash to delete one, and use the checkbox to disable an operation. A disabled op keeps its place in the stack and changes nothing, which isolates what one operation did to the picture. Disabled ops are saved with the recipe and stay disabled when the command line replays it.

Each row also shows what the op changed on the current frame: samples touched per channel, and the largest code delta. "no change" means exactly that, and it is the useful case as often as not: a legalize over a frame that was already legal writes nothing, and the column is where you see it. An op scoped to other frames reads no change here; step to a frame it covers and the numbers appear. The census is for the frame in front of you, not the clip. For whole-clip totals use videre edit --report.

Reordering re-checks the whole stack. Frame ranges address the timeline as it stands at that point, so moving a cut ahead of an operation scoped to frames the cut removes is refused, naming the operation that no longer fits, rather than quietly editing different frames.

Encoded files (MP4/MOV) open in Edit mode too: the decoded frames are the working material, and export stays raw/y4m - repair here, then hand the frames to the encoder of your choice.

Videre's Edit mode: the edit stack in the toolbar under the seek row, amber in and out marks on the seek bar, and the Levels panel reading the frame through the stack.
The edit stack. Every scope reads the frame through it; nothing is written until export.

10.1 · The operations#

  • Cut, trim, subclip: mark a range with I and O (amber marks on the seek bar), or paint one on the time ruler with -drag (an -click clears it; ⌥⌘-drag paints the loop range and the selection together, for looping exactly what you marked). Then Remove Selected Frames (), Trim to Selection, or Export Selection as Subclip (which bakes the range to a new file without touching the stack). In Edit mode the transport walks the edited timeline: the counter and scrubber reflect the cuts.
  • Legalize clamps or soft-knees levels beyond a threshold. The domain matches the problem: code values (defaults prefill the video-range legal bounds at the file's bit depth), a nits ceiling resolved through the active transfer (a 100-nit limit on 10-bit PQ video lands exactly on code 509), or converted RGB for 4:4:4 sources. Only samples beyond the threshold are written; everything legal stays byte-identical.
  • Channel ops: swap Cb/Cr (the classic swapped-chroma defect; the vectorscope confirms the fix), neutralize a plane (chroma to center, luma to black), invert or copy a plane.
  • Range bake rescales every code between video and full range: the real fix for double-range files, which reinterpreting cannot touch. The picture looks identical under the new declaration, and a second bake in the same direction is refused.
  • Pixel poke and rect patch: set exact component codes, adjust them by a signed amount, or fill with a nits-defined value. With the Patch row open, click a pixel or drag a region on the image; -click / -drag adds to the selection and -click / -drag removes from it, so the selection can be any shape. -arrow grows the selection one pixel in that direction, ⇧⌥-arrow moves the whole selection (plain arrows keep stepping frames), and Esc clears it. A single picked pixel prefills its own codes, so a poke starts from what is there. Values are absolute by default; a leading + or makes them relative, so -3 lowers every selected sample by 3 (clamped at the code limits) instead of setting it to a fixed value. Poking Y at one pixel changes exactly one byte of the output.

Operations take a scope where it makes sense: this frame, the marked selection, or every frame.

A swapped-chroma frame with the Swap Cb/Cr op applied: the fixed image and the vectorscope rotated back into place.
The swapped-chroma fix. Swap Cb/Cr in the stack; the vectorscope lands back where it should.

10.2 · Geometry: crop, pad, rotate, flip#

The Geometry row bakes geometry into the stored pixels. Rotation elsewhere in Videre is a display setting; here the samples actually move, so the exported file is the right way up in every player.

  • Crop: how much comes off each edge. Symmetric mirrors each edge onto its opposite, so typing 10 in Top also takes 10 off the Bottom; switch it off to trim one side. From Selection and Active Picture fill the four numbers for you.
  • Pad: how much goes on each edge, filled with the declared range's black and neutral chroma. Symmetric works the same way.
  • Rotate: 90, 180, or 270 degrees. 90 and 270 swap the frame's dimensions.
  • Flip: horizontal or vertical mirror.

These are whole-clip operations. A raw or y4m file has one frame size, so there is no per-frame scope to choose.

On subsampled footage (4:2:0, 4:2:2) the crop origin and the pad offset have to land on the chroma grid. An odd inset is snapped rather than refused, and the readout says snapped to the chroma grid when that happened, so the numbers you typed and the file you get never disagree silently. A 90 degree rotation of 4:2:2 is refused outright: its rotated chroma grid has no representable layout, and the message points at converting to 4:4:4 in the Output row first. Four 90 degree rotations return the original bytes.

Geometry threads through the rest of the stack. An operation added after a crop addresses the cropped frame, and one that pointed at pixels the crop removed is refused, naming the operation, instead of landing somewhere else.

10.3 · Repairing damage#

The Repair row interpolates over damage instead of setting codes:

  • Selection: the selected pixels are filled from their unselected neighbours. Bilinear interpolates between the nearest good samples on each axis, which covers a single dead pixel, a dropped line, and a cluster with one rule. Median takes the middle of the good neighbours, so one bright neighbour does not drag the result up; that is the one for isolated hot pixels.
  • Lines: name rows and columns (1-based, comma separated) and each is interpolated between the good lines bounding it. The classic capture glitch, without having to select it.
  • Frame: replace the current frame's pixels with the previous frame, the next frame, or the average of both. The clip length never changes.

Three rules hold across all of it. A repair reads only unselected samples, so a cluster of dead pixels cannot fill itself with its own damage. A defect touching the frame border uses the neighbours that exist on one side rather than mirroring, because a mirror invents data. And on subsampled footage a chroma sample is interpolated only when every pixel it covers is selected: one dead luma pixel does not license rewriting the chroma its healthy neighbours share.

If there is nothing good left to read from (every row selected, the whole frame selected), the repair is refused rather than leaving the file unchanged and reporting success.

10.4 · Selecting by measurement#

The Select row builds the pixel selection from a measurement instead of the mouse, which is how a scope's finding becomes the edit that fixes it. Pick a criterion, then Count to see how many pixels it covers on the current frame before anything changes, then Select, Add, or Subtract (the same three verbs the mouse has).

  • Out of range: sub-black and super-white samples. This selects exactly the samples the Levels panel counts, so the number you saw there is the number you get here.
  • Out of gamut: pixels whose converted RGB leaves 0 to 1. Exactly the pixels a legalize in the RGB domain would rewrite. 4:4:4 only, because subsampled chroma is shared between pixels.
  • ICtCp border: pixels within a JND threshold of the RGB volume's edge, the gamut panel's border flag evaluated per pixel. This one probes every pixel, so it is the slow criterion; Count first.
  • Carriage damage: pixels the carriage stress scope's current configuration damages by more than a ΔE ITP threshold, read from the same per-pixel numbers the heatmap draws.
  • Differs from B: pixels differing from compare slot B by more than N codes on any channel.
  • Active picture: the picture inside the detected letterbox bounds.

A criterion that cannot run on the open file says why rather than selecting nothing: an empty selection would read as "nothing wrong here". The criterion measures the frame as the stack has edited it so far, so selecting out-of-range after a legalize finds what the legalize missed.

10.5 · Working space and output format#

The Output row holds two choices that shape everything else.

Work in decides where the operations run. Native keeps the file's own layout: samples you did not edit come out byte-identical, which is what makes the whole mode surgical, but subsampled chroma limits per-pixel color work (an isolated pixel on 4:2:0 shares its chroma with three neighbors). RGB 4:4:4 converts the frame first, so color edits are exact per pixel; the cost is that the conversion touches every pixel, and the byte-identity guarantee goes with it.

Write as decides the file's pixel format, whatever the source was: planar, semi-planar, or RGB, at any supported bit depth, with an optional range change. Chroma is resampled at the file's own siting, and bit depth is scaled by the rule that keeps that range's anchors exact (video range holds 16 and 235; full range holds 0 and maximum). Leave both alone and nothing is converted at all. Packed layouts (YUYV, UYVY, v210) are read but not yet written; the picker says so instead of quietly writing the planar equivalent.

Scale sets the output resolution. It is an output setting, not a stack operation: it applies after everything else, so no operation's pixel coordinates move. Filters:

  • Area (box) averages the source footprint. The default, and the right answer for a downscale: a 2× area downscale lands on the exact block means, matching ffmpeg's swscale. Plain bilinear downscaling aliases.
  • Nearest point-samples, for looking at scaling artifacts rather than avoiding them.
  • Bilinear, Bicubic (Catmull-Rom), and Lanczos-3 for upscales and for matching another tool's output.

Keep aspect fits the picture inside the target and pads the remainder with the declared range's black and neutral chroma. With it off you get the exact dimensions, so a stretch is possible but only as the explicit choice. A target equal to the source resolution writes the file untouched: the scaling stage is never entered.

Scaling runs in 4:4:4, after chroma is upsampled and before it is subsampled again. Scaling subsampled chroma directly compounds siting error, and the conversion pipeline already has a 4:4:4 stage for exactly this reason.

The row's right-hand readout always names what the file will be, format and frame size, or says no conversion when the export is the plain surgical path.

10.6 · Comparing the edit with the source#

Compare (⇧⌘C) bakes the stack to a temporary file and opens it as B against the untouched source, landing in Compare mode with the difference view up: what lights up is exactly what the edit changed, and Run Metrics (⇧⌘R) puts numbers on it. The edit stack survives the trip - ⌘1 returns to it. Available while the edit keeps the frame count (a cut changes the timeline, so the two clips would no longer line up).

10.7 · Export and verify#

Export… (⇧⌘E) bakes the stack to a new file: .y4m (which carries the format tag, rational frame rate, and range), or headerless raw for anything else. Every export is verified before success is reported: the written file is re-read with the same reader that would open it, and every frame is compared byte-for-byte against an independently recomputed reference. Anything off is discarded - and replacing an existing file can never destroy it on a failed export. Sources the y4m container cannot carry directly (NV12/P010-class decoder output, packed 4:2:2) are repacked losslessly to their planar equivalent; code values never change, only the byte arrangement.

10.8 · Recipes#

Save Recipe writes the stack as a small JSON document; videre edit clip.mp4 --ops recipe.json -o healed.y4m replays it byte-identically from the command line - batch repair across a folder of captures, or a shareable fix attached to a bug report. Load Recipe replaces the current stack. A recipe from a newer version of the app, or one whose ranges don't fit the open file, is refused whole rather than half-applied.


11 · Measure mode (⌘3)#

Measure mode (⌘3) reads the part of the frame you point at. The scopes in section 6 read whole frames; this is the complement, and it does not edit anything.

  • Region: drag a rectangle on the image, or build any shape with -drag to add and -drag to remove. The toolbar reports min, max, mean, and standard deviation per channel, plus the region's mean color and its luminance in nits. With a comparison loaded, slot B's mean and the difference come with it. The min and max are buttons: click one and the canvas centers on the exact pixel that produced it, zoomed in enough to see it.
  • Select menu: canned regions - the whole frame, a centered patch at half the frame's dimensions, the active picture inside detected letterbox bars, or the bars themselves. Measuring the bars on a frame that has none is refused rather than reporting an empty region as a result.
  • Histogram: the region's own per-channel histogram. Select the whole frame and it matches the Levels panel bin for bin.
  • Line: drag a line and the chart underneath plots code values along it, one series per channel. This is how ringing, banding, and gradient behaviour become visible; a whole-frame histogram shows none of them. A plain click profiles the whole row under the cursor and -click the column - the fastest way to read a suspect scanline. On PQ and HLG interpretations a Codes / Nits control switches the chart to luminance.
  • Ruler: drag between two points for pixel distance, signed deltas, and the angle in degrees (measured from the horizontal, positive downward, because image y grows downward). Holding snaps a line or ruler drag to horizontal, vertical, or 45°.
  • Scan Region: pins the current region and measures it on every frame of the clip - per-frame mean, deviation, and nits as a chart, a fixed window watched over time (a logo area, a suspect corner). Changing the selection or the interpretation clears the trace, because a trace of a different region would read as this one's.
  • Use as Crop hands the region to Edit mode as a crop operation, snapped outward to the chroma grid, with the selection carried along.

The line and the ruler draw on the image with their endpoints marked and the reading at the midpoint, so the numbers in the toolbar always belong to something you can see.

Copy puts the readout on the clipboard as text or JSON, so a measurement can go straight into a bug report. Esc clears the region, line, or ruler, the same key that clears a selection anywhere else.

Sampling is nearest, never interpolated, and the codes come from the same reader the status strip uses. Measure a whole frame and the numbers match the Levels panel exactly. Positions past the frame edge are dropped from a line profile rather than clamped, because a clamped sample repeats the edge value and would read as real data.

The region tool shares its selection with Edit mode. Measure a suspicious area, press ⌘1, and the selection is already there for the repair.

Videre's Measure mode: a region on the frame with per-channel statistics in the toolbar and the region's own histograms underneath.
Measure mode. Region statistics and the region's own histograms; the numbers always belong to something you can see. Footage: Big Buck Bunny (CC) Blender Foundation.

12 · Conform mode (⌘4)#

Conform mode (⌘4) turns a delivery spec into a checklist you can act on. Pick the spec; Videre checks the file against it and lists one row per requirement: pixel format, resolution, frame rate, range, matrix, transfer, light levels, legal levels.

Each failing row carries the fix that would resolve it, and the button applies it to the surface that actually performs it:

  • Tags only for matrix and transfer. No pixels move. On an MP4/MOV the fix stages onto the Metadata plan - a real tag write, reviewable in ⌘6's op list and written as one verified copy - and the row shows a Staged label rather than turning green: the file has not changed yet, and the row says so honestly until the written copy is opened. On raw and y4m sources, which have no container to write, the fix adjusts the viewing interpretation and the row passes immediately.
  • An edit-stack operation where pixels have to change: the range fix rescales every code (a re-tag would declare the file fixed while it still looked wrong), and the legal-levels fix clamps to the legal bounds.
  • An output setting for pixel format and resolution.

The table re-checks itself as you work, so a row whose fix changed the model confirms it immediately. Fix All applies everything on offer (already-staged tag fixes are skipped); Export… writes the conformed copy with the usual frame-by-frame verify.

Requirements the spec does not state read SKIP, never a quiet pass, and so do requirements whose measurement has not run: legal levels are judged on the worst frame of the whole clip, so until the clip analysis has run the row skips with an Analyze button inline rather than guessing from one frame. With the analysis in hand, a missing MaxCLL declaration offers its fix directly: the measured values, declared through Metadata mode (⌘6), entered with the light-level fix prefilled - stage it and Write Metadata Copy. Rows Videre cannot fix say so and why: a frame-rate mismatch needs retiming, which changes which frames exist, and a measurement over the spec's limit needs a clamp before a declaration.

Below the spec table, MP4/MOV files get a File integrity section: the same six checks as videre verify (section 16) with the same severities - color agreement between the container and the coded stream, declared against measured light levels, mastering display consistency, chroma siting, edit list sanity, and whether the file opens on the system decoder. These are properties of the file, true whatever spec is picked, so they run once per file when you enter the mode. The light-level row states the interpretation it measured under (the file's own tags); the ⌃5 panel measures under the interpretation you are looking at, and when the two disagree, each says which question it answered.

Presets ship for HDR10 master, Rec.709 SDR deliverable, and a mezzanine profile. Specs you save yourself appear in the same picker; a saved spec cannot take a preset's name, so hdr10 always means the same thing.

Videre's Conform mode: a delivery-spec checklist with pass, fail, and skip rows, inline fix buttons, and the File integrity section below.
Conform mode. One row per requirement; every failing row carries the fix that resolves it.

12.1 · On the command line#

videre conform master.mp4 --spec hdr10
videre conform master.mp4 --spec rec709 --fix -o deliverable.y4m

The check-only form exits nonzero when the file does not meet the spec, so a pipeline can block a bad deliverable before upload (0 conforms, 4 does not, which is distinct from the verification-failed code the writers use). With --fix the offered fixes are applied, the copy is written and verified, and then re-checked against the spec: the report describes the file that came out, not the one that went in.

By default the command decodes the clip once and measures it, so legal levels are judged on the worst frame of the whole file; a clip that is clean on its first frame and illegal afterwards does not pass. --no-measure skips that pass, and the measured rows report skip instead of a verdict. With --fix, the written copy is measured under the same rule.


13 · Scenes mode (⌘5)#

Scenes mode (⌘5) groups the clip into shots. Find Scenes runs the same whole-clip analysis as Analyze (⇧⌘A), measuring every frame against the one before it in one pass over the file, and the shot list appears underneath: in point, out point, length, how the shot begins, and the difference score at that boundary. Click a row to jump there; ⌥→ and ⌥← step between cuts.

The measurement happens once. Everything to the right of the scan button regroups the same measurements without reading the file again, so you can try a setting and see the answer immediately:

  • Sensitivity sets how different a frame has to be to count as a cut.
  • Adaptive compares each frame against its neighbours rather than against a fixed number, so a handheld shot or a fast pan does not read as a run of cuts.
  • Min length stops a busy passage from being chopped into shots too short to be real.

The strip under the viewer draws the per-frame difference with the current threshold across it and a tick at every cut, so a setting that is too high or too low is visible rather than inferred. The same ticks appear on the seek bar.

Videre's Scenes mode: the shot filmstrip and list with per-shot statistics, the difference-score strip with cut ticks under the viewer.
Scenes mode. One scan; every control to the right regroups the same measurements. Footage: Big Buck Bunny (CC) Blender Foundation.

13.1 · How a shot is labelled#

The label describes how the shot begins:

  • Cut, a single-frame jump in content.
  • To black and From black, the segment where the picture is black and the shot that follows it. A black gap is its own segment, which is what a delivery usually wants to see.
  • Gradual, a sustained run of elevated difference. That covers dissolves, wipes and fast camera movement. Videre does not distinguish between them.

Frames Videre could not measure are counted under the list and are never treated as cuts.

13.2 · What each shot measures#

The same pass that finds the cuts measures the frames, so every shot carries its own numbers:

  • Peak and Avg, the shot's MaxCLL and MaxFALL in nits: the highest single pixel, and the highest frame average.
  • SI / TI, spatial and temporal complexity per ITU-T P.910. High numbers are where an encoder spends its bits.
  • Illegal, the worst single frame's fraction of samples outside video range. This is the worst frame rather than the shot's average, because one badly clipped frame is the defect and an average hides it. Sources with no video-range concept, full-range and RGB, show a dash rather than 0%.
  • Conform, this shot's own measurements against the delivery spec picked in ⌘4: shot light levels, legal levels, and flash risk. A red ✕ counts failing checks and the tooltip names them; ✓ means every measured check passes; a dash means nothing was measured for this shot. The report says which shots are the problem and leaves the rest passing.

A dash always means "not measured", never "zero".

13.3 · Two checks that need the cuts#

Once Videre knows where the shots are, it can check two things nothing else on the Mac checks.

Cuts against keyframes. A cut that does not land on a keyframe costs bitrate at the boundary and stops the file segmenting cleanly for HLS and DASH. The badge says how many cuts are mid-GOP, and the tooltip says how many keyframes carry no cut, which is bitrate spent on nothing. Raw and y4m have no keyframes, so the check is skipped with that reason rather than reported as a failure.

Cuts against dynamic metadata. HDR10+ is graded per shot. Two things go wrong when the metadata disagrees with the picture: a cut with no metadata refresh carries the previous shot's tone mapping into the new one, and a metadata refresh with no cut is a mid-shot jump in the tone map, which is the effect people describe as the picture breathing. Videre reports both directions, allowing one frame of slop, because authoring tools routinely place the refresh on the frame either side of the cut.

HDR10+ carries no scene identifier, so a boundary is inferred from a change in the tone-mapping knee, the target display, or a large step in peak level, and the tooltip says so. Treat the result as a pointer, not a verdict.

Neither check offers a fix. A mid-GOP cut needs a re-encode and a metadata mismatch needs regrading, and neither is something Videre should pretend to do from an inspector.

13.4 · Flash risk#

The same pass measures photosensitivity risk, following the shape broadcast guidance uses (ITU-R BT.1702): a flash is a pair of opposing transitions of at least 20 cd/m² over more than a quarter of the picture, where the darker of the two states is below 160 cd/m², and more than three flashes in any one second is the threshold. Saturated red transitions are counted separately, because deep red provokes a response at levels plain brightness does not. Shots containing a flagged range are marked in the list.

The window slides: four flashes that straddle a second boundary are still four flashes in one second.

SDR carries no absolute light levels, so the check assumes a reference display and the tooltip says which. PQ and HLG are assessed against their own levels.

This is an indicator, not a certified test. The certified Harding test is a licensed product, and the part of the guidance covering regular spatial patterns, stripes and gratings, is not implemented here. A clean result is a reason to keep working, not a clearance.

13.5 · Correcting the shot list#

⌘B puts a cut at the playhead and ⇧⌘B removes the one there, merging that shot into the one before it. The scissors buttons in the toolbar do the same.

Your corrections survive everything else. Change the sensitivity and the cuts you placed stay exactly where they are while the detected ones move around them. A cut you place is never removed by the minimum-length setting, and it never removes a detected cut near it: the two kinds of boundary do not compete. Remove a cut that the detector is not currently finding and nothing happens now, but the removal comes back into effect if you lower the threshold far enough to find it again, so dragging the sensitivity is never quietly destructive.

Manual boundaries are labelled Manual and drawn in a different color from found ones, and the summary row counts them, so a shot list always says which boundaries a person decided. Reset hands the whole thing back to the detector.

13.6 · Looking at shots#

A filmstrip of shot heads sits above the list. Click one to jump there. The pictures fill in as they decode, and re-grouping keeps every picture whose shot still starts on the same frame.

Loop shot keeps playback inside whichever shot the playhead is in, which is what you want while judging a single shot's grade or motion.

13.7 · Sending a shot somewhere else#

Right-click a row in the shot list for Keep Only This Shot and Remove This Shot. Both push an operation onto the edit stack and switch to Edit mode, where the usual verified export applies. The range is mapped through the edited timeline rather than the source numbering, so a shot pushed after an earlier trim still removes the frames you pointed at. If an earlier operation already removed everything the shot covered, Videre says so instead of acting on the nearest frames it can find.

Export This Shot… writes that shot on its own without touching the edit stack, so looking at one shot does not change the edit you are building.

13.8 · Planning keyframes for a delivery#

Once the cuts are known, Videre can work out which frames should be keyframes for a delivery, and hand that to an encoder.

The reason this is not simply "a keyframe at every cut": a streaming segment has to start with a keyframe, so segment boundaries usually have to fall on a fixed cadence. A segment may contain more keyframes, though, which is why the default mode puts keyframes on the cadence and on every cut. The cuts cost a little bitrate and the segment boundaries stay even, which is what a fixed-duration DASH template needs. The other modes are cadence only, cuts only, and a cadence that shifts onto a nearby cut when there is one in reach, which compresses better but makes segment durations uneven, so it needs a segment timeline instead of a template. Videre tells you which of the two you have produced.

The GOP Plan Report lists the segments and their durations, and names every cut that did not get a keyframe with the reason, which is usually that it sat closer to the previous keyframe than the minimum GOP allows.

Export the plan as an ffmpeg force_key_frames argument (seconds, or the frame expression, which is exact where the seconds form can round at 29.97), an x264 or x265 qpfile, frame numbers, or timecodes.

13.9 · Exporting#

File › Export… (⌥⌘E) opens the export window. It works for any open file in any mode, and offers two destinations. Every export path in the app lands here: ⇧⌘E, the transport and Edit toolbar buttons, and Export Selection as Subclip are all this window.

Raw / y4m writes the file itself: choose a pixel format, a range and a working space, and Videre converts and verifies every frame against a freshly opened source before replacing anything. Choose a .y4m extension for a header, any other extension for headerless raw. If the edit stack has operations on it, they apply, and the window says how many. A Scope control writes everything or just the Edit selection between the I and O marks; Export Selection as Subclip arrives with Selection pre-picked. The ffmpeg destination always encodes the whole timeline.

ffmpeg hands the job over instead, with the encoder, the settings, the command, and the result.

Use scenes as keyframes forces a keyframe at every detected cut, on top of the cadence. It needs the clip analysis (⇧⌘A, or Find Scenes in ⌘5) and says so when there is not one; with it off the command is a plain cadence encode.

Pick an encoder and the command below it changes. Choose an output, set quality or a bitrate, and the command changes again. Copy takes it, Run runs it.

The command is editable. Type in it and it stops regenerating, so a change you make is never silently overwritten; Reset hands it back. Videre tokenizes what you wrote and runs it directly, never through a shell, so a semicolon in the field is an argument rather than a second command. The one thing it will not do is launch a different binary: use Encoders… → Choose ffmpeg… to change which ffmpeg runs.

After a run, Videre reads the keyframes out of the file it just made and says whether they match the plan. That check is the reason editing is safe to offer: Videre cannot promise a command you rewrote still follows the plan, but it can tell you afterwards whether it did.

Videre does not encode and does not ship an encoder. It looks for an ffmpeg already on your Mac, on your PATH or in the usual Homebrew locations. If there is not one, the command is still yours to copy.

The encoder's own scene detection is turned off in the command, because the whole point is that the plan decides where the keyframes go. Audio is copied rather than re-encoded.

Videre's export window: the ffmpeg destination with the encoder picker, the keyframe plan, and the editable command.
The export window. The command is visible, editable, and checked after it runs.

13.10 · Which encoders you can use#

Encoders… in that window lists what your ffmpeg has, and what Videre knows about each one:

  • Verified: Videre has a tested set of arguments for it and has checked that keyframes land where the plan says.
  • Generic: available, but Videre has no tested arguments for it, so it gets the keyframe positions and the GOP size and nothing else. Its own scene detection, GOP closure and quality stay at its defaults.
  • All-intra: every frame is a keyframe, so there is no GOP to plan.
  • Not in this build: Videre would know how to drive it, your ffmpeg does not have it. That row is there so "why can I not pick rav1e" has an answer.

Verify on any row encodes a short test clip with a known keyframe plan and reads the result back, so the claim is about your build rather than about Videre's table.

13.11 · Chapters, markers and timelines#

The Export menu writes the shot list as chapters (FFMETADATA, which ffmpeg can mux straight into a file, or WebVTT), as markers (a CSV that Resolve and Premiere import), as YouTube chapters for a description box, or as an OpenTimelineIO timeline with one clip per shot.

Titles say what Videre knows: the shot number and how it begins. It does not invent descriptions of what is in the picture.

Conform mode gains two requirements that need the clip analysis: every cut on a keyframe, and a flash-rate ceiling. Until an analysis has run they report as skipped with an inline Analyze button, never as a pass. Neither offers a fix, for the reasons above.

13.12 · On the command line#

videre scenes clip.mp4
videre scenes clip.mp4 --threshold 20 --min-length 12 --json
videre scenes clip.mp4 --edl > shots.edl

videre scenes clip.mp4 --markers ffmetadata > chapters.txt
videre scenes clip.mp4 --otio > clip.otio
videre scenes clip.mp4 --keyframes ffmpeg-expr
videre scenes clip.mp4 --gop-plan --segment-seconds 4
videre scenes clip.mp4 --ffmpeg-command out.mp4

The same engine as the mode, with --json, --csv, --edl (CMX3600), --otio and --markers outputs. --luma-only scores the luma plane alone, which reproduces ffmpeg's scdet number exactly, including the equal-brightness cuts it cannot see. --drop-frame is honoured at 29.97 and 59.94 and ignored elsewhere, since drop-frame numbering does not exist at other rates.

--keyframes and --gop-plan produce the keyframe plan, controlled by --gop-mode (cadence, cuts, cadence+cuts, snap), --segment-seconds or --keyint, --snap-tolerance, --min-gop and --max-gop. --ffmpeg-command out.mp4 prints the ffmpeg command that would encode with that structure. The command-line tool prints it and stops; running it is your call.

Pick one output at a time: each produces a whole document, so two would mean two file formats in one stream.

The command reports rather than gates, so it never exits nonzero because of what it found: 0 means the report was produced, 2 is a usage error, and 3 means the analysis could not run. Use conform when a pipeline needs to block a file.

13.13 · Timecode#

Timecode follows the file's frame rate. At 29.97 and 59.94 the Drop-frame switch appears and is on by default, because that is what those deliverables number in; the semicolon before the frames field is what marks it, as SMPTE does. At any other rate drop-frame does not exist and the switch is not offered. On a variable-rate file timecode counts against the declared rate, so it is nominal.

13.14 · Difference scores#

The score is the mean absolute difference between the two frames, scaled so a full-scale change reads 100. Videre measures all three planes by default. This matters: two shots can have the same brightness and completely different color, and a luma-only measurement scores that real cut at zero. The luma-only figure is kept alongside, and it matches ffmpeg's scdet filter exactly, so a disputed result can be checked against the tool most pipelines already run.


14 · ICtCp tools#

ICtCp (ITU-R BT.2100) is the color representation modern HDR pipelines measure in: I carries PQ-coded intensity, Ct the blue-yellow axis, Cp the red-green axis. Only a curved solid inside the I/Ct/Cp box maps back to real RGB; distance to its surface is a color's headroom against further processing. Videre reads that space three ways.

All thresholds are in ΔE ITP units (BT.2124), scaled so 1 equals one just-noticeable difference under critical viewing. Rule of thumb: below 1 nobody sees it, 2 to 3 is noticeable side by side, above 3 is plainly visible, 10+ is gross. Real content in motion tolerates several JND.

14.1 · Channel views (Display › Channel)#

  • I (ICtCp): PQ-coded intensity as grayscale; shadows get more of the scale than in a plain luma view.
  • Ct (ICtCp) and Cp (ICtCp): the opponent axes as gray, neutral at mid.
  • ICtCp (composite): all three packed into R/G/B (chroma shifted so neutral lands at mid). Neutral content collapses to a flat teal-gray; color pushes away from it. A quick saturation map.

These are measurement views computed through the active interpretation; changing Matrix / Range / Transfer changes them.

14.2 · ICtCp border check (gamut panel)#

Flags pixels whose chroma margin to the edge of the representable volume is below a threshold: the colors with no headroom, which chroma subsampling, filtering, or quantization can push out of range (a clipped channel there reads as a hue shift).

  • The checkbox paints flagged pixels cyan on the image. The stat gives the count; the overlay gives the location.
  • The slider sets the threshold, 0.5 to 8 JND, default 2.
  • The stat reads like 0.05% within 2.0 JND of the ICtCp border · min 0.0; min is the worst pixel's margin.
  • Two ways onto the border: a channel at zero (full saturation) or at peak (nothing left to add). Near-black pixels are exempt; they have no chroma freedom at all.

Try it: a color in ICtCp

I
Ct
Cp
Margin
inside

The tinted shape is every Ct/Cp value that is a real color at this pixel's intensity. The dot is the picked color; the dashed circle is its margin, the distance it can drift before it stops being representable. Colors here are treated as SDR signal graded at 100 nits; in the app, the interpretation decides.

14.3 · Carriage stress (⌃9)#

Simulates a carriage on the current frame and scores the damage per pixel: convert → quantize → chroma-subsample → upsample → convert back → compare as ΔE ITP against the frame's own interpreted signal.

ControlOptionsDecides
SpaceYCbCr · ICtCpCarriage color space; YCbCr follows the active matrix
Chroma4:4:4 · 4:2:2 · 4:2:0Chroma resolution; 4:4:4 isolates quantization
FilterNearest · BilinearSited pick / replicate, or box down + siting-aware bilinear up
Depth8 · 10 · 12 · OffCode depth; Off means no quantization

The heatmap draws each pixel's ΔE ITP on a fixed 0-10 JND scale, in display orientation:

02.557.510+ JND

Stats show mean, max, the worst pixel (source coordinates), and a threshold slider that re-bins the percentage without recomputing. Reading it: thin bright seams at color boundaries are subsampling; an even wash on flat areas is quantization.

  • Pre-delivery: set the carriage to the delivery spec, step through the most saturated shots. Mean under 1 and isolated seams under 3 is transparent carriage.
  • Isolate the cause: switch to 4:4:4; damage that survives is quantization, damage that disappears was subsampling.
  • 8-bit vs 10-bit: flip Depth and read the difference off the stats.

Try it: what 4:2:0 does to a color boundary

meets
YCbCr 4:2:0
ok
ICtCp 4:2:0
ok
the two middle columns are what comes back from the carriage

Numbers are the worst-pixel ΔE ITP at the boundary for a BT.709, 10-bit, bilinear carriage. Saturated complementary pairs hurt the most; try two pastels to see the damage collapse below threshold.

Honest limits. This is a carriage preview, not a codec (no DCT, no rate control). The simulation runs on the stored pixel grid; rotation metadata passes through a real re-encode untouched, and the math matches that. A color edge aligned to the chroma block grid reconstructs losslessly, so test charts undersell what real footage shows. Full-range coding clips the most extreme chroma on its own (roughly 0.13 JND on a pure primary). PQ uses the full 10,000-nit container.

The ICtCp border check: cyan flags on saturated pixels with the gamut panel stat row.
The border check. The stat counts; the overlay locates. Footage: Big Buck Bunny (CC) Blender Foundation.
The carriage stress scope: damage heatmap with seams at color boundaries and the config pills.
Carriage stress. Seams are subsampling; the flat wash is quantization.

15 · Signal generator#

File › Signal Generator… (⌘G), the Generate chip beside the mode bar, or the Generate a test signal tile in the empty window. The generator writes a synthetic test clip to a new raw or y4m file. Nothing needs to be open first.

Pattern reference, bottom right of the generator window, opens the pattern catalogue: every pattern with a picture, what it exposes, and what to read off it. This section covers the window; that page is the per-pattern reference.

15.1 · What it makes#

Pick a pattern, a format and an interpretation, and the generator computes the codes for that exact combination. A color bar is its standard R'G'B' definition encoded through the matrix, range and bit depth you chose, so 75% white lands on 721 at 10-bit narrow range and 2884 at 12-bit. HDR levels go through the same PQ and HLG math the scopes and the edit surface use, so a 1000-nit stair tread and a 1000-nit legalize ceiling agree.

The catalogue:

GroupPatterns
ColorSolid field (by code, R'G'B', or CIE xy plus nits), color bars, HDR bars, a 24-patch ColorChecker-style chart, conversion probe patches labelled with the codes they should carry
GradientsRamp (any channel set, any code window, optional staircase), bit-depth ramp
LevelsPLUGE, range checker
GamutGamut edge sweep, narrow-gamut content inside a wide container, out-of-gamut marker pairs
ResolutionZone plate, gratings, checkerboard, chroma-siting probe, grid and graticule
HDRPQ stairs, luminance window, HDR grey ramp
TemporalMotion, cadence, drop detector, flash sequence, noise field

Overlays compose onto any of them: a frame counter (with a machine-readable block strip and optional timecode), a text label, a 1-pixel border with lettered corner boxes, and a centre cross. Add several segments and the clip becomes a scene-cut test: Scenes mode finds the boundaries where the segments meet.

The counter and the label each carry their own Position: top left, top right, bottom left, bottom right, or centre. Set them per segment in the Overlays card, or from the command line with --counter-position and --label-position. An overlay that would not fit the frame is refused rather than drawn clipped, which is why a large scale on a small frame reports an error instead of a truncated mark.

15.2 · Chroma siting#

Each plane is rendered at its own sample position. On 4:2:0 the chroma samples are computed where the chosen siting says they sit, not filtered down from a 4:4:4 picture, so a file carries chroma that matches what it declares. The chroma-siting probe makes this visible: its color edges sit a quarter pixel from the luma markers beside them, which is the position that separates the three sitings. Under the wrong siting the color edge lands half a chroma sample away from the luma marker beside it.

15.3 · Presets#

The Presets menu holds fourteen starting points, including SMPTE-style bars at 1080p, BT.2111-style bars in HLG and in PQ at UHD, a PQ stairs ladder, PLUGE, a range checker, a drop detector at 60p, a zone plate, a chroma-siting probe, a five-shot demo clip, and a flash-risk fixture. The command line takes the same names.

15.4 · Writing the file#

Generate… asks where to put the file and writes it. y4m is the default because it carries its own format, dimensions, frame rate and range, so it re-opens without the parameter sheet. Raw is available for everything, and required for RGB formats, which y4m has no tag for. Videre refuses to write a y4m whose header cannot declare the chroma siting you chose: only the 8-bit 4:2:0 tags spell siting out, so above that the file would re-open claiming left siting whatever it holds. Write raw instead, or accept the mislabelling explicitly.

Every written frame is read back off disk and byte-compared against a freshly rendered reference before the command reports success. That check proves the bytes landed intact. It cannot tell you the pattern was the one you wanted, and the readout says so.

A run reports where it is by frame, in two passes: it writes every frame, then re-reads and checks every frame. "Verifying frame 12 of 30" means the file is already written and Videre is checking it. Cancel stops at the next frame; the temporary file goes with it, and anything already at the destination is left exactly as it was.

Preview in Videre writes the current spec to a temporary file and opens it, so the scopes measure the real thing rather than the window's thumbnail. The preview thumbnail is a plausibility check: it is capped at 384 pixels wide and applies no transfer.

After a write, Reveal in Finder and Open in Videre appear beside the receipt.

Two things worth knowing about opening a generated file. Opening any file while an edit stack is in progress discards that stack, here as everywhere else in Videre. And opening re-checks the licence, so an expired trial stops there.

15.5 · From the command line#

videre generate -o bars.y4m --pattern bars --size 1920x1080 \
    --format yuv422p10 --fps 25 --frames 250 --matrix bt709

videre generate -o hdr.y4m --preset hdr-bars-pq-uhd --json

videre generate -o clip.y4m --spec-file spec.json

--list-patterns prints the catalogue with a line on what each pattern is for; --list-presets prints the presets. --param key=value sets a pattern's own fields, using the same names the window's controls carry and the same names a spec file uses. --spec-file takes a full specification, which is the way to compose several segments.

The same specification always produces the same bytes. Two runs of one command give byte-identical files, and the --json receipt carries the specification that made the file, so feeding a saved receipt back through --spec-file reproduces it exactly.

The Signal Generator window: preview, segments, pattern and overlay cards on the left, format, interpretation and output on the right.
The signal generator. Color bars at 1080p25, 4:2:2 10-bit, BT.709 video range, left siting, with the frame counter overlay on. Generate… writes the file and verifies every frame.

16 · Command-line tool#

Videre → Install Command-Line Tool… links the bundled videre binary into /usr/local/bin. Ten subcommands on the same engine as the app:

videre generate -o bars.y4m --pattern bars …  # write a synthetic test clip, verified
videre inspect  file.mp4              # format, interpretation, metadata → JSON
videre compare  ref.y4m dist.mp4      # PSNR / SSIM / MS-SSIM / VMAF / ΔE → JSON
videre bitstream file.hevc --frames   # parameter sets / SEI / RPUs + GOP stats → JSON
videre container file.mp4             # ISO box tree → JSON
videre retag    in.mp4 -o out.mp4 …   # repair signalling, verified
videre edit     in.mp4 -o out.y4m …   # bake an edit recipe, verified
videre verify   master.mp4 --strict   # delivery checks, exit code for CI
videre conform  master.mp4 --spec …   # check against a delivery spec, exit code for CI
videre scenes   clip.mp4 --json       # shots, per-shot stats, keyframe plans, exports

videre edit replays a recipe saved from Edit mode (--ops recipe.json) or, with no recipe, does a verified passthrough - y4m to raw and back, or an MP4/MOV decoded out to raw frames. Output is raw or y4m only, routed by the output extension. --out-format, --out-range, --chroma-filter, and --working-space are the command line's half of the Output row, so a format conversion scripts the same way it clicks. --report adds the per-operation census over the whole clip (samples touched per channel, largest code delta, one line or one JSON entry per operation in the recipe), which is how a batch run proves which repair did the work; it is opt-in because counting costs a pass over every sample. Exit codes match retag: 0 ok, 1 error, 2 usage, 3 the written file failed verification (and was not kept).

videre verify is the delivery gate: it runs six checks (color agreement between the container and the coded stream, declared against measured MaxCLL/MaxFALL, mastering display consistency across carriers, chroma siting, edit list sanity, system-decoder openability) and exits nonzero when one fails, so a pipeline can block a bad file before upload. Warnings pass by default; --strict fails them, and --fail-on / --warn-on tune single checks. Exit codes: 0 clean, 1 a check failed, 2 usage, 3 the analysis could not run, so a script can tell a bad deliverable from a broken gate. --json gives the same verdicts with the measured numbers included.

Raw inputs take a spec: --raw 1920x1080:i420:video:bt709 on inspect, --raw-a / --raw-b on compare. A preset saved in the app's parameter sheet works anywhere a spec does: --raw-a preset:mezz carries the full declaration, including strides and color.

Reports use a stable, versioned schema, so scripted QC can pin against it.


17 · Shortcuts and Finder Services#

Shortcuts and Finder reach the same engine as the app and the command line.

Shortcuts (the macOS Shortcuts app) gets three actions:

  • Inspect Video File: the inspect report as a JSON file. Takes a path; raw files add a spec (1920x1080:i420) or preset:NAME. An optional frame number adds per-component min/max/mean statistics.
  • Compare Video Files: the full compare report as a JSON file (PSNR, SSIM, MS-SSIM, VMAF, CAMBI, delta E per frame plus aggregates). The first path is A, the reference; an offset shifts B.
  • Verify Video File: the delivery checks, returned as a chainable verdict: Passed (true/false), per-severity counts, and the report text, so a Shortcut can branch ("if Passed is false, move the file to rejects"). Strict promotes warnings to failures, matching videre verify --strict.

Paths are text parameters, so they bind to the clipboard, Ask for Text, or any text variable; plain, tilde, file://, and quoted paths all resolve. The JSON files carry the same versioned schema as the command line (section 16), and untagged SDR files read under the BT.1886 default regardless of the app's Analysis setting, so a Shortcut produces the same numbers on every machine.

Finder Services (right-click a video file › Services):

  • Compare in Videre: select exactly two renders; they open as a compare session with the first file as A, the reference.
  • Inspect to JSON with Videre: writes the inspect report to Downloads, named after the source file, and reveals it in Finder. No window opens.

The entries appear for MP4/MOV/y4m files. Raw files need a declared format, so they go through the app or the command line instead.


18 · Keyboard reference#

KeysAction
⌘O / ⇧⌘OOpen / open comparison file
⌘GSignal generator
⌘1⌘6Edit / Compare / Measure / Conform / Scenes / Metadata mode (press again to leave)
⌘FReinterpret raw file
⌘IInfo panel
SpacePlay / pause
/ Step one frame
⌘← / ⌘→First / last frame
⌘JFocus the jump field
⌘LLoop playback
⌥I / ⌥O / ⌥⌘LLoop in / out at the playhead / clear the loop range
-drag on the rulerPaint the loop range (-click clears)
-drag on the rulerPaint the Edit selection (Edit mode; ⌥⌘-drag paints both)
⌘+ / ⌘− / ⌘0 / ⌥⌘1Zoom in / out / fit / actual size
MLoupe
V / ⇧VNext / previous display channel
T / CTone map to SDR / clipping highlight (HDR)
[ / ] / \Display exposure −0.5 EV / +0.5 EV / reset (HDR)
⌥⌘IShow / hide the scopes inspector
⌘R / ⌥⌘RRotate clockwise / counterclockwise
XToggle A/B
⇧⌘AAnalyze the whole clip
⇧⌘RRun Metrics (compare)
⌥↑ / ⌥↓ / ⌥⌘0Nudge / reset the compare offset
⌥⌘EExport window
I / OMark selection in / out (Edit mode)
Remove selected frames (Edit mode)
⌘Z / ⇧⌘ZUndo / redo edit op (Edit mode)
⇧⌘CCompare the edit with the source (Edit mode)
⇧⌘EExport (opens the export window)
click / dragPick a pixel or region (Edit mode, Patch row)
-click / -dragAdd to the pixel selection (Edit mode)
-click / -dragRemove from the pixel selection (Edit mode)
-arrowsExtend the pixel selection (Edit mode)
⇧⌥-arrowsMove the pixel selection (Edit mode)
⌥← / ⌥→Previous / next cut (Scenes mode)
⌘B / ⇧⌘BAdd / remove a cut at the playhead (Scenes mode)
⇧⌘LLoop the current shot (Scenes mode)
EscClear the selection (any mode: the pixel selection, and a Measure line or ruler)
⌥⌘C / ⇧⌘SCopy frame / save frame as PNG
⇧⌘MMetadata mode (alias of ⌘6)
⌃1⌃9Toggle analyzers (see section 6)
⌃⌥1⌃⌥9Pop analyzer out to its own window

19 · Cross-validation#

Videre's numbers are pinned to external references, not to itself: PSNR matches ffmpeg's psnr filter to the printed precision; VMAF and CAMBI are gated against the reference vmaf CLI; HDR10+ metadata parsing against hdr10plus_tool; container decoding against GPAC's mp4box and libheif's heif-info; bitstream parsing against ffprobe, MediaInfo, and known encodes from x264, x265, and SVT-AV1. Color math anchors (BT.601/709/2020, BT.2100 PQ and HLG, BT.2124, CIEDE2000) are pinned to published test values, and the display shader is tested per-pixel against the CPU reference.

Two documented deviations, stated rather than hidden: SSIM follows the canonical Wang 2004 definition, which reads a few 10⁻⁴ from ffmpeg's x264-derived variant; and the HLG display preview applies the system gamma per channel while readout and measurements use the luminance-correct form.

Of these, only libvmaf ships inside the app (statically linked, BSD+Patent); its license text is under Settings › Acknowledgements. The rest are development-time references, and ffmpeg encodes run through whatever ffmpeg is already on your Mac.

Screenshots in this guide use the Blender Foundation open movies Big Buck Bunny (© 2008 Blender Foundation / bigbuckbunny.org) and Tears of Steel ((CC) Blender Foundation / mango.blender.org), both CC-BY.

Back to top ↑