Skip to content

← All documentation

Post-install setup · Y2Reborn

Reborn Platform 1.0: FFmpeg, metadata and library ingest

Documentation published by SchulzCode/Y2Reborn.

Instructions published by the project, shown here word for word.

Reborn Platform 1.0: FFmpeg, metadata and library ingest

2026-10-04. Verdict: PLATFORM_V1_READY_WITH_LIMITATION for this software subpass. Metadata ingestion is substantially faster, bounded and better tested. The new candidate has not been qualified on physical SD storage with concurrent playback; this receipt does not close the wider Platform 1.0 hardware gates.

Baseline: Reborn b71b468860233faa0a42b8448ec5777fa952b8e3; Linux worktree base b5aea93. Implementation: a22107c53fc841f7f7e6e7767822ebec720bea99, followed by 43a695c for the sidecar-only collection-open correction. Work is isolated on codex/platform-v1-ffmpeg-metadata. No main-worktree edits, flash or push. Existing Luca author/committer identity was reused without changing Git settings.

Compact measured evidence preserves samples, phases, RSS, component versions and fixture hashes. Raw local receipts are in ignored out/media-pass/. Admission and database-extension audits are in the paired roadmap audit. Retained UART01 hardware evidence identifies Linux e9e8d63, Reborn b71b4688, boot fd955840-35d9-47db-83e0-ff47d6bb2d2b, taint 0. It proves bounded installed playback/storage/CPU behavior, not this candidate's library throughput. The shared device lock was busy with the separate storage lane; this pass did not operate the physical device. That lane's owner-reported SDR104 results remain separate evidence.

Later receipt update: the storage owner supplied actual 1,000-file stock scanner receipts for Baseline02 on DATA and SD. They were read and summarized below, with original hashes in the compact evidence. This adds physical baseline evidence; the new metadata candidate still has no physical run.

1. Current metadata architecture and file-open trace

The architecture remains file → direct FFmpeg demux/decode/metadata → Reborn media abstractions → stereo float DSP → sink conversion → ALSA/BlueALSA. No FFmpeg CLI subprocess, replacement framework or production tag parser was introduced. The lazy shared media membrane remains process resident; each demux/decoder context has one owner and is closed by Rust Drop.

StageBaselineCurrent
Discovery/filterDirectory queue, case-insensitive supported suffixes, pinned source rootDepth-first directory iterators, maximum depth 32; supported regular files only; symlinks skipped
Incremental identityWhole-source map of complete track rowsAt most 64 candidate stamps: source/path, size, nanosecond mtime, extractor revision
Changed-file initial openPlayback Decoder::openDemux-only MediaFile::open; one regular-file descriptor, custom FFmpeg AVIO
avformat_open_input / detectionFFmpeg, 2 MiB probe budgetSame FFmpeg format detection and probe budget
avformat_find_stream_infoAlwaysComplete single-audio-stream header path skips it; otherwise normal bounded analysis
Codec/DSP setup during scanAudio decoder, two resamplers, FLTP graph, packet/frame stateNone; FLAC codec extradata initialization supplies channels/precision without decoding frames
Tags/propertiesShared with playback, some incorrect aliases/propertiesOne common extractor for inspection and playback
Artwork during scanAttached picture could be decoded by stream analysisDetection only; picture streams discarded during analysis; no thumbnail decode
DB publishBatch 64; reused rows cloned/upserted/reindexedBatch 64; reused rows update seen/deleted only; changed rows preserve ID at same source/path
Finish/removalSource guards; wall-clock scan generationSame guards plus strictly increasing generation; prune only complete, identity-consistent sources
Collection coverAnother complete playback openEmbedded cover: another lightweight inspection on a cache miss. Sidecar-only track: no media open
PlaybackSeparate decoder openSeparate decoder open, necessary for current codec/packet/seek state; artwork uses that same owner

An unchanged incremental file has zero media opens and zero FFmpeg parses. A newly indexed file has one media open. If its embedded cover is subsequently requested, a collection-cache miss adds one lightweight open; playback adds its own necessary open. The four-entry collection pixel cache avoids repeat embedded decoding. No scanner stores encoded artwork or keeps thousands of demux contexts alive to avoid that occasional second open. Sidecar discovery and decoding are on demand. Each external image is opened once per decode attempt, with a size check before allocation.

