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
/*
* Copyright 2026 LiveKit, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WEBRTC_AV1_BITSTREAM_H_
#define WEBRTC_AV1_BITSTREAM_H_
#include <cstddef>
#include <cstdint>
#include <vector>
namespace livekit {
namespace av1 {
/// Parsed span of a single AV1 OBU inside a low-overhead bitstream.
struct ObuSpan {
size_t offset = 0;
size_t total_size = 0;
int type = -1;
bool has_size_field = false;
};
/// Parse AV1 OBUs using the same rules as WebRTC's `RtpPacketizerAv1`.
/// Returns an empty vector when the bitstream is malformed.
std::vector<ObuSpan> ParseObus(const uint8_t* data, size_t len);
/// Returns true when the bitstream contains an `OBU_SEQUENCE_HEADER`.
bool HasSequenceHeaderObu(const uint8_t* data, size_t len);
/// Extract the first sequence-header OBU bytes, if present.
bool ExtractSequenceHeaderObu(const uint8_t* data,
size_t len,
std::vector<uint8_t>* out);
/// Prepend a cached sequence-header OBU to a keyframe when the encoder omitted it.
void EnsureSequenceHeaderOnKeyframe(std::vector<uint8_t>* packet,
const std::vector<uint8_t>& cached_seq_header);
/// Strip a per-frame IVF container header when present.
void StripIvfFrameHeaderIfPresent(std::vector<uint8_t>* packet);
/// Convert AV1 Annex-B temporal/frame/OBU units to low-overhead OBUs when
/// present.
void ConvertAnnexBToLowOverheadIfPresent(std::vector<uint8_t>* packet);
/// Strip OBUs that should not be transferred in WebRTC RTP payloads when present.
void StripNonTransferObusIfPresent(std::vector<uint8_t>* packet);
/// Normalizes an AV1 temporal unit for WebRTC RTP packetization: strips IVF
/// framing, converts Annex-B units to low-overhead OBUs, and strips
/// non-transfer OBUs. Shared by every encoder that emits AV1 into the RTP
/// pipeline so the steps cannot drift apart.
void NormalizeForRtp(std::vector<uint8_t>* packet);
/// Basic validation that WebRTC's AV1 packetizer can parse the bitstream.
bool IsWebRtcParseable(const uint8_t* data, size_t len);
} // namespace av1
} // namespace livekit
#endif // WEBRTC_AV1_BITSTREAM_H_