node-av 4.0.0 → 5.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 (109) hide show
  1. package/README.md +23 -0
  2. package/binding.gyp +19 -11
  3. package/dist/api/bitstream-filter.d.ts +13 -12
  4. package/dist/api/bitstream-filter.js +33 -29
  5. package/dist/api/bitstream-filter.js.map +1 -1
  6. package/dist/api/decoder.d.ts +211 -96
  7. package/dist/api/decoder.js +396 -375
  8. package/dist/api/decoder.js.map +1 -1
  9. package/dist/api/demuxer.d.ts +10 -10
  10. package/dist/api/demuxer.js +7 -10
  11. package/dist/api/demuxer.js.map +1 -1
  12. package/dist/api/encoder.d.ts +155 -122
  13. package/dist/api/encoder.js +368 -541
  14. package/dist/api/encoder.js.map +1 -1
  15. package/dist/api/filter-complex.d.ts +769 -0
  16. package/dist/api/filter-complex.js +1596 -0
  17. package/dist/api/filter-complex.js.map +1 -0
  18. package/dist/api/filter-presets.d.ts +68 -0
  19. package/dist/api/filter-presets.js +96 -0
  20. package/dist/api/filter-presets.js.map +1 -1
  21. package/dist/api/filter.d.ts +183 -113
  22. package/dist/api/filter.js +347 -365
  23. package/dist/api/filter.js.map +1 -1
  24. package/dist/api/fmp4-stream.d.ts +18 -2
  25. package/dist/api/fmp4-stream.js +45 -4
  26. package/dist/api/fmp4-stream.js.map +1 -1
  27. package/dist/api/hardware.d.ts +47 -0
  28. package/dist/api/hardware.js +45 -0
  29. package/dist/api/hardware.js.map +1 -1
  30. package/dist/api/index.d.ts +2 -0
  31. package/dist/api/index.js +3 -0
  32. package/dist/api/index.js.map +1 -1
  33. package/dist/api/io-stream.d.ts +3 -3
  34. package/dist/api/io-stream.js.map +1 -1
  35. package/dist/api/muxer.d.ts +10 -10
  36. package/dist/api/muxer.js +6 -6
  37. package/dist/api/muxer.js.map +1 -1
  38. package/dist/api/pipeline.d.ts +2 -2
  39. package/dist/api/pipeline.js +22 -22
  40. package/dist/api/pipeline.js.map +1 -1
  41. package/dist/api/rtp-stream.d.ts +5 -2
  42. package/dist/api/rtp-stream.js +33 -4
  43. package/dist/api/rtp-stream.js.map +1 -1
  44. package/dist/api/types.d.ts +63 -7
  45. package/dist/api/utilities/audio-sample.d.ts +10 -0
  46. package/dist/api/utilities/audio-sample.js +10 -0
  47. package/dist/api/utilities/audio-sample.js.map +1 -1
  48. package/dist/api/utilities/channel-layout.d.ts +1 -0
  49. package/dist/api/utilities/channel-layout.js +1 -0
  50. package/dist/api/utilities/channel-layout.js.map +1 -1
  51. package/dist/api/utilities/image.d.ts +38 -0
  52. package/dist/api/utilities/image.js +38 -0
  53. package/dist/api/utilities/image.js.map +1 -1
  54. package/dist/api/utilities/index.d.ts +1 -0
  55. package/dist/api/utilities/index.js +2 -0
  56. package/dist/api/utilities/index.js.map +1 -1
  57. package/dist/api/utilities/media-type.d.ts +1 -0
  58. package/dist/api/utilities/media-type.js +1 -0
  59. package/dist/api/utilities/media-type.js.map +1 -1
  60. package/dist/api/utilities/pixel-format.d.ts +3 -0
  61. package/dist/api/utilities/pixel-format.js +3 -0
  62. package/dist/api/utilities/pixel-format.js.map +1 -1
  63. package/dist/api/utilities/sample-format.d.ts +5 -0
  64. package/dist/api/utilities/sample-format.js +5 -0
  65. package/dist/api/utilities/sample-format.js.map +1 -1
  66. package/dist/api/utilities/scheduler.d.ts +21 -52
  67. package/dist/api/utilities/scheduler.js +20 -58
  68. package/dist/api/utilities/scheduler.js.map +1 -1
  69. package/dist/api/utilities/streaming.d.ts +32 -1
  70. package/dist/api/utilities/streaming.js +32 -1
  71. package/dist/api/utilities/streaming.js.map +1 -1
  72. package/dist/api/utilities/timestamp.d.ts +14 -0
  73. package/dist/api/utilities/timestamp.js +14 -0
  74. package/dist/api/utilities/timestamp.js.map +1 -1
  75. package/dist/api/utilities/whisper-model.d.ts +310 -0
  76. package/dist/api/utilities/whisper-model.js +528 -0
  77. package/dist/api/utilities/whisper-model.js.map +1 -0
  78. package/dist/api/whisper.d.ts +324 -0
  79. package/dist/api/whisper.js +362 -0
  80. package/dist/api/whisper.js.map +1 -0
  81. package/dist/constants/constants.d.ts +3 -1
  82. package/dist/constants/constants.js +1 -0
  83. package/dist/constants/constants.js.map +1 -1
  84. package/dist/ffmpeg/index.d.ts +3 -3
  85. package/dist/ffmpeg/index.js +3 -3
  86. package/dist/ffmpeg/utils.d.ts +27 -0
  87. package/dist/ffmpeg/utils.js +28 -16
  88. package/dist/ffmpeg/utils.js.map +1 -1
  89. package/dist/lib/binding.d.ts +4 -4
  90. package/dist/lib/binding.js.map +1 -1
  91. package/dist/lib/codec-parameters.d.ts +47 -1
  92. package/dist/lib/codec-parameters.js +55 -0
  93. package/dist/lib/codec-parameters.js.map +1 -1
  94. package/dist/lib/fifo.d.ts +416 -0
  95. package/dist/lib/fifo.js +453 -0
  96. package/dist/lib/fifo.js.map +1 -0
  97. package/dist/lib/frame.d.ts +96 -1
  98. package/dist/lib/frame.js +139 -1
  99. package/dist/lib/frame.js.map +1 -1
  100. package/dist/lib/index.d.ts +1 -0
  101. package/dist/lib/index.js +2 -0
  102. package/dist/lib/index.js.map +1 -1
  103. package/dist/lib/native-types.d.ts +29 -2
  104. package/dist/lib/rational.d.ts +18 -0
  105. package/dist/lib/rational.js +19 -0
  106. package/dist/lib/rational.js.map +1 -1
  107. package/dist/lib/types.d.ts +23 -1
  108. package/install/check.js +2 -2
  109. package/package.json +31 -21
