75474dcc90
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>
17 lines
894 B
Diff
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);
|