Skip to content

Commit fe52ec1

Browse files
HITGIFrainliu
authored andcommitted
wip
1 parent c66520f commit fe52ec1

File tree

4 files changed

+109
-1
lines changed

4 files changed

+109
-1
lines changed

rtp/src/codecs/av1/mod.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use std::cmp::min;
2+
3+
use bytes::Bytes;
4+
5+
use crate::packetizer::Payloader;
6+
7+
#[derive(Default, Clone, Debug)]
8+
pub struct Av1Payloader {}
9+
10+
const AV1_PAYLOADER_HEADER_SIZE: usize = 1;
11+
12+
// fn encode_leb128(mut val: u32) -> u32 {
13+
// let mut b = 0;
14+
// loop {
15+
// b |= val & 0b01111111;
16+
// val >>= 7;
17+
// if val != 0 {
18+
// b |= 0x80;
19+
// b <<= 8;
20+
// } else {
21+
// return b;
22+
// }
23+
// }
24+
// }
25+
26+
fn encode_leb128(input: u32) -> u32 {
27+
let mut output: u32 = 0;
28+
let mut in_value = input;
29+
30+
loop {
31+
output |= in_value & 0b0111_1111;
32+
in_value >>= 7;
33+
34+
if in_value != 0 {
35+
output |= 0b1000_0000;
36+
output <<= 8;
37+
} else {
38+
return output;
39+
}
40+
}
41+
}
42+
43+
impl Payloader for Av1Payloader {
44+
fn payload(&mut self, mtu: usize, payload: &Bytes) -> crate::error::Result<Vec<Bytes>> {
45+
let max_fragment_size = mtu - AV1_PAYLOADER_HEADER_SIZE;
46+
let mut packets = vec![];
47+
let mut payload_data_remaining = payload.len();
48+
let mut payload_data_index = 0;
49+
50+
if min(max_fragment_size, payload_data_remaining) <= 0 {
51+
return Ok(packets);
52+
}
53+
54+
while payload_data_remaining > 0 {
55+
let current_fragment_size = min(max_fragment_size, payload_data_remaining);
56+
let leb128_size = if current_fragment_size >= 127 { 2 } else { 1 };
57+
58+
let mut packet = vec![0; AV1_PAYLOADER_HEADER_SIZE + leb128_size + current_fragment_size];
59+
let leb128_value = encode_leb128(current_fragment_size as u32);
60+
if leb128_size == 1 {
61+
packet[1] = leb128_value as u8;
62+
} else {
63+
packet[1] = (leb128_value >> 8) as u8;
64+
packet[2] = leb128_value as u8;
65+
}
66+
packet[AV1_PAYLOADER_HEADER_SIZE + leb128_size..]
67+
.copy_from_slice(&payload[payload_data_index..payload_data_index + current_fragment_size]);
68+
69+
payload_data_remaining -= current_fragment_size;
70+
payload_data_index += current_fragment_size;
71+
72+
if packets.len() == 0 {
73+
// Set the N bit to 1 for the first packet
74+
packet[0] |= 0b00001000;
75+
}
76+
if packets.len() > 0 {
77+
// Set the Z bit to 0 for all but the first packet
78+
packet[0] |= 0b10000000;
79+
}
80+
if payload_data_remaining != 0 {
81+
// Set the Y bit to 1 for all but the last packet
82+
packet[0] |= 0b01000000;
83+
}
84+
85+
packets.push(Bytes::from(packet));
86+
}
87+
88+
Ok(packets)
89+
}
90+
91+
fn clone_to(&self) -> Box<dyn Payloader + Send + Sync> {
92+
Box::new(self.clone())
93+
}
94+
}

rtp/src/codecs/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pub mod h265;
44
pub mod opus;
55
pub mod vp8;
66
pub mod vp9;
7+
pub mod av1;

webrtc/src/api/media_engine/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,22 @@ impl MediaEngine {
274274
sdp_fmtp_line:
275275
"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032"
276276
.to_owned(),
277-
rtcp_feedback: video_rtcp_feedback,
277+
rtcp_feedback: video_rtcp_feedback.clone(),
278278
},
279279
payload_type: 123,
280280
..Default::default()
281281
},
282+
RTCRtpCodecParameters {
283+
capability: RTCRtpCodecCapability {
284+
mime_type: MIME_TYPE_AV1.to_owned(),
285+
clock_rate: 90000,
286+
channels: 0,
287+
sdp_fmtp_line: "profile-id=0".to_owned(),
288+
rtcp_feedback: video_rtcp_feedback,
289+
},
290+
payload_type: 41,
291+
..Default::default()
292+
},
282293
RTCRtpCodecParameters {
283294
capability: RTCRtpCodecCapability {
284295
mime_type: "video/ulpfec".to_owned(),

webrtc/src/rtp_transceiver/rtp_codec.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ impl RTCRtpCodecCapability {
8080
|| mime_type == MIME_TYPE_TELEPHONE_EVENT.to_lowercase()
8181
{
8282
Ok(Box::<rtp::codecs::g7xx::G7xxPayloader>::default())
83+
} else if mime_type == MIME_TYPE_AV1.to_lowercase() {
84+
Ok(Box::<rtp::codecs::av1::Av1Payloader>::default())
8385
} else {
8486
Err(Error::ErrNoPayloaderForCodec)
8587
}

0 commit comments

Comments
 (0)