node-av-light 0.0.0-stage → 7.1.0-beta.1

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 (311) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +710 -2
  3. package/dist/api/audio-frame-buffer.d.ts +636 -0
  4. package/dist/api/audio-frame-buffer.js +1027 -0
  5. package/dist/api/audio-frame-buffer.js.map +1 -0
  6. package/dist/api/bitstream-filter.d.ts +938 -0
  7. package/dist/api/bitstream-filter.js +1427 -0
  8. package/dist/api/bitstream-filter.js.map +1 -0
  9. package/dist/api/constants.d.ts +44 -0
  10. package/dist/api/constants.js +45 -0
  11. package/dist/api/constants.js.map +1 -0
  12. package/dist/api/data/test_av1.ivf +0 -0
  13. package/dist/api/data/test_h264.h264 +0 -0
  14. package/dist/api/data/test_hevc.h265 +0 -0
  15. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  16. package/dist/api/data/test_vp8.ivf +0 -0
  17. package/dist/api/data/test_vp9.ivf +0 -0
  18. package/dist/api/decoder.d.ts +1413 -0
  19. package/dist/api/decoder.js +2367 -0
  20. package/dist/api/decoder.js.map +1 -0
  21. package/dist/api/demuxer.d.ts +1295 -0
  22. package/dist/api/demuxer.js +2344 -0
  23. package/dist/api/demuxer.js.map +1 -0
  24. package/dist/api/device.d.ts +589 -0
  25. package/dist/api/device.js +964 -0
  26. package/dist/api/device.js.map +1 -0
  27. package/dist/api/encoder-pool.d.ts +262 -0
  28. package/dist/api/encoder-pool.js +397 -0
  29. package/dist/api/encoder-pool.js.map +1 -0
  30. package/dist/api/encoder.d.ts +1509 -0
  31. package/dist/api/encoder.js +2619 -0
  32. package/dist/api/encoder.js.map +1 -0
  33. package/dist/api/filter-complex.d.ts +828 -0
  34. package/dist/api/filter-complex.js +1661 -0
  35. package/dist/api/filter-complex.js.map +1 -0
  36. package/dist/api/filter-presets.d.ts +800 -0
  37. package/dist/api/filter-presets.js +1554 -0
  38. package/dist/api/filter-presets.js.map +1 -0
  39. package/dist/api/filter.d.ts +1339 -0
  40. package/dist/api/filter.js +2075 -0
  41. package/dist/api/filter.js.map +1 -0
  42. package/dist/api/fmp4-stream.d.ts +797 -0
  43. package/dist/api/fmp4-stream.js +1428 -0
  44. package/dist/api/fmp4-stream.js.map +1 -0
  45. package/dist/api/hardware.d.ts +677 -0
  46. package/dist/api/hardware.js +1300 -0
  47. package/dist/api/hardware.js.map +1 -0
  48. package/dist/api/index.d.ts +21 -0
  49. package/dist/api/index.js +38 -0
  50. package/dist/api/index.js.map +1 -0
  51. package/dist/api/io-stream.d.ts +308 -0
  52. package/dist/api/io-stream.js +358 -0
  53. package/dist/api/io-stream.js.map +1 -0
  54. package/dist/api/muxer.d.ts +1311 -0
  55. package/dist/api/muxer.js +2672 -0
  56. package/dist/api/muxer.js.map +1 -0
  57. package/dist/api/pipeline.d.ts +801 -0
  58. package/dist/api/pipeline.js +1344 -0
  59. package/dist/api/pipeline.js.map +1 -0
  60. package/dist/api/probe.d.ts +128 -0
  61. package/dist/api/probe.js +227 -0
  62. package/dist/api/probe.js.map +1 -0
  63. package/dist/api/rtp-stream.d.ts +497 -0
  64. package/dist/api/rtp-stream.js +1131 -0
  65. package/dist/api/rtp-stream.js.map +1 -0
  66. package/dist/api/scaler.d.ts +561 -0
  67. package/dist/api/scaler.js +918 -0
  68. package/dist/api/scaler.js.map +1 -0
  69. package/dist/api/types.d.ts +17 -0
  70. package/dist/api/types.js +2 -0
  71. package/dist/api/types.js.map +1 -0
  72. package/dist/api/utilities/async-queue.d.ts +149 -0
  73. package/dist/api/utilities/async-queue.js +254 -0
  74. package/dist/api/utilities/async-queue.js.map +1 -0
  75. package/dist/api/utilities/audio-sample.d.ts +117 -0
  76. package/dist/api/utilities/audio-sample.js +112 -0
  77. package/dist/api/utilities/audio-sample.js.map +1 -0
  78. package/dist/api/utilities/audio-transcode.d.ts +20 -0
  79. package/dist/api/utilities/audio-transcode.js +27 -0
  80. package/dist/api/utilities/audio-transcode.js.map +1 -0
  81. package/dist/api/utilities/channel-layout.d.ts +76 -0
  82. package/dist/api/utilities/channel-layout.js +80 -0
  83. package/dist/api/utilities/channel-layout.js.map +1 -0
  84. package/dist/api/utilities/codec-format.d.ts +87 -0
  85. package/dist/api/utilities/codec-format.js +117 -0
  86. package/dist/api/utilities/codec-format.js.map +1 -0
  87. package/dist/api/utilities/context-options.d.ts +25 -0
  88. package/dist/api/utilities/context-options.js +23 -0
  89. package/dist/api/utilities/context-options.js.map +1 -0
  90. package/dist/api/utilities/electron-shared-texture.d.ts +368 -0
  91. package/dist/api/utilities/electron-shared-texture.js +540 -0
  92. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  93. package/dist/api/utilities/image.d.ts +207 -0
  94. package/dist/api/utilities/image.js +213 -0
  95. package/dist/api/utilities/image.js.map +1 -0
  96. package/dist/api/utilities/index.d.ts +14 -0
  97. package/dist/api/utilities/index.js +27 -0
  98. package/dist/api/utilities/index.js.map +1 -0
  99. package/dist/api/utilities/live-decoding.d.ts +15 -0
  100. package/dist/api/utilities/live-decoding.js +32 -0
  101. package/dist/api/utilities/live-decoding.js.map +1 -0
  102. package/dist/api/utilities/media-type.d.ts +49 -0
  103. package/dist/api/utilities/media-type.js +53 -0
  104. package/dist/api/utilities/media-type.js.map +1 -0
  105. package/dist/api/utilities/packet-age-watchdog.d.ts +198 -0
  106. package/dist/api/utilities/packet-age-watchdog.js +594 -0
  107. package/dist/api/utilities/packet-age-watchdog.js.map +1 -0
  108. package/dist/api/utilities/pixel-format.d.ts +89 -0
  109. package/dist/api/utilities/pixel-format.js +97 -0
  110. package/dist/api/utilities/pixel-format.js.map +1 -0
  111. package/dist/api/utilities/sample-format.d.ts +129 -0
  112. package/dist/api/utilities/sample-format.js +141 -0
  113. package/dist/api/utilities/sample-format.js.map +1 -0
  114. package/dist/api/utilities/scale-size.d.ts +51 -0
  115. package/dist/api/utilities/scale-size.js +55 -0
  116. package/dist/api/utilities/scale-size.js.map +1 -0
  117. package/dist/api/utilities/scheduler.d.ts +138 -0
  118. package/dist/api/utilities/scheduler.js +98 -0
  119. package/dist/api/utilities/scheduler.js.map +1 -0
  120. package/dist/api/utilities/streaming.d.ts +186 -0
  121. package/dist/api/utilities/streaming.js +309 -0
  122. package/dist/api/utilities/streaming.js.map +1 -0
  123. package/dist/api/utilities/timestamp.d.ts +193 -0
  124. package/dist/api/utilities/timestamp.js +206 -0
  125. package/dist/api/utilities/timestamp.js.map +1 -0
  126. package/dist/api/utilities/video-transcode.d.ts +218 -0
  127. package/dist/api/utilities/video-transcode.js +624 -0
  128. package/dist/api/utilities/video-transcode.js.map +1 -0
  129. package/dist/api/utilities/whisper-model.d.ts +330 -0
  130. package/dist/api/utilities/whisper-model.js +587 -0
  131. package/dist/api/utilities/whisper-model.js.map +1 -0
  132. package/dist/api/utils.d.ts +19 -0
  133. package/dist/api/utils.js +39 -0
  134. package/dist/api/utils.js.map +1 -0
  135. package/dist/api/webrtc-stream.d.ts +294 -0
  136. package/dist/api/webrtc-stream.js +546 -0
  137. package/dist/api/webrtc-stream.js.map +1 -0
  138. package/dist/api/whisper.d.ts +326 -0
  139. package/dist/api/whisper.js +402 -0
  140. package/dist/api/whisper.js.map +1 -0
  141. package/dist/constants/bsf-options.d.ts +364 -0
  142. package/dist/constants/bsf-options.js +7 -0
  143. package/dist/constants/bsf-options.js.map +1 -0
  144. package/dist/constants/channel-layouts.d.ts +53 -0
  145. package/dist/constants/channel-layouts.js +57 -0
  146. package/dist/constants/channel-layouts.js.map +1 -0
  147. package/dist/constants/constants.d.ts +2435 -0
  148. package/dist/constants/constants.js +1989 -0
  149. package/dist/constants/constants.js.map +1 -0
  150. package/dist/constants/decoders.d.ts +651 -0
  151. package/dist/constants/decoders.js +641 -0
  152. package/dist/constants/decoders.js.map +1 -0
  153. package/dist/constants/encoders.d.ts +314 -0
  154. package/dist/constants/encoders.js +309 -0
  155. package/dist/constants/encoders.js.map +1 -0
  156. package/dist/constants/filter-options.d.ts +12099 -0
  157. package/dist/constants/filter-options.js +7 -0
  158. package/dist/constants/filter-options.js.map +1 -0
  159. package/dist/constants/format-options.d.ts +4319 -0
  160. package/dist/constants/format-options.js +7 -0
  161. package/dist/constants/format-options.js.map +1 -0
  162. package/dist/constants/formats.d.ts +18 -0
  163. package/dist/constants/formats.js +7 -0
  164. package/dist/constants/formats.js.map +1 -0
  165. package/dist/constants/hardware.d.ts +26 -0
  166. package/dist/constants/hardware.js +27 -0
  167. package/dist/constants/hardware.js.map +1 -0
  168. package/dist/constants/index.d.ts +10 -0
  169. package/dist/constants/index.js +6 -0
  170. package/dist/constants/index.js.map +1 -0
  171. package/dist/constants/options.d.ts +6217 -0
  172. package/dist/constants/options.js +7 -0
  173. package/dist/constants/options.js.map +1 -0
  174. package/dist/ffmpeg/index.d.ts +101 -0
  175. package/dist/ffmpeg/index.js +161 -0
  176. package/dist/ffmpeg/index.js.map +1 -0
  177. package/dist/ffmpeg/version.d.ts +6 -0
  178. package/dist/ffmpeg/version.js +7 -0
  179. package/dist/ffmpeg/version.js.map +1 -0
  180. package/dist/index.d.ts +4 -0
  181. package/dist/index.js +9 -0
  182. package/dist/index.js.map +1 -0
  183. package/dist/lib/audio-fifo.d.ts +399 -0
  184. package/dist/lib/audio-fifo.js +431 -0
  185. package/dist/lib/audio-fifo.js.map +1 -0
  186. package/dist/lib/binding.d.ts +242 -0
  187. package/dist/lib/binding.js +102 -0
  188. package/dist/lib/binding.js.map +1 -0
  189. package/dist/lib/bitstream-filter-context.d.ts +381 -0
  190. package/dist/lib/bitstream-filter-context.js +443 -0
  191. package/dist/lib/bitstream-filter-context.js.map +1 -0
  192. package/dist/lib/bitstream-filter.d.ts +140 -0
  193. package/dist/lib/bitstream-filter.js +154 -0
  194. package/dist/lib/bitstream-filter.js.map +1 -0
  195. package/dist/lib/codec-context.d.ts +1069 -0
  196. package/dist/lib/codec-context.js +1336 -0
  197. package/dist/lib/codec-context.js.map +1 -0
  198. package/dist/lib/codec-parameters.d.ts +664 -0
  199. package/dist/lib/codec-parameters.js +813 -0
  200. package/dist/lib/codec-parameters.js.map +1 -0
  201. package/dist/lib/codec-parser.d.ts +201 -0
  202. package/dist/lib/codec-parser.js +213 -0
  203. package/dist/lib/codec-parser.js.map +1 -0
  204. package/dist/lib/codec.d.ts +617 -0
  205. package/dist/lib/codec.js +746 -0
  206. package/dist/lib/codec.js.map +1 -0
  207. package/dist/lib/device.d.ts +294 -0
  208. package/dist/lib/device.js +326 -0
  209. package/dist/lib/device.js.map +1 -0
  210. package/dist/lib/dictionary.d.ts +333 -0
  211. package/dist/lib/dictionary.js +372 -0
  212. package/dist/lib/dictionary.js.map +1 -0
  213. package/dist/lib/error.d.ts +311 -0
  214. package/dist/lib/error.js +395 -0
  215. package/dist/lib/error.js.map +1 -0
  216. package/dist/lib/fifo.d.ts +416 -0
  217. package/dist/lib/fifo.js +453 -0
  218. package/dist/lib/fifo.js.map +1 -0
  219. package/dist/lib/filter-context.d.ts +714 -0
  220. package/dist/lib/filter-context.js +783 -0
  221. package/dist/lib/filter-context.js.map +1 -0
  222. package/dist/lib/filter-graph-segment.d.ts +161 -0
  223. package/dist/lib/filter-graph-segment.js +172 -0
  224. package/dist/lib/filter-graph-segment.js.map +1 -0
  225. package/dist/lib/filter-graph.d.ts +641 -0
  226. package/dist/lib/filter-graph.js +704 -0
  227. package/dist/lib/filter-graph.js.map +1 -0
  228. package/dist/lib/filter-inout.d.ts +202 -0
  229. package/dist/lib/filter-inout.js +261 -0
  230. package/dist/lib/filter-inout.js.map +1 -0
  231. package/dist/lib/filter.d.ts +243 -0
  232. package/dist/lib/filter.js +272 -0
  233. package/dist/lib/filter.js.map +1 -0
  234. package/dist/lib/format-context.d.ts +1335 -0
  235. package/dist/lib/format-context.js +1455 -0
  236. package/dist/lib/format-context.js.map +1 -0
  237. package/dist/lib/frame-utils.d.ts +116 -0
  238. package/dist/lib/frame-utils.js +98 -0
  239. package/dist/lib/frame-utils.js.map +1 -0
  240. package/dist/lib/frame.d.ts +1315 -0
  241. package/dist/lib/frame.js +1535 -0
  242. package/dist/lib/frame.js.map +1 -0
  243. package/dist/lib/hardware-device-context.d.ts +362 -0
  244. package/dist/lib/hardware-device-context.js +383 -0
  245. package/dist/lib/hardware-device-context.js.map +1 -0
  246. package/dist/lib/hardware-frames-context.d.ts +418 -0
  247. package/dist/lib/hardware-frames-context.js +471 -0
  248. package/dist/lib/hardware-frames-context.js.map +1 -0
  249. package/dist/lib/index.d.ts +35 -0
  250. package/dist/lib/index.js +60 -0
  251. package/dist/lib/index.js.map +1 -0
  252. package/dist/lib/input-format.d.ts +249 -0
  253. package/dist/lib/input-format.js +306 -0
  254. package/dist/lib/input-format.js.map +1 -0
  255. package/dist/lib/io-context.d.ts +698 -0
  256. package/dist/lib/io-context.js +771 -0
  257. package/dist/lib/io-context.js.map +1 -0
  258. package/dist/lib/log.d.ts +174 -0
  259. package/dist/lib/log.js +184 -0
  260. package/dist/lib/log.js.map +1 -0
  261. package/dist/lib/native-types.d.ts +1024 -0
  262. package/dist/lib/native-types.js +2 -0
  263. package/dist/lib/native-types.js.map +1 -0
  264. package/dist/lib/option.d.ts +953 -0
  265. package/dist/lib/option.js +1607 -0
  266. package/dist/lib/option.js.map +1 -0
  267. package/dist/lib/output-format.d.ts +222 -0
  268. package/dist/lib/output-format.js +259 -0
  269. package/dist/lib/output-format.js.map +1 -0
  270. package/dist/lib/packet.d.ts +521 -0
  271. package/dist/lib/packet.js +613 -0
  272. package/dist/lib/packet.js.map +1 -0
  273. package/dist/lib/rational.d.ts +251 -0
  274. package/dist/lib/rational.js +278 -0
  275. package/dist/lib/rational.js.map +1 -0
  276. package/dist/lib/software-resample-context.d.ts +552 -0
  277. package/dist/lib/software-resample-context.js +592 -0
  278. package/dist/lib/software-resample-context.js.map +1 -0
  279. package/dist/lib/software-scale-context.d.ts +344 -0
  280. package/dist/lib/software-scale-context.js +366 -0
  281. package/dist/lib/software-scale-context.js.map +1 -0
  282. package/dist/lib/stream.d.ts +383 -0
  283. package/dist/lib/stream.js +524 -0
  284. package/dist/lib/stream.js.map +1 -0
  285. package/dist/lib/sync-queue.d.ts +179 -0
  286. package/dist/lib/sync-queue.js +197 -0
  287. package/dist/lib/sync-queue.js.map +1 -0
  288. package/dist/lib/types.d.ts +34 -0
  289. package/dist/lib/types.js +2 -0
  290. package/dist/lib/types.js.map +1 -0
  291. package/dist/lib/utilities.d.ts +1198 -0
  292. package/dist/lib/utilities.js +1302 -0
  293. package/dist/lib/utilities.js.map +1 -0
  294. package/dist/utils/electron.d.ts +49 -0
  295. package/dist/utils/electron.js +63 -0
  296. package/dist/utils/electron.js.map +1 -0
  297. package/dist/utils/index.d.ts +6 -0
  298. package/dist/utils/index.js +7 -0
  299. package/dist/utils/index.js.map +1 -0
  300. package/dist/utils/libc.d.ts +11 -0
  301. package/dist/utils/libc.js +35 -0
  302. package/dist/utils/libc.js.map +1 -0
  303. package/dist/utils/variant.d.ts +26 -0
  304. package/dist/utils/variant.js +31 -0
  305. package/dist/utils/variant.js.map +1 -0
  306. package/dist/webrtc/index.d.ts +4 -0
  307. package/dist/webrtc/index.js +7 -0
  308. package/dist/webrtc/index.js.map +1 -0
  309. package/install/check.js +124 -0
  310. package/install/ffmpeg.js +66 -0
  311. package/package.json +167 -4
