Skip to content

fix(encode): pad odd dimensions so H.264 encode produces web-ready video - #21

Merged
Chouffe merged 1 commit into
mainfrom
fix/h264-encode-odd-dimensions
Jun 4, 2026
Merged

Chouffe merged 1 commit into
mainfrom
fix/h264-encode-odd-dimensions

Conversation

@Chouffe

@Chouffe Chouffe commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Problem

aris-encode --video-codec h264 silently fails on ARIS clips with odd
dimensions
(e.g. 924×1765, a common sonar frame size). libx264 with
yuv420p requires even width and height, so ffmpeg fails to open the
encoder:

[libx264] height not divisible by 2 (924x1765)
Error while opening encoder
Nothing was written into output file — Conversion failed!

Worse, the failure was silent: encode_video_with_h264_codec caught the
ffmpeg.Error and returned normally, and the CLI exited 0 while leaving a
0-byte output file. A whole batch looked successful but produced empty files.

Discovered while converting a 107-clip ARIS selection (all 924×1765) for web
playback — every output was empty.

Fix

  • Pad to even dimensions before libx264: pad=ceil(iw/2)*2:ceil(ih/2)*2
    (adds at most a 1px border, no rescaling). Even-sized inputs are unchanged.
  • Web-ready flags: pix_fmt=yuv420p and movflags=+faststart for reliable
    in-browser playback (moov atom moved to the front for progressive streaming).
  • Stop swallowing errors: re-raise ffmpeg.Error (the docstring already
    documents Raises: ffmpeg.Error) and fix the malformed error-log call.
  • CLI exit code: aris-encode now counts failures and exits non-zero,
    mirroring aris-convert.

Test

Adds test_encodes_odd_dimension_video, which builds a real odd-dimension
(63×65) clip the way pyARIS does (MJPEG frames piped to mpeg4 — cv2.VideoWriter
silently rounds odd dims down to even) and asserts the output is non-empty with
even dimensions. This test fails on main and passes with the fix.

All 77 unit tests pass; ruff check and ruff format --check clean.

aris-encode failed on odd-sized ARIS clips (e.g. 924x1765) because libx264
with yuv420p requires even width and height. The encoder failed to open and
wrote a 0-byte file, yet the CLI still reported success and exited 0.

- Pad each dimension up to the next even number before libx264 (adds at most
  a 1px border, no rescaling).
- Set pix_fmt=yuv420p and movflags=+faststart for reliable browser playback.
- Re-raise ffmpeg errors instead of swallowing them (the docstring already
  documents this), and fix the malformed error log call.
- Make the encode CLI count failures and exit non-zero, mirroring aris-convert.
- Add a regression test that encodes a real odd-dimension (63x65) clip.
@Chouffe
Chouffe merged commit 09e822d into main Jun 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant