blob: 3598a6626fdf13534c8d70ed18da7ec5d9061af6 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/protocol/webrtc_video_track_source.h"
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "remoting/protocol/webrtc_video_frame_adapter.h"
namespace remoting {
namespace protocol {
WebrtcVideoTrackSource::WebrtcVideoTrackSource(
AddSinkCallback add_sink_callback)
: add_sink_callback_(add_sink_callback),
main_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
WebrtcVideoTrackSource::~WebrtcVideoTrackSource() = default;
webrtc::MediaSourceInterface::SourceState WebrtcVideoTrackSource::state()
const {
return kLive;
}
bool WebrtcVideoTrackSource::remote() const {
return false;
}
bool WebrtcVideoTrackSource::is_screencast() const {
return true;
}
absl::optional<bool> WebrtcVideoTrackSource::needs_denoising() const {
return absl::nullopt;
}
bool WebrtcVideoTrackSource::GetStats(
webrtc::VideoTrackSourceInterface::Stats* stats) {
return false;
}
void WebrtcVideoTrackSource::AddOrUpdateSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
const rtc::VideoSinkWants& wants) {
DCHECK(sink);
if (sink_ && (sink != sink_)) {
// The same sink can be added more than once, but there should only be 1
// in total.
LOG(WARNING) << "More than one sink added, only the latest will be used.";
}
sink_ = sink;
main_task_runner_->PostTask(FROM_HERE,
base::BindRepeating(add_sink_callback_, wants));
}
void WebrtcVideoTrackSource::RemoveSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) {
DCHECK(sink);
if (sink != sink_) {
// This might happen if more than one sink was added.
LOG(WARNING) << "RemoveSink() called with unexpected sink.";
return;
}
sink_ = nullptr;
}
bool WebrtcVideoTrackSource::SupportsEncodedOutput() const {
return false;
}
void WebrtcVideoTrackSource::GenerateKeyFrame() {}
void WebrtcVideoTrackSource::AddEncodedSink(
rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame>* sink) {}
void WebrtcVideoTrackSource::RemoveEncodedSink(
rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame>* sink) {}
void WebrtcVideoTrackSource::SendCapturedFrame(
std::unique_ptr<webrtc::DesktopFrame> desktop_frame,
std::unique_ptr<WebrtcVideoEncoder::FrameStats> frame_stats) {
if (!sink_) {
LOG(WARNING) << "No sink registered, dropping frame.";
return;
}
webrtc::VideoFrame video_frame = WebrtcVideoFrameAdapter::CreateVideoFrame(
std::move(desktop_frame), std::move(frame_stats));
// Wrap-around behavior of '++' is defined for unsigned types.
// VideoFrame::id() is a 16-bit number which could wrap back to 0 many times
// during a connection.
video_frame.set_id(frame_id_++);
sink_->OnFrame(video_frame);
}
} // namespace protocol
} // namespace remoting