@mediaway/ffi 0.1.4 → 0.1.6

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
@@ -13,33 +13,46 @@
13
13
  * buffers, polled device frames) MUST be released through the matching
14
14
  * `_free` — the public packages do this automatically.
15
15
  */
16
+ import { type TypeObject } from "koffi";
16
17
  export declare function findLibrary(name: string): string;
17
18
  export declare const containerLib: import("koffi").LibraryHandle;
18
19
  export declare const pipelineLib: import("koffi").LibraryHandle;
19
20
  export declare const deviceLib: import("koffi").LibraryHandle;
20
- export declare const MwRational: import("koffi").TypeObject;
21
- export declare const MwVideoTrackInfo: import("koffi").TypeObject;
22
- export declare const MwAudioTrackInfo: import("koffi").TypeObject;
23
- export declare const MwPacketView: import("koffi").TypeObject;
24
- export declare const MwPacket: import("koffi").TypeObject;
25
- export declare const MwStreamInfo: import("koffi").TypeObject;
26
- export declare const MwGpuDeviceHandle: import("koffi").TypeObject;
27
- export declare const MwGpuBufferHandle: import("koffi").TypeObject;
28
- export declare const MwEncConfig: import("koffi").TypeObject;
29
- export declare const MwPipelineFrame: import("koffi").TypeObject;
30
- export declare const MwCameraConfig: import("koffi").TypeObject;
31
- export declare const MwCameraFrame: import("koffi").TypeObject;
32
- export declare const MwDesktopConfig: import("koffi").TypeObject;
33
- export declare const MwDesktopFrame: import("koffi").TypeObject;
34
- export declare const MwAudioConfig: import("koffi").TypeObject;
35
- export declare const MwAudioFrame: import("koffi").TypeObject;
36
- export declare const MwAudioEncodeConfig: import("koffi").TypeObject;
37
- export declare const MwAudioFrameView: import("koffi").TypeObject;
38
- export declare const MwAudioPacket: import("koffi").TypeObject;
39
- export declare const MwAudioStreamInfo: import("koffi").TypeObject;
21
+ export declare const MwRational: TypeObject;
22
+ export declare const MwVideoTrackInfo: TypeObject;
23
+ export declare const MwAudioTrackInfo: TypeObject;
24
+ export declare const MwPacketView: TypeObject;
25
+ export declare const MwPacket: TypeObject;
26
+ export declare const MwTsElementaryStream: TypeObject;
27
+ export declare const MwMp3FrameHeader: TypeObject;
28
+ export declare const MwWaveFormat: TypeObject;
29
+ export declare const MwStreamInfo: TypeObject;
30
+ export declare const MwGpuDeviceHandle: TypeObject;
31
+ export declare const MwGpuBufferHandle: TypeObject;
32
+ export declare const MwEncConfig: TypeObject;
33
+ export declare const MwPipelineFrame: TypeObject;
34
+ export declare const MwCameraConfig: TypeObject;
35
+ export declare const MwCameraFrame: TypeObject;
36
+ export declare const MwDesktopConfig: TypeObject;
37
+ export declare const MwDesktopFrame: TypeObject;
38
+ export declare const MwGpuAdapterInfo: TypeObject;
39
+ export declare const MwGpuAdapterSelect: TypeObject;
40
+ export declare const MwGpuDeviceOptions: TypeObject;
41
+ export declare const MwAudioConfig: TypeObject;
42
+ export declare const MwAudioFrame: TypeObject;
43
+ export declare const MwAudioEncodeConfig: TypeObject;
44
+ export declare const MwAudioFrameView: TypeObject;
45
+ export declare const MwAudioPacket: TypeObject;
46
+ export declare const MwAudioStreamInfo: TypeObject;
47
+ export declare const MwDecodePacketView: TypeObject;
48
+ export declare const MwAutoVideoDecodeConfig: TypeObject;
49
+ export declare const MwDecodedVideoFrame: TypeObject;
50
+ export declare const MwAudioDecodeConfig: TypeObject;
51
+ export declare const MwDecodedAudioFrame: TypeObject;
40
52
  export declare const container: {
41
53
  abiVersion: import("koffi").Callable;
42
54
  muxerCreate: import("koffi").Callable;
55
+ muxerCreateForFormat: import("koffi").Callable;
43
56
  muxerCreateWithBatch: import("koffi").Callable;
44
57
  muxerAddVideoTrack: import("koffi").Callable;
45
58
  muxerAddAudioTrack: import("koffi").Callable;
@@ -49,6 +62,7 @@ export declare const container: {
49
62
  muxerPollBytes: import("koffi").Callable;
50
63
  muxerClose: import("koffi").Callable;
51
64
  demuxerCreate: import("koffi").Callable;
65
+ demuxerCreateForFormat: import("koffi").Callable;
52
66
  demuxerPushBytes: import("koffi").Callable;
53
67
  demuxerStreamCount: import("koffi").Callable;
54
68
  demuxerStreamAt: import("koffi").Callable;
@@ -59,6 +73,67 @@ export declare const container: {
59
73
  bufferFree: import("koffi").Callable;
60
74
  packetFree: import("koffi").Callable;
61
75
  streamInfoFree: import("koffi").Callable;
76
+ oggMuxerCreate: import("koffi").Callable;
77
+ oggMuxerPushPacket: import("koffi").Callable;
78
+ oggMuxerFlush: import("koffi").Callable;
79
+ oggMuxerPollBytes: import("koffi").Callable;
80
+ oggMuxerClose: import("koffi").Callable;
81
+ oggDemuxerCreate: import("koffi").Callable;
82
+ oggDemuxerPushBytes: import("koffi").Callable;
83
+ oggDemuxerStreamCount: import("koffi").Callable;
84
+ oggDemuxerStreamAt: import("koffi").Callable;
85
+ oggDemuxerPollPacket: import("koffi").Callable;
86
+ oggDemuxerClose: import("koffi").Callable;
87
+ adtsMuxerCreate: import("koffi").Callable;
88
+ adtsMuxerPushPacket: import("koffi").Callable;
89
+ adtsMuxerFlush: import("koffi").Callable;
90
+ adtsMuxerPollBytes: import("koffi").Callable;
91
+ adtsMuxerClose: import("koffi").Callable;
92
+ adtsDemuxerCreate: import("koffi").Callable;
93
+ adtsDemuxerPushBytes: import("koffi").Callable;
94
+ adtsDemuxerStreamCount: import("koffi").Callable;
95
+ adtsDemuxerStreamAt: import("koffi").Callable;
96
+ adtsDemuxerPollPacket: import("koffi").Callable;
97
+ adtsDemuxerClose: import("koffi").Callable;
98
+ flvMuxerCreate: import("koffi").Callable;
99
+ flvMuxerWriteHeader: import("koffi").Callable;
100
+ flvMuxerAddVideoTrack: import("koffi").Callable;
101
+ flvMuxerAddAudioTrack: import("koffi").Callable;
102
+ flvMuxerPushPacket: import("koffi").Callable;
103
+ flvMuxerClose: import("koffi").Callable;
104
+ flvDemuxerCreate: import("koffi").Callable;
105
+ flvDemuxerPushBytes: import("koffi").Callable;
106
+ flvDemuxerStreamCount: import("koffi").Callable;
107
+ flvDemuxerStreamAt: import("koffi").Callable;
108
+ flvDemuxerPollPacket: import("koffi").Callable;
109
+ flvDemuxerClose: import("koffi").Callable;
110
+ tsMuxerCreate: import("koffi").Callable;
111
+ tsMuxerWritePatPmt: import("koffi").Callable;
112
+ tsMuxerWriteAccessUnit: import("koffi").Callable;
113
+ tsMuxerClose: import("koffi").Callable;
114
+ tsDemuxerCreate: import("koffi").Callable;
115
+ tsDemuxerPushBytes: import("koffi").Callable;
116
+ tsDemuxerStreamCount: import("koffi").Callable;
117
+ tsDemuxerStreamAt: import("koffi").Callable;
118
+ tsDemuxerPollPacket: import("koffi").Callable;
119
+ tsDemuxerFinish: import("koffi").Callable;
120
+ tsDemuxerFinishFree: import("koffi").Callable;
121
+ tsDemuxerClose: import("koffi").Callable;
122
+ mp3MuxerCreate: import("koffi").Callable;
123
+ mp3MuxerWriteFrame: import("koffi").Callable;
124
+ mp3MuxerClose: import("koffi").Callable;
125
+ mp3DemuxerCreate: import("koffi").Callable;
126
+ mp3DemuxerPushBytes: import("koffi").Callable;
127
+ mp3DemuxerStreamCount: import("koffi").Callable;
128
+ mp3DemuxerStreamAt: import("koffi").Callable;
129
+ mp3DemuxerPollPacket: import("koffi").Callable;
130
+ mp3DemuxerClose: import("koffi").Callable;
131
+ wavMuxerCreate: import("koffi").Callable;
132
+ wavMuxerCreateWithFormat: import("koffi").Callable;
133
+ wavMuxerPushPacket: import("koffi").Callable;
134
+ wavMuxerFinish: import("koffi").Callable;
135
+ wavMuxerClose: import("koffi").Callable;
136
+ wavParse: import("koffi").Callable;
62
137
  };
63
138
  export declare const pipeline: {
64
139
  abiVersion: import("koffi").Callable;
@@ -80,6 +155,22 @@ export declare const pipeline: {
80
155
  audioSessionClose: import("koffi").Callable;
81
156
  pipelinePacketFree: import("koffi").Callable;
82
157
  pipelineStreamInfoFree: import("koffi").Callable;
158
+ decodeConfigNew: import("koffi").Callable;
159
+ decodeSessionOpen: import("koffi").Callable;
160
+ decodeSessionPushPacket: import("koffi").Callable;
161
+ decodeSessionPollFrame: import("koffi").Callable;
162
+ decodeSessionFlush: import("koffi").Callable;
163
+ decodeSessionClose: import("koffi").Callable;
164
+ decodedVideoFrameFree: import("koffi").Callable;
165
+ audioDecodeConfigOpus: import("koffi").Callable;
166
+ audioDecodeSessionOpen: import("koffi").Callable;
167
+ audioDecodeSessionPushPacket: import("koffi").Callable;
168
+ audioDecodeSessionPollFrame: import("koffi").Callable;
169
+ audioDecodeSessionFlush: import("koffi").Callable;
170
+ audioDecodeSessionClose: import("koffi").Callable;
171
+ decodedAudioFrameFree: import("koffi").Callable;
172
+ sessionWriteFrameFromCameraCapture: import("koffi").Callable;
173
+ sessionWriteFrameFromDesktopCapture: import("koffi").Callable;
83
174
  };
84
175
  export declare const device: {
85
176
  abiVersion: import("koffi").Callable;
@@ -104,9 +195,21 @@ export declare const device: {
104
195
  audioPollFrame: import("koffi").Callable;
105
196
  audioClose: import("koffi").Callable;
106
197
  audioFrameFree: import("koffi").Callable;
198
+ gpuAdapterList: import("koffi").Callable;
199
+ gpuAdapterListFree: import("koffi").Callable;
200
+ gpuDeviceCreate: import("koffi").Callable;
201
+ gpuDeviceHandle: import("koffi").Callable;
202
+ gpuDeviceClose: import("koffi").Callable;
107
203
  };
108
204
  /** Copy `len` bytes out of a koffi pointer/opaque handle. */
109
205
  export declare function copyBytes(ptr: unknown, len: number): Buffer;
206
+ /**
207
+ * Decode `count` consecutive struct instances out of a pointer to an owned
208
+ * native array (e.g. `mediaway_ts_demuxer_finish`'s `out_packets`) — the only
209
+ * multi-element owned-array output shape in this crate. Free the underlying
210
+ * array with the matching `_finish_free` after copying out what's needed.
211
+ */
212
+ export declare function decodeArray<T>(ptr: unknown, type: TypeObject, count: number): T[];
110
213
  /** `mediaway_rational_t` (u64 num / u32 den). */
111
214
  export interface RawRational {
112
215
  num: bigint | number;
@@ -159,12 +262,32 @@ export interface RawStreamInfo {
159
262
  export interface RawPacket {
160
263
  stream_id: number;
161
264
  pts: bigint | number;
265
+ dts: bigint | number;
162
266
  duration: bigint | number;
163
267
  is_keyframe: boolean;
164
268
  is_discard: boolean;
165
269
  payload: unknown;
166
270
  payload_len: number;
167
271
  }
272
+ /** `mediaway_ts_elementary_stream_t` (MPEG-TS muxer construction input). */
273
+ export interface RawTsElementaryStream {
274
+ pid: number;
275
+ codec: number;
276
+ }
277
+ /** `mediaway_mp3_frame_header_t` (MP3 muxer construction input). */
278
+ export interface RawMp3FrameHeader {
279
+ version: number;
280
+ bitrate_kbps: number;
281
+ sample_rate: number;
282
+ channel_mode: number;
283
+ }
284
+ /** `mediaway_wave_format_t` (WAV muxer construction input). */
285
+ export interface RawWaveFormat {
286
+ sample_format: number;
287
+ channels: number;
288
+ sample_rate: number;
289
+ bits_per_sample: number;
290
+ }
168
291
  /** ABI output structs — fields are filled by the ABI call; callers construct
169
292
  * them empty (`{} as RawX`) and read the fields after the call. */
170
293
  /** `mediaway_camera_frame_t` / `mediaway_audio_frame_t` (device outputs). */
@@ -177,6 +300,20 @@ export interface RawCameraFrame {
177
300
  data: unknown;
178
301
  data_len: number;
179
302
  }
303
+ /** `mediaway_desktop_frame_t` (Screen output) — unlike `RawCameraFrame`, GPU
304
+ * storage (`storage_kind == 1`) leaves `data`/`data_len` empty and carries the
305
+ * frame in `gpu_buffer` instead (borrowed — never freed by the caller). */
306
+ export interface RawDesktopFrame {
307
+ pts: bigint | number;
308
+ duration: bigint | number;
309
+ width: number;
310
+ height: number;
311
+ pixel_format: number;
312
+ storage_kind: number;
313
+ data: unknown;
314
+ data_len: number;
315
+ gpu_buffer: RawGpuBufferHandle;
316
+ }
180
317
  export interface RawAudioFrame {
181
318
  pts: bigint | number;
182
319
  duration: bigint | number;
@@ -198,6 +335,13 @@ export interface RawPipelineFrame {
198
335
  raw_bytes_len: number;
199
336
  gpu_buffer: RawGpuBufferHandle;
200
337
  }
338
+ /** `mediaway_gpu_device_handle_t` (Screen capture / GPU-input encode input,
339
+ * mediaway_gpu_device_handle()'s output). */
340
+ export interface RawGpuDeviceHandle {
341
+ kind: number;
342
+ native: number | bigint;
343
+ webgpu_device_id: number | bigint;
344
+ }
201
345
  /** `mediaway_gpu_buffer_handle_t`. */
202
346
  export interface RawGpuBufferHandle {
203
347
  kind: number;
@@ -242,3 +386,71 @@ export interface RawAudioPacket {
242
386
  payload: unknown;
243
387
  payload_len: number;
244
388
  }
389
+ /** `mediaway_decode_packet_view_t` (decode session input; shared by video + audio). */
390
+ export interface RawDecodePacketView {
391
+ stream_id: number;
392
+ pts: bigint | number;
393
+ dts: bigint | number;
394
+ duration: bigint | number;
395
+ is_keyframe: boolean;
396
+ is_discard: boolean;
397
+ payload: unknown;
398
+ payload_len: number;
399
+ }
400
+ /** `mediaway_auto_video_decode_config_t`. */
401
+ export interface RawAutoVideoDecodeConfig {
402
+ codec: number;
403
+ width: number;
404
+ height: number;
405
+ time_base: RawRational;
406
+ pixel_format: number;
407
+ extra_data: unknown;
408
+ extra_data_len: number;
409
+ }
410
+ /** `mediaway_decoded_video_frame_t` (decode session output). */
411
+ export interface RawDecodedVideoFrame {
412
+ pts: bigint | number;
413
+ duration: bigint | number;
414
+ width: number;
415
+ height: number;
416
+ pixel_format: number;
417
+ data: unknown;
418
+ data_len: number;
419
+ }
420
+ /** `mediaway_audio_decode_config_t` (Opus only today). */
421
+ export interface RawAudioDecodeConfig {
422
+ codec: number;
423
+ sample_rate: number;
424
+ channels: number;
425
+ time_base: RawRational;
426
+ }
427
+ /** `mediaway_decoded_audio_frame_t` (audio decode session output; always F32). */
428
+ export interface RawDecodedAudioFrame {
429
+ pts: bigint | number;
430
+ duration: bigint | number;
431
+ sample_rate: number;
432
+ channels: number;
433
+ sample_format: number;
434
+ data: unknown;
435
+ data_len: number;
436
+ }
437
+ /** `mediaway_gpu_adapter_info_t` (mediaway-device ADR-0007). */
438
+ export interface RawGpuAdapterInfo {
439
+ index: number;
440
+ name: string;
441
+ vendor_id: number;
442
+ device_id: number;
443
+ dedicated_video_memory: bigint | number;
444
+ is_hardware: boolean;
445
+ }
446
+ /** `mediaway_gpu_adapter_select_t`. */
447
+ export interface RawGpuAdapterSelect {
448
+ kind: number;
449
+ index: number;
450
+ }
451
+ /** `mediaway_gpu_device_options_t`. */
452
+ export interface RawGpuDeviceOptions {
453
+ adapter: RawGpuAdapterSelect;
454
+ video_support: boolean;
455
+ debug_layer: boolean;
456
+ }
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * buffers, polled device frames) MUST be released through the matching
14
14
  * `_free` — the public packages do this automatically.
15
15
  */
16
- import koffi from "koffi";
16
+ import koffi, {} from "koffi";
17
17
  import fs from "node:fs";
18
18
  import path from "node:path";
19
19
  import { fileURLToPath } from "node:url";
@@ -43,12 +43,29 @@ export function findLibrary(name) {
43
43
  }
44
44
  throw new Error(`cannot find ${name}; set $MEDIAWAY_FFI_DIR or build the -ffi crates`);
45
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
+ }
46
62
  function load(name) {
47
63
  return koffi.load(findLibrary(name));
48
64
  }
49
- export const containerLib = load("mediaway_ffi.dll");
50
- export const pipelineLib = load("mediaway_ffi.dll");
51
- export const deviceLib = load("mediaway_ffi.dll");
65
+ const libraryName = libraryFilename();
66
+ export const containerLib = load(libraryName);
67
+ export const pipelineLib = load(libraryName);
68
+ export const deviceLib = load(libraryName);
52
69
  // ── Structs (layouts mirror the headers exactly) ───────────────────────────────
53
70
  export const MwRational = koffi.struct("MwRational", {
54
71
  num: "uint64",
@@ -92,6 +109,22 @@ export const MwPacket = koffi.struct("MwPacket", {
92
109
  payload: "uint8_t *",
93
110
  payload_len: "size_t",
94
111
  });
112
+ export const MwTsElementaryStream = koffi.struct("MwTsElementaryStream", {
113
+ pid: "uint16",
114
+ codec: "int32",
115
+ });
116
+ export const MwMp3FrameHeader = koffi.struct("MwMp3FrameHeader", {
117
+ version: "int32",
118
+ bitrate_kbps: "uint16",
119
+ sample_rate: "uint32",
120
+ channel_mode: "int32",
121
+ });
122
+ export const MwWaveFormat = koffi.struct("MwWaveFormat", {
123
+ sample_format: "int32",
124
+ channels: "uint16",
125
+ sample_rate: "uint32",
126
+ bits_per_sample: "uint16",
127
+ });
95
128
  export const MwStreamInfo = koffi.struct("MwStreamInfo", {
96
129
  id: "uint32",
97
130
  codec: "int32",
@@ -166,6 +199,23 @@ export const MwDesktopFrame = koffi.struct("MwDesktopFrame", {
166
199
  data_len: "size_t",
167
200
  gpu_buffer: MwGpuBufferHandle,
168
201
  });
202
+ export const MwGpuAdapterInfo = koffi.struct("MwGpuAdapterInfo", {
203
+ index: "uint32",
204
+ name: "str", // owned NUL-terminated UTF-8; freed via gpuAdapterListFree, not per-entry
205
+ vendor_id: "uint32",
206
+ device_id: "uint32",
207
+ dedicated_video_memory: "uint64",
208
+ is_hardware: "bool",
209
+ });
210
+ export const MwGpuAdapterSelect = koffi.struct("MwGpuAdapterSelect", {
211
+ kind: "int32", // 0 = Default, 1 = Index
212
+ index: "uint32", // meaningful only when kind == Index
213
+ });
214
+ export const MwGpuDeviceOptions = koffi.struct("MwGpuDeviceOptions", {
215
+ adapter: MwGpuAdapterSelect,
216
+ video_support: "bool",
217
+ debug_layer: "bool",
218
+ });
169
219
  export const MwAudioConfig = koffi.struct("MwAudioConfig", {
170
220
  device_index: "uint32",
171
221
  time_base: MwRational,
@@ -214,10 +264,57 @@ export const MwAudioStreamInfo = koffi.struct("MwAudioStreamInfo", {
214
264
  extra_data: "uint8_t *",
215
265
  extra_data_len: "size_t",
216
266
  });
267
+ // ── Decode (adr/0004-auto-decode-c-abi.md, adr/pipeline/0006) ──────────────────
268
+ // MwDecodePacketView is shared by both video and audio decode push_packet
269
+ // calls — a new, pipeline-scoped type, not MwPacketView above.
270
+ export const MwDecodePacketView = koffi.struct("MwDecodePacketView", {
271
+ stream_id: "uint32", // unused by decode; kept for call-site symmetry
272
+ pts: "int64",
273
+ dts: "int64",
274
+ duration: "uint64",
275
+ is_keyframe: "bool",
276
+ is_discard: "bool",
277
+ payload: "uint8_t *",
278
+ payload_len: "size_t",
279
+ });
280
+ export const MwAutoVideoDecodeConfig = koffi.struct("MwAutoVideoDecodeConfig", {
281
+ codec: "int32",
282
+ width: "uint32",
283
+ height: "uint32",
284
+ time_base: MwRational,
285
+ pixel_format: "int32",
286
+ extra_data: "uint8_t *", // borrowed, open-call only
287
+ extra_data_len: "size_t",
288
+ });
289
+ export const MwDecodedVideoFrame = koffi.struct("MwDecodedVideoFrame", {
290
+ pts: "int64",
291
+ duration: "uint64",
292
+ width: "uint32",
293
+ height: "uint32",
294
+ pixel_format: "int32",
295
+ data: "uint8_t *", // owned
296
+ data_len: "size_t",
297
+ });
298
+ export const MwAudioDecodeConfig = koffi.struct("MwAudioDecodeConfig", {
299
+ codec: "int32", // Opus only today
300
+ sample_rate: "uint32",
301
+ channels: "uint16",
302
+ time_base: MwRational,
303
+ });
304
+ export const MwDecodedAudioFrame = koffi.struct("MwDecodedAudioFrame", {
305
+ pts: "int64",
306
+ duration: "uint64",
307
+ sample_rate: "uint32",
308
+ channels: "uint16",
309
+ sample_format: "int32", // always F32 for Opus
310
+ data: "uint8_t *", // owned interleaved PCM
311
+ data_len: "size_t",
312
+ });
217
313
  // ── Container functions ────────────────────────────────────────────────────────
218
314
  export const container = {
219
315
  abiVersion: containerLib.func("uint32_t mediaway_container_ffi_abi_version()"),
220
316
  muxerCreate: containerLib.func("void *mediaway_muxer_create()"),
317
+ muxerCreateForFormat: containerLib.func("void *mediaway_muxer_create_for_format(int format)"),
221
318
  muxerCreateWithBatch: containerLib.func("void *mediaway_muxer_create_with_fragment_batch(size_t batch)"),
222
319
  muxerAddVideoTrack: containerLib.func("int mediaway_muxer_add_video_track(void *muxer, MwVideoTrackInfo *info)"),
223
320
  muxerAddAudioTrack: containerLib.func("int mediaway_muxer_add_audio_track(void *muxer, MwAudioTrackInfo *info)"),
@@ -227,6 +324,7 @@ export const container = {
227
324
  muxerPollBytes: containerLib.func("int mediaway_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
228
325
  muxerClose: containerLib.func("void mediaway_muxer_close(void *muxer)"),
229
326
  demuxerCreate: containerLib.func("void *mediaway_demuxer_create()"),
327
+ demuxerCreateForFormat: containerLib.func("void *mediaway_demuxer_create_for_format(int format)"),
230
328
  demuxerPushBytes: containerLib.func("int mediaway_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
231
329
  demuxerStreamCount: containerLib.func("size_t mediaway_demuxer_stream_count(void *demuxer)"),
232
330
  demuxerStreamAt: containerLib.func("int mediaway_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
@@ -237,6 +335,73 @@ export const container = {
237
335
  bufferFree: containerLib.func("void mediaway_buffer_free(uint8_t *data, size_t len)"),
238
336
  packetFree: containerLib.func("void mediaway_packet_free(MwPacket *packet)"),
239
337
  streamInfoFree: containerLib.func("void mediaway_stream_info_free(MwStreamInfo *info)"),
338
+ // ── Ogg (adr/container/0004) ──────────────────────────────────────────────
339
+ oggMuxerCreate: containerLib.func("void *mediaway_ogg_muxer_create(uint32_t serial)"),
340
+ oggMuxerPushPacket: containerLib.func("int mediaway_ogg_muxer_push_packet(void *muxer, MwPacketView *packet)"),
341
+ oggMuxerFlush: containerLib.func("int mediaway_ogg_muxer_flush(void *muxer)"),
342
+ oggMuxerPollBytes: containerLib.func("int mediaway_ogg_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
343
+ oggMuxerClose: containerLib.func("void mediaway_ogg_muxer_close(void *muxer)"),
344
+ oggDemuxerCreate: containerLib.func("void *mediaway_ogg_demuxer_create()"),
345
+ oggDemuxerPushBytes: containerLib.func("int mediaway_ogg_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
346
+ oggDemuxerStreamCount: containerLib.func("size_t mediaway_ogg_demuxer_stream_count(void *demuxer)"),
347
+ oggDemuxerStreamAt: containerLib.func("int mediaway_ogg_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
348
+ oggDemuxerPollPacket: containerLib.func("int mediaway_ogg_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
349
+ oggDemuxerClose: containerLib.func("void mediaway_ogg_demuxer_close(void *demuxer)"),
350
+ // ── ADTS (adr/container/0004) ─────────────────────────────────────────────
351
+ adtsMuxerCreate: containerLib.func("void *mediaway_adts_muxer_create(uint32_t sample_rate, uint8_t channels)"),
352
+ adtsMuxerPushPacket: containerLib.func("int mediaway_adts_muxer_push_packet(void *muxer, MwPacketView *packet)"),
353
+ adtsMuxerFlush: containerLib.func("int mediaway_adts_muxer_flush(void *muxer)"),
354
+ adtsMuxerPollBytes: containerLib.func("int mediaway_adts_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
355
+ adtsMuxerClose: containerLib.func("void mediaway_adts_muxer_close(void *muxer)"),
356
+ adtsDemuxerCreate: containerLib.func("void *mediaway_adts_demuxer_create()"),
357
+ adtsDemuxerPushBytes: containerLib.func("int mediaway_adts_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
358
+ adtsDemuxerStreamCount: containerLib.func("size_t mediaway_adts_demuxer_stream_count(void *demuxer)"),
359
+ adtsDemuxerStreamAt: containerLib.func("int mediaway_adts_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
360
+ adtsDemuxerPollPacket: containerLib.func("int mediaway_adts_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
361
+ adtsDemuxerClose: containerLib.func("void mediaway_adts_demuxer_close(void *demuxer)"),
362
+ // ── FLV (adr/container/0005) ──────────────────────────────────────────────
363
+ flvMuxerCreate: containerLib.func("void *mediaway_flv_muxer_create()"),
364
+ flvMuxerWriteHeader: containerLib.func("int mediaway_flv_muxer_write_header(void *muxer, bool has_audio, bool has_video, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
365
+ flvMuxerAddVideoTrack: containerLib.func("int mediaway_flv_muxer_add_video_track(void *muxer, MwVideoTrackInfo *info)"),
366
+ flvMuxerAddAudioTrack: containerLib.func("int mediaway_flv_muxer_add_audio_track(void *muxer, MwAudioTrackInfo *info)"),
367
+ flvMuxerPushPacket: containerLib.func("int mediaway_flv_muxer_push_packet(void *muxer, MwPacketView *packet, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
368
+ flvMuxerClose: containerLib.func("void mediaway_flv_muxer_close(void *muxer)"),
369
+ flvDemuxerCreate: containerLib.func("void *mediaway_flv_demuxer_create()"),
370
+ flvDemuxerPushBytes: containerLib.func("int mediaway_flv_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
371
+ flvDemuxerStreamCount: containerLib.func("size_t mediaway_flv_demuxer_stream_count(void *demuxer)"),
372
+ flvDemuxerStreamAt: containerLib.func("int mediaway_flv_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
373
+ flvDemuxerPollPacket: containerLib.func("int mediaway_flv_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
374
+ flvDemuxerClose: containerLib.func("void mediaway_flv_demuxer_close(void *demuxer)"),
375
+ // ── MPEG-TS (adr/container/0006) ──────────────────────────────────────────
376
+ tsMuxerCreate: containerLib.func("void *mediaway_ts_muxer_create(uint16_t program_number, uint16_t pmt_pid, MwTsElementaryStream *streams, size_t stream_count)"),
377
+ tsMuxerWritePatPmt: containerLib.func("int mediaway_ts_muxer_write_pat_pmt(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
378
+ tsMuxerWriteAccessUnit: containerLib.func("int mediaway_ts_muxer_write_access_unit(void *muxer, uint16_t pid, uint8_t *data, size_t data_len, uint64_t pts_90k, bool has_dts, uint64_t dts_90k, bool random_access, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
379
+ tsMuxerClose: containerLib.func("void mediaway_ts_muxer_close(void *muxer)"),
380
+ tsDemuxerCreate: containerLib.func("void *mediaway_ts_demuxer_create()"),
381
+ tsDemuxerPushBytes: containerLib.func("int mediaway_ts_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
382
+ tsDemuxerStreamCount: containerLib.func("size_t mediaway_ts_demuxer_stream_count(void *demuxer)"),
383
+ tsDemuxerStreamAt: containerLib.func("int mediaway_ts_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
384
+ tsDemuxerPollPacket: containerLib.func("int mediaway_ts_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
385
+ tsDemuxerFinish: containerLib.func("int mediaway_ts_demuxer_finish(void *demuxer, _Out_ MwPacket **out_packets, _Out_ size_t *out_count)"),
386
+ tsDemuxerFinishFree: containerLib.func("void mediaway_ts_demuxer_finish_free(MwPacket *packets, size_t count)"),
387
+ tsDemuxerClose: containerLib.func("void mediaway_ts_demuxer_close(void *demuxer)"),
388
+ // ── MP3 (adr/container/0007) ──────────────────────────────────────────────
389
+ mp3MuxerCreate: containerLib.func("void *mediaway_mp3_muxer_create(MwMp3FrameHeader *header)"),
390
+ mp3MuxerWriteFrame: containerLib.func("int mediaway_mp3_muxer_write_frame(void *muxer, uint8_t *frame_body, size_t frame_body_len, bool padding, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
391
+ mp3MuxerClose: containerLib.func("void mediaway_mp3_muxer_close(void *muxer)"),
392
+ mp3DemuxerCreate: containerLib.func("void *mediaway_mp3_demuxer_create()"),
393
+ mp3DemuxerPushBytes: containerLib.func("int mediaway_mp3_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
394
+ mp3DemuxerStreamCount: containerLib.func("size_t mediaway_mp3_demuxer_stream_count(void *demuxer)"),
395
+ mp3DemuxerStreamAt: containerLib.func("int mediaway_mp3_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
396
+ mp3DemuxerPollPacket: containerLib.func("int mediaway_mp3_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
397
+ mp3DemuxerClose: containerLib.func("void mediaway_mp3_demuxer_close(void *demuxer)"),
398
+ // ── WAV (adr/container/0008) ──────────────────────────────────────────────
399
+ wavMuxerCreate: containerLib.func("void *mediaway_wav_muxer_create(uint32_t sample_rate, uint16_t channels, uint16_t bits_per_sample)"),
400
+ wavMuxerCreateWithFormat: containerLib.func("void *mediaway_wav_muxer_create_with_format(MwWaveFormat *format)"),
401
+ wavMuxerPushPacket: containerLib.func("int mediaway_wav_muxer_push_packet(void *muxer, MwPacketView *packet)"),
402
+ wavMuxerFinish: containerLib.func("int mediaway_wav_muxer_finish(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
403
+ wavMuxerClose: containerLib.func("void mediaway_wav_muxer_close(void *muxer)"),
404
+ wavParse: containerLib.func("int mediaway_wav_parse(uint8_t *data, size_t data_len, _Out_ MwStreamInfo *out_info, _Out_ MwPacket *out_packet)"),
240
405
  };
241
406
  // ── Pipeline functions ─────────────────────────────────────────────────────────
242
407
  export const pipeline = {
@@ -259,6 +424,26 @@ export const pipeline = {
259
424
  audioSessionClose: pipelineLib.func("void mediaway_audio_encode_session_close(void *session)"),
260
425
  pipelinePacketFree: pipelineLib.func("void mediaway_pipeline_ffi_packet_free(MwAudioPacket *packet)"),
261
426
  pipelineStreamInfoFree: pipelineLib.func("void mediaway_pipeline_ffi_stream_info_free(MwAudioStreamInfo *info)"),
427
+ // ── Decode (adr/0004-auto-decode-c-abi.md, adr/pipeline/0006) ────────────
428
+ decodeConfigNew: pipelineLib.func("MwAutoVideoDecodeConfig mediaway_auto_video_decode_config_new(int codec, uint32_t width, uint32_t height, MwRational time_base, uint8_t *extra_data, size_t extra_data_len)"),
429
+ decodeSessionOpen: pipelineLib.func("int mediaway_decode_session_open(MwAutoVideoDecodeConfig *config, _Out_ void **out_session)"),
430
+ decodeSessionPushPacket: pipelineLib.func("int mediaway_decode_session_push_packet(void *session, MwDecodePacketView *packet)"),
431
+ decodeSessionPollFrame: pipelineLib.func("int mediaway_decode_session_poll_frame(void *session, _Out_ MwDecodedVideoFrame *out_frame, _Out_ bool *out_has)"),
432
+ decodeSessionFlush: pipelineLib.func("int mediaway_decode_session_flush(void *session)"),
433
+ decodeSessionClose: pipelineLib.func("void mediaway_decode_session_close(void *session)"),
434
+ decodedVideoFrameFree: pipelineLib.func("void mediaway_decoded_video_frame_free(MwDecodedVideoFrame *frame)"),
435
+ audioDecodeConfigOpus: pipelineLib.func("MwAudioDecodeConfig mediaway_audio_decode_config_opus(uint32_t sample_rate, uint16_t channels, MwRational time_base)"),
436
+ audioDecodeSessionOpen: pipelineLib.func("int mediaway_audio_decode_session_open(MwAudioDecodeConfig *config, _Out_ void **out_session)"),
437
+ audioDecodeSessionPushPacket: pipelineLib.func("int mediaway_audio_decode_session_push_packet(void *session, MwDecodePacketView *packet)"),
438
+ audioDecodeSessionPollFrame: pipelineLib.func("int mediaway_audio_decode_session_poll_frame(void *session, _Out_ MwDecodedAudioFrame *out_frame, _Out_ bool *out_has)"),
439
+ audioDecodeSessionFlush: pipelineLib.func("int mediaway_audio_decode_session_flush(void *session)"),
440
+ audioDecodeSessionClose: pipelineLib.func("void mediaway_audio_decode_session_close(void *session)"),
441
+ decodedAudioFrameFree: pipelineLib.func("void mediaway_decoded_audio_frame_free(MwDecodedAudioFrame *frame)"),
442
+ // ── Capture-to-encode bridge (adr/pipeline/0005-capture-encode-bridge-c-abi.md) ──
443
+ // Pushes one polled frame from a device.h capture handle straight into a
444
+ // session — no intermediate MwCameraFrame/MwDesktopFrame, no extra copy.
445
+ sessionWriteFrameFromCameraCapture: pipelineLib.func("int mediaway_encode_session_write_frame_from_camera_capture(void *session, void *capture, _Out_ bool *out_wrote_frame)"),
446
+ sessionWriteFrameFromDesktopCapture: pipelineLib.func("int mediaway_encode_session_write_frame_from_desktop_capture(void *session, void *capture, _Out_ bool *out_wrote_frame)"),
262
447
  };
263
448
  // ── Device functions ───────────────────────────────────────────────────────────
264
449
  export const device = {
@@ -284,6 +469,12 @@ export const device = {
284
469
  audioPollFrame: deviceLib.func("int mediaway_audio_capture_poll_frame(void *capture, _Out_ MwAudioFrame *out_frame, _Out_ bool *out_has)"),
285
470
  audioClose: deviceLib.func("int mediaway_audio_capture_close(void *capture)"),
286
471
  audioFrameFree: deviceLib.func("void mediaway_audio_frame_free(MwAudioFrame *frame)"),
472
+ // ── GPU device factory (mediaway-device ADR-0007) ─────────────────────────
473
+ gpuAdapterList: deviceLib.func("int mediaway_gpu_adapter_list(_Out_ MwGpuAdapterInfo **out_adapters, _Out_ size_t *out_count)"),
474
+ gpuAdapterListFree: deviceLib.func("void mediaway_gpu_adapter_list_free(MwGpuAdapterInfo *adapters, size_t count)"),
475
+ gpuDeviceCreate: deviceLib.func("int mediaway_gpu_device_create(MwGpuDeviceOptions *options, _Out_ void **out_device)"),
476
+ gpuDeviceHandle: deviceLib.func("int mediaway_gpu_device_handle(void *device, _Out_ MwGpuDeviceHandle *out_handle)"),
477
+ gpuDeviceClose: deviceLib.func("void mediaway_gpu_device_close(void *device)"),
287
478
  };
288
479
  // ── Copy helpers ───────────────────────────────────────────────────────────────
289
480
  /** Copy `len` bytes out of a koffi pointer/opaque handle. */
@@ -292,3 +483,14 @@ export function copyBytes(ptr, len) {
292
483
  return Buffer.alloc(0);
293
484
  return Buffer.from(koffi.decode(ptr, "uint8_t", len));
294
485
  }
486
+ /**
487
+ * Decode `count` consecutive struct instances out of a pointer to an owned
488
+ * native array (e.g. `mediaway_ts_demuxer_finish`'s `out_packets`) — the only
489
+ * multi-element owned-array output shape in this crate. Free the underlying
490
+ * array with the matching `_finish_free` after copying out what's needed.
491
+ */
492
+ export function decodeArray(ptr, type, count) {
493
+ if (!ptr || count <= 0)
494
+ return [];
495
+ return koffi.decode(ptr, type, count);
496
+ }
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mediaway/ffi",
3
- "version": "0.1.4",
4
- "description": "Mediaway native C ABI bindings for Node.js — the shared DLL behind the @mediaway packages",
3
+ "version": "0.1.6",
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",
7
7
  "types": "./dist/index.d.ts",