Declarative media player configs: VLC and MPC-HC
VLC and MPC-HC settings are both text files and registry entries, and the two players differ in how much of their config can live in git. This reference covers where each player stores state, what a commit-able config looks like, and the tuning for streaming, audio, and HDR playback on the desktop box: RTX 5090, MSI MPG271QX OLED (1440p, 360 Hz, HDR), SMSL D70 Pro SABRE DAC plus SSL 2 USB interface, wired LAN. The configs live in the media-player-config repo on git.erfi.io; the doc explains the decisions behind them.
Provenance: the VLC key names, defaults, and the MPC-HC registry layout were checked against the live machine on 2026-09-27 (a stock VLC 3.0.23 vlcrc and a stock MPC-HC 2.5.2 install; MPC-HC was upgraded to 2.8.2 and configured from source-verified values the same day - the evidence table tracks which rows are measured, source-verified, or documented). The tuning itself is documented, not lab-measured - each claim below links its source.
TL;DR:
- VLC is fully declarable: one
vlcrctext file, keys matched by name, missing keys fall back to defaults. Ship a delta of changed keys; the full file is disposable. The one streaming knob isnetwork-caching(default 1000 ms; 2000 ms for public-internet streams, 1000-1500 ms for LAN). - MPC-HC splits its state: player settings can move to
mpc-hc64.ininext to the exe (INI mode), while internal filter settings (LAV decoders, renderers) stay in the registry even in INI mode. The declarative form is one GUI pass, then a snapshot script that exports both surfaces into the repo. - Video: MPC Video Renderer (MPCVR) with LAV Video on D3D11, native device. MPCVR is the 2.7.4 default, consumes D3D11 textures directly, and passes HDR through to the OLED. madVR is a separate install with the same goal and a heavier chain.
- Audio: WASAPI exclusive with bit-exact output into the USB DAC; bitstreaming stays off (it is a receiver feature; into a DAC it produces silence), no mixing, no dynamic range compression.
Which player, for what
Section titled “Which player, for what”| You are playing | Use | Why |
|---|---|---|
| Local files, any platform | mpv | Best-quality video pipeline, config carries over in dotfiles |
| Network streams, IPTV, HLS | VLC | Adaptive/demux layer that recovers well; one caching knob to tune |
| Local files, best Windows quality | MPC-HC | LAV + MPCVR + WASAPI exclusive chain, HDR passthrough |
The three cover different cases: mpv and VLC share the dotfiles-style config story, and MPC-HC is the Windows-only quality chain. All three coexist on the same machine.
Where each player keeps its config
Section titled “Where each player keeps its config”| Player | Surface | Location | Declarable? |
|---|---|---|---|
| VLC | vlcrc | Linux ~/.config/vlc/vlcrc; Windows %APPDATA%\vlc\vlcrc | Fully - one text file |
| VLC | Qt interface state | vlc-qt-interface.ini | Partly; mostly cosmetic |
| MPC-HC | Player settings | HKCU\Software\MPC-HC\MPC-HC, or mpc-hc64.ini in INI mode | Yes in INI mode |
| MPC-HC | Internal LAV + audio renderer | profile store (mpc-hc64.ini in INI mode, else the MPC-HC registry tree) | Yes - follows INI mode |
| MPC-HC | MPC Video Renderer | HKCU\Software\MPC-BE Filters\MPC Video Renderer | Registry only, always |
The VLC file is read line by line: every key=value is matched by name across the whole file, section headers are documentation for humans, and an absent key means default. A first GUI save rewrites the file in full with every default listed as a comment; the delta stays the source of truth and the expanded copy is disposable.
MPC-HC 2.x keeps one profile store - player settings, the internal LAV filters, and the MPC Audio Renderer section - plus one exception. INI mode moves the profile store to mpc-hc64.ini next to the exe1; MPC Video Renderer writes its own registry key regardless of INI mode2, so the setup checklist captures it with a snapshot script. The checkbox is greyed out when MPC-HC sits in C:\Program Files (the exe directory must be writable), so the install goes in a user directory first1.
VLC: the delta file
Section titled “VLC: the delta file”The Linux and Windows deltas differ in one entry: the hardware decoding pin.
| Key | Linux value | Windows value | Default | Why |
|---|---|---|---|---|
avcodec-hw | vaapi | leave at any | any | NVIDIA exposes NVDEC through VA-API only via the libva-nvidia-driver shim; on Windows, any selects the D3D11VA path already present |
network-caching | 2000 | 2000 | 1000 | public-internet headroom; see table below |
qt-privacy-ask | 0 | 0 | unset | suppresses the first-run privacy dialog |
metadata-network-access | 1 | 1 | unset | allows online metadata lookup, matching the pre-existing Windows install |
Everything else stays at default on purpose: audio-resampler (auto), aout (auto - PulseAudio on Linux, MMDevice on Windows), audio-time-stretch (on), replay gain (off). Pinning module names VLC may rename between releases risks the pin breaking on a version jump, and the defaults work. On Windows, the Preferences UI’s “Hardware-accelerated decoding” switch is a UI-level setting rather than a vlcrc key in the delta - verify it once in the GUI.
Caching, per source type (defaults from the live 3.0.23 file):
| Key | Default | Set to | Applies to |
|---|---|---|---|
network-caching | 1000 ms | 2000 (internet), 1000-1500 (LAN) | HTTP, RTSP, IPTV, HLS |
file-caching | 1000 ms | default | local files |
live-caching | 300 ms | default | capture devices |
Bumping network-caching above ~3000 ms adds jitter tolerance at the cost of channel-switch latency; below ~500 ms on a public-internet source, stutter. The Linux delta needs libva-nvidia-driver installed (in the Arch extra repo; CachyOS mirrors it)3. If a stream fails to open with the pin in place, delete the avcodec-hw line: VLC then decodes in software instead of erroring per stream.
MPC-HC: the Windows chain
Section titled “MPC-HC: the Windows chain”The live install is MPC-HC 2.8.2 (upgraded from 2.5.2 on 2026-09-27). Since 2.7.4, MPCVR is the default renderer on modern systems and a one-time GPU-detection pass rewrites decoder defaults, so configure on top of whatever that pass wrote4.
Renderer and decode
Section titled “Renderer and decode”| Choice | What it is | Pick it when |
|---|---|---|
| MPC Video Renderer (MPCVR) | 2.8.x default on modern systems; D3D11-native, HDR passthrough4 | the default; this setup |
| madVR | Separate download, historically the reference-quality renderer | willing to manage a third-party component for upscale quality |
| EVR-CP / VMR9 | Windows built-in presenters | troubleshooting only |
LAV Video decodes on D3D11 with the device set to Automatic (Native). Native works because MPCVR consumes D3D11 textures without a system-memory round trip; with EVR-CP or VMR9 as the renderer, LAV would need the GPU-by-name (copy-back) selection instead5. Verify after playing a 10-bit HEVC file: Internal Filters > Video Decoder > Status must read D3D11, with avcodec appearing only for codecs the hardware list omits. The 5090 covers AV1 and 10-bit HEVC in hardware, and D3D11 is LAV’s only hardware path for AV15.
HDR: Windows HDR on, MPCVR set to pass HDR content through to the display, 10-bit native bitdepth. On this box the driver-side 610.43 bug that feeds invalid HDR metadata to clients applies - a crash on HDR open is the driver, not the config.
| Setting | Value | Reason |
|---|---|---|
| Audio renderer | MPC Audio Renderer, WASAPI exclusive, bit-exact output | bypasses the Windows shared-mode resampler and mixer entirely |
| Device | SMSL D70 Pro | the music/video DAC; the SSL 2 handles voice work |
| Bitstreaming | All off | bitstreaming exists to hand AC3/DTS/TrueHD to a receiver decoder; into a USB DAC it produces silence5 |
| Mixing, DRC | Off | no downmix, no dynamic range compression in the player |
| Buffer | 50 ms (2.8.2 MPCAR default; 0 = device period, 1 = reserved, 100 ms alternatives) | raise on underruns before touching anything else |
With WASAPI exclusive mode engaged, the Control Panel’s shared-mode format (24-bit/48000 Hz) is bypassed for MPC-HC playback; keep it as the shared default for everything else on the machine.
INI mode and the renderer’s own key
Section titled “INI mode and the renderer’s own key”| Store | Contents | Declarative path |
|---|---|---|
mpc-hc64.ini (INI mode) | player settings, internal LAV filters, MPC Audio Renderer section | copy the file next to the exe |
HKCU\Software\MPC-HC\... (INI mode off) | the same profile contents in the registry | .reg export of the whole tree |
HKCU\Software\MPC-BE Filters\MPC Video Renderer | MPCVR settings | .reg export; unaffected by INI mode |
The profile store choice is global: WriteProfileInt from the LAV wrapper and the audio renderer lands in the ini or the registry depending on the INI-mode switch6. MPCVR bypasses the profile entirely and writes its own key2. The registry value enums (renderer IDs, WASAPI mode dwords) are not hand-authored anywhere in this setup: they are set once through the GUI, then captured. A wrong dword breaks playback without an error message, and the enums are not all documented7.
pwsh .\mpc-hc\capture-config.ps1 -RepoRoot C:\path\to\media-player-configwrites mpc-hc64.ini (found via the player’s ExePath registry value), mpc-hc-registry.reg (the whole HKCU\Software\MPC-HC tree) and mpcvr-registry.reg (the MPCVR key) into mpc-hc/windows-snapshot/, with the player closed. Reapply after a reinstall: import both .reg files, copy the ini, tick INI mode once - the ini then wins for the profile, and MPCVR keeps living in its own key. Commit the snapshot; that commit is the config’s state history.
Gotchas and lessons learned
Section titled “Gotchas and lessons learned”- A full
vlcrcis version-coupled; a delta is not. The full file carries thousands of commented defaults that change shape between VLC releases. Commit the delta, keep the expanded copy disposable. - INI mode covers the profile store, and only it. The internal LAV filters and the audio renderer move with it; MPC Video Renderer keeps its own registry key either way - the capture script’s second export exists for exactly that2.
- Install MPC-HC outside Program Files first. The INI-mode checkbox reads as permanently greyed out otherwise, and the reason (exe-directory write access) is documented nowhere in the UI1.
- Bitstreaming into a DAC produces silence, not an error. The toggles exist for receiver decoders; the DAC gets a raw PCM stream instead5.
- The stock state was nearly empty on this machine (VLC: two privacy flags; MPC-HC: interface language). Curation from sources beats trying to “export the tuned config” when nothing was ever tuned - the export would have captured the defaults.
Decision guide
Section titled “Decision guide”Text fallback:
- Player: mpv for local files anywhere, VLC for network streams, MPC-HC for best Windows playback quality.
- VLC hardware decode: pin
avcodec-hw=vaapion Linux with NVIDIA (needslibva-nvidia-driver); leaveanyon Windows, where D3D11VA is auto-selected. - Audio output: WASAPI exclusive with bit-exact output for the USB DAC listening chain; shared mode for communications and everything else.
Reproducing and evidence
Section titled “Reproducing and evidence”| Claim | How it was checked | Status |
|---|---|---|
VLC key names and defaults (network-caching 1000, avcodec-hw any, aout empty, resampler empty) | read from the live %APPDATA%\vlc\vlcrc on the ERFI1 Windows host, 2026-09-27 | measured |
MPC-HC registry tree (HKCU\Software\MPC-HC) and stock state (language only, morning of 2026-09-27) | reg export HKCU\Software\MPC-HC on the same host | measured |
| MPC-HC 2.8.2: MPCVR default on modern systems, LAV 0.83, MPCVR 0.10.8 | release notes4 | documented |
| MPC-HC INI mode and the Program Files write-access caveat | Doom9 thread1 | documented |
| Internal LAV + audio renderer follow the profile store (registry or ini) | source: FGFilterLAV.cpp / MpcAudioRenderer.cpp6 | source-verified |
| MPCVR keeps its own key regardless of INI mode | source: VideoRenderer.cpp line 362 | source-verified |
| MPCAR enums: DeviceMode 0=shared/1=exclusive, WasapiMethod 0=EVENT, BufferDuration 50 ms default, UseBitExactOutput default true | source: IMpcAudioRenderer.h, MpcAudioRenderer.cpp (2.8.2 tag)8 | source-verified |
| AudioRendererType values: empty = system default, “MPC Audio Renderer” = MPCAR, device string = MPCAR pinned | source: AppSettings.h AUDRNDT_*, PPageOutput.cpp8 | source-verified |
| MPCVR HDR passthrough defaults true on Win10+, 1000 nits | source: IVideoRenderer.h2 | source-verified |
| libva-nvidia-driver in Arch extra (not the AUR) | Arch package page3 | documented |
| D3D11-native vs copy-back, bitstreaming rules | LAV Filters guide5 | documented |
The media-player-config repo holds the files this doc describes; its README and mpc-hc/SETUP.md carry the apply steps.
Related docs
Section titled “Related docs”- Making cliamp play sound on WSL2 - audio routing on this estate’s dev box: where Pulse/ALSA breaks and how to see it.
- GPU voltage-frequency curve control without Afterburner - same machine, the other tuned-GPU component.
References
Section titled “References”-
clsid2, “MPC-HC settings storage and INI mode,” Doom9 Forum. https://forum.doom9.net/showthread.php?p=1995928 ↩ ↩2 ↩3 ↩4
-
Aleksoid1978, “VideoRenderer source: Source/VideoRenderer.cpp,” GitHub. https://github.com/Aleksoid1978/VideoRenderer ↩ ↩2 ↩3 ↩4 ↩5
-
Arch Linux, “libva-nvidia-driver 0.0.18-1,” Arch package registry. https://archlinux.org/packages/extra/x86_64/libva-nvidia-driver/ ↩ ↩2
-
clsid2, “MPC-HC release 2.8.2,” GitHub. https://github.com/clsid2/mpc-hc/releases/tag/2.8.2 ↩ ↩2 ↩3
-
Free-Codecs, “Transform your media player with LAV Filters,” LAV Filters guide. https://www.free-codecs.com/guides/transform-your-media-player-with-lav-filters.htm ↩ ↩2 ↩3 ↩4 ↩5
-
clsid2, “mpc-hc source: FGFilterLAV.cpp, MpcAudioRenderer.cpp,” GitHub. https://github.com/clsid2/mpc-hc/blob/5ad34988/src/mpc-hc/FGFilterLAV.cpp ↩ ↩2
-
DeepWiki, “clsid2/mpc-hc: settings and configuration.” https://deepwiki.com/clsid2/mpc-hc/2.4-settings-and-configuration ↩
-
clsid2, “mpc-hc source at tag 2.8.2: AppSettings.h, PPageOutput.cpp, thirdparty/MpcAudioRenderer,” GitHub. https://github.com/clsid2/mpc-hc/tree/2.8.2/src ↩ ↩2