node-av 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +51 -59
  2. package/dist/api/bitstream-filter.d.ts +183 -123
  3. package/dist/api/bitstream-filter.js +185 -127
  4. package/dist/api/bitstream-filter.js.map +1 -1
  5. package/dist/api/decoder.d.ts +282 -130
  6. package/dist/api/decoder.js +290 -142
  7. package/dist/api/decoder.js.map +1 -1
  8. package/dist/api/encoder.d.ts +249 -160
  9. package/dist/api/encoder.js +276 -207
  10. package/dist/api/encoder.js.map +1 -1
  11. package/dist/api/filter-presets.d.ts +1944 -96
  12. package/dist/api/filter-presets.js +2059 -105
  13. package/dist/api/filter-presets.js.map +1 -1
  14. package/dist/api/filter.d.ts +264 -200
  15. package/dist/api/filter.js +269 -231
  16. package/dist/api/filter.js.map +1 -1
  17. package/dist/api/hardware.d.ts +246 -117
  18. package/dist/api/hardware.js +440 -217
  19. package/dist/api/hardware.js.map +1 -1
  20. package/dist/api/index.d.ts +3 -3
  21. package/dist/api/index.js +1 -1
  22. package/dist/api/index.js.map +1 -1
  23. package/dist/api/io-stream.d.ts +65 -55
  24. package/dist/api/io-stream.js +43 -40
  25. package/dist/api/io-stream.js.map +1 -1
  26. package/dist/api/media-input.d.ts +242 -139
  27. package/dist/api/media-input.js +205 -103
  28. package/dist/api/media-input.js.map +1 -1
  29. package/dist/api/media-output.d.ts +208 -126
  30. package/dist/api/media-output.js +212 -126
  31. package/dist/api/media-output.js.map +1 -1
  32. package/dist/api/pipeline.d.ts +361 -38
  33. package/dist/api/pipeline.js +255 -14
  34. package/dist/api/pipeline.js.map +1 -1
  35. package/dist/api/types.d.ts +26 -187
  36. package/dist/api/utilities/audio-sample.d.ts +0 -8
  37. package/dist/api/utilities/audio-sample.js +0 -8
  38. package/dist/api/utilities/audio-sample.js.map +1 -1
  39. package/dist/api/utilities/channel-layout.d.ts +0 -8
  40. package/dist/api/utilities/channel-layout.js +0 -8
  41. package/dist/api/utilities/channel-layout.js.map +1 -1
  42. package/dist/api/utilities/image.d.ts +0 -8
  43. package/dist/api/utilities/image.js +0 -8
  44. package/dist/api/utilities/image.js.map +1 -1
  45. package/dist/api/utilities/index.d.ts +3 -3
  46. package/dist/api/utilities/index.js +3 -3
  47. package/dist/api/utilities/index.js.map +1 -1
  48. package/dist/api/utilities/media-type.d.ts +1 -9
  49. package/dist/api/utilities/media-type.js +1 -9
  50. package/dist/api/utilities/media-type.js.map +1 -1
  51. package/dist/api/utilities/pixel-format.d.ts +1 -9
  52. package/dist/api/utilities/pixel-format.js +1 -9
  53. package/dist/api/utilities/pixel-format.js.map +1 -1
  54. package/dist/api/utilities/sample-format.d.ts +1 -9
  55. package/dist/api/utilities/sample-format.js +1 -9
  56. package/dist/api/utilities/sample-format.js.map +1 -1
  57. package/dist/api/utilities/streaming.d.ts +0 -8
  58. package/dist/api/utilities/streaming.js +0 -8
  59. package/dist/api/utilities/streaming.js.map +1 -1
  60. package/dist/api/utilities/timestamp.d.ts +0 -8
  61. package/dist/api/utilities/timestamp.js +0 -8
  62. package/dist/api/utilities/timestamp.js.map +1 -1
  63. package/dist/api/utils.d.ts +1 -2
  64. package/dist/api/utils.js +11 -0
  65. package/dist/api/utils.js.map +1 -1
  66. package/dist/constants/constants.d.ts +1 -1
  67. package/dist/constants/constants.js +2 -0
  68. package/dist/constants/constants.js.map +1 -1
  69. package/dist/lib/audio-fifo.d.ts +127 -170
  70. package/dist/lib/audio-fifo.js +130 -173
  71. package/dist/lib/audio-fifo.js.map +1 -1
  72. package/dist/lib/binding.d.ts +1 -0
  73. package/dist/lib/binding.js +7 -0
  74. package/dist/lib/binding.js.map +1 -1
  75. package/dist/lib/bitstream-filter-context.d.ts +139 -184
  76. package/dist/lib/bitstream-filter-context.js +139 -188
  77. package/dist/lib/bitstream-filter-context.js.map +1 -1
  78. package/dist/lib/bitstream-filter.d.ts +68 -54
  79. package/dist/lib/bitstream-filter.js +68 -54
  80. package/dist/lib/bitstream-filter.js.map +1 -1
  81. package/dist/lib/codec-context.d.ts +316 -380
  82. package/dist/lib/codec-context.js +316 -381
  83. package/dist/lib/codec-context.js.map +1 -1
  84. package/dist/lib/codec-parameters.d.ts +160 -170
  85. package/dist/lib/codec-parameters.js +162 -172
  86. package/dist/lib/codec-parameters.js.map +1 -1
  87. package/dist/lib/codec-parser.d.ts +91 -104
  88. package/dist/lib/codec-parser.js +92 -103
  89. package/dist/lib/codec-parser.js.map +1 -1
  90. package/dist/lib/codec.d.ts +266 -283
  91. package/dist/lib/codec.js +270 -287
  92. package/dist/lib/codec.js.map +1 -1
  93. package/dist/lib/dictionary.d.ts +149 -203
  94. package/dist/lib/dictionary.js +158 -212
  95. package/dist/lib/dictionary.js.map +1 -1
  96. package/dist/lib/error.d.ts +96 -130
  97. package/dist/lib/error.js +98 -128
  98. package/dist/lib/error.js.map +1 -1
  99. package/dist/lib/filter-context.d.ts +284 -218
  100. package/dist/lib/filter-context.js +290 -227
  101. package/dist/lib/filter-context.js.map +1 -1
  102. package/dist/lib/filter-graph.d.ts +251 -292
  103. package/dist/lib/filter-graph.js +253 -294
  104. package/dist/lib/filter-graph.js.map +1 -1
  105. package/dist/lib/filter-inout.d.ts +87 -95
  106. package/dist/lib/filter-inout.js +87 -95
  107. package/dist/lib/filter-inout.js.map +1 -1
  108. package/dist/lib/filter.d.ts +93 -111
  109. package/dist/lib/filter.js +93 -111
  110. package/dist/lib/filter.js.map +1 -1
  111. package/dist/lib/format-context.d.ts +320 -428
  112. package/dist/lib/format-context.js +313 -385
  113. package/dist/lib/format-context.js.map +1 -1
  114. package/dist/lib/frame.d.ts +262 -405
  115. package/dist/lib/frame.js +263 -408
  116. package/dist/lib/frame.js.map +1 -1
  117. package/dist/lib/hardware-device-context.d.ts +149 -203
  118. package/dist/lib/hardware-device-context.js +149 -203
  119. package/dist/lib/hardware-device-context.js.map +1 -1
  120. package/dist/lib/hardware-frames-context.d.ts +170 -180
  121. package/dist/lib/hardware-frames-context.js +171 -181
  122. package/dist/lib/hardware-frames-context.js.map +1 -1
  123. package/dist/lib/index.d.ts +3 -2
  124. package/dist/lib/index.js +3 -3
  125. package/dist/lib/index.js.map +1 -1
  126. package/dist/lib/input-format.d.ts +89 -117
  127. package/dist/lib/input-format.js +89 -117
  128. package/dist/lib/input-format.js.map +1 -1
  129. package/dist/lib/io-context.d.ts +209 -241
  130. package/dist/lib/io-context.js +220 -252
  131. package/dist/lib/io-context.js.map +1 -1
  132. package/dist/lib/log.d.ts +85 -119
  133. package/dist/lib/log.js +85 -122
  134. package/dist/lib/log.js.map +1 -1
  135. package/dist/lib/native-types.d.ts +118 -106
  136. package/dist/lib/native-types.js +0 -7
  137. package/dist/lib/native-types.js.map +1 -1
  138. package/dist/lib/option.d.ts +437 -218
  139. package/dist/lib/option.js +462 -226
  140. package/dist/lib/option.js.map +1 -1
  141. package/dist/lib/output-format.d.ts +77 -101
  142. package/dist/lib/output-format.js +77 -101
  143. package/dist/lib/output-format.js.map +1 -1
  144. package/dist/lib/packet.d.ts +172 -240
  145. package/dist/lib/packet.js +172 -241
  146. package/dist/lib/packet.js.map +1 -1
  147. package/dist/lib/rational.d.ts +0 -2
  148. package/dist/lib/rational.js +0 -2
  149. package/dist/lib/rational.js.map +1 -1
  150. package/dist/lib/software-resample-context.d.ts +241 -325
  151. package/dist/lib/software-resample-context.js +242 -326
  152. package/dist/lib/software-resample-context.js.map +1 -1
  153. package/dist/lib/software-scale-context.d.ts +129 -173
  154. package/dist/lib/software-scale-context.js +131 -175
  155. package/dist/lib/software-scale-context.js.map +1 -1
  156. package/dist/lib/stream.d.ts +87 -197
  157. package/dist/lib/stream.js +87 -197
  158. package/dist/lib/stream.js.map +1 -1
  159. package/dist/lib/utilities.d.ts +435 -181
  160. package/dist/lib/utilities.js +438 -182
  161. package/dist/lib/utilities.js.map +1 -1
  162. package/install/check.js +0 -1
  163. package/install/ffmpeg.js +0 -11
  164. package/package.json +25 -18
  165. package/release_notes.md +24 -59
  166. package/CHANGELOG.md +0 -8
