#pragma once
#include <memory>
#include "api/media_stream_interface.h"
#include "api/video/video_frame.h"
#include "livekit/helper.h"
#include "livekit/media_stream_track.h"
#include "livekit/video_frame.h"
#include "livekit/webrtc.h"
#include "media/base/adapted_video_track_source.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/timestamp_aligner.h"
#include "rust/cxx.h"
namespace livekit_ffi {
class VideoTrack;
class NativeVideoSink;
class VideoTrackSource;
class PacketTrailerHandler; } #include "webrtc-sys/src/video_track.rs.h"
namespace livekit_ffi {
class VideoTrack : public MediaStreamTrack {
private:
friend RtcRuntime;
VideoTrack(std::shared_ptr<RtcRuntime> rtc_runtime,
webrtc::scoped_refptr<webrtc::VideoTrackInterface> track);
public:
~VideoTrack();
void add_sink(const std::shared_ptr<NativeVideoSink>& sink) const;
void remove_sink(const std::shared_ptr<NativeVideoSink>& sink) const;
void set_should_receive(bool should_receive) const;
bool should_receive() const;
ContentHint content_hint() const;
void set_content_hint(ContentHint hint) const;
private:
webrtc::VideoTrackInterface* track() const {
return static_cast<webrtc::VideoTrackInterface*>(track_.get());
}
mutable webrtc::Mutex mutex_;
mutable std::vector<std::shared_ptr<NativeVideoSink>> sinks_;
};
class NativeVideoSink : public webrtc::VideoSinkInterface<webrtc::VideoFrame> {
public:
explicit NativeVideoSink(rust::Box<VideoSinkWrapper> observer);
void OnFrame(const webrtc::VideoFrame& frame) override;
void OnDiscardedFrame() override;
void OnConstraintsChanged(
const webrtc::VideoTrackSourceConstraints& constraints) override;
private:
rust::Box<VideoSinkWrapper> observer_;
};
std::shared_ptr<NativeVideoSink> new_native_video_sink(
rust::Box<VideoSinkWrapper> observer);
class VideoTrackSource {
class InternalSource : public webrtc::AdaptedVideoTrackSource {
public:
InternalSource(const VideoResolution& resolution,
bool is_screencast); ~InternalSource() override;
bool is_screencast() const override;
std::optional<bool> needs_denoising() const override;
SourceState state() const override;
bool remote() const override;
VideoResolution video_resolution() const;
bool on_captured_frame(const webrtc::VideoFrame& frame,
const FrameMetadata& frame_metadata);
void set_packet_trailer_handler(
std::shared_ptr<PacketTrailerHandler> handler);
private:
mutable webrtc::Mutex mutex_;
webrtc::TimestampAligner timestamp_aligner_;
VideoResolution resolution_;
std::shared_ptr<PacketTrailerHandler> packet_trailer_handler_;
bool is_screencast_;
};
public:
VideoTrackSource(const VideoResolution& resolution, bool is_screencast);
VideoResolution video_resolution() const;
bool on_captured_frame(const std::unique_ptr<VideoFrame>& frame,
const FrameMetadata& frame_metadata)
const;
bool capture_dmabuf_frame(int dmabuf_fd,
int width,
int height,
int pixel_format,
int64_t timestamp_us,
const FrameMetadata& frame_metadata) const;
void set_packet_trailer_handler(
std::shared_ptr<PacketTrailerHandler> handler) const;
webrtc::scoped_refptr<InternalSource> get() const;
private:
webrtc::scoped_refptr<InternalSource> source_;
};
std::shared_ptr<VideoTrackSource> new_video_track_source(
const VideoResolution& resolution, bool is_screencast);
static std::shared_ptr<MediaStreamTrack> video_to_media(
std::shared_ptr<VideoTrack> track) {
return track;
}
static std::shared_ptr<VideoTrack> media_to_video(
std::shared_ptr<MediaStreamTrack> track) {
return std::static_pointer_cast<VideoTrack>(track);
}
static std::shared_ptr<VideoTrack> _shared_video_track() {
return nullptr; }
}