node-av 1.3.0 → 2.1.0

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.
Files changed (127) hide show
  1. package/README.md +47 -40
  2. package/binding.gyp +12 -0
  3. package/dist/api/bitstream-filter.d.ts +134 -2
  4. package/dist/api/bitstream-filter.js +200 -2
  5. package/dist/api/bitstream-filter.js.map +1 -1
  6. package/dist/api/decoder.d.ts +261 -105
  7. package/dist/api/decoder.js +384 -171
  8. package/dist/api/decoder.js.map +1 -1
  9. package/dist/api/encoder.d.ts +338 -74
  10. package/dist/api/encoder.js +546 -188
  11. package/dist/api/encoder.js.map +1 -1
  12. package/dist/api/filter-presets.d.ts +479 -1513
  13. package/dist/api/filter-presets.js +1044 -2005
  14. package/dist/api/filter-presets.js.map +1 -1
  15. package/dist/api/filter.d.ts +370 -150
  16. package/dist/api/filter.js +647 -364
  17. package/dist/api/filter.js.map +1 -1
  18. package/dist/api/hardware.d.ts +25 -31
  19. package/dist/api/hardware.js +36 -70
  20. package/dist/api/hardware.js.map +1 -1
  21. package/dist/api/index.d.ts +1 -1
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/index.js.map +1 -1
  24. package/dist/api/io-stream.d.ts +6 -0
  25. package/dist/api/io-stream.js +2 -0
  26. package/dist/api/io-stream.js.map +1 -1
  27. package/dist/api/media-input.d.ts +208 -2
  28. package/dist/api/media-input.js +356 -8
  29. package/dist/api/media-input.js.map +1 -1
  30. package/dist/api/media-output.d.ts +142 -104
  31. package/dist/api/media-output.js +446 -179
  32. package/dist/api/media-output.js.map +1 -1
  33. package/dist/api/pipeline.d.ts +82 -17
  34. package/dist/api/pipeline.js +80 -42
  35. package/dist/api/pipeline.js.map +1 -1
  36. package/dist/api/types.d.ts +24 -57
  37. package/dist/api/utils.js +2 -0
  38. package/dist/api/utils.js.map +1 -1
  39. package/dist/lib/audio-fifo.d.ts +103 -0
  40. package/dist/lib/audio-fifo.js +109 -0
  41. package/dist/lib/audio-fifo.js.map +1 -1
  42. package/dist/lib/binding.d.ts +1 -0
  43. package/dist/lib/binding.js.map +1 -1
  44. package/dist/lib/bitstream-filter-context.d.ts +79 -0
  45. package/dist/lib/bitstream-filter-context.js +83 -0
  46. package/dist/lib/bitstream-filter-context.js.map +1 -1
  47. package/dist/lib/bitstream-filter.d.ts +2 -0
  48. package/dist/lib/bitstream-filter.js +2 -0
  49. package/dist/lib/bitstream-filter.js.map +1 -1
  50. package/dist/lib/codec-context.d.ts +168 -0
  51. package/dist/lib/codec-context.js +178 -0
  52. package/dist/lib/codec-context.js.map +1 -1
  53. package/dist/lib/codec-parameters.d.ts +3 -0
  54. package/dist/lib/codec-parameters.js +3 -0
  55. package/dist/lib/codec-parameters.js.map +1 -1
  56. package/dist/lib/codec-parser.d.ts +6 -0
  57. package/dist/lib/codec-parser.js +6 -0
  58. package/dist/lib/codec-parser.js.map +1 -1
  59. package/dist/lib/codec.d.ts +12 -0
  60. package/dist/lib/codec.js +12 -0
  61. package/dist/lib/codec.js.map +1 -1
  62. package/dist/lib/dictionary.d.ts +18 -2
  63. package/dist/lib/dictionary.js +18 -2
  64. package/dist/lib/dictionary.js.map +1 -1
  65. package/dist/lib/error.d.ts +8 -0
  66. package/dist/lib/error.js +9 -0
  67. package/dist/lib/error.js.map +1 -1
  68. package/dist/lib/filter-context.d.ts +119 -2
  69. package/dist/lib/filter-context.js +119 -0
  70. package/dist/lib/filter-context.js.map +1 -1
  71. package/dist/lib/filter-graph.d.ts +80 -0
  72. package/dist/lib/filter-graph.js +84 -0
  73. package/dist/lib/filter-graph.js.map +1 -1
  74. package/dist/lib/filter-inout.d.ts +1 -0
  75. package/dist/lib/filter-inout.js +1 -0
  76. package/dist/lib/filter-inout.js.map +1 -1
  77. package/dist/lib/filter.d.ts +2 -0
  78. package/dist/lib/filter.js +2 -0
  79. package/dist/lib/filter.js.map +1 -1
  80. package/dist/lib/format-context.d.ts +356 -20
  81. package/dist/lib/format-context.js +375 -23
  82. package/dist/lib/format-context.js.map +1 -1
  83. package/dist/lib/frame.d.ts +84 -1
  84. package/dist/lib/frame.js +96 -0
  85. package/dist/lib/frame.js.map +1 -1
  86. package/dist/lib/hardware-device-context.d.ts +8 -0
  87. package/dist/lib/hardware-device-context.js +8 -0
  88. package/dist/lib/hardware-device-context.js.map +1 -1
  89. package/dist/lib/hardware-frames-context.d.ts +55 -0
  90. package/dist/lib/hardware-frames-context.js +57 -0
  91. package/dist/lib/hardware-frames-context.js.map +1 -1
  92. package/dist/lib/input-format.d.ts +43 -3
  93. package/dist/lib/input-format.js +48 -0
  94. package/dist/lib/input-format.js.map +1 -1
  95. package/dist/lib/io-context.d.ts +212 -0
  96. package/dist/lib/io-context.js +228 -0
  97. package/dist/lib/io-context.js.map +1 -1
  98. package/dist/lib/log.d.ts +2 -0
  99. package/dist/lib/log.js +2 -0
  100. package/dist/lib/log.js.map +1 -1
  101. package/dist/lib/native-types.d.ts +39 -1
  102. package/dist/lib/option.d.ts +90 -0
  103. package/dist/lib/option.js +97 -0
  104. package/dist/lib/option.js.map +1 -1
  105. package/dist/lib/output-format.d.ts +4 -0
  106. package/dist/lib/output-format.js +4 -0
  107. package/dist/lib/output-format.js.map +1 -1
  108. package/dist/lib/packet.d.ts +7 -0
  109. package/dist/lib/packet.js +7 -0
  110. package/dist/lib/packet.js.map +1 -1
  111. package/dist/lib/rational.d.ts +1 -0
  112. package/dist/lib/rational.js +1 -0
  113. package/dist/lib/rational.js.map +1 -1
  114. package/dist/lib/software-resample-context.d.ts +64 -0
  115. package/dist/lib/software-resample-context.js +66 -0
  116. package/dist/lib/software-resample-context.js.map +1 -1
  117. package/dist/lib/software-scale-context.d.ts +98 -0
  118. package/dist/lib/software-scale-context.js +102 -0
  119. package/dist/lib/software-scale-context.js.map +1 -1
  120. package/dist/lib/stream.d.ts +1 -0
  121. package/dist/lib/stream.js +1 -0
  122. package/dist/lib/stream.js.map +1 -1
  123. package/dist/lib/utilities.d.ts +60 -0
  124. package/dist/lib/utilities.js +60 -0
  125. package/dist/lib/utilities.js.map +1 -1
  126. package/package.json +18 -18
  127. package/release_notes.md +0 -29
