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