@@ -1,61 +1,47 @@
1
- /**
2
- * Decoder - High-level wrapper for media decoding
3
- *
4
- * Simplifies FFmpeg's decoding API with automatic codec selection,
5
- * parameter configuration, and frame management.
6
- *
7
- * Handles codec initialization, packet decoding, and frame output.
8
- * Supports hardware acceleration and zero-copy transcoding.
9
- *
10
- * @module api/decoder
11
- */
12
1
  import { CodecContext, Frame } from '../lib/index.js';
13
2
  import type { Packet, Stream } from '../lib/index.js';
14
3
  import type { DecoderOptions, StreamInfo } from './types.js';
15
4
  /**
16
- * High-level decoder for media streams.
17
- *
18
- * Handles codec initialization, packet decoding, and frame output.
19
- * Designed for simple, efficient decoding workflows.
5
+ * High-level decoder for audio and video streams.
20
6
  *
21
- * Manages codec context lifecycle and provides automatic cleanup.
22
- * Supports hardware acceleration with zero-copy frame sharing.
7
+ * Provides a simplified interface for decoding media streams from packets to frames.
8
+ * Handles codec initialization, hardware acceleration setup, and frame management.
9
+ * Supports both synchronous packet-by-packet decoding and async iteration over frames.
10
+ * Essential component in media processing pipelines for converting compressed data to raw frames.
23
11
  *
24
12
  * @example
25
13
  * ```typescript
26
- * // Create decoder for video stream
27
- * const media = await MediaInput.open('video.mp4');
28
- * const stream = media.video(); // Get video stream
29
- * const decoder = await Decoder.create(stream);
14
+ * import { MediaInput, Decoder } from 'node-av/api';
30
15
  *
31
- * // Decode packets
32
- * for await (const packet of media.packets()) {
33
- * if (packet.streamIndex === stream.index) {
34
- * const frame = await decoder.decode(packet);
35
- * if (frame) {
36
- * console.log(`Decoded frame: ${frame.width}x${frame.height}`);
37
- * // Process frame...
38
- * }
39
- * }
40
- * }
16
+ * // Open media and create decoder
17
+ * await using input = await MediaInput.open('video.mp4');
18
+ * using decoder = await Decoder.create(input.video());
41
19
  *
42
- * // Flush decoder
43
- * const lastFrame = await decoder.flush();
44
- * decoder.close();
20
+ * // Decode frames
21
+ * for await (const frame of decoder.frames(input.packets())) {
22
+ * console.log(`Decoded frame: ${frame.width}x${frame.height}`);
23
+ * frame.free();
24
+ * }
45
25
  * ```
46
26
  *
47
27
  * @example
48
28
  * ```typescript
49
- * // With hardware acceleration
50
- * const hw = await HardwareContext.auto();
51
- * const stream = media.video();
52
- * const decoder = await Decoder.create(stream, {
53
- * hardware: hw
54
- * });
55
- * // ... use decoder
56
- * decoder.close();
57
- * hw?.dispose(); // Safe to call again (no-op)
29
+ * import { HardwareContext } from 'node-av/api';
30
+ * import { AV_HWDEVICE_TYPE_CUDA } from 'node-av/constants';
31
+ *
32
+ * // Setup hardware acceleration
33
+ * const hw = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA);
34
+ * using decoder = await Decoder.create(stream, { hardware: hw });
35
+ *
36
+ * // Frames will be decoded on GPU
37
+ * for await (const frame of decoder.frames(packets)) {
38
+ * // frame.hwFramesCtx contains GPU memory reference
39
+ * }
58
40
  * ```
41
+ *
42
+ * @see {@link Encoder} For encoding frames to packets
43
+ * @see {@link MediaInput} For reading media files
44
+ * @see {@link HardwareContext} For GPU acceleration
59
45
  */