@@ -1,6 +1,6 @@
1
1
  import { Frame } from '../lib/index.js';
2
- import type { AVFilterCmdFlag, AVMediaType } from '../constants/constants.js';
3
- import type { FilterOptions, StreamInfo } from './types.js';
2
+ import type { AVFilterCmdFlag } from '../constants/constants.js';
3
+ import type { FilterOptions } from './types.js';
4
4
  /**
5
5
  * High-level filter API for audio and video processing.
6
6
  *
@@ -13,10 +13,12 @@ import type { FilterOptions, StreamInfo } from './types.js';
13
13
  * ```typescript
14
14
  * import { FilterAPI } from 'node-av/api';
15
15
  *
16
- * // Create video filter
17
- * const filter = await FilterAPI.create('scale=1280:720', videoInfo);
16
+ * // Create video filter - initializes on first frame
17
+ * const filter = await FilterAPI.create('scale=1280:720', {
18
+ * timeBase: video.timeBase,
19
+ * });
18
20
  *
19
- * // Process frame
21
+ * // Process frame - first frame configures filter graph
20
22
  * const output = await filter.process(inputFrame);
21
23
  * if (output) {
22
24
  * console.log(`Filtered frame: ${output.width}x${output.height}`);
@@ -26,48 +28,47 @@ import type { FilterOptions, StreamInfo } from './types.js';
26
28
  *
27
29
  * @example
28
30
  * ```typescript
29
- * // Hardware-accelerated filtering
30
- * const hw = HardwareContext.auto();
31
- * const filter = await FilterAPI.create(
32
- * 'hwupload,scale_cuda=1920:1080,hwdownload',
33
- * videoInfo,
34
- * { hardware: hw }
35
- * );
31
+ * // Hardware-accelerated filtering - hw context detected from frame
32
+ * const filter = await FilterAPI.create('hwupload,scale_cuda=1920:1080,hwdownload', {
33
+ * timeBase: video.timeBase,
34
+ * });
35
+ * // Hardware frames context will be automatically detected from first frame
36
36
  * ```
37
37
  *
38
38
  * @see {@link FilterGraph} For low-level filter graph API
39
- * @see {@link HardwareContext} For hardware acceleration
40
39
  * @see {@link Frame} For frame operations
41
40
  */
