@mediaway/ffi 0.1.5 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -14,10 +14,8 @@
14
14
  * `_free` — the public packages do this automatically.
15
15
  */
16
16
  import { type TypeObject } from "koffi";
17
- export declare function findLibrary(name: string): string;
18
- export declare const containerLib: import("koffi").LibraryHandle;
19
- export declare const pipelineLib: import("koffi").LibraryHandle;
20
- export declare const deviceLib: import("koffi").LibraryHandle;
17
+ import { findLibrary, containerLib, pipelineLib, deviceLib } from "./loader.js";
18
+ export { findLibrary, containerLib, pipelineLib, deviceLib };
21
19
  export declare const MwRational: TypeObject;
22
20
  export declare const MwVideoTrackInfo: TypeObject;
23
21
  export declare const MwAudioTrackInfo: TypeObject;
@@ -35,6 +33,9 @@ export declare const MwCameraConfig: TypeObject;
35
33
  export declare const MwCameraFrame: TypeObject;
36
34
  export declare const MwDesktopConfig: TypeObject;
37
35
  export declare const MwDesktopFrame: TypeObject;
36
+ export declare const MwGpuAdapterInfo: TypeObject;
37
+ export declare const MwGpuAdapterSelect: TypeObject;
38
+ export declare const MwGpuDeviceOptions: TypeObject;
38
39
  export declare const MwAudioConfig: TypeObject;
39
40
  export declare const MwAudioFrame: TypeObject;
40
41
  export declare const MwAudioEncodeConfig: TypeObject;
@@ -166,6 +167,8 @@ export declare const pipeline: {
166
167
  audioDecodeSessionFlush: import("koffi").Callable;
167
168
  audioDecodeSessionClose: import("koffi").Callable;
168
169
  decodedAudioFrameFree: import("koffi").Callable;
170
+ sessionWriteFrameFromCameraCapture: import("koffi").Callable;
171
+ sessionWriteFrameFromDesktopCapture: import("koffi").Callable;
169
172
  };
