mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 12:06:16 -08:00
feat(embedded-mpv): add Windows frame-copy support (#1175)
Port the embedded mpv frame-copy pipeline to Windows with WGL rendering and named shared memory. Includes packaging validation, platform gates, tests, and architecture documentation.
This commit is contained in:
1 parent
7d75d989e8
commit
59e08fd2d6
41 files changed
+1284
-157
No files matched your search
@@ -7,13 +7,30 @@
|
||||
* memory cage forbids external ArrayBuffers over foreign memory.
|
||||
*
|
||||
* Plain C N-API (no node-addon-api) so it stays ABI-stable and trivial.
|
||||
* macOS and Linux (POSIX shm) — other platforms export an empty object;
|
||||
* the TypeScript side gates on platform before requiring it.
|
||||
* macOS and Linux (POSIX shm) plus Windows (named file mapping; binding.gyp
|
||||
* compiles this file as C++ there because MSVC's C mode has no
|
||||
* <stdatomic.h>) — other platforms export an empty object; the TypeScript
|
||||
* side gates on platform before requiring it.
|
||||
*/
|
||||
#define NAPI_VERSION 8
|
||||
#include <node_api.h>
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__)
|
||||
#if defined(__APPLE__) || defined(__linux__) || defined(_WIN32)
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../helper/frame_shm.h"
|
||||
|
||||
/* frame_shm.h typed the fields as std::atomic in C++ mode; keep the shared
|
||||
* atomic_load_explicit call sites below spelling-compatible. */
|
||||
using std::atomic_load_explicit;
|
||||
using std::memory_order_acquire;
|
||||
using std::memory_order_relaxed;
|
||||
|
||||
#else
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdatomic.h>
|
||||
@@ -26,6 +43,8 @@
|
||||
|
||||
#include "../helper/frame_shm.h"
|
||||
|
||||
#endif
|
||||
|
||||
static FrameShmHeader* g_header = NULL;
|
||||
static uint8_t* g_base = NULL;
|
||||
static size_t g_size = 0;
|
||||
@@ -35,7 +54,11 @@ static uint64_t now_ns(void) { return frame_shm_now_ns(); }
|
||||
|
||||
static void unmap_current(void) {
|
||||
if (g_base) {
|
||||
#if defined(_WIN32)
|
||||
UnmapViewOfFile(g_base);
|
||||
#else
|
||||
munmap(g_base, g_size);
|
||||
#endif
|
||||
}
|
||||
g_base = NULL;
|
||||
g_header = NULL;
|
||||
@@ -68,6 +91,23 @@ static napi_value Open(napi_env env, napi_callback_info info) {
|
||||
return throw_error(env, "shm name must be a string");
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
char mapping_name[280];
|
||||
frame_shm_windows_name(name, mapping_name, sizeof(mapping_name));
|
||||
HANDLE mapping = OpenFileMappingA(FILE_MAP_READ, FALSE, mapping_name);
|
||||
if (!mapping) return throw_error(env, "shm open failed (helper gone?)");
|
||||
void* mapped = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
|
||||
/* The view holds its own reference to the section object. */
|
||||
CloseHandle(mapping);
|
||||
if (!mapped) return throw_error(env, "shm map failed");
|
||||
MEMORY_BASIC_INFORMATION region;
|
||||
if (VirtualQuery(mapped, ®ion, sizeof(region)) == 0 ||
|
||||
region.RegionSize < sizeof(FrameShmHeader)) {
|
||||
UnmapViewOfFile(mapped);
|
||||
return throw_error(env, "shm segment too small");
|
||||
}
|
||||
const size_t segment_size = (size_t)region.RegionSize;
|
||||
#else
|
||||
const int fd = shm_open(name, O_RDONLY, 0);
|
||||
if (fd < 0) return throw_error(env, "shm_open failed (helper gone?)");
|
||||
struct stat segment;
|
||||
@@ -80,17 +120,23 @@ static napi_value Open(napi_env env, napi_callback_info info) {
|
||||
mmap(NULL, (size_t)segment.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
close(fd);
|
||||
if (mapped == MAP_FAILED) return throw_error(env, "mmap failed");
|
||||
const size_t segment_size = (size_t)segment.st_size;
|
||||
#endif
|
||||
|
||||
FrameShmHeader* header = (FrameShmHeader*)mapped;
|
||||
if (header->magic != FRAME_SHM_MAGIC ||
|
||||
header->version != FRAME_SHM_VERSION) {
|
||||
munmap(mapped, (size_t)segment.st_size);
|
||||
#if defined(_WIN32)
|
||||
UnmapViewOfFile(mapped);
|
||||
#else
|
||||
munmap(mapped, segment_size);
|
||||
#endif
|
||||
return throw_error(env, "frame ring not initialized yet");
|
||||
}
|
||||
|
||||
unmap_current();
|
||||
g_base = (uint8_t*)mapped;
|
||||
g_size = (size_t)segment.st_size;
|
||||
g_size = segment_size;
|
||||
g_header = header;
|
||||
|
||||
napi_value result;
|
||||
@@ -204,7 +250,7 @@ static napi_value Init(napi_env env, napi_value exports) {
|
||||
return exports;
|
||||
}
|
||||
|
||||
#else /* neither __APPLE__ nor __linux__ */
|
||||
#else /* no frame-copy port for this platform */
|
||||
|
||||
static napi_value Init(napi_env env, napi_value exports) {
|
||||
/* Frame-copy is not ported to this platform yet; loading this module
|
||||
|
||||
Reference in new issue
Block a user