node-av 1.1.0 → 1.2.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 (134) hide show
  1. package/README.md +51 -38
  2. package/dist/api/bitstream-filter.d.ts +180 -123
  3. package/dist/api/bitstream-filter.js +180 -125
  4. package/dist/api/bitstream-filter.js.map +1 -1
  5. package/dist/api/decoder.d.ts +279 -132
  6. package/dist/api/decoder.js +285 -142
  7. package/dist/api/decoder.js.map +1 -1
  8. package/dist/api/encoder.d.ts +246 -162
  9. package/dist/api/encoder.js +272 -208
  10. package/dist/api/encoder.js.map +1 -1
  11. package/dist/api/filter-presets.d.ts +690 -94
  12. package/dist/api/filter-presets.js +686 -102
  13. package/dist/api/filter-presets.js.map +1 -1
  14. package/dist/api/filter.d.ts +249 -213
  15. package/dist/api/filter.js +252 -242
  16. package/dist/api/filter.js.map +1 -1
  17. package/dist/api/hardware.d.ts +224 -117
  18. package/dist/api/hardware.js +380 -214
  19. package/dist/api/hardware.js.map +1 -1
  20. package/dist/api/index.d.ts +3 -3
  21. package/dist/api/index.js +1 -1
  22. package/dist/api/index.js.map +1 -1
  23. package/dist/api/io-stream.d.ts +65 -61
  24. package/dist/api/io-stream.js +43 -46
  25. package/dist/api/io-stream.js.map +1 -1
  26. package/dist/api/media-input.d.ts +242 -140
  27. package/dist/api/media-input.js +205 -103
  28. package/dist/api/media-input.js.map +1 -1
  29. package/dist/api/media-output.d.ts +206 -128
  30. package/dist/api/media-output.js +210 -128
  31. package/dist/api/media-output.js.map +1 -1
  32. package/dist/api/pipeline.d.ts +168 -38
  33. package/dist/api/pipeline.js +238 -14
  34. package/dist/api/pipeline.js.map +1 -1
  35. package/dist/api/types.d.ts +21 -187
  36. package/dist/api/utils.d.ts +1 -2
  37. package/dist/api/utils.js +9 -0
  38. package/dist/api/utils.js.map +1 -1
  39. package/dist/lib/audio-fifo.d.ts +127 -170
  40. package/dist/lib/audio-fifo.js +130 -173
  41. package/dist/lib/audio-fifo.js.map +1 -1
  42. package/dist/lib/binding.js +5 -0
  43. package/dist/lib/binding.js.map +1 -1
  44. package/dist/lib/bitstream-filter-context.d.ts +139 -184
  45. package/dist/lib/bitstream-filter-context.js +139 -188
  46. package/dist/lib/bitstream-filter-context.js.map +1 -1
  47. package/dist/lib/bitstream-filter.d.ts +68 -54
  48. package/dist/lib/bitstream-filter.js +68 -54
  49. package/dist/lib/bitstream-filter.js.map +1 -1
  50. package/dist/lib/codec-context.d.ts +316 -380
  51. package/dist/lib/codec-context.js +316 -381
  52. package/dist/lib/codec-context.js.map +1 -1
  53. package/dist/lib/codec-parameters.d.ts +160 -170
  54. package/dist/lib/codec-parameters.js +162 -172
  55. package/dist/lib/codec-parameters.js.map +1 -1
  56. package/dist/lib/codec-parser.d.ts +91 -104
  57. package/dist/lib/codec-parser.js +92 -103
  58. package/dist/lib/codec-parser.js.map +1 -1
  59. package/dist/lib/codec.d.ts +264 -281
  60. package/dist/lib/codec.js +268 -285
  61. package/dist/lib/codec.js.map +1 -1
  62. package/dist/lib/dictionary.d.ts +149 -203
  63. package/dist/lib/dictionary.js +158 -212
  64. package/dist/lib/dictionary.js.map +1 -1
  65. package/dist/lib/error.d.ts +96 -130
  66. package/dist/lib/error.js +98 -128
  67. package/dist/lib/error.js.map +1 -1
  68. package/dist/lib/filter-context.d.ts +284 -218
  69. package/dist/lib/filter-context.js +290 -227
  70. package/dist/lib/filter-context.js.map +1 -1
  71. package/dist/lib/filter-graph.d.ts +251 -292
  72. package/dist/lib/filter-graph.js +253 -294
  73. package/dist/lib/filter-graph.js.map +1 -1
  74. package/dist/lib/filter-inout.d.ts +87 -95
  75. package/dist/lib/filter-inout.js +87 -95
  76. package/dist/lib/filter-inout.js.map +1 -1
  77. package/dist/lib/filter.d.ts +93 -111
  78. package/dist/lib/filter.js +93 -111
  79. package/dist/lib/filter.js.map +1 -1
  80. package/dist/lib/format-context.d.ts +320 -428
  81. package/dist/lib/format-context.js +313 -385
  82. package/dist/lib/format-context.js.map +1 -1
  83. package/dist/lib/frame.d.ts +262 -405
  84. package/dist/lib/frame.js +263 -408
  85. package/dist/lib/frame.js.map +1 -1
  86. package/dist/lib/hardware-device-context.d.ts +149 -203
  87. package/dist/lib/hardware-device-context.js +149 -203
  88. package/dist/lib/hardware-device-context.js.map +1 -1
  89. package/dist/lib/hardware-frames-context.d.ts +170 -180
  90. package/dist/lib/hardware-frames-context.js +171 -181
  91. package/dist/lib/hardware-frames-context.js.map +1 -1
  92. package/dist/lib/index.d.ts +2 -1
  93. package/dist/lib/index.js +2 -2
  94. package/dist/lib/index.js.map +1 -1
  95. package/dist/lib/input-format.d.ts +89 -117
  96. package/dist/lib/input-format.js +89 -117
  97. package/dist/lib/input-format.js.map +1 -1
  98. package/dist/lib/io-context.d.ts +209 -241
  99. package/dist/lib/io-context.js +220 -252
  100. package/dist/lib/io-context.js.map +1 -1
  101. package/dist/lib/log.d.ts +85 -119
  102. package/dist/lib/log.js +85 -122
  103. package/dist/lib/log.js.map +1 -1
  104. package/dist/lib/native-types.d.ts +117 -106
  105. package/dist/lib/native-types.js +0 -7
  106. package/dist/lib/native-types.js.map +1 -1
  107. package/dist/lib/option.d.ts +284 -241
  108. package/dist/lib/option.js +309 -249
  109. package/dist/lib/option.js.map +1 -1
  110. package/dist/lib/output-format.d.ts +77 -101
  111. package/dist/lib/output-format.js +77 -101
  112. package/dist/lib/output-format.js.map +1 -1
  113. package/dist/lib/packet.d.ts +172 -240
  114. package/dist/lib/packet.js +172 -241
  115. package/dist/lib/packet.js.map +1 -1
  116. package/dist/lib/rational.d.ts +0 -2
  117. package/dist/lib/rational.js +0 -2
  118. package/dist/lib/rational.js.map +1 -1
  119. package/dist/lib/software-resample-context.d.ts +241 -325
  120. package/dist/lib/software-resample-context.js +242 -326
  121. package/dist/lib/software-resample-context.js.map +1 -1
  122. package/dist/lib/software-scale-context.d.ts +129 -173
  123. package/dist/lib/software-scale-context.js +131 -175
  124. package/dist/lib/software-scale-context.js.map +1 -1
  125. package/dist/lib/stream.d.ts +87 -197
  126. package/dist/lib/stream.js +87 -197
  127. package/dist/lib/stream.js.map +1 -1
  128. package/dist/lib/utilities.d.ts +372 -181
  129. package/dist/lib/utilities.js +373 -182
  130. package/dist/lib/utilities.js.map +1 -1
  131. package/install/check.js +0 -1
  132. package/package.json +21 -12
  133. package/release_notes.md +43 -59
  134. package/CHANGELOG.md +0 -8
