webrtc_sys/
video_track.rs1use std::sync::Arc;
16
17use cxx::UniquePtr;
18
19use crate::{impl_thread_safety, video_frame::ffi::VideoFrame};
20
21#[cxx::bridge(namespace = "livekit_ffi")]
22pub mod ffi {
23 #[repr(i32)]
24 pub enum ContentHint {
25 None,
26 Fluid,
27 Detailed,
28 Text,
29 }
30
31 #[derive(Debug)]
32 pub struct VideoTrackSourceConstraints {
33 pub has_min_fps: bool,
34 pub min_fps: f64,
35 pub has_max_fps: bool,
36 pub max_fps: f64,
37 }
38
39 #[derive(Debug)]
40 pub struct VideoResolution {
41 pub width: u32,
42 pub height: u32,
43 }
44
45 #[derive(Debug)]
46 pub struct FrameMetadata {
47 pub has_packet_trailer: bool,
48 pub user_timestamp: u64,
49 pub frame_id: u32,
50 pub user_data: Vec<u8>,
51 }
52
53 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
54 #[repr(i32)]
55 pub enum EncodedVideoCodec {
56 H264,
57 H265,
58 VP8,
59 VP9,
60 AV1,
61 }
62
63 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
64 #[repr(i32)]
65 pub enum EncodedFrameType {
66 Key,
67 Delta,
68 }
69
70 #[derive(Debug)]
71 pub struct EncodedVideoFrameData {
72 pub codec: EncodedVideoCodec,
73 pub frame_type: EncodedFrameType,
74 pub timestamp_us: i64,
75 }
76
77 #[derive(Debug)]
78 pub struct EncodedRateControlRequest {
79 pub has_request: bool,
80 pub target_bitrate_bps: u64,
81 pub framerate_fps: f64,
82 }
83
84 extern "C++" {
85 include!("livekit/video_frame.h");
86 include!("livekit/media_stream_track.h");
87
88 type VideoFrame = crate::video_frame::ffi::VideoFrame;
89 type MediaStreamTrack = crate::media_stream_track::ffi::MediaStreamTrack;
90 }
91
92 extern "C++" {
93 include!("livekit/packet_trailer.h");
94 include!("livekit/video_track.h");
95
96 type PacketTrailerHandler = crate::packet_trailer::ffi::PacketTrailerHandler;
97 }
98
99 unsafe extern "C++" {
100
101 type VideoTrack;
102 type NativeVideoSink;
103 type VideoTrackSource;
104
105 fn add_sink(self: &VideoTrack, sink: &SharedPtr<NativeVideoSink>);
106 fn remove_sink(self: &VideoTrack, sink: &SharedPtr<NativeVideoSink>);
107 fn set_should_receive(self: &VideoTrack, should_receive: bool);
108 fn should_receive(self: &VideoTrack) -> bool;
109 fn content_hint(self: &VideoTrack) -> ContentHint;
110 fn set_content_hint(self: &VideoTrack, hint: ContentHint);
111 fn new_native_video_sink(observer: Box<VideoSinkWrapper>) -> SharedPtr<NativeVideoSink>;
112
113 fn video_resolution(self: &VideoTrackSource) -> VideoResolution;
114 fn on_captured_frame(
115 self: &VideoTrackSource,
116 frame: &UniquePtr<VideoFrame>,
117 frame_metadata: &FrameMetadata,
118 ) -> bool;
119 fn capture_encoded_frame(
120 self: &VideoTrackSource,
121 width: i32,
122 height: i32,
123 frame: &EncodedVideoFrameData,
124 payload: &[u8],
125 frame_metadata: &FrameMetadata,
126 ) -> bool;
127 fn take_keyframe_request(self: &VideoTrackSource) -> bool;
128 fn take_rate_control_request(self: &VideoTrackSource) -> EncodedRateControlRequest;
129 fn set_packet_trailer_handler(
130 self: &VideoTrackSource,
131 handler: SharedPtr<PacketTrailerHandler>,
132 );
133 fn new_video_track_source(
134 resolution: &VideoResolution,
135 is_screencast: bool,
136 ) -> SharedPtr<VideoTrackSource>;
137 fn video_to_media(track: SharedPtr<VideoTrack>) -> SharedPtr<MediaStreamTrack>;
138 unsafe fn media_to_video(track: SharedPtr<MediaStreamTrack>) -> SharedPtr<VideoTrack>;
139 fn _shared_video_track() -> SharedPtr<VideoTrack>;
140 }
141
142 extern "Rust" {
143 type VideoSinkWrapper;
144
145 fn on_frame(self: &VideoSinkWrapper, frame: UniquePtr<VideoFrame>);
146 fn on_discarded_frame(self: &VideoSinkWrapper);
147 fn on_constraints_changed(
148 self: &VideoSinkWrapper,
149 constraints: VideoTrackSourceConstraints,
150 );
151 }
152}
153
154impl_thread_safety!(ffi::VideoTrack, Send + Sync);
155impl_thread_safety!(ffi::NativeVideoSink, Send + Sync);
156impl_thread_safety!(ffi::VideoTrackSource, Send + Sync);
157
158pub trait VideoSink: Send {
159 fn on_frame(&self, frame: UniquePtr<VideoFrame>);
160 fn on_discarded_frame(&self);
161 fn on_constraints_changed(&self, constraints: ffi::VideoTrackSourceConstraints);
162}
163
164pub struct VideoSinkWrapper {
165 observer: Arc<dyn VideoSink>,
166}
167
168impl VideoSinkWrapper {
169 pub fn new(observer: Arc<dyn VideoSink>) -> Self {
170 Self { observer }
171 }
172
173 fn on_frame(&self, frame: UniquePtr<VideoFrame>) {
174 self.observer.on_frame(frame);
175 }
176
177 fn on_discarded_frame(&self) {
178 self.observer.on_discarded_frame();
179 }
180
181 fn on_constraints_changed(&self, constraints: ffi::VideoTrackSourceConstraints) {
182 self.observer.on_constraints_changed(constraints);
183 }
184}