Commit Graph

8 Commits

Author SHA1 Message Date
Skyler Lehmkuhl da65b63bdf Repair test suite + fix sample key-range overlap bug
The suite had accumulated breakage from prior refactors:
- selection unification: rewrite the integration tests for the single
  unified clip_instances collection (shapes+clips are one set now).
- tempo-map: thread a TempoMap (constant 60 BPM = identity) into the
  clip remap_time tests so the second-based expectations hold.
- drop two dead rgba_to_yuv420p tests that asserted tight plane sizes
  incompatible with the function's 16-macroblock alignment.
- ignore the WIP theme var() cascade test (theme system not wired up).

Also a real bug the tests caught: auto_key_ranges produced overlapping
sample key ranges (the midpoint key mapped to both adjacent samples).
Start each range one past the previous midpoint.
2026-06-23 19:07:06 -04:00
Skyler Lehmkuhl ce151ffd61 Pack video into .beam and stream frames + audio from the blob
Video was the only media type always kept external (VideoClip.file_path),
so a project with video wasn't self-contained. Now video packs into the
SQLite container under the same large-media policy as audio (pack < 2 GB
unless the user chose Reference), and both the frames and the embedded audio
track decode by streaming directly from the blob — no temp files.

- New crate ffmpeg-blob-io: an AVIOContext-over-Read+Seek shim (BlobInput)
  that lets ffmpeg demux from an arbitrary byte source. Isolates all the
  unsafe FFI + ffmpeg ABI coupling (version-pinned =8.0.0/=8.0.1). Manual
  Drop teardown order; AVSEEK_SIZE restores the read position (FFmpeg assumes
  a size query doesn't move it — required for MP4 moov-at-end).
- Schema/save/load: VideoClip.media_id; save_beam packs/references video as
  MediaKind::Video (keyed by clip id); load resolves packed vs referenced and
  reports missing sources. A packed clip points its linked video-audio pool
  entry's media_id at the video row so the audio streams from the same blob.
- Frames: video.rs VideoSource{Path,Packed} threaded through new/seek/scan/
  probe/thumbnails (a fresh BlobReader per open); editor builds the source
  from current_file_path (now set before register_loaded_videos).
- Audio: VideoAudioReader::open_source via BlobInput; the disk_reader
  StreamSource block on packed video-audio is removed; the engine's existing
  factory activation routes it unchanged.

Tests: ffmpeg-blob-io AVIO unit tests (WAV via Cursor, seek, open/drop loop);
core packed_video_stream (blob->AVIO->Input) and beam_archive video round-trip;
daw-backend open_source test (compiles; links/runs only off-container).
Runtime-verified: a packed video plays frames + audio after the source file
is removed.
2026-06-22 09:17:10 -04:00
Skyler Lehmkuhl 3d7cff9ad0 Stream audio & video from .beam container; waveform LOD pyramid + persistence
Migrate the .beam container to SQLite and stream media from it instead of
decoding whole files into RAM on import/load.

Container & large files:
- SQLite .beam container (beam_archive) with in-place transactional saves and an
  incremental BlobReader; supports both packed (chunked blobs) and referenced
  (external path) media, with a user preference + first-import prompt for files
  over the large-media threshold.

Audio streaming:
- Stream packed compressed audio on load via an inversion-of-control blob factory
  (AudioBlobSourceFactory): daw-backend defines the trait, core implements it
  over BlobReader, so the audio engine stays container-agnostic.
- Bulk-activate disk streaming for all loaded clips after SetProject.
- Sample-accurate compressed seek (SeekMode::Accurate; Coarse mislands on VBR).

Video:
- Video frames decoded/streamed on demand; thumbnails generated asynchronously
  on a dedicated decoder so import/load never blocks the UI.
- The video's audio track is streamed on demand via an ffmpeg VideoAudioReader
  as a separate editable AudioClip (no /tmp WAV extraction).

Waveform overview:
- Streaming min/max LOD pyramid (waveform_pyramid), bounded memory, configurable
  floor B; serialized into the container and restored on load (or generated in
  the background from the packed blob when absent), so no re-decode on reload.
- GPU min/max upload path; integer-LOD textureLoad fixes zoom-dependent wobble.
2026-06-17 13:52:38 -04:00
Skyler Lehmkuhl 99f8dcfcf4 Change vector drawing primitive from shape to doubly-connected edge graph 2026-02-23 21:29:58 -05:00
Skyler Lehmkuhl 2222e68a3e Work on region select 2026-02-21 06:04:54 -05:00
Skyler Lehmkuhl 1fcad0355d handle preview rendering during shape editing 2025-12-23 09:36:54 -05:00
Skyler Lehmkuhl c943f7bfe6 Add info panel 2025-11-30 10:01:10 -05:00
Skyler Lehmkuhl 8f830b7799 tests 2025-11-29 13:39:31 -05:00