use crate::impl_thread_safety; use crate::video_frame::ffi::VideoFrame; use cxx::UniquePtr; use std::sync::Arc; #[cxx::bridge(namespace = "livekit")] pub mod ffi { #[repr(i32)] pub enum ContentHint { None, Fluid, Detailed, Text, } #[derive(Debug)] pub struct VideoTrackSourceConstraints { pub has_min_fps: bool, pub min_fps: f64, pub has_max_fps: bool, pub max_fps: f64, } #[derive(Debug)] pub struct VideoResolution { pub width: u32, pub height: u32, } extern "C++" { include!("livekit/video_frame.h"); include!("livekit/media_stream_track.h"); type VideoFrame = crate::video_frame::ffi::VideoFrame; type MediaStreamTrack = crate::media_stream_track::ffi::MediaStreamTrack; } unsafe extern "C++" { include!("livekit/video_track.h"); type VideoTrack; type NativeVideoSink; type VideoTrackSource; fn add_sink(self: &VideoTrack, sink: &SharedPtr); fn remove_sink(self: &VideoTrack, sink: &SharedPtr); fn set_should_receive(self: &VideoTrack, should_receive: bool); fn should_receive(self: &VideoTrack) -> bool; fn content_hint(self: &VideoTrack) -> ContentHint; fn set_content_hint(self: &VideoTrack, hint: ContentHint); fn new_native_video_sink(observer: Box) -> SharedPtr; fn video_resolution(self: &VideoTrackSource) -> VideoResolution; fn on_captured_frame(self: &VideoTrackSource, frame: &UniquePtr) -> bool; fn new_video_track_source(resolution: &VideoResolution) -> SharedPtr; fn video_to_media(track: SharedPtr) -> SharedPtr; unsafe fn media_to_video(track: SharedPtr) -> SharedPtr; fn _shared_video_track() -> SharedPtr; } extern "Rust" { type VideoSinkWrapper; fn on_frame(self: &VideoSinkWrapper, frame: UniquePtr); fn on_discarded_frame(self: &VideoSinkWrapper); fn on_constraints_changed( self: &VideoSinkWrapper, constraints: VideoTrackSourceConstraints, ); } } impl_thread_safety!(ffi::VideoTrack, Send + Sync); impl_thread_safety!(ffi::NativeVideoSink, Send + Sync); impl_thread_safety!(ffi::VideoTrackSource, Send + Sync); pub trait VideoSink: Send { fn on_frame(&self, frame: UniquePtr); fn on_discarded_frame(&self); fn on_constraints_changed(&self, constraints: ffi::VideoTrackSourceConstraints); } pub struct VideoSinkWrapper { observer: Arc, } impl VideoSinkWrapper { pub fn new(observer: Arc) -> Self { Self { observer } } fn on_frame(&self, frame: UniquePtr) { self.observer.on_frame(frame); } fn on_discarded_frame(&self) { self.observer.on_discarded_frame(); } fn on_constraints_changed(&self, constraints: ffi::VideoTrackSourceConstraints) { self.observer.on_constraints_changed(constraints); } }