← Commit history

docs/recording: 60fps GPU-path clips, equal-bitrate comparison, 4px recording dot

John Lauer ·f35464d35a ·1mo ago ·parent a38add8
1 file changed +59−42
docs/recording.md+59−42
@@ -4,31 +4,42 @@ Adom Bridge records your screen, a whole monitor or a single window, to an **MP4** file, on your machine, with the system audio mixed in. It is native: Windows Graphics Capture for the pixels and Media Foundation for the encode, with a **hardware encoder** (NVENC / Quick Sync / AMD) doing the work and the-frames staying on the GPU end to end. No browser, no screenshot loop, no extra-capture app.+frames staying on the GPU end to end, for both codecs. No browser, no screenshot+loop, no extra capture app.  ## It can never record you silently -Whenever an AI records your screen, a small **animated Adom orbital sits in the-bottom-right corner** for the whole take. It is the Orbital Lab animation-itself, the same one Hydrogen shows while it installs, rendered in a-transparent window that is click-through and never takes focus, so it marks the-recording without getting in the way of what you are recording. You can see it-in the corner of all four clips below. Starting a desktop recording also forces+While a take is running, a **4 pixel teal dot** sits in the corner of your+screen, out of the way of whatever you are recording. It is deliberately tiny+and deliberately still: recordings often get sped up 10x afterwards, and+anything that moves looks wrong at 10x. Starting a desktop recording also forces the AI to confirm it means the *whole desktop* and not just one window. The clip is a normal MP4 you keep; Adom Bridge prunes its own recordings folder (oldest first) so it never fills your disk, and never touches a clip that is still being written. +If you want the Adom orbital on screen for its own sake, that is a separate+verb: `desktop_orbital {"action":"show","size":220,"corner":"top-left"}` puts+the real Orbital Lab animation up as a transparent, click-through overlay, the+same single-file WebGL loader Hydrogen shows while it installs. It has nothing+to do with recording.+ ## The verbs  | Verb | What it does | |---|---| | `desktop_record_start` | Start a take. `{monitor}` (or `"primary"`) for a screen; `{hwnd}` / `{titleContains}` for one window. Optional `fps` (default 30), `codec` (`h264` default, `h265`), `bitrate` (bits/s), `audio` (default on for a monitor). | | `desktop_record_stop` | Stop and finalise. Answers within its budget; if the encoder is still closing the file it reports `state:"finalising"` and you poll status, so the take is never dropped. |-| `desktop_record_status` | Live state: `frames`, `bytes`, `droppedFrames`, `encodeFps`, `state` (recording, finalising, finalised). |+| `desktop_record_status` | Live state: `capturedFrames`, `captureFps`, `bytes`, `droppedFrames`, `framePath`, `state`. | | `desktop_record_list` | Finished clips on disk. |-| `desktop_record_encoders` | Which codecs this machine can hardware-encode (see below). |+| `desktop_record_encoders` | Which codecs this machine can hardware-encode. |+| `desktop_orbital` | The Orbital Lab overlay, unrelated to recording. |++**`captureFps` is the honest number.** Windows Graphics Capture only hands over+a frame when the desktop actually changed, so the capture source, not the+encoder, sets the real framerate. Ask for `fps: 60` and you get it if the screen+is doing something; ask for 30 and 30 is your ceiling no matter how fast the+machine is.  ## H.264 vs H.265: see it and size it @@ -42,53 +53,54 @@ desktop_record_encoders     default:"h264" } ``` -- **H.264** is the default and plays everywhere.-- **H.265 (HEVC)** reaches the same picture at roughly **half the bitrate**. It needs a reasonably modern player.+- **H.264** is the default, encodes at **High** profile, and plays everywhere.+- **H.265 (HEVC)** reaches the same picture for fewer bits. Halve the `bitrate`+  against H.264 and you get a file about half the size that still holds up. It+  needs a reasonably modern player.  ### Four takes of the same scene  Adom Bridge recorded the **Orbital Lab** (a live Babylon.js 3D hydrogen-orbital-animation, spinning the whole time) in a browser window sized to 80% of the-screen, capturing the **full screen** on an idle test PC with an NVIDIA GPU.-Same scene, same 20 seconds, at two resolutions and in both codecs. H.265 was-given **half the bitrate of H.264** at each resolution, which is the honest-comparison: it is the bitrate saving that H.265 buys you. Every number below is-from `ffprobe` on the finished file.+animation, spinning the whole time) in a browser window sized to exactly 80% of+the screen, capturing the **full screen** on an idle test PC with an NVIDIA GPU.+Same scene, 20 seconds, at 60 fps, at two resolutions and in both codecs.++Both codecs were given the **same bitrate** at each resolution. That is the fair+comparison: it shows what each one does with an identical budget, rather than+flattering one of them. Every number is from `ffprobe` on the finished file, and+**no take dropped a single frame**.  | Clip | Resolution | Codec | Bitrate asked for | File size | Bitrate measured | Framerate | |---|---|---|---|---|---|---|-| 1 | 1080p | H.264 | 8 Mbps | 17.6 MB | 7.05 Mbps | 27.9 fps |-| 2 | 1080p | **H.265** | 4 Mbps | **9.5 MB** | 3.8 Mbps | 30.0 fps |-| 3 | 1440p | H.264 | 14 Mbps | 30.8 MB | 12.3 Mbps | 27.9 fps |-| 4 | 1440p | **H.265** | 7 Mbps | **16.6 MB** | 6.65 Mbps | 30.0 fps |--Every clip is 20 seconds of the same scene, captured full-screen. At each-resolution **H.265 lands at about half the size of H.264**, which is the whole-point of giving it half the bitrate: the picture holds up. The hardware HEVC-encoder also held a steady **30 fps** where H.264 dipped to about 28 on this-busy 3D scene. Neither codec dropped a single frame.-+| 1 | 1080p | H.264 High | 8 Mbps | 18.6 MB | 7.44 Mbps | 55.1 fps |+| 2 | 1080p | **H.265 Main** | 8 Mbps | **17.4 MB** | 6.97 Mbps | 55.2 fps |+| 3 | 1440p | H.264 High | 14 Mbps | 32.5 MB | 12.98 Mbps | 54.9 fps |+| 4 | 1440p | **H.265 Main** | 14 Mbps | **30.4 MB** | 12.15 Mbps | 55.0 fps | -Each player is labelled with its own resolution and codec, so you always know which one you are watching.+Given the same budget, H.265 comes in a little smaller and spends its bits more+efficiently on the picture. The bigger win is the one this table does not show:+ask H.265 for half the bitrate and you get roughly half the file for a+comparable image. Both codecs ran on the GPU zero-copy path here, and both+captured about 55 real frames per second. -#### Clip 1 of 4 - 1080p, H.264 - 17.6 MB at 7.05 Mbps, 27.9 fps+#### Clip 1 of 4 - 1080p, H.264 High - 18.6 MB at 7.44 Mbps, 55.1 fps  <video src="docs/recording/orbital-1080p-h264.mp4" controls muted loop playsinline width="720"></video> -#### Clip 2 of 4 - 1080p, H.265 - 9.5 MB at 3.8 Mbps, 30.0 fps+#### Clip 2 of 4 - 1080p, H.265 Main - 17.4 MB at 6.97 Mbps, 55.2 fps  <video src="docs/recording/orbital-1080p-h265.mp4" controls muted loop playsinline width="720"></video> -#### Clip 3 of 4 - 1440p, H.264 - 30.8 MB at 12.3 Mbps, 27.9 fps+#### Clip 3 of 4 - 1440p, H.264 High - 32.5 MB at 12.98 Mbps, 54.9 fps  <video src="docs/recording/orbital-1440p-h264.mp4" controls muted loop playsinline width="720"></video> -#### Clip 4 of 4 - 1440p, H.265 - 16.6 MB at 6.65 Mbps, 30.0 fps+#### Clip 4 of 4 - 1440p, H.265 Main - 30.4 MB at 12.15 Mbps, 55.0 fps  <video src="docs/recording/orbital-1440p-h265.mp4" controls muted loop playsinline width="720"></video> -If your Markdown viewer does not play inline video, the four files are on-this page under `docs/recording/`.+If your Markdown viewer does not play inline video, the four files are on this+page under `docs/recording/`.  ## Examples @@ -97,8 +109,8 @@ this page under `docs/recording/`. desktop_record_start '{"monitor":"primary","audio":true,"reason":"capturing the export walkthrough"}' desktop_record_stop  '{}' -# Record in H.265 at half the bitrate for the same picture-desktop_record_start '{"monitor":"primary","codec":"h265","bitrate":7000000,"reason":"..."}'+# 60 fps, H.265 at half the bitrate for roughly half the file+desktop_record_start '{"monitor":"primary","codec":"h265","fps":60,"bitrate":7000000,"reason":"..."}'  # Record one window in the background, no audio desktop_record_start '{"titleContains":"KiCad","codec":"h265","bitrate":6000000,"reason":"..."}'@@ -106,11 +118,16 @@ desktop_record_start '{"titleContains":"KiCad","codec":"h265","bitrate":6000000,  ## Under the hood -- **GPU zero-copy:** the captured frame goes WGC surface, then a pooled GPU-  texture, then the hardware encoder through a shared Direct3D device. No copy-  to system memory.+- **GPU zero-copy, both codecs:** the captured frame goes WGC surface, then a+  pooled GPU texture, then the hardware encoder through a shared Direct3D+  device. No copy to system memory. `desktop_record_status` reports `framePath`+  so you can see which path a take actually took. - **H.265 path:** the hardware HEVC encoder wants NV12, so Adom Bridge runs a   Direct3D VideoProcessor to convert each frame on the GPU, and writes HEVC into   a standard MP4 (`hvc1`) alongside an AAC audio track.+- **Full colour range** is preserved end to end, so smooth shading on a dark+  scene does not band. - **Timestamps track a wall clock shared with the audio**, so a long screen and-  audio recording stays in sync and finalises quickly instead of stalling.+  audio recording stays in sync and finalises quickly instead of stalling. A+  tick with no new frame behind it is skipped rather than re-encoded, so the+  framerate in the file is the framerate that was captured.