@mediaway/ffi 0.1.3 → 0.1.5

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,43 @@
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 MwAudioConfig: TypeObject;
39
+ export declare const MwAudioFrame: TypeObject;
40
+ export declare const MwAudioEncodeConfig: TypeObject;
41
+ export declare const MwAudioFrameView: TypeObject;
42
+ export declare const MwAudioPacket: TypeObject;
43
+ export declare const MwAudioStreamInfo: TypeObject;
44
+ export declare const MwDecodePacketView: TypeObject;
45
+ export declare const MwAutoVideoDecodeConfig: TypeObject;
46
+ export declare const MwDecodedVideoFrame: TypeObject;
47
+ export declare const MwAudioDecodeConfig: TypeObject;
48
+ export declare const MwDecodedAudioFrame: TypeObject;
40
49
  export declare const container: {
41
50
  abiVersion: import("koffi").Callable;
42
51
  muxerCreate: import("koffi").Callable;
52
+ muxerCreateForFormat: import("koffi").Callable;
43
53
  muxerCreateWithBatch: import("koffi").Callable;
44
54
  muxerAddVideoTrack: import("koffi").Callable;
45
55
  muxerAddAudioTrack: import("koffi").Callable;
@@ -49,6 +59,7 @@ export declare const container: {
49
59
  muxerPollBytes: import("koffi").Callable;
50
60
  muxerClose: import("koffi").Callable;
51
61
  demuxerCreate: import("koffi").Callable;
62
+ demuxerCreateForFormat: import("koffi").Callable;
52
63
  demuxerPushBytes: import("koffi").Callable;
53
64
  demuxerStreamCount: import("koffi").Callable;
54
65
  demuxerStreamAt: import("koffi").Callable;
@@ -59,6 +70,67 @@ export declare const container: {
59
70
  bufferFree: import("koffi").Callable;
60
71
  packetFree: import("koffi").Callable;
61
72
  streamInfoFree: import("koffi").Callable;
73
+ oggMuxerCreate: import("koffi").Callable;
74
+ oggMuxerPushPacket: import("koffi").Callable;
75
+ oggMuxerFlush: import("koffi").Callable;
76
+ oggMuxerPollBytes: import("koffi").Callable;
77
+ oggMuxerClose: import("koffi").Callable;
78
+ oggDemuxerCreate: import("koffi").Callable;
79
+ oggDemuxerPushBytes: import("koffi").Callable;
80
+ oggDemuxerStreamCount: import("koffi").Callable;
81
+ oggDemuxerStreamAt: import("koffi").Callable;
82
+ oggDemuxerPollPacket: import("koffi").Callable;
83
+ oggDemuxerClose: import("koffi").Callable;
84
+ adtsMuxerCreate: import("koffi").Callable;
85
+ adtsMuxerPushPacket: import("koffi").Callable;
86
+ adtsMuxerFlush: import("koffi").Callable;
87
+ adtsMuxerPollBytes: import("koffi").Callable;
88
+ adtsMuxerClose: import("koffi").Callable;
89
+ adtsDemuxerCreate: import("koffi").Callable;
90
+ adtsDemuxerPushBytes: import("koffi").Callable;
91
+ adtsDemuxerStreamCount: import("koffi").Callable;
92
+ adtsDemuxerStreamAt: import("koffi").Callable;
93
+ adtsDemuxerPollPacket: import("koffi").Callable;
94
+ adtsDemuxerClose: import("koffi").Callable;
95
+ flvMuxerCreate: import("koffi").Callable;
96
+ flvMuxerWriteHeader: import("koffi").Callable;
97
+ flvMuxerAddVideoTrack: import("koffi").Callable;
98
+ flvMuxerAddAudioTrack: import("koffi").Callable;
99
+ flvMuxerPushPacket: import("koffi").Callable;
100
+ flvMuxerClose: import("koffi").Callable;
101
+ flvDemuxerCreate: import("koffi").Callable;
102
+ flvDemuxerPushBytes: import("koffi").Callable;
103
+ flvDemuxerStreamCount: import("koffi").Callable;
104
+ flvDemuxerStreamAt: import("koffi").Callable;
105
+ flvDemuxerPollPacket: import("koffi").Callable;
106
+ flvDemuxerClose: import("koffi").Callable;
107
+ tsMuxerCreate: import("koffi").Callable;
108
+ tsMuxerWritePatPmt: import("koffi").Callable;
109
+ tsMuxerWriteAccessUnit: import("koffi").Callable;
110
+ tsMuxerClose: import("koffi").Callable;
111
+ tsDemuxerCreate: import("koffi").Callable;
112
+ tsDemuxerPushBytes: import("koffi").Callable;
113
+ tsDemuxerStreamCount: import("koffi").Callable;
114
+ tsDemuxerStreamAt: import("koffi").Callable;
115
+ tsDemuxerPollPacket: import("koffi").Callable;
116
+ tsDemuxerFinish: import("koffi").Callable;
117
+ tsDemuxerFinishFree: import("koffi").Callable;
118
+ tsDemuxerClose: import("koffi").Callable;
119
+ mp3MuxerCreate: import("koffi").Callable;
120
+ mp3MuxerWriteFrame: import("koffi").Callable;
121
+ mp3MuxerClose: import("koffi").Callable;
122
+ mp3DemuxerCreate: import("koffi").Callable;
123
+ mp3DemuxerPushBytes: import("koffi").Callable;
124
+ mp3DemuxerStreamCount: import("koffi").Callable;
125
+ mp3DemuxerStreamAt: import("koffi").Callable;
126
+ mp3DemuxerPollPacket: import("koffi").Callable;
127
+ mp3DemuxerClose: import("koffi").Callable;
128
+ wavMuxerCreate: import("koffi").Callable;
129
+ wavMuxerCreateWithFormat: import("koffi").Callable;
130
+ wavMuxerPushPacket: import("koffi").Callable;
131
+ wavMuxerFinish: import("koffi").Callable;
132
+ wavMuxerClose: import("koffi").Callable;
133
+ wavParse: import("koffi").Callable;
62
134
  };
63
135
  export declare const pipeline: {
64
136
  abiVersion: import("koffi").Callable;
@@ -80,6 +152,20 @@ export declare const pipeline: {
80
152
  audioSessionClose: import("koffi").Callable;
81
153
  pipelinePacketFree: import("koffi").Callable;
82
154
  pipelineStreamInfoFree: import("koffi").Callable;
155
+ decodeConfigNew: import("koffi").Callable;
156
+ decodeSessionOpen: import("koffi").Callable;
157
+ decodeSessionPushPacket: import("koffi").Callable;
158
+ decodeSessionPollFrame: import("koffi").Callable;
159
+ decodeSessionFlush: import("koffi").Callable;
160
+ decodeSessionClose: import("koffi").Callable;
161
+ decodedVideoFrameFree: import("koffi").Callable;
162
+ audioDecodeConfigOpus: import("koffi").Callable;
163
+ audioDecodeSessionOpen: import("koffi").Callable;
164
+ audioDecodeSessionPushPacket: import("koffi").Callable;
165
+ audioDecodeSessionPollFrame: import("koffi").Callable;
166
+ audioDecodeSessionFlush: import("koffi").Callable;
167
+ audioDecodeSessionClose: import("koffi").Callable;
168
+ decodedAudioFrameFree: import("koffi").Callable;
83
169
  };
84
170
  export declare const device: {
85
171
  abiVersion: import("koffi").Callable;
@@ -107,6 +193,13 @@ export declare const device: {
107
193
  };
108
194
  /** Copy `len` bytes out of a koffi pointer/opaque handle. */
109
195
  export declare function copyBytes(ptr: unknown, len: number): Buffer;
196
+ /**
197
+ * Decode `count` consecutive struct instances out of a pointer to an owned
198
+ * native array (e.g. `mediaway_ts_demuxer_finish`'s `out_packets`) — the only
199
+ * multi-element owned-array output shape in this crate. Free the underlying
200
+ * array with the matching `_finish_free` after copying out what's needed.
201
+ */
202
+ export declare function decodeArray<T>(ptr: unknown, type: TypeObject, count: number): T[];
110
203
  /** `mediaway_rational_t` (u64 num / u32 den). */
111
204
  export interface RawRational {
112
205
  num: bigint | number;
@@ -159,12 +252,32 @@ export interface RawStreamInfo {
159
252
  export interface RawPacket {
160
253
  stream_id: number;
161
254
  pts: bigint | number;
255
+ dts: bigint | number;
162
256
  duration: bigint | number;
163
257
  is_keyframe: boolean;
164
258
  is_discard: boolean;
165
259
  payload: unknown;
166
260
  payload_len: number;
167
261
  }
262
+ /** `mediaway_ts_elementary_stream_t` (MPEG-TS muxer construction input). */
263
+ export interface RawTsElementaryStream {
264
+ pid: number;
265
+ codec: number;
266
+ }
267
+ /** `mediaway_mp3_frame_header_t` (MP3 muxer construction input). */
268
+ export interface RawMp3FrameHeader {
269
+ version: number;
270
+ bitrate_kbps: number;
271
+ sample_rate: number;
272
+ channel_mode: number;
273
+ }
274
+ /** `mediaway_wave_format_t` (WAV muxer construction input). */
275
+ export interface RawWaveFormat {
276
+ sample_format: number;
277
+ channels: number;
278
+ sample_rate: number;
279
+ bits_per_sample: number;
280
+ }
168
281
  /** ABI output structs — fields are filled by the ABI call; callers construct
169
282
  * them empty (`{} as RawX`) and read the fields after the call. */
170
283
  /** `mediaway_camera_frame_t` / `mediaway_audio_frame_t` (device outputs). */
@@ -242,3 +355,51 @@ export interface RawAudioPacket {
242
355
  payload: unknown;
243
356
  payload_len: number;
244
357
  }
358
+ /** `mediaway_decode_packet_view_t` (decode session input; shared by video + audio). */
359
+ export interface RawDecodePacketView {
360
+ stream_id: number;
361
+ pts: bigint | number;
362
+ dts: bigint | number;
363
+ duration: bigint | number;
364
+ is_keyframe: boolean;
365
+ is_discard: boolean;
366
+ payload: unknown;
367
+ payload_len: number;
368
+ }
369
+ /** `mediaway_auto_video_decode_config_t`. */
370
+ export interface RawAutoVideoDecodeConfig {
371
+ codec: number;
372
+ width: number;
373
+ height: number;
374
+ time_base: RawRational;
375
+ pixel_format: number;
376
+ extra_data: unknown;
377
+ extra_data_len: number;
378
+ }
379
+ /** `mediaway_decoded_video_frame_t` (decode session output). */
380
+ export interface RawDecodedVideoFrame {
381
+ pts: bigint | number;
382
+ duration: bigint | number;
383
+ width: number;
384
+ height: number;
385
+ pixel_format: number;
386
+ data: unknown;
387
+ data_len: number;
388
+ }
389
+ /** `mediaway_audio_decode_config_t` (Opus only today). */
390
+ export interface RawAudioDecodeConfig {
391
+ codec: number;
392
+ sample_rate: number;
393
+ channels: number;
394
+ time_base: RawRational;
395
+ }
396
+ /** `mediaway_decoded_audio_frame_t` (audio decode session output; always F32). */
397
+ export interface RawDecodedAudioFrame {
398
+ pts: bigint | number;
399
+ duration: bigint | number;
400
+ sample_rate: number;
401
+ channels: number;
402
+ sample_format: number;
403
+ data: unknown;
404
+ data_len: number;
405
+ }
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",
@@ -214,10 +247,57 @@ export const MwAudioStreamInfo = koffi.struct("MwAudioStreamInfo", {
214
247
  extra_data: "uint8_t *",
215
248
  extra_data_len: "size_t",
216
249
  });
250
+ // ── Decode (adr/0004-auto-decode-c-abi.md, adr/pipeline/0006) ──────────────────
251
+ // MwDecodePacketView is shared by both video and audio decode push_packet
252
+ // calls — a new, pipeline-scoped type, not MwPacketView above.
253
+ export const MwDecodePacketView = koffi.struct("MwDecodePacketView", {
254
+ stream_id: "uint32", // unused by decode; kept for call-site symmetry
255
+ pts: "int64",
256
+ dts: "int64",
257
+ duration: "uint64",
258
+ is_keyframe: "bool",
259
+ is_discard: "bool",
260
+ payload: "uint8_t *",
261
+ payload_len: "size_t",
262
+ });
263
+ export const MwAutoVideoDecodeConfig = koffi.struct("MwAutoVideoDecodeConfig", {
264
+ codec: "int32",
265
+ width: "uint32",
266
+ height: "uint32",
267
+ time_base: MwRational,
268
+ pixel_format: "int32",
269
+ extra_data: "uint8_t *", // borrowed, open-call only
270
+ extra_data_len: "size_t",
271
+ });
272
+ export const MwDecodedVideoFrame = koffi.struct("MwDecodedVideoFrame", {
273
+ pts: "int64",
274
+ duration: "uint64",
275
+ width: "uint32",
276
+ height: "uint32",
277
+ pixel_format: "int32",
278
+ data: "uint8_t *", // owned
279
+ data_len: "size_t",
280
+ });
281
+ export const MwAudioDecodeConfig = koffi.struct("MwAudioDecodeConfig", {
282
+ codec: "int32", // Opus only today
283
+ sample_rate: "uint32",
284
+ channels: "uint16",
285
+ time_base: MwRational,
286
+ });
287
+ export const MwDecodedAudioFrame = koffi.struct("MwDecodedAudioFrame", {
288
+ pts: "int64",
289
+ duration: "uint64",
290
+ sample_rate: "uint32",
291
+ channels: "uint16",
292
+ sample_format: "int32", // always F32 for Opus
293
+ data: "uint8_t *", // owned interleaved PCM
294
+ data_len: "size_t",
295
+ });
217
296
  // ── Container functions ────────────────────────────────────────────────────────
218
297
  export const container = {
219
298
  abiVersion: containerLib.func("uint32_t mediaway_container_ffi_abi_version()"),
220
299
  muxerCreate: containerLib.func("void *mediaway_muxer_create()"),
300
+ muxerCreateForFormat: containerLib.func("void *mediaway_muxer_create_for_format(int format)"),
221
301
  muxerCreateWithBatch: containerLib.func("void *mediaway_muxer_create_with_fragment_batch(size_t batch)"),
222
302
  muxerAddVideoTrack: containerLib.func("int mediaway_muxer_add_video_track(void *muxer, MwVideoTrackInfo *info)"),
223
303
  muxerAddAudioTrack: containerLib.func("int mediaway_muxer_add_audio_track(void *muxer, MwAudioTrackInfo *info)"),
@@ -227,6 +307,7 @@ export const container = {
227
307
  muxerPollBytes: containerLib.func("int mediaway_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
228
308
  muxerClose: containerLib.func("void mediaway_muxer_close(void *muxer)"),
229
309
  demuxerCreate: containerLib.func("void *mediaway_demuxer_create()"),
310
+ demuxerCreateForFormat: containerLib.func("void *mediaway_demuxer_create_for_format(int format)"),
230
311
  demuxerPushBytes: containerLib.func("int mediaway_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
231
312
  demuxerStreamCount: containerLib.func("size_t mediaway_demuxer_stream_count(void *demuxer)"),
232
313
  demuxerStreamAt: containerLib.func("int mediaway_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
@@ -237,6 +318,73 @@ export const container = {
237
318
  bufferFree: containerLib.func("void mediaway_buffer_free(uint8_t *data, size_t len)"),
238
319
  packetFree: containerLib.func("void mediaway_packet_free(MwPacket *packet)"),
239
320
  streamInfoFree: containerLib.func("void mediaway_stream_info_free(MwStreamInfo *info)"),
321
+ // ── Ogg (adr/container/0004) ──────────────────────────────────────────────
322
+ oggMuxerCreate: containerLib.func("void *mediaway_ogg_muxer_create(uint32_t serial)"),
323
+ oggMuxerPushPacket: containerLib.func("int mediaway_ogg_muxer_push_packet(void *muxer, MwPacketView *packet)"),
324
+ oggMuxerFlush: containerLib.func("int mediaway_ogg_muxer_flush(void *muxer)"),
325
+ oggMuxerPollBytes: containerLib.func("int mediaway_ogg_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
326
+ oggMuxerClose: containerLib.func("void mediaway_ogg_muxer_close(void *muxer)"),
327
+ oggDemuxerCreate: containerLib.func("void *mediaway_ogg_demuxer_create()"),
328
+ oggDemuxerPushBytes: containerLib.func("int mediaway_ogg_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
329
+ oggDemuxerStreamCount: containerLib.func("size_t mediaway_ogg_demuxer_stream_count(void *demuxer)"),
330
+ oggDemuxerStreamAt: containerLib.func("int mediaway_ogg_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
331
+ oggDemuxerPollPacket: containerLib.func("int mediaway_ogg_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
332
+ oggDemuxerClose: containerLib.func("void mediaway_ogg_demuxer_close(void *demuxer)"),
333
+ // ── ADTS (adr/container/0004) ─────────────────────────────────────────────
334
+ adtsMuxerCreate: containerLib.func("void *mediaway_adts_muxer_create(uint32_t sample_rate, uint8_t channels)"),
335
+ adtsMuxerPushPacket: containerLib.func("int mediaway_adts_muxer_push_packet(void *muxer, MwPacketView *packet)"),
336
+ adtsMuxerFlush: containerLib.func("int mediaway_adts_muxer_flush(void *muxer)"),
337
+ adtsMuxerPollBytes: containerLib.func("int mediaway_adts_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
338
+ adtsMuxerClose: containerLib.func("void mediaway_adts_muxer_close(void *muxer)"),
339
+ adtsDemuxerCreate: containerLib.func("void *mediaway_adts_demuxer_create()"),
340
+ adtsDemuxerPushBytes: containerLib.func("int mediaway_adts_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
341
+ adtsDemuxerStreamCount: containerLib.func("size_t mediaway_adts_demuxer_stream_count(void *demuxer)"),
342
+ adtsDemuxerStreamAt: containerLib.func("int mediaway_adts_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
343
+ adtsDemuxerPollPacket: containerLib.func("int mediaway_adts_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
344
+ adtsDemuxerClose: containerLib.func("void mediaway_adts_demuxer_close(void *demuxer)"),
345
+ // ── FLV (adr/container/0005) ──────────────────────────────────────────────
346
+ flvMuxerCreate: containerLib.func("void *mediaway_flv_muxer_create()"),
347
+ 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)"),
348
+ flvMuxerAddVideoTrack: containerLib.func("int mediaway_flv_muxer_add_video_track(void *muxer, MwVideoTrackInfo *info)"),
349
+ flvMuxerAddAudioTrack: containerLib.func("int mediaway_flv_muxer_add_audio_track(void *muxer, MwAudioTrackInfo *info)"),
350
+ flvMuxerPushPacket: containerLib.func("int mediaway_flv_muxer_push_packet(void *muxer, MwPacketView *packet, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
351
+ flvMuxerClose: containerLib.func("void mediaway_flv_muxer_close(void *muxer)"),
352
+ flvDemuxerCreate: containerLib.func("void *mediaway_flv_demuxer_create()"),
353
+ flvDemuxerPushBytes: containerLib.func("int mediaway_flv_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
354
+ flvDemuxerStreamCount: containerLib.func("size_t mediaway_flv_demuxer_stream_count(void *demuxer)"),
355
+ flvDemuxerStreamAt: containerLib.func("int mediaway_flv_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
356
+ flvDemuxerPollPacket: containerLib.func("int mediaway_flv_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
357
+ flvDemuxerClose: containerLib.func("void mediaway_flv_demuxer_close(void *demuxer)"),
358
+ // ── MPEG-TS (adr/container/0006) ──────────────────────────────────────────
359
+ tsMuxerCreate: containerLib.func("void *mediaway_ts_muxer_create(uint16_t program_number, uint16_t pmt_pid, MwTsElementaryStream *streams, size_t stream_count)"),
360
+ tsMuxerWritePatPmt: containerLib.func("int mediaway_ts_muxer_write_pat_pmt(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
361
+ 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)"),
362
+ tsMuxerClose: containerLib.func("void mediaway_ts_muxer_close(void *muxer)"),
363
+ tsDemuxerCreate: containerLib.func("void *mediaway_ts_demuxer_create()"),
364
+ tsDemuxerPushBytes: containerLib.func("int mediaway_ts_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
365
+ tsDemuxerStreamCount: containerLib.func("size_t mediaway_ts_demuxer_stream_count(void *demuxer)"),
366
+ tsDemuxerStreamAt: containerLib.func("int mediaway_ts_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
367
+ tsDemuxerPollPacket: containerLib.func("int mediaway_ts_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
368
+ tsDemuxerFinish: containerLib.func("int mediaway_ts_demuxer_finish(void *demuxer, _Out_ MwPacket **out_packets, _Out_ size_t *out_count)"),
369
+ tsDemuxerFinishFree: containerLib.func("void mediaway_ts_demuxer_finish_free(MwPacket *packets, size_t count)"),
370
+ tsDemuxerClose: containerLib.func("void mediaway_ts_demuxer_close(void *demuxer)"),
371
+ // ── MP3 (adr/container/0007) ──────────────────────────────────────────────
372
+ mp3MuxerCreate: containerLib.func("void *mediaway_mp3_muxer_create(MwMp3FrameHeader *header)"),
373
+ 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)"),
374
+ mp3MuxerClose: containerLib.func("void mediaway_mp3_muxer_close(void *muxer)"),
375
+ mp3DemuxerCreate: containerLib.func("void *mediaway_mp3_demuxer_create()"),
376
+ mp3DemuxerPushBytes: containerLib.func("int mediaway_mp3_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
377
+ mp3DemuxerStreamCount: containerLib.func("size_t mediaway_mp3_demuxer_stream_count(void *demuxer)"),
378
+ mp3DemuxerStreamAt: containerLib.func("int mediaway_mp3_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
379
+ mp3DemuxerPollPacket: containerLib.func("int mediaway_mp3_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
380
+ mp3DemuxerClose: containerLib.func("void mediaway_mp3_demuxer_close(void *demuxer)"),
381
+ // ── WAV (adr/container/0008) ──────────────────────────────────────────────
382
+ wavMuxerCreate: containerLib.func("void *mediaway_wav_muxer_create(uint32_t sample_rate, uint16_t channels, uint16_t bits_per_sample)"),
383
+ wavMuxerCreateWithFormat: containerLib.func("void *mediaway_wav_muxer_create_with_format(MwWaveFormat *format)"),
384
+ wavMuxerPushPacket: containerLib.func("int mediaway_wav_muxer_push_packet(void *muxer, MwPacketView *packet)"),
385
+ wavMuxerFinish: containerLib.func("int mediaway_wav_muxer_finish(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
386
+ wavMuxerClose: containerLib.func("void mediaway_wav_muxer_close(void *muxer)"),
387
+ wavParse: containerLib.func("int mediaway_wav_parse(uint8_t *data, size_t data_len, _Out_ MwStreamInfo *out_info, _Out_ MwPacket *out_packet)"),
240
388
  };
241
389
  // ── Pipeline functions ─────────────────────────────────────────────────────────
242
390
  export const pipeline = {
@@ -259,6 +407,21 @@ export const pipeline = {
259
407
  audioSessionClose: pipelineLib.func("void mediaway_audio_encode_session_close(void *session)"),
260
408
  pipelinePacketFree: pipelineLib.func("void mediaway_pipeline_ffi_packet_free(MwAudioPacket *packet)"),
261
409
  pipelineStreamInfoFree: pipelineLib.func("void mediaway_pipeline_ffi_stream_info_free(MwAudioStreamInfo *info)"),
410
+ // ── Decode (adr/0004-auto-decode-c-abi.md, adr/pipeline/0006) ────────────
411
+ 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)"),
412
+ decodeSessionOpen: pipelineLib.func("int mediaway_decode_session_open(MwAutoVideoDecodeConfig *config, _Out_ void **out_session)"),
413
+ decodeSessionPushPacket: pipelineLib.func("int mediaway_decode_session_push_packet(void *session, MwDecodePacketView *packet)"),
414
+ decodeSessionPollFrame: pipelineLib.func("int mediaway_decode_session_poll_frame(void *session, _Out_ MwDecodedVideoFrame *out_frame, _Out_ bool *out_has)"),
415
+ decodeSessionFlush: pipelineLib.func("int mediaway_decode_session_flush(void *session)"),
416
+ decodeSessionClose: pipelineLib.func("void mediaway_decode_session_close(void *session)"),
417
+ decodedVideoFrameFree: pipelineLib.func("void mediaway_decoded_video_frame_free(MwDecodedVideoFrame *frame)"),
418
+ audioDecodeConfigOpus: pipelineLib.func("MwAudioDecodeConfig mediaway_audio_decode_config_opus(uint32_t sample_rate, uint16_t channels, MwRational time_base)"),
419
+ audioDecodeSessionOpen: pipelineLib.func("int mediaway_audio_decode_session_open(MwAudioDecodeConfig *config, _Out_ void **out_session)"),
420
+ audioDecodeSessionPushPacket: pipelineLib.func("int mediaway_audio_decode_session_push_packet(void *session, MwDecodePacketView *packet)"),
421
+ audioDecodeSessionPollFrame: pipelineLib.func("int mediaway_audio_decode_session_poll_frame(void *session, _Out_ MwDecodedAudioFrame *out_frame, _Out_ bool *out_has)"),
422
+ audioDecodeSessionFlush: pipelineLib.func("int mediaway_audio_decode_session_flush(void *session)"),
423
+ audioDecodeSessionClose: pipelineLib.func("void mediaway_audio_decode_session_close(void *session)"),
424
+ decodedAudioFrameFree: pipelineLib.func("void mediaway_decoded_audio_frame_free(MwDecodedAudioFrame *frame)"),
262
425
  };
263
426
  // ── Device functions ───────────────────────────────────────────────────────────
264
427
  export const device = {
@@ -292,3 +455,14 @@ export function copyBytes(ptr, len) {
292
455
  return Buffer.alloc(0);
293
456
  return Buffer.from(koffi.decode(ptr, "uint8_t", len));
294
457
  }
458
+ /**
459
+ * Decode `count` consecutive struct instances out of a pointer to an owned
460
+ * native array (e.g. `mediaway_ts_demuxer_finish`'s `out_packets`) — the only
461
+ * multi-element owned-array output shape in this crate. Free the underlying
462
+ * array with the matching `_finish_free` after copying out what's needed.
463
+ */
464
+ export function decodeArray(ptr, type, count) {
465
+ if (!ptr || count <= 0)
466
+ return [];
467
+ return koffi.decode(ptr, type, count);
468
+ }
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mediaway/ffi",
3
- "version": "0.1.3",
4
- "description": "Mediaway native C ABI bindings for Node.js — the shared DLL behind the @mediaway packages",
3
+ "version": "0.1.5",
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",