Skip to content

gstreamer: fix processing crashes on fixed-output-bus + float textures#130

Closed
jcelerier wants to merge 1 commit into
mainfrom
fix/gstreamer-channels-and-float-texture
Closed

gstreamer: fix processing crashes on fixed-output-bus + float textures#130
jcelerier wants to merge 1 commit into
mainfrom
fix/gstreamer-channels-and-float-texture

Conversation

@jcelerier

Copy link
Copy Markdown
Member

Found by running actual processing (gst-launch pipelines) through the GStreamer elements, not just inspecting registration — a sweep that went from 4 crashes to 0.

1. Compile (clang): float* vs unsigned char*

texture_filter.hpp cast the mapped buffer to unsigned char* and assigned it to field.texture.bytes, which is float* for float textures → clang error. (MSVC never reaches this — it fails earlier on a GLib macro collision; building via msys2 clang64 compiles the binding, 92/93 plugins vs 0 on MSVC.) Cast to the field's own pointer type with decltype.

2. Crash: fixed output bus fed fewer channels

per_bus_as_ports_fixed, test_audio_bus_fixed, oscr_Distortion segfaulted on the first buffer. set_caps set output_channels = input channels and never called impl.init_channels(), so an object with a fixed_audio_bus<…, 2> output fed a mono stream wrote to unallocated output channels. (Same class as the Max multichanneloutputs bug, #127.)

Fix: size the planar buffers to max(caps channels, the object's own in/out counts) and call impl.init_channels(in, out) before prepare().

3. Crash: float texture over 8-bit RGBA caps

test_tex_rgba32f read 4× past the buffer: the element advertises 8-bit RGBA caps (4 B/px) but a float texture is 16 B/px. Until the caps are made format-aware, skip non-byte textures (leave bytes null so the effect early-outs) instead of an OOB read.

Validation

audiotestsrc/videotestsrc … ! <element> ! … ! fakesink across every built plugin:

  • before: 4 crashes
  • after: 0 crashes; 22 elements push audio/video through cleanly.

Pairs with #129 (needed to configure a GStreamer-only build). The 68 elements that don't register are per-sample/mono/controls-only shapes with no GStreamer element mapping (graceful, not crashes).

🤖 Generated with Claude Code

… compile

Three fixes, found by actually running processing (gst-launch) through the
elements rather than only inspecting registration:

1. audio_filter compile: `field.texture.bytes` is `float*` for float textures,
   but line 122/142 cast the buffer to `unsigned char*` -> clang error
   (MSVC never got this far -- it fails earlier on a GLib macro). Cast to the
   field's own pointer type via decltype. Now 92/93 gstreamer plugins compile
   with clang (0 with MSVC).

2. audio_filter crash on fixed output buses (per_bus_as_ports_fixed,
   test_audio_bus_fixed, oscr_Distortion): set_caps used output_channels =
   input `channels` and never called impl.init_channels(), so an object with a
   fixed_audio_bus<..,2> output fed a mono stream wrote to unallocated output
   channels -> segfault on the first buffer (same class as the Max bug).
   Size buffers to max(caps, the object's own in/out channel counts) and call
   impl.init_channels(in, out) before prepare().

3. texture_filter crash on float textures (test_tex_rgba32f): the element
   advertises 8-bit RGBA caps (4 B/px) but a float texture's bytes are 16 B/px,
   so the effect read 4x past the GStreamer buffer. Until the caps become
   format-aware, skip non-byte textures (leave bytes null -> effect early-outs)
   instead of reading out of bounds.

Validation: gst-launch processing sweep across all built plugins went from
4 crashes to 0; 22 elements now push audio/video through cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
@jcelerier

Copy link
Copy Markdown
Member Author

Superseded by #137, which combines all outstanding work into a single PR.

@jcelerier jcelerier closed this Jul 2, 2026
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