[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:
parent
2148f8ed71
commit
6a78e93346
@ -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
6
api/test/video/DEPS
Normal 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",
|
||||
],
|
||||
}
|
||||
54
api/test/video/test_video_track_source.cc
Normal file
54
api/test/video/test_video_track_source.cc
Normal 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
|
||||
78
api/test/video/test_video_track_source.h
Normal file
78
api/test/video/test_video_track_source.h
Normal 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_
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user