Skip to content

jpegio moves here from displayif (media Phase 1) - #40

Merged
bdbarnett merged 3 commits into
mainfrom
media/1-jpegio
Oct 6, 2026
Merged

bdbarnett merged 3 commits into
mainfrom
media/1-jpegio

Conversation

@bdbarnett

@bdbarnett bdbarnett commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Phase 1 of the media modules roadmap (anchor docs/media-modules-roadmap.md): jpegio moves here from displayif as modules/jpegio, with its tests and a CI workflow that builds it from a bare clone (with and without LVGL). It also pins the displayif that no longer carries it (PyDevices/displayif#50) and the lvgl-micropython that checks for jpegio rather than displayif (PyDevices/lvgl-micropython#21).

Evidence (Gate 1):

  • The golden corpus is identical on unix, the P4 DEV-KIT and the S3 LCD-7 (7 frames, 28 digests; 35 s and 163 s on the boards).
  • An LVGL lv.image puts a JPEG on the glass through jpegio. The panel framebuffer matches jpegio's own decode in 76800 of 76800 pixels on both the KeDei (P4) and the LCD-7 (S3), and in 76.86 % when the image is planted 4 px off.
  • displayif without jpegio builds for the S3, the P4, the Pico, the Pico 2, Windows and WebAssembly, and its CI is green.

Also fixed: a coordinate past a machine word is the same ValueError on 32-bit boards as on 64-bit unix (it was an OverflowError there), and the golden test no longer needs sys.argv.

modules/jpegio is displayif's src/jpegio and tests/jpegio, unchanged in
behaviour: CircuitPython's JpegDecoder API on the vendored TJpgDec, and
LVGL's JPEG decoder when lvgl-micropython is in the build. Its own glue
(manifest.py, micropython.cmake/.mk) replaces displayif's; displayif's
build.h and __revision__ stamp are gone (the build record has the commit).
A firmware that wants JPEG now names jpegio; all includes it.

.github/workflows/jpegio.yml builds it from a bare clone with build_mp.py
and runs its golden corpus with and without LVGL, plus the one-TJpgDec
check (these moved from displayif's clean-build workflow).
exercise_build.sh's Picos name jpegio, as displayif gave it them before.

Locally: unix --modules jpegio passes the corpus (7 frames, 28 digests);
unix with jpegio,lvgl-micropython passes it beside LVGL and puts 3 frames
through lv.image exactly, with exactly one jd_prepare in the firmware.
…checks

decode()'s x and y went through MP_ARG_INT, so on a 32-bit board an int
past a machine word (the test's 2**62) raised OverflowError from the
argument parser before jpegio's own "0..65535" check; on 64-bit unix it
fit and the check caught it. They are parsed as objects now, and anything
that isn't a small int is out of range: the same ValueError, with the
value in the message, on every platform. The golden test read sys.argv,
which the esp32 builds lack; it uses getattr(sys, "argv", []).

tests/board_lvgl_glass.py draws a corpus JPEG with lv.image and compares
the panel framebuffer with jpegio's own decode of the same file. On the
P4 DEV-KIT with the KeDei panel: 76800 of 76800 pixels match, and 76.86 %
when the image is planted 4 px off.
@bdbarnett
bdbarnett marked this pull request as ready for review October 6, 2026 16:24
@bdbarnett
bdbarnett merged commit 1266f85 into main Oct 6, 2026
2 checks passed
@bdbarnett
bdbarnett deleted the media/1-jpegio branch October 6, 2026 16:25
bdbarnett added a commit that referenced this pull request Oct 19, 2026
…ock (#40) (#59)

The sound card advertised a feedback endpoint and sent 0 on it, so the host
played at its own rate and the board at its codec's. At 44.1 kHz on the P4
the I2S queue stayed full and the pump dropped samples about once a second.

The pump now estimates the codec's consumption (I2S DMA bytes) and the
host's clock against the board's (frames received over frames asked for),
both accumulated from the start of the stream on the board's clock, and sets
the value that makes them agree with tud_audio_fb_set. A write timeout or a
starved DMA buffer adds a small, decaying nudge the other way. Values stay
within 0.5 % of nominal.

_usbif.uac_feedback(False) turns it off; uac_pump_clock() reports the value,
its offset from nominal, and the clock estimate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant