pipewire/spa
George Kiagiadakis 4e46489964 bluez5: fix shared A2DP endpoint caps including disabled companion codecs
Codecs that share an A2DP endpoint (e.g. aac + aac_eld) previously used
an asymmetric pattern: one codec (the "owner") had fill_caps and quietly
advertised the union of all siblings' capability bits; companions had
fill_caps = NULL.

This caused a bug: when aac_eld is absent from bluez5.codecs, the "aac"
endpoint still advertised the ELD object-type bit because a2dp_codec_aac's
fill_caps emitted it unconditionally (gated only by eld_supported(), never
by enabled_codecs). A remote could then select ELD; SetConfiguration
resolved the transport to a2dp_codec_aac (the only fill_caps holder for "aac")

Refactor to a symmetric, composable model:

- Add bool endpoint_companion to struct media_codec (default false = owner).
  Companion codec objects set this flag instead of fill_caps = NULL.
- Add combine_caps() function to struct media_codec. Owners that share
  an endpoint implement this to union two capability blobs of the same
  codec_id.
- Each codec's fill_caps now describes only its own bits. AAC LC advertises
  only LC object types; AAC ELD advertises only the ELD type (or returns
  -ENOTSUP when FDK-AAC lacks ELD support).
- Bump SPA_VERSION_BLUEZ5_CODEC_MEDIA 16 -> 17.

On the monitor side (bluez5-dbus.c):
- New media_codec_fill_endpoint_caps() helper fills the owner's caps then
  walks enabled companions on the same endpoint and merges each via
  combine_caps. All five endpoint-registration fill_caps call sites are
  routed through this helper.
- endpoint_should_be_registered() gates on !endpoint_companion (not on
  fill_caps != NULL), so companions correctly skip endpoint registration.
- media_endpoint_to_codec() now filters by is_media_codec_enabled and
  prefers owners as a tiebreaker.
- New media_endpoint_to_codec_for_config() resolves SetConfiguration by
  calling each enabled candidate's validate_config against the negotiated
  config bytes. This ensures that an "aac" endpoint carrying ELD bytes is
  mapped to a2dp_codec_aac_eld (not a2dp_codec_aac).
- AAC validate_config and codec_init are id-gated so a stale ELD config
  can never be decoded by the LC codec object.

Assisted-by: Claude Opus 4.7
2026-06-30 21:21:24 +03:00
..
examples examples: set diffent Clock and Position on source 2026-05-11 14:02:29 +02:00
include io: flesh out the node IO_Latency 2026-06-30 12:35:00 +02:00
include-private/spa-private spa: move dbus helpers out of bluez plugin 2024-02-05 13:03:20 +00:00
lib spa: update lib.c 2026-03-09 18:33:32 +01:00
plugins bluez5: fix shared A2DP endpoint caps including disabled companion codecs 2026-06-30 21:21:24 +03:00
tests tests: don't redefine spa_assert 2026-05-25 11:05:35 +02:00
tools tools: port various tools to the new json-builder 2026-02-26 10:51:17 +01:00
meson.build meson: Always use -fno-strict-aliasing and -fno-strict-overflow 2025-07-24 07:30:28 +00:00