Files

141 lines
4.1 KiB
C++

/*
* Copyright 2023 LiveKit
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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 {
class VideoTrack;
class NativeVideoSink;
class VideoTrackSource;
} // namespace livekit
#include "webrtc-sys/src/video_track.rs.h"
namespace livekit {
class VideoTrack : public MediaStreamTrack {
private:
friend RtcRuntime;
VideoTrack(std::shared_ptr<RtcRuntime> rtc_runtime,
rtc::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_;
// Same for AudioTrack:
// Keep a strong reference to the added sinks, so we don't need to
// manage the lifetime safety on the Rust side
mutable std::vector<std::shared_ptr<NativeVideoSink>> sinks_;
};
class NativeVideoSink : public rtc::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 rtc::AdaptedVideoTrackSource {
public:
InternalSource(const VideoResolution&
resolution); // (0, 0) means no resolution/optional, the
// source will guess the resolution at the
// first captured frame
~InternalSource() override;
bool is_screencast() const override;
absl::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);
private:
mutable webrtc::Mutex mutex_;
rtc::TimestampAligner timestamp_aligner_;
VideoResolution resolution_;
};
public:
VideoTrackSource(const VideoResolution& resolution);
VideoResolution video_resolution() const;
bool on_captured_frame(const std::unique_ptr<VideoFrame>& frame)
const; // frames pushed from Rust (+interior mutability)
rtc::scoped_refptr<InternalSource> get() const;
private:
rtc::scoped_refptr<InternalSource> source_;
};
std::shared_ptr<VideoTrackSource> new_video_track_source(
const VideoResolution& resolution);
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; // Ignore
}
} // namespace livekit