@@ -1,25 +1,34 @@
1
- /**
2
- * FilterPresets - Pre-defined filter configurations
3
- *
4
- * Provides convenient filter string builders for common operations.
5
- * Includes both software and hardware-accelerated filter presets.
6
- *
7
- * Simplifies filter creation with type-safe parameter handling.
8
- * Supports platform-specific hardware acceleration capabilities.
9
- *
10
- * @module api/filter-presets
11
- */
12
1
  import { AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_D3D12VA, AV_HWDEVICE_TYPE_DRM, AV_HWDEVICE_TYPE_DXVA2, AV_HWDEVICE_TYPE_MEDIACODEC, AV_HWDEVICE_TYPE_OPENCL, AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_RKMPP, AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_VIDEOTOOLBOX, AV_HWDEVICE_TYPE_VULKAN, AVFILTER_FLAG_HWDEVICE, } from '../constants/constants.js';
13
2
  import { Filter } from '../lib/filter.js';
14
3
  import { avGetPixFmtName, avGetSampleFmtName } from '../lib/utilities.js';
15
4
  /**
16
5
  * Base class for filter preset implementations.
17
- * Provides common filter building methods that can be overridden.
6
+ * Provides common filter building methods that can be overridden by hardware-specific implementations.
7
+ *
8
+ * This class defines the standard filter operations available in FFmpeg,
9
+ * with each method returning a filter string that can be used in a filter graph.
10
+ * Hardware-specific implementations may override these methods to use optimized
11
+ * hardware filters instead of software implementations.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * class CustomPresets extends FilterPresetBase {
16
+ * override scale(width: number, height: number): string | null {
17
+ * return `custom_scale=${width}:${height}`;
18
+ * }
19
+ * }
20
+ * ```
18
21
  */