@@ -1,9 +1,9 @@
1
1
  import { CodecContext } from '../lib/codec-context.js';
2
2
  import { Codec } from '../lib/codec.js';
3
3
  import { Frame } from '../lib/frame.js';
4
+ import { Packet } from '../lib/packet.js';
4
5
  import { Scheduler } from './utilities/scheduler.js';
5
- import type { AVCodecID, FFDecoderCodec } from '../constants/index.js';
6
- import type { Packet } from '../lib/packet.js';
6
+ import type { AVCodecID, EOFSignal, FFDecoderCodec } from '../constants/index.js';
7
7
  import type { Stream } from '../lib/stream.js';
8
8
  import type { Encoder } from './encoder.js';
9
9
  import type { FilterAPI } from './filter.js';
@@ -259,28 +259,31 @@ export declare class Decoder implements Disposable {
259
259
  */
260
260
  isReady(): boolean;
261
261
  /**
262
- * Decode a packet to a frame.
262
+ * Send a packet to the decoder.
263
263
  *
264
- * Sends a packet to the decoder and attempts to receive a decoded frame.
265
- * Handles internal buffering - may return null if more packets needed.
264
+ * Sends a compressed packet to the decoder for decoding.
265
+ * Does not return decoded frames - use {@link receive} to retrieve frames.
266
+ * A single packet can produce zero, one, or multiple frames depending on codec buffering.
266
267
  * Automatically manages decoder state and error recovery.
267
268
  *
268
- * **Note**: This method receives only ONE frame per call.
269
- * A single packet can produce multiple frames (e.g., packed B-frames, codec buffering).
270
- * To receive all frames from a packet, use {@link decodeAll} or {@link frames} instead.
269
+ * **Important**: This method only SENDS the packet to the decoder.
270
+ * You must call {@link receive} separately (potentially multiple times) to get decoded frames.
271
271
  *
272
- * Direct mapping to avcodec_send_packet() and avcodec_receive_frame().
273
- *
274
- * @param packet - Compressed packet to decode
272
+ * Direct mapping to avcodec_send_packet().
275
273
  *
276
- * @returns Decoded frame or null if more data needed or decoder is closed
274
+ * @param packet - Compressed packet to send to decoder
277
275
  *
278
- * @throws {FFmpegError} If decoding fails
276
+ * @throws {FFmpegError} If sending packet fails
279
277
  *
280
278
  * @example
281
279
  * ```typescript
282
- * const frame = await decoder.decode(packet);
283
- * if (frame) {
280
+ * // Send packet and receive frames
281
+ * await decoder.decode(packet);
282
+ *
283
+ * // Receive all available frames
284
+ * while (true) {
285
+ * const frame = await decoder.receive();
286
+ * if (!frame) break;
284
287
  * console.log(`Decoded frame with PTS: ${frame.pts}`);
285
288
  * frame.free();
286
289
  * }
@@ -290,8 +293,12 @@ export declare class Decoder implements Disposable {
290
293
  * ```typescript
291
294
  * for await (const packet of input.packets()) {
292
295
  * if (packet.streamIndex === decoder.getStream().index) {
293
- * const frame = await decoder.decode(packet);
294
- * if (frame) {
296
+ * // Send packet
297
+ * await decoder.decode(packet);
298
+ *
299
+ * // Receive available frames
300
+ * let frame;
301
+ * while ((frame = await decoder.receive())) {
295
302
  * await processFrame(frame);
296
303
  * frame.free();
297
304
  * }
@@ -300,44 +307,70 @@ export declare class Decoder implements Disposable {
300
307
  * }
301
308
  * ```
302
309
  *
303
- * @see {@link decodeAll} For multiple frame decoding
310
+ * @see {@link receive} For receiving decoded frames
311
+ * @see {@link decodeAll} For combined send+receive operation
304
312
  * @see {@link frames} For automatic packet iteration
305
313
  * @see {@link flush} For end-of-stream handling
306
314
  * @see {@link decodeSync} For synchronous version
307
315
  */
308
- decode(packet: Packet): Promise<Frame | null>;
316
+ decode(packet: Packet): Promise<void>;
309
317
  /**
310
- * Decode a packet to frame synchronously.
318
+ * Send a packet to the decoder synchronously.
311
319
  * Synchronous version of decode.
312
320
  *
313
- * Send packet to decoder and attempt to receive frame.
314
- * Handles decoder buffering and error conditions.
315
- * May return null if decoder needs more data.
321
+ * Sends a compressed packet to the decoder for decoding.
322
+ * Does not return decoded frames - use {@link receiveSync} to retrieve frames.
323
+ * A single packet can produce zero, one, or multiple frames depending on codec buffering.
324
+ * Automatically manages decoder state and error recovery.
316
325
  *
317
- * **Note**: This method receives only ONE frame per call.
318
- * A single packet can produce multiple frames (e.g., packed B-frames, codec buffering).
319
- * To receive all frames from a packet, use {@link decodeAllSync} or {@link framesSync} instead.
326
+ * **Important**: This method only SENDS the packet to the decoder.
327
+ * You must call {@link receiveSync} separately (potentially multiple times) to get decoded frames.
320
328
  *
321
- * @param packet - Compressed packet to decode
329
+ * Direct mapping to avcodec_send_packet().
322
330
  *
323
- * @returns Decoded frame or null if more data needed or decoder is closed
331
+ * @param packet - Compressed packet to send to decoder
324
332
  *
325
- * @throws {FFmpegError} If decoding fails
333
+ * @throws {FFmpegError} If sending packet fails
326
334
  *
327
335
  * @example
328
336
  * ```typescript
329
- * const frame = decoder.decodeSync(packet);
330
- * if (frame) {
331
- * console.log(`Decoded: ${frame.width}x${frame.height}`);
337
+ * // Send packet and receive frames
338
+ * await decoder.decode(packet);
339
+ *
340
+ * // Receive all available frames
341
+ * while (true) {
342
+ * const frame = await decoder.receive();
343
+ * if (!frame) break;
344
+ * console.log(`Decoded frame with PTS: ${frame.pts}`);
345
+ * frame.free();
332
346
  * }
333
347
  * ```
334
348
  *
335
- * @see {@link decodeAllSync} For multiple frame decoding
349
+ * @example
350
+ * ```typescript
351
+ * for await (const packet of input.packets()) {
352
+ * if (packet.streamIndex === decoder.getStream().index) {
353
+ * // Send packet
354
+ * await decoder.decode(packet);
355
+ *
356
+ * // Receive available frames
357
+ * let frame;
358
+ * while ((frame = await decoder.receive())) {
359
+ * await processFrame(frame);
360
+ * frame.free();
361
+ * }
362
+ * }
363
+ * packet.free();
364
+ * }
365
+ * ```
366
+ *
367
+ * @see {@link receiveSync} For receiving decoded frames
368
+ * @see {@link decodeAllSync} For combined send+receive operation
336
369
  * @see {@link framesSync} For automatic packet iteration
337
370
  * @see {@link flushSync} For end-of-stream handling
338
371
  * @see {@link decode} For async version
339
372
  */
340
- decodeSync(packet: Packet): Frame | null;
373
+ decodeSync(packet: Packet): void;
341
374
  /**
342
375
  * Decode a packet to frames.
343
376
  *
@@ -366,12 +399,10 @@ export declare class Decoder implements Disposable {
366
399
  * @example
367
400
  * ```typescript
368
401
  * for await (const packet of input.packets()) {
369
- * if (packet.streamIndex === decoder.getStream().index) {
370
- * const frames = await decoder.decodeAll(packet);
371
- * for (const frame of frames) {
372
- * await processFrame(frame);
373
- * frame.free();
374
- * }
402
+ * const frames = await decoder.decodeAll(packet);
403
+ * for (const frame of frames) {
404
+ * await processFrame(frame);
405
+ * frame.free();
375
406
  * }
376
407
  * packet.free();
377
408
  * }
@@ -382,7 +413,7 @@ export declare class Decoder implements Disposable {
382
413
  * @see {@link flush} For end-of-stream handling
383
414
  * @see {@link decodeAllSync} For synchronous version
384
415
  */
385
- decodeAll(packet: Packet): Promise<Frame[]>;
416
+ decodeAll(packet: Packet | null): Promise<Frame[]>;
386
417
  /**
387
418
  * Decode a packet to frames synchronously.
388
419
  * Synchronous version of decodeAll.
@@ -404,6 +435,17 @@ export declare class Decoder implements Disposable {
404
435
  * console.log(`Decoded: ${frame.width}x${frame.height}`);
405
436
  * frame.free();
406
437
  * }
438
+ *
439
+ * @example
440
+ * ```typescript
441
+ * for (const packet of input.packetsSync()) {
442
+ * const frames = await decoder.decodeAllSync(packet);
443
+ * for (const frame of frames) {
444
+ * processFrame(frame);
445
+ * frame.free();
446
+ * }
447
+ * packet.free();
448
+ * }
407
449
  * ```
408
450
  *
409
451
  * @see {@link decodeSync} For single packet decoding
@@ -411,18 +453,22 @@ export declare class Decoder implements Disposable {
411
453
  * @see {@link flushSync} For end-of-stream handling
412
454
  * @see {@link decodeAll} For async version
413
455
  */
414
- decodeAllSync(packet: Packet): Frame[];
456
+ decodeAllSync(packet: Packet | null): Frame[];
415
457
  /**
416
458
  * Decode packet stream to frame stream.
417
459
  *
418
460
  * High-level async generator for complete decoding pipeline.
419
- * Automatically filters packets for this stream, manages memory,
420
- * and flushes buffered frames at end.
461
+ * Decoder is only flushed when EOF (null) signal is explicitly received.
421
462
  * Primary interface for stream-based decoding.
422
463
  *
423
- * @param packets - Async iterable of packets
464
+ * **EOF Handling:**
465
+ * - Send null to flush decoder and get remaining buffered frames
466
+ * - Generator yields null after flushing when null is received
467
+ * - No automatic flushing - decoder stays open until EOF or close()
424
468
  *
425
- * @yields {Frame} Decoded frames
469
+ * @param packets - Async iterable of packets, single packet, or null to flush
470
+ *
471
+ * @yields {Frame | null} Decoded frames, followed by null when explicitly flushed
426
472
  *
427
473
  * @throws {Error} If decoder is closed
428
474
  *
@@ -430,10 +476,15 @@ export declare class Decoder implements Disposable {
430
476
  *
431
477
  * @example
432
478
  * ```typescript
479
+ * // Stream of packets with automatic EOF propagation
433
480
  * await using input = await Demuxer.open('video.mp4');
434
481
  * using decoder = await Decoder.create(input.video());
435
482
  *
436
483
  * for await (const frame of decoder.frames(input.packets())) {
484
+ * if (frame === null) {
485
+ * console.log('Decoding complete');
486
+ * break;
487
+ * }
437
488
  * console.log(`Frame: ${frame.width}x${frame.height}`);
438
489
  * frame.free();
439
490
  * }
@@ -441,44 +492,53 @@ export declare class Decoder implements Disposable {
441
492
  *
442
493
  * @example
443
494
  * ```typescript
444
- * for await (const frame of decoder.frames(input.packets())) {
445
- * // Process frame
446
- * await filter.process(frame);
447
- *
448
- * // Frame automatically freed
495
+ * // Single packet (no automatic flush)
496
+ * for await (const frame of decoder.frames(singlePacket)) {
497
+ * await encoder.encode(frame);
498
+ * frame.free();
499
+ * }
500
+ * // Decoder still has buffered frames - send null to flush
501
+ * for await (const frame of decoder.frames(null)) {
502
+ * if (frame === null) break;
503
+ * await encoder.encode(frame);
449
504
  * frame.free();
450
505
  * }
451
506
  * ```
452
507
  *
453
508
  * @example
454
509
  * ```typescript
455
- * import { pipeline } from 'node-av/api';
456
- *
457
- * const control = pipeline(
458
- * input,
459
- * decoder,
460
- * encoder,
461
- * output
462
- * );
463
- * await control.completion;
510
+ * // Explicit flush with EOF
511
+ * for await (const frame of decoder.frames(null)) {
512
+ * if (frame === null) {
513
+ * console.log('All buffered frames flushed');
514
+ * break;
515
+ * }
516
+ * console.log('Buffered frame:', frame.pts);
517
+ * frame.free();
518
+ * }
464
519
  * ```
465
520
  *
466
521
  * @see {@link decode} For single packet decoding
467
522
  * @see {@link Demuxer.packets} For packet source
468
523
  * @see {@link framesSync} For sync version
469
524
  */
470
- frames(packets: AsyncIterable<Packet | null>): AsyncGenerator<Frame | null>;
525
+ frames(packets: AsyncIterable<Packet | null> | Packet | null): AsyncGenerator<Frame | null>;
471
526
  /**
472
527
  * Decode packet stream to frame stream synchronously.
473
528
  * Synchronous version of frames.
474
529
  *
475
- * High-level sync generator for complete decoding pipeline.
476
- * Automatically filters packets for this stream, manages memory,
477
- * and flushes buffered frames at end.
530
+ * High-level async generator for complete decoding pipeline.
531
+ * Decoder is only flushed when EOF (null) signal is explicitly received.
532
+ * Primary interface for stream-based decoding.
533
+ *
534
+ * **EOF Handling:**
535
+ * - Send null to flush decoder and get remaining buffered frames
536
+ * - Generator yields null after flushing when null is received
537
+ * - No automatic flushing - decoder stays open until EOF or close()
478
538
  *
479
- * @param packets - Iterable of packets
539
+ * @param packets - Iterable of packets, single packet, or null to flush
480
540
  *
481
- * @yields {Frame} Decoded frames
541
+ * @yields {Frame | null} Decoded frames, followed by null when explicitly flushed
482
542
  *
483
543
  * @throws {Error} If decoder is closed
484
544
  *
@@ -486,17 +546,49 @@ export declare class Decoder implements Disposable {
486
546
  *
487
547
  * @example
488
548
  * ```typescript
489
- * for (const frame of decoder.framesSync(packets)) {
549
+ * // Stream of packets with automatic EOF propagation
550
+ * await using input = await Demuxer.open('video.mp4');
551
+ * using decoder = await Decoder.create(input.video());
552
+ *
553
+ * for (const frame of decoder.framesSync(input.packetsSync())) {
554
+ * if (frame === null) {
555
+ * console.log('Decoding complete');
556
+ * break;
557
+ * }
490
558
  * console.log(`Frame: ${frame.width}x${frame.height}`);
491
- * // Process frame...
559
+ * frame.free();
492
560
  * }
493
561
  * ```
494
562
  *
495
- * @see {@link decodeSync} For single packet decoding
496
- * @see {@link Demuxer.packetsSync} For packet source
497
- * @see {@link frames} For async version
563
+ * @example
564
+ * ```typescript
565
+ * // Single packet (no automatic flush)
566
+ * for (const frame of decoder.framesSync(singlePacket)) {
567
+ * encoder.encodeSync(frame);
568
+ * frame.free();
569
+ * }
570
+ * // Decoder still has buffered frames - send null to flush
571
+ * for (const frame of decoder.framesSync(null)) {
572
+ * if (frame === null) break;
573
+ * encoder.encodeSync(frame);
574
+ * frame.free();
575
+ * }
576
+ * ```
577
+ *
578
+ * @example
579
+ * ```typescript
580
+ * // Explicit flush with EOF
581
+ * for (const frame of decoder.framesSync(null)) {
582
+ * if (frame === null) {
583
+ * console.log('All buffered frames flushed');
584
+ * break;
585
+ * }
586
+ * console.log('Buffered frame:', frame.pts);
587
+ * frame.free();
588
+ * }
589
+ * ```
498
590
  */
499
- framesSync(packets: Iterable<Packet | null>): Generator<Frame | null>;
591
+ framesSync(packets: Iterable<Packet | null> | Packet | null): Generator<Frame | null>;
500
592
  /**
501
593
  * Flush decoder and signal end-of-stream.
502
594
  *
@@ -606,38 +698,48 @@ export declare class Decoder implements Disposable {
606
698
  * Gets decoded frames from the codec's internal buffer.
607
699
  * Handles frame cloning and error checking.
608
700
  * Hardware frames include hw_frames_ctx reference.
609
- * Call repeatedly until null to drain all buffered frames.
701
+ * Call repeatedly to drain all buffered frames.
702
+ *
703
+ * **Return Values:**
704
+ * - `Frame` - Successfully decoded frame
705
+ * - `null` - No frame available (AVERROR_EAGAIN), send more packets
706
+ * - `undefined` - End of stream reached (AVERROR_EOF), decoder flushed
610
707
  *
611
708
  * Direct mapping to avcodec_receive_frame().
612
709
  *
613
- * @returns Cloned frame or null if no frames available
710
+ * @returns Decoded frame, null (need more data), or undefined (end of stream)
614
711
  *
615
712
  * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
616
713
  *
617
714
  * @example
618
715
  * ```typescript
619
716
  * const frame = await decoder.receive();
620
- * if (frame) {
717
+ * if (frame === EOF) {
718
+ * console.log('Decoder flushed, no more frames');
719
+ * } else if (frame) {
621
720
  * console.log('Got decoded frame');
622
721
  * frame.free();
722
+ * } else {
723
+ * console.log('Need more packets');
623
724
  * }
624
725
  * ```
625
726
  *
626
727
  * @example
627
728
  * ```typescript
628
- * // Drain all buffered frames
729
+ * // Drain all buffered frames (stop on null or EOF)
629
730
  * let frame;
630
- * while ((frame = await decoder.receive()) !== null) {
731
+ * while ((frame = await decoder.receive()) && frame !== EOF) {
631
732
  * console.log(`Frame PTS: ${frame.pts}`);
632
733
  * frame.free();
633
734
  * }
634
735
  * ```
635
736
  *
636
- * @see {@link decode} For sending packets and receiving frames
737
+ * @see {@link decode} For sending packets
637
738
  * @see {@link flush} For signaling end-of-stream
638
739
  * @see {@link receiveSync} For synchronous version
740
+ * @see {@link EOF} For end-of-stream signal
639
741
  */
640
- receive(): Promise<Frame | null>;
742
+ receive(): Promise<Frame | EOFSignal | null>;
641
743
  /**
642
744
  * Receive frame from decoder synchronously.
643
745
  * Synchronous version of receive.
@@ -645,38 +747,48 @@ export declare class Decoder implements Disposable {
645
747
  * Gets decoded frames from the codec's internal buffer.
646
748
  * Handles frame cloning and error checking.
647
749
  * Hardware frames include hw_frames_ctx reference.
648
- * Call repeatedly until null to drain all buffered frames.
750
+ * Call repeatedly to drain all buffered frames.
751
+ *
752
+ * **Return Values:**
753
+ * - `Frame` - Successfully decoded frame
754
+ * - `null` - No frame available (AVERROR_EAGAIN), send more packets
755
+ * - `undefined` - End of stream reached (AVERROR_EOF), decoder flushed
649
756
  *
650
757
  * Direct mapping to avcodec_receive_frame().
651
758
  *
652
- * @returns Cloned frame or null if no frames available
759
+ * @returns Decoded frame, null (need more data), or undefined (end of stream)
653
760
  *
654
761
  * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
655
762
  *
656
763
  * @example
657
764
  * ```typescript
658
765
  * const frame = decoder.receiveSync();
659
- * if (frame) {
766
+ * if (frame === EOF) {
767
+ * console.log('Decoder flushed, no more frames');
768
+ * } else if (frame) {
660
769
  * console.log('Got decoded frame');
661
770
  * frame.free();
771
+ * } else {
772
+ * console.log('Need more packets');
662
773
  * }
663
774
  * ```
664
775
  *
665
776
  * @example
666
777
  * ```typescript
667
- * // Drain all buffered frames
778
+ * // Drain all buffered frames (stop on null or EOF)
668
779
  * let frame;
669
- * while ((frame = decoder.receiveSync()) !== null) {
780
+ * while ((frame = decoder.receiveSync()) && frame !== EOF) {
670
781
  * console.log(`Frame PTS: ${frame.pts}`);
671
782
  * frame.free();
672
783
  * }
673
784
  * ```
674
785
  *
675
- * @see {@link decodeSync} For sending packets and receiving frames
786
+ * @see {@link decodeSync} For sending packets
676
787
  * @see {@link flushSync} For signaling end-of-stream
677
788
  * @see {@link receive} For async version
789
+ * @see {@link EOF} For end-of-stream signal
678
790
  */
679
- receiveSync(): Frame | null;
791
+ receiveSync(): Frame | EOFSignal | null;
680
792
  /**
681
793
  * Pipe decoded frames to a filter component or encoder.
682
794
  *
@@ -758,9 +870,20 @@ export declare class Decoder implements Disposable {
758
870
  */
759
871
  private runWorker;
760
872
  /**
761
- * Send packet to input queue.
873
+ * Send packet to input queue or flush the pipeline.
874
+ *
875
+ * When packet is provided, queues it for processing.
876
+ * When null is provided, triggers flush sequence:
877
+ * - Closes input queue
878
+ * - Waits for worker completion
879
+ * - Flushes decoder and sends remaining frames to output queue
880
+ * - Closes output queue
881
+ * - Waits for pipeTo task completion
882
+ * - Propagates flush to next component (if any)
883
+ *
884
+ * Used by scheduler system for pipeline control.
762
885
  *
763
- * @param packet - Packet to send
886
+ * @param packet - Packet to send, or null to flush
764
887
  *
765
888
  * @internal
766
889
  */
@@ -773,14 +896,6 @@ export declare class Decoder implements Disposable {
773
896
  * @internal
774
897
  */
775
898
  private receiveFromQueue;
776
- /**
777
- * Flush the entire filter pipeline.
778
- *
779
- * Propagates flush through worker, output queue, and next component.
780
- *
781
- * @internal
782
- */
783
- private flushPipeline;
784
899
  /**
785
900
  * Estimate video frame duration.
786
901
  *