SubtitleEdit/subtitleedit · error · InvalidOperationException

MPV delegates not loaded for software rendering.

Error message

MPV delegates not loaded for software rendering.

What it means

InvalidOperationException: after LoadLibraryInternal, at least one critical P/Invoke delegate (_mpvInitialize, _mpvRenderContextCreate, or _mpvRenderContextSetUpdateCallback) is still null. The native library loaded, but the expected symbols were not found, indicating an ABI/version mismatch.

Source

Thrown at src/ui/Logic/VideoPlayers/LibMpvDynamic/LibMpvDynamicPlayer.cs:1779

        var err = DoMpvCommand("set", "aid", trackId.ToString(CultureInfo.InvariantCulture));
        if (err < 0)
        {
            Se.LogError(new InvalidOperationException(GetErrorString(err)), "LibMpvDynamicPlayer SetAudioTrack");
        }
    }

    public void InitializeWithSoftwareRendering()
    {
        LoadLibraryInternal();
        EnsureNotDisposed();

        // Set mpv to use software rendering
        SetOptionString("vo", "libmpv");
        SetStartPausedOption();

        if (_mpvInitialize == null || _mpvRenderContextCreate == null || _mpvRenderContextSetUpdateCallback == null)
        {
            throw new InvalidOperationException("MPV delegates not loaded for software rendering.");
        }

        SetYtDlpPathOption();

        // Initialize mpv
        var err = _mpvInitialize(_mpv);
        if (err < 0)
        {
            throw new InvalidOperationException(GetErrorString(err));
        }

        _coreInitialized = true;

        // Build render context params for software rendering
        var apiTypeBytes = Encoding.UTF8.GetBytes(MPV_RENDER_API_TYPE_SW + "\0");
        var apiTypePtr = Marshal.AllocHGlobal(apiTypeBytes.Length);
        Marshal.Copy(apiTypeBytes, 0, apiTypePtr, apiTypeBytes.Length);

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Install a libmpv build recent enough to export mpv_render_context_create and mpv_render_context_set_update_callback.
  2. Ensure the loader resolves the bundled libmpv rather than a stale system copy (check rpath / LD_LIBRARY_PATH / dyld).
  3. Fall back to a GPU vo context if software rendering is unavailable on this build.

Example fix

// before
if (_mpvInitialize == null || _mpvRenderContextCreate == null || _mpvRenderContextSetUpdateCallback == null)
    throw new InvalidOperationException("MPV delegates not loaded for software rendering.");

// after
if (_mpvInitialize == null || _mpvRenderContextCreate == null || _mpvRenderContextSetUpdateCallback == null)
{
    logger.LogWarning("libmpv lacks software-render API; falling back to GPU vo");
    SwitchToGpuVo();
    return;
}
Defensive patterns

Strategy: validation

Validate before calling

if (!LibMpvExportsSymbol("mpv_render_context_create"))
{
    logger.LogWarning("libmpv lacks render API; using GPU vo");
    SwitchToGpuVo();
    return;
}

Try / catch

try { player.InitializeWithSoftwareRendering(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("delegates not loaded"))
{
    logger.LogWarning("{Msg}; falling back to GPU vo", ex.Message);
    SwitchToGpuVo();
}

Prevention

When it happens

Trigger: A libmpv is present but too old to export mpv_render_context_create/set_update_callback, the wrong library revision was loaded (e.g. libmpv.so.1 vs libmpv.so.2), a stripped/minimal build lacking the render API, or symbols renamed across versions.

Common situations: A distro libmpv older than required, multiple libmpv versions on the library path, or a custom minimal build compiled without the render context API.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/d1dfe11836f46b84. Report an issue: GitHub.