493. The platform decoders are part of media
Date: 2026-09-30
Status
Accepted. Supersedes the module boundary of
ADR-0472, which put
the system decoders in a module of their own, goldberry-media-platform. What
ADR-0472 and ADR-0489
decided about the decoders themselves still stands.
Context
:media-platform held the DecoderProviders that hand H.264, HEVC, AAC, AC-3
and E-AC-3 to the operating system: VideoToolbox and AudioToolbox on macOS,
GStreamer on Linux, Media Foundation on Windows. ADR-0472 made it optional, like
every content module, so an application that did not want the system’s decoders
would not get them.
It was optional in name only.
- It ships no native code. It binds libraries the system already has with FFM. An application that does not decode H.264 loses nothing by having it: a provider is asked only about a track in one of its codecs, and binds its system’s libraries on that first question.
- Each provider supports nothing off its own system. On Linux the
VideoToolbox provider answers “no” to everything and opens nothing. Being on
the path is inert until a file in a patent-pool codec is opened, and then it
is the difference between a picture and
UNSUPPORTED_CODEC. - Nothing used
:mediawithout it. The showcase depended on both. CI ran both in the same job, and:media-platform’s tests demuxed with:media’s FFmpeg through:media’s test classes. - It cost a module’s worth of wiring. It had its own build script, test
task and coverage floor. It had a second
foreignMetadatagenerator with a second copy of the metadata grammar, kept apart only because the first sat in an unexported package of another module (ADR-0280). It had its own--enable-native-accessflag, its own CI step and its own paragraph inNOTICE. And it was one more thing for ADR-0495 to publish.
Decision
The system decoders are part of :media, in the packages they already had.
io.github.digitalsmile.goldberry.media.platformand itsbitstream,macos,linuxandwindowspackages move into:mediaunchanged. The descriptor exports…media.platform(for PlatformDecoders) and nothing under it. Theprovideslines for the sixDecoderProviders and CoreAudio’sOutputLatencymove with them.- One metadata file.
…media.nativeimageis new and unexported.MetadataGrammaris the tracing agent’s grammar, written once, with the sealed switch overValueLayoutthe platform copy had.FfmpegDescriptors(in…media.ffi) andPlatformDescriptorsgive each family’s shapes.MediaForeignMetadatawrites both into the module’s singlereachability-metadata.json.:natives’ForeignMetadatakeeps its own copy, for ADR-0280’s reason, which still holds across modules. - The coverage floor counts what runs.
:media’s floor stays at 88% of lines and 77% of branches. Another system’s decoder package is never counted. This system’s is counted only under-Pgoldberry.platform.required=true, which is when the job has its decoders installed. That is the rule:media-platform’s own floor kept. - One CI step.
media.ymlruns:media:checkwith bothrequiredflags. - The fixture script is
media/src/test/fixtures/make-platform-fixtures.sh, beside the one that makes FFmpeg’s fixtures.
OutputLatencyTest asserted that no latency provider was on :media’s path.
CoreAudio’s now always is, so the test asserts what holds on every system but
macOS: the installed provider answers nothing.
Consequences
- An application with
goldberry-mediaplays the patent-pool codecs wherever the operating system can, with no second dependency and no second--enable-native-accessflag. One that wants FFmpeg only lists its own providers withMediaPlayer.builder().decoderProviders(…), which is how it always opted out ofServiceLoader’s list. goldberry-media-platformwas never published, so no coordinates are withdrawn.- The licence position does not change. The jar carries no copy of any system
decoder, and
NOTICEandTHIRD-PARTY-NOTICES.mdnow say so for all three systems. Before, they named only macOS’s frameworks.
Alternatives considered
- Keep the module and publish it too. That means two artifacts, two natives-access flags and two metadata generators for code that is inert where it is not wanted. Being optional protected nothing.
- Merge it and rename the packages to
…media.decode.*. The names are already role-shaped (ADR-0172):platformis “the system’s decoders”, and the three below it are split where each system’s foreign memory stops. Renaming would churn seventy files and every ADR that cites them, and buy nothing.