The fast header path is admitted only for FLAC, WAV, AIFF, APE, WavPack, Ogg and MP4/M4A when there is one audio stream and usable rate, channels and duration. MP3, raw AAC, multiple audio streams and incomplete headers retain avformat_find_stream_info and av_find_best_stream. FFmpeg may decode limited audio during that fallback; it is not a whole-track decode. No lower probe or analysis limit was used to improve the benchmark. FFmpeg documents probing and analysis controls separately in AVFormatContext. The exact local FFmpeg 9.0.2 demuxer/decoder sources were also inspected.

2. Bugs found

3. Metadata correctness

Container tags take precedence; an absent/empty container value falls back to the selected stream. FFmpeg owns case/encoding/container normalization. Missing title remains empty at the media boundary and becomes the filename at ingestion. Repeated Vorbis values retain FFmpeg's deterministic first;second representation; the product does not guess a new artist-splitting convention.

FieldBehavior / evidence
Title, artist, albumUTF-8-safe bounded copy; invalid bytes repaired deterministically by Rust; AIFF author fallback
Album artistalbum_artist, then albumartist; Unicode FLAC/ID3/APE and existing MP4/Ogg assertions
Track, discStrict unsigned number or number/total; 3/12 → 3, 1/2 → 1; invalid/negative/overflow → 0
Date/year, genreExtracted as bounded raw strings, date then year; exposed in Metadata. Current Track/DB/UI does not persist these fields
ComposerNo existing product field; intentionally not added
DurationSelected stream time base preferred; container fallback; explicit Ogg Opus pre-skip removed; MP3 Xing and MP4 edit handling preserved
Codec/rate/channelsEncoded codec ID/name and codec parameters, constrained to supported audio limits; playback/header agreement tested
Source bits/formatPCM encoding, or raw/coded lossless precision; lossy unknown remains 0/unspecified, never “32-bit” because decoding is float
Decoder/DSP/sinkSeparate fields; inspection leaves decoder/DSP/output fields empty; playback still reports decoder format, FLTP and negotiated packed sink
ReplayGainFour independently validated fields; gain ±60 dB, peaks 0..16, finite only. Explicit valid tags precede coded side-data fallback
Embedded artJPEG/PNG/WebP attached pictures with usable bounded packets; corrupt art can fail independently of audio metadata
External artShared case-insensitive cover/folder/album preference; regular files; corrupt candidate falls through
Delay/paddingManual codec skip side data enabled correctly; existing sample-trim path retained; exact MP3/Opus/M4A frame counts asserted

FLAC/ALAC/APE 24-bit or 16-bit precision is distinct from a 32-bit decoder container. WAV float32 really is a 32-bit float source and is labeled pcm_f32le; lossy AAC/MP3/Vorbis/Opus are unspecified precision. WavPack is labeled lossless-N-bit, avoiding an unsupported claim that its encoding is necessarily integer. Bitrate prefers the audio codec parameter and otherwise uses FFmpeg's container estimate; an unavailable estimate stays zero.

4. Performance bottlenecks

Native phase measurements found playback setup costing approximately 0.38–0.58 ms per short track, versus 0.06–0.15 ms for initial demux open. It dominated the old metadata path. For the sparse 180-second PCM WAV, stream analysis dominated: 17.74 ms and 720,940 bytes read, compared with no stream analysis and 65,580 bytes on the metadata header path. FFmpeg still reads beyond the initial WAV header to find supported trailing metadata; the implementation does not stop at an assumed 44-byte header.

Whole-row incremental DB rewriting and repeated library-count queries were the next demonstrated costs. The final 10k initial scan's median measured metadata work was about 0.83 seconds, DB request/transaction wait about 0.16 seconds, and total 1.08 seconds. An unchanged scan did no FFmpeg work; DB wait plus traversal dominated its 130 ms. These phase timers are nested: do not add FFmpeg open/probe time to metadata time. DB time includes channel wait and SQL, not only SQLite CPU time. Artwork time during library scanning is zero.

