Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit dadf759

Browse files
committed
add init code
1 parent 427a9cf commit dadf759

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+7047
-0
lines changed

.github/actions-rs/grcov.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
branch: true
2+
ignore-not-existing: true
3+
llvm: true
4+
filter: covered
5+
output-type: lcov
6+
output-path: ./lcov.info
7+
source-dir: .
8+
ignore:
9+
- "/*"
10+
- "C:/*"
11+
- "../*"
12+
excl-line: "#\\[derive\\("
13+
excl-start: "mod tests \\{"
14+
excl-br-line: "#\\[derive\\("
15+
excl-br-start: "mod tests \\{"

.github/workflows/cargo.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Cargo
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
build:
14+
name: Build and test
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v2
18+
- name: Build
19+
run: cargo build --verbose
20+
- name: Run tests
21+
run: cargo test --verbose
22+
23+
rustfmt_and_clippy:
24+
name: Check rustfmt style && run clippy
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v2
28+
- uses: actions-rs/toolchain@v1
29+
with:
30+
toolchain: 1.46.0
31+
profile: minimal
32+
components: clippy, rustfmt
33+
override: true
34+
- name: Cache cargo registry
35+
uses: actions/cache@v1
36+
with:
37+
path: ~/.cargo/registry
38+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
39+
- name: Run clippy
40+
uses: actions-rs/cargo@v1
41+
with:
42+
command: clippy
43+
- name: Check formating
44+
uses: actions-rs/cargo@v1
45+
with:
46+
command: fmt
47+
args: --all -- --check

.github/workflows/grcov.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Coverage
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
grcov:
14+
name: Coverage
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
matrix:
18+
os:
19+
- ubuntu-latest
20+
toolchain:
21+
- nightly
22+
cargo_flags:
23+
- "--all-features"
24+
steps:
25+
- name: Checkout source code
26+
uses: actions/checkout@v2
27+
28+
- name: Install Rust
29+
uses: actions-rs/toolchain@v1
30+
with:
31+
profile: minimal
32+
toolchain: ${{ matrix.toolchain }}
33+
override: true
34+
35+
- name: Install grcov
36+
uses: actions-rs/[email protected]
37+
with:
38+
crate: grcov
39+
version: latest
40+
use-tool-cache: true
41+
42+
- name: Test
43+
uses: actions-rs/cargo@v1
44+
with:
45+
command: test
46+
args: --all --no-fail-fast ${{ matrix.cargo_flags }}
47+
env:
48+
CARGO_INCREMENTAL: "0"
49+
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort -Cdebug-assertions=off'
50+
RUSTDOCFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort -Cdebug-assertions=off'
51+
52+
- name: Generate coverage data
53+
id: grcov
54+
# uses: actions-rs/[email protected]
55+
run: |
56+
grcov target/debug/ \
57+
--branch \
58+
--llvm \
59+
--source-dir . \
60+
--output-path lcov.info \
61+
--ignore='/**' \
62+
--ignore='C:/**' \
63+
--ignore='../**' \
64+
--ignore-not-existing \
65+
--excl-line "#\\[derive\\(" \
66+
--excl-br-line "#\\[derive\\(" \
67+
--excl-start "#\\[cfg\\(test\\)\\]" \
68+
--excl-br-start "#\\[cfg\\(test\\)\\]" \
69+
--commit-sha ${{ github.sha }} \
70+
--service-job-id ${{ github.job }} \
71+
--service-name "GitHub Actions" \
72+
--service-number ${{ github.run_id }}
73+
- name: Upload coverage as artifact
74+
uses: actions/upload-artifact@v2
75+
with:
76+
name: lcov.info
77+
# path: ${{ steps.grcov.outputs.report }}
78+
path: lcov.info
79+
80+
- name: Upload coverage to codecov.io
81+
uses: codecov/codecov-action@v1
82+
with:
83+
# file: ${{ steps.grcov.outputs.report }}
84+
file: lcov.info
85+
fail_ci_if_error: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Generated by Cargo
22
# will have compiled files and executables
33
/target/
4+
/.idea/
45

