Refactor PeerConnectionIntegrationTest to not use cricket::VideoCapturer

Bug: webrtc:6353
Change-Id: Ie3f6411d8e21eaad6927c94af126213e650994ca
Reviewed-on: https://webrtc-review.googlesource.com/74587
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23203}
This commit is contained in:
Niels Möller 2018-05-11 10:34:46 +02:00 committed by Commit Bot
parent c43fc20a44
commit 5c7efe7fe8
5 changed files with 105 additions and 81 deletions

View File

@ -11,6 +11,7 @@
#include "media/base/fakeframesource.h"
#include "api/video/i420_buffer.h"
#include "rtc_base/checks.h"
namespace cricket {
@ -21,7 +22,7 @@ FakeFrameSource::FakeFrameSource(int width, int height, int interval_us)
RTC_CHECK_GT(interval_us_, 0);
}
webrtc::VideoRotation FakeFrameSource::GetRotation() {
webrtc::VideoRotation FakeFrameSource::GetRotation() const {
return rotation_;
}
@ -29,12 +30,28 @@ void FakeFrameSource::SetRotation(webrtc::VideoRotation rotation) {
rotation_ = rotation;
}
webrtc::VideoFrame FakeFrameSource::GetFrameRotationApplied() {
switch (rotation_) {
case webrtc::kVideoRotation_0:
case webrtc::kVideoRotation_180:
return GetFrame(width_, height_, webrtc::kVideoRotation_0, interval_us_);
case webrtc::kVideoRotation_90:
case webrtc::kVideoRotation_270:
return GetFrame(height_, width_, webrtc::kVideoRotation_0, interval_us_);
}
RTC_NOTREACHED() << "Invalid rotation value: " << static_cast<int>(rotation_);
// Without this return, the Windows Visual Studio compiler complains
// "not all control paths return a value".
return GetFrame();
}
webrtc::VideoFrame FakeFrameSource::GetFrame() {
return GetFrame(width_, height_, interval_us_);
return GetFrame(width_, height_, rotation_, interval_us_);
}
webrtc::VideoFrame FakeFrameSource::GetFrame(int width,
int height,
webrtc::VideoRotation rotation,
int interval_us) {
RTC_CHECK_GT(width, 0);
RTC_CHECK_GT(height, 0);
@ -45,7 +62,7 @@ webrtc::VideoFrame FakeFrameSource::GetFrame(int width,
buffer->InitializeData();
webrtc::VideoFrame frame =
webrtc::VideoFrame(buffer, rotation_, next_timestamp_us_);
webrtc::VideoFrame(buffer, rotation, next_timestamp_us_);
next_timestamp_us_ += interval_us;
return frame;

View File

@ -21,12 +21,17 @@ class FakeFrameSource {
public:
FakeFrameSource(int width, int height, int interval_us);
webrtc::VideoRotation GetRotation();
webrtc::VideoRotation GetRotation() const;
void SetRotation(webrtc::VideoRotation rotation);
webrtc::VideoFrame GetFrame();
// Override default size and interval.
webrtc::VideoFrame GetFrame(int width, int height, int interval_us);
webrtc::VideoFrame GetFrameRotationApplied();
// Override configuration.
webrtc::VideoFrame GetFrame(int width,
int height,
webrtc::VideoRotation rotation,
int interval_us);
private:
const int width_;

View File

@ -53,8 +53,8 @@ bool FakeVideoCapturer::CaptureCustomFrame(int width, int height) {
// Default to 30fps.
// TODO(nisse): Would anything break if we always stick to
// the configure frame interval?
return CaptureFrame(
frame_source_->GetFrame(width, height, rtc::kNumMicrosecsPerSec / 30));
return CaptureFrame(frame_source_->GetFrame(width, height, rotation_,
rtc::kNumMicrosecsPerSec / 30));
}
bool FakeVideoCapturer::CaptureFrame(const webrtc::VideoFrame& frame) {

View File

@ -48,7 +48,7 @@
#include "pc/rtpmediautils.h"
#include "pc/sessiondescription.h"
#include "pc/test/fakeaudiocapturemodule.h"
#include "pc/test/fakeperiodicvideocapturer.h"
#include "pc/test/fakeperiodicvideosource.h"
#include "pc/test/fakertccertificategenerator.h"
#include "pc/test/fakevideotrackrenderer.h"
#include "pc/test/mockpeerconnectionobservers.h"
@ -238,6 +238,20 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
return client;
}
~PeerConnectionWrapper() {
// Tear down video sources in the proper order.
for (const auto& video_source : fake_video_sources_) {
// No more calls to downstream OnFrame
video_source->Stop();
}
for (const auto& track_source : video_track_sources_) {
// No more calls to upstream AddOrUpdateSink
track_source->OnSourceDestroyed();
}
fake_video_sources_.clear();
video_track_sources_.clear();
}
webrtc::PeerConnectionFactoryInterface* pc_factory() const {
return peer_connection_factory_.get();
}
@ -325,18 +339,21 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
}
rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack() {
return CreateLocalVideoTrackInternal(FakeConstraints(),
webrtc::kVideoRotation_0);
return CreateLocalVideoTrackInternal(
webrtc::FakePeriodicVideoSource::Config());
}
rtc::scoped_refptr<webrtc::VideoTrackInterface>
CreateLocalVideoTrackWithConstraints(const FakeConstraints& constraints) {
return CreateLocalVideoTrackInternal(constraints, webrtc::kVideoRotation_0);
CreateLocalVideoTrackWithConfig(
webrtc::FakePeriodicVideoSource::Config config) {
return CreateLocalVideoTrackInternal(config);
}
rtc::scoped_refptr<webrtc::VideoTrackInterface>
CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) {
return CreateLocalVideoTrackInternal(FakeConstraints(), rotation);
webrtc::FakePeriodicVideoSource::Config config;
config.rotation = rotation;
return CreateLocalVideoTrackInternal(config);
}
rtc::scoped_refptr<RtpSenderInterface> AddTrack(
@ -679,23 +696,20 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
}
rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrackInternal(
const FakeConstraints& constraints,
webrtc::VideoRotation rotation) {
webrtc::FakePeriodicVideoSource::Config config) {
// Set max frame rate to 10fps to reduce the risk of test flakiness.
// TODO(deadbeef): Do something more robust.
FakeConstraints source_constraints = constraints;
source_constraints.SetMandatoryMaxFrameRate(10);
config.frame_interval_ms = 100;
cricket::FakeVideoCapturer* fake_capturer =
new webrtc::FakePeriodicVideoCapturer();
fake_capturer->SetRotation(rotation);
video_capturers_.push_back(fake_capturer);
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source =
peer_connection_factory_->CreateVideoSource(fake_capturer,
&source_constraints);
fake_video_sources_.emplace_back(
rtc::MakeUnique<webrtc::FakePeriodicVideoSource>(config));
video_track_sources_.emplace_back(
new rtc::RefCountedObject<webrtc::VideoTrackSource>(
fake_video_sources_.back().get(), false /* remote */));
rtc::scoped_refptr<webrtc::VideoTrackInterface> track(
peer_connection_factory_->CreateVideoTrack(rtc::CreateRandomUuid(),
source));
peer_connection_factory_->CreateVideoTrack(
rtc::CreateRandomUuid(), video_track_sources_.back()));
if (!local_video_renderer_) {
local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track));
}
@ -975,9 +989,12 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
int signaling_delay_ms_ = 0;
bool signal_ice_candidates_ = true;
// Store references to the video capturers we've created, so that we can stop
// Store references to the video sources we've created, so that we can stop
// them, if required.
std::vector<cricket::FakeVideoCapturer*> video_capturers_;
std::vector<std::unique_ptr<webrtc::FakePeriodicVideoSource>>
fake_video_sources_;
std::vector<rtc::scoped_refptr<webrtc::VideoTrackSource>>
video_track_sources_;
// |local_video_renderer_| attached to the first created local video track.
std::unique_ptr<webrtc::FakeVideoTrackRenderer> local_video_renderer_;
@ -1750,35 +1767,6 @@ TEST_P(PeerConnectionIntegrationTest,
remote_cert->ToPEMString());
}
// This test sets up a call between two parties (using DTLS) and tests that we
// can get a video aspect ratio of 16:9.
TEST_P(PeerConnectionIntegrationTest, SendAndReceive16To9AspectRatio) {
ASSERT_TRUE(CreatePeerConnectionWrappers());
ConnectFakeSignaling();
// Add video tracks with 16:9 constraint.
FakeConstraints constraints;
double requested_ratio = 16.0 / 9;
constraints.SetMandatoryMinAspectRatio(requested_ratio);
caller()->AddTrack(
caller()->CreateLocalVideoTrackWithConstraints(constraints));
callee()->AddTrack(
callee()->CreateLocalVideoTrackWithConstraints(constraints));
// Do normal offer/answer and wait for at least one frame to be received in
// each direction.
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
callee()->min_video_frames_received_per_track() > 0,
kMaxWaitForFramesMs);
// Check rendered aspect ratio.
EXPECT_EQ(requested_ratio, caller()->local_rendered_aspect_ratio());
EXPECT_EQ(requested_ratio, caller()->rendered_aspect_ratio());
EXPECT_EQ(requested_ratio, callee()->local_rendered_aspect_ratio());
EXPECT_EQ(requested_ratio, callee()->rendered_aspect_ratio());
}
// This test sets up a call between two parties with a source resolution of
// 1280x720 and verifies that a 16:9 aspect ratio is received.
TEST_P(PeerConnectionIntegrationTest,
@ -1786,15 +1774,12 @@ TEST_P(PeerConnectionIntegrationTest,
ASSERT_TRUE(CreatePeerConnectionWrappers());
ConnectFakeSignaling();
// Similar to above test, but uses MandatoryMin[Width/Height] constraint
// instead of aspect ratio constraint.
FakeConstraints constraints;
constraints.SetMandatoryMinWidth(1280);
constraints.SetMandatoryMinHeight(720);
caller()->AddTrack(
caller()->CreateLocalVideoTrackWithConstraints(constraints));
callee()->AddTrack(
callee()->CreateLocalVideoTrackWithConstraints(constraints));
// Add video tracks with 16:9 aspect ratio, size 1280 x 720.
webrtc::FakePeriodicVideoSource::Config config;
config.width = 1280;
config.height = 720;
caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
// Do normal offer/answer and wait for at least one frame to be received in
// each direction.

View File

@ -24,15 +24,23 @@ namespace webrtc {
class FakePeriodicVideoSource final
: public rtc::VideoSourceInterface<VideoFrame> {
public:
static constexpr int kFrameIntervalMs = 33;
static constexpr int kWidth = 640;
static constexpr int kHeight = 480;
static constexpr int kDefaultFrameIntervalMs = 33;
static constexpr int kDefaultWidth = 640;
static constexpr int kDefaultHeight = 480;
FakePeriodicVideoSource()
struct Config {
int width = kDefaultWidth;
int height = kDefaultHeight;
int frame_interval_ms = kDefaultFrameIntervalMs;
VideoRotation rotation = kVideoRotation_0;
};
FakePeriodicVideoSource() : FakePeriodicVideoSource(Config()) {}
explicit FakePeriodicVideoSource(Config config)
: task_queue_(
rtc::MakeUnique<rtc::TaskQueue>("FakePeriodicVideoTrackSource")) {
thread_checker_.DetachFromThread();
task_queue_->PostTask(rtc::MakeUnique<FrameTask>(&broadcaster_));
task_queue_->PostTask(rtc::MakeUnique<FrameTask>(config, &broadcaster_));
}
void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
@ -54,23 +62,32 @@ class FakePeriodicVideoSource final
private:
class FrameTask : public rtc::QueuedTask {
public:
explicit FrameTask(rtc::VideoSinkInterface<VideoFrame>* sink)
: frame_source_(kWidth,
kHeight,
kFrameIntervalMs * rtc::kNumMicrosecsPerMillisec),
sink_(sink) {}
FrameTask(Config config, rtc::VideoBroadcaster* broadcaster)
: frame_interval_ms_(config.frame_interval_ms),
frame_source_(
config.width,
config.height,
config.frame_interval_ms * rtc::kNumMicrosecsPerMillisec),
broadcaster_(broadcaster) {
frame_source_.SetRotation(config.rotation);
}
bool Run() override {
sink_->OnFrame(frame_source_.GetFrame());
if (broadcaster_->wants().rotation_applied) {
broadcaster_->OnFrame(frame_source_.GetFrameRotationApplied());
} else {
broadcaster_->OnFrame(frame_source_.GetFrame());
}
rtc::TaskQueue::Current()->PostDelayedTask(rtc::WrapUnique(this),
kFrameIntervalMs);
frame_interval_ms_);
return false;
}
int frame_interval_ms_;
cricket::FakeFrameSource frame_source_;
rtc::VideoSinkInterface<VideoFrame>* sink_;
rtc::VideoBroadcaster* broadcaster_;
};
void OnFrame(const webrtc::VideoFrame& frame) { broadcaster_.OnFrame(frame); }
rtc::ThreadChecker thread_checker_;
rtc::VideoBroadcaster broadcaster_;