Files
iptvnator/apps/electron-backend/native/binding.gyp
T
4grayandClaude Fable 5 1a0c2306a9 feat(embedded-mpv): Linux frame-copy helper via headless EGL
Port the frame-copy engine's native layer to Linux (PORTING.md items 1-4):

- frame_helper_gl.h: platform GlContext abstraction. macOS keeps the CGL
  path (moved verbatim); Linux acquires an EGL display in order
  surfaceless-Mesa -> default display -> GBM render node, binds a 3.2 core
  desktop-GL context surfaceless (1x1 pbuffer fallback), and hands mpv
  eglGetProcAddress. The helper's own GL calls link against glvnd
  libOpenGL, so no display server is required.
- frame_shm.h: portable frame_shm_now_ns() (CLOCK_MONOTONIC) shared by the
  helper and the reader addon, replacing the macOS-only
  clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); producer and consumer stay on
  the same clock.
- embedded_mpv_frame_reader.c: real implementation now also on __linux__
  (the code was already POSIX apart from the clock call).
- binding.gyp: OS==linux executable branch for iptvnator_mpv_helper linking
  system libmpv (-lmpv) + EGL/OpenGL/gbm, with rpaths for $ORIGIN/lib and
  the build-time library dir. The in-process addon still does not link
  libmpv - the ban only binds in-process, the helper is out of process.
- build-embedded-mpv.js: system-dev fallback on Linux (LIBMPV_INCLUDE_DIR
  or /usr/include) so a distro libmpv-dev install builds without staging a
  vendored runtime; a pre-set LINUX_NATIVE_LIBRARY_DIR now wins over the
  vendored lib dir.

Verified on Ubuntu 25.04 / i7-1165G7 (Iris Xe): lavfi smoke per PORTING.md
(idle->loading->playing snapshots at 4 Hz, aspect-fit generation bump
g1 1280x720 -> g2 960x720 for a 4:3 source), reader probe 60 fps at
1080p60 with 0 torn reads, clean quit with no leaked processes or shm.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 19:48:33 +02:00

160 lines
4.6 KiB
Python

{
"targets": [
{
"target_name": "embedded_mpv",
"sources": [],
"include_dirs": [
"<(module_root_dir)/../../../node_modules/.pnpm/node_modules/node-addon-api",
"<!(node -p \"process.env.LIBMPV_INCLUDE_DIR || '/opt/homebrew/include'\")",
"src"
],
"defines": [
"NAPI_CPP_EXCEPTIONS"
],
"cflags_cc": [
"-fexceptions",
"-std=c++20"
],
"conditions": [
[
"OS==\"mac\"",
{
"sources": [
"src/embedded_mpv.mm"
],
"xcode_settings": {
"CLANG_CXX_LANGUAGE_STANDARD": "c++20",
"CLANG_ENABLE_OBJC_ARC": "YES",
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
"MACOSX_DEPLOYMENT_TARGET": "10.15",
"OTHER_LDFLAGS": [
"-Wl,-rpath,@loader_path/lib"
]
},
"libraries": [
"-framework AppKit",
"-framework CoreVideo",
"-framework Foundation",
"-framework OpenGL",
"<!(node -e \"const path = require('path'); const dir = process.env.LIBMPV_LIBRARY_DIR || '/opt/homebrew/lib'; process.stdout.write(path.join(dir, 'libmpv.2.dylib'))\")"
]
}
],
[
"OS==\"win\"",
{
"sources": [
"src/embedded_mpv_win32.cc"
],
"defines": [
"WIN32_LEAN_AND_MEAN",
"NOMINMAX"
],
"libraries": [
"<!(node -e \"const path = require('path'); const dir = process.env.LIBMPV_LIBRARY_DIR || process.cwd(); const lib = process.env.LIBMPV_IMPORT_LIB || path.join(dir, 'mpv.lib'); process.stdout.write(lib.replace(/\\\\\\\\/g, '/'))\")",
"user32.lib",
"gdi32.lib"
]
}
],
[
"OS==\"linux\"",
{
"sources": [
"src/embedded_mpv_linux.cc"
],
"defines": [
"IPTVNATOR_DYNAMIC_LIBMPV"
],
"libraries": [
"-L<!(node -p \"process.env.LINUX_NATIVE_LIBRARY_DIR || '/usr/lib'\")",
"-lX11",
"-lXext",
"-ldl"
]
}
]
]
},
{
"target_name": "embedded_mpv_frame_reader",
"sources": [
"src/embedded_mpv_frame_reader.c"
],
"include_dirs": [
"helper"
]
},
{
"target_name": "iptvnator_mpv_helper",
"type": "none",
"conditions": [
[
"OS==\"mac\"",
{
"type": "executable",
"sources": [
"helper/mpv_frame_helper.cpp"
],
"include_dirs": [
"<!(node -p \"process.env.LIBMPV_INCLUDE_DIR || '/opt/homebrew/include'\")",
"helper"
],
"cflags_cc": [
"-std=c++17"
],
"xcode_settings": {
"CLANG_CXX_LANGUAGE_STANDARD": "c++17",
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
"MACOSX_DEPLOYMENT_TARGET": "11.0",
"OTHER_LDFLAGS": [
"-Wl,-rpath,@executable_path/lib",
"-Wl,-rpath,@loader_path/lib"
]
},
"libraries": [
"-framework OpenGL",
"<!(node -e \"const path = require('path'); const dir = process.env.LIBMPV_LIBRARY_DIR || '/opt/homebrew/lib'; process.stdout.write(path.join(dir, 'libmpv.2.dylib'))\")"
]
}
],
[
"OS==\"linux\"",
{
"type": "executable",
"sources": [
"helper/mpv_frame_helper.cpp"
],
"include_dirs": [
"<!(node -p \"process.env.LIBMPV_INCLUDE_DIR || '/usr/include'\")",
"helper"
],
"cflags_cc!": [
"-fno-exceptions"
],
"cflags_cc": [
"-std=c++17",
"-fexceptions"
],
"cflags": [
"-pthread"
],
"ldflags": [
"-pthread",
"-Wl,-rpath,'$$ORIGIN/lib'",
"-Wl,-rpath,<!(node -p \"process.env.LINUX_NATIVE_LIBRARY_DIR || '/usr/lib'\")"
],
"libraries": [
"-L<!(node -p \"process.env.LINUX_NATIVE_LIBRARY_DIR || '/usr/lib'\")",
"-lmpv",
"-lEGL",
"-lOpenGL",
"-lgbm"
]
}
]
]
}
]
}