PrismCore / API reference / Probing and input
Enumeration
FFmpegBuild
enum FFmpegBuildDeclared in Sources/PrismCore/Probe/FFmpegBuild.swift · PrismCore 3.5.4
Which FFmpeg actually answered, and whether it is the one we compiled against.
Both halves of that question have already cost us time. PrismCore compiles against MPVKit's headers, but an integrating host may override the package with its own fork of the same identity (see Package.swift) — so the libraries that answer at runtime are not necessarily the ones the headers described. A major version apart is not a cosmetic difference: libav* bumps major exactly when a public struct's layout changes, and Swift reads those structs field by field through the headers it saw. AVStream, AVCodecParameters and AVFrame are read on every packet in this engine, so a silent major drift is not a wrong version string, it is wrong pixels and wrong timestamps — with no error anywhere to point at it.
The second half is behaviour that legitimately differs between correct builds. Half the routing decisions in this engine are questions about the build rather than the media: whether eac3 was compiled in decides whether a TrueHD track bridges or evicts the source to the software path, and stock MPVKit ships the E-AC-3 decoders only. A bug report that says "audio is missing" is unreproducible without knowing which build was asked; the same report with summary attached usually needs no round trip at all.
Nothing here reads media or opens anything — it is four *_version() calls and a string, cheap enough for a host to log at launch and to put behind a diagnostics screen:
print(FFmpegBuild.summary)
if !FFmpegBuild.isABIMatched { /* refuse, or at least log loudly */ }Type properties
static let libraries: [Library]Every libav* library this engine links, in FFmpeg's own dependency order. libavfilter, libswresample and libswscale are in the list even though only the audio bridge and the seek-preview scaler touch them — a host that overrode the package overrode all of them, and a mismatch in the one library the current session happens not to use is still the signal that the override is wrong.
static var mismatchedLibraries: [Library] { get }The libraries whose major version disagrees with our headers — empty on a sane install.
static var isABIMatched: Bool { get }Whether every linked library matches the headers this engine saw.
A host that ships its own FFmpeg fork should assert this once at launch. PrismCore deliberately does not refuse to run on false: the engine cannot know whether the drift touches anything this particular source needs, and a hard failure would ground a host over a build detail its media may never reach. Loud, not fatal.
static var versionInfo: String { get }FFmpeg's own build identity — n8.0.1-eac3-vt.1 for the fork we ship against, a bare 8.0.1 for a stock tarball. This is the string that names which FFmpeg answered, where the version triples only describe its shape.
static var configuration: String { get }libavcodec's configure line. Long (a couple of kilobytes), so it is kept out of summary and left for a host to attach to a bug report — it is the only place that says whether --enable-encoder=eac3 was passed, which is the question behind most "the audio track is missing" reports.
static var capabilities: Capabilities { get }No documentation comment in the source.
Structure
FFmpegBuild.Capabilities
struct CapabilitiesThe build-dependent capabilities this engine actually branches on, resolved against the libraries that answered.
Deliberately asked of FFmpeg rather than derived from the configure string: a --enable-encoder=eac3 that failed to take is exactly the case worth catching, and avcodec_find_encoder is the same question the audio bridge itself asks at runtime.
Instance properties
let hasEAC3Encoder: BoolWhether this build carries FFmpeg's eac3 encoder. Stock MPVKit does not; the bridge then falls back to AAC (see audioBridgeEncoder), so this no longer decides whether a source can remux — only whether the bridged track can be passed through to an AVR as a bitstream.
let audioBridgeEncoder: String?The encoder the audio bridge will actually use — eac3, aac, or nil in a build with neither, where non-copyable audio routes to the software path.
let av1Decoder: String?Which AV1 decoder answered (libdav1d, av1, …), or nil in a build without one. The software path is the only way AV1 plays on a device without hardware support, so "which decoder" and "hardware or not" are one story.
let isAV1HardwareSupported: BoolWhether this device decodes AV1 in hardware — the other half of that story, and the reason the same source routes differently on an M2 and an M4.
let hasDialogueBoost: BoolWhether dialogue-boost renditions can be produced: the eac3 encoder and libavfilter's pan. A separate answer from hasEAC3Encoder because the filter can be missing on its own.
let gpuDeinterlacer: String?The GPU deinterlacer's filter name, or nil in a build without it — yadif_videotoolbox needs Metal, which is a separate Xcode component and easy to build without. Its absence is not a failure (deinterlacing falls back to the CPU route) but it is the difference between zero-copy and a full CPU decode plus filter, so a "playback is slow on interlaced broadcast content" report wants this line.
Structure
FFmpegBuild.Library
struct LibraryOne linked libav* library: what the headers promised, and what the runtime delivered.
Instance properties
let compiled: VersionThe version of the headers this build of PrismCore was compiled against.
var isABIMatched: Bool { get }Same major means the struct layouts this engine walks are the ones its headers described. Minor and micro drift is expected and fine — libav* adds fields within a major, and everything we read predates them.
Structure
FFmpegBuild.Version
struct VersionA libav* version triple. Kept as three numbers rather than the packed int the C API hands out, because the only comparison that matters — major against major — is the one the packed form hides.
Instance properties
Generated from the public symbols of PrismCore 3.5.4. All types