node-av-lgpl 0.0.0 → 7.1.0-beta.2

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 +711 -0
  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 +384 -0
  283. package/dist/lib/stream.js +525 -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 +165 -3
@@ -0,0 +1,1535 @@
1
+ import { AV_NOPTS_VALUE, AV_PIX_FMT_BGRA, AV_TIME_BASE_Q, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_UNKNOWN, AVMEDIA_TYPE_VIDEO } from '../constants/constants.js';
2
+ import { bindings } from './binding.js';
3
+ import { FFmpegError } from './error.js';
4
+ import { HardwareFramesContext } from './hardware-frames-context.js';
5
+ import { Rational } from './rational.js';
6
+ import { Dictionary } from './dictionary.js';
7
+ /**
8
+ * Container for uncompressed audio/video data.
9
+ *
10
+ * Stores decoded audio samples or video pixels. Each frame contains raw data
11
+ * for a single video frame or a set of audio samples. Includes format information,
12
+ * timing data, and metadata. Supports both software and hardware (GPU) frames.
13
+ * Essential for decoding, encoding, and filter operations.
14
+ *
15
+ * Direct mapping to FFmpeg's AVFrame.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { Frame, FFmpegError } from 'node-av';
20
+ * import { AV_PIX_FMT_YUV420P } from 'node-av/constants';
21
+ *
22
+ * // Create and allocate frame
23
+ * const frame = new Frame();
24
+ * frame.alloc();
25
+ *
26
+ * // Configure video frame
27
+ * frame.format = AV_PIX_FMT_YUV420P;
28
+ * frame.width = 1920;
29
+ * frame.height = 1080;
30
+ * const ret = frame.allocBuffer();
31
+ * FFmpegError.throwIfError(ret, 'allocBuffer');
32
+ *
33
+ * // Receive decoded frame
34
+ * const ret2 = await codecContext.receiveFrame(frame);
35
+ * if (ret2 >= 0) {
36
+ * console.log(`Frame PTS: ${frame.pts}`);
37
+ * console.log(`Frame type: ${frame.pictType}`);
38
+ * console.log(`Keyframe: ${frame.keyFrame}`);
39
+ * }
40
+ *
41
+ * // Cleanup
42
+ * frame.unref();
43
+ * ```
44
+ *
45
+ * @see [AVFrame](https://ffmpeg.org/doxygen/trunk/structAVFrame.html) - FFmpeg Doxygen
46
+ * @see {@link CodecContext} For encoding/decoding frames
47
+ * @see {@link FilterContext} For filtering frames
48
+ */
49
+ export class Frame {
50
+ native;
51
+ constructor() {
52
+ this.native = new bindings.Frame();
53
+ }
54
+ /**
55
+ * Create a video frame from a buffer with pixel data.
56
+ *
57
+ * Allocates frame buffers, sets properties, and copies buffer data.
58
+ * Convenience factory method that combines frame allocation and data copy.
59
+ *
60
+ * @param buffer - Buffer containing raw pixel data
61
+ *
62
+ * @param props - Video Frame properties
63
+ *
64
+ * @returns Allocated frame with data from buffer
65
+ *
66
+ * @throws {FFmpegError} If allocation or buffer copy fails
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * import { Frame, AV_PIX_FMT_RGBA, FFmpegError } from 'node-av';
71
+ *
72
+ * const rawPixels = Buffer.alloc(1920 * 1080 * 4); // RGBA data
73
+ * using frame = Frame.fromVideoBuffer(rawPixels, {
74
+ * width: 1920,
75
+ * height: 1080,
76
+ * format: AV_PIX_FMT_RGBA,
77
+ * timeBase: { num: 1, den: 30 }
78
+ * });
79
+ * ```
80
+ */
81
+ static fromVideoBuffer(buffer, props) {
82
+ const frame = new Frame();
83
+ frame.alloc();
84
+ frame.width = props.width;
85
+ frame.height = props.height;
86
+ frame.format = props.format;
87
+ frame.pts = props.pts ?? AV_NOPTS_VALUE;
88
+ if (props.timeBase) {
89
+ frame.timeBase = new Rational(props.timeBase.num, props.timeBase.den);
90
+ }
91
+ else {
92
+ frame.timeBase = Rational.fromObject(AV_TIME_BASE_Q);
93
+ }
94
+ if (props.sampleAspectRatio) {
95
+ frame.sampleAspectRatio = new Rational(props.sampleAspectRatio.num, props.sampleAspectRatio.den);
96
+ }
97
+ if (props.alphaMode !== undefined) {
98
+ frame.alphaMode = props.alphaMode;
99
+ }
100
+ const ret = frame.getBuffer();
101
+ FFmpegError.throwIfError(ret, 'Failed to allocate frame buffers');
102
+ const copyRet = frame.fromBuffer(buffer);
103
+ FFmpegError.throwIfError(copyRet, 'Failed to copy buffer to frame');
104
+ return frame;
105
+ }
106
+ /**
107
+ * Create an audio frame from a buffer with sample data.
108
+ *
109
+ * Allocates frame buffers, sets properties, and copies buffer data.
110
+ * Convenience factory method that combines frame allocation and data copy.
111
+ *
112
+ * @param buffer - Buffer containing raw audio samples
113
+ *
114
+ * @param props - Frame properties
115
+ *
116
+ * @returns Allocated frame with data from buffer
117
+ *
118
+ * @throws {FFmpegError} If allocation or buffer copy fails
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * import { Frame, AV_SAMPLE_FMT_FLT, AV_CH_LAYOUT_STEREO, FFmpegError } from 'node-av';
123
+ *
124
+ * const samples = Buffer.alloc(960 * 2 * 4); // 960 samples, stereo, float32
125
+ * using frame = Frame.fromAudioBuffer(samples, {
126
+ * nbSamples: 960,
127
+ * format: AV_SAMPLE_FMT_FLT,
128
+ * sampleRate: 48000,
129
+ * channelLayout: AV_CH_LAYOUT_STEREO,
130
+ * timeBase: { num: 1, den: 48000 }
131
+ * });
132
+ * ```
133
+ */
134
+ static fromAudioBuffer(buffer, props) {
135
+ const frame = new Frame();
136
+ frame.alloc();
137
+ frame.nbSamples = props.nbSamples;
138
+ frame.format = props.format;
139
+ frame.sampleRate = props.sampleRate;
140
+ frame.channelLayout = props.channelLayout;
141
+ frame.pts = props.pts ?? AV_NOPTS_VALUE;
142
+ if (props.timeBase) {
143
+ frame.timeBase = new Rational(props.timeBase.num, props.timeBase.den);
144
+ }
145
+ else {
146
+ frame.timeBase = Rational.fromObject(AV_TIME_BASE_Q);
147
+ }
148
+ const ret = frame.getBuffer();
149
+ FFmpegError.throwIfError(ret, 'Failed to allocate frame buffers');
150
+ const copyRet = frame.fromBuffer(buffer);
151
+ FFmpegError.throwIfError(copyRet, 'Failed to copy buffer to frame');
152
+ return frame;
153
+ }
154
+ /**
155
+ * Create a hardware frame from an IOSurface handle (macOS only).
156
+ *
157
+ * Zero-copy: the frame references the same GPU memory as the IOSurface.
158
+ * Width and height are auto-detected from the IOSurface.
159
+ *
160
+ * @param ioSurface - IOSurfaceRef pointer as Buffer
161
+ *
162
+ * @param props - Hardware context and timing options
163
+ *
164
+ * @returns Hardware frame referencing the IOSurface GPU memory
165
+ *
166
+ * @throws {FFmpegError} If the import fails (e.g., invalid handle, wrong platform)
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * import { Frame, HardwareFramesContext } from 'node-av/lib';
171
+ *
172
+ * const frame = Frame.fromIOSurface(ioSurfaceBuffer, {
173
+ * hwFramesCtx,
174
+ * pts: 0n,
175
+ * timeBase: { num: 1, den: 90000 },
176
+ * });
177
+ * ```
178
+ */
179
+ static fromIOSurface(ioSurface, props) {
180
+ const frame = new Frame();
181
+ frame.alloc();
182
+ frame.pts = props.pts ?? AV_NOPTS_VALUE;
183
+ if (props.timeBase) {
184
+ frame.timeBase = new Rational(props.timeBase.num, props.timeBase.den);
185
+ }
186
+ const ret = frame.native.importIOSurface(ioSurface, props.hwFramesCtx.getNative());
187
+ FFmpegError.throwIfError(ret, 'Failed to import IOSurface');
188
+ return frame;
189
+ }
190
+ /**
191
+ * Create a software frame from an NSImage native handle (macOS only).
192
+ *
193
+ * Zero-copy: the frame references the NSBitmapImageRep pixel data directly.
194
+ * Width, height, and pixel format are auto-detected.
195
+ *
196
+ * @param nsImageHandle - NSImage pointer as Buffer
197
+ *
198
+ * @param props - Timing options
199
+ *
200
+ * @returns Software frame referencing the NSImage pixel data
201
+ *
202
+ * @throws {FFmpegError} If the import fails (e.g., no NSBitmapImageRep, wrong platform)
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * import { Frame } from 'node-av/lib';
207
+ *
208
+ * // Electron: nativeImage.getNativeHandle() returns 8-byte NSImage* pointer
209
+ * const frame = Frame.fromNSImage(nativeImage.getNativeHandle(), {
210
+ * pts: 0n,
211
+ * timeBase: { num: 1, den: 30 },
212
+ * });
213
+ * ```
214
+ */
215
+ static fromNSImage(nsImageHandle, props) {
216
+ const frame = new Frame();
217
+ frame.alloc();
218
+ frame.pts = props?.pts ?? AV_NOPTS_VALUE;
219
+ if (props?.timeBase) {
220
+ frame.timeBase = new Rational(props.timeBase.num, props.timeBase.den);
221
+ }
222
+ const ret = frame.native.importNSImage(nsImageHandle);
223
+ FFmpegError.throwIfError(ret, 'Failed to import NSImage');
224
+ return frame;
225
+ }
226
+ /**
227
+ * Create a hardware frame from a D3D11 shared texture (Windows only).
228
+ *
229
+ * Zero-copy: the frame references the shared GPU texture.
230
+ * Width and height are auto-detected from the texture descriptor.
231
+ *
232
+ * @param handle - D3D11 shared texture handle as Buffer
233
+ *
234
+ * @param props - Hardware context and timing options
235
+ *
236
+ * @returns Hardware frame referencing the D3D11 texture
237
+ *
238
+ * @throws {FFmpegError} If the import fails (e.g., invalid handle, wrong platform)
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * import { Frame, HardwareDeviceContext } from 'node-av/lib';
243
+ *
244
+ * const frame = Frame.fromD3D11Texture(sharedTextureHandle, {
245
+ * hwDeviceCtx,
246
+ * pts: 0n,
247
+ * timeBase: { num: 1, den: 90000 },
248
+ * });
249
+ * ```
250
+ */
251
+ static fromD3D11Texture(handle, props) {
252
+ const frame = new Frame();
253
+ frame.alloc();
254
+ frame.pts = props.pts ?? AV_NOPTS_VALUE;
255
+ if (props.timeBase) {
256
+ frame.timeBase = new Rational(props.timeBase.num, props.timeBase.den);
257
+ }
258
+ const ret = frame.native.importD3D11Texture(handle, props.hwDeviceCtx.getNative());
259
+ FFmpegError.throwIfError(ret, 'Failed to import D3D11 shared texture');
260
+ return frame;
261
+ }
262
+ /**
263
+ * Create a DRM PRIME frame from DMA-BUF file descriptors (Linux only).
264
+ *
265
+ * Zero-copy: the frame references the DMA-BUF GPU memory.
266
+ *
267
+ * @param dmaBuf - DMA-BUF plane descriptors
268
+ *
269
+ * @param props - Dimensions and timing options
270
+ *
271
+ * @returns Hardware frame referencing the DMA-BUF memory
272
+ *
273
+ * @throws {FFmpegError} If the import fails (e.g., invalid descriptors, wrong platform)
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * import { Frame } from 'node-av/lib';
278
+ *
279
+ * // Create DRM PRIME frame from DMA-BUF
280
+ * const drmFrame = Frame.fromDmaBuf(dmaBufPlanes, {
281
+ * width: 1920,
282
+ * height: 1080,
283
+ * pts: 0n,
284
+ * timeBase: { num: 1, den: 90000 },
285
+ * });
286
+ * ```
287
+ */
288
+ static fromDmaBuf(dmaBuf, props) {
289
+ const frame = new Frame();
290
+ frame.alloc();
291
+ frame.pts = props.pts ?? AV_NOPTS_VALUE;
292
+ if (props.timeBase) {
293
+ frame.timeBase = new Rational(props.timeBase.num, props.timeBase.den);
294
+ }
295
+ const swFormat = props.swFormat ?? AV_PIX_FMT_BGRA;
296
+ const ret = frame.native.importDmaBuf(dmaBuf.planes, props.width, props.height, BigInt(dmaBuf.modifier), swFormat);
297
+ FFmpegError.throwIfError(ret, 'Failed to import DMA-BUF');
298
+ return frame;
299
+ }
300
+ /**
301
+ * Pixel format for video frames or sample format for audio.
302
+ *
303
+ * Direct mapping to AVFrame->format.
304
+ */
305
+ get format() {
306
+ return this.native.format;
307
+ }
308
+ set format(value) {
309
+ this.native.format = value;
310
+ }
311
+ /**
312
+ * Width of video frame in pixels.
313
+ *
314
+ * Direct mapping to AVFrame->width.
315
+ */
316
+ get width() {
317
+ return this.native.width;
318
+ }
319
+ set width(value) {
320
+ this.native.width = value;
321
+ }
322
+ /**
323
+ * Height of video frame in pixels.
324
+ *
325
+ * Direct mapping to AVFrame->height.
326
+ */
327
+ get height() {
328
+ return this.native.height;
329
+ }
330
+ set height(value) {
331
+ this.native.height = value;
332
+ }
333
+ /**
334
+ * Number of audio samples per channel.
335
+ *
336
+ * Direct mapping to AVFrame->nb_samples.
337
+ */
338
+ get nbSamples() {
339
+ return this.native.nbSamples;
340
+ }
341
+ set nbSamples(value) {
342
+ this.native.nbSamples = value;
343
+ }
344
+ /**
345
+ * Presentation timestamp.
346
+ *
347
+ * Time when the frame should be presented.
348
+ * In time base units. AV_NOPTS_VALUE if unknown.
349
+ *
350
+ * Direct mapping to AVFrame->pts.
351
+ */
352
+ get pts() {
353
+ return this.native.pts;
354
+ }
355
+ set pts(value) {
356
+ this.native.pts = value;
357
+ }
358
+ /**
359
+ * DTS from the packet that produced this frame.
360
+ *
361
+ * Copy of packet DTS for reference.
362
+ * In time base units. AV_NOPTS_VALUE if unknown.
363
+ *
364
+ * Direct mapping to AVFrame->pkt_dts.
365
+ */
366
+ get pktDts() {
367
+ return this.native.pktDts;
368
+ }
369
+ set pktDts(value) {
370
+ this.native.pktDts = value;
371
+ }
372
+ /**
373
+ * Best effort timestamp.
374
+ *
375
+ * Frame timestamp estimated using various heuristics.
376
+ * In time base units.
377
+ *
378
+ * Direct mapping to AVFrame->best_effort_timestamp.
379
+ */
380
+ get bestEffortTimestamp() {
381
+ return this.native.bestEffortTimestamp;
382
+ }
383
+ set bestEffortTimestamp(value) {
384
+ this.native.bestEffortTimestamp = value;
385
+ }
386
+ /**
387
+ * Time base for timestamps.
388
+ *
389
+ * Defines the unit of the timestamps (seconds per tick).
390
+ *
391
+ * Direct mapping to AVFrame->time_base.
392
+ */
393
+ get timeBase() {
394
+ const tb = this.native.timeBase;
395
+ return new Rational(tb.num, tb.den);
396
+ }
397
+ set timeBase(value) {
398
+ this.native.timeBase = { num: value.num, den: value.den };
399
+ }
400
+ /**
401
+ * Whether this frame is a keyframe.
402
+ *
403
+ * 1 if keyframe, 0 otherwise.
404
+ *
405
+ * Direct mapping to AVFrame->key_frame.
406
+ */
407
+ get keyFrame() {
408
+ return this.native.keyFrame;
409
+ }
410
+ set keyFrame(value) {
411
+ this.native.keyFrame = value;
412
+ }
413
+ /**
414
+ * Picture type of the frame.
415
+ *
416
+ * Type of frame (I, P, B, etc.).
417
+ *
418
+ * Direct mapping to AVFrame->pict_type.
419
+ */
420
+ get pictType() {
421
+ return this.native.pictType;
422
+ }
423
+ set pictType(value) {
424
+ this.native.pictType = value;
425
+ }
426
+ /**
427
+ * Quality (between 1 (good) and FF_LAMBDA_MAX (bad)).
428
+ *
429
+ * Set by libavcodec for some coded frames.
430
+ * Can be set before encoding to specify desired quality for encoders that support it.
431
+ * Used by FFmpeg CLI's frame_encode() to propagate encoder's global_quality setting.
432
+ *
433
+ * Direct mapping to AVFrame->quality.
434
+ */
435
+ get quality() {
436
+ return this.native.quality;
437
+ }
438
+ set quality(value) {
439
+ this.native.quality = value;
440
+ }
441
+ /**
442
+ * Sample aspect ratio.
443
+ *
444
+ * Pixel width/height ratio. 0/1 if unknown.
445
+ *
446
+ * Direct mapping to AVFrame->sample_aspect_ratio.
447
+ */
448
+ get sampleAspectRatio() {
449
+ const sar = this.native.sampleAspectRatio;
450
+ return new Rational(sar.num || 0, sar.den || 1);
451
+ }
452
+ set sampleAspectRatio(value) {
453
+ this.native.sampleAspectRatio = { num: value.num, den: value.den };
454
+ }
455
+ /**
456
+ * Audio sample rate.
457
+ *
458
+ * Number of samples per second.
459
+ *
460
+ * Direct mapping to AVFrame->sample_rate.
461
+ */
462
+ get sampleRate() {
463
+ return this.native.sampleRate;
464
+ }
465
+ set sampleRate(value) {
466
+ this.native.sampleRate = value;
467
+ }
468
+ /**
469
+ * Audio channel layout.
470
+ *
471
+ * Describes the channel configuration.
472
+ *
473
+ * Direct mapping to AVFrame->ch_layout.
474
+ */
475
+ get channelLayout() {
476
+ return this.native.channelLayout;
477
+ }
478
+ set channelLayout(value) {
479
+ this.native.channelLayout = value;
480
+ }
481
+ /**
482
+ * Number of audio channels.
483
+ *
484
+ * Derived from channel layout.
485
+ */
486
+ get channels() {
487
+ return this.native.channels;
488
+ }
489
+ /**
490
+ * Line sizes for each plane.
491
+ *
492
+ * Number of bytes per line for each data plane.
493
+ *
494
+ * Direct mapping to AVFrame->linesize.
495
+ */
496
+ get linesize() {
497
+ return this.native.linesize;
498
+ }
499
+ /**
500
+ * Color range.
501
+ *
502
+ * MPEG (limited) or JPEG (full) range.
503
+ *
504
+ * Direct mapping to AVFrame->color_range.
505
+ */
506
+ get colorRange() {
507
+ return this.native.colorRange;
508
+ }
509
+ set colorRange(value) {
510
+ this.native.colorRange = value;
511
+ }
512
+ /**
513
+ * Color primaries.
514
+ *
515
+ * Chromaticity coordinates of the source primaries.
516
+ *
517
+ * Direct mapping to AVFrame->color_primaries.
518
+ */
519
+ get colorPrimaries() {
520
+ return this.native.colorPrimaries;
521
+ }
522
+ set colorPrimaries(value) {
523
+ this.native.colorPrimaries = value;
524
+ }
525
+ /**
526
+ * Color transfer characteristic.
527
+ *
528
+ * Transfer function (gamma).
529
+ *
530
+ * Direct mapping to AVFrame->color_trc.
531
+ */
532
+ get colorTrc() {
533
+ return this.native.colorTrc;
534
+ }
535
+ set colorTrc(value) {
536
+ this.native.colorTrc = value;
537
+ }
538
+ /**
539
+ * YUV color space.
540
+ *
541
+ * Color space type for YUV content.
542
+ *
543
+ * Direct mapping to AVFrame->colorspace.
544
+ */
545
+ get colorSpace() {
546
+ return this.native.colorSpace;
547
+ }
548
+ set colorSpace(value) {
549
+ this.native.colorSpace = value;
550
+ }
551
+ /**
552
+ * Chroma sample location.
553
+ *
554
+ * Position of chroma samples.
555
+ *
556
+ * Direct mapping to AVFrame->chroma_location.
557
+ */
558
+ get chromaLocation() {
559
+ return this.native.chromaLocation;
560
+ }
561
+ set chromaLocation(value) {
562
+ this.native.chromaLocation = value;
563
+ }
564
+ /**
565
+ * Alpha channel mode.
566
+ *
567
+ * Specifies how the alpha channel relates to color values.
568
+ *
569
+ * Direct mapping to AVFrame->alpha_mode.
570
+ */
571
+ get alphaMode() {
572
+ return this.native.alphaMode;
573
+ }
574
+ set alphaMode(value) {
575
+ this.native.alphaMode = value;
576
+ }
577
+ /**
578
+ * Raw frame data planes.
579
+ *
580
+ * Array of buffers containing the frame data.
581
+ * One buffer per plane (e.g., Y, U, V for YUV420P).
582
+ *
583
+ * Direct mapping to AVFrame->data.
584
+ */
585
+ get data() {
586
+ return this.native.data;
587
+ }
588
+ /**
589
+ * Extended data planes.
590
+ *
591
+ * For audio with >8 channels or planar audio.
592
+ * Points to data planes beyond the first 8.
593
+ *
594
+ * Direct mapping to AVFrame->extended_data.
595
+ */
596
+ get extendedData() {
597
+ return this.native.extendedData;
598
+ }
599
+ /**
600
+ * Check if frame data is writable.
601
+ *
602
+ * True if the frame data can be modified.
603
+ */
604
+ get isWritable() {
605
+ return this.native.isWritable;
606
+ }
607
+ /**
608
+ * Bytes of native buffer memory this frame currently reports to V8's GC via
609
+ * `napi_adjust_external_memory`. Exposed only so the accounting can be
610
+ * asserted in tests; the value is not observable through V8 heap statistics.
611
+ *
612
+ * @internal
613
+ */
614
+ get reportedExternalMemory() {
615
+ return this.native.reportedExternalMemory;
616
+ }
617
+ /**
618
+ * Hardware frames context.
619
+ *
620
+ * Reference to hardware frames context for GPU frames.
621
+ * Null for software frames.
622
+ *
623
+ * Direct mapping to AVFrame->hw_frames_ctx.
624
+ */
625
+ get hwFramesCtx() {
626
+ // Not cached: the frame's hw_frames_ctx changes across unref()/reuse, and the
627
+ // native wrapper holds its own AVBufferRef, so a fresh wrapper per access is safe
628
+ const native = this.native.hwFramesCtx;
629
+ if (!native) {
630
+ return null;
631
+ }
632
+ const frames = Object.create(HardwareFramesContext.prototype);
633
+ frames.native = native;
634
+ return frames;
635
+ }
636
+ set hwFramesCtx(value) {
637
+ this.native.hwFramesCtx = value?.getNative() ?? null;
638
+ }
639
+ /**
640
+ * Frame flags.
641
+ *
642
+ * Combination of AVFrameFlags (e.g., AV_FRAME_FLAG_CORRUPT, AV_FRAME_FLAG_KEY).
643
+ *
644
+ * Direct mapping to AVFrame->flags.
645
+ */
646
+ get flags() {
647
+ return this.native.flags;
648
+ }
649
+ set flags(value) {
650
+ this.native.flags = value;
651
+ }
652
+ /**
653
+ * Decode error flags.
654
+ *
655
+ * Indicates errors detected during decoding.
656
+ * Non-zero value means the frame may be corrupted.
657
+ *
658
+ * Direct mapping to AVFrame->decode_error_flags.
659
+ */
660
+ get decodeErrorFlags() {
661
+ return this.native.decodeErrorFlags;
662
+ }
663
+ set decodeErrorFlags(value) {
664
+ this.native.decodeErrorFlags = value;
665
+ }
666
+ /**
667
+ * Frame duration.
668
+ *
669
+ * Duration of this frame in units of time_base.
670
+ * This is FFmpeg's best guess for how long the frame should be displayed.
671
+ * May be 0 if unknown or unavailable.
672
+ *
673
+ * Direct mapping to AVFrame->duration.
674
+ */
675
+ get duration() {
676
+ return this.native.duration;
677
+ }
678
+ set duration(value) {
679
+ this.native.duration = value;
680
+ }
681
+ /**
682
+ * Number of fields in this frame that should be repeated.
683
+ *
684
+ * For interlaced video, indicates how many times the frame should be repeated
685
+ * when displayed. For progressive video, this is typically 0.
686
+ * Formula: display_time = (repeat_pict / (2*fps))
687
+ *
688
+ * Direct mapping to AVFrame->repeat_pict.
689
+ */
690
+ get repeatPict() {
691
+ return this.native.repeatPict;
692
+ }
693
+ set repeatPict(value) {
694
+ this.native.repeatPict = value;
695
+ }
696
+ /**
697
+ * Set frame flags.
698
+ *
699
+ * Sets one or more flags using bitwise OR. Allows setting multiple flags
700
+ * without manually performing bitwise operations.
701
+ *
702
+ * @param flags - One or more flag values to set
703
+ *
704
+ * @example
705
+ * ```typescript
706
+ * import { AV_FRAME_FLAG_KEY } from 'node-av/constants';
707
+ *
708
+ * // Mark frame as key frame
709
+ * frame.setFlags(AV_FRAME_FLAG_KEY);
710
+ * ```
711
+ *
712
+ * @see {@link clearFlags} To unset flags
713
+ * @see {@link hasFlags} To check flags
714
+ * @see {@link flags} For direct flag access
715
+ */
716
+ setFlags(...flags) {
717
+ for (const flag of flags) {
718
+ this.native.flags |= flag;
719
+ }
720
+ }
721
+ /**
722
+ * Clear frame flags.
723
+ *
724
+ * Clears one or more flags using bitwise AND NOT. Allows clearing multiple
725
+ * flags without manually performing bitwise operations.
726
+ *
727
+ * @param flags - One or more flag values to clear
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * import { AV_FRAME_FLAG_CORRUPT } from 'node-av/constants';
732
+ *
733
+ * // Clear corrupt flag
734
+ * frame.clearFlags(AV_FRAME_FLAG_CORRUPT);
735
+ * ```
736
+ *
737
+ * @see {@link setFlags} To set flags
738
+ * @see {@link hasFlags} To check flags
739
+ * @see {@link flags} For direct flag access
740
+ */
741
+ clearFlags(...flags) {
742
+ for (const flag of flags) {
743
+ this.native.flags &= ~flag;
744
+ }
745
+ }
746
+ /**
747
+ * Check if frame has specific flags.
748
+ *
749
+ * Tests whether all specified flags are set using bitwise AND.
750
+ *
751
+ * @param flags - One or more flag values to check
752
+ *
753
+ * @returns true if all specified flags are set, false otherwise
754
+ *
755
+ * @example
756
+ * ```typescript
757
+ * import { AV_FRAME_FLAG_CORRUPT } from 'node-av/constants';
758
+ *
759
+ * if (frame.hasFlags(AV_FRAME_FLAG_CORRUPT)) {
760
+ * console.log('Frame is corrupted');
761
+ * }
762
+ * ```
763
+ *
764
+ * @see {@link setFlags} To set flags
765
+ * @see {@link clearFlags} To unset flags
766
+ * @see {@link flags} For direct flag access
767
+ */
768
+ hasFlags(...flags) {
769
+ for (const flag of flags) {
770
+ if ((this.native.flags & flag) !== flag) {
771
+ return false;
772
+ }
773
+ }
774
+ return true;
775
+ }
776
+ /**
777
+ * Check if frame has decode errors.
778
+ *
779
+ * Tests whether all specified decode error flags are set using bitwise AND.
780
+ *
781
+ * @param flags - One or more decode error flag values to check
782
+ *
783
+ * @returns true if all specified error flags are set, false otherwise
784
+ *
785
+ * @example
786
+ * ```typescript
787
+ * import { FF_DECODE_ERROR_INVALID_BITSTREAM } from 'node-av/constants';
788
+ *
789
+ * if (frame.hasDecodeErrorFlags(FF_DECODE_ERROR_INVALID_BITSTREAM)) {
790
+ * console.log('Frame has invalid bitstream error');
791
+ * }
792
+ * ```
793
+ *
794
+ * @see {@link decodeErrorFlags} For direct error flag access
795
+ */
796
+ hasDecodeErrorFlags(...flags) {
797
+ for (const flag of flags) {
798
+ if ((this.native.decodeErrorFlags & flag) !== flag) {
799
+ return false;
800
+ }
801
+ }
802
+ return true;
803
+ }
804
+ /**
805
+ * Check if this is a video frame.
806
+ *
807
+ * Video frames have width and height > 0.
808
+ *
809
+ * @returns true if this is a video frame
810
+ *
811
+ * @example
812
+ * ```typescript
813
+ * if (frame.isVideo()) {
814
+ * console.log(`Video frame: ${frame.width}x${frame.height}`);
815
+ * }
816
+ * ```
817
+ */
818
+ isVideo() {
819
+ return this.width > 0 && this.height > 0;
820
+ }
821
+ /**
822
+ * Check if this is an audio frame.
823
+ *
824
+ * Audio frames have sampleRate > 0 and nbSamples > 0.
825
+ *
826
+ * @returns true if this is an audio frame
827
+ *
828
+ * @example
829
+ * ```typescript
830
+ * if (frame.isAudio()) {
831
+ * console.log(`Audio frame: ${frame.sampleRate}Hz, ${frame.nbSamples} samples`);
832
+ * }
833
+ * ```
834
+ */
835
+ isAudio() {
836
+ return this.sampleRate > 0 && this.nbSamples > 0;
837
+ }
838
+ /**
839
+ * Get the media type of this frame.
840
+ *
841
+ * @returns AVMEDIA_TYPE_VIDEO for video frames, AVMEDIA_TYPE_AUDIO for audio frames, or AVMEDIA_TYPE_UNKNOWN
842
+ *
843
+ * @example
844
+ * ```typescript
845
+ * const type = frame.getMediaType();
846
+ * console.log(`Frame type: ${type}`);
847
+ * ```
848
+ */
849
+ getMediaType() {
850
+ if (this.isVideo())
851
+ return AVMEDIA_TYPE_VIDEO;
852
+ if (this.isAudio())
853
+ return AVMEDIA_TYPE_AUDIO;
854
+ return AVMEDIA_TYPE_UNKNOWN;
855
+ }
856
+ /**
857
+ * Allocate a new frame.
858
+ *
859
+ * Allocates the frame structure. Must be called before using the frame
860
+ * unless it was created by another function (e.g., clone()).
861
+ *
862
+ * Direct mapping to av_frame_alloc().
863
+ *
864
+ * @throws {Error} If allocation fails (ENOMEM)
865
+ *
866
+ * @example
867
+ * ```typescript
868
+ * const frame = new Frame();
869
+ * frame.alloc();
870
+ * // Frame structure is now ready
871
+ * ```
872
+ *
873
+ * @see {@link allocBuffer} To allocate data buffers
874
+ * @see {@link free} To deallocate the frame
875
+ */
876
+ alloc() {
877
+ this.native.alloc();
878
+ }
879
+ /**
880
+ * Free the frame.
881
+ *
882
+ * Deallocates the frame and its data. The frame becomes invalid after this.
883
+ *
884
+ * Direct mapping to av_frame_free().
885
+ *
886
+ * @example
887
+ * ```typescript
888
+ * frame.free();
889
+ * // Frame is now invalid
890
+ * ```
891
+ *
892
+ * @see {@link unref} To only free data, keeping structure
893
+ */
894
+ free() {
895
+ this.native.free();
896
+ }
897
+ /**
898
+ * Create a reference to another frame.
899
+ *
900
+ * Sets up this frame as a reference to the source frame's data.
901
+ * Both frames will share the same data buffers.
902
+ *
903
+ * Direct mapping to av_frame_ref().
904
+ *
905
+ * IMPORTANT: per FFmpeg's contract, this frame (the destination) MUST be
906
+ * unreferenced or freshly allocated before calling. Re-using a frame as the
907
+ * destination without {@link unref} first leaks its previous buffers (the old
908
+ * references are overwritten, not freed). When reusing one frame across a loop,
909
+ * call `frame.unref()` before each `frame.ref(src)`.
910
+ *
911
+ * @param src - Source frame to reference
912
+ *
913
+ * @returns 0 on success, negative AVERROR on error:
914
+ * - AVERROR_ENOMEM: Memory allocation failure
915
+ * - AVERROR_EINVAL: Invalid parameters
916
+ *
917
+ * @example
918
+ * ```typescript
919
+ * import { FFmpegError } from 'node-av';
920
+ *
921
+ * // Reusing one frame across a loop: unref before re-referencing.
922
+ * frame2.unref();
923
+ * const ret = frame2.ref(frame1);
924
+ * FFmpegError.throwIfError(ret, 'ref');
925
+ * // frame2 now references frame1's data
926
+ * ```
927
+ *
928
+ * @see {@link unref} To remove reference (call before re-referencing a reused frame)
929
+ * @see {@link clone} To create independent copy
930
+ */
931
+ ref(src) {
932
+ return this.native.ref(src.getNative());
933
+ }
934
+ /**
935
+ * Unreference the frame.
936
+ *
937
+ * Frees the frame data if this was the last reference.
938
+ * The frame structure remains allocated and can be reused.
939
+ *
940
+ * Direct mapping to av_frame_unref().
941
+ *
942
+ * @example
943
+ * ```typescript
944
+ * frame.unref();
945
+ * // Frame data is freed, structure can be reused
946
+ * ```
947
+ *
948
+ * @see {@link ref} To create reference
949
+ * @see {@link free} To free everything
950
+ */
951
+ unref() {
952
+ this.native.unref();
953
+ }
954
+ /**
955
+ * Clone the frame.
956
+ *
957
+ * Creates an independent copy of the frame with its own data buffers.
958
+ * The new frame has the same content but can be modified independently.
959
+ *
960
+ * Direct mapping to av_frame_clone().
961
+ *
962
+ * @returns New frame instance, or null on allocation failure
963
+ *
964
+ * @example
965
+ * ```typescript
966
+ * const copy = frame.clone();
967
+ * if (copy) {
968
+ * // Modify copy without affecting original
969
+ * copy.pts = frame.pts + 1000n;
970
+ * }
971
+ * ```
972
+ *
973
+ * @see {@link ref} To create reference instead of copy
974
+ * @see {@link copy} To copy into existing frame
975
+ */
976
+ clone() {
977
+ const cloned = this.native.clone();
978
+ if (!cloned) {
979
+ return null;
980
+ }
981
+ // Wrap the native cloned frame
982
+ const frame = Object.create(Frame.prototype);
983
+ frame.native = cloned;
984
+ return frame;
985
+ }
986
+ /**
987
+ * Allocate data buffers for the frame.
988
+ *
989
+ * Allocates buffers based on frame parameters.
990
+ * Must set format, width/height (video) or format, nb_samples, channel_layout (audio) first.
991
+ *
992
+ * Direct mapping to av_frame_get_buffer().
993
+ *
994
+ * @param align - Buffer size alignment (0 for default)
995
+ *
996
+ * @returns 0 on success, negative AVERROR on error:
997
+ * - AVERROR_EINVAL: Invalid frame parameters
998
+ * - AVERROR_ENOMEM: Memory allocation failure
999
+ *
1000
+ * @example
1001
+ * ```typescript
1002
+ * import { FFmpegError } from 'node-av';
1003
+ *
1004
+ * const ret = frame.getBuffer();
1005
+ * FFmpegError.throwIfError(ret, 'getBuffer');
1006
+ * ```
1007
+ *
1008
+ * @see {@link allocBuffer} Equivalent without alignment parameter
1009
+ */
1010
+ getBuffer(align = 0) {
1011
+ return this.native.getBuffer(align);
1012
+ }
1013
+ /**
1014
+ * Allocate data buffers for the frame.
1015
+ *
1016
+ * Allocates buffers based on frame format and dimensions.
1017
+ * Frame parameters must be set before calling.
1018
+ *
1019
+ * Direct mapping to av_frame_get_buffer().
1020
+ *
1021
+ * @returns 0 on success, negative AVERROR on error:
1022
+ * - AVERROR_EINVAL: Invalid frame parameters
1023
+ * - AVERROR_ENOMEM: Memory allocation failure
1024
+ *
1025
+ * @example
1026
+ * ```typescript
1027
+ * import { FFmpegError } from 'node-av';
1028
+ * import { AV_PIX_FMT_YUV420P } from 'node-av/constants';
1029
+ *
1030
+ * frame.format = AV_PIX_FMT_YUV420P;
1031
+ * frame.width = 1920;
1032
+ * frame.height = 1080;
1033
+ * const ret = frame.allocBuffer();
1034
+ * FFmpegError.throwIfError(ret, 'allocBuffer');
1035
+ * ```
1036
+ *
1037
+ * @see {@link getBuffer} Equivalent with an alignment parameter
1038
+ */
1039
+ allocBuffer() {
1040
+ return this.native.allocBuffer();
1041
+ }
1042
+ /**
1043
+ * Ensure frame data is writable.
1044
+ *
1045
+ * Creates a private copy of the data if it's shared with other frames.
1046
+ * Call before modifying frame data to avoid affecting other references.
1047
+ *
1048
+ * Direct mapping to av_frame_make_writable().
1049
+ *
1050
+ * @returns 0 on success, negative AVERROR on error:
1051
+ * - AVERROR_ENOMEM: Memory allocation failure
1052
+ * - AVERROR_EINVAL: Invalid frame
1053
+ *
1054
+ * @example
1055
+ * ```typescript
1056
+ * import { FFmpegError } from 'node-av';
1057
+ *
1058
+ * // Ensure we can safely modify data
1059
+ * const ret = frame.makeWritable();
1060
+ * FFmpegError.throwIfError(ret, 'makeWritable');
1061
+ * // Now safe to modify frame.data
1062
+ * ```
1063
+ */
1064
+ makeWritable() {
1065
+ return this.native.makeWritable();
1066
+ }
1067
+ /**
1068
+ * Copy non-layout frame properties without copying data.
1069
+ *
1070
+ * Copies metadata like timestamp, duration, etc., but not the actual data.
1071
+ * Layout-defining properties, such as width, height, channel count, format, etc., are not copied.
1072
+ * Useful for preparing output frames with same properties.
1073
+ *
1074
+ * Direct mapping to av_frame_copy_props().
1075
+ *
1076
+ * @param src - Source frame to copy properties from
1077
+ *
1078
+ * @returns 0 on success, negative AVERROR on error:
1079
+ * - AVERROR_ENOMEM: Memory allocation failure
1080
+ *
1081
+ * @example
1082
+ * ```typescript
1083
+ * import { FFmpegError } from 'node-av';
1084
+ *
1085
+ * const ret = dstFrame.copyProps(srcFrame);
1086
+ * FFmpegError.throwIfError(ret, 'copyProps');
1087
+ * // dstFrame now has same non-layout properties as srcFrame
1088
+ * ```
1089
+ *
1090
+ * @see {@link copy} To copy data
1091
+ */
1092
+ copyProps(src) {
1093
+ return this.native.copyProps(src.getNative());
1094
+ }
1095
+ /**
1096
+ * Copy frame data.
1097
+ *
1098
+ * Copies only data (but not metadata) from source frame.
1099
+ * Destination must have allocated buffers of correct size.
1100
+ *
1101
+ * Direct mapping to av_frame_copy().
1102
+ *
1103
+ * @param src - Source frame to copy from
1104
+ *
1105
+ * @returns 0 on success, negative AVERROR on error:
1106
+ * - AVERROR_EINVAL: Incompatible frames
1107
+ *
1108
+ * @example
1109
+ * ```typescript
1110
+ * import { FFmpegError } from 'node-av';
1111
+ *
1112
+ * // Allocate destination with same format
1113
+ * dstFrame.format = srcFrame.format;
1114
+ * dstFrame.width = srcFrame.width;
1115
+ * dstFrame.height = srcFrame.height;
1116
+ * dstFrame.allocBuffer();
1117
+ *
1118
+ * const ret = dstFrame.copy(srcFrame);
1119
+ * FFmpegError.throwIfError(ret, 'copy');
1120
+ * ```
1121
+ *
1122
+ * @see {@link copyProps} To copy non-format metadata
1123
+ * @see {@link clone} To create new frame with copy
1124
+ */
1125
+ copy(src) {
1126
+ return this.native.copy(src.getNative());
1127
+ }
1128
+ /**
1129
+ * Fill frame data from buffer.
1130
+ *
1131
+ * Copies data from buffer into frame-owned data planes; the frame never
1132
+ * references the source buffer, so it may be reused or garbage collected
1133
+ * afterwards. Allocates the frame's buffers if not already allocated.
1134
+ *
1135
+ * @param buffer - Source buffer with frame data
1136
+ *
1137
+ * @returns 0 on success, negative AVERROR on error:
1138
+ * - AVERROR_EINVAL: Invalid parameters
1139
+ *
1140
+ * @example
1141
+ * ```typescript
1142
+ * import { FFmpegError } from 'node-av';
1143
+ *
1144
+ * const buffer = Buffer.from(rawVideoData);
1145
+ * const ret = frame.fromBuffer(buffer);
1146
+ * FFmpegError.throwIfError(ret, 'fromBuffer');
1147
+ * ```
1148
+ */
1149
+ fromBuffer(buffer) {
1150
+ return this.native.fromBuffer(buffer);
1151
+ }
1152
+ /**
1153
+ * Convert frame data to buffer.
1154
+ *
1155
+ * Copies frame data into a single contiguous buffer.
1156
+ * For video frames, converts all planes into packed format.
1157
+ * For audio frames, handles both planar and interleaved formats.
1158
+ * Cannot be used with hardware frames - use hwframeTransferData first.
1159
+ *
1160
+ * @param output - Optional Buffer to copy into instead of allocating one; it must hold at least the frame's size and must not overlap the frame's data
1161
+ *
1162
+ * @returns Buffer containing frame data (a view of `output` when given)
1163
+ *
1164
+ * @throws {Error} If frame is not allocated, has no data, or is a hardware frame
1165
+ *
1166
+ * @throws {TypeError} If `output` is not a Buffer or is smaller than the frame data
1167
+ *
1168
+ * @example Video frame to buffer
1169
+ * ```typescript
1170
+ * // Get YUV420P video frame as buffer
1171
+ * const buffer = frame.toBuffer();
1172
+ * console.log(`Frame buffer size: ${buffer.length} bytes`);
1173
+ * // Buffer contains Y plane, then U plane, then V plane
1174
+ * ```
1175
+ *
1176
+ * @example Audio frame to buffer
1177
+ * ```typescript
1178
+ * // Get audio samples as buffer
1179
+ * const audioBuffer = frame.toBuffer();
1180
+ * console.log(`Audio buffer size: ${audioBuffer.length} bytes`);
1181
+ * // For planar audio: channel 0 samples, then channel 1 samples, etc.
1182
+ * // For interleaved audio: sample0_ch0, sample0_ch1, sample1_ch0, sample1_ch1, etc.
1183
+ * ```
1184
+ *
1185
+ * @example Error handling
1186
+ * ```typescript
1187
+ * try {
1188
+ * const buffer = frame.toBuffer();
1189
+ * // Process buffer...
1190
+ * } catch (error) {
1191
+ * if (frame.isHwFrame()) {
1192
+ * // Transfer to software first
1193
+ * const swFrame = new Frame();
1194
+ * swFrame.alloc();
1195
+ * await frame.hwframeTransferData(swFrame);
1196
+ * const buffer = swFrame.toBuffer();
1197
+ * }
1198
+ * }
1199
+ * ```
1200
+ *
1201
+ * @see {@link fromBuffer} To create frame from buffer
1202
+ * @see {@link hwframeTransferData} To transfer hardware frames to software
1203
+ * @see {@link isHwFrame} To check if frame is hardware
1204
+ * @see {@link data} To access individual planes
1205
+ */
1206
+ toBuffer(output) {
1207
+ // The native side accepts any Uint8Array, but the result would then not be a Buffer
1208
+ if (output !== undefined && !Buffer.isBuffer(output)) {
1209
+ throw new TypeError('output must be a Buffer');
1210
+ }
1211
+ return this.native.toBuffer(output);
1212
+ }
1213
+ /**
1214
+ * Transfer data between hardware and software frames.
1215
+ *
1216
+ * Copies frame data between GPU and system memory.
1217
+ * Direction depends on source and destination frame types.
1218
+ *
1219
+ * Direct mapping to av_hwframe_transfer_data().
1220
+ *
1221
+ * @param dst - Destination frame (software or hardware)
1222
+ *
1223
+ * @param flags - Transfer flags (0 for default)
1224
+ *
1225
+ * @returns 0 on success, negative AVERROR on error:
1226
+ * - AVERROR_EINVAL: Invalid parameters
1227
+ * - AVERROR_ENOMEM: Memory allocation failure
1228
+ *
1229
+ * @example
1230
+ * ```typescript
1231
+ * import { FFmpegError } from 'node-av';
1232
+ *
1233
+ * // Download from GPU to CPU
1234
+ * const swFrame = new Frame();
1235
+ * swFrame.alloc();
1236
+ * const ret = await hwFrame.hwframeTransferData(swFrame);
1237
+ * FFmpegError.throwIfError(ret, 'hwframeTransferData');
1238
+ * ```
1239
+ *
1240
+ * @see {@link isHwFrame} To check if frame is hardware
1241
+ * @see {@link isSwFrame} To check if frame is software
1242
+ */
1243
+ async hwframeTransferData(dst, flags) {
1244
+ return await this.native.hwframeTransferData(dst.getNative(), flags ?? 0);
1245
+ }
1246
+ /**
1247
+ * Transfer data between hardware and software frames synchronously.
1248
+ * Synchronous version of hwframeTransferData.
1249
+ *
1250
+ * Copies frame data between GPU and system memory.
1251
+ * Direction depends on source and destination frame types.
1252
+ *
1253
+ * Direct mapping to av_hwframe_transfer_data().
1254
+ *
1255
+ * @param dst - Destination frame (software or hardware)
1256
+ *
1257
+ * @param flags - Transfer flags (0 for default)
1258
+ *
1259
+ * @returns 0 on success, negative AVERROR on error:
1260
+ * - AVERROR_EINVAL: Invalid parameters
1261
+ * - AVERROR_ENOMEM: Memory allocation failure
1262
+ *
1263
+ * @example
1264
+ * ```typescript
1265
+ * import { FFmpegError } from 'node-av';
1266
+ *
1267
+ * // Download from GPU to CPU
1268
+ * const swFrame = new Frame();
1269
+ * swFrame.alloc();
1270
+ * const ret = hwFrame.hwframeTransferData(swFrame);
1271
+ * FFmpegError.throwIfError(ret, 'hwframeTransferData');
1272
+ * ```
1273
+ *
1274
+ * @see {@link hwframeTransferData} For async version
1275
+ */
1276
+ hwframeTransferDataSync(dst, flags) {
1277
+ return this.native.hwframeTransferDataSync(dst.getNative(), flags ?? 0);
1278
+ }
1279
+ /**
1280
+ * Check if this is a hardware frame.
1281
+ *
1282
+ * Returns true if frame data is in GPU memory.
1283
+ *
1284
+ * @returns True if hardware frame, false otherwise
1285
+ *
1286
+ * @example
1287
+ * ```typescript
1288
+ * if (frame.isHwFrame()) {
1289
+ * console.log('Frame is in GPU memory');
1290
+ * }
1291
+ * ```
1292
+ *
1293
+ * @see {@link isSwFrame} To check for software frame
1294
+ * @see {@link hwframeTransferData} To transfer between GPU/CPU
1295
+ */
1296
+ isHwFrame() {
1297
+ return this.native.isHwFrame();
1298
+ }
1299
+ /**
1300
+ * Check if this is a software frame.
1301
+ *
1302
+ * Returns true if frame data is in system memory.
1303
+ *
1304
+ * @returns True if software frame, false otherwise
1305
+ *
1306
+ * @example
1307
+ * ```typescript
1308
+ * if (frame.isSwFrame()) {
1309
+ * console.log('Frame is in system memory');
1310
+ * }
1311
+ * ```
1312
+ *
1313
+ * @see {@link isHwFrame} To check for hardware frame
1314
+ * @see {@link hwframeTransferData} To transfer between GPU/CPU
1315
+ */
1316
+ isSwFrame() {
1317
+ return this.native.isSwFrame();
1318
+ }
1319
+ /**
1320
+ * Export the IOSurface backing a decoded VideoToolbox frame (macOS only).
1321
+ *
1322
+ * Returns the `IOSurfaceRef` carried by an `AV_PIX_FMT_VIDEOTOOLBOX` frame as
1323
+ * an 8-byte pointer Buffer — the same handle format accepted by
1324
+ * {@link Frame.fromIOSurface}. This enables zero-copy interop with Metal /
1325
+ * CoreVideo (e.g. feeding a hardware-decoded frame into a GPU compositor)
1326
+ * without a GPU→CPU readback.
1327
+ *
1328
+ * Returns `null` when the frame is not a decoded VideoToolbox hardware frame,
1329
+ * has no backing IOSurface, or on non-macOS platforms.
1330
+ *
1331
+ * **Lifetime:** the IOSurface stays owned by the frame's `CVPixelBuffer`.
1332
+ * Keep this `Frame` alive while using the handle. If the surface must outlive
1333
+ * the frame, retain it separately (e.g. `IOSurfaceIncrementUseCount`).
1334
+ *
1335
+ * @returns IOSurfaceRef pointer as Buffer, or null if not available
1336
+ *
1337
+ * @example
1338
+ * ```typescript
1339
+ * const handle = frame.exportIOSurface();
1340
+ * if (handle) {
1341
+ * // Pass to a Metal-based compositor; keep `frame` alive while in use.
1342
+ * }
1343
+ * ```
1344
+ *
1345
+ * @see {@link fromIOSurface} For the inverse (import) direction
1346
+ */
1347
+ exportIOSurface() {
1348
+ return this.native.exportIOSurface();
1349
+ }
1350
+ /**
1351
+ * Get frame side data.
1352
+ *
1353
+ * Retrieves additional data associated with the frame
1354
+ * (e.g., motion vectors, film grain, HDR metadata).
1355
+ *
1356
+ * Direct mapping to av_frame_get_side_data().
1357
+ *
1358
+ * @param type - Type of side data to retrieve
1359
+ *
1360
+ * @returns Side data buffer, or null if not present
1361
+ *
1362
+ * @example
1363
+ * ```typescript
1364
+ * import { AV_FRAME_DATA_MOTION_VECTORS } from 'node-av/constants';
1365
+ *
1366
+ * const motionVectors = frame.getSideData(AV_FRAME_DATA_MOTION_VECTORS);
1367
+ * if (motionVectors) {
1368
+ * console.log(`Motion data size: ${motionVectors.length} bytes`);
1369
+ * }
1370
+ * ```
1371
+ *
1372
+ * @see {@link newSideData} To add side data
1373
+ * @see {@link removeSideData} To remove side data
1374
+ */
1375
+ getSideData(type) {
1376
+ return this.native.getSideData(type);
1377
+ }
1378
+ /**
1379
+ * Allocate new side data.
1380
+ *
1381
+ * Allocates side data buffer attached to the frame.
1382
+ * Returns buffer that can be written to directly.
1383
+ *
1384
+ * Direct mapping to av_frame_new_side_data().
1385
+ *
1386
+ * @param type - Type of side data
1387
+ *
1388
+ * @param size - Size in bytes to allocate
1389
+ *
1390
+ * @returns Allocated buffer for writing
1391
+ *
1392
+ * @throws {Error} If allocation fails
1393
+ *
1394
+ * @example
1395
+ * ```typescript
1396
+ * import { AV_FRAME_DATA_MASTERING_DISPLAY_METADATA } from 'node-av/constants';
1397
+ *
1398
+ * // Allocate and write HDR metadata
1399
+ * const hdrData = frame.newSideData(
1400
+ * AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
1401
+ * 40
1402
+ * );
1403
+ * // Write metadata to buffer...
1404
+ * ```
1405
+ *
1406
+ * @see {@link getSideData} To retrieve side data
1407
+ * @see {@link removeSideData} To remove side data
1408
+ */
1409
+ newSideData(type, size) {
1410
+ return this.native.newSideData(type, size);
1411
+ }
1412
+ /**
1413
+ * Remove side data from frame.
1414
+ *
1415
+ * Removes specific type of side data.
1416
+ *
1417
+ * Direct mapping to av_frame_remove_side_data().
1418
+ *
1419
+ * @param type - Type of side data to remove
1420
+ *
1421
+ * @example
1422
+ * ```typescript
1423
+ * import { AV_FRAME_DATA_MOTION_VECTORS } from 'node-av/constants';
1424
+ *
1425
+ * frame.removeSideData(AV_FRAME_DATA_MOTION_VECTORS);
1426
+ * // Motion vectors removed
1427
+ * ```
1428
+ *
1429
+ * @see {@link getSideData} To retrieve side data
1430
+ * @see {@link newSideData} To add side data
1431
+ */
1432
+ removeSideData(type) {
1433
+ this.native.removeSideData(type);
1434
+ }
1435
+ /**
1436
+ * Get frame metadata dictionary.
1437
+ *
1438
+ * Returns metadata attached to the frame by filters or demuxers.
1439
+ * Metadata is stored as key-value pairs in a Dictionary.
1440
+ * Useful for reading filter-generated metadata (e.g., whisper transcription).
1441
+ *
1442
+ * Direct mapping to AVFrame->metadata.
1443
+ *
1444
+ * @returns Dictionary containing frame metadata
1445
+ *
1446
+ * @example
1447
+ * ```typescript
1448
+ * // Read whisper filter metadata
1449
+ * const metadata = frame.getMetadata();
1450
+ * const text = metadata.get('lavfi.whisper.text');
1451
+ * const duration = metadata.get('lavfi.whisper.duration');
1452
+ *
1453
+ * if (text) {
1454
+ * console.log(`Transcribed: ${text}`);
1455
+ * console.log(`Duration: ${duration}s`);
1456
+ * }
1457
+ * ```
1458
+ *
1459
+ * @example
1460
+ * ```typescript
1461
+ * // Read scene detection metadata
1462
+ * const metadata = frame.getMetadata();
1463
+ * const score = metadata.get('lavfi.scene_score');
1464
+ * if (score) {
1465
+ * console.log(`Scene change score: ${score}`);
1466
+ * }
1467
+ * ```
1468
+ *
1469
+ * @see {@link Dictionary} For metadata dictionary operations
1470
+ */
1471
+ getMetadata() {
1472
+ return Dictionary.fromNative(this.native.getMetadata());
1473
+ }
1474
+ /**
1475
+ * Apply cropping to the frame.
1476
+ *
1477
+ * Crops the frame according to its crop metadata (AVFrame crop fields).
1478
+ * This adjusts the frame dimensions and data pointers to reflect the cropped region.
1479
+ * The cropped-out area is discarded, reducing frame size.
1480
+ *
1481
+ * Direct mapping to av_frame_apply_cropping().
1482
+ *
1483
+ * @param flags - Cropping flags (default: AV_FRAME_CROP_UNALIGNED = 1)
1484
+ * AV_FRAME_CROP_UNALIGNED allows unaligned cropping for lavfi compatibility
1485
+ *
1486
+ * @returns 0 on success, negative error code on failure
1487
+ *
1488
+ * @example
1489
+ * ```typescript
1490
+ * import { Frame, FFmpegError } from 'node-av';
1491
+ *
1492
+ * const frame = new Frame();
1493
+ * // ... decode frame with crop metadata ...
1494
+ *
1495
+ * // Apply cropping based on metadata
1496
+ * const ret = frame.applyCropping();
1497
+ * FFmpegError.throwIfError(ret, 'Failed to apply cropping');
1498
+ *
1499
+ * // Frame dimensions are now updated to cropped size
1500
+ * console.log(`Cropped to ${frame.width}x${frame.height}`);
1501
+ * ```
1502
+ */
1503
+ applyCropping(flags) {
1504
+ return this.native.applyCropping(flags);
1505
+ }
1506
+ /**
1507
+ * Get the underlying native Frame object.
1508
+ *
1509
+ * @returns The native Frame binding object
1510
+ *
1511
+ * @internal
1512
+ */
1513
+ getNative() {
1514
+ return this.native;
1515
+ }
1516
+ /**
1517
+ * Dispose of the frame.
1518
+ *
1519
+ * Implements the Disposable interface for automatic cleanup.
1520
+ * Equivalent to calling free().
1521
+ *
1522
+ * @example
1523
+ * ```typescript
1524
+ * {
1525
+ * using frame = new Frame();
1526
+ * frame.alloc();
1527
+ * // Use frame...
1528
+ * } // Automatically freed when leaving scope
1529
+ * ```
1530
+ */
1531
+ [Symbol.dispose]() {
1532
+ this.native[Symbol.dispose]();
1533
+ }
1534
+ }
1535
+ //# sourceMappingURL=frame.js.map