3.4.1 — HE-AAC plays natively (no needless EAC3 bridge)
Fixed
HE-AAC no longer needlessly bridged to EAC3 (#33)
HE-AAC (SBR) and HE-AACv2 (PS) audio tracks were unconditionally routed through the audio bridge and re-encoded to EAC3, even from movie containers that AVPlayer decodes natively. Reported by DrHurt (#33), who confirmed a manual remux and a Jellyfin server-side remux both played fine.
Root cause. The HE-AAC detection (profile == AAC_HE / AAC_HE_V2, or an SBR frame_size of 2048) forced the bridge for every HE-AAC source. That was only ever justified for the live ADTS/MPEG-TS path, where the source carries no AudioSpecificConfig and prepareAACForFMP4 has to synthesize one. The synthesized ASC declares plain LC at the SBR output rate (e.g. mp4a.40.2 @ 48 kHz for a 24 kHz core), which AudioToolbox decodes as garbage (-11821). A movie container already ships a correct ASC in extradata, so fMP4 stream-copy preserves the SBR/PS signaling and plays natively.
Fix. The HE-AAC bridge decision now lives in a pure, unit-tested aacRequiresBridge(profile:frameSize:hasASC:) and is gated on the source lacking an ASC. With an ASC present the track stream-copies; without one (live) it still bridges, exactly as before.
Verified end-to-end with aetherctl serve on a real HE-AAC track (same file, before vs after):
before: audio: HE-AAC (profile=4 frameSize=2048) ... bridging instead -> audio=bridge, codec=...,ec-3
after: audio: codec=aac -> stream-copy as `mp4a.40.2` -> audio=stream-copy, codec=...,mp4a.40.2
Full test suite green (62 tests, incl. 6 new AACBridgeRoutingTests).
Full changelog: https://github.com/superuser404notfound/AetherEngine/blob/main/CHANGELOG.md