42
41
  export declare class FilterAPI implements Disposable {
43
42
  private graph;
43
+ private description;
44
+ private options;
44
45
  private buffersrcCtx;
45
46
  private buffersinkCtx;
46
- private config;
47
- private mediaType;
48
47
  private initialized;
49
- private hardware?;
50
- private description;
51
- private options;
48
+ private isClosed;
52
49
  /**
53
- * @param config - Stream configuration
50
+ * @param graph - Filter graph instance
51
+ *
54
52
  * @param description - Filter description string
53
+ *
55
54
  * @param options - Filter options
55
+ *
56
56
  * @internal
57
57
  */
58
58
  private constructor();
59
59
  /**
60
60
  * Create a filter with specified description and configuration.
61
61
  *
62
- * Constructs filter graph from description string.
63
- * Configures input/output buffers and threading.
64
- * For video filters, uses lazy initialization to detect hardware frames.
62
+ * Creates and allocates filter graph immediately.
63
+ * Filter configuration is completed on first frame with frame properties.
64
+ * Hardware frames context is automatically detected from input frames.
65
65
  *
66
66
  * Direct mapping to avfilter_graph_parse_ptr() and avfilter_graph_config().
67
67
  *
68
68
  * @param description - Filter graph description
69
- * @param input - Input stream configuration
70
- * @param options - Filter options
69
+ *
70
+ * @param options - Filter options including required timeBase
71
+ *
71
72
  * @returns Configured filter instance
72
73
  *
73
74
  * @throws {Error} If filter creation or configuration fails
@@ -77,44 +78,104 @@ export declare class FilterAPI implements Disposable {
77
78
  * @example
78
79
  * ```typescript
79
80
  * // Simple video filter
80
- * const filter = await FilterAPI.create('scale=640:480', videoInfo);
81
+ * const filter = await FilterAPI.create('scale=640:480', {
82
+ * timeBase: video.timeBase
83
+ * });
81
84
  * ```
82
85
  *
83
86
  * @example
84
87
  * ```typescript
85
88
  * // Complex filter chain
86
- * const filter = await FilterAPI.create(
87
- * 'crop=640:480:0:0,rotate=PI/4',
88
- * videoInfo
89
- * );
89
+ * const filter = await FilterAPI.create('crop=640:480:0:0,rotate=PI/4', {
90
+ * timeBase: video.timeBase
91
+ * });
90
92
  * ```
91
93
  *
92
94
  * @example
93
95
  * ```typescript
94
96
  * // Audio filter
95
- * const filter = await FilterAPI.create(
96
- * 'volume=0.5,aecho=0.8:0.9:1000:0.3',
97
- * audioInfo
98
- * );
97
+ * const filter = await FilterAPI.create('volume=0.5,aecho=0.8:0.9:1000:0.3', {
98
+ * timeBase: audio.timeBase
99
+ * });
99
100
  * ```
100
101
  *
101
102
  * @see {@link process} For frame processing
102
103
  * @see {@link FilterOptions} For configuration options
103
104
  */
104
- static create(description: string, input: StreamInfo, options?: FilterOptions): Promise<FilterAPI>;
105
+ static create(description: string, options: FilterOptions): Promise<FilterAPI>;
106
+ /**
107
+ * Check if filter is open.
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * if (filter.isFilterOpen) {
112
+ * const output = await filter.process(frame);
113
+ * }
114
+ * ```
115
+ */
116
+ get isFilterOpen(): boolean;
117
+ /**
118
+ * Check if filter has been initialized.
119
+ *
120
+ * Returns true after first frame has been processed and filter graph configured.
121
+ * Useful for checking if filter has received frame properties.
122
+ *
123
+ * @returns true if filter graph has been built from first frame
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * if (!filter.isFilterInitialized) {
128
+ * console.log('Filter will initialize on first frame');
129
+ * }
130
+ * ```
131
+ */
132
+ get isFilterInitialized(): boolean;
133
+ /**
134
+ * Check if filter is ready for processing.
135
+ *
136
+ * @returns true if initialized and ready
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * if (filter.isReady()) {
141
+ * const output = await filter.process(frame);
142
+ * }
143
+ * ```
144
+ */
145
+ isReady(): boolean;
146
+ /**
147
+ * Get filter graph description.
148
+ *
149
+ * Returns human-readable graph structure.
150
+ * Useful for debugging filter chains.
151
+ *
152
+ * Direct mapping to avfilter_graph_dump().
153
+ *
154
+ * @returns Graph description or null if closed
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const description = filter.getGraphDescription();
159
+ * console.log('Filter graph:', description);
160
+ * ```
161
+ */
162
+ getGraphDescription(): string | null;
105
163
  /**
106
164
  * Process a frame through the filter.
107
165
  *
108
166
  * Applies filter operations to input frame.
167
+ * On first frame, automatically builds filter graph with frame properties.
109
168
  * May buffer frames internally before producing output.
110
- * For video, performs lazy initialization on first frame.
169
+ * Hardware frames context is automatically detected from frame.
170
+ * Returns null if filter is closed and frame is null.
111
171
  *
112
172
  * Direct mapping to av_buffersrc_add_frame() and av_buffersink_get_frame().
113
173
  *
114
- * @param frame - Input frame to process
174
+ * @param frame - Input frame to process (or null to flush)
175
+ *
115
176
  * @returns Filtered frame or null if buffered
116
177
  *
117
- * @throws {Error} If filter not ready
178
+ * @throws {Error} If filter is closed with non-null frame
118
179
  *
119
180
  * @throws {FFmpegError} If processing fails
120
181
  *
@@ -129,21 +190,62 @@ export declare class FilterAPI implements Disposable {
129
190
  *
130
191
  * @example
131
192
  * ```typescript
132
- * // Process and drain
193
+ * // Process frame - may buffer internally
133
194
  * const output = await filter.process(frame);
134
- * if (output) yield output;
195
+ * if (output) {
196
+ * // Got output immediately
197
+ * yield output;
198
+ * }
199
+ * // For buffered frames, use the frames() async generator
200
+ * ```
201
+ *
202
+ * @see {@link frames} For processing frame streams
203
+ * @see {@link flush} For end-of-stream handling
204
+ */
205
+ process(frame: Frame | null): Promise<Frame | null>;
206
+ /**
207
+ * Process a frame through the filter synchronously.
208
+ * Synchronous version of process.
209
+ *
210
+ * Applies filter operations to input frame.
211
+ * On first frame, automatically builds filter graph with frame properties.
212
+ * May buffer frames internally before producing output.
213
+ * Hardware frames context is automatically detected from frame.
214
+ * Returns null if filter is closed and frame is null.
215
+ *
216
+ * Direct mapping to av_buffersrc_add_frame() and av_buffersink_get_frame().
217
+ *
218
+ * @param frame - Input frame to process (or null to flush)
219
+ *
220
+ * @returns Filtered frame or null if buffered
221
+ *
222
+ * @throws {Error} If filter is closed with non-null frame
223
+ *
224
+ * @throws {FFmpegError} If processing fails
135
225
  *
136
- * // Drain buffered frames
137
- * let buffered;
138
- * while ((buffered = await filter.receive()) !== null) {
139
- * yield buffered;
226
+ * @example
227
+ * ```typescript
228
+ * const output = filter.processSync(inputFrame);
229
+ * if (output) {
230
+ * console.log(`Got filtered frame: pts=${output.pts}`);
231
+ * output.free();
140
232
  * }
141
233
  * ```
142
234
  *
143
- * @see {@link receive} For draining buffered frames
144
- * @see {@link frames} For stream processing
235
+ * @example
236
+ * ```typescript
237
+ * // Process frame - may buffer internally
238
+ * const output = filter.processSync(frame);
239
+ * if (output) {
240
+ * // Got output immediately
241
+ * yield output;
242
+ * }
243
+ * // For buffered frames, use the framesSync() generator
244
+ * ```
245
+ *
246
+ * @see {@link process} For async version
145
247
  */
146
- process(frame: Frame): Promise<Frame | null>;
248
+ processSync(frame: Frame | null): Frame | null;
147
249
  /**
148
250
  * Process multiple frames at once.
149
251
  *
@@ -151,6 +253,7 @@ export declare class FilterAPI implements Disposable {
151
253
  * Useful for filters that buffer multiple frames.
152
254
  *
153
255
  * @param frames - Array of input frames
256
+ *
154
257
  * @returns Array of all output frames
155
258
  *
156
259
  * @throws {Error} If filter not ready
@@ -170,43 +273,129 @@ export declare class FilterAPI implements Disposable {
170
273
  */
171
274
  processMultiple(frames: Frame[]): Promise<Frame[]>;
172
275
  /**
173
- * Receive buffered frame from filter.
276
+ * Process multiple frames at once synchronously.
277
+ * Synchronous version of processMultiple.
174
278
  *
175
- * Drains frames buffered by the filter.
176
- * Call repeatedly until null to get all buffered frames.
279
+ * Processes batch of frames and drains all output.
280
+ * Useful for filters that buffer multiple frames.
177
281
  *
178
- * Direct mapping to av_buffersink_get_frame().
282
+ * @param frames - Array of input frames
179
283
  *
180
- * @returns Buffered frame or null if none available
284
+ * @returns Array of all output frames
181
285
  *
182
286
  * @throws {Error} If filter not ready
183
287
  *
184
- * @throws {FFmpegError} If receive fails
288
+ * @throws {FFmpegError} If processing fails
185
289
  *
186
290
  * @example
187
291
  * ```typescript
188
- * // Drain buffered frames
189
- * let frame;
190
- * while ((frame = await filter.receive()) !== null) {
191
- * console.log(`Buffered frame: pts=${frame.pts}`);
292
+ * const outputs = filter.processMultipleSync([frame1, frame2, frame3]);
293
+ * for (const output of outputs) {
294
+ * console.log(`Output frame: pts=${output.pts}`);
295
+ * output.free();
296
+ * }
297
+ * ```
298
+ *
299
+ * @see {@link processMultiple} For async version
300
+ */
301
+ processMultipleSync(frames: Frame[]): Frame[];
302
+ /**
303
+ * Process frame stream through filter.
304
+ *
305
+ * High-level async generator for filtering frame streams.
306
+ * Automatically handles buffering and flushing.
307
+ * Frees input frames after processing.
308
+ *
309
+ * @param frames - Async generator of input frames
310
+ *
311
+ * @yields {Frame} Filtered frames
312
+ *
313
+ * @throws {Error} If filter not ready
314
+ *
315
+ * @throws {FFmpegError} If processing fails
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * // Filter decoded frames
320
+ * for await (const frame of filter.frames(decoder.frames(packets))) {
321
+ * await encoder.encode(frame);
192
322
  * frame.free();
193
323
  * }
194
324
  * ```
195
325
  *
196
- * @see {@link process} For input processing
197
- * @see {@link flush} For end-of-stream
326
+ * @example
327
+ * ```typescript
328
+ * // Chain filters
329
+ * const filter1 = await FilterAPI.create('scale=640:480', {
330
+ * timeBase: video.timeBase
331
+ * });
332
+ * const filter2 = await FilterAPI.create('rotate=PI/4', {
333
+ * timeBase: video.timeBase
334
+ * });
335
+ *
336
+ * for await (const frame of filter2.frames(filter1.frames(input))) {
337
+ * // Process filtered frames
338
+ * frame.free();
339
+ * }
340
+ * ```
341
+ *
342
+ * @see {@link process} For single frame processing
343
+ * @see {@link flush} For end-of-stream handling
198
344
  */
199
- receive(): Promise<Frame | null>;
345
+ frames(frames: AsyncGenerator<Frame>): AsyncGenerator<Frame>;
346
+ /**
347
+ * Process frame stream through filter synchronously.
348
+ * Synchronous version of frames.
349
+ *
350
+ * High-level sync generator for filtering frame streams.
351
+ * Automatically handles buffering and flushing.
352
+ * Frees input frames after processing.
353
+ *
354
+ * @param frames - Generator of input frames
355
+ *
356
+ * @yields {Frame} Filtered frames
357
+ *
358
+ * @throws {Error} If filter not ready
359
+ *
360
+ * @throws {FFmpegError} If processing fails
361
+ *
362
+ * @example
363
+ * ```typescript
364
+ * // Filter decoded frames
365
+ * for (const frame of filter.framesSync(decoder.framesSync(packets))) {
366
+ * encoder.encodeSync(frame);
367
+ * frame.free();
368
+ * }
369
+ * ```
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * // Chain filters
374
+ * const filter1 = await FilterAPI.create('scale=640:480', {
375
+ * timeBase: video.timeBase
376
+ * });
377
+ * const filter2 = await FilterAPI.create('rotate=PI/4', {
378
+ * timeBase: video.timeBase
379
+ * });
380
+ *
381
+ * for (const frame of filter2.framesSync(filter1.framesSync(input))) {
382
+ * // Process filtered frames
383
+ * frame.free();
384
+ * }
385
+ * ```
386
+ *
387
+ * @see {@link frames} For async version
388
+ */
389
+ framesSync(frames: Generator<Frame>): Generator<Frame>;
200
390
  /**
201
391
  * Flush filter and signal end-of-stream.
202
392
  *
203
393
  * Sends null frame to flush buffered data.
204
394
  * Must call receive() to get flushed frames.
395
+ * Does nothing if filter is closed or was never initialized.
205
396
  *
206
397
  * Direct mapping to av_buffersrc_add_frame(NULL).
207
398
  *
208
- * @throws {Error} If filter not ready
209
- *
210
399
  * @throws {FFmpegError} If flush fails
211
400
  *
212
401
  * @example
@@ -220,17 +409,42 @@ export declare class FilterAPI implements Disposable {
220
409
  * ```
221
410
  *
222
411
  * @see {@link flushFrames} For async iteration
223
- * @see {@link receive} For draining frames
412
+ * @see {@link frames} For complete pipeline
224
413
  */
225
414
  flush(): Promise<void>;
415
+ /**
416
+ * Flush filter and signal end-of-stream synchronously.
417
+ * Synchronous version of flush.
418
+ *
419
+ * Sends null frame to flush buffered data.
420
+ * Must call receiveSync() to get flushed frames.
421
+ * Does nothing if filter is closed or was never initialized.
422
+ *
423
+ * Direct mapping to av_buffersrc_add_frame(NULL).
424
+ *
425
+ * @throws {FFmpegError} If flush fails
426
+ *
427
+ * @example
428
+ * ```typescript
429
+ * filter.flushSync();
430
+ * // Get remaining frames
431
+ * let frame;
432
+ * while ((frame = filter.receiveSync()) !== null) {
433
+ * frame.free();
434
+ * }
435
+ * ```
436
+ *
437
+ * @see {@link flush} For async version
438
+ */
439
+ flushSync(): void;
226
440
  /**
227
441
  * Flush filter and yield remaining frames.
228
442
  *
229
443
  * Convenient async generator for flushing.
230
444
  * Combines flush and receive operations.
445
+ * Returns immediately if filter is closed or was never initialized.
231
446
  *
232
- * @yields Remaining frames from filter
233
- * @throws {Error} If filter not ready
447
+ * @yields {Frame} Remaining frames from filter
234
448
  *
235
449
  * @throws {FFmpegError} If flush fails
236
450
  *
@@ -247,43 +461,77 @@ export declare class FilterAPI implements Disposable {
247
461
  */
248
462
  flushFrames(): AsyncGenerator<Frame>;
249
463
  /**
250
- * Process frame stream through filter.
464
+ * Flush filter and yield remaining frames synchronously.
465
+ * Synchronous version of flushFrames.
251
466
  *
252
- * High-level async generator for filtering frame streams.
253
- * Automatically handles buffering and flushing.
254
- * Frees input frames after processing.
467
+ * Convenient sync generator for flushing.
468
+ * Combines flush and receive operations.
469
+ * Returns immediately if filter is closed or was never initialized.
255
470
  *
256
- * @param frames - Async generator of input frames
257
- * @yields Filtered frames
258
- * @throws {Error} If filter not ready
471
+ * @yields {Frame} Remaining frames from filter
259
472
  *
260
- * @throws {FFmpegError} If processing fails
473
+ * @throws {FFmpegError} If flush fails
261
474
  *
262
475
  * @example
263
476
  * ```typescript
264
- * // Filter decoded frames
265
- * for await (const frame of filter.frames(decoder.frames(packets))) {
266
- * await encoder.encode(frame);
477
+ * for (const frame of filter.flushFramesSync()) {
478
+ * console.log(`Flushed frame: pts=${frame.pts}`);
267
479
  * frame.free();
268
480
  * }
269
481
  * ```
270
482
  *
483
+ * @see {@link flushFrames} For async version
484
+ */
485
+ flushFramesSync(): Generator<Frame>;
486
+ /**
487
+ * Receive buffered frame from filter.
488
+ *
489
+ * Drains frames buffered by the filter.
490
+ * Call repeatedly until null to get all buffered frames.
491
+ * Returns null if filter is closed, not initialized, or no frames available.
492
+ *
493
+ * Direct mapping to av_buffersink_get_frame().
494
+ *
495
+ * @returns Buffered frame or null if none available
496
+ *
497
+ * @throws {FFmpegError} If receiving fails
498
+ *
271
499
  * @example
272
500
  * ```typescript
273
- * // Chain filters
274
- * const filter1 = await FilterAPI.create('scale=640:480', info);
275
- * const filter2 = await FilterAPI.create('rotate=PI/4', info);
501
+ * let frame;
502
+ * while ((frame = await filter.receive()) !== null) {
503
+ * console.log(`Received frame: pts=${frame.pts}`);
504
+ * frame.free();
505
+ * }
506
+ * ```
507
+ */
508
+ receive(): Promise<Frame | null>;
509
+ /**
510
+ * Receive buffered frame from filter synchronously.
511
+ * Synchronous version of receive.
276
512
  *
277
- * for await (const frame of filter2.frames(filter1.frames(input))) {
278
- * // Process filtered frames
513
+ * Drains frames buffered by the filter.
514
+ * Call repeatedly until null to get all buffered frames.
515
+ * Returns null if filter is closed, not initialized, or no frames available.
516
+ *
517
+ * Direct mapping to av_buffersink_get_frame().
518
+ *
519
+ * @returns Buffered frame or null if none available
520
+ *
521
+ * @throws {FFmpegError} If receiving fails
522
+ *
523
+ * @example
524
+ * ```typescript
525
+ * let frame;
526
+ * while ((frame = filter.receiveSync()) !== null) {
527
+ * console.log(`Received frame: pts=${frame.pts}`);
279
528
  * frame.free();
280
529
  * }
281
530
  * ```
282
531
  *
283
- * @see {@link process} For single frame processing
284
- * @see {@link flush} For end-of-stream handling
532
+ * @see {@link receive} For async version
285
533
  */
286
- frames(frames: AsyncGenerator<Frame>): AsyncGenerator<Frame>;
534
+ receiveSync(): Frame | null;
287
535
  /**
288
536
  * Send command to filter.
289
537
  *
@@ -293,9 +541,13 @@ export declare class FilterAPI implements Disposable {
293
541
  * Direct mapping to avfilter_graph_send_command().
294
542
  *
295
543
  * @param target - Target filter name
544
+ *
296
545
  * @param cmd - Command name
546
+ *
297
547
  * @param arg - Command argument
548
+ *
298
549
  * @param flags - Command flags
550
+ *
299
551
  * @returns Response string from filter
300
552
  *
301
553
  * @throws {Error} If filter not ready
@@ -321,10 +573,15 @@ export declare class FilterAPI implements Disposable {
321
573
  * Direct mapping to avfilter_graph_queue_command().
322
574
  *
323
575
  * @param target - Target filter name
576
+ *
324
577
  * @param cmd - Command name
578
+ *
325
579
  * @param arg - Command argument
580
+ *
326
581
  * @param ts - Timestamp for execution
582
+ *
327
583
  * @param flags - Command flags
584
+ *
328
585
  * @throws {Error} If filter not ready
329
586
  *
330
587
  * @throws {FFmpegError} If queue fails
@@ -338,49 +595,6 @@ export declare class FilterAPI implements Disposable {
338
595
  * @see {@link sendCommand} For immediate commands
339
596
  */
340
597
  queueCommand(target: string, cmd: string, arg: string, ts: number, flags?: AVFilterCmdFlag): void;
341
- /**
342
- * Get filter graph description.
343
- *
344
- * Returns human-readable graph structure.
345
- * Useful for debugging filter chains.
346
- *
347
- * Direct mapping to avfilter_graph_dump().
348
- *
349
- * @returns Graph description or null if not initialized
350
- *
351
- * @example
352
- * ```typescript
353
- * const description = filter.getGraphDescription();
354
- * console.log('Filter graph:', description);
355
- * ```
356
- */
357
- getGraphDescription(): string | null;
358
- /**
359
- * Check if filter is ready for processing.
360
- *
361
- * @returns true if initialized and ready
362
- *
363
- * @example
364
- * ```typescript
365
- * if (filter.isReady()) {
366
- * const output = await filter.process(frame);
367
- * }
368
- * ```
369
- */
370
- isReady(): boolean;
371
- /**
372
- * Get media type of filter.
373
- *
374
- * @returns AVMEDIA_TYPE_VIDEO or AVMEDIA_TYPE_AUDIO
375
- *
376
- * @example
377
- * ```typescript
378
- * if (filter.getMediaType() === AVMEDIA_TYPE_VIDEO) {
379
- * console.log('Video filter');
380
- * }
381
- * ```
382
- */
383
- getMediaType(): AVMediaType;
384
598
  /**
385
599
  * Free filter resources.
386
600
  *
@@ -389,19 +603,20 @@ export declare class FilterAPI implements Disposable {
389
603
  *
390
604
  * @example
391
605
  * ```typescript
392
- * filter.free();
606
+ * filter.close();
393
607
  * ```
394
608
  *
395
609
  * @see {@link Symbol.dispose} For automatic cleanup
396
610
  */
397
- free(): void;
611
+ close(): void;
398
612
  /**
399
- * Initialize filter graph.
613
+ * Initialize filter graph from first frame.
400
614
  *
401
615
  * Creates and configures filter graph components.
402
- * For video, may use hardware frames context from first frame.
616
+ * Sets buffer source parameters from frame properties.
617
+ * Automatically configures hardware frames context if present.
403
618
  *
404
- * @param firstFrame - First frame for hardware detection (video only)
619
+ * @param frame - First frame to process, provides format and hw context
405
620
  *
406
621
  * @throws {Error} If initialization fails
407
622
  *
@@ -411,28 +626,44 @@ export declare class FilterAPI implements Disposable {
411
626
  */
412
627
  private initialize;
413
628
  /**
414
- * Create buffer source with hardware frames context.
629
+ * Initialize filter graph from first frame synchronously.
630
+ * Synchronous version of initialize.
415
631
  *
416
- * @param frame - Frame with hw_frames_ctx
632
+ * Creates and configures filter graph components.
633
+ * Sets buffer source parameters from frame properties.
634
+ * Automatically configures hardware frames context if present.
417
635
  *
418
- * @throws {Error} If creation fails
636
+ * @param frame - First frame to process, provides format and hw context
637
+ *
638
+ * @throws {Error} If initialization fails
419
639
  *
420
640
  * @throws {FFmpegError} If configuration fails
421
641
  *
422
642
  * @internal
643
+ *
644
+ * @see {@link initialize} For async version
423
645
  */
424
- private createBufferSourceWithHwFrames;
646
+ private initializeSync;
425
647
  /**
426
- * Create standard buffer source.
648
+ * Create buffer source with frame parameters.
649
+ *
650
+ * Configures buffer source with frame properties including hardware context.
651
+ * Automatically detects video/audio and sets appropriate parameters.
652
+ *
653
+ * @param frame - Frame providing format, dimensions, and hw_frames_ctx
427
654
  *
428
655
  * @throws {Error} If creation fails
429
656
  *
657
+ * @throws {FFmpegError} If configuration fails
658
+ *
430
659
  * @internal
431
660
  */
432
661
  private createBufferSource;
433
662
  /**
434
663
  * Create buffer sink.
435
664
  *
665
+ * @param frame - Frame
666
+ *
436
667
  * @throws {Error} If creation fails
437
668
  *
438
669
  * @internal
@@ -450,32 +681,21 @@ export declare class FilterAPI implements Disposable {
450
681
  * @internal
451
682
  */
452
683
  private parseFilterDescription;
453
- /**
454
- * Check hardware requirements for filters.
455
- *
456
- * @param description - Filter description
457
- * @param options - Filter options
458
- *
459
- * @throws {Error} If hardware requirements not met
460
- *
461
- * @internal
462
- */
463
- private checkHardwareRequirements;
464
684
  /**
465
685
  * Dispose of filter.
466
686
  *
467
687
  * Implements Disposable interface for automatic cleanup.
468
- * Equivalent to calling free().
688
+ * Equivalent to calling close().
469
689
  *
470
690
  * @example
471
691
  * ```typescript
472
692
  * {
473
- * using filter = await FilterAPI.create('scale=640:480', info);
693
+ * using filter = await FilterAPI.create('scale=640:480', { ... });
474
694
  * // Use filter...
475
695
  * } // Automatically freed
476
696
  * ```
477
697
  *
478
- * @see {@link free} For manual cleanup
698
+ * @see {@link close} For manual cleanup
479
699
  */
480
700
  [Symbol.dispose](): void;
481
701
  }