Files
punktfunk/crates/pyrowave-sys/patches/0003-devel-encode-16bit-read.patch
T
enricobuehler 75474dcc90 fix(pyrowave): guard 4:4:4 modes that overflow the rate controller's block index
The vendored rate controller packs its wavelet block index into 16 bits
(RDOperation.block_offset_saving), so a mode whose 32x32-block count exceeds
u16::MAX wraps inside the controller and corrupts the bitstream — ~8K-class
4:4:4 territory. Compute the exact count (`block_count_32x32`, the counting walk
of upstream init_block_meta, pinned against the validated Apple WaveletLayout)
and expose `pyrowave_mode_fits_rdo`; the negotiator downgrades such a session to
4:2:0 before the Welcome (the honest-downgrade channel), and both encoders
refuse outright if one slips through rather than emit a wrapped stream.

Vendor patches: 0002-rdo-saving-clamp (analyze_rate_control.comp clamps the
saving accumulation to the target, same overrun class as 0001; slangmosh.hpp
regenerated), 0003-devel-encode-16bit-read (devel tool y4m 16-bit plane reads;
tool-only, kept so the vendored source stays honest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 01:16:51 +02:00

17 lines
894 B
Diff

diff --git a/crates/pyrowave-sys/vendor/pyrowave/encode.cpp b/crates/pyrowave-sys/vendor/pyrowave/encode.cpp
index 95725551..2e78fada 100644
--- a/crates/pyrowave-sys/vendor/pyrowave/encode.cpp
+++ b/crates/pyrowave-sys/vendor/pyrowave/encode.cpp
@@ -201,7 +201,10 @@ static void run_encoder(Device &device, const char *out_path, const char *in_pat
for (auto &img : inputs.images)
{
auto *y = cmd->update_image(*img);
- if (!input.read(y, img->get_width() * img->get_height()))
+ // PUNKTFUNK PATCH 0003: size the plane read in BYTES, not texels — 16-bit y4m
+ // inputs otherwise read half a plane and desync the stream after frame 1.
+ if (!input.read(y, size_t(img->get_width()) * img->get_height() *
+ YUV4MPEGFile::format_to_bytes_per_component(input.get_format())))
{
LOGE("Failed to read plane.\n");
device.submit_discard(cmd);