The 1,500-open concurrency experiment took 152/68/35 ms on the host for 1/2/4 metadata workers (QEMU exploratory run 821/393/200 ms). That experiment omits physical SD contention, playback and CPU policy. The product remains serial with a bounded DB pipeline; these figures do not establish the best worker count on a quad Cortex-A7. No desktop worker pool was added.

5. Memory bottlenecks and bounds

The old incremental map retained complete metadata strings for every indexed track, then cloned rows. It added about 10 MiB RSS for 10k rows. Directory queues could also grow with breadth. Both are replaced by bounded candidates and a depth-first iterator stack. The baseline filter pool amplified emulated ARM memory/thread overhead. Graphs without active EQ, including crossfade, now use one thread, and at most two for the slice-threaded stereo EQ.

ResourceCurrent bound
Scan candidates, DB publish batch, identity results64 files/rows each; synchronous acknowledgment
Directory stack / supported files33 iterators / existing 250,000-file guard
Scanner request/result channels, DB commands1 / 2 / existing 32; no unbounded new task queue
Native FFmpeg allocation32 MiB per allocation, initialized once before workers regardless of logging setup
Header + analysis I/O32 MiB aggregate per open, including rereads; 10-second cancellation deadline; regular nonempty files only
Pending native PCM allocation32 MiB; normal playback releases only the header byte budget after initialization
Exported textExisting 512-byte title/artist/album/album-artist buffers; date 128, genre 512; UTF-8 repair remains bounded
Encoded artwork16 MiB per image packet/file; max 16 streams per input
Decode dimensionsJPEG 16 Mi pixels with FFmpeg lowres up to 1/8; PNG/WebP 4 Mi pixels
UI pixels / collection cache160×160 RGBA = 100 KiB; four successful embedded covers = 400 KiB plus bounded replies
Sidecar candidatesAt most 12 paths; no complete directory list retained

PNG/WebP do not offer a reduced-resolution decoder here, so oversized images are refused rather than decoded fully. The JPEG 4000×4000 fixture reduces to 500×500 before scaling to the UI buffer. Its header dimensions are obtained through FFmpeg's MJPEG decoder with frames discarded, not a custom JPEG parser. The per-allocation limit is not a promise that the whole process consumes at most 32 MiB; measured process RSS includes FFmpeg mappings, SQLite and workers.

6. Changes made

MediaFile owns a demux-only native context and shares extraction/artwork functions with playback. Custom AVIO preserves FFmpeg detection while enforcing regular files, byte budget and cancellation, and closes its AVIO buffer and file exactly once. Attached images are excluded from analysis. Metadata and gapless fixes are listed above; DSP math and sink packing remain covered by the existing regression matrix.

Ingestion uses lean batched identity queries, moves extracted strings into changed rows, and only marks reused IDs seen. It checks dev/inode/size/mtime/ ctime after extraction and source identity before publishing/finishing. One bad file is logged and does not prevent later tracks being indexed. Existing conservative deletion behavior is preserved: a source with failures retains its old rows until a complete scan can safely prune.

The additive metadata_revision INTEGER NOT NULL DEFAULT 0 column preserves SQLite schema/user_version 1 and row IDs. Old rows reparse once and successful rows record extractor revision 2. A malformed file cannot force every other track to reparse on subsequent scans. Rapid scan generations now increase strictly, including across reopening the database.

Collection and playback share sidecar selection. Only successful embedded pixels are cached against the track stamp; sidecars are checked anew on a new request. Playback validates cached pixel file length before reading it. A sidecar-only collection request skips opening the music file entirely.

7. Intentionally unchanged

FFmpeg 9.0.2, supported media/artwork matrix, probe/analyze budgets, the decoder/ float DSP/sink architecture, SQLite/WAL ownership, row identity, source UUID/ mount protections, rebuild behavior and bounded playback queues remain. No content hash is computed for every rescan. Identical content at two paths is two library entries; duplicate filenames on different media remain distinct. Renames/moves become a new source/path entry and prune the old path after a complete scan; queue ID preservation across moves is not an existing promise.

Playback still calls stream analysis: startup decoder state and correct trim/ seeking matter more than borrowing the scanner shortcut. A separate playback open is necessary. Source replacement, hotplug and DB recovery protections were already correct and retain their tests. No kernel, memory-layout, hardware, partition, firmware, networking, video, streaming or DRM scope was added.

