Commit Graph

5 Commits

Author SHA1 Message Date
157888d6d8 [0.1.13] Models load when first needed, and unload after 10 minutes unused
- No model is made at startup (private memory there falls from about 4.3 GB to about 420 MB).
  ocr_ui_models_ready makes the OCR engine, then the label engine and the list's set, on the OCR
  thread when a reading, a scan (the button, -scan, or after a capture or an import) needs them;
  the OCR and scan buttons wait for them, showing "Loading the models...". A like: search asks
  for the label engine alone (labels_ui_want) and is worked out again once it is up.
- ocr_ui_unload_idle_models, each frame and also in the tray: an engine (OCR, labels or
  segmentation) unused for MODELS_IDLE_UNLOAD_SECONDS (10 min) is destroyed by an UNLOAD task on
  the OCR thread, never during a scan, a waiting read or scan, or while search jobs hold the label
  engine. The label list's set stays, so loading again does not score the prompts again.
- Choosing another OCR model with none loaded only notes it; -segment no longer waits for the OCR
  and label engines. Some 1.4 GB stays after an unload, the CUDA runtime it loaded.
2026-10-12 21:58:17 +01:00
72f2754226 [0.1.8] Video capture phase 5: sound, from the computer and the microphone, in sync
- modules/Screen_Record/audio_source.jai: WASAPI, in loopback from the default output device
  (what the computer plays) and from the default input device (the microphone), asked for as
  48 kHz stereo float, which Windows converts any device to; a device that will not convert is
  taken as it is when it gives 48 kHz float. Packets carry the time they were heard. A device
  lost (unplugged, default changed) is opened again from the new default once a second.
- An audio thread mixes them onto the video's own timeline: the same time 0, less the same
  pauses (record_pause now keeps one account of time paused for both threads). A packet within
  30 ms of where its source left off follows on exactly; a source that sends nothing is silence,
  passed 200 ms late. Each 1024 samples every source has covered become an AAC frame.
