node-av 0.0.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 (175) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +377 -0
  4. package/binding.gyp +78 -0
  5. package/dist/api/bitstream-filter.d.ts +246 -0
  6. package/dist/api/bitstream-filter.js +369 -0
  7. package/dist/api/bitstream-filter.js.map +1 -0
  8. package/dist/api/decoder.d.ts +257 -0
  9. package/dist/api/decoder.js +424 -0
  10. package/dist/api/decoder.js.map +1 -0
  11. package/dist/api/encoder.d.ts +298 -0
  12. package/dist/api/encoder.js +574 -0
  13. package/dist/api/encoder.js.map +1 -0
  14. package/dist/api/filter.d.ts +457 -0
  15. package/dist/api/filter.js +876 -0
  16. package/dist/api/filter.js.map +1 -0
  17. package/dist/api/hardware.d.ts +318 -0
  18. package/dist/api/hardware.js +558 -0
  19. package/dist/api/hardware.js.map +1 -0
  20. package/dist/api/index.d.ts +12 -0
  21. package/dist/api/index.js +20 -0
  22. package/dist/api/index.js.map +1 -0
  23. package/dist/api/io-stream.d.ts +109 -0
  24. package/dist/api/io-stream.js +124 -0
  25. package/dist/api/io-stream.js.map +1 -0
  26. package/dist/api/media-input.d.ts +295 -0
  27. package/dist/api/media-input.js +456 -0
  28. package/dist/api/media-input.js.map +1 -0
  29. package/dist/api/media-output.d.ts +274 -0
  30. package/dist/api/media-output.js +486 -0
  31. package/dist/api/media-output.js.map +1 -0
  32. package/dist/api/pipeline.d.ts +117 -0
  33. package/dist/api/pipeline.js +836 -0
  34. package/dist/api/pipeline.js.map +1 -0
  35. package/dist/api/types.d.ts +440 -0
  36. package/dist/api/types.js +2 -0
  37. package/dist/api/types.js.map +1 -0
  38. package/dist/api/utilities/audio-sample.d.ts +115 -0
  39. package/dist/api/utilities/audio-sample.js +110 -0
  40. package/dist/api/utilities/audio-sample.js.map +1 -0
  41. package/dist/api/utilities/channel-layout.d.ts +83 -0
  42. package/dist/api/utilities/channel-layout.js +87 -0
  43. package/dist/api/utilities/channel-layout.js.map +1 -0
  44. package/dist/api/utilities/image.d.ts +177 -0
  45. package/dist/api/utilities/image.js +183 -0
  46. package/dist/api/utilities/image.js.map +1 -0
  47. package/dist/api/utilities/index.d.ts +8 -0
  48. package/dist/api/utilities/index.js +17 -0
  49. package/dist/api/utilities/index.js.map +1 -0
  50. package/dist/api/utilities/media-type.d.ts +56 -0
  51. package/dist/api/utilities/media-type.js +60 -0
  52. package/dist/api/utilities/media-type.js.map +1 -0
  53. package/dist/api/utilities/pixel-format.d.ts +94 -0
  54. package/dist/api/utilities/pixel-format.js +102 -0
  55. package/dist/api/utilities/pixel-format.js.map +1 -0
  56. package/dist/api/utilities/sample-format.d.ts +132 -0
  57. package/dist/api/utilities/sample-format.js +144 -0
  58. package/dist/api/utilities/sample-format.js.map +1 -0
  59. package/dist/api/utilities/streaming.d.ts +104 -0
  60. package/dist/api/utilities/streaming.js +137 -0
  61. package/dist/api/utilities/streaming.js.map +1 -0
  62. package/dist/api/utilities/timestamp.d.ts +187 -0
  63. package/dist/api/utilities/timestamp.js +200 -0
  64. package/dist/api/utilities/timestamp.js.map +1 -0
  65. package/dist/api/utils.d.ts +61 -0
  66. package/dist/api/utils.js +330 -0
  67. package/dist/api/utils.js.map +1 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.js +5 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/lib/audio-fifo.d.ts +339 -0
  72. package/dist/lib/audio-fifo.js +365 -0
  73. package/dist/lib/audio-fifo.js.map +1 -0
  74. package/dist/lib/binding.d.ts +192 -0
  75. package/dist/lib/binding.js +70 -0
  76. package/dist/lib/binding.js.map +1 -0
  77. package/dist/lib/bitstream-filter-context.d.ts +345 -0
  78. package/dist/lib/bitstream-filter-context.js +407 -0
  79. package/dist/lib/bitstream-filter-context.js.map +1 -0
  80. package/dist/lib/bitstream-filter.d.ts +124 -0
  81. package/dist/lib/bitstream-filter.js +138 -0
  82. package/dist/lib/bitstream-filter.js.map +1 -0
  83. package/dist/lib/channel-layouts.d.ts +51 -0
  84. package/dist/lib/channel-layouts.js +55 -0
  85. package/dist/lib/channel-layouts.js.map +1 -0
  86. package/dist/lib/codec-context.d.ts +763 -0
  87. package/dist/lib/codec-context.js +974 -0
  88. package/dist/lib/codec-context.js.map +1 -0
  89. package/dist/lib/codec-parameters.d.ts +362 -0
  90. package/dist/lib/codec-parameters.js +460 -0
  91. package/dist/lib/codec-parameters.js.map +1 -0
  92. package/dist/lib/codec-parser.d.ts +185 -0
  93. package/dist/lib/codec-parser.js +193 -0
  94. package/dist/lib/codec-parser.js.map +1 -0
  95. package/dist/lib/codec.d.ts +432 -0
  96. package/dist/lib/codec.js +492 -0
  97. package/dist/lib/codec.js.map +1 -0
  98. package/dist/lib/constants.d.ts +2037 -0
  99. package/dist/lib/constants.js +1659 -0
  100. package/dist/lib/constants.js.map +1 -0
  101. package/dist/lib/dictionary.d.ts +371 -0
  102. package/dist/lib/dictionary.js +406 -0
  103. package/dist/lib/dictionary.js.map +1 -0
  104. package/dist/lib/error.d.ts +216 -0
  105. package/dist/lib/error.js +254 -0
  106. package/dist/lib/error.js.map +1 -0
  107. package/dist/lib/filter-context.d.ts +445 -0
  108. package/dist/lib/filter-context.js +505 -0
  109. package/dist/lib/filter-context.js.map +1 -0
  110. package/dist/lib/filter-graph.d.ts +556 -0
  111. package/dist/lib/filter-graph.js +608 -0
  112. package/dist/lib/filter-graph.js.map +1 -0
  113. package/dist/lib/filter-inout.d.ts +205 -0
  114. package/dist/lib/filter-inout.js +264 -0
  115. package/dist/lib/filter-inout.js.map +1 -0
  116. package/dist/lib/filter.d.ts +231 -0
  117. package/dist/lib/filter.js +260 -0
  118. package/dist/lib/filter.js.map +1 -0
  119. package/dist/lib/format-context.d.ts +798 -0
  120. package/dist/lib/format-context.js +845 -0
  121. package/dist/lib/format-context.js.map +1 -0
  122. package/dist/lib/frame.d.ts +784 -0
  123. package/dist/lib/frame.js +933 -0
  124. package/dist/lib/frame.js.map +1 -0
  125. package/dist/lib/hardware-device-context.d.ts +407 -0
  126. package/dist/lib/hardware-device-context.js +429 -0
  127. package/dist/lib/hardware-device-context.js.map +1 -0
  128. package/dist/lib/hardware-frames-context.d.ts +374 -0
  129. package/dist/lib/hardware-frames-context.js +430 -0
  130. package/dist/lib/hardware-frames-context.js.map +1 -0
  131. package/dist/lib/index.d.ts +31 -0
  132. package/dist/lib/index.js +54 -0
  133. package/dist/lib/index.js.map +1 -0
  134. package/dist/lib/input-format.d.ts +216 -0
  135. package/dist/lib/input-format.js +246 -0
  136. package/dist/lib/input-format.js.map +1 -0
  137. package/dist/lib/io-context.d.ts +495 -0
  138. package/dist/lib/io-context.js +550 -0
  139. package/dist/lib/io-context.js.map +1 -0
  140. package/dist/lib/log.d.ts +201 -0
  141. package/dist/lib/log.js +219 -0
  142. package/dist/lib/log.js.map +1 -0
  143. package/dist/lib/native-types.d.ts +719 -0
  144. package/dist/lib/native-types.js +2 -0
  145. package/dist/lib/native-types.js.map +1 -0
  146. package/dist/lib/option.d.ts +589 -0
  147. package/dist/lib/option.js +853 -0
  148. package/dist/lib/option.js.map +1 -0
  149. package/dist/lib/output-format.d.ts +179 -0
  150. package/dist/lib/output-format.js +205 -0
  151. package/dist/lib/output-format.js.map +1 -0
  152. package/dist/lib/packet.d.ts +487 -0
  153. package/dist/lib/packet.js +558 -0
  154. package/dist/lib/packet.js.map +1 -0
  155. package/dist/lib/rational.d.ts +210 -0
  156. package/dist/lib/rational.js +233 -0
  157. package/dist/lib/rational.js.map +1 -0
  158. package/dist/lib/software-resample-context.d.ts +572 -0
  159. package/dist/lib/software-resample-context.js +610 -0
  160. package/dist/lib/software-resample-context.js.map +1 -0
  161. package/dist/lib/software-scale-context.d.ts +290 -0
  162. package/dist/lib/software-scale-context.js +308 -0
  163. package/dist/lib/software-scale-context.js.map +1 -0
  164. package/dist/lib/stream.d.ts +322 -0
  165. package/dist/lib/stream.js +408 -0
  166. package/dist/lib/stream.js.map +1 -0
  167. package/dist/lib/types.d.ts +59 -0
  168. package/dist/lib/types.js +8 -0
  169. package/dist/lib/types.js.map +1 -0
  170. package/dist/lib/utilities.d.ts +346 -0
  171. package/dist/lib/utilities.js +424 -0
  172. package/dist/lib/utilities.js.map +1 -0
  173. package/install/check.js +113 -0
  174. package/install/ffmpeg.js +163 -0
  175. package/package.json +107 -0