@@ -0,0 +1,1413 @@
1
+ import { CodecContext } from '../lib/codec-context.js';
2
+ import { Codec } from '../lib/codec.js';
3
+ import { Frame } from '../lib/frame.js';
4
+ import { Packet } from '../lib/packet.js';
5
+ import { Scheduler } from './utilities/scheduler.js';
6
+ import type { AVCodecID, AVPixelFormat, AVSampleFormat, AVThreadType, DecoderOptionsFor, EOFSignal, FFDecoderCodec } from '../constants/index.js';
7
+ import type { Stream } from '../lib/stream.js';
8
+ import type { ChannelLayout, IRational } from '../lib/types.js';
9
+ import type { Encoder } from './encoder.js';
10
+ import type { FilterAPI } from './filter.js';
11
+ import type { HardwareContext } from './hardware.js';
12
+ import type { ContextOptions } from './utilities/context-options.js';
13
+ /**
14
+ * Options for decoder creation.
15
+ */
16
+ export interface DecoderOptions<C = unknown> {
17
+ /**
18
+ * Exit immediately on first decode error.
19
+ *
20
+ * When enabled, the decoder throws on the first decode error or corrupt frame.
21
+ * When disabled it continues like FFmpeg CLI: failed packets are skipped and
22
+ * counted in {@link Decoder.decodeErrors}, and corrupt frames are returned with
23
+ * `decodeErrorFlags` or `AV_FRAME_FLAG_CORRUPT` set, so callers can drop them.
24
+ *
25
+ * @default true
26
+ */
27
+ exitOnError?: boolean;
28
+ /**
29
+ * Hardware acceleration context.
30
+ *
31
+ * Pass a HardwareContext instance to enable hardware-accelerated decoding.
32
+ * Set to null to disable hardware acceleration.
33
+ */
34
+ hardware?: HardwareContext | null;
35
+ /**
36
+ * Decode in software when the hardware decoder produces nothing.
37
+ *
38
+ * Some drivers accept a stream and then fail on every frame, which with
39
+ * `exitOnError: false` leaves a stream without pictures. A new hardware
40
+ * decoder has to produce a frame within a few packets after its first
41
+ * keyframe, a running one counts as stuck once two keyframes in a row stay
42
+ * silent. The decoder then reopens in software and decodes the packets since
43
+ * the last silent keyframe again, so the frames carry on from there.
44
+ *
45
+ * @default false
46
+ */
47
+ hardwareFallback?: boolean;
48
+ /**
49
+ * Number of extra hardware frames to allocate.
50
+ *
51
+ * Useful for hardware decoders requiring additional frame buffering.
52
+ * Some hardware decoders need extra frames for reference or look-ahead.
53
+ */
54
+ extraHWFrames?: number;
55
+ /**
56
+ * Force constant framerate mode.
57
+ *
58
+ * When set, ignores all timestamps and generates frames at a constant rate.
59
+ * Sets frame PTS to AV_NOPTS_VALUE, duration to 1, and time_base to 1/framerate.
60
+ * Matches FFmpeg CLI's DECODER_FLAG_FRAMERATE_FORCED behavior.
61
+ */
62
+ forcedFramerate?: IRational;
63
+ /**
64
+ * Override sample aspect ratio.
65
+ *
66
+ * When set, overrides the frame's sample_aspect_ratio with this value.
67
+ * Useful for fixing incorrect SAR in source material.
68
+ */
69
+ sarOverride?: IRational;
70
+ /**
71
+ * Apply cropping from frame metadata.
72
+ *
73
+ * When true, automatically crops frames based on their crop metadata.
74
+ * Uses av_frame_apply_cropping() with AV_FRAME_CROP_UNALIGNED flag.
75
+ * Useful for streams with letterboxing/pillarboxing metadata.
76
+ *
77
+ * @default false
78
+ */
79
+ applyCropping?: boolean;
80
+ /**
81
+ * Resample decoded audio to a target format (audio only).
82
+ *
83
+ * When set, decoded audio frames are transparently converted to the requested
84
+ * sample rate, sample format, and/or channel layout before they are returned —
85
+ * the audio mirror of {@link rescale}. Any omitted field keeps the decoded
86
+ * value, and conversion is skipped entirely when the source already matches the
87
+ * target. Useful when a capture device delivers a rate you cannot control (e.g.
88
+ * avfoundation ignoring a microphone sample-rate request) and you want every
89
+ * downstream stage to receive the rate you asked for.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * // Guarantee 48 kHz frames regardless of the device's actual rate
94
+ * const decoder = await Decoder.create(stream, { resample: { sampleRate: 48000 } });
95
+ * ```
96
+ */
97
+ resample?: {
98
+ sampleRate?: number;
99
+ sampleFormat?: AVSampleFormat;
100
+ channelLayout?: ChannelLayout;
101
+ };
102
+ /**
103
+ * Rescale decoded video to a target pixel format and/or size (video only).
104
+ *
105
+ * When set, decoded video frames are transparently converted to the requested
106
+ * pixel format and/or dimensions before they are returned — the video mirror of
107
+ * {@link resample}. Any omitted field keeps the decoded value, and conversion is
108
+ * skipped entirely when the source already matches the target.
109
+ *
110
+ * Hardware frames are automatically transferred to a supported software format
111
+ * first and then converted to the requested one; software frames are converted
112
+ * directly. Hardware frames are left untouched (kept on the GPU, zero-copy) when
113
+ * `rescale` is not set. This replaces the former `hwaccelOutputFormat` option:
114
+ * use `rescale: { pixelFormat }` to get decoded frames in a fixed software format.
115
+ *
116
+ * Useful to normalize a heterogeneous set of sources (e.g. RTSP cameras that each
117
+ * deliver a different pixel format) so every downstream stage receives a uniform
118
+ * format/size, regardless of whether a stream was hardware- or software-decoded.
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * // Normalize any source to yuv420p, whether it was hardware- or software-decoded
123
+ * const decoder = await Decoder.create(stream, { hardware: hw, rescale: { pixelFormat: AV_PIX_FMT_YUV420P } });
124
+ * ```
125
+ */
126
+ rescale?: {
127
+ width?: number;
128
+ height?: number;
129
+ pixelFormat?: AVPixelFormat;
130
+ };
131
+ /**
132
+ * Number of threads to use for decoding.
133
+ *
134
+ * Set to 0 to auto-detect based on CPU cores.
135
+ *
136
+ * @default 1
137
+ *
138
+ * @deprecated Use the {@link DecoderOptions.context} option instead, e.g. `context: { threadCount: 0 }`.
139
+ */
140
+ threadCount?: number;
141
+ /**
142
+ * Type of threading to use for decoding.
143
+ *
144
+ * - `FF_THREAD_FRAME` (1): Decode multiple frames in parallel.
145
+ * Higher throughput but adds latency (1 frame delay per thread).
146
+ * Not recommended for live streaming where future frames are unavailable.
147
+ *
148
+ * - `FF_THREAD_SLICE` (2): Decode parts of a single frame in parallel.
149
+ * No additional latency, suitable for real-time/live streaming.
150
+ *
151
+ * @default FFmpeg default (both methods, codec chooses best)
152
+ *
153
+ * @deprecated Use the {@link DecoderOptions.context} option instead, e.g. `context: { threadType: FF_THREAD_SLICE }`.
154
+ */
155
+ threadType?: AVThreadType;
156
+ /**
157
+ * Additional codec-specific options.
158
+ *
159
+ * Key-value pairs of FFmpeg private codec options, passed directly to the decoder.
160
+ * When the codec is created from a branded constant (e.g. `FF_DECODER_H264_CUVID`),
161
+ * these are strongly typed to that codec's known options (autocomplete + validation);
162
+ * otherwise any string/number/boolean values are accepted.
163
+ */
164
+ options?: DecoderOptionsFor<C>;
165
+ /**
166
+ * Fields to set on the underlying codec context.
167
+ *
168
+ * A typed, declarative bag for any writable {@link CodecContext} field that has
169
+ * no dedicated option — e.g. `skipLoopFilter`, `skipFrame`, `flags2`,
170
+ * `exportSideData`. Applied after node-av's stream parameters, hardware, and
171
+ * threading settings and immediately before `avcodec_open2`. The allowed keys
172
+ * are derived from the class, so every writable field is available and
173
+ * correctly typed.
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * await Decoder.create(stream, {
178
+ * context: {
179
+ * skipLoopFilter: AVDISCARD_ALL,
180
+ * },
181
+ * });
182
+ * ```
183
+ */
184
+ context?: ContextOptions<CodecContext>;
185
+ /**
186
+ * Configure the underlying codec context just before it is opened.
187
+ *
188
+ * The imperative escape hatch for cases the {@link DecoderOptions.context} bag
189
+ * cannot express: additive flags via `setFlags`, other methods, or conditional
190
+ * logic. Called with the decoder's {@link CodecContext} after `context` is
191
+ * applied and immediately before `avcodec_open2`.
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * await Decoder.create(stream, {
196
+ * configure: (ctx) => {
197
+ * ctx.setFlags(AV_CODEC_FLAG_LOW_DELAY);
198
+ * },
199
+ * });
200
+ * ```
201
+ */
202
+ configure?: (context: CodecContext) => void;
203
+ /**
204
+ * AbortSignal for cancellation.
205
+ *
206
+ * When aborted, async generators stop yielding and async methods throw AbortError.
207
+ */
208
+ signal?: AbortSignal;
209
+ }
210
+ /**
211
+ * High-level decoder for audio and video streams.
212
+ *
213
+ * Provides a simplified interface for decoding media streams from packets to frames.
214
+ * Handles codec initialization, hardware acceleration setup, and frame management.
215
+ * Supports both synchronous packet-by-packet decoding and async iteration over frames.
216
+ * Essential component in media processing pipelines for converting compressed data to raw frames.
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * import { Demuxer, Decoder } from 'node-av/api';
221
+ *
222
+ * // Open media and create decoder
223
+ * await using input = await Demuxer.open('video.mp4');
224
+ * using decoder = await Decoder.create(input.video());
225
+ *
226
+ * // Decode frames
227
+ * for await (const frame of decoder.frames(input.packets())) {
228
+ * console.log(`Decoded frame: ${frame.width}x${frame.height}`);
229
+ * frame.free();
230
+ * }
231
+ * ```
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * import { HardwareContext } from 'node-av/api';
236
+ * import { AV_HWDEVICE_TYPE_CUDA } from 'node-av/constants';
237
+ *
238
+ * // Setup hardware acceleration
239
+ * const hw = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA);
240
+ * using decoder = await Decoder.create(stream, { hardware: hw });
241
+ *
242
+ * // Frames will be decoded on GPU
243
+ * for await (const frame of decoder.frames(packets)) {
244
+ * // frame.hwFramesCtx contains GPU memory reference
245
+ * }
246
+ * ```
247
+ *
248
+ * @see {@link Encoder} For encoding frames to packets
249
+ * @see {@link Demuxer} For reading media files
250
+ * @see {@link HardwareContext} For GPU acceleration
251
+ */
252
+ export declare class Decoder implements Disposable {
253
+ private codecContext;
254
+ private codec;
255
+ private frame;
256
+ private stream;
257
+ private readonly streamIndex;
258
+ private readonly streamFramerate;
259
+ private readonly guessedFramerate;
260
+ private initialized;
261
+ private isClosed;
262
+ private options;
263
+ private _decodeErrors;
264
+ private hardwareWatch?;
265
+ private replayedFrames;
266
+ private lastFramePts;
267
+ private lastFrameDurationEst;
268
+ private lastFrameTb;
269
+ private lastFrameSampleRate;
270
+ private lastFilterInRescaleDelta;
271
+ private audioResampler?;
272
+ private resampledFrame?;
273
+ private resampleTarget?;
274
+ private resampleInputLayout?;
275
+ private audioResamplerSetup;
276
+ private audioResamplerDrained;
277
+ private videoScaler?;
278
+ private scaledFrame?;
279
+ private hwTransferFormat?;
280
+ private inputQueue;
281
+ private outputQueue;
282
+ private workerPromise;
283
+ private nextComponent;
284
+ private pipeToPromise;
285
+ private signal?;
286
+ /**
287
+ * @param codecContext - Configured codec context
288
+ *
289
+ * @param codec - Codec being used
290
+ *
291
+ * @param stream - Media stream being decoded
292
+ *
293
+ * @param options - Decoder options
294
+ *
295
+ * Use {@link create} factory method
296
+ *
297
+ * @internal
298
+ */
299
+ private constructor();
300
+ /**
301
+ * Create a decoder for a media stream.
302
+ *
303
+ * Initializes a decoder with the appropriate codec and configuration.
304
+ * Automatically detects and configures hardware acceleration if provided.
305
+ * Applies custom codec options and threading configuration.
306
+ *
307
+ * @param stream - Media stream to decode
308
+ *
309
+ * @param options - Decoder configuration options
310
+ *
311
+ * @returns Configured decoder instance
312
+ *
313
+ * @throws {FFmpegError} If codec initialization fails
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * import { Demuxer, Decoder } from 'node-av/api';
318
+ *
319
+ * await using input = await Demuxer.open('video.mp4');
320
+ * using decoder = await Decoder.create(input.video());
321
+ * ```
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * using decoder = await Decoder.create(stream, {
326
+ * threads: 4,
327
+ * options: {
328
+ * 'refcounted_frames': '1',
329
+ * 'skip_frame': 'nonkey' // Only decode keyframes
330
+ * }
331
+ * });
332
+ * ```
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * const hw = HardwareContext.auto();
337
+ * using decoder = await Decoder.create(stream, {
338
+ * hardware: hw,
339
+ * threads: 0 // Auto-detect thread count
340
+ * exitOnError: false // Continue on decode errors (default: true)
341
+ * });
342
+ * ```
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * using decoder = await Decoder.create(stream, FF_DECODER_H264_AMF, {
347
+ * hardware: hw,
348
+ * threads: 2,
349
+ * });
350
+ * ```
351
+ *
352
+ * @see {@link HardwareContext} For GPU acceleration setup
353
+ * @see {@link DecoderOptions} For configuration options
354
+ * @see {@link createSync} For synchronous version
355
+ */
356
+ static create(stream: Stream, options?: DecoderOptions): Promise<Decoder>;
357
+ static create<const C extends FFDecoderCodec | AVCodecID | Codec>(stream: Stream, decoderCodec: C, options?: DecoderOptions<C>): Promise<Decoder>;
358
+ /**
359
+ * Create a decoder for a media stream synchronously.
360
+ * Synchronous version of create.
361
+ *
362
+ * Initializes a decoder with the appropriate codec and configuration.
363
+ * Automatically detects and configures hardware acceleration if provided.
364
+ * Applies custom codec options and threading configuration.
365
+ *
366
+ * @param stream - Media stream to decode
367
+ *
368
+ * @param options - Decoder configuration options
369
+ *
370
+ * @returns Configured decoder instance
371
+ *
372
+ * @throws {FFmpegError} If codec initialization fails
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * import { Demuxer, Decoder } from 'node-av/api';
377
+ *
378
+ * await using input = await Demuxer.open('video.mp4');
379
+ * using decoder = Decoder.createSync(input.video());
380
+ * ```
381
+ *
382
+ * @example
383
+ * ```typescript
384
+ * using decoder = Decoder.createSync(stream, {
385
+ * threads: 4,
386
+ * options: {
387
+ * 'refcounted_frames': '1',
388
+ * 'skip_frame': 'nonkey' // Only decode keyframes
389
+ * }
390
+ * });
391
+ * ```
392
+ *
393
+ * @example
394
+ * ```typescript
395
+ * const hw = HardwareContext.auto();
396
+ * using decoder = Decoder.createSync(stream, {
397
+ * hardware: hw,
398
+ * threads: 0 // Auto-detect thread count
399
+ * });
400
+ * ```
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * using decoder = Decoder.createSync(stream, FF_DECODER_H264_NVDEC, {
405
+ * hardware: hw
406
+ * });
407
+ * ```
408
+ *
409
+ * @see {@link HardwareContext} For GPU acceleration setup
410
+ * @see {@link DecoderOptions} For configuration options
411
+ * @see {@link create} For async version
412
+ */
413
+ static createSync(stream: Stream, options?: DecoderOptions): Decoder;
414
+ static createSync<const C extends FFDecoderCodec | AVCodecID | Codec>(stream: Stream, decoderCodec: C, options?: DecoderOptions<C>): Decoder;
415
+ /**
416
+ * Check if decoder is open.
417
+ *
418
+ * @returns true if decoder is open and ready
419
+ *
420
+ * @example
421
+ * ```typescript
422
+ * if (decoder.isDecoderOpen) {
423
+ * const frame = await decoder.decode(packet);
424
+ * }
425
+ * ```
426
+ */
427
+ get isDecoderOpen(): boolean;
428
+ /**
429
+ * Check if decoder has been initialized.
430
+ *
431
+ * Returns true if decoder is initialized (true by default for decoders).
432
+ * Decoders are pre-initialized from stream parameters.
433
+ *
434
+ * @returns true if decoder has been initialized
435
+ *
436
+ * @example
437
+ * ```typescript
438
+ * if (decoder.isDecoderInitialized) {
439
+ * console.log('Decoder is ready to process frames');
440
+ * }
441
+ * ```
442
+ */
443
+ get isDecoderInitialized(): boolean;
444
+ /**
445
+ * Number of decode errors so far.
446
+ *
447
+ * Counts packets the decoder rejected, failed frame receives and frames that
448
+ * could not be transferred from the GPU, rescaled or cropped. With
449
+ * `exitOnError: false` these are skipped instead of thrown, so this is the way
450
+ * to notice them (e.g. a hardware decoder that keeps failing).
451
+ *
452
+ * Like FFmpeg CLI's decode error count. Corrupt frames are not counted; they are
453
+ * returned with `decodeErrorFlags` or `AV_FRAME_FLAG_CORRUPT` set.
454
+ *
455
+ * @returns Decode error count
456
+ *
457
+ * @example
458
+ * ```typescript
459
+ * const decoder = await Decoder.create(stream, { exitOnError: false });
460
+ * // ...
461
+ * if (decoder.decodeErrors > lastErrors) {
462
+ * console.warn(`${decoder.decodeErrors - lastErrors} decode errors`);
463
+ * }
464
+ * ```
465
+ */
466
+ get decodeErrors(): number;
467
+ /**
468
+ * Check if decoder uses hardware acceleration.
469
+ *
470
+ * @returns true if hardware-accelerated
471
+ *
472
+ * @example
473
+ * ```typescript
474
+ * if (decoder.isHardware()) {
475
+ * console.log('Using GPU acceleration');
476
+ * }
477
+ * ```
478
+ *
479
+ * @see {@link HardwareContext} For hardware setup
480
+ */
481
+ isHardware(): boolean;
482
+ /**
483
+ * Check if decoder is ready for processing.
484
+ *
485
+ * @returns true if initialized and ready
486
+ *
487
+ * @example
488
+ * ```typescript
489
+ * if (decoder.isReady()) {
490
+ * const frame = await decoder.decode(packet);
491
+ * }
492
+ * ```
493
+ */
494
+ isReady(): boolean;
495
+ /**
496
+ * Send a packet to the decoder.
497
+ *
498
+ * Sends a compressed packet to the decoder for decoding.
499
+ * Does not return decoded frames - use {@link receive} to retrieve frames.
500
+ * A single packet can produce zero, one, or multiple frames depending on codec buffering.
501
+ * Automatically manages decoder state and error recovery.
502
+ *
503
+ * **Important**: This method only SENDS the packet to the decoder.
504
+ * You must call {@link receive} separately (potentially multiple times) to get decoded frames.
505
+ *
506
+ * Direct mapping to avcodec_send_packet().
507
+ *
508
+ * @param packet - Compressed packet to send to decoder, or null to flush
509
+ *
510
+ * @throws {FFmpegError} If sending packet fails
511
+ *
512
+ * @example
513
+ * ```typescript
514
+ * // Send packet and receive frames
515
+ * await decoder.decode(packet);
516
+ *
517
+ * // Receive all available frames
518
+ * while (true) {
519
+ * const frame = await decoder.receive();
520
+ * if (!frame) break;
521
+ * console.log(`Decoded frame with PTS: ${frame.pts}`);
522
+ * frame.free();
523
+ * }
524
+ * ```
525
+ *
526
+ * @example
527
+ * ```typescript
528
+ * for await (const packet of input.packets()) {
529
+ * // packet is null at end of stream - automatically flushes decoder
530
+ * await decoder.decode(packet);
531
+ *
532
+ * // Receive available frames
533
+ * let frame;
534
+ * while ((frame = await decoder.receive())) {
535
+ * await processFrame(frame);
536
+ * frame.free();
537
+ * }
538
+ * }
539
+ * ```
540
+ *
541
+ * @see {@link receive} For receiving decoded frames
542
+ * @see {@link decodeAll} For combined send+receive operation
543
+ * @see {@link frames} For automatic packet iteration
544
+ * @see {@link flush} For end-of-stream handling
545
+ * @see {@link decodeSync} For synchronous version
546
+ */
547
+ decode(packet: Packet | null): Promise<void>;
548
+ /**
549
+ * Send a packet to the decoder synchronously.
550
+ * Synchronous version of decode.
551
+ *
552
+ * Sends a compressed packet to the decoder for decoding.
553
+ * Does not return decoded frames - use {@link receiveSync} to retrieve frames.
554
+ * A single packet can produce zero, one, or multiple frames depending on codec buffering.
555
+ * Automatically manages decoder state and error recovery.
556
+ *
557
+ * **Important**: This method only SENDS the packet to the decoder.
558
+ * You must call {@link receiveSync} separately (potentially multiple times) to get decoded frames.
559
+ *
560
+ * Direct mapping to avcodec_send_packet().
561
+ *
562
+ * @param packet - Compressed packet to send to decoder, or null to flush
563
+ *
564
+ * @throws {FFmpegError} If sending packet fails
565
+ *
566
+ * @example
567
+ * ```typescript
568
+ * // Send packet and receive frames
569
+ * decoder.decodeSync(packet);
570
+ *
571
+ * // Receive all available frames
572
+ * while (true) {
573
+ * const frame = decoder.receiveSync();
574
+ * if (!frame) break;
575
+ * console.log(`Decoded frame with PTS: ${frame.pts}`);
576
+ * frame.free();
577
+ * }
578
+ * ```
579
+ *
580
+ * @example
581
+ * ```typescript
582
+ * for (const packet of input.packetsSync()) {
583
+ * // packet is null at end of stream - automatically flushes decoder
584
+ * decoder.decodeSync(packet);
585
+ *
586
+ * // Receive available frames
587
+ * let frame;
588
+ * while ((frame = decoder.receiveSync())) {
589
+ * processFrame(frame);
590
+ * frame.free();
591
+ * }
592
+ * }
593
+ * ```
594
+ *
595
+ * @see {@link receiveSync} For receiving decoded frames
596
+ * @see {@link decodeAllSync} For combined send+receive operation
597
+ * @see {@link framesSync} For automatic packet iteration
598
+ * @see {@link flushSync} For end-of-stream handling
599
+ * @see {@link decode} For async version
600
+ */
601
+ decodeSync(packet: Packet | null): void;
602
+ /**
603
+ * Decode a packet to frames.
604
+ *
605
+ * Sends a packet to the decoder and receives all available decoded frames.
606
+ * Returns array of frames - may be empty if decoder needs more data.
607
+ * One packet can produce zero, one, or multiple frames depending on codec.
608
+ * Automatically manages decoder state and error recovery.
609
+ *
610
+ * Direct mapping to avcodec_send_packet() and avcodec_receive_frame().
611
+ *
612
+ * @param packet - Compressed packet to decode
613
+ *
614
+ * @returns Array of decoded frames (empty if more data needed or decoder is closed)
615
+ *
616
+ * @throws {FFmpegError} If decoding fails
617
+ *
618
+ * @example
619
+ * ```typescript
620
+ * const frames = await decoder.decodeAll(packet);
621
+ * for (const frame of frames) {
622
+ * console.log(`Decoded frame with PTS: ${frame.pts}`);
623
+ * frame.free();
624
+ * }
625
+ * ```
626
+ *
627
+ * @example
628
+ * ```typescript
629
+ * for await (const packet of input.packets()) {
630
+ * const frames = await decoder.decodeAll(packet);
631
+ * for (const frame of frames) {
632
+ * await processFrame(frame);
633
+ * frame.free();
634
+ * }
635
+ * packet.free();
636
+ * }
637
+ * ```
638
+ *
639
+ * @see {@link decode} For single packet decoding
640
+ * @see {@link frames} For automatic packet iteration
641
+ * @see {@link flush} For end-of-stream handling
642
+ * @see {@link decodeAllSync} For synchronous version
643
+ */
644
+ decodeAll(packet: Packet | null): Promise<Frame[]>;
645
+ /**
646
+ * Decode a packet to frames synchronously.
647
+ * Synchronous version of decodeAll.
648
+ *
649
+ * Sends packet to decoder and receives all available decoded frames.
650
+ * Returns array of frames - may be empty if decoder needs more data.
651
+ * One packet can produce zero, one, or multiple frames depending on codec.
652
+ *
653
+ * @param packet - Compressed packet to decode
654
+ *
655
+ * @returns Array of decoded frames (empty if more data needed or decoder is closed)
656
+ *
657
+ * @throws {FFmpegError} If decoding fails
658
+ *
659
+ * @example
660
+ * ```typescript
661
+ * const frames = decoder.decodeAllSync(packet);
662
+ * for (const frame of frames) {
663
+ * console.log(`Decoded: ${frame.width}x${frame.height}`);
664
+ * frame.free();
665
+ * }
666
+ *
667
+ * @example
668
+ * ```typescript
669
+ * for (const packet of input.packetsSync()) {
670
+ * const frames = await decoder.decodeAllSync(packet);
671
+ * for (const frame of frames) {
672
+ * processFrame(frame);
673
+ * frame.free();
674
+ * }
675
+ * packet.free();
676
+ * }
677
+ * ```
678
+ *
679
+ * @see {@link decodeSync} For single packet decoding
680
+ * @see {@link framesSync} For automatic packet iteration
681
+ * @see {@link flushSync} For end-of-stream handling
682
+ * @see {@link decodeAll} For async version
683
+ */
684
+ decodeAllSync(packet: Packet | null): Frame[];
685
+ /**
686
+ * Decode packet stream to frame stream.
687
+ *
688
+ * High-level async generator for complete decoding pipeline.
689
+ * Decoder is only flushed when EOF (null) signal is explicitly received.
690
+ * Primary interface for stream-based decoding.
691
+ *
692
+ * **EOF Handling:**
693
+ * - Send null to flush decoder and get remaining buffered frames
694
+ * - Generator yields null after flushing when null is received
695
+ * - No automatic flushing - decoder stays open until EOF or close()
696
+ *
697
+ * @param packets - Async iterable of packets, single packet, or null to flush
698
+ *
699
+ * @yields {Frame | null} Decoded frames, followed by null when explicitly flushed
700
+ *
701
+ * @throws {Error} If decoder is closed
702
+ *
703
+ * @throws {FFmpegError} If decoding fails
704
+ *
705
+ * @example
706
+ * ```typescript
707
+ * // Stream of packets with automatic EOF propagation
708
+ * await using input = await Demuxer.open('video.mp4');
709
+ * using decoder = await Decoder.create(input.video());
710
+ *
711
+ * for await (const frame of decoder.frames(input.packets())) {
712
+ * if (frame === null) {
713
+ * console.log('Decoding complete');
714
+ * break;
715
+ * }
716
+ * console.log(`Frame: ${frame.width}x${frame.height}`);
717
+ * frame.free();
718
+ * }
719
+ * ```
720
+ *
721
+ * @example
722
+ * ```typescript
723
+ * // Single packet (no automatic flush)
724
+ * for await (const frame of decoder.frames(singlePacket)) {
725
+ * await encoder.encode(frame);
726
+ * frame.free();
727
+ * }
728
+ * // Decoder still has buffered frames - send null to flush
729
+ * for await (const frame of decoder.frames(null)) {
730
+ * if (frame === null) break;
731
+ * await encoder.encode(frame);
732
+ * frame.free();
733
+ * }
734
+ * ```
735
+ *
736
+ * @example
737
+ * ```typescript
738
+ * // Explicit flush with EOF
739
+ * for await (const frame of decoder.frames(null)) {
740
+ * if (frame === null) {
741
+ * console.log('All buffered frames flushed');
742
+ * break;
743
+ * }
744
+ * console.log('Buffered frame:', frame.pts);
745
+ * frame.free();
746
+ * }
747
+ * ```
748
+ *
749
+ * @see {@link decode} For single packet decoding
750
+ * @see {@link Demuxer.packets} For packet source
751
+ * @see {@link framesSync} For sync version
752
+ */
753
+ frames(packets: AsyncIterable<Packet | null> | Packet | null): AsyncGenerator<Frame | null>;
754
+ /**
755
+ * Decode packet stream to frame stream synchronously.
756
+ * Synchronous version of frames.
757
+ *
758
+ * High-level async generator for complete decoding pipeline.
759
+ * Decoder is only flushed when EOF (null) signal is explicitly received.
760
+ * Primary interface for stream-based decoding.
761
+ *
762
+ * **EOF Handling:**
763
+ * - Send null to flush decoder and get remaining buffered frames
764
+ * - Generator yields null after flushing when null is received
765
+ * - No automatic flushing - decoder stays open until EOF or close()
766
+ *
767
+ * @param packets - Iterable of packets, single packet, or null to flush
768
+ *
769
+ * @yields {Frame | null} Decoded frames, followed by null when explicitly flushed
770
+ *
771
+ * @throws {Error} If decoder is closed
772
+ *
773
+ * @throws {FFmpegError} If decoding fails
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * // Stream of packets with automatic EOF propagation
778
+ * await using input = await Demuxer.open('video.mp4');
779
+ * using decoder = await Decoder.create(input.video());
780
+ *
781
+ * for (const frame of decoder.framesSync(input.packetsSync())) {
782
+ * if (frame === null) {
783
+ * console.log('Decoding complete');
784
+ * break;
785
+ * }
786
+ * console.log(`Frame: ${frame.width}x${frame.height}`);
787
+ * frame.free();
788
+ * }
789
+ * ```
790
+ *
791
+ * @example
792
+ * ```typescript
793
+ * // Single packet (no automatic flush)
794
+ * for (const frame of decoder.framesSync(singlePacket)) {
795
+ * encoder.encodeSync(frame);
796
+ * frame.free();
797
+ * }
798
+ * // Decoder still has buffered frames - send null to flush
799
+ * for (const frame of decoder.framesSync(null)) {
800
+ * if (frame === null) break;
801
+ * encoder.encodeSync(frame);
802
+ * frame.free();
803
+ * }
804
+ * ```
805
+ *
806
+ * @example
807
+ * ```typescript
808
+ * // Explicit flush with EOF
809
+ * for (const frame of decoder.framesSync(null)) {
810
+ * if (frame === null) {
811
+ * console.log('All buffered frames flushed');
812
+ * break;
813
+ * }
814
+ * console.log('Buffered frame:', frame.pts);
815
+ * frame.free();
816
+ * }
817
+ * ```
818
+ */
819
+ framesSync(packets: Iterable<Packet | null> | Packet | null): Generator<Frame | null>;
820
+ /**
821
+ * Flush decoder and signal end-of-stream.
822
+ *
823
+ * Sends null packet to decoder to signal end-of-stream.
824
+ * Does nothing if decoder is closed.
825
+ * Must use receive() or flushFrames() to get remaining buffered frames.
826
+ *
827
+ * Direct mapping to avcodec_send_packet(NULL).
828
+ *
829
+ * @throws {FFmpegError} If flush fails
830
+ *
831
+ * @example
832
+ * ```typescript
833
+ * // Signal end of stream
834
+ * await decoder.flush();
835
+ *
836
+ * // Then get remaining frames
837
+ * let frame;
838
+ * while ((frame = await decoder.receive()) !== null) {
839
+ * console.log('Got buffered frame');
840
+ * frame.free();
841
+ * }
842
+ * ```
843
+ *
844
+ * @see {@link flushFrames} For convenient async iteration
845
+ * @see {@link receive} For getting buffered frames
846
+ * @see {@link flushSync} For synchronous version
847
+ */
848
+ flush(): Promise<void>;
849
+ /**
850
+ * Flush decoder and signal end-of-stream synchronously.
851
+ * Synchronous version of flush.
852
+ *
853
+ * Send null packet to signal end of input stream.
854
+ * Decoder may still have buffered frames.
855
+ * Call receiveSync() repeatedly to get remaining frames.
856
+ *
857
+ * @throws {FFmpegError} If flush fails
858
+ *
859
+ * @example
860
+ * ```typescript
861
+ * decoder.flushSync();
862
+ * // Get remaining frames
863
+ * let frame;
864
+ * while ((frame = decoder.receiveSync()) !== null) {
865
+ * console.log('Buffered frame');
866
+ * }
867
+ * ```
868
+ *
869
+ * @see {@link flushFramesSync} For convenient sync iteration
870
+ * @see {@link receiveSync} For getting buffered frames
871
+ * @see {@link flush} For async version
872
+ */
873
+ flushSync(): void;
874
+ /**
875
+ * Flush all buffered frames as async generator.
876
+ *
877
+ * Convenient async iteration over remaining frames.
878
+ * Automatically sends flush signal and retrieves buffered frames.
879
+ * Useful for end-of-stream processing.
880
+ *
881
+ * @yields {Frame} Buffered frames
882
+ *
883
+ * @example
884
+ * ```typescript
885
+ * // Flush at end of decoding
886
+ * for await (const frame of decoder.flushFrames()) {
887
+ * console.log('Processing buffered frame');
888
+ * await encoder.encode(frame);
889
+ * frame.free();
890
+ * }
891
+ * ```
892
+ *
893
+ * @see {@link decode} For sending packets and receiving frames
894
+ * @see {@link flush} For signaling end-of-stream
895
+ * @see {@link flushFramesSync} For synchronous version
896
+ */
897
+ flushFrames(): AsyncGenerator<Frame>;
898
+ /**
899
+ * Flush all buffered frames as generator synchronously.
900
+ * Synchronous version of flushFrames.
901
+ *
902
+ * Convenient sync iteration over remaining frames.
903
+ * Automatically sends flush signal and retrieves buffered frames.
904
+ * Useful for end-of-stream processing.
905
+ *
906
+ * @yields {Frame} Buffered frames
907
+ *
908
+ * @example
909
+ * ```typescript
910
+ * // Flush at end of decoding
911
+ * for (const frame of decoder.flushFramesSync()) {
912
+ * console.log('Processing buffered frame');
913
+ * encoder.encodeSync(frame);
914
+ * frame.free();
915
+ * }
916
+ * ```
917
+ *
918
+ * @see {@link decodeSync} For sending packets and receiving frames
919
+ * @see {@link flushSync} For signaling end-of-stream
920
+ * @see {@link flushFrames} For async version
921
+ */
922
+ flushFramesSync(): Generator<Frame>;
923
+ /**
924
+ * Receive frame from decoder.
925
+ *
926
+ * Gets decoded frames from the codec's internal buffer.
927
+ * Handles frame cloning and error checking.
928
+ * Hardware frames include hw_frames_ctx reference.
929
+ * Call repeatedly to drain all buffered frames.
930
+ *
931
+ * **Return Values:**
932
+ * - `Frame` - Successfully decoded frame
933
+ * - `null` - No frame available (AVERROR_EAGAIN), send more packets
934
+ * - `undefined` - End of stream reached (AVERROR_EOF), decoder flushed
935
+ *
936
+ * Direct mapping to avcodec_receive_frame().
937
+ *
938
+ * @returns Decoded frame, null (need more data), or undefined (end of stream)
939
+ *
940
+ * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
941
+ *
942
+ * @throws {Error} If frame cloning fails (out of memory)
943
+ *
944
+ * @example
945
+ * ```typescript
946
+ * const frame = await decoder.receive();
947
+ * if (frame === EOF) {
948
+ * console.log('Decoder flushed, no more frames');
949
+ * } else if (frame) {
950
+ * console.log('Got decoded frame');
951
+ * frame.free();
952
+ * } else {
953
+ * console.log('Need more packets');
954
+ * }
955
+ * ```
956
+ *
957
+ * @example
958
+ * ```typescript
959
+ * // Drain all buffered frames (stop on null or EOF)
960
+ * let frame;
961
+ * while ((frame = await decoder.receive()) && frame !== EOF) {
962
+ * console.log(`Frame PTS: ${frame.pts}`);
963
+ * frame.free();
964
+ * }
965
+ * ```
966
+ *
967
+ * @see {@link decode} For sending packets
968
+ * @see {@link flush} For signaling end-of-stream
969
+ * @see {@link receiveSync} For synchronous version
970
+ * @see {@link EOF} For end-of-stream signal
971
+ */
972
+ receive(): Promise<Frame | EOFSignal | null>;
973
+ /**
974
+ * Receive frame from decoder synchronously.
975
+ * Synchronous version of receive.
976
+ *
977
+ * Gets decoded frames from the codec's internal buffer.
978
+ * Handles frame cloning and error checking.
979
+ * Hardware frames include hw_frames_ctx reference.
980
+ * Call repeatedly to drain all buffered frames.
981
+ *
982
+ * **Return Values:**
983
+ * - `Frame` - Successfully decoded frame
984
+ * - `null` - No frame available (AVERROR_EAGAIN), send more packets
985
+ * - `undefined` - End of stream reached (AVERROR_EOF), decoder flushed
986
+ *
987
+ * Direct mapping to avcodec_receive_frame().
988
+ *
989
+ * @returns Decoded frame, null (need more data), or undefined (end of stream)
990
+ *
991
+ * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
992
+ *
993
+ * @throws {Error} If frame cloning fails (out of memory)
994
+ *
995
+ * @example
996
+ * ```typescript
997
+ * const frame = decoder.receiveSync();
998
+ * if (frame === EOF) {
999
+ * console.log('Decoder flushed, no more frames');
1000
+ * } else if (frame) {
1001
+ * console.log('Got decoded frame');
1002
+ * frame.free();
1003
+ * } else {
1004
+ * console.log('Need more packets');
1005
+ * }
1006
+ * ```
1007
+ *
1008
+ * @example
1009
+ * ```typescript
1010
+ * // Drain all buffered frames (stop on null or EOF)
1011
+ * let frame;
1012
+ * while ((frame = decoder.receiveSync()) && frame !== EOF) {
1013
+ * console.log(`Frame PTS: ${frame.pts}`);
1014
+ * frame.free();
1015
+ * }
1016
+ * ```
1017
+ *
1018
+ * @see {@link decodeSync} For sending packets
1019
+ * @see {@link flushSync} For signaling end-of-stream
1020
+ * @see {@link receive} For async version
1021
+ * @see {@link EOF} For end-of-stream signal
1022
+ */
1023
+ receiveSync(): Frame | EOFSignal | null;
1024
+ /**
1025
+ * Pipe decoded frames to a filter component or encoder.
1026
+ *
1027
+ * @param target - Filter to receive frames or encoder to encode frames
1028
+ *
1029
+ * @returns Scheduler for continued chaining
1030
+ *
1031
+ * @example
1032
+ * ```typescript
1033
+ * decoder.pipeTo(filter).pipeTo(encoder)
1034
+ * ```
1035
+ */
1036
+ pipeTo(target: FilterAPI): Scheduler<Packet>;
1037
+ pipeTo(target: Encoder): Scheduler<Packet>;
1038
+ /**
1039
+ * Close decoder and free resources.
1040
+ *
1041
+ * Releases codec context and internal frame buffer.
1042
+ * Safe to call multiple times.
1043
+ * Automatically called by Symbol.dispose.
1044
+ *
1045
+ * @example
1046
+ * ```typescript
1047
+ * const decoder = await Decoder.create(stream);
1048
+ * try {
1049
+ * // Use decoder
1050
+ * } finally {
1051
+ * decoder.close();
1052
+ * }
1053
+ * ```
1054
+ *
1055
+ * @see {@link Symbol.dispose} For automatic cleanup
1056
+ */
1057
+ close(): void;
1058
+ /**
1059
+ * Get stream object.
1060
+ *
1061
+ * Returns the underlying stream being decoded.
1062
+ * Provides access to stream metadata and parameters.
1063
+ *
1064
+ * Borrowed: the stream is owned by the demuxer's format context and must not
1065
+ * be read after that demuxer is closed.
1066
+ *
1067
+ * @returns Stream object
1068
+ *
1069
+ * @internal
1070
+ *
1071
+ * @see {@link Stream} For stream details
1072
+ */
1073
+ getStream(): Stream;
1074
+ /**
1075
+ * Get the stream's guessed frame rate.
1076
+ *
1077
+ * av_guess_frame_rate() of the decoded stream, taken when the decoder was
1078
+ * created, so it outlives the demuxer. FFmpeg CLI feeds this rate into the
1079
+ * filter graph, from where it reaches the encoder.
1080
+ *
1081
+ * @returns Guessed frame rate, or 0/1 if unknown
1082
+ *
1083
+ * @internal
1084
+ */
1085
+ getGuessedFrameRate(): IRational;
1086
+ /**
1087
+ * Get decoder codec.
1088
+ *
1089
+ * Returns the codec used by this decoder.
1090
+ * Useful for checking codec capabilities and properties.
1091
+ *
1092
+ * @returns Codec instance
1093
+ *
1094
+ * @internal
1095
+ *
1096
+ * @see {@link Codec} For codec details
1097
+ */
1098
+ getCodec(): Codec;
1099
+ /**
1100
+ * Get underlying codec context.
1101
+ *
1102
+ * Returns the codec context for advanced operations.
1103
+ * Useful for accessing low-level codec properties and settings.
1104
+ * Returns null if decoder is closed.
1105
+ *
1106
+ * @returns Codec context or null if closed
1107
+ *
1108
+ * @internal
1109
+ *
1110
+ * @see {@link CodecContext} For context details
1111
+ */
1112
+ getCodecContext(): CodecContext | null;
1113
+ /**
1114
+ * Account for the packet that went in before this one and hold this one.
1115
+ *
1116
+ * A new hardware decoder has to produce a frame within {@link HW_DECODE_PROBE}
1117
+ * packets (plus its threads' delay) after its first keyframe. A running one
1118
+ * counts as stuck once two keyframes in a row stayed silent, because a
1119
+ * single corrupt keyframe leaves even a healthy decoder silent until the next
1120
+ * one. Packets since the last silent keyframe are held, so the software
1121
+ * decoder can start over from it.
1122
+ *
1123
+ * @param packet - The packet about to go in
1124
+ *
1125
+ * @returns Why the decoder counts as stuck, or null while it is not
1126
+ *
1127
+ * @internal
1128
+ */
1129
+ private watchHardware;
1130
+ /**
1131
+ * Reopen the decoder in software and decode the held packets again.
1132
+ *
1133
+ * The frames they produce are returned by the next receive calls, before
1134
+ * anything the new decoder makes of later packets.
1135
+ *
1136
+ * @param reason - Why the hardware decoder counts as stuck
1137
+ *
1138
+ * @throws {FFmpegError} If the software decoder fails to open or decode
1139
+ *
1140
+ * @internal
1141
+ */
1142
+ private fallBackToSoftware;
1143
+ /**
1144
+ * Reopen the decoder in software and decode the held packets again synchronously.
1145
+ * Synchronous version of fallBackToSoftware.
1146
+ *
1147
+ * @param reason - Why the hardware decoder counts as stuck
1148
+ *
1149
+ * @throws {FFmpegError} If the software decoder fails to open or decode
1150
+ *
1151
+ * @internal
1152
+ *
1153
+ * @see {@link fallBackToSoftware} For async version
1154
+ */
1155
+ private fallBackToSoftwareSync;
1156
+ /**
1157
+ * End the watch on the hardware decoder, which fell back once and for all.
1158
+ *
1159
+ * @param reason - Why the hardware decoder counts as stuck
1160
+ *
1161
+ * @returns The held packets, owned by the caller
1162
+ *
1163
+ * @internal
1164
+ */
1165
+ private takeHardwareWatch;
1166
+ /**
1167
+ * Take over the codec context of a freshly opened decoder and close it with the old one.
1168
+ *
1169
+ * @param software - Decoder opened in software for the same stream
1170
+ *
1171
+ * @internal
1172
+ */
1173
+ private adoptCodecContext;
1174
+ /**
1175
+ * Worker loop for push-based processing.
1176
+ *
1177
+ * @internal
1178
+ */
1179
+ private runWorker;
1180
+ /**
1181
+ * Send packet to input queue or flush the pipeline.
1182
+ *
1183
+ * When packet is provided, queues it for processing.
1184
+ * When null is provided, triggers flush sequence:
1185
+ * - Closes input queue
1186
+ * - Waits for worker completion
1187
+ * - Flushes decoder and sends remaining frames to output queue
1188
+ * - Closes output queue
1189
+ * - Waits for pipeTo task completion
1190
+ * - Propagates flush to next component (if any)
1191
+ *
1192
+ * Used by scheduler system for pipeline control.
1193
+ *
1194
+ * @param packet - Packet to send, or null to flush
1195
+ *
1196
+ * @internal
1197
+ */
1198
+ private sendToQueue;
1199
+ /**
1200
+ * Receive frame from output queue.
1201
+ *
1202
+ * @returns Frame from output queue or null if closed
1203
+ *
1204
+ * @internal
1205
+ */
1206
+ private receiveFromQueue;
1207
+ /**
1208
+ * Estimate video frame duration.
1209
+ *
1210
+ * Implements FFmpeg CLI's video_duration_estimate() logic.
1211
+ * Uses multiple heuristics to determine frame duration when not explicitly available:
1212
+ * 1. Frame duration from container (if reliable)
1213
+ * 2. Duration from codec framerate
1214
+ * 3. PTS difference between frames
1215
+ * 4. Stream framerate
1216
+ * 5. Last frame's estimated duration
1217
+ *
1218
+ * @param frame - Frame to estimate duration for
1219
+ *
1220
+ * @returns Estimated duration in frame's timebase units
1221
+ *
1222
+ * @internal
1223
+ */
1224
+ private estimateVideoDuration;
1225
+ /**
1226
+ * Process video frame after decoding.
1227
+ *
1228
+ * Implements FFmpeg CLI's video_frame_process() logic.
1229
+ * Handles:
1230
+ * - Hardware frame transfer to software format
1231
+ * - PTS assignment from best_effort_timestamp
1232
+ * - PTS extrapolation when missing
1233
+ * - Duration estimation
1234
+ * - Frame tracking for next frame
1235
+ *
1236
+ * @param frame - Decoded frame to process
1237
+ *
1238
+ * @internal
1239
+ */
1240
+ private processVideoFrame;
1241
+ /**
1242
+ * Audio samplerate update - handles sample rate changes.
1243
+ *
1244
+ * Based on FFmpeg's audio_samplerate_update().
1245
+ *
1246
+ * On sample rate change, chooses a new internal timebase that can represent
1247
+ * timestamps from all sample rates seen so far. Uses GCD to find minimal
1248
+ * common timebase, with fallback to LCM of common sample rates (28224000).
1249
+ *
1250
+ * Handles:
1251
+ * - Sample rate change detection
1252
+ * - Timebase calculation via GCD
1253
+ * - Overflow detection and fallback
1254
+ * - Frame timebase optimization
1255
+ * - Rescaling existing timestamps
1256
+ *
1257
+ * @param frame - Audio frame to process
1258
+ *
1259
+ * @returns Timebase to use for this frame
1260
+ *
1261
+ * @internal
1262
+ */
1263
+ private audioSamplerateUpdate;
1264
+ /**
1265
+ * Audio timestamp processing - handles audio frame timestamps.
1266
+ *
1267
+ * Based on FFmpeg's audio_ts_process().
1268
+ *
1269
+ * Processes audio frame timestamps with:
1270
+ * - Sample rate change handling via audioSamplerateUpdate()
1271
+ * - PTS extrapolation when missing (pts_pred)
1272
+ * - Gap detection (resets av_rescale_delta state)
1273
+ * - Smooth timestamp conversion via av_rescale_delta
1274
+ * - Duration calculation from nb_samples
1275
+ * - Conversion to filtering timebase {1, sample_rate}
1276
+ *
1277
+ * Handles:
1278
+ * - Dynamic sample rate changes
1279
+ * - Missing timestamps (AV_NOPTS_VALUE)
1280
+ * - Timestamp gaps/discontinuities
1281
+ * - Sample-accurate timestamp generation
1282
+ * - Frame duration calculation
1283
+ *
1284
+ * @param frame - Decoded audio frame to process
1285
+ *
1286
+ * @internal
1287
+ */
1288
+ private processAudioFrame;
1289
+ /**
1290
+ * Lazily configure the audio output resampler from the first decoded frame.
1291
+ *
1292
+ * Reads the source format from the frame, resolves the target from
1293
+ * `options.resample` (omitted fields keep the source value), and builds a
1294
+ * `SoftwareResampleContext` only when something actually differs. Runs once.
1295
+ *
1296
+ * @param frame - First decoded audio frame
1297
+ *
1298
+ * @throws {FFmpegError} If the resampler cannot be configured or initialized
1299
+ *
1300
+ * @internal
1301
+ */
1302
+ private setupAudioResampler;
1303
+ /**
1304
+ * Lazily allocate the reused resampler output frame.
1305
+ *
1306
+ * @returns The allocated output frame
1307
+ *
1308
+ * @internal
1309
+ */
1310
+ private getResampleFrame;
1311
+ /**
1312
+ * Resample a decoded audio frame to the target format and clone it for the user.
1313
+ *
1314
+ * `swr_convert_frame` allocates/sizes the output buffer; the sample timestamp
1315
+ * (carried in the frame's own timebase) is preserved, while `nb_samples` and
1316
+ * `sample_rate` reflect the new rate. Returns null when the resampler buffered
1317
+ * the input without emitting samples yet (caller should feed more).
1318
+ *
1319
+ * @param frame - Decoded source audio frame
1320
+ *
1321
+ * @returns Cloned resampled frame owned by the caller, or null if none emitted
1322
+ *
1323
+ * @throws {FFmpegError} If resampling fails
1324
+ *
1325
+ * @internal
1326
+ */
1327
+ private resampleAudioClone;
1328
+ /**
1329
+ * Drain samples buffered inside the resampler (rate-conversion delay) at EOF.
1330
+ *
1331
+ * @returns Cloned drained frame owned by the caller, or null when empty
1332
+ *
1333
+ * @throws {FFmpegError} If draining fails
1334
+ *
1335
+ * @internal
1336
+ */
1337
+ private drainResamplerClone;
1338
+ /**
1339
+ * Resolve (once, then cache) the software format to download hardware frames to.
1340
+ *
1341
+ * When `rescale.pixelFormat` is set and the frame's hardware frames context can
1342
+ * transfer directly to it, that format is used so the subsequent swscale can be
1343
+ * skipped entirely (when no resize is requested) or stay format-preserving. When
1344
+ * it cannot, `AV_PIX_FMT_NONE` is returned so `av_hwframe_transfer_data` picks a
1345
+ * supported format and the swscale handles the final conversion. Cached because
1346
+ * the hardware frames context is stable for the lifetime of the decoder.
1347
+ *
1348
+ * @param frame - First hardware frame (used to read the hardware frames context)
1349
+ *
1350
+ * @returns The download format, or `AV_PIX_FMT_NONE` to let FFmpeg choose
1351
+ *
1352
+ * @internal
1353
+ */
1354
+ private resolveHwTransferFormat;
1355
+ /**
1356
+ * Transfer a hardware frame down to system memory, replacing it in place.
1357
+ *
1358
+ * The destination software format is the requested one when the GPU can transfer
1359
+ * to it directly (see {@link resolveHwTransferFormat}), otherwise one chosen
1360
+ * automatically by FFmpeg. The downloaded data replaces the hardware frame's
1361
+ * contents so the rest of the pipeline operates on a software frame.
1362
+ *
1363
+ * @param frame - Hardware frame to download (modified in place)
1364
+ *
1365
+ * @returns True on success; false when the transfer failed and `exitOnError` is off
1366
+ *
1367
+ * @throws {FFmpegError} If the transfer fails and `exitOnError` is enabled
1368
+ *
1369
+ * @internal
1370
+ */
1371
+ private transferHwFrameToSoftware;
1372
+ /**
1373
+ * Lazily allocate the reused rescaler output frame.
1374
+ *
1375
+ * @returns The allocated output frame
1376
+ *
1377
+ * @internal
1378
+ */
1379
+ private getScaledFrame;
1380
+ /**
1381
+ * Convert a (software) video frame to the requested `rescale` pixel format and/or
1382
+ * size, replacing it in place.
1383
+ *
1384
+ * Each omitted target field keeps the source value, and the conversion is skipped
1385
+ * entirely when the frame already matches. The swscale context is configured
1386
+ * lazily from the first frame that needs conversion. `sws_scale_frame` copies the
1387
+ * frame properties (timing, colorimetry, aspect ratio).
1388
+ *
1389
+ * @param frame - Software video frame to convert (modified in place)
1390
+ *
1391
+ * @throws {FFmpegError} If the rescaler fails to configure or convert and `exitOnError` is enabled
1392
+ *
1393
+ * @internal
1394
+ */
1395
+ private rescaleVideoInPlace;
1396
+ /**
1397
+ * Dispose of decoder.
1398
+ *
1399
+ * Implements Disposable interface for automatic cleanup.
1400
+ * Equivalent to calling close().
1401
+ *
1402
+ * @example
1403
+ * ```typescript
1404
+ * {
1405
+ * using decoder = await Decoder.create(stream);
1406
+ * // Decode frames...
1407
+ * } // Automatically closed
1408
+ * ```
1409
+ *
1410
+ * @see {@link close} For manual cleanup
1411
+ */
1412
+ [Symbol.dispose](): void;
1413
+ }