Skip to content

Commit ee8a2bc

Browse files
authored
Add optional drv feature deriving drv::Input on identity types (algesten#974)
* Add optional drv feature deriving drv::Input on identity types Adds a default-off `drv` feature that derives `drv::Input` (drv's memoization cache-key plumbing) on the public identity types, so downstream `#[drv::memo]` queries can take them by value as cache keys without newtyping them to satisfy drv's ToStatic bound (the orphan rule blocks a consumer-side impl on str0m's foreign types). Types covered: Mid, Rid, Ssrc, Pt, SessionId, SeqNo, Direction, MediaKind, Frequency, Codec, CodecSpec, FormatParams, VideoOrientation, and the H265 profile types (H265ProfileTierLevel, H265Profile, H265Tier, H265Level) — the last of which FormatParams transitively requires. Frequency(NonZeroU32) relies on drv 0.4.3's NonZero ToStatic impls. The feature is off by default, so non-drv consumers pay no dependency. Support MediaTime as a drv::Input via an identity ToStatic impl MediaTime's PartialEq rebases to a common timebase before comparing, so the structural drv::Input derive would diverge from its real equality. It's Copy + 'static, so give it a hand-written identity ToStatic impl that defers to that PartialEq — the same shape drv uses for primitives.
1 parent cdca17f commit ee8a2bc

11 files changed

Lines changed: 126 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ subtle = "2.0.0"
5959
arrayvec = "0.7.6"
6060
serde = { version = "1.0.152", features = ["derive"] }
6161
dimpl = { version = "0.6.2", default-features = false }
62+
drv = { version = "0.4.3" }
6263
time = "0.3"
6364
base64ct = "1"
6465

@@ -118,6 +119,13 @@ examples = ["rouille/rustls"]
118119
_internal_dont_use_log_stats = []
119120
_internal_test_exports = ["str0m-proto/_internal_test_exports", "is/_internal_test_exports"]
120121

122+
# Derives `drv::Input` (drv's memoization cache-key plumbing) on the public
123+
# identity types — Mid, Rid, Ssrc, Pt, SessionId, SeqNo, Direction, MediaKind,
124+
# Frequency, Codec, CodecSpec, FormatParams, VideoOrientation, and the H265
125+
# profile types — so downstream `#[drv::memo]` queries can take them by value.
126+
# Off by default.
127+
drv = ["dep:drv"]
128+
121129
[dependencies]
122130
tracing.workspace = true
123131
fastrand.workspace = true
@@ -135,6 +143,8 @@ dimpl.workspace = true
135143
str0m-proto = { workspace = true, features = ["dtls"] }
136144
is.workspace = true
137145

146+
drv = { workspace = true, optional = true }
147+
138148
# Crypto providers
139149
str0m-aws-lc-rs = { workspace = true, optional = true }
140150
str0m-rust-crypto = { workspace = true, optional = true }

src/format/codec.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use super::format_params::FormatParams;
88

99
/// Codec specification
1010
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
11+
#[cfg_attr(feature = "drv", derive(drv::Input))]
1112
pub struct CodecSpec {
1213
/// The codec identifier.
1314
pub codec: Codec,
@@ -25,6 +26,7 @@ pub struct CodecSpec {
2526

2627
/// Known codecs.
2728
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
29+
#[cfg_attr(feature = "drv", derive(drv::Input))]
2830
#[non_exhaustive]
2931
#[allow(missing_docs)]
3032
pub enum Codec {

src/format/format_params.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::sdp::FormatParam;
55

66
/// Codec specific format parameters.
77
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
8+
#[cfg_attr(feature = "drv", derive(drv::Input))]
89
pub struct FormatParams {
910
/// Opus specific parameter.
1011
///

src/packet/h265_profile.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
77
/// Represents the three SDP fmtp parameters `profile-id`, `tier-flag`, and `level-id`
88
/// as defined in RFC 7798 §7.1 and ITU-T H.265 Annex A.
99
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
10+
#[cfg_attr(feature = "drv", derive(drv::Input))]
1011
pub struct H265ProfileTierLevel {
1112
profile: H265Profile,
1213
tier: H265Tier,
@@ -94,6 +95,7 @@ impl From<(u8, u8, u8)> for H265ProfileTierLevel {
9495

9596
/// H.265 profile as defined in ITU-T H.265 Annex A.
9697
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
98+
#[cfg_attr(feature = "drv", derive(drv::Input))]
9799
pub enum H265Profile {
98100
/// Main profile (profile_id=1).
99101
Main,
@@ -160,6 +162,7 @@ impl H265Profile {
160162

161163
/// H.265 tier (Main or High).
162164
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
165+
#[cfg_attr(feature = "drv", derive(drv::Input))]
163166
pub enum H265Tier {
164167
/// Main tier (tier_flag=0).
165168
Main,
@@ -192,6 +195,7 @@ impl H265Tier {
192195
///
193196
/// Level IDs are 30× the level number (e.g., Level 3.1 = 93).
194197
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
198+
#[cfg_attr(feature = "drv", derive(drv::Input))]
195199
#[repr(u8)]
196200
#[rustfmt::skip]
197201
pub enum H265Level {

src/packet/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ mod payload;
6767
pub(crate) use payload::Payloader;
6868

6969
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70+
#[cfg_attr(feature = "drv", derive(drv::Input))]
7071
/// Types of media.
7172
pub enum MediaKind {
7273
/// Audio media.

src/rtp/dir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::fmt;
44
///
55
/// And also extmap direction.
66
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7+
#[cfg_attr(feature = "drv", derive(drv::Input))]
78
pub enum Direction {
89
/// Send only direction.
910
SendOnly,

src/rtp/ext.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,7 @@ impl fmt::Debug for ExtensionMap {
12221222

12231223
/// How the video is rotated.
12241224
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1225+
#[cfg_attr(feature = "drv", derive(drv::Input))]
12251226
pub enum VideoOrientation {
12261227
/// Not rotated.
12271228
Deg0 = 0,

src/rtp/id.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ macro_rules! num_id {
123123
/// 3 incoming StreamRx, but since they belong to the same media,
124124
/// the have the same `Mid`.
125125
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
126+
#[cfg_attr(feature = "drv", derive(drv::Input))]
126127
pub struct Mid([u8; 16]);
127128
str_id!(Mid, "Mid", 16, 3);
128129

@@ -134,6 +135,7 @@ str_id!(Mid, "Mid", 16, 3);
134135
/// In SDP this is an optional value that will be seen in [`MediaData`][crate::media::MediaData]
135136
/// if the remote peer is configured for simulcast.
136137
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
138+
#[cfg_attr(feature = "drv", derive(drv::Input))]
137139
pub struct Rid([u8; 8]);
138140
str_id!(Rid, "Rid", 8, 3);
139141

@@ -143,6 +145,7 @@ str_id!(Rid, "Rid", 8, 3);
143145
/// with at least one synchronization source. Multiple sources for the same stream happens
144146
/// for RTX (resend) and simulcast.
145147
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
148+
#[cfg_attr(feature = "drv", derive(drv::Input))]
146149
pub struct Ssrc(u32);
147150
num_id!(Ssrc, u32);
148151

@@ -163,13 +166,15 @@ impl Ssrc {
163166
///
164167
/// PTs in RTP headers are 7 bits. Values >=128 are not valid.
165168
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
169+
#[cfg_attr(feature = "drv", derive(drv::Input))]
166170
pub struct Pt(u8);
167171
num_id!(Pt, u8);
168172

169173
/// Identifier of an SDP session.
170174
///
171175
/// This value is rarely interesting, but is part of the SDP OFFER and ANSWER.
172176
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
177+
#[cfg_attr(feature = "drv", derive(drv::Input))]
173178
pub struct SessionId(u64);
174179
num_id!(SessionId, u64);
175180

@@ -194,6 +199,7 @@ num_id!(SessionId, u64);
194199
/// assert_eq!(b, 1);
195200
/// ```
196201
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
202+
#[cfg_attr(feature = "drv", derive(drv::Input))]
197203
pub struct SeqNo(u64);
198204
num_id!(SeqNo, u64);
199205

src/rtp/mtime.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use serde::{Deserialize, Serialize};
3333
/// let mtime = MediaTime::new(2000, freq);
3434
/// ```
3535
#[derive(Debug, Clone, Copy, Serialize)]
36+
#[cfg_attr(feature = "drv", derive(drv::Input))]
3637
pub struct Frequency(NonZeroU32);
3738

3839
impl Frequency {
@@ -332,6 +333,22 @@ impl PartialEq for MediaTime {
332333
}
333334
impl Eq for MediaTime {}
334335

336+
// `MediaTime`'s `PartialEq` rebases to a common timebase before comparing,
337+
// so the structural `drv::Input` derive (raw numerator + frequency) would
338+
// diverge from its real equality. It's `Copy + 'static`, so give it an
339+
// identity `ToStatic` that defers to that `PartialEq` — mirroring how drv
340+
// treats primitives.
341+
#[cfg(feature = "drv")]
342+
impl drv::ToStatic for MediaTime {
343+
type Static = MediaTime;
344+
fn to_static(&self) -> MediaTime {
345+
*self
346+
}
347+
fn eq_static(&self, other: &MediaTime) -> bool {
348+
self == other
349+
}
350+
}
351+
335352
impl PartialOrd for MediaTime {
336353
#[inline(always)]
337354
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {

0 commit comments

Comments
 (0)