v0.4.1 — recording FPS fix, GLFanout encode-only, JSch ProGuard fix
PixelPilot v0.4.1
Bumps the Devourer submodule to v0.4.1 (RTP-sequence reorder → fixes dongle
video quality drops) plus three app-side fixes.
1. Recording FPS: no more progressive slowdown
The mp4 muxer stamped every sample with a fixed 90000/fps cadence. When the
actual decode rate (60 / 90 / 120 fps) != the configured fps, each sample's
timestamp was wrong by a constant factor, so a long recording's total duration
drifted from real time — the longer you recorded, the slower playback got.
Now samples are stamped from the real wall-clock encoder PTS
(\eglPresentationTimeANDROID, fed through \AMediaCodecBufferInfo.presentationTimeUs)
for the GL-fanout DVR, and from the NALU \creationTime\ for the legacy DVR path.
Duration tracks wall-clock at any source fps.
2. GLFanout: encode-only render path
The DVR encoder now receives every decoded frame at the full decode rate
while the display surface is throttled (prevents BLAST buffer exhaustion). The
encoder's timestamps stay in sync with the source, avoiding the drift above.
3. ProGuard: JSch ClassNotFoundException fix
Release builds (\minifyEnabled = true) stripped \com.jcraft.jsch.jce.*
because JSch loads its crypto providers reflectively
(\getJceName()\ → \Class.forName). Opening SSH/settings then threw
\ClassNotFoundException: com.jcraft.jsch.jce.Random.
Added -keep class com.jcraft.jsch.**\ and -dontwarn\ for JSch's optional
Android-absent deps (jna / bouncycastle / log4j / slf4j / newsclub / ietf-jgss).
Verification
On-device: 0 ClassNotFoundException on settings/SSH path; connect stable
(state→7); RTP reorder backlog 0; render 89–91 fps; recording duration matches
wall-clock.
Full diff: \c1cfbb0\ (one commit since v0.4.0). Devourer submodule at v0.4.1.