@@ -0,0 +1,574 @@
1
+ /**
2
+ * Encoder - High-level wrapper for media encoding
3
+ *
4
+ * Simplifies FFmpeg's encoding API with automatic codec selection,
5
+ * parameter configuration, and packet management.
6
+ *
7
+ * Handles codec initialization, frame encoding, and packet output.
8
+ * Supports hardware acceleration and zero-copy transcoding.
9
+ *
10
+ * @module api/encoder
11
+ */
12
+ import { AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, AVERROR_EAGAIN, AVERROR_EOF, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_VIDEO, Codec, CodecContext, FFmpegError, Packet, Rational, } from '../lib/index.js';
13
+ import { Stream } from '../lib/stream.js';
14
+ import { parseBitrate } from './utils.js';
15
+ /**
16
+ * High-level encoder for media streams.
17
+ *
18
+ * Handles codec initialization, frame encoding, and packet output.
19
+ * Supports various codecs with flexible configuration options.
20
+ *
21
+ * Manages codec context lifecycle and provides automatic cleanup.
22
+ * Supports hardware acceleration with shared frames context for zero-copy.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Create H.264 encoder
27
+ * const encoder = await Encoder.create('libx264', {
28
+ * width: 1920,
29
+ * height: 1080,
30
+ * pixelFormat: 'yuv420p',
31
+ * bitrate: '5M',
32
+ * gopSize: 60,
33
+ * options: {
34
+ * preset: 'fast',
35
+ * crf: 23
36
+ * }
37
+ * });
38
+ *
39
+ * // Encode frames
40
+ * const packet = await encoder.encode(frame);
41
+ * if (packet) {
42
+ * // Write packet to output
43
+ * }
44
+ *
45
+ * // Flush encoder
46
+ * let packet;
47
+ * while ((packet = await encoder.flush()) !== null) {
48
+ * // Process final packets
49
+ * }
50
+ * encoder.close();
51
+ * ```
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // With hardware acceleration
56
+ * const hw = await HardwareContext.auto();
57
+ * const encoder = await Encoder.create('h264_videotoolbox', {
58
+ * width: 1920,
59
+ * height: 1080,
60
+ * pixelFormat: 'nv12',
61
+ * bitrate: '5M',
62
+ * hardware: hw
63
+ * });
64
+ * // ... use encoder
65
+ * encoder.close(); // Also disposes hardware
66
+ * hw?.dispose(); // Safe to call again (no-op)
67
+ * ```
68
+ */
69
+ export class Encoder {
70
+ codecContext;
71
+ packet;
72
+ codecName;
73
+ isOpen = true;
74
+ supportedFormats = [];
75
+ preferredFormat;
76
+ hardware; // Store reference to check for late framesContext
77
+ isHardwareEncoder = false; // Track if this is a hardware encoder
78
+ /**
79
+ * Private constructor - use Encoder.create() instead.
80
+ *
81
+ * Initializes the encoder with a codec context and allocates a packet buffer.
82
+ *
83
+ * @param codecContext - Initialized codec context
84
+ * @param codecName - Name of the codec
85
+ * @param hardware - Optional hardware context for late framesContext binding
86
+ */
87
+ constructor(codecContext, codecName, hardware) {
88
+ this.codecContext = codecContext;
89
+ this.codecName = codecName;
90
+ this.hardware = hardware;
91
+ this.packet = new Packet();
92
+ this.packet.alloc();
93
+ }
94
+ /**
95
+ * Create an encoder with specified codec and options.
96
+ *
97
+ * Factory method that handles codec discovery, context setup,
98
+ * and initialization.
99
+ *
100
+ * Uses avcodec_find_encoder_by_name() to locate the codec,
101
+ * configures the context with provided options, and opens it.
102
+ * Handles hardware setup including shared frames context for zero-copy.
103
+ *
104
+ * @param codecName - Name of codec (e.g., 'libx264', 'aac', 'libopus')
105
+ * @param input - Stream or StreamInfo to copy parameters from
106
+ * @param options - Encoder configuration options
107
+ *
108
+ * @returns Promise resolving to configured Encoder
109
+ *
110
+ * @throws {Error} If codec not found or configuration fails
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * // Video encoder from stream
115
+ * const videoStream = media.video();
116
+ * const videoEncoder = await Encoder.create('libx264', videoStream, {
117
+ * bitrate: '5M',
118
+ * gopSize: 60
119
+ * });
120
+ *
121
+ * // Audio encoder from stream
122
+ * const audioStream = media.audio();
123
+ * const audioEncoder = await Encoder.create('aac', audioStream, {
124
+ * bitrate: '192k'
125
+ * });
126
+ *
127
+ * ```
128
+ */
129
+ static async create(codecName, input, options = {}) {
130
+ const actualCodecName = codecName;
131
+ // Find encoder by name
132
+ const codec = Codec.findEncoderByName(actualCodecName);
133
+ if (!codec) {
134
+ throw new Error(`Encoder ${actualCodecName} not found`);
135
+ }
136
+ // Allocate codec context
137
+ const codecContext = new CodecContext();
138
+ codecContext.allocContext3(codec);
139
+ // Apply parameters based on input type
140
+ if (input instanceof Stream) {
141
+ // It's a Stream - copy ONLY the essential parameters
142
+ // DO NOT use parametersToContext as it copies everything including decoder-specific settings
143
+ if (codec.type === AVMEDIA_TYPE_VIDEO) {
144
+ // Set required video parameters from input stream
145
+ codecContext.width = input.codecpar.width;
146
+ codecContext.height = input.codecpar.height;
147
+ codecContext.pixelFormat = input.codecpar.format;
148
+ // Set timing information
149
+ codecContext.pktTimebase = input.timeBase;
150
+ codecContext.timeBase = input.timeBase;
151
+ // Set framerate if available
152
+ if (input.avgFrameRate && input.avgFrameRate.num > 0 && input.avgFrameRate.den > 0) {
153
+ codecContext.framerate = new Rational(input.avgFrameRate.num, input.avgFrameRate.den);
154
+ }
155
+ else if (input.rFrameRate && input.rFrameRate.num > 0 && input.rFrameRate.den > 0) {
156
+ codecContext.framerate = new Rational(input.rFrameRate.num, input.rFrameRate.den);
157
+ }
158
+ // Copy sample aspect ratio if present
159
+ if (input.sampleAspectRatio && input.sampleAspectRatio.num > 0) {
160
+ codecContext.sampleAspectRatio = new Rational(input.sampleAspectRatio.num, input.sampleAspectRatio.den);
161
+ }
162
+ }
163
+ else if (codec.type === AVMEDIA_TYPE_AUDIO) {
164
+ // Set required audio parameters from input stream
165
+ codecContext.sampleRate = input.codecpar.sampleRate;
166
+ codecContext.sampleFormat = input.codecpar.format;
167
+ // Copy channel layout from input
168
+ // NOTE: This means the encoder will use the same channel configuration as the input
169
+ // If you need different channels, use an audio filter or pass StreamInfo instead
170
+ codecContext.channelLayout = input.codecpar.channelLayout;
171
+ // Set timing information
172
+ codecContext.pktTimebase = input.timeBase;
173
+ codecContext.timeBase = input.timeBase;
174
+ }
175
+ else {
176
+ codecContext.freeContext();
177
+ throw new Error('Unsupported codec type for encoder');
178
+ }
179
+ }
180
+ else {
181
+ // It's StreamInfo - apply manually
182
+ if (input.type === 'video' && codec.type === AVMEDIA_TYPE_VIDEO) {
183
+ const videoInfo = input;
184
+ codecContext.width = videoInfo.width;
185
+ codecContext.height = videoInfo.height;
186
+ // Only set pixelFormat if provided (might be omitted for hardware encoders)
187
+ if (videoInfo.pixelFormat !== undefined) {
188
+ codecContext.pixelFormat = videoInfo.pixelFormat;
189
+ }
190
+ // Set pkt_timebase and timeBase to input timebase
191
+ codecContext.pktTimebase = new Rational(videoInfo.timeBase.num, videoInfo.timeBase.den);
192
+ codecContext.timeBase = new Rational(videoInfo.timeBase.num, videoInfo.timeBase.den);
193
+ if (videoInfo.frameRate) {
194
+ codecContext.framerate = new Rational(videoInfo.frameRate.num, videoInfo.frameRate.den);
195
+ }
196
+ if (videoInfo.sampleAspectRatio) {
197
+ codecContext.sampleAspectRatio = new Rational(videoInfo.sampleAspectRatio.num, videoInfo.sampleAspectRatio.den);
198
+ }
199
+ }
200
+ else if (input.type === 'audio' && codec.type === AVMEDIA_TYPE_AUDIO) {
201
+ const audioInfo = input;
202
+ codecContext.sampleRate = audioInfo.sampleRate;
203
+ codecContext.sampleFormat = audioInfo.sampleFormat;
204
+ codecContext.channelLayout = audioInfo.channelLayout;
205
+ // Set both pkt_timebase and timeBase for audio
206
+ codecContext.pktTimebase = new Rational(audioInfo.timeBase.num, audioInfo.timeBase.den);
207
+ codecContext.timeBase = new Rational(audioInfo.timeBase.num, audioInfo.timeBase.den);
208
+ if (audioInfo.frameSize) {
209
+ codecContext.frameSize = audioInfo.frameSize;
210
+ }
211
+ }
212
+ else {
213
+ throw new Error(`Codec type mismatch: ${input.type} info but ${codec.type === AVMEDIA_TYPE_VIDEO ? 'video' : 'audio'} codec`);
214
+ }
215
+ }
216
+ // Apply encoder-specific options
217
+ if (options.gopSize !== undefined) {
218
+ codecContext.gopSize = options.gopSize;
219
+ }
220
+ if (options.maxBFrames !== undefined) {
221
+ codecContext.maxBFrames = options.maxBFrames;
222
+ }
223
+ // Apply common options
224
+ if (options.bitrate !== undefined) {
225
+ const bitrate = typeof options.bitrate === 'string' ? parseBitrate(options.bitrate) : BigInt(options.bitrate);
226
+ codecContext.bitRate = bitrate;
227
+ }
228
+ if (options.threads !== undefined) {
229
+ codecContext.threadCount = options.threads;
230
+ }
231
+ // Override timeBase if explicitly specified in options
232
+ if (options.timeBase) {
233
+ codecContext.timeBase = new Rational(options.timeBase.num, options.timeBase.den);
234
+ }
235
+ // Apply codec-specific options via AVOptions
236
+ if (options.options) {
237
+ for (const [key, value] of Object.entries(options.options)) {
238
+ codecContext.setOption(key, value.toString());
239
+ }
240
+ }
241
+ // Check if this encoder supports hardware acceleration
242
+ let supportsHardware = false;
243
+ let isHardwareEncoder = false;
244
+ // Check encoder's hardware configurations
245
+ for (let i = 0;; i++) {
246
+ const config = codec.getHwConfig(i);
247
+ if (!config)
248
+ break;
249
+ // Check if encoder supports HW_FRAMES_CTX method
250
+ if ((config.methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) !== 0) {
251
+ supportsHardware = true;
252
+ // If hardware context provided, check if it matches this encoder
253
+ if (options.hardware && config.deviceType === options.hardware.deviceType) {
254
+ isHardwareEncoder = true;
255
+ break;
256
+ }
257
+ }
258
+ }
259
+ // Validation: Hardware encoder MUST have HardwareContext
260
+ if (supportsHardware && !options.hardware) {
261
+ throw new Error(`Hardware encoder '${actualCodecName}' requires a hardware context. ` + 'Please provide one via options.hardware');
262
+ }
263
+ // Apply hardware acceleration if provided and encoder supports it
264
+ if (options.hardware && isHardwareEncoder) {
265
+ // For hardware encoders, always set the hardware pixel format
266
+ // (overrides what was copied from stream parameters)
267
+ codecContext.pixelFormat = options.hardware.getHardwarePixelFormat();
268
+ // Check if frames context already available (shared from decoder)
269
+ if (options.hardware.framesContext) {
270
+ codecContext.hwFramesCtx = options.hardware.framesContext;
271
+ }
272
+ // Else: Will set hwFramesCtx later in encode() when first frame arrives
273
+ // DO NOT create frames context here - wait for first frame!
274
+ }
275
+ // Note: Software encoder silently ignores hardware context
276
+ // Open codec
277
+ const openRet = await codecContext.open2(codec, null);
278
+ if (openRet < 0) {
279
+ codecContext.freeContext();
280
+ FFmpegError.throwIfError(openRet, 'Failed to open encoder');
281
+ }
282
+ const encoder = new Encoder(codecContext, codecName, isHardwareEncoder ? options.hardware : undefined);
283
+ encoder.isHardwareEncoder = isHardwareEncoder;
284
+ // Get supported formats from codec (for validation and helpers)
285
+ if (codec.pixelFormats) {
286
+ encoder.supportedFormats = codec.pixelFormats;
287
+ encoder.preferredFormat = encoder.supportedFormats[0];
288
+ }
289
+ return encoder;
290
+ }
291
+ /**
292
+ * Check if encoder is open.
293
+ */
294
+ get isEncoderOpen() {
295
+ return this.isOpen;
296
+ }
297
+ /**
298
+ * Encode a frame and return a packet if available.
299
+ *
300
+ * Sends frame to encoder and attempts to receive a packet.
301
+ * May return null if encoder needs more data.
302
+ *
303
+ * Uses avcodec_send_frame() and avcodec_receive_packet() internally.
304
+ * The encoder may buffer frames before producing packets.
305
+ *
306
+ * @param frame - Frame to encode (or null to flush)
307
+ *
308
+ * @returns Promise resolving to Packet or null
309
+ *
310
+ * @throws {Error} If encoder is closed or encode fails
311
+ *
312
+ * @example
313
+ * ```typescript
314
+ * const packet = await encoder.encode(frame);
315
+ * if (packet) {
316
+ * // Write packet to output
317
+ * await output.writePacket(packet);
318
+ * }
319
+ * ```
320
+ */
321
+ async encode(frame) {
322
+ if (!this.isOpen) {
323
+ throw new Error('Encoder is closed');
324
+ }
325
+ // Late binding of hw_frames_ctx ONLY for hardware encoders
326
+ if (this.hardware && this.isHardwareEncoder && !this.codecContext.hwFramesCtx) {
327
+ if (this.hardware.framesContext) {
328
+ // Use shared frames context from decoder
329
+ this.codecContext.hwFramesCtx = this.hardware.framesContext;
330
+ }
331
+ else if (frame?.width && frame.height) {
332
+ // First frame - create frames context for upload
333
+ this.hardware.ensureFramesContext(frame.width, frame.height);
334
+ this.codecContext.hwFramesCtx = this.hardware.framesContext ?? null;
335
+ }
336
+ }
337
+ // Software encoder completely ignores hardware context
338
+ // NO MANUAL RESCALING! FFmpeg's avcodec_send_frame() does this internally
339
+ // The encoder needs pkt_timebase to be set for proper rescaling
340
+ // Send frame to encoder
341
+ const sendRet = await this.codecContext.sendFrame(frame);
342
+ if (sendRet < 0 && sendRet !== AVERROR_EOF) {
343
+ // Encoder might be full, try to receive first
344
+ const packet = await this.receivePacket();
345
+ if (packet)
346
+ return packet;
347
+ // If still failing, it's an error
348
+ if (sendRet !== AVERROR_EAGAIN) {
349
+ FFmpegError.throwIfError(sendRet, 'Failed to send frame');
350
+ }
351
+ }
352
+ // Try to receive packet
353
+ return this.receivePacket();
354
+ }
355
+ /**
356
+ * Async iterator that encodes frames and yields packets.
357
+ *
358
+ * Encodes all provided frames and yields resulting packets.
359
+ * Automatically handles encoder flushing at the end.
360
+ * Input frames are automatically freed after encoding.
361
+ *
362
+ * Processes frames in sequence, encoding each and yielding packets.
363
+ * After all frames are processed, flushes the encoder for remaining packets.
364
+ *
365
+ * IMPORTANT: The yielded packets MUST be freed by the caller!
366
+ * Input frames are automatically freed after processing.
367
+ *
368
+ * @param frames - Async iterable of frames to encode (will be freed automatically)
369
+ *
370
+ * @yields Encoded packets (ownership transferred to caller)
371
+ *
372
+ * @example
373
+ * ```typescript
374
+ * // Transcode video
375
+ * for await (const packet of encoder.packets(decoder.frames(media.packets()))) {
376
+ * await output.writePacket(packet);
377
+ * packet.free(); // Must free output packet
378
+ * }
379
+ * ```
380
+ */
381
+ async *packets(frames) {
382
+ if (!this.isOpen) {
383
+ throw new Error('Encoder is closed');
384
+ }
385
+ // Process frames
386
+ for await (const frame of frames) {
387
+ try {
388
+ const packet = await this.encode(frame);
389
+ if (packet) {
390
+ yield packet;
391
+ }
392
+ }
393
+ finally {
394
+ // Free the input frame after encoding
395
+ frame.free();
396
+ }
397
+ }
398
+ // Flush encoder after all frames
399
+ let packet;
400
+ while ((packet = await this.flush()) !== null) {
401
+ yield packet;
402
+ }
403
+ }
404
+ /**
405
+ * Flush encoder and get remaining packets.
406
+ *
407
+ * Sends null frame to trigger flush mode.
408
+ * Call repeatedly until it returns null.
409
+ *
410
+ * Uses avcodec_send_frame(NULL) to signal end of stream.
411
+ * Retrieves buffered packets from the encoder.
412
+ *
413
+ * @returns Promise resolving to Packet or null
414
+ *
415
+ * @throws {Error} If encoder is closed
416
+ *
417
+ * @example
418
+ * ```typescript
419
+ * // Flush all remaining packets
420
+ * let packet;
421
+ * while ((packet = await encoder.flush()) !== null) {
422
+ * // Write final packets
423
+ * await output.writePacket(packet);
424
+ * }
425
+ * ```
426
+ */
427
+ async flush() {
428
+ if (!this.isOpen) {
429
+ throw new Error('Encoder is closed');
430
+ }
431
+ // Send flush frame (null)
432
+ await this.codecContext.sendFrame(null);
433
+ // Receive packet
434
+ return this.receivePacket();
435
+ }
436
+ /**
437
+ * Flush encoder and yield all remaining packets as a generator.
438
+ *
439
+ * More convenient than calling flush() in a loop.
440
+ * Automatically sends flush signal and yields all buffered packets.
441
+ *
442
+ * @returns Async generator of remaining packets
443
+ *
444
+ * @throws {Error} If encoder is closed
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * // Process all remaining packets with generator
449
+ * for await (const packet of encoder.flushPackets()) {
450
+ * await output.writePacket(packet, streamIdx);
451
+ * using _ = packet; // Auto cleanup
452
+ * }
453
+ * ```
454
+ */
455
+ async *flushPackets() {
456
+ if (!this.isOpen) {
457
+ throw new Error('Encoder is closed');
458
+ }
459
+ let packet;
460
+ while ((packet = await this.flush()) !== null) {
461
+ yield packet;
462
+ }
463
+ }
464
+ /**
465
+ * Close encoder and free resources.
466
+ *
467
+ * After closing, the encoder cannot be used again.
468
+ *
469
+ * Frees the packet buffer and codec context.
470
+ * Note: Does NOT dispose the HardwareContext - caller is responsible for that.
471
+ */
472
+ close() {
473
+ if (!this.isOpen)
474
+ return;
475
+ this.packet.free();
476
+ this.codecContext.freeContext();
477
+ // NOTE: We do NOT dispose the hardware context here anymore
478
+ // The caller who created the HardwareContext is responsible for disposing it
479
+ // This allows reusing the same HardwareContext for multiple encoders
480
+ this.isOpen = false;
481
+ }
482
+ /**
483
+ * Get the codec name.
484
+ */
485
+ getCodecName() {
486
+ return this.codecName;
487
+ }
488
+ /**
489
+ * Get codec context for advanced configuration.
490
+ *
491
+ * Use with caution - direct manipulation may cause issues.
492
+ *
493
+ * Provides access to the underlying AVCodecContext for advanced operations.
494
+ *
495
+ * @returns CodecContext or null if closed
496
+ *
497
+ * @internal
498
+ */
499
+ getCodecContext() {
500
+ return this.isOpen ? this.codecContext : null;
501
+ }
502
+ /**
503
+ * Get the preferred pixel format for this encoder.
504
+ *
505
+ * Returns the first supported format, which is usually the most efficient.
506
+ *
507
+ * @returns Preferred pixel format or null if not available
508
+ *
509
+ * @example
510
+ * ```typescript
511
+ * const format = encoder.getPreferredPixelFormat();
512
+ * if (format) {
513
+ * console.log(`Encoder prefers format: ${format}`);
514
+ * }
515
+ * ```
516
+ */
517
+ getPreferredPixelFormat() {
518
+ return this.preferredFormat ?? null;
519
+ }
520
+ /**
521
+ * Get all supported pixel formats for this encoder.
522
+ *
523
+ * Returns a list of pixel formats that this encoder can accept.
524
+ *
525
+ * @returns Array of supported pixel formats
526
+ *
527
+ * @example
528
+ * ```typescript
529
+ * const formats = encoder.getSupportedPixelFormats();
530
+ * console.log(`Encoder supports: ${formats.join(', ')}`);
531
+ * ```
532
+ */
533
+ getSupportedPixelFormats() {
534
+ return this.supportedFormats;
535
+ }
536
+ /**
537
+ * Receive a packet from the encoder.
538
+ *
539
+ * Internal method to receive encoded packets.
540
+ *
541
+ * Uses avcodec_receive_packet() to get encoded packets from the codec.
542
+ * Clones the packet for the user to prevent internal buffer corruption.
543
+ *
544
+ * @returns Packet or null if no packet available
545
+ */
546
+ async receivePacket() {
547
+ // Clear previous packet data
548
+ this.packet.unref();
549
+ const ret = await this.codecContext.receivePacket(this.packet);
550
+ if (ret === 0) {
551
+ // Got a packet, clone it for the user
552
+ return this.packet.clone();
553
+ }
554
+ else if (ret === AVERROR_EAGAIN || ret === AVERROR_EOF) {
555
+ // Need more data or end of stream
556
+ return null;
557
+ }
558
+ else {
559
+ // Error
560
+ FFmpegError.throwIfError(ret, 'Failed to receive packet');
561
+ return null;
562
+ }
563
+ }
564
+ /**
565
+ * Symbol.dispose for automatic cleanup.
566
+ *
567
+ * Implements the Disposable interface for automatic resource management.
568
+ * Calls close() to free all resources.
569
+ */
570
+ [Symbol.dispose]() {
571
+ this.close();
572
+ }
573
+ }
574
+ //# sourceMappingURL=encoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../src/api/encoder.ts"],"names":[],"mappings":"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"}