8. Before/after metadata parse times and playback startup

Host x86_64, Rust 1.90.0, FFmpeg 9.0.2; 20 direct native owner initializations per fixture, both C builds -Os. Timer stops before owner close. Baseline C is the original b71b468 implementation with timing instrumentation only. OS cache is uncontrolled; these are warm p50 latency measurements, not SD latency. All p95 values and I/O phases are in the compact evidence.

FixtureBefore msAfter metadata msAfter playback open ms
FLAC 24/960.5850.0530.200
MP30.6640.1390.307
Raw AAC0.8200.1790.582
M4A AAC0.7750.0560.591
M4A ALAC0.6240.0540.338
Vorbis0.8430.0800.446
Opus0.7020.0710.223
WAV PCM240.5300.0630.134
WAV float320.5690.0480.211
AIFF PCM240.4980.0490.122
APE0.5180.0350.127
WavPack0.8140.0460.432
FLAC + JPEG / PNG / WebP0.716 / 0.718 / 0.6880.063 / 0.062 / 0.0610.283 / 0.189 / 0.276
Sparse 180-second WAV18.3060.08518.200

Playback improvements come from bounded graph threads and avoiding picture analysis, not weaker format detection. The long WAV remains analysis-bound at playback open, intentionally. These measurements exclude sink negotiation, DAC/radio behavior and audible start latency. First lazy membrane load was about 21–35 ms in the benchmark processes and is visible in maxima; it is not repeated for every file.

Artwork after this pass: embedded JPEG/PNG/WebP warm p50 0.150/0.112/0.151 ms; 4000×4000 external JPEG p50 3.764 ms, max 4.022 ms, 10/10 successful decodes. Corrupt/oversized fixtures return errors without crashing. The standalone artwork benchmark process peaked at 47,464 KiB. No comparable pre-change large image decode receipt was collected, so no invented artwork speedup is claimed.

9. Before/after library scans

Same read-only 15-variant mixed corpus, fresh DB per initial scan, immediate unchanged rescan; three alternating before/after runs. The source scanner and DB are the product implementations, not a loop around a tag parser. The old host harness uses the old ABI/native library explicitly; the ARM archive's product source files match b71b468 byte for byte. Corpus is synthetic and short: 1,000 files total 23,703,609 bytes, not music-sized SD bandwidth.

TracksFirst before msFirst after msFirst files/s before → afterIncremental before → after ms
10094311,053 → 3,1391 → 1
1,0007541251,325 → 7,99017 → 8
10,0007,4081,0841,350 → 9,218191 → 130

These are medians. The 10k first-scan ranges were 7,384–7,514 ms before and 1,084–1,102 ms after; incremental 189–195 and 122–135 ms. Earlier shared-host runs were noisier (after first scan 1.2–3.8 seconds); they were retained locally, not substituted into the alternating comparison. No global cache flushing or CPU/governor changes were performed.

Cortex-A7 user-mode QEMU, exact Baseline02 ARM libraries and four allowed host CPUs: 1,000-track median first scan 17,058 → 692 ms, unchanged 109 → 66 ms. First ranges: 16,259–19,382 → 687–705 ms. QEMU especially magnifies the original filter-thread setup cost. This validates ARM behavior and relative cost under emulation, not a physical Y2 speed estimate. Production scanning remains one worker. Every unchanged scan reused all files and recorded zero FFmpeg opens/analysis/I/O in the candidate metrics.

The independent storage lane then ran the exact stock ARM scanner harness (16e64c9e… SHA256) against the installed old media membrane, on both physical volumes in its own lock slot. Receipt identity: Linux 8584ccd85f052f351fe51650b2348c83ca894ed4, Reborn b71b4688, Baseline02, kernel 6.18.0-y2linux-baseline-02, rootfs 2025.02.18-platform-v1.21, boot 27e6d684-3794-4490-95db-a489027cd4f4; closing taint 0. These are single bounded runs of the same 1,000-file, 23,703,609-byte corpus:

Physical stock baselineInitial ms / files/sIncremental msInitial / cumulative peak KiB
DATA, eMMC HS2005,526 / 181.039310,468 / 10,656
SD, ext4 SDR1045,495 / 182.040110,580 / 10,936