170
173
  export declare const device: {
171
174
  abiVersion: import("koffi").Callable;
@@ -190,6 +193,11 @@ export declare const device: {
190
193
  audioPollFrame: import("koffi").Callable;
191
194
  audioClose: import("koffi").Callable;
192
195
  audioFrameFree: import("koffi").Callable;
196
+ gpuAdapterList: import("koffi").Callable;
197
+ gpuAdapterListFree: import("koffi").Callable;
198
+ gpuDeviceCreate: import("koffi").Callable;
199
+ gpuDeviceHandle: import("koffi").Callable;
200
+ gpuDeviceClose: import("koffi").Callable;
193
201
  };
194
202
  /** Copy `len` bytes out of a koffi pointer/opaque handle. */
195
203
  export declare function copyBytes(ptr: unknown, len: number): Buffer;
@@ -290,6 +298,20 @@ export interface RawCameraFrame {
290
298
  data: unknown;
291
299
  data_len: number;
292
300
  }
301
+ /** `mediaway_desktop_frame_t` (Screen output) — unlike `RawCameraFrame`, GPU
302
+ * storage (`storage_kind == 1`) leaves `data`/`data_len` empty and carries the
303
+ * frame in `gpu_buffer` instead (borrowed — never freed by the caller). */
304
+ export interface RawDesktopFrame {
305
+ pts: bigint | number;
306
+ duration: bigint | number;
307
+ width: number;
308
+ height: number;
309
+ pixel_format: number;
310
+ storage_kind: number;
311
+ data: unknown;
312
+ data_len: number;
313
+ gpu_buffer: RawGpuBufferHandle;
314
+ }
293
315
  export interface RawAudioFrame {
294
316
  pts: bigint | number;
295
317
  duration: bigint | number;
@@ -311,6 +333,13 @@ export interface RawPipelineFrame {
311
333
  raw_bytes_len: number;
312
334
  gpu_buffer: RawGpuBufferHandle;
313
335
  }
336
+ /** `mediaway_gpu_device_handle_t` (Screen capture / GPU-input encode input,
337
+ * mediaway_gpu_device_handle()'s output). */
338
+ export interface RawGpuDeviceHandle {
339
+ kind: number;
340
+ native: number | bigint;
341
+ webgpu_device_id: number | bigint;
342
+ }
314
343
  /** `mediaway_gpu_buffer_handle_t`. */
315
344
  export interface RawGpuBufferHandle {
316
345
  kind: number;
@@ -403,3 +432,23 @@ export interface RawDecodedAudioFrame {
403
432
  data: unknown;
404
433
  data_len: number;
405
434
  }
435
+ /** `mediaway_gpu_adapter_info_t` (mediaway-device ADR-0007). */
436
+ export interface RawGpuAdapterInfo {
437
+ index: number;
438
+ name: string;
439
+ vendor_id: number;
440
+ device_id: number;
441
+ dedicated_video_memory: bigint | number;
442
+ is_hardware: boolean;
443
+ }
444
+ /** `mediaway_gpu_adapter_select_t`. */
445
+ export interface RawGpuAdapterSelect {
446
+ kind: number;
447
+ index: number;
448
+ }
449
+ /** `mediaway_gpu_device_options_t`. */
450
+ export interface RawGpuDeviceOptions {
451
+ adapter: RawGpuAdapterSelect;
452
+ video_support: boolean;
453
+ debug_layer: boolean;
454
+ }
package/dist/index.js CHANGED
@@ -14,58 +14,8 @@
14
14
  * `_free` — the public packages do this automatically.
15
15
  */
16
16
  import koffi, {} from "koffi";
17
- import fs from "node:fs";
18
- import path from "node:path";
19
- import { fileURLToPath } from "node:url";
20
- // ── Library discovery ──────────────────────────────────────────────────────────
21
- // The cdylibs are Rust build artifacts, not installed system libraries. Search:
22
- // 1. $MEDIAWAY_FFI_DIR
23
- // 2. <this package>/native (DLLs bundled at pack time — the npm distribution)
24
- // 3. <repo root>/target/x86_64-pc-windows-gnu/debug (GNU toolchain, dev runs)
25
- // 4. <repo root>/target/debug (host/MSVC toolchain)
26
- // 5. cwd
27
- const here = path.dirname(fileURLToPath(import.meta.url));
28
- const repoRoot = path.resolve(here, "..", "..", "..", "..", "..");
29
- const searchDirs = [
30
- process.env.MEDIAWAY_FFI_DIR ?? "",
31
- path.resolve(here, "..", "native"),
32
- path.join(repoRoot, "target", "x86_64-pc-windows-gnu", "debug"),
33
- path.join(repoRoot, "target", "debug"),
34
- process.cwd(),
35
- ];
36
- export function findLibrary(name) {
37
- for (const dir of searchDirs) {
38
- if (!dir)
39
- continue;
40
- const candidate = path.join(dir, name);
41
- if (fs.existsSync(candidate))
42
- return candidate;
43
- }
44
- throw new Error(`cannot find ${name}; set $MEDIAWAY_FFI_DIR or build the -ffi crates`);
45
- }
46
- /**
47
- * cdylib filename Cargo produces for this platform. Windows and Linux only —
48
- * the workspace's own hardware/CI coverage is limited to those two (see
49
- * docs/ai/wiki/platform/order.md); macOS support is not claimed here since
50
- * it has never been built or run.
51
- */
52
- function libraryFilename() {
53
- switch (process.platform) {
54
- case "win32":
55
- return "mediaway_ffi.dll";
56
- case "linux":
57
- return "libmediaway_ffi.so";
58
- default:
59
- throw new Error(`mediaway: unsupported platform ${process.platform} (Windows and Linux only)`);
60
- }
61
- }
62
- function load(name) {
63
- return koffi.load(findLibrary(name));
64
- }
65
- const libraryName = libraryFilename();
66
- export const containerLib = load(libraryName);
67
- export const pipelineLib = load(libraryName);
68
- export const deviceLib = load(libraryName);
17
+ import { findLibrary, containerLib, pipelineLib, deviceLib } from "./loader.js";
18
+ export { findLibrary, containerLib, pipelineLib, deviceLib };
69
19
  // ── Structs (layouts mirror the headers exactly) ───────────────────────────────
70
20
  export const MwRational = koffi.struct("MwRational", {
71
21
  num: "uint64",
@@ -199,6 +149,23 @@ export const MwDesktopFrame = koffi.struct("MwDesktopFrame", {
199
149
  data_len: "size_t",
200
150
  gpu_buffer: MwGpuBufferHandle,
201
151
  });
152
+ export const MwGpuAdapterInfo = koffi.struct("MwGpuAdapterInfo", {
153
+ index: "uint32",
154
+ name: "str", // owned NUL-terminated UTF-8; freed via gpuAdapterListFree, not per-entry
155
+ vendor_id: "uint32",
156
+ device_id: "uint32",
157
+ dedicated_video_memory: "uint64",
158
+ is_hardware: "bool",
159
+ });
160
+ export const MwGpuAdapterSelect = koffi.struct("MwGpuAdapterSelect", {
161
+ kind: "int32", // 0 = Default, 1 = Index
162
+ index: "uint32", // meaningful only when kind == Index
163
+ });
164
+ export const MwGpuDeviceOptions = koffi.struct("MwGpuDeviceOptions", {
165
+ adapter: MwGpuAdapterSelect,
166
+ video_support: "bool",
167
+ debug_layer: "bool",
168
+ });
202
169
  export const MwAudioConfig = koffi.struct("MwAudioConfig", {
203
170
  device_index: "uint32",
204
171
  time_base: MwRational,
@@ -422,6 +389,11 @@ export const pipeline = {
422
389
  audioDecodeSessionFlush: pipelineLib.func("int mediaway_audio_decode_session_flush(void *session)"),
423
390
  audioDecodeSessionClose: pipelineLib.func("void mediaway_audio_decode_session_close(void *session)"),
424
391
  decodedAudioFrameFree: pipelineLib.func("void mediaway_decoded_audio_frame_free(MwDecodedAudioFrame *frame)"),
392
+ // ── Capture-to-encode bridge (adr/pipeline/0005-capture-encode-bridge-c-abi.md) ──
393
+ // Pushes one polled frame from a device.h capture handle straight into a
394
+ // session — no intermediate MwCameraFrame/MwDesktopFrame, no extra copy.
395
+ sessionWriteFrameFromCameraCapture: pipelineLib.func("int mediaway_encode_session_write_frame_from_camera_capture(void *session, void *capture, _Out_ bool *out_wrote_frame)"),
396
+ sessionWriteFrameFromDesktopCapture: pipelineLib.func("int mediaway_encode_session_write_frame_from_desktop_capture(void *session, void *capture, _Out_ bool *out_wrote_frame)"),
425
397
  };
426
398
  // ── Device functions ───────────────────────────────────────────────────────────
427
399
  export const device = {
@@ -447,6 +419,12 @@ export const device = {
447
419
  audioPollFrame: deviceLib.func("int mediaway_audio_capture_poll_frame(void *capture, _Out_ MwAudioFrame *out_frame, _Out_ bool *out_has)"),
448
420
  audioClose: deviceLib.func("int mediaway_audio_capture_close(void *capture)"),
449
421
  audioFrameFree: deviceLib.func("void mediaway_audio_frame_free(MwAudioFrame *frame)"),
422
+ // ── GPU device factory (mediaway-device ADR-0007) ─────────────────────────
423
+ gpuAdapterList: deviceLib.func("int mediaway_gpu_adapter_list(_Out_ MwGpuAdapterInfo **out_adapters, _Out_ size_t *out_count)"),
424
+ gpuAdapterListFree: deviceLib.func("void mediaway_gpu_adapter_list_free(MwGpuAdapterInfo *adapters, size_t count)"),
425
+ gpuDeviceCreate: deviceLib.func("int mediaway_gpu_device_create(MwGpuDeviceOptions *options, _Out_ void **out_device)"),
426
+ gpuDeviceHandle: deviceLib.func("int mediaway_gpu_device_handle(void *device, _Out_ MwGpuDeviceHandle *out_handle)"),
427
+ gpuDeviceClose: deviceLib.func("void mediaway_gpu_device_close(void *device)"),
450
428
  };
451
429
  // ── Copy helpers ───────────────────────────────────────────────────────────────
452
430
  /** Copy `len` bytes out of a koffi pointer/opaque handle. */
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Native library discovery + koffi load for @mediaway/ffi.
3
+ *
4
+ * Split out of index.ts (ADR-0024, multi-platform binding distribution)
5
+ * once the added per-platform search-path logic pushed index.ts's struct/
6
+ * function-binding definitions past the workspace's 1000-line source cap.
7
+ */
8
+ export declare function findLibrary(name: string): string;
9
+ export declare const containerLib: import("koffi").LibraryHandle;
10
+ export declare const pipelineLib: import("koffi").LibraryHandle;
11
+ export declare const deviceLib: import("koffi").LibraryHandle;
package/dist/loader.js ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Native library discovery + koffi load for @mediaway/ffi.
3
+ *
4
+ * Split out of index.ts (ADR-0024, multi-platform binding distribution)
5
+ * once the added per-platform search-path logic pushed index.ts's struct/
6
+ * function-binding definitions past the workspace's 1000-line source cap.
7
+ */
8
+ import koffi from "koffi";
9
+ import fs from "node:fs";
10
+ import path from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+ // ── Library discovery ──────────────────────────────────────────────────────────
13
+ // The cdylib is a Rust build artifact, not an installed system library.
14
+ // Search:
15
+ // 1. $MEDIAWAY_FFI_DIR
16
+ // 2. <this package>/native/<platform>-<arch> (libs for every platform
17
+ // bundled at pack time — the npm distribution; see § platform tag)
18
+ // 3. <repo root>/target/x86_64-pc-windows-gnu/debug (GNU toolchain, dev runs)
19
+ // 4. <repo root>/target/debug (host/MSVC toolchain)
20
+ // 5. cwd
21
+ const here = path.dirname(fileURLToPath(import.meta.url));
22
+ const repoRoot = path.resolve(here, "..", "..", "..", "..", "..");
23
+ /**
24
+ * `os-arch` tag matching one of `native/<tag>`'s subdirectories (this
25
+ * package bundles every platform's prebuilt lib directly — see
26
+ * tools/scripts/copy-native-dlls.ts). Returns `undefined` for an
27
+ * unsupported platform/arch pair rather than throwing, so callers can still
28
+ * fall through to the other search dirs (e.g. `$MEDIAWAY_FFI_DIR` during
29
+ * local development on an unlisted arch).
30
+ */
31
+ function platformTag() {
32
+ const os = process.platform === "win32" ? "win32" : process.platform === "linux" ? "linux"
33
+ : process.platform === "darwin" ? "darwin" : undefined;
34
+ const arch = process.arch === "x64" ? "x64" : process.arch === "arm64" ? "arm64" : undefined;
35
+ return os && arch ? `${os}-${arch}` : undefined;
36
+ }
37
+ const tag = platformTag();
38
+ const searchDirs = [
39
+ process.env.MEDIAWAY_FFI_DIR ?? "",
40
+ tag ? path.resolve(here, "..", "native", tag) : "",
41
+ path.join(repoRoot, "target", "x86_64-pc-windows-gnu", "debug"),
42
+ path.join(repoRoot, "target", "debug"),
43
+ process.cwd(),
44
+ ];
45
+ export function findLibrary(name) {
46
+ for (const dir of searchDirs) {
47
+ if (!dir)
48
+ continue;
49
+ const candidate = path.join(dir, name);
50
+ if (fs.existsSync(candidate))
51
+ return candidate;
52
+ }
53
+ throw new Error(`cannot find ${name}; set $MEDIAWAY_FFI_DIR or build the -ffi crates`);
54
+ }
55
+ /** cdylib filename Cargo produces for this platform. */
56
+ function libraryFilename() {
57
+ switch (process.platform) {
58
+ case "win32":
59
+ return "mediaway_ffi.dll";
60
+ case "linux":
61
+ return "libmediaway_ffi.so";
62
+ case "darwin":
63
+ return "libmediaway_ffi.dylib";
64
+ default:
65
+ throw new Error(`mediaway: unsupported platform ${process.platform}`);
66
+ }
67
+ }
68
+ function load(name) {
69
+ return koffi.load(findLibrary(name));
70
+ }
71
+ const libraryName = libraryFilename();
72
+ export const containerLib = load(libraryName);
73
+ export const pipelineLib = load(libraryName);
74
+ export const deviceLib = load(libraryName);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediaway/ffi",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "description": "Rust-based, lightweight, fast — Mediaway native C ABI bindings for Node.js — the shared DLL behind the @mediaway packages",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",