- encoder.jai: an AAC stream (FFmpeg's aac, 160 kb/s) beside the video, written from the audio
  thread; both threads' packets meet in the file under a lock. The remux keeps it.
- [video] system_audio (true) and microphone (false). capture.json: Audio, AudioSources. A toast
  when a source asked for could not be opened.
- record-probe: -audio system|mic|both, the sound read back (length, level), and -sync-test,
  which flashes a white square and beeps together every 2 s, then finds both in the file.
- Measured: 20 s, beeps 0-21 ms from their flashes, no drift; both sources mixed, 5-18 ms;
  a 6 s pause cuts the same 6 s from sound and video; 3 min, 85 of 90 beeps within 3-24 ms and
  -14 ms from first to last, with 5 outliers (53-147 ms) where two beeps went missing. Tests:
  an MP4 with sound keeps its AAC stream through the remux into the library (30 checks).
2026-10-10 08:08:47 +01:00
59c5b8dd62 [0.1.6] Video capture phase 4: border, toolbar, pause, discard, recovery, leftovers, [video]
- src/app/screen_record_win32.jai: while recording, a red frame just outside the region (one
  window shaped by a window region, clicks let through) and a toolbar beside it (below the
  region at its right, else above, else inside a whole screen's top right): a blinking dot,
  the time less time paused, the size, frames dropped and screen losses, and Pause/Resume,
  Stop, and Discard, confirmed in the toolbar itself ("Yes, discard / No"). GDI windows that
  never take the focus, kept out of every capture (WDA_EXCLUDEFROMCAPTURE). Buttons only ask;
  screen_record_frame acts on the next frame. On the shutdown thread they are hidden, not
  destroyed.
- modules/Screen_Record: record_pause; while paused the source is drained but nothing is sent,
  and frames' times leave the pause out, so the video has no gap. Record_Stats.paused_seconds;
  Record_Testing.LOSE_DUPLICATION loses Desktop Duplication every 3 s.
- Recordings left in %TEMP%/mcap by a crash are offered at startup: into the library (no window
  known; size from its frames, date from its name), deleted, or later.
- [video] in settings.config: fps (1-120, 30), cursor (true), capture (auto, dxgi, wgc); written
  into existing files on the next launch.
- The Win32 GDI bindings move to src/base/platform/win32_gdi_bindings.jai, shared by the overlay
  and the toolbar.
- -record-region X Y W H and -record-ui-visible for -record; -pause SECONDS and -lose for
  record-probe. capture.json's Paused.
- Checked: the toolbar is not in a whole-screen recording's frame; a 10 s pause leaves a 6.2 s
  video of a 16 s run at a steady 30 fps (DXGI and WGC); 3 simulated losses in 10 s recover with
  no gap. Tests: a leftover's date and its write (22 checks in the recording group); all pass.
- Fixed on the way: a recording's path repeated the temporary folder ("%1" is the first argument).
2026-10-10 07:45:14 +01:00
93274a2b04 [0.1.5] Video capture phase 3: Ctrl+PrintScreen records a region into the library
- record_region, a new [global_hotkeys] action on Ctrl-PrintScreen (Windows only; none on
  macOS): starts a recording, or stops the one running.
- The overlay's video mode (screen_capture_win32.jai): red outline and magnifier; the drag held
  to the screen it began on; under 240 x 180 (record_size_allowed, in Screen_Record) the outline
  is dashed, the label gives the minimum, and letting go takes nothing; a click or Enter takes
  the whole screen; no pixels copied. With immediate, no overlay at all: the screen under the
  cursor, for PrintScreen while recording.
- src/app/screen_record.jai: records with modules/Screen_Record to %TEMP%/mcap at 30 fps; a
  recording that stops by itself keeps what it has, as does quitting (the shutdown step stops it).
  The MP4 goes into the library through the stills' jobs: a video .mcap in Screen Captures, the
  MP4 its original, a frame of it its rendered image, metadata.json as a still's, capture.json
  with Duration, FrameRate, VideoCodec, PosterTime, Encoder, Capture and DroppedFrames; the MP4 is
  deleted once it is in. The catalog reads a video's keys from capture.json too.
- The capture thread makes itself aware of each monitor's DPI: ImGui makes only the main thread
  aware, and Desktop Duplication refused the app's capture thread with DXGI_ERROR_UNSUPPORTED
  (the fallback recorded with Windows.Graphics.Capture, and the log said so).
- -record SECONDS records the screen under the cursor, puts it in the library and exits;
  -record-quit quits while recording instead. Both pass on a scratch library.
- Tests: a "screen recording" group (the size rule; an MP4 from the module's encoder written as a
  recording reads back, and the catalog takes it as a video). The segment overlay test no longer
  depends on the colours chosen in the app's own data folder.
- README, the format's README and the plan describe it.
2026-10-10 07:14:35 +01:00
7f8bcdd1ad [0.1.1] Screen capture: PrintScreen freezes the screens, a dragged region goes to the clipboard and the library
- capture_region, a new [global_hotkeys] action, on PrintScreen by default (Windows only; none on
  macOS). Existing settings files get the line appended on the next launch. When the key cannot be
  registered, the log names Snagit and Windows' "Print screen opens screen capture" setting.
- app/screen_capture_win32.jai: every screen copied the moment the key fires (BitBlt with
  CAPTUREBLT over the virtual desktop), shown darkened in a topmost GDI window in a modal loop of its
  own, so it works with mcap hidden in the tray. Dragging shows the region bright and outlined; a
  magnifier shows the pixels under the cursor with its position or the selection's size; arrow keys
  move a pixel (ten with Shift). A click or Enter takes the whole screen under the cursor; Escape,
  a right click or losing the focus cancels. Only the parts that change are redrawn.
- app/screen_capture.jai: the region goes on the clipboard (CF_DIB) at once, then a thread writes it
  into the library's "Screen Captures" folder as a PNG .mcap: metadata.json with the window under
  the region's middle (its title as WindowName, its program's description as AppName) and
  capture.json (where on the desktop, the program's path, the hash). mcap then comes to the front
  showing it, and OCR, labels and segmentation read it as they read an import.
- A "screen capture" group in the import tests: the file written, its pixels, preview and Capture
  Text read back. README and the format's README describe it.
2026-10-10 06:17:43 +01:00