-
Notifications
You must be signed in to change notification settings - Fork 186
add user_data trailer type #1180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
3a37ba6
add user_data trailer type
chenosaurus 6bf5b38
fix max length
chenosaurus 87ea8d7
update local video example to publish user_data
chenosaurus 8b7a7bd
generated protobuf
github-actions[bot] b63418f
bump protocol to 1.48.0
chenosaurus 7c896e6
Merge branch 'dc/fm_user_data' of github.com:livekit/rust-sdks into d…
chenosaurus d96d855
generated protobuf
github-actions[bot] d9f101a
add changeset
chenosaurus 796ca23
Merge branch 'dc/fm_user_data' of github.com:livekit/rust-sdks into d…
chenosaurus 80fec16
fix build error, new field in proto
chenosaurus 68e88b5
fix build issues from protocol bump
chenosaurus 5671d3f
add check for user data feature
chenosaurus 82591df
Merge remote-tracking branch 'origin/main' into dc/fm_user_data
chenosaurus cc672f9
fix dupe properties
chenosaurus b19dfbd
Merge remote-tracking branch 'origin/main' into dc/fm_user_data
chenosaurus 2b732c2
dupe property
chenosaurus ac9109b
cargo fmt
chenosaurus 10d5fc9
ensure all frame metadata fields are optional
chenosaurus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| livekit: minor | ||
| livekit-ffi: minor | ||
| livekit-protocol: minor | ||
| --- | ||
|
|
||
| Add `user_data` support to frame metadata, allowing arbitrary application-supplied bytes to be attached to a video frame via the `PTF_USER_DATA` packet trailer feature. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| //! Shared 6-channel codec for the `--attach-user-data` demo. | ||
| //! | ||
| //! Six channel values are encoded as little-endian `int16` fixed-point, 2 bytes | ||
| //! per channel = 12 bytes total, and shipped in the `user_data` frame-metadata | ||
| //! trailer field. The full `int16` range maps to `±VALUE_RANGE`, giving | ||
| //! ~1/32767 of the range in resolution — well within the ~232-byte trailer | ||
| //! budget. | ||
| //! | ||
| //! Both the `publisher` and `subscriber` binaries include this file via | ||
| //! `mod user_data;` so they agree on the wire format. | ||
|
|
||
| /// Number of channels carried in the user_data payload. | ||
| pub const NUM_CHANNELS: usize = 6; | ||
|
|
||
| /// Encoded payload size in bytes (2 bytes per channel). | ||
| pub const ENCODED_LEN: usize = NUM_CHANNELS * 2; | ||
|
|
||
| /// Value that maps to `i16::MAX`. Channel values are normalized to | ||
| /// `±VALUE_RANGE` before quantization. | ||
| pub const VALUE_RANGE: f32 = 1.0; | ||
|
|
||
| /// Value units per `int16` step. | ||
| fn scale() -> f32 { | ||
| VALUE_RANGE / i16::MAX as f32 | ||
| } | ||
|
|
||
| /// Clamp a channel value to the encodable `±VALUE_RANGE` range. | ||
| pub fn clamp_value(value: f32) -> f32 { | ||
| value.clamp(-VALUE_RANGE, VALUE_RANGE) | ||
| } | ||
|
|
||
| /// Encode 6 channel values into 12 little-endian `int16` bytes. | ||
| pub fn encode(values: &[f32; NUM_CHANNELS]) -> Vec<u8> { | ||
| let s = scale(); | ||
| let mut buf = Vec::with_capacity(ENCODED_LEN); | ||
| for &v in values { | ||
| let q = (v / s).round().clamp(i16::MIN as f32, i16::MAX as f32) as i16; | ||
| buf.extend_from_slice(&q.to_le_bytes()); | ||
| } | ||
| buf | ||
| } | ||
|
|
||
| /// Decode 6 channel values from the `user_data` payload. Returns `None` if the | ||
| /// buffer is too short to hold all six values. | ||
| pub fn decode(buf: &[u8]) -> Option<[f32; NUM_CHANNELS]> { | ||
| if buf.len() < ENCODED_LEN { | ||
| return None; | ||
| } | ||
| let s = scale(); | ||
| let mut out = [0.0f32; NUM_CHANNELS]; | ||
| for (i, chunk) in buf.chunks_exact(2).take(NUM_CHANNELS).enumerate() { | ||
| out[i] = i16::from_le_bytes([chunk[0], chunk[1]]) as f32 * s; | ||
| } | ||
| Some(out) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn round_trips_within_quantization_error() { | ||
| let values = [0.0, 0.5, -0.75, 1.0, -0.1, 0.9]; | ||
| let decoded = decode(&encode(&values)).unwrap(); | ||
| for (v, d) in values.iter().zip(decoded.iter()) { | ||
| assert!((v - d).abs() <= scale(), "got {d}, expected ~{v}"); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn clamp_keeps_within_range() { | ||
| assert_eq!(clamp_value(100.0), VALUE_RANGE); | ||
| assert_eq!(clamp_value(-100.0), -VALUE_RANGE); | ||
| assert_eq!(clamp_value(0.5), 0.5); | ||
| } | ||
|
|
||
| #[test] | ||
| fn decode_rejects_short_buffer() { | ||
| assert!(decode(&[0u8; ENCODED_LEN - 1]).is_none()); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion(non-blocking): Calling this data channel might imply this is related to WebRTC data channels, not frame metadata.