[PCLF] Introduce test video source and make it more controllable

Bug: b/272350185
Change-Id: I15572b7e4d0cb0ce41da676a4eedbc1e138510fc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298047
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39621}
This commit is contained in:
Artem Titov 2023-03-21 13:46:47 +01:00 committed by WebRTC LUCI CQ
parent 2148f8ed71
commit 6a78e93346
8 changed files with 210 additions and 11 deletions

View File

@ -11,7 +11,7 @@ import("../../../webrtc.gni")
rtc_library("function_video_factory") {
visibility = [ "*" ]
testonly = true
public = [
sources = [
"function_video_decoder_factory.h",
"function_video_encoder_factory.h",
]
@ -25,7 +25,27 @@ rtc_library("function_video_factory") {
rtc_library("video_frame_writer") {
visibility = [ "*" ]
testonly = true
public = [ "video_frame_writer.h" ]
sources = [ "video_frame_writer.h" ]
deps = [ "../../video:video_frame" ]
}
rtc_library("test_video_track_source") {
visibility = [ "*" ]
testonly = true
sources = [
"test_video_track_source.cc",
"test_video_track_source.h",
]
deps = [
"../..:media_stream_interface",
"../..:sequence_checker",
"../../../rtc_base:checks",
"../../../rtc_base:macromagic",
"../../../rtc_base/system:no_unique_address",
"../../video:recordable_encoded_frame",
"../../video:video_frame",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}

6
api/test/video/DEPS Normal file
View File

@ -0,0 +1,6 @@
specific_include_rules = {
"test_video_track_source\.h": [
"+rtc_base/thread_annotations.h",
"+rtc_base/system/no_unique_address.h",
],
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "api/test/video/test_video_track_source.h"
#include "api/media_stream_interface.h"
#include "api/sequence_checker.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_source_interface.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace test {
TestVideoTrackSource::TestVideoTrackSource(bool remote)
: state_(kInitializing), remote_(remote) {
worker_thread_checker_.Detach();
}
VideoTrackSourceInterface::SourceState TestVideoTrackSource::state() const {
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
return state_;
}
void TestVideoTrackSource::SetState(SourceState new_state) {
RTC_DCHECK_RUN_ON(&signaling_thread_checker_);
if (state_ != new_state) {
state_ = new_state;
FireOnChanged();
}
}
void TestVideoTrackSource::AddOrUpdateSink(
rtc::VideoSinkInterface<VideoFrame>* sink,
const rtc::VideoSinkWants& wants) {
RTC_DCHECK(worker_thread_checker_.IsCurrent());
source()->AddOrUpdateSink(sink, wants);
}
void TestVideoTrackSource::RemoveSink(
rtc::VideoSinkInterface<VideoFrame>* sink) {
RTC_DCHECK(worker_thread_checker_.IsCurrent());
source()->RemoveSink(sink);
}
} // namespace test
} // namespace webrtc

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef API_TEST_VIDEO_TEST_VIDEO_TRACK_SOURCE_H_
#define API_TEST_VIDEO_TEST_VIDEO_TRACK_SOURCE_H_
#include "absl/types/optional.h"
#include "api/media_stream_interface.h"
#include "api/notifier.h"
#include "api/sequence_checker.h"
#include "api/video/recordable_encoded_frame.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_source_interface.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h"
namespace webrtc {
namespace test {
// Video source that can be used as input for tests.
class TestVideoTrackSource : public Notifier<VideoTrackSourceInterface> {
public:
explicit TestVideoTrackSource(bool remote);
~TestVideoTrackSource() override = default;
void SetState(SourceState new_state);
SourceState state() const override;
bool remote() const override { return remote_; }
bool is_screencast() const override { return false; }
absl::optional<bool> needs_denoising() const override {
return absl::nullopt;
}
bool GetStats(Stats* stats) override { return false; }
void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
const rtc::VideoSinkWants& wants) override;
void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override;
bool SupportsEncodedOutput() const override { return false; }
void GenerateKeyFrame() override {}
void AddEncodedSink(
rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) override {}
void RemoveEncodedSink(
rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) override {}
// Starts producing video.
virtual void Start() = 0;
// Stops producing video.
virtual void Stop() = 0;
virtual void SetScreencast(bool is_screencast) = 0;
protected:
virtual rtc::VideoSourceInterface<VideoFrame>* source() = 0;
private:
RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_;
RTC_NO_UNIQUE_ADDRESS SequenceChecker signaling_thread_checker_;
SourceState state_ RTC_GUARDED_BY(&signaling_thread_checker_);
const bool remote_;
};
} // namespace test
} // namespace webrtc
#endif // API_TEST_VIDEO_TEST_VIDEO_TRACK_SOURCE_H_

View File

@ -136,8 +136,10 @@ if (!build_with_chromium) {
"../../../api:create_frame_generator",
"../../../api:frame_generator_api",
"../../../api:media_stream_interface",
"../../../api:sequence_checker",
"../../../api/test/pclf:media_configuration",
"../../../api/test/pclf:peer_configurer",
"../../../api/test/video:test_video_track_source",
"../../../api/video:video_frame",
"../../../pc:session_description",
"../../../pc:video_track_source",

View File

@ -14,30 +14,54 @@
#include <memory>
#include <utility>
#include "api/sequence_checker.h"
#include "api/test/video/test_video_track_source.h"
#include "api/video/video_frame.h"
#include "api/video/video_source_interface.h"
#include "pc/video_track_source.h"
#include "test/test_video_capturer.h"
namespace webrtc {
namespace webrtc_pc_e2e {
class TestVideoCapturerVideoTrackSource : public VideoTrackSource {
class TestVideoCapturerVideoTrackSource : public test::TestVideoTrackSource {
public:
TestVideoCapturerVideoTrackSource(
std::unique_ptr<test::TestVideoCapturer> video_capturer,
bool is_screencast)
: VideoTrackSource(/*remote=*/false),
: TestVideoTrackSource(/*remote=*/false),
video_capturer_(std::move(video_capturer)),
is_screencast_(is_screencast) {}
is_screencast_(is_screencast) {
sequence_checker_.Detach();
}
TestVideoCapturerVideoTrackSource(const TestVideoCapturerVideoTrackSource&) =
delete;
TestVideoCapturerVideoTrackSource& operator=(
const TestVideoCapturerVideoTrackSource&) = delete;
TestVideoCapturerVideoTrackSource(TestVideoCapturerVideoTrackSource&&) =
delete;
TestVideoCapturerVideoTrackSource& operator=(
TestVideoCapturerVideoTrackSource&&) = delete;
~TestVideoCapturerVideoTrackSource() = default;
void Start() { SetState(kLive); }
void Start() override { SetState(kLive); }
void Stop() { SetState(kMuted); }
void Stop() override { SetState(kMuted); }
bool is_screencast() const override { return is_screencast_; }
bool is_screencast() const override {
RTC_DCHECK_RUN_ON(&sequence_checker_);
return is_screencast_;
}
void SetDisableAdaptation(bool disable_adaptation) {
video_capturer_->SetDisableAdaptation(disable_adaptation);
}
void SetScreencast(bool is_screencast) override {
RTC_DCHECK_RUN_ON(&sequence_checker_);
is_screencast_ = is_screencast;
}
protected:
rtc::VideoSourceInterface<VideoFrame>* source() override {
@ -45,8 +69,9 @@ class TestVideoCapturerVideoTrackSource : public VideoTrackSource {
}
private:
std::unique_ptr<test::TestVideoCapturer> video_capturer_;
const bool is_screencast_;
const std::unique_ptr<test::TestVideoCapturer> video_capturer_;
SequenceChecker sequence_checker_;
bool is_screencast_ RTC_GUARDED_BY(sequence_checker_);
};
} // namespace webrtc_pc_e2e

View File

@ -40,6 +40,15 @@ void TestVideoCapturer::OnFrame(const VideoFrame& original_frame) {
VideoFrame frame = MaybePreprocess(original_frame);
bool disable_adaptation;
{
MutexLock lock(&lock_);
disable_adaptation = disable_adaptation_;
}
if (disable_adaptation) {
broadcaster_.OnFrame(frame);
}
if (!video_adapter_.AdaptFrameResolution(
frame.width(), frame.height(), frame.timestamp_us() * 1000,
&cropped_width, &cropped_height, &out_width, &out_height)) {

View File

@ -41,6 +41,10 @@ class TestVideoCapturer : public rtc::VideoSourceInterface<VideoFrame> {
MutexLock lock(&lock_);
preprocessor_ = std::move(preprocessor);
}
void SetDisableAdaptation(bool disable_adaptation) {
MutexLock lock(&lock_);
disable_adaptation_ = disable_adaptation;
}
void OnOutputFormatRequest(int width,
int height,
const absl::optional<int>& max_fps);
@ -55,6 +59,7 @@ class TestVideoCapturer : public rtc::VideoSourceInterface<VideoFrame> {
Mutex lock_;
std::unique_ptr<FramePreprocessor> preprocessor_ RTC_GUARDED_BY(lock_);
bool disable_adaptation_ RTC_GUARDED_BY(lock_) = false;
rtc::VideoBroadcaster broadcaster_;
cricket::VideoAdapter video_adapter_;
};