Both initial scans indexed all 1,000 files with zero failures; both rescans reused all 1,000. Controller fault deltas were zero during write/fsync, read/SHA256 and scanning. Separate storage workload rates were DATA 1.731 MB/s write/fsync and 3.078 MB/s read/SHA256, SD 1.532/3.034 MB/s; those are small-file workload rates, not FFmpeg parse rates. Aggregate CPU busy during each initial+incremental scanner process was about 27%. Private scratch was cleaned and services/modes/settings left unchanged by that slot. The next device slot is reserved for suspend work; this lane did not acquire the device. Receipts originate in storage's ignored out/platform-v1-storage/{emmc,sd}-corpus.json and corpus-restored.stdout, copied immutably to this pass's ignored evidence. There is no physical candidate after-number, concurrency comparison or speedup extrapolation from these stock results.

10. Peak memory measured

Linux /proc/self/status VmHWM, maximum across each three-run group; KiB. The scan process includes libraries/DB/log worker but not the GUI or simultaneous playback. Incremental HWM is cumulative within the initial+rescan process.

TracksInitial before → after KiBThrough incremental before → after KiB
10054,432 → 51,11254,536 → 51,136
1,00055,388 → 52,48856,368 → 52,496
10,00056,808 → 53,71666,488 → 53,720

At 10k, the measured process peak is about 64.9 → 52.5 MiB. Remaining modest growth includes SQLite page/cache state, not retained artwork blobs. QEMU 1k peak was 133,592 → 35,536 KiB; those values include emulator mappings and translated code and must not be described as physical ARM process RSS. No physical candidate peak RSS was measured. The later physical stock scanner peaks in section 9 are real ARM process measurements, still excluding the running GUI/whole-application memory. They must not be compared as an after-result to the host or QEMU figures.

11. Metadata edge cases covered

The metadata fixture manifest records 17 fixtures, sizes, hashes and generation provenance. Coverage includes FLAC comments, UTF-8/UTF-16 ID3v2, APE tags, WAV INFO, AIFF NAME/AUTH, existing MP4/M4A and Vorbis/Opus tags; Japanese/accented text, missing/empty tags, duplicate/multiple values, invalid UTF-8, long strings, track/total, multi-disc, negative/overflow ordinals, non-finite/malformed ReplayGain, four gain/peak fields, embedded JPEG/PNG/WebP, corrupt art, malicious declared lengths/dimensions, zero-length media, mixed-case sidecars and fallback after corrupt covers.

Deterministic fuzz-style tests exercise 99 truncation/header-XOR cases across nine formats. A generated 33 MiB multi-tag FLAC is refused by the aggregate I/O budget in both inspection and playback. Dimensions of 100,000×100,000 are rejected. Metadata and valid subsequent library tracks survive bad artwork/ media. Exact gapless output counts remain MP3 11,025, Opus 12,000 and M4A AAC 11,025 frames for their 250 ms fixtures. Source precision, duration and channel/ rate agreement are checked between inspection and playback.

Library tests cover same-path changes with stable ID, removal and move pruning, unchanged scans with a trigger forbidding metadata rewrites, a good+bad library, same-size/mtime replacement detection during extraction, source identity changes, incomplete traversal, SQL failures/ENOSPC and preserved prior rows. Migration removes the new column from a populated schema-1 fixture, reopens it, proves one-time old-row reparse and subsequent reuse even with an invalid neighbor.

12. Files changed

13. Validation and reproduction

CheckResult
cargo fmt --all -- --checkPASS
cargo clippy --workspace --all-targets --locked -- -D warningsPASS
cargo test --workspace --lockedPASS, 252 tests; media 32, library 30
tools/build/cross.sh with exact Baseline02 Buildroot SDKPASS, ARM workspace release, Cortex-A7 hardfloat
Fresh ARM media/library test binaries under QEMUPASS, 32 + 30 tests
Fresh ARM daemon + control/media checksPASS, six checks; decoder/database/library diagnostics explicitly assert passed
Native dependencies / runtime policyPASS, FFmpeg 9.0.2 six-library ABI; required formats/decoders/filters; file protocol only
Native ASan/UBSan/LSan ownership stressPASS, 26 fixture arguments × 20 iterations: inspect/art/read/cancel/close; no reported leak or invalid access
Python syntax / diff whitespacePASS
Reborn documentation links/catalogPASS, 59 pages / 572 local links
Physical new-candidate scan/concurrent playbackNOT_RUN
Physical stock 1k scan/reuse, DATA and SDPASS, separate storage owner receipts; zero failures/controller fault deltas

