Skip to content

fix(pipeline): scale odd-sized streams to even resolution - #389

Open
noesisx8 wants to merge 1 commit into
SeaDve:mainfrom
noesisx8:fix-odd-stream-resolution
Open

noesisx8 wants to merge 1 commit into
SeaDve:mainfrom
noesisx8:fix-odd-stream-resolution

Conversation

@noesisx8

Copy link
Copy Markdown

Fixes #357

Problem

Recording with the MP4 or Matroska profile fails with Can not initialize x264 encoder when the captured stream has an odd width or height — typical for window captures. The pipeline log shows the underlying cause:

x264enc gstx264enc.c:1331: width not divisible by 2 (1365x717)
gstx264enc.c(1965): gst_x264_enc_init_encoder (): ... Can not initialize x264 encoder.

x264 requires even dimensions, but the even rounding previously only existed in the select-area path (videoscale + videocrop). Captures without a selection linked the stream directly to the encoder queue.

Fix

When there is no area selection and the combined stream size is odd or unknown, insert a videoscale restricted to even stepped caps (width/height = [2, 65536, 2]). This way videoscale follows the actually negotiated size (after videoflip/compositor) and rounds down to even, instead of relying on portal metadata that may be missing or disagree with the buffers. Streams known to be even are linked directly, as before.

The combined size of multiple streams is computed as the sum of widths and the maximum height, matching how they are stacked horizontally by the compositor.

The stepped range maximum is 65536 rather than i32::MAX because larger values overflow videoscale's internal aspect-ratio arithmetic, producing empty ([0, 0]) caps during negotiation.

Verification

  • Unit tests for the combined-size computation (single, odd, multiple, unknown size).
  • gst-launch check: 1365x717 input with the stepped caps negotiates to 1364x716; even input passes through unscaled.
  • Smoke test: recorded an odd-sized window to MP4 successfully.
  • cargo fmt --check and cargo clippy -- -D warnings are clean.
  • cargo test passes except for 5 failures (i18n, profile, settings tests) that also fail on unmodified main in this environment (missing installed gresource, should-panic behavior).

Some encoders (e.g., x264enc used by the MP4 and Matroska profiles)
require even resolution, but streams without area selection (e.g., a
window capture) may have odd dimensions, failing with "Can not
initialize x264 encoder". The even rounding previously only existed in
the select-area path.

When the combined stream size is odd or unknown, insert a videoscale
restricted to even stepped caps so it follows the negotiated size and
rounds down to even. Streams known to be even are linked directly as
before. The combined size of multiple streams is the sum of widths and
the maximum height, matching how they are stacked horizontally.

The stepped range maximum must be well below i32::MAX, as larger values
overflow videoscale's internal aspect-ratio arithmetic.

Fixes SeaDve#357
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.

"Can not initialize x264 encoder" on ArchLinux

2 participants