56
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
67
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "rtcp"
3+
version = "0.1.0"
4+
authors = ["Rain Liu <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
util = { git = "https://github.com/webrtc-rs/util", branch = "main" }
11+
byteorder = "1.3.2"
12+
lazy_static = "1.3.0"

codecov.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
codecov:
2+
require_ci_to_pass: yes
3+
max_report_age: off
4+
5+
coverage:
6+
precision: 2
7+
round: down
8+
range: 50..90
9+
status:
10+
project:
11+
default:
12+
enabled: no
13+
threshold: 0.2
14+
if_not_found: success
15+
patch:
16+
default:
17+
enabled: no
18+
if_not_found: success
19+
changes:
20+
default:
21+
enabled: no
22+
if_not_found: success

src/compound_packet.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use std::io::Write;
2+
3+
use util::Error;
4+
5+
use super::errors::*;
6+
use super::packet::*;
7+
use super::source_description::*;
8+
9+
#[cfg(test)]
10+
mod compound_packet_test;
11+
12+
// A CompoundPacket is a collection of RTCP packets transmitted as a single packet with
13+
// the underlying protocol (for example UDP).
14+
//
15+
// To maximize the resolution of receiption statistics, the first Packet in a CompoundPacket
16+
// must always be either a SenderReport or a ReceiverReport. This is true even if no data
17+
// has been sent or received, in which case an empty ReceiverReport must be sent, and even
18+
// if the only other RTCP packet in the compound packet is a Goodbye.
19+
//
20+
// Next, a SourceDescription containing a CNAME item must be included in each CompoundPacket
21+
// to identify the source and to begin associating media for purposes such as lip-sync.
22+
//
23+
// Other RTCP packet types may follow in any order. Packet types may appear more than once.
24+
#[derive(Debug, Clone)]
25+
pub struct CompoundPacket(pub Vec<Packet>);
26+
27+
impl CompoundPacket {
28+
// Validate returns an error if this is not an RFC-compliant CompoundPacket.
29+
pub fn validate(&self) -> Result<(), Error> {
30+
if self.0.is_empty() {
31+
return Err(ERR_EMPTY_COMPOUND.clone());
32+
}
33+
34+
// SenderReport and ReceiverReport are the only types that
35+
// are allowed to be the first packet in a compound datagram
36+
match &self.0[0] {
37+
Packet::SenderReport(_) | Packet::ReceiverReport(_) => {}
38+
_ => return Err(ERR_BAD_FIRST_PACKET.clone()),
39+
};
40+
41+
for pkt in &self.0[1..] {
42+
match pkt {
43+
// If the number of RecetpionReports exceeds 31 additional ReceiverReports
44+
// can be included here.
45+
Packet::ReceiverReport(_) => {}
46+
47+
// A SourceDescription containing a CNAME must be included in every
48+
// CompoundPacket.
49+
Packet::SourceDescription(p) => {
50+
let mut has_cname = false;
51+
for c in &p.chunks {
52+
for it in &c.items {
53+
if it.sdes_type == SDESType::SDESCNAME {
54+
has_cname = true
55+
}
56+
}
57+
}
58+
59+
if !has_cname {
60+
return Err(ERR_MISSING_CNAME.clone());
61+
}
62+
63+
return Ok(());
64+
}
65+
// Other packets are not permitted before the CNAME
66+
_ => return Err(ERR_PACKET_BEFORE_CNAME.clone()),
67+
};
68+
}
69+
70+
// CNAME never reached
71+
Err(ERR_MISSING_CNAME.clone())
72+
}
73+
74+
//CNAME returns the CNAME that *must* be present in every CompoundPacket
75+
pub fn cname(&self) -> Result<String, Error> {
76+
if self.0.is_empty() {
77+
return Err(ERR_EMPTY_COMPOUND.clone());
78+
}
79+
80+
for pkt in &self.0[1..] {
81+
match pkt {
82+
Packet::ReceiverReport(_) => {}
83+
84+
// A SourceDescription containing a CNAME must be included in every
85+
// CompoundPacket.
86+
Packet::SourceDescription(p) => {
87+
for c in &p.chunks {
88+
for it in &c.items {
89+
if it.sdes_type == SDESType::SDESCNAME {
90+
return Ok(it.text.clone());
91+
}
92+
}
93+
}
94+
}
95+
96+
_ => return Err(ERR_PACKET_BEFORE_CNAME.clone()),
97+
};
98+
}
99+
Err(ERR_MISSING_CNAME.clone())
100+
}
101+
102+
// Marshal encodes the CompoundPacket as binary.
103+
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
104+
self.validate()?;
105+
106+
// use packet::marshal function
107+
marshal(&self.0, writer)
108+
}
109+
110+
// destination_ssrc returns the synchronization sources associated with this
111+
// CompoundPacket's reception report.
112+
pub fn destination_ssrc(&self) -> Vec<u32> {
113+
if self.0.is_empty() {
114+
vec![]
115+
} else {
116+
match &self.0[0] {
117+
Packet::SenderReport(p) => p.destination_ssrc(),
118+
Packet::ReceiverReport(p) => p.destination_ssrc(),
119+
_ => vec![],
120+
}
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)