[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}
diff --git a/api/test/video/BUILD.gn b/api/test/video/BUILD.gn
index d24ffa5..0eae85a 100644
--- a/api/test/video/BUILD.gn
+++ b/api/test/video/BUILD.gn
@@ -11,7 +11,7 @@
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("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" ]
+}
diff --git a/api/test/video/DEPS b/api/test/video/DEPS
new file mode 100644
index 0000000..2256b34
--- /dev/null
+++ b/api/test/video/DEPS
@@ -0,0 +1,6 @@
+specific_include_rules = {
+ "test_video_track_source\.h": [
+ "+rtc_base/thread_annotations.h",
+ "+rtc_base/system/no_unique_address.h",
+ ],
+}
diff --git a/api/test/video/test_video_track_source.cc b/api/test/video/test_video_track_source.cc
new file mode 100644
index 0000000..c570a7a
--- /dev/null
+++ b/api/test/video/test_video_track_source.cc
@@ -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
diff --git a/api/test/video/test_video_track_source.h b/api/test/video/test_video_track_source.h
new file mode 100644
index 0000000..4e2d138
--- /dev/null
+++ b/api/test/video/test_video_track_source.h
@@ -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_
diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn
index ae9dd64..635b917 100644
--- a/test/pc/e2e/BUILD.gn
+++ b/test/pc/e2e/BUILD.gn
@@ -136,8 +136,10 @@
"../../../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",
diff --git a/test/pc/e2e/media/test_video_capturer_video_track_source.h b/test/pc/e2e/media/test_video_capturer_video_track_source.h
index c883a2e..350766b 100644
--- a/test/pc/e2e/media/test_video_capturer_video_track_source.h
+++ b/test/pc/e2e/media/test_video_capturer_video_track_source.h
@@ -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 @@
}
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
diff --git a/test/test_video_capturer.cc b/test/test_video_capturer.cc
index 4a4adc6..b55eefc 100644
--- a/test/test_video_capturer.cc
+++ b/test/test_video_capturer.cc
@@ -40,6 +40,15 @@
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)) {
diff --git a/test/test_video_capturer.h b/test/test_video_capturer.h
index 6fafd96..3fc03f0 100644
--- a/test/test_video_capturer.h
+++ b/test/test_video_capturer.h
@@ -41,6 +41,10 @@
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 @@
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_;
};