Runtime versions: avutil 61.1.102, avcodec/avformat 63.1.102, avfilter 12.1.102, swresample 7.1.102, swscale 10.1.102. ELF and runtime manifests agree. Production has no FFmpeg CLI, encoders/muxers, network or libavdevice. The sanitizer rebuild covers the membrane driver; FFmpeg shared dependencies were not themselves rebuilt with sanitizers. These tests are bounded malformed-input regression checks, not comprehensive fuzz qualification. The paired Linux documentation check finds one unchanged legacy Y2Player link whose sibling repository is absent from the isolated worktree layout; its original target exists. All new links resolve. No unrelated documentation was rewritten to accommodate that layout.

cargo build -p reborn-library --example media_bench --release --locked
python3 tools/build/media_bench.py --output out/new-media-receipt --repeats 3 --long-wave
target/release/examples/media_bench artwork assets/fixtures/metadata
target/release/examples/media_bench parallel out/new-media-receipt/parse-fixtures
python3 tools/build/metadata_fixtures.py

# Caller supplies the exact production SDK; no device access.
Y2_BUILDROOT_OUTPUT=/absolute/buildroot-output sh tools/build/cross.sh
# Run inside an isolated environment providing qemu-arm and the ARM rootfs:
python3 tools/build/media_qemu.py --sysroot /absolute/arm-rootfs \
  --binaries target/armv7-unknown-linux-gnueabihf/release --scratch out/new-qemu-receipt

The benchmark refuses existing scratch/output, reads media only and writes its own DB/logs. To reproduce baseline scans, archive b71b468, add the measurement example using its original Decoder metadata path and build against its matching membrane. Do not run a new Rust binary against an old native membrane or vice versa; the opaque private ABI changed and the pair must be built/packaged together.

cc -g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer \
  tools/build/media_sanitize.c -o /tmp/reborn-media-sanitize \
  $(pkg-config --cflags --libs libavformat libavcodec libavutil libavfilter libswresample libswscale) -lm
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 /tmp/reborn-media-sanitize \
  assets/fixtures/tone.flac assets/fixtures/mp3.mp3 assets/fixtures/m4a-aac.m4a \
  assets/fixtures/vorbis.ogg assets/fixtures/opus.opus assets/fixtures/wav-pcm24.wav \
  assets/fixtures/aiff-pcm24.aiff assets/fixtures/ape-silence.ape \
  assets/fixtures/wavpack-silence.wv assets/fixtures/metadata/*

The 26-argument sanitizer receipt used the nine listed original formats plus the 17 fixture files, excluding manifest.json (the wildcard above also tests that unsupported JSON input fails cleanly). Large JPEG regeneration uses the direct-library encoder in jpeg_fixture.c; encoders remain host fixture tooling only. Fixture writers are not production tag parsers.

14. Commits

a22107c — Harden FFmpeg metadata and bound incremental library ingestion. 43a695c — Skip media opens for sidecar-only collection artwork; explicitly assert QEMU diagnostic success. bf1c50a records the initial receipt and 0d692f2 the paired Linux audit. Following documentation commits reconcile the later physical stock receipts; their hashes are in the handoff. No push.

15. Remaining Platform 1.0 limitations

16. Verdict

PLATFORM_V1_READY_WITH_LIMITATION. This media software subpass is ready for integration and bounded physical qualification. Correctness/ownership and ARM regressions pass; 10k ingestion is about 6.8× faster, incremental work is lean, and scan memory no longer holds the library's complete raw metadata/art corpus. No substantial engine or database rewrite is justified by the measurements. The next evidence boundary is the matched candidate's guarded SD scan alongside playback, under the shared device lock; no hardware milestone is closed here.

Published by the SchulzCode/Y2Reborn project [1] [3]