1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! FLV (Flash Video / RTMP container).
//!
//! An interchange format only, not a wire format: [`Import`] demuxes an FLV byte
//! stream into a broadcast and [`Export`] muxes a broadcast back into FLV. Two
//! payload generations are handled:
//!
//! - **Legacy FLV/RTMP**: H.264 (AVC) video as length-prefixed NALU with an
//! out-of-band `AVCDecoderConfigurationRecord` (avcC), and AAC audio with an
//! out-of-band `AudioSpecificConfig`.
//! - **Enhanced RTMP (E-RTMP)**: the FourCC payloads for HEVC (`hvc1`), AV1
//! (`av01`), VP9 (`vp09`), Opus (`Opus`), AC-3 (`ac-3`), and E-AC-3 (`ec-3`).
//!
//! MP3 is handled in both generations: the legacy SoundFormat 2 tag and the
//! E-RTMP `.mp3` FourCC on import, and the legacy SoundFormat 2 tag on export.
//!
//! Each codec's config record passes straight through as the catalog
//! `description` (or, for the in-band codecs VP9 / MP3 / AC-3 / E-AC-3, is read
//! from the frame), and the sample bytes already match the
//! [`Legacy`](crate::catalog::hang::Container) container, so no codec transform is
//! needed. Other legacy codecs (VP6, Speex, …) and the E-RTMP FLAC audio are
//! logged and dropped on import, and rejected on export.
pub use *;
pub use *;
/// FLV tag type: audio.
const TAG_AUDIO: u8 = 8;
/// FLV tag type: video.
const TAG_VIDEO: u8 = 9;
/// FLV tag type: script data (`onMetaData`, etc.).
const TAG_SCRIPT: u8 = 18;
/// Bytes in an FLV tag header (type, data size, timestamp, stream id).
const TAG_HEADER_LEN: usize = 11;
/// Bytes in the `PreviousTagSize` field that trails every tag.
const PREV_TAG_SIZE_LEN: usize = 4;
/// Bytes in the FLV file header preceding the first `PreviousTagSize`.
const FILE_HEADER_LEN: usize = 9;
/// Video CodecID for H.264 (low nibble of a video tag's first byte).
const VIDEO_CODEC_AVC: u8 = 7;
/// SoundFormat for AAC (high nibble of an audio tag's first byte).
const AUDIO_FORMAT_AAC: u8 = 10;
/// SoundFormat for MP3 (high nibble of an audio tag's first byte).
const AUDIO_FORMAT_MP3: u8 = 2;
/// Video FrameType for a keyframe.
const FRAME_TYPE_KEY: u8 = 1;
/// Video FrameType for an inter frame.
const FRAME_TYPE_INTER: u8 = 2;
/// AVCPacketType for the `AVCDecoderConfigurationRecord`.
const AVC_SEQUENCE_HEADER: u8 = 0;
/// AVCPacketType for a length-prefixed NALU access unit.
const AVC_NALU: u8 = 1;
/// AACPacketType for the `AudioSpecificConfig`.
const AAC_SEQUENCE_HEADER: u8 = 0;
/// AACPacketType for a raw AAC frame.
const AAC_RAW: u8 = 1;
/// Standard first byte of an AAC audio tag: SoundFormat 10, SoundRate 3
/// (44 kHz flag), SoundSize 1 (16-bit), SoundType 1 (stereo). The real rate and
/// channel layout live in the `AudioSpecificConfig`, so these bits are nominal.
const AAC_AUDIO_TAG_HEADER: u8 = | | | 1;
/// First byte of an MP3 audio tag: SoundFormat 2, with the same nominal
/// SoundRate / SoundSize / SoundType bits as AAC. The real rate and channel
/// layout live in the MP3 frame header that follows, so these bits are nominal.
const MP3_AUDIO_TAG_HEADER: u8 = | | | 1;
/// Enhanced-RTMP (E-RTMP) video signaling: a set high bit on a video tag's
/// first byte switches from a legacy CodecID to a FourCC codec + packet type.
const VIDEO_EX_HEADER: u8 = 0x80;
/// Enhanced video `VideoPacketType` (low nibble of an ex-video tag's first byte).
const VIDEO_PACKET_SEQUENCE_START: u8 = 0;
const VIDEO_PACKET_CODED_FRAMES: u8 = 1;
const VIDEO_PACKET_SEQUENCE_END: u8 = 2;
/// Coded frames with the composition-time offset omitted (always zero).
const VIDEO_PACKET_CODED_FRAMES_X: u8 = 3;
const VIDEO_PACKET_METADATA: u8 = 4;
/// Multitrack framing: the next byte carries the `AvMultitrackType` plus the real
/// `VideoPacketType`, and each track payload is tagged with its own track id.
const VIDEO_PACKET_MULTITRACK: u8 = 5;
/// Enhanced-RTMP audio signaling: SoundFormat 9 in the high nibble of an audio
/// tag's first byte switches to a FourCC codec + packet type.
const AUDIO_FORMAT_EX: u8 = 9;
/// Enhanced audio `AudioPacketType` (low nibble of an ex-audio tag's first byte).
const AUDIO_PACKET_SEQUENCE_START: u8 = 0;
const AUDIO_PACKET_CODED_FRAMES: u8 = 1;
const AUDIO_PACKET_SEQUENCE_END: u8 = 2;
const AUDIO_PACKET_MULTICHANNEL_CONFIG: u8 = 4;
/// Multitrack framing, mirroring [`VIDEO_PACKET_MULTITRACK`] for audio.
const AUDIO_PACKET_MULTITRACK: u8 = 5;
/// `AvMultitrackType` (high nibble of the multitrack framing byte): how the
/// per-track payloads that follow are laid out.
///
/// - `OneTrack`: a single track, tagged with its id; the payload runs to the end
/// of the tag (no per-track size).
/// - `ManyTracks`: several tracks sharing one codec, each length-prefixed.
/// - `ManyTracksManyCodecs`: several tracks, each carrying its own FourCC and
/// length prefix.
const MULTITRACK_ONE_TRACK: u8 = 0;
const MULTITRACK_MANY_TRACKS: u8 = 1;
const MULTITRACK_MANY_TRACKS_MANY_CODECS: u8 = 2;
/// Read a 24-bit big-endian unsigned integer.
/// Read a 24-bit big-endian signed integer (FLV composition time offset).