19
22
  export class FilterPresetBase {
20
23
  /**
21
- * Scale video to specified dimensions.
24
+ * Creates a scale filter string.
25
+ *
26
+ * @param width - Target width in pixels
27
+ * @param height - Target height in pixels
28
+ * @param options - Additional scaling options (e.g., flags for algorithm)
22
29
  * @returns Filter string or null if not supported
30
+ *
31
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#scale | FFmpeg scale filter}
23
32
  */
24
33
  scale(width, height, options) {
25
34
  const flags = options?.flags;
@@ -27,21 +36,47 @@ export class FilterPresetBase {
27
36
  return flags ? `${base}:flags=${flags}` : base;
28
37
  }
29
38
  /**
30
- * Crop video to specified dimensions.
39
+ * Creates a crop filter string.
40
+ *
41
+ * @param width - Width of the cropped area
42
+ * @param height - Height of the cropped area
43
+ * @param x - X coordinate of top-left corner (default: 0)
44
+ * @param y - Y coordinate of top-left corner (default: 0)
45
+ * @returns Filter string or null if not supported
46
+ *
47
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#crop | FFmpeg crop filter}
31
48
  */
32
49
  crop(width, height, x = 0, y = 0) {
33
50
  return `crop=${width}:${height}:${x}:${y}`;
34
51
  }
35
52
  /**
36
- * Change frame rate.
53
+ * Creates an FPS filter string to change frame rate.
54
+ *
55
+ * @param fps - Target frames per second
56
+ * @returns Filter string or null if not supported
57
+ *
58
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#fps | FFmpeg fps filter}
37
59
  */
38
60
  fps(fps) {
39
61
  return `fps=${fps}`;
40
62
  }
41
63
  /**
42
- * Convert pixel format.
43
- * Can accept a single format or an array of formats for fallback.
44
- * Multiple formats will create a chain: format=fmt1,format=fmt2,...
64
+ * Creates a format filter string to convert pixel format.
65
+ *
66
+ * @param pixelFormat - Target pixel format(s) - can be string, AVPixelFormat enum, or array
67
+ * @returns Filter string or null if not supported
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * // Single format
72
+ * presets.format('yuv420p');
73
+ * presets.format(AV_PIX_FMT_YUV420P);
74
+ *
75
+ * // Multiple formats (creates a chain)
76
+ * presets.format(['yuv420p', 'rgb24']);
77
+ * ```
78
+ *
79
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#format | FFmpeg format filter}
45
80
  */
46
81
  format(pixelFormat) {
47
82
  if (Array.isArray(pixelFormat)) {
@@ -56,31 +91,67 @@ export class FilterPresetBase {
56
91
  return `format=${formatName}`;
57
92
  }
58
93
  /**
59
- * Rotate video by angle.
94
+ * Creates a rotate filter string.
95
+ *
96
+ * @param angle - Rotation angle in degrees
97
+ * @returns Filter string or null if not supported
98
+ *
99
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#rotate | FFmpeg rotate filter}
60
100
  */
61
101
  rotate(angle) {
62
102
  return `rotate=${angle}*PI/180`;
63
103
  }
64
104
  /**
65
- * Flip video horizontally.
105
+ * Creates a horizontal flip filter string.
106
+ *
107
+ * @returns Filter string or null if not supported
108
+ *
109
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#hflip | FFmpeg hflip filter}
66
110
  */
67
111
  hflip() {
68
112
  return 'hflip';
69
113
  }
70
114
  /**
71
- * Flip video vertically.
115
+ * Creates a vertical flip filter string.
116
+ *
117
+ * @returns Filter string or null if not supported
118
+ *
119
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#vflip | FFmpeg vflip filter}
72
120
  */
73
121
  vflip() {
74
122
  return 'vflip';
75
123
  }
76
124
  /**
77
- * Apply fade effect.
125
+ * Creates a fade filter string for video.
126
+ *
127
+ * @param type - Fade type ('in' or 'out')
128
+ * @param start - Start time in seconds
129
+ * @param duration - Fade duration in seconds
130
+ * @returns Filter string or null if not supported
131
+ *
132
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#fade | FFmpeg fade filter}
78
133
  */
79
134
  fade(type, start, duration) {
80
135
  return `fade=t=${type}:st=${start}:d=${duration}`;
81
136
  }
82
137
  /**
83
- * Overlay one video on another.
138
+ * Creates an overlay filter string to composite two video streams.
139
+ *
140
+ * @param x - X position for overlay (default: 0)
141
+ * @param y - Y position for overlay (default: 0)
142
+ * @param options - Additional overlay options
143
+ * @returns Filter string or null if not supported
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * // Basic overlay at position
148
+ * presets.overlay(100, 50);
149
+ *
150
+ * // With additional options
151
+ * presets.overlay(0, 0, { format: 'yuv420' });
152
+ * ```
153
+ *
154
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#overlay | FFmpeg overlay filter}
84
155
  */
85
156
  overlay(x = 0, y = 0, options) {
86
157
  let filter = `overlay=${x}:${y}`;
@@ -92,13 +163,37 @@ export class FilterPresetBase {
92
163
  return filter;
93
164
  }
94
165
  /**
95
- * Adjust audio volume.
166
+ * Creates a volume filter string for audio.
167
+ *
168
+ * @param factor - Volume multiplication factor (1.0 = unchanged, 2.0 = double)
169
+ * @returns Filter string or null if not supported
170
+ *
171
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#volume | FFmpeg volume filter}
96
172
  */
97
173
  volume(factor) {
98
174
  return `volume=${factor}`;
99
175
  }
100
176
  /**
101
- * Convert audio sample format.
177
+ * Creates an audio format filter string.
178
+ *
179
+ * @param sampleFormat - Target sample format (e.g., 's16', 'fltp')
180
+ * @param sampleRate - Target sample rate in Hz (optional)
181
+ * @param channelLayout - Target channel layout (optional)
182
+ * @returns Filter string or null if not supported
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * // Change sample format only
187
+ * presets.aformat('s16');
188
+ *
189
+ * // Change format and sample rate
190
+ * presets.aformat('fltp', 48000);
191
+ *
192
+ * // Full conversion
193
+ * presets.aformat('s16', 44100, 'stereo');
194
+ * ```
195
+ *
196
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#aformat | FFmpeg aformat filter}
102
197
  */
103
198
  aformat(sampleFormat, sampleRate, channelLayout) {
104
199
  const formatName = typeof sampleFormat === 'string' ? sampleFormat : (avGetSampleFmtName(sampleFormat) ?? 's16');
@@ -110,19 +205,38 @@ export class FilterPresetBase {
110
205
  return filter;
111
206
  }
112
207
  /**
113
- * Change audio tempo without changing pitch.
208
+ * Creates an atempo filter string to change audio playback speed.
209
+ * Factor must be between 0.5 and 2.0. For larger changes, chain multiple atempo filters.
210
+ *
211
+ * @param factor - Tempo factor (0.5 = half speed, 2.0 = double speed)
212
+ * @returns Filter string or null if not supported
213
+ *
214
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#atempo | FFmpeg atempo filter}
114
215
  */
115
216
  atempo(factor) {
116
217
  return `atempo=${factor}`;
117
218
  }
118
219
  /**
119
- * Apply audio fade.
220
+ * Creates an audio fade filter string.
221
+ *
222
+ * @param type - Fade type ('in' or 'out')
223
+ * @param start - Start time in seconds
224
+ * @param duration - Fade duration in seconds
225
+ * @returns Filter string or null if not supported
226
+ *
227
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#afade | FFmpeg afade filter}
120
228
  */
121
229
  afade(type, start, duration) {
122
230
  return `afade=t=${type}:st=${start}:d=${duration}`;
123
231
  }
124
232
  /**
125
- * Mix multiple audio streams.
233
+ * Creates an amix filter string to mix multiple audio streams.
234
+ *
235
+ * @param inputs - Number of input streams to mix (default: 2)
236
+ * @param duration - How to determine output duration (default: 'longest')
237
+ * @returns Filter string or null if not supported
238
+ *
239
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#amix | FFmpeg amix filter}
126
240
  */
127
241
  amix(inputs = 2, duration = 'longest') {
128
242
  return `amix=inputs=${inputs}:duration=${duration}`;
@@ -130,13 +244,25 @@ export class FilterPresetBase {
130
244
  }
131
245
  /**
132
246
  * Filter chain builder for composing multiple filters.
133
- * Allows fluent API for building complex filter graphs.
247
+ * Allows fluent API for building complex filter graphs by chaining filter operations.
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * const chain = new FilterChain()
252
+ * .add('scale=1920:1080')
253
+ * .add('fps=30')
254
+ * .custom('rotate=45*PI/180')
255
+ * .build();
256
+ * // Result: "scale=1920:1080,fps=30,rotate=45*PI/180"
257
+ * ```
134
258
  */
135
259
  export class FilterChain {
136
260
  filters = [];
137
261
  /**
138
- * Add a filter to the chain.
139
- * @param filter - Filter string or null/undefined (will be skipped)
262
+ * Adds a filter to the chain.
263
+ *
264
+ * @param filter - Filter string to add (ignored if null/undefined)
265
+ * @returns This instance for chaining
140
266
  */
141
267
  add(filter) {
142
268
  if (filter) {
@@ -145,20 +271,27 @@ export class FilterChain {
145
271
  return this;
146
272
  }
147
273
  /**
148
- * Add a custom filter string.
274
+ * Adds a custom filter string to the chain.
275
+ *
276
+ * @param filter - Custom filter string
277
+ * @returns This instance for chaining
149
278
  */
150
279
  custom(filter) {
151
280
  return this.add(filter);
152
281
  }
153
282
  /**
154
- * Build the filter chain string.
283
+ * Builds the final filter string.
284
+ *
155
285
  * @param separator - Separator between filters (default: ',')
286
+ * @returns Combined filter string
156
287
  */
157
288
  build(separator = ',') {
158
289
  return this.filters.join(separator);
159
290
  }
160
291
  /**
161
- * Get the filter array.
292
+ * Returns the filters as an array.
293
+ *
294
+ * @returns Array of filter strings
162
295
  */
163
296
  toArray() {
164
297
  return [...this.filters];
@@ -166,75 +299,245 @@ export class FilterChain {
166
299
  }
167
300
  /**
168
301
  * Base chain builder with common filter methods.
302
+ * Provides a fluent API for building filter chains using preset methods.
303
+ *
169
304
  * @template T The preset type this builder uses
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const chain = new ChainBuilderBase(presets)
309
+ * .scale(1920, 1080)
310
+ * .fps(30)
311
+ * .fade('in', 0, 2)
312
+ * .build();
313
+ * ```
170
314
  */
171
315
  export class ChainBuilderBase extends FilterChain {
172
316
  presets;
317
+ /**
318
+ * @param presets - The filter presets to use
319
+ * @internal
320
+ */
173
321
  constructor(presets) {
174
322
  super();
175
323
  this.presets = presets;
176
324
  }
325
+ /**
326
+ * Adds a scale filter to the chain.
327
+ *
328
+ * @param width - Target width
329
+ * @param height - Target height
330
+ * @param options - Additional scaling options
331
+ * @returns This instance for chaining
332
+ *
333
+ * @see {@link FilterPresetBase.scale}
334
+ */
177
335
  scale(width, height, options) {
178
336
  return this.add(this.presets.scale(width, height, options));
179
337
  }
338
+ /**
339
+ * Adds a crop filter to the chain.
340
+ *
341
+ * @param width - Crop width
342
+ * @param height - Crop height
343
+ * @param x - X position (default: 0)
344
+ * @param y - Y position (default: 0)
345
+ * @returns This instance for chaining
346
+ *
347
+ * @see {@link FilterPresetBase.crop}
348
+ */
180
349
  crop(width, height, x = 0, y = 0) {
181
350
  return this.add(this.presets.crop(width, height, x, y));
182
351
  }
352
+ /**
353
+ * Adds an FPS filter to the chain.
354
+ *
355
+ * @param fps - Target frame rate
356
+ * @returns This instance for chaining
357
+ *
358
+ * @see {@link FilterPresetBase.fps}
359
+ */
183
360
  fps(fps) {
184
361
  return this.add(this.presets.fps(fps));
185
362
  }
363
+ /**
364
+ * Adds a format filter to the chain.
365
+ *
366
+ * @param pixelFormat - Target pixel format(s)
367
+ * @returns This instance for chaining
368
+ *
369
+ * @see {@link FilterPresetBase.format}
370
+ */
186
371
  format(pixelFormat) {
187
372
  return this.add(this.presets.format(pixelFormat));
188
373
  }
374
+ /**
375
+ * Adds a rotate filter to the chain.
376
+ *
377
+ * @param angle - Rotation angle in degrees
378
+ * @returns This instance for chaining
379
+ *
380
+ * @see {@link FilterPresetBase.rotate}
381
+ */
189
382
  rotate(angle) {
190
383
  return this.add(this.presets.rotate(angle));
191
384
  }
385
+ /**
386
+ * Adds a horizontal flip filter to the chain.
387
+ *
388
+ * @returns This instance for chaining
389
+ *
390
+ * @see {@link FilterPresetBase.hflip}
391
+ */
192
392
  hflip() {
193
393
  return this.add(this.presets.hflip());
194
394
  }
395
+ /**
396
+ * Adds a vertical flip filter to the chain.
397
+ *
398
+ * @returns This instance for chaining
399
+ *
400
+ * @see {@link FilterPresetBase.vflip}
401
+ */
195
402
  vflip() {
196
403
  return this.add(this.presets.vflip());
197
404
  }
405
+ /**
406
+ * Adds a fade filter to the chain.
407
+ *
408
+ * @param type - Fade type ('in' or 'out')
409
+ * @param start - Start time in seconds
410
+ * @param duration - Fade duration in seconds
411
+ * @returns This instance for chaining
412
+ *
413
+ * @see {@link FilterPresetBase.fade}
414
+ */
198
415
  fade(type, start, duration) {
199
416
  return this.add(this.presets.fade(type, start, duration));
200
417
  }
418
+ /**
419
+ * Adds an overlay filter to the chain.
420
+ *
421
+ * @param x - X position (default: 0)
422
+ * @param y - Y position (default: 0)
423
+ * @param options - Additional overlay options
424
+ * @returns This instance for chaining
425
+ *
426
+ * @see {@link FilterPresetBase.overlay}
427
+ */
201
428
  overlay(x = 0, y = 0, options) {
202
429
  return this.add(this.presets.overlay(x, y, options));
203
430
  }
431
+ /**
432
+ * Adds a volume filter to the chain.
433
+ *
434
+ * @param factor - Volume factor
435
+ * @returns This instance for chaining
436
+ *
437
+ * @see {@link FilterPresetBase.volume}
438
+ */
204
439
  volume(factor) {
205
440
  return this.add(this.presets.volume(factor));
206
441
  }
442
+ /**
443
+ * Adds an audio format filter to the chain.
444
+ *
445
+ * @param sampleFormat - Target sample format
446
+ * @param sampleRate - Target sample rate (optional)
447
+ * @param channelLayout - Target channel layout (optional)
448
+ * @returns This instance for chaining
449
+ *
450
+ * @see {@link FilterPresetBase.aformat}
451
+ */
207
452
  aformat(sampleFormat, sampleRate, channelLayout) {
208
453
  return this.add(this.presets.aformat(sampleFormat, sampleRate, channelLayout));
209
454
  }
455
+ /**
456
+ * Adds an atempo filter to the chain.
457
+ *
458
+ * @param factor - Tempo factor (0.5 to 2.0)
459
+ * @returns This instance for chaining
460
+ *
461
+ * @see {@link FilterPresetBase.atempo}
462
+ */
210
463
  atempo(factor) {
211
464
  return this.add(this.presets.atempo(factor));
212
465
  }
466
+ /**
467
+ * Adds an audio fade filter to the chain.
468
+ *
469
+ * @param type - Fade type ('in' or 'out')
470
+ * @param start - Start time in seconds
471
+ * @param duration - Fade duration in seconds
472
+ * @returns This instance for chaining
473
+ *
474
+ * @see {@link FilterPresetBase.afade}
475
+ */
213
476
  afade(type, start, duration) {
214
477
  return this.add(this.presets.afade(type, start, duration));
215
478
  }
479
+ /**
480
+ * Adds an amix filter to the chain.
481
+ *
482
+ * @param inputs - Number of inputs (default: 2)
483
+ * @param duration - Duration mode (default: 'longest')
484
+ * @returns This instance for chaining
485
+ *
486
+ * @see {@link FilterPresetBase.amix}
487
+ */
216
488
  amix(inputs = 2, duration = 'longest') {
217
489
  return this.add(this.presets.amix(inputs, duration));
218
490
  }
219
- // Hardware-specific methods (only available if presets support them)
491
+ /**
492
+ * Adds a transpose filter to the chain (hardware-specific).
493
+ * Only available for hardware presets that support transpose
494
+ *
495
+ * @param dir - Transpose direction (default: 0)
496
+ * @returns This instance for chaining
497
+ *
498
+ */
220
499
  transpose(dir = 0) {
221
500
  if ('transpose' in this.presets) {
222
501
  return this.add(this.presets.transpose(dir));
223
502
  }
224
503
  return this.add(null);
225
504
  }
505
+ /**
506
+ * Adds a tonemap filter to the chain (hardware-specific).
507
+ * Only available for hardware presets that support tonemapping
508
+ *
509
+ * @param options - Tonemapping options
510
+ * @returns This instance for chaining
511
+ *
512
+ */
226
513
  tonemap(options) {
227
514
  if ('tonemap' in this.presets) {
228
515
  return this.add(this.presets.tonemap(options));
229
516
  }
230
517
  return this.add(null);
231
518
  }
519
+ /**
520
+ * Adds a deinterlace filter to the chain (hardware-specific).
521
+ * Only available for hardware presets that support deinterlacing
522
+ *
523
+ * @param mode - Deinterlace mode (optional)
524
+ * @returns This instance for chaining
525
+ *
526
+ */
232
527
  deinterlace(mode) {
233
528
  if ('deinterlace' in this.presets) {
234
529
  return this.add(this.presets.deinterlace(mode));
235
530
  }
236
531
  return this.add(null);
237
532
  }
533
+ /**
534
+ * Adds a flip filter to the chain (hardware-specific).
535
+ * Falls back to hflip/vflip if hardware flip not available
536
+ *
537
+ * @param direction - Flip direction ('h' or 'v')
538
+ * @returns This instance for chaining
539
+ *
540
+ */
238
541
  flip(direction) {
239
542
  if ('flip' in this.presets) {
240
543
  return this.add(this.presets.flip(direction));
@@ -242,36 +545,78 @@ export class ChainBuilderBase extends FilterChain {
242
545
  // Fallback to hflip/vflip
243
546
  return direction === 'h' ? this.hflip() : this.vflip();
244
547
  }
548
+ /**
549
+ * Adds a blur filter to the chain (hardware-specific).
550
+ * Only available for hardware presets that support blur
551
+ *
552
+ * @param type - Blur type (default: 'avg')
553
+ * @param radius - Blur radius (optional)
554
+ * @returns This instance for chaining
555
+ *
556
+ */
245
557
  blur(type = 'avg', radius) {
246
558
  if ('blur' in this.presets) {
247
559
  return this.add(this.presets.blur(type, radius));
248
560
  }
249
561
  return this.add(null);
250
562
  }
563
+ /**
564
+ * Adds a sharpen filter to the chain (hardware-specific).
565
+ * Only available for hardware presets that support sharpening
566
+ *
567
+ * @param amount - Sharpen amount (optional)
568
+ * @returns This instance for chaining
569
+ *
570
+ */
251
571
  sharpen(amount) {
252
572
  if ('sharpen' in this.presets) {
253
573
  return this.add(this.presets.sharpen(amount));
254
574
  }
255
575
  return this.add(null);
256
576
  }
577
+ /**
578
+ * Adds a stack filter to the chain (hardware-specific).
579
+ * Only available for hardware presets that support stacking
580
+ *
581
+ * @param type - Stack type ('h' for horizontal, 'v' for vertical, 'x' for grid)
582
+ * @param inputs - Number of inputs (default: 2)
583
+ * @returns This instance for chaining
584
+ *
585
+ */
257
586
  stack(type, inputs = 2) {
258
587
  if ('stack' in this.presets) {
259
588
  return this.add(this.presets.stack(type, inputs));
260
589
  }
261
590
  return this.add(null);
262
591
  }
592
+ /**
593
+ * Adds a hwupload filter to upload frames to hardware.
594
+ *
595
+ * @returns This instance for chaining
596
+ */
263
597
  hwupload() {
264
598
  if ('hwupload' in this.presets) {
265
599
  return this.add(this.presets.hwupload());
266
600
  }
267
601
  return this.add('hwupload');
268
602
  }
603
+ /**
604
+ * Adds a hwdownload filter to download frames from hardware.
605
+ *
606
+ * @returns This instance for chaining
607
+ */
269
608
  hwdownload() {
270
609
  if ('hwdownload' in this.presets) {
271
610
  return this.add(this.presets.hwdownload());
272
611
  }
273
612
  return this.add('hwdownload');
274
613
  }
614
+ /**
615
+ * Adds a hwmap filter to map frames between hardware devices.
616
+ *
617
+ * @param derive - Device to derive from (optional)
618
+ * @returns This instance for chaining
619
+ */
275
620
  hwmap(derive) {
276
621
  if ('hwmap' in this.presets) {
277
622
  return this.add(this.presets.hwmap(derive));
@@ -281,91 +626,204 @@ export class ChainBuilderBase extends FilterChain {
281
626
  }
282
627
  /**
283
628
  * Fluent filter chain builder with preset methods.
629
+ * Provides a convenient API for building filter chains using standard presets.
630
+ *
631
+ * @example
632
+ * ```typescript
633
+ * const filter = FilterPresets.chain()
634
+ * .scale(1920, 1080)
635
+ * .fps(30)
636
+ * .fade('in', 0, 2)
637
+ * .format('yuv420p')
638
+ * .build();
639
+ * ```
284
640
  */
285
641
  export class FilterChainBuilder extends ChainBuilderBase {
286
642
  }
287
643
  /**
288
- * Common filter presets for convenience.
289
- *
290
- * Provides pre-defined filter strings for common operations.
291
- * Can be used with Filter.create() for quick setup.
644
+ * Standard filter presets for software filtering.
645
+ * Provides static methods for creating common filter strings and
646
+ * a chain builder for composing complex filter graphs.
292
647
  *
293
648
  * @example
294
649
  * ```typescript
295
- * const filter = await Filter.create(
296
- * FilterPresets.scale(1280, 720),
297
- * config
298
- * );
650
+ * // Static methods for individual filters
651
+ * const scaleFilter = FilterPresets.scale(1920, 1080);
652
+ * const fpsFilter = FilterPresets.fps(30);
299
653
  *
300
- * // Using chain builder
654
+ * // Chain builder for complex graphs
301
655
  * const chain = FilterPresets.chain()
302
656
  * .scale(1920, 1080)
303
- * .format('yuv420p')
304
- * .custom('unsharp=5:5:1.0')
657
+ * .fps(30)
658
+ * .fade('in', 0, 2)
305
659
  * .build();
306
660
  * ```
307
661
  */
308
662
  export class FilterPresets extends FilterPresetBase {
309
663
  static instance = new FilterPresets();
310
664
  /**
311
- * Create a new filter chain builder.
665
+ * Creates a new filter chain builder.
666
+ *
667
+ * @returns A new FilterChainBuilder instance
668
+ *
669
+ * @example
670
+ * ```typescript
671
+ * const filter = FilterPresets.chain()
672
+ * .scale(1280, 720)
673
+ * .fps(30)
674
+ * .build();
675
+ * ```
312
676
  */
313
677
  static chain() {
314
678
  return new FilterChainBuilder(FilterPresets.instance);
315
679
  }
316
- // Static methods that delegate to instance
680
+ /**
681
+ * Creates a scale filter string.
682
+ *
683
+ * @param width - Target width
684
+ * @param height - Target height
685
+ * @param flags - Scaling algorithm flags (optional)
686
+ * @returns Scale filter string
687
+ */
317
688
  static scale(width, height, flags) {
318
689
  const result = FilterPresets.instance.scale(width, height, { flags });
319
690
  return result ?? '';
320
691
  }
692
+ /**
693
+ * Creates a crop filter string.
694
+ *
695
+ * @param width - Crop width
696
+ * @param height - Crop height
697
+ * @param x - X position (default: 0)
698
+ * @param y - Y position (default: 0)
699
+ * @returns Crop filter string
700
+ */
321
701
  static crop(width, height, x = 0, y = 0) {
322
702
  const result = FilterPresets.instance.crop(width, height, x, y);
323
703
  return result ?? '';
324
704
  }
705
+ /**
706
+ * Creates an FPS filter string.
707
+ *
708
+ * @param fps - Target frame rate
709
+ * @returns FPS filter string
710
+ */
325
711
  static fps(fps) {
326
712
  const result = FilterPresets.instance.fps(fps);
327
713
  return result ?? '';
328
714
  }
715
+ /**
716
+ * Creates a format filter string.
717
+ *
718
+ * @param pixelFormat - Target pixel format(s)
719
+ * @returns Format filter string
720
+ */
329
721
  static format(pixelFormat) {
330
722
  const result = FilterPresets.instance.format(pixelFormat);
331
723
  return result ?? '';
332
724
  }
725
+ /**
726
+ * Creates a rotate filter string.
727
+ *
728
+ * @param angle - Rotation angle in degrees
729
+ * @returns Rotate filter string
730
+ */
333
731
  static rotate(angle) {
334
732
  const result = FilterPresets.instance.rotate(angle);
335
733
  return result ?? '';
336
734
  }
735
+ /**
736
+ * Creates a horizontal flip filter string.
737
+ *
738
+ * @returns Horizontal flip filter string
739
+ */
337
740
  static hflip() {
338
741
  const result = FilterPresets.instance.hflip();
339
742
  return result ?? '';
340
743
  }
744
+ /**
745
+ * Creates a vertical flip filter string.
746
+ *
747
+ * @returns Vertical flip filter string
748
+ */
341
749
  static vflip() {
342
750
  const result = FilterPresets.instance.vflip();
343
751
  return result ?? '';
344
752
  }
753
+ /**
754
+ * Creates a fade filter string.
755
+ *
756
+ * @param type - Fade type ('in' or 'out')
757
+ * @param start - Start time in seconds
758
+ * @param duration - Fade duration in seconds
759
+ * @returns Fade filter string
760
+ */
345
761
  static fade(type, start, duration) {
346
762
  const result = FilterPresets.instance.fade(type, start, duration);
347
763
  return result ?? '';
348
764
  }
765
+ /**
766
+ * Creates an overlay filter string.
767
+ *
768
+ * @param x - X position (default: 0)
769
+ * @param y - Y position (default: 0)
770
+ * @returns Overlay filter string
771
+ */
349
772
  static overlay(x = 0, y = 0) {
350
773
  const result = FilterPresets.instance.overlay(x, y);
351
774
  return result ?? '';
352
775
  }
776
+ /**
777
+ * Creates a volume filter string.
778
+ *
779
+ * @param factor - Volume multiplication factor
780
+ * @returns Volume filter string
781
+ */
353
782
  static volume(factor) {
354
783
  const result = FilterPresets.instance.volume(factor);
355
784
  return result ?? '';
356
785
  }
786
+ /**
787
+ * Creates an audio format filter string.
788
+ *
789
+ * @param sampleFormat - Target sample format
790
+ * @param sampleRate - Target sample rate (optional)
791
+ * @param channelLayout - Target channel layout (optional)
792
+ * @returns Audio format filter string
793
+ */
357
794
  static aformat(sampleFormat, sampleRate, channelLayout) {
358
795
  const result = FilterPresets.instance.aformat(sampleFormat, sampleRate, channelLayout);
359
796
  return result ?? '';
360
797
  }
798
+ /**
799
+ * Creates an atempo filter string.
800
+ *
801
+ * @param factor - Tempo factor (0.5 to 2.0)
802
+ * @returns Atempo filter string
803
+ */
361
804
  static atempo(factor) {
362
805
  const result = FilterPresets.instance.atempo(factor);
363
806
  return result ?? '';
364
807
  }
808
+ /**
809
+ * Creates an audio fade filter string.
810
+ *
811
+ * @param type - Fade type ('in' or 'out')
812
+ * @param start - Start time in seconds
813
+ * @param duration - Fade duration in seconds
814
+ * @returns Audio fade filter string
815
+ */
365
816
  static afade(type, start, duration) {
366
817
  const result = FilterPresets.instance.afade(type, start, duration);
367
818
  return result ?? '';
368
819
  }
820
+ /**
821
+ * Creates an amix filter string.
822
+ *
823
+ * @param inputs - Number of inputs (default: 2)
824
+ * @param duration - Duration mode (default: 'longest')
825
+ * @returns Amix filter string
826
+ */
369
827
  static amix(inputs = 2, duration = 'longest') {
370
828
  const result = FilterPresets.instance.amix(inputs, duration);
371
829
  return result ?? '';
@@ -373,47 +831,54 @@ export class FilterPresets extends FilterPresetBase {
373
831
  }
374
832
  /**
375
833
  * Hardware-accelerated filter presets.
376
- *
377
- * Provides hardware-specific filter strings for accelerated processing.
378
- * Created and managed by HardwareContext for type-safe hardware operations.
834
+ * Provides optimized filter implementations for specific hardware types,
835
+ * with automatic fallback when operations aren't supported.
379
836
  *
380
837
  * @example
381
838
  * ```typescript
382
- * const hw = await HardwareContext.auto();
383
- * if (hw) {
384
- * // Get hardware-specific scale filter (returns null if unsupported)
385
- * const scaleFilter = hw.filterPresets.scale(1920, 1080);
839
+ * // Create hardware presets for CUDA
840
+ * const hw = new HardwareFilterPresets(AV_HWDEVICE_TYPE_CUDA, 'cuda');
386
841
  *
387
- * // Build a filter chain (unsupported filters are skipped)
388
- * const chain = hw.filterPresets.chain()
389
- * .hwupload()
390
- * .scale(1920, 1080)
391
- * .tonemap() // Skipped if not supported
392
- * .custom('unsharp=5:5:1.0')
393
- * .hwdownload()
394
- * .build();
842
+ * // Check capabilities
843
+ * if (hw.support.scale) {
844
+ * const scaleFilter = hw.scale(1920, 1080);
395
845
  * }
846
+ *
847
+ * // Use chain builder
848
+ * const chain = hw.chain()
849
+ * .hwupload()
850
+ * .scale(1920, 1080)
851
+ * .tonemap()
852
+ * .hwdownload()
853
+ * .build();
396
854
  * ```
397
855
  */
398
856
  export class HardwareFilterPresets extends FilterPresetBase {
399
857
  deviceType;
400
- deviceName;
858
+ deviceTypeName;
401
859
  support;
402
860
  /**
403
- * Create hardware filter presets for a specific device type.
404
- * @internal Used by HardwareContext
861
+ * @param deviceType - Hardware device type enum
862
+ * @param deviceTypeName - Hardware device type name (e.g., 'cuda', 'vaapi')
405
863
  */
406
- constructor(deviceType, deviceName = null) {
864
+ constructor(deviceType, deviceTypeName) {
407
865
  super();
408
866
  this.deviceType = deviceType;
409
- this.deviceName = deviceName ?? 'unknown';
867
+ this.deviceTypeName = deviceTypeName;
410
868
  this.support = this.getSupport();
411
869
  }
412
870
  /**
413
- * Check if a filter name is a hardware-accelerated filter.
414
- * Uses FFmpeg's AVFILTER_FLAG_HWDEVICE flag to determine if a filter is hardware-accelerated.
415
- * @param filterName - The filter name to check
416
- * @returns True if it's a hardware filter, false otherwise
871
+ * Checks if a filter is hardware-accelerated.
872
+ *
873
+ * @param filterName - Name of the filter to check
874
+ * @returns True if the filter uses hardware acceleration
875
+ *
876
+ * @example
877
+ * ```typescript
878
+ * if (HardwareFilterPresets.isHardwareFilter('scale_cuda')) {
879
+ * console.log('Hardware accelerated scaling');
880
+ * }
881
+ * ```
417
882
  */
418
883
  static isHardwareFilter(filterName) {
419
884
  const filter = Filter.getByName(filterName);
@@ -424,14 +889,39 @@ export class HardwareFilterPresets extends FilterPresetBase {
424
889
  return (filter.flags & AVFILTER_FLAG_HWDEVICE) !== 0;
425
890
  }
426
891
  /**
427
- * Create a new hardware filter chain builder.
892
+ * Creates a hardware filter chain builder.
893
+ *
894
+ * @returns A new HardwareFilterChainBuilder instance
895
+ *
896
+ * @example
897
+ * ```typescript
898
+ * const filter = hw.chain()
899
+ * .hwupload()
900
+ * .scale(1920, 1080)
901
+ * .hwdownload()
902
+ * .build();
903
+ * ```
428
904
  */
429
905
  chain() {
430
906
  return new HardwareFilterChainBuilder(this);
431
907
  }
432
908
  /**
433
- * Hardware-accelerated scale filter.
434
- * @returns Filter string or null if not supported
909
+ * Creates a hardware-accelerated scale filter.
910
+ *
911
+ * Different hardware types use different scale filters:
912
+ * - CUDA: scale_cuda or scale_npp (with npp option)
913
+ * - VAAPI: scale_vaapi
914
+ * - QSV: scale_qsv
915
+ * - VideoToolbox: scale_vt
916
+ * - RKMPP: scale_rkrga
917
+ *
918
+ * @param width - Target width
919
+ * @param height - Target height
920
+ * @param options - Hardware-specific scaling options
921
+ * @returns Hardware scale filter string or null if not supported
922
+ *
923
+ *
924
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#scale_005fcuda | FFmpeg scale_cuda filter}
435
925
  */
436
926
  scale(width, height, options) {
437
927
  if (!this.support.scale) {
@@ -449,7 +939,7 @@ export class HardwareFilterPresets extends FilterPresetBase {
449
939
  filterName = 'scale_vt'; // VideoToolbox uses scale_vt
450
940
  }
451
941
  else {
452
- filterName = `scale_${this.deviceName}`;
942
+ filterName = `scale_${this.deviceTypeName}`;
453
943
  }
454
944
  let filter = `${filterName}=${width}:${height}`;
455
945
  if (options) {
@@ -463,15 +953,21 @@ export class HardwareFilterPresets extends FilterPresetBase {
463
953
  return filter;
464
954
  }
465
955
  /**
466
- * Hardware-accelerated overlay filter.
467
- * @returns Filter string or null if not supported
956
+ * Creates a hardware-accelerated overlay filter.
957
+ *
958
+ * @param x - X position (default: 0)
959
+ * @param y - Y position (default: 0)
960
+ * @param options - Hardware-specific overlay options
961
+ * @returns Hardware overlay filter string or null if not supported
962
+ *
963
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda | FFmpeg overlay_cuda filter}
468
964
  */
469
965
  overlay(x = 0, y = 0, options) {
470
966
  if (!this.support.overlay) {
471
967
  return null;
472
968
  }
473
969
  // Special handling for RKMPP which uses RGA
474
- const filterName = this.deviceType === AV_HWDEVICE_TYPE_RKMPP ? 'overlay_rkrga' : `overlay_${this.deviceName}`;
970
+ const filterName = this.deviceType === AV_HWDEVICE_TYPE_RKMPP ? 'overlay_rkrga' : `overlay_${this.deviceTypeName}`;
475
971
  let filter = `${filterName}=${x}:${y}`;
476
972
  if (options) {
477
973
  for (const [key, value] of Object.entries(options)) {
@@ -481,8 +977,17 @@ export class HardwareFilterPresets extends FilterPresetBase {
481
977
  return filter;
482
978
  }
483
979
  /**
484
- * Hardware-accelerated transpose filter.
485
- * @returns Filter string or null if not supported
980
+ * Creates a hardware-accelerated transpose filter.
981
+ *
982
+ * Direction values:
983
+ * - 0: 90 degrees counter-clockwise and vertical flip
984
+ * - 1: 90 degrees clockwise
985
+ * - 2: 90 degrees counter-clockwise
986
+ * - 3: 90 degrees clockwise and vertical flip
987
+ *
988
+ * @param dir - Transpose direction (default: 0)
989
+ * @returns Hardware transpose filter string or null if not supported
990
+ *
486
991
  */
487
992
  transpose(dir = 0) {
488
993
  if (!this.support.transpose) {
@@ -497,20 +1002,24 @@ export class HardwareFilterPresets extends FilterPresetBase {
497
1002
  filterName = 'transpose_vt'; // CoreImage-based transpose
498
1003
  }
499
1004
  else {
500
- filterName = `transpose_${this.deviceName}`;
1005
+ filterName = `transpose_${this.deviceTypeName}`;
501
1006
  }
502
1007
  return `${filterName}=dir=${dir}`;
503
1008
  }
504
1009
  /**
505
- * Hardware-accelerated tonemap filter.
506
- * @returns Filter string or null if not supported
1010
+ * Creates a hardware-accelerated tonemap filter.
1011
+ * Used for HDR to SDR conversion with hardware acceleration.
1012
+ *
1013
+ * @param options - Tonemapping options (algorithm, parameters)
1014
+ * @returns Hardware tonemap filter string or null if not supported
1015
+ *
507
1016
  */
508
1017
  tonemap(options) {
509
1018
  if (!this.support.tonemap) {
510
1019
  return null;
511
1020
  }
512
1021
  // VideoToolbox uses different filter name
513
- const filterName = this.deviceType === AV_HWDEVICE_TYPE_VIDEOTOOLBOX ? 'tonemap_videotoolbox' : `tonemap_${this.deviceName}`;
1022
+ const filterName = this.deviceType === AV_HWDEVICE_TYPE_VIDEOTOOLBOX ? 'tonemap_videotoolbox' : `tonemap_${this.deviceTypeName}`;
514
1023
  let filter = filterName;
515
1024
  if (options) {
516
1025
  const opts = Object.entries(options)
@@ -521,8 +1030,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
521
1030
  return filter;
522
1031
  }
523
1032
  /**
524
- * Hardware-accelerated deinterlace filter.
525
- * @returns Filter string or null if not supported
1033
+ * Creates a hardware-accelerated deinterlace filter.
1034
+ *
1035
+ * Different hardware types use different deinterlacers:
1036
+ * - CUDA: yadif_cuda
1037
+ * - VAAPI: deinterlace_vaapi
1038
+ * - QSV: deinterlace_qsv
1039
+ * - Vulkan: bwdif_vulkan
1040
+ * - VideoToolbox: yadif_videotoolbox
1041
+ *
1042
+ * @param mode - Deinterlacing mode (optional)
1043
+ * @returns Hardware deinterlace filter string or null if not supported
1044
+ *
526
1045
  */
527
1046
  deinterlace(mode) {
528
1047
  if (!this.support.deinterlace) {
@@ -544,8 +1063,12 @@ export class HardwareFilterPresets extends FilterPresetBase {
544
1063
  }
545
1064
  }
546
1065
  /**
547
- * Hardware-accelerated flip filter.
548
- * @returns Filter string or null if not supported
1066
+ * Creates a hardware-accelerated flip filter.
1067
+ * Currently only Vulkan supports hardware flip filters.
1068
+ *
1069
+ * @param direction - Flip direction ('h' for horizontal, 'v' for vertical)
1070
+ * @returns Hardware flip filter string or null if not supported
1071
+ *
549
1072
  */
550
1073
  flip(direction) {
551
1074
  if (!this.support.flip) {
@@ -557,8 +1080,17 @@ export class HardwareFilterPresets extends FilterPresetBase {
557
1080
  return null;
558
1081
  }
559
1082
  /**
560
- * Hardware-accelerated blur filter.
561
- * @returns Filter string or null if not supported
1083
+ * Creates a hardware-accelerated blur filter.
1084
+ *
1085
+ * Different hardware types support different blur filters:
1086
+ * - CUDA: bilateral_cuda
1087
+ * - Vulkan: avgblur_vulkan, gblur_vulkan
1088
+ * - OpenCL: avgblur_opencl, boxblur_opencl
1089
+ *
1090
+ * @param type - Blur type ('avg', 'gaussian', or 'box', default: 'avg')
1091
+ * @param radius - Blur radius (optional)
1092
+ * @returns Hardware blur filter string or null if not supported
1093
+ *
562
1094
  */
563
1095
  blur(type = 'avg', radius) {
564
1096
  if (!this.support.blur) {
@@ -576,8 +1108,16 @@ export class HardwareFilterPresets extends FilterPresetBase {
576
1108
  }
577
1109
  }
578
1110
  /**
579
- * Hardware-accelerated sharpen filter.
580
- * @returns Filter string or null if not supported
1111
+ * Creates a hardware-accelerated sharpen filter.
1112
+ *
1113
+ * Hardware sharpening support:
1114
+ * - VAAPI: sharpness_vaapi
1115
+ * - OpenCL: unsharp_opencl
1116
+ * - CUDA: sharpen_npp (NPP-based)
1117
+ *
1118
+ * @param amount - Sharpening amount (optional)
1119
+ * @returns Hardware sharpen filter string or null if not supported
1120
+ *
581
1121
  */
582
1122
  sharpen(amount) {
583
1123
  if (!this.support.sharpen) {
@@ -596,20 +1136,30 @@ export class HardwareFilterPresets extends FilterPresetBase {
596
1136
  }
597
1137
  }
598
1138
  /**
599
- * Hardware-accelerated stack filters (hstack, vstack, xstack).
600
- * @returns Filter string or null if not supported
1139
+ * Creates a hardware-accelerated stack filter.
1140
+ * Only VAAPI and QSV support hardware stacking.
1141
+ *
1142
+ * @param type - Stack type ('h' for horizontal, 'v' for vertical, 'x' for grid)
1143
+ * @param inputs - Number of inputs to stack (default: 2)
1144
+ * @returns Hardware stack filter string or null if not supported
1145
+ *
601
1146
  */
602
1147
  stack(type, inputs = 2) {
603
1148
  if (!this.support.stack) {
604
1149
  return null;
605
1150
  }
606
1151
  if (this.deviceType === AV_HWDEVICE_TYPE_VAAPI || this.deviceType === AV_HWDEVICE_TYPE_QSV) {
607
- return `${type}stack_${this.deviceName}=inputs=${inputs}`;
1152
+ return `${type}stack_${this.deviceTypeName}=inputs=${inputs}`;
608
1153
  }
609
1154
  return null;
610
1155
  }
611
1156
  /**
612
- * Hardware upload filter to transfer frames to GPU.
1157
+ * Creates a hwupload filter to upload frames to hardware memory.
1158
+ * CUDA uses hwupload_cuda, others use generic hwupload.
1159
+ *
1160
+ * @returns Hardware upload filter string
1161
+ *
1162
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#hwupload | FFmpeg hwupload filter}
613
1163
  */
614
1164
  hwupload() {
615
1165
  if (this.deviceType === AV_HWDEVICE_TYPE_CUDA) {
@@ -618,25 +1168,48 @@ export class HardwareFilterPresets extends FilterPresetBase {
618
1168
  return 'hwupload';
619
1169
  }
620
1170
  /**
621
- * Hardware download filter to transfer frames from GPU.
1171
+ * Creates a hwdownload filter to download frames from hardware memory.
1172
+ *
1173
+ * @returns Hardware download filter string
1174
+ *
1175
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#hwdownload | FFmpeg hwdownload filter}
622
1176
  */
623
1177
  hwdownload() {
624
1178
  return 'hwdownload';
625
1179
  }
626
1180
  /**
627
- * Format conversion for hardware frames.
1181
+ * Creates a hwmap filter to map frames between hardware devices.
1182
+ *
1183
+ * @param derive - Device to derive from (optional)
1184
+ * @returns Hardware map filter string
1185
+ *
1186
+ * @see {@link https://ffmpeg.org/ffmpeg-filters.html#hwmap | FFmpeg hwmap filter}
628
1187
  */
629
1188
  hwmap(derive) {
630
1189
  return derive ? `hwmap=derive_device=${derive}` : 'hwmap';
631
1190
  }
632
1191
  /**
633
- * Get capabilities for this hardware type.
1192
+ * Gets the filter capabilities for this hardware type.
1193
+ *
1194
+ * @returns Object describing which filters are supported
1195
+ *
1196
+ * @example
1197
+ * ```typescript
1198
+ * const caps = hw.getCapabilities();
1199
+ * if (caps.scale && caps.overlay) {
1200
+ * console.log('Hardware supports scaling and overlay');
1201
+ * }
1202
+ * ```
634
1203
  */
635
1204
  getCapabilities() {
636
1205
  return this.support;
637
1206
  }
638
1207
  /**
639
- * Get supported filters for this hardware type.
1208
+ * Determines filter support for the hardware type.
1209
+ *
1210
+ * @returns Hardware filter support configuration
1211
+ *
1212
+ * @internal
640
1213
  */
641
1214
  getSupport() {
642
1215
  switch (this.deviceType) {
@@ -816,7 +1389,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
816
1389
  }
817
1390
  /**
818
1391
  * Hardware filter chain builder with fluent API.
819
- * Automatically skips unsupported filters (returns null).
1392
+ * Automatically skips unsupported filters (returns null) allowing graceful fallback.
1393
+ *
1394
+ * @example
1395
+ * ```typescript
1396
+ * const hw = new HardwareFilterPresets(AV_HWDEVICE_TYPE_CUDA, 'cuda');
1397
+ * const chain = hw.chain()
1398
+ * .hwupload()
1399
+ * .scale(1920, 1080)
1400
+ * .tonemap() // Skipped if not supported
1401
+ * .hwdownload()
1402
+ * .build();
1403
+ * ```
820
1404
  */
821
1405
  export class HardwareFilterChainBuilder extends ChainBuilderBase {
822
1406
  }