60
46
  export declare class Decoder implements Disposable {
61
47
  private codecContext;
@@ -65,202 +51,368 @@ export declare class Decoder implements Disposable {
65
51
  private isOpen;
66
52
  private hardware?;
67
53
  /**
68
- * Private constructor - use Decoder.create() instead.
69
- *
70
- * Initializes the decoder with a codec context and allocates a frame buffer.
54
+ * @param codecContext - Configured codec context
55
+ * @param stream - Media stream being decoded
56
+ * @param hardware - Optional hardware context
57
+ * Use {@link create} factory method
71
58
  *
72
- * @param codecContext - Initialized codec context
73
- * @param stream - The stream this decoder is for
74
- * @param hardware - Optional hardware context for auto-sharing frames context
59
+ * @internal
75
60
  */
76
61
  private constructor();
77
62
  /**
78
- * Create a decoder for a specific stream.
63
+ * Create a decoder for a media stream.
79
64
  *
80
- * Factory method that handles codec discovery, context setup,
81
- * and initialization.
65
+ * Initializes a decoder with the appropriate codec and configuration.
66
+ * Automatically detects and configures hardware acceleration if provided.
67
+ * Applies custom codec options and threading configuration.
82
68
  *
83
- * Uses avcodec_find_decoder() to locate the appropriate codec,
84
- * then initializes and opens the codec context.
85
- *
86
- * @param stream - Stream to decode
69
+ * @param stream - Media stream to decode
87
70
  * @param options - Decoder configuration options
71
+ * @returns Configured decoder instance
88
72
  *
89
- * @returns Promise resolving to configured Decoder
73
+ * @throws {Error} If decoder not found for codec
90
74
  *
91
- * @throws {Error} If codec unavailable
75
+ * @throws {FFmpegError} If codec initialization fails
92
76
  *
93
77
  * @example
94
78
  * ```typescript
95
- * const media = await MediaInput.open('video.mp4');
96
- * const stream = media.video();
97
- * const decoder = await Decoder.create(stream);
79
+ * import { MediaInput, Decoder } from 'node-av/api';
80
+ *
81
+ * await using input = await MediaInput.open('video.mp4');
82
+ * using decoder = await Decoder.create(input.video());
83
+ * ```
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * using decoder = await Decoder.create(stream, {
88
+ * threads: 4,
89
+ * options: {
90
+ * 'refcounted_frames': '1',
91
+ * 'skip_frame': 'nonkey' // Only decode keyframes
92
+ * }
93
+ * });
98
94
  * ```
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const hw = HardwareContext.auto();
99
+ * using decoder = await Decoder.create(stream, {
100
+ * hardware: hw,
101
+ * threads: 0 // Auto-detect thread count
102
+ * });
103
+ * ```
104
+ *
105
+ * @see {@link HardwareContext} For GPU acceleration setup
106
+ * @see {@link DecoderOptions} For configuration options
99
107
  */
100
108
  static create(stream: Stream, options?: DecoderOptions): Promise<Decoder>;
101
109
  /**
102
110
  * Check if decoder is open.
111
+ *
112
+ * @returns true if decoder is open and ready
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * if (decoder.isDecoderOpen) {
117
+ * const frame = await decoder.decode(packet);
118
+ * }
119
+ * ```
103
120
  */
104
121
  get isDecoderOpen(): boolean;
105
122
  /**
106
123
  * Get output stream information.
107
124
  *
108
- * Returns the actual decoder output format, which may differ from the input stream.
109
- * For hardware decoders, this returns the hardware pixel format.
125
+ * Returns format information about decoded frames.
126
+ * For hardware decoding, returns the hardware pixel format.
127
+ * Essential for configuring downstream components like encoders or filters.
128
+ *
129
+ * @returns Stream format information
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const info = decoder.getOutputStreamInfo();
134
+ * if (info.type === 'video') {
135
+ * console.log(`Video: ${info.width}x${info.height} @ ${info.pixelFormat}`);
136
+ * console.log(`Frame rate: ${info.frameRate.num}/${info.frameRate.den}`);
137
+ * }
138
+ * ```
110
139
  *
111
- * @returns StreamInfo with decoder output properties
140
+ * @example
141
+ * ```typescript
142
+ * const info = decoder.getOutputStreamInfo();
143
+ * if (info.type === 'audio') {
144
+ * console.log(`Audio: ${info.sampleRate}Hz ${info.sampleFormat}`);
145
+ * console.log(`Channels: ${info.channelLayout}`);
146
+ * }
147
+ * ```
148
+ *
149
+ * @see {@link StreamInfo} For format details
150
+ * @see {@link Encoder.create} For matching encoder configuration
112
151
  */
113
152
  getOutputStreamInfo(): StreamInfo;
114
153
  /**
115
- * Decode a packet and return a frame if available.
154
+ * Check if decoder uses hardware acceleration.
116
155
  *
117
- * Sends packet to decoder and attempts to receive a frame.
118
- * May return null if decoder needs more data.
156
+ * @returns true if hardware-accelerated
119
157
  *
120
- * Uses avcodec_send_packet() and avcodec_receive_frame() internally.
121
- * The decoder may buffer packets before producing frames.
158
+ * @example
159
+ * ```typescript
160
+ * if (decoder.isHardware()) {
161
+ * console.log('Using GPU acceleration');
162
+ * }
163
+ * ```
122
164
  *
123
- * @param packet - Packet to decode
165
+ * @see {@link HardwareContext} For hardware setup
166
+ */
167
+ isHardware(): boolean;
168
+ /**
169
+ * Decode a packet to a frame.
124
170
  *
125
- * @returns Promise resolving to Frame or null
171
+ * Sends a packet to the decoder and attempts to receive a decoded frame.
172
+ * Handles internal buffering - may return null if more packets needed.
173
+ * Automatically manages decoder state and error recovery.
126
174
  *
127
- * @throws {Error} If decoder is closed or decode fails
175
+ * Direct mapping to avcodec_send_packet() and avcodec_receive_frame().
176
+ *
177
+ * @param packet - Compressed packet to decode
178
+ * @returns Decoded frame or null if more data needed
179
+ *
180
+ * @throws {Error} If decoder is closed
181
+ *
182
+ * @throws {FFmpegError} If decoding fails
128
183
  *
129
184
  * @example
130
185
  * ```typescript
131
186
  * const frame = await decoder.decode(packet);
132
187
  * if (frame) {
133
- * // Process frame
188
+ * console.log(`Decoded frame with PTS: ${frame.pts}`);
189
+ * frame.free();
134
190
  * }
135
191
  * ```
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * for await (const packet of input.packets()) {
196
+ * if (packet.streamIndex === decoder.getStreamIndex()) {
197
+ * const frame = await decoder.decode(packet);
198
+ * if (frame) {
199
+ * await processFrame(frame);
200
+ * frame.free();
201
+ * }
202
+ * }
203
+ * packet.free();
204
+ * }
205
+ * ```
206
+ *
207
+ * @see {@link frames} For automatic packet iteration
208
+ * @see {@link flush} For end-of-stream handling
136
209
  */
137
210
  decode(packet: Packet): Promise<Frame | null>;
138
211
  /**
139
- * Flush decoder and get remaining frames.
212
+ * Flush decoder and get buffered frame.
140
213
  *
141
- * Sends null packet to trigger flush mode.
142
- * Call repeatedly until it returns null.
214
+ * Signals end-of-stream and retrieves remaining frames.
215
+ * Call repeatedly until null to get all buffered frames.
216
+ * Essential for ensuring all frames are decoded.
143
217
  *
144
- * Uses avcodec_send_packet(NULL) to signal end of stream.
145
- * Retrieves buffered frames from the decoder.
218
+ * Direct mapping to avcodec_send_packet(NULL).
146
219
  *
147
- * @returns Promise resolving to Frame or null
220
+ * @returns Buffered frame or null if none remaining
148
221
  *
149
222
  * @throws {Error} If decoder is closed
150
223
  *
151
224
  * @example
152
225
  * ```typescript
153
- * // Flush all remaining frames
226
+ * // After all packets processed
154
227
  * let frame;
155
228
  * while ((frame = await decoder.flush()) !== null) {
156
- * // Process final frames
229
+ * console.log('Got buffered frame');
230
+ * await processFrame(frame);
231
+ * frame.free();
157
232
  * }
158
233
  * ```
234
+ *
235
+ * @see {@link flushFrames} For async iteration
236
+ * @see {@link frames} For complete decoding pipeline
159
237
  */
160
238
  flush(): Promise<Frame | null>;
161
239
  /**
162
- * Flush decoder and yield all remaining frames as a generator.
163
- *
164
- * More convenient than calling flush() in a loop.
165
- * Automatically sends flush signal and yields all buffered frames.
240
+ * Flush all buffered frames as async generator.
166
241
  *
167
- * IMPORTANT: The yielded frames MUST be freed by the caller!
168
- * Use 'using' statement or manually call frame.free() to avoid memory leaks.
169
- *
170
- * @returns Async generator of remaining frames
242
+ * Convenient async iteration over remaining frames.
243
+ * Automatically handles repeated flush calls.
244
+ * Useful for end-of-stream processing.
171
245
  *
246
+ * @yields Buffered frames
172
247
  * @throws {Error} If decoder is closed
173
248
  *
174
249
  * @example
175
250
  * ```typescript
176
- * // Process all remaining frames with generator
251
+ * // Flush at end of decoding
177
252
  * for await (const frame of decoder.flushFrames()) {
178
- * // Process final frame
179
- * using _ = frame; // Auto cleanup
253
+ * console.log('Processing buffered frame');
254
+ * await encoder.encode(frame);
255
+ * frame.free();
180
256
  * }
181
257
  * ```
258
+ *
259
+ * @see {@link flush} For single frame flush
260
+ * @see {@link frames} For complete pipeline
182
261
  */
183
262
  flushFrames(): AsyncGenerator<Frame>;
184
263
  /**
185
- * Async iterator that decodes packets and yields frames.
186
- *
187
- * Filters packets for this decoder's stream and yields decoded frames.
188
- * Automatically handles packet cleanup and decoder flushing.
189
- *
190
- * Processes packets in sequence, decoding each and yielding frames.
191
- * After all packets are processed, flushes the decoder for remaining frames.
264
+ * Decode packet stream to frame stream.
192
265
  *
193
- * IMPORTANT: The yielded frames MUST be freed by the caller!
194
- * Use 'using' statement or manually call frame.free() to avoid memory leaks.
266
+ * High-level async generator for complete decoding pipeline.
267
+ * Automatically filters packets for this stream, manages memory,
268
+ * and flushes buffered frames at end.
269
+ * Primary interface for stream-based decoding.
195
270
  *
196
- * @param packets - Async iterable of packets (e.g., from MediaInput.packets())
271
+ * @param packets - Async iterable of packets
272
+ * @yields Decoded frames
273
+ * @throws {Error} If decoder is closed
197
274
  *
198
- * @yields Decoded frames (ownership transferred to caller)
275
+ * @throws {FFmpegError} If decoding fails
199
276
  *
200
277
  * @example
201
278
  * ```typescript
202
- * // RECOMMENDED: Use 'using' for automatic cleanup
203
- * for await (using frame of decoder.frames(media.packets())) {
279
+ * await using input = await MediaInput.open('video.mp4');
280
+ * using decoder = await Decoder.create(input.video());
281
+ *
282
+ * for await (const frame of decoder.frames(input.packets())) {
204
283
  * console.log(`Frame: ${frame.width}x${frame.height}`);
205
- * // Frame is automatically freed at end of iteration
284
+ * frame.free();
206
285
  * }
286
+ * ```
207
287
  *
208
- * // OR: Manual cleanup
209
- * for await (const frame of decoder.frames(media.packets())) {
210
- * console.log(`Frame: ${frame.width}x${frame.height}`);
211
- * // Process frame...
212
- * frame.free(); // MUST call free()!
288
+ * @example
289
+ * ```typescript
290
+ * for await (const frame of decoder.frames(input.packets())) {
291
+ * // Process frame
292
+ * await filter.filterFrame(frame);
293
+ *
294
+ * // Frame automatically freed
295
+ * frame.free();
213
296
  * }
214
297
  * ```
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * import { pipeline } from 'node-av/api';
302
+ *
303
+ * const control = pipeline(
304
+ * input,
305
+ * decoder,
306
+ * encoder,
307
+ * output
308
+ * );
309
+ * await control.completion;
310
+ * ```
311
+ *
312
+ * @see {@link decode} For single packet decoding
313
+ * @see {@link MediaInput.packets} For packet source
215
314
  */
216
315
  frames(packets: AsyncIterable<Packet>): AsyncGenerator<Frame>;
217
316
  /**
218
317
  * Close decoder and free resources.
219
318
  *
220
- * After closing, the decoder cannot be used again.
319
+ * Releases codec context and internal frame buffer.
320
+ * Safe to call multiple times.
321
+ * Automatically called by Symbol.dispose.
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * const decoder = await Decoder.create(stream);
326
+ * try {
327
+ * // Use decoder
328
+ * } finally {
329
+ * decoder.close();
330
+ * }
331
+ * ```
221
332
  *
222
- * Frees the frame buffer and codec context.
223
- * Note: Does NOT dispose the HardwareContext - caller is responsible for that.
333
+ * @see {@link Symbol.dispose} For automatic cleanup
224
334
  */
225
335
  close(): void;
226
336
  /**
227
- * Get the stream index this decoder is for.
337
+ * Get stream index.
338
+ *
339
+ * Returns the index of the stream being decoded.
340
+ * Used for packet filtering in multi-stream files.
341
+ *
342
+ * @returns Stream index
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * if (packet.streamIndex === decoder.getStreamIndex()) {
347
+ * const frame = await decoder.decode(packet);
348
+ * }
349
+ * ```
350
+ *
351
+ * @see {@link getStream} For full stream object
228
352
  */
229
353
  getStreamIndex(): number;
230
354
  /**
231
- * Get the original stream this decoder was created from.
232
- * Used for stream-copy operations in pipeline.
355
+ * Get stream object.
356
+ *
357
+ * Returns the underlying stream being decoded.
358
+ * Provides access to stream metadata and parameters.
359
+ *
360
+ * @returns Stream object
361
+ *
362
+ * @example
363
+ * ```typescript
364
+ * const stream = decoder.getStream();
365
+ * console.log(`Duration: ${stream.duration}`);
366
+ * console.log(`Time base: ${stream.timeBase.num}/${stream.timeBase.den}`);
367
+ * ```
368
+ *
369
+ * @see {@link Stream} For stream properties
370
+ * @see {@link getStreamIndex} For index only
233
371
  */
234
372
  getStream(): Stream;
235
373
  /**
236
- * Get codec context for advanced configuration.
374
+ * Get underlying codec context.
237
375
  *
238
- * Use with caution - direct manipulation may cause issues.
376
+ * Returns the internal codec context for advanced operations.
377
+ * Returns null if decoder is closed.
239
378
  *
240
- * Provides access to the underlying AVCodecContext for advanced operations.
241
- *
242
- * @returns CodecContext or null if closed
379
+ * @returns Codec context or null
243
380
  *
244
381
  * @internal
245
382
  */
246
383
  getCodecContext(): CodecContext | null;
247
384
  /**
248
- * Receive a frame from the decoder (internal).
385
+ * Receive frame from decoder.
386
+ *
387
+ * Internal method to get decoded frames from codec.
388
+ * Handles frame cloning and error checking.
389
+ * Hardware frames include hw_frames_ctx reference.
390
+ *
391
+ * Direct mapping to avcodec_receive_frame().
249
392
  *
250
- * Internal method to receive decoded frames without conversion.
393
+ * @returns Cloned frame or null
251
394
  *
252
- * Uses avcodec_receive_frame() to get decoded frames from the codec.
253
- * Clones the frame for the user to prevent internal buffer corruption.
395
+ * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
254
396
  *
255
- * @returns Frame or null if no frame available
256
397
  * @internal
398
+ *
257
399
  */
258
400
  private receiveFrameInternal;
259
401
  /**
260
- * Symbol.dispose for automatic cleanup.
402
+ * Dispose of decoder.
403
+ *
404
+ * Implements Disposable interface for automatic cleanup.
405
+ * Equivalent to calling close().
406
+ *
407
+ * @example
408
+ * ```typescript
409
+ * {
410
+ * using decoder = await Decoder.create(stream);
411
+ * // Decode frames...
412
+ * } // Automatically closed
413
+ * ```
261
414
  *
262
- * Implements the Disposable interface for automatic resource management.
263
- * Calls close() to free all resources.
415
+ * @see {@link close} For manual cleanup
264
416
  */
265
417
  [Symbol.dispose](): void;
266
418
  }