Make VideoSendStream/VideoReceiveStream configs const.
Benefits of this is that the send config previously had unclear locking
requirements, a lock was used to lock parts parts of it while
reconfiguring the VideoEncoder. Primary work was splitting out video
streams from config as well as encoder_settings as these change on
ReconfigureVideoEncoder. Now threading requirements for both member
configs are clear (as they are read-only), and encoder_settings doesn't
stay in the config as a stale pointer.
CreateVideoSendStream now takes video streams separately as well as the
encoder_settings pointer, analogous to ReconfigureVideoEncoder.
This change required changing so that pacing is silently enabled when
using suspend_below_min_bitrate rather than silently setting it.
R=henrik.lundin@webrtc.org, mflodman@webrtc.org, pthatcher@webrtc.org, stefan@webrtc.org
BUG=3260
Review URL: https://webrtc-codereview.appspot.com/20409004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@6349 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 723ef1d..6593b2a 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -197,22 +197,15 @@
class DefaultVideoEncoderFactory : public WebRtcVideoEncoderFactory2 {
public:
- virtual bool CreateEncoderSettings(
- webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings,
- const VideoOptions& options,
+ virtual std::vector<webrtc::VideoStream> CreateVideoStreams(
const VideoCodec& codec,
+ const VideoOptions& options,
size_t num_streams) OVERRIDE {
+ assert(SupportsCodec(codec));
if (num_streams != 1) {
LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams;
- return false;
+ return std::vector<webrtc::VideoStream>();
}
- if (!SupportsCodec(codec)) {
- LOG(LS_ERROR) << "Can't create encoder settings for unsupported codec: '"
- << codec.name << "'";
- return false;
- }
-
- *encoder_settings = webrtc::VideoSendStream::Config::EncoderSettings();
webrtc::VideoStream stream;
stream.width = codec.width;
@@ -230,13 +223,16 @@
int max_qp = 56;
codec.GetParam(kCodecParamMaxQuantization, &max_qp);
stream.max_qp = max_qp;
- encoder_settings->streams.push_back(stream);
+ std::vector<webrtc::VideoStream> streams;
+ streams.push_back(stream);
+ return streams;
+ }
- encoder_settings->encoder = webrtc::VP8Encoder::Create();
- encoder_settings->payload_type = kDefaultVideoCodecPref.payload_type;
- encoder_settings->payload_name = kDefaultVideoCodecPref.name;
-
- return true;
+ virtual webrtc::VideoEncoder* CreateVideoEncoder(
+ const VideoCodec& codec,
+ const VideoOptions& options) OVERRIDE {
+ assert(SupportsCodec(codec));
+ return webrtc::VP8Encoder::Create();
}
virtual bool SupportsCodec(const VideoCodec& codec) OVERRIDE {
@@ -471,11 +467,11 @@
return default_video_encoder_factory_.get();
}
-// Thin map between cricket::VideoFrame and an existing webrtc::I420VideoFrame
+// Thin map between VideoFrame and an existing webrtc::I420VideoFrame
// to avoid having to copy the rendered VideoFrame prematurely.
// This implementation is only safe to use in a const context and should never
// be written to.
-class WebRtcVideoRenderFrame : public cricket::VideoFrame {
+class WebRtcVideoRenderFrame : public VideoFrame {
public:
explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame)
: frame_(frame) {}
@@ -924,14 +920,17 @@
// CreateEncoderSettings will allocate a suitable VideoEncoder instance
// matching current settings.
- if (!encoder_factory_->CreateEncoderSettings(&config.encoder_settings,
- options_,
- codec_settings.codec,
- config.rtp.ssrcs.size())) {
- LOG(LS_ERROR) << "Failed to create suitable encoder settings.";
+ std::vector<webrtc::VideoStream> video_streams =
+ encoder_factory_->CreateVideoStreams(
+ codec_settings.codec, options_, config.rtp.ssrcs.size());
+ if (video_streams.empty()) {
return false;
}
+ config.encoder_settings.encoder =
+ encoder_factory_->CreateVideoEncoder(codec_settings.codec, options_);
+ config.encoder_settings.payload_name = codec_settings.codec.name;
+ config.encoder_settings.payload_type = codec_settings.codec.id;
config.rtp.c_name = sp.cname;
config.rtp.fec = codec_settings.fec;
if (!config.rtp.rtx.ssrcs.empty()) {
@@ -942,7 +941,12 @@
config.rtp.max_packet_size = kVideoMtu;
WebRtcVideoSendStream* stream =
- new WebRtcVideoSendStream(call_.get(), config, encoder_factory_);
+ new WebRtcVideoSendStream(call_.get(),
+ config,
+ options_,
+ codec_settings.codec,
+ video_streams,
+ encoder_factory_);
send_streams_[ssrc] = stream;
if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) {
@@ -1339,21 +1343,35 @@
}
}
+WebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters::
+ VideoSendStreamParameters(
+ const webrtc::VideoSendStream::Config& config,
+ const VideoOptions& options,
+ const VideoCodec& codec,
+ const std::vector<webrtc::VideoStream>& video_streams)
+ : config(config),
+ options(options),
+ codec(codec),
+ video_streams(video_streams) {
+}
+
WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream(
webrtc::Call* call,
const webrtc::VideoSendStream::Config& config,
+ const VideoOptions& options,
+ const VideoCodec& codec,
+ const std::vector<webrtc::VideoStream>& video_streams,
WebRtcVideoEncoderFactory2* encoder_factory)
: call_(call),
- config_(config),
+ parameters_(config, options, codec, video_streams),
encoder_factory_(encoder_factory),
capturer_(NULL),
stream_(NULL),
sending_(false),
muted_(false),
- format_(static_cast<int>(config.encoder_settings.streams.back().height),
- static_cast<int>(config.encoder_settings.streams.back().width),
- VideoFormat::FpsToInterval(
- config.encoder_settings.streams.back().max_framerate),
+ format_(static_cast<int>(video_streams.back().height),
+ static_cast<int>(video_streams.back().width),
+ VideoFormat::FpsToInterval(video_streams.back().max_framerate),
FOURCC_I420) {
RecreateWebRtcStream();
}
@@ -1361,7 +1379,7 @@
WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() {
DisconnectCapturer();
call_->DestroyVideoSendStream(stream_);
- delete config_.encoder_settings.encoder;
+ delete parameters_.config.encoder_settings.encoder;
}
static void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) {
@@ -1428,8 +1446,8 @@
}
LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x"
<< video_frame_.height() << " -> (codec) "
- << config_.encoder_settings.streams.back().width << "x"
- << config_.encoder_settings.streams.back().height;
+ << parameters_.video_streams.back().width << "x"
+ << parameters_.video_streams.back().height;
stream_->Input()->SwapFrame(&video_frame_);
}
@@ -1480,10 +1498,10 @@
if (format.width == 0 && format.height == 0) {
LOG(LS_INFO)
<< "0x0 resolution selected. Captured frames will be dropped for ssrc: "
- << config_.rtp.ssrcs[0] << ".";
+ << parameters_.config.rtp.ssrcs[0] << ".";
} else {
// TODO(pbos): Fix me, this only affects the last stream!
- config_.encoder_settings.streams.back().max_framerate =
+ parameters_.video_streams.back().max_framerate =
VideoFormat::IntervalToFps(format.interval);
SetDimensions(format.width, format.height);
}
@@ -1513,44 +1531,46 @@
const VideoOptions& options,
const VideoCodecSettings& codec) {
talk_base::CritScope cs(&lock_);
- webrtc::VideoEncoder* old_encoder = config_.encoder_settings.encoder;
- if (!encoder_factory_->CreateEncoderSettings(
- &config_.encoder_settings,
- options,
- codec.codec,
- config_.encoder_settings.streams.size())) {
- LOG(LS_ERROR) << "Could not create encoder settings for: '"
- << codec.codec.name
- << "'. This is most definitely a bug as SetCodec should only "
- "receive codecs which the encoder factory claims to "
- "support.";
+
+ std::vector<webrtc::VideoStream> video_streams =
+ encoder_factory_->CreateVideoStreams(
+ codec.codec, options, parameters_.video_streams.size());
+ if (video_streams.empty()) {
return;
}
+ parameters_.video_streams = video_streams;
format_ = VideoFormat(codec.codec.width,
codec.codec.height,
VideoFormat::FpsToInterval(30),
FOURCC_I420);
- config_.rtp.fec = codec.fec;
+
+ webrtc::VideoEncoder* old_encoder =
+ parameters_.config.encoder_settings.encoder;
+ parameters_.config.encoder_settings.encoder =
+ encoder_factory_->CreateVideoEncoder(codec.codec, options);
+ parameters_.config.rtp.fec = codec.fec;
// TODO(pbos): Should changing RTX payload type be allowed?
+ parameters_.codec = codec.codec;
+ parameters_.options = options;
RecreateWebRtcStream();
delete old_encoder;
}
void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width,
- int height) {
- assert(!config_.encoder_settings.streams.empty());
+ int height) {
+ assert(!parameters_.video_streams.empty());
LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height;
- if (config_.encoder_settings.streams.back().width == width &&
- config_.encoder_settings.streams.back().height == height) {
+ if (parameters_.video_streams.back().width == width &&
+ parameters_.video_streams.back().height == height) {
return;
}
// TODO(pbos): Fix me, this only affects the last stream!
- config_.encoder_settings.streams.back().width = width;
- config_.encoder_settings.streams.back().height = height;
- // TODO(pbos): Last parameter shouldn't always be NULL?
- if (!stream_->ReconfigureVideoEncoder(config_.encoder_settings.streams,
- NULL)) {
+ parameters_.video_streams.back().width = width;
+ parameters_.video_streams.back().height = height;
+
+ // TODO(pbos): Wire up encoder_parameters, webrtc:3424.
+ if (!stream_->ReconfigureVideoEncoder(parameters_.video_streams, NULL)) {
LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: "
<< width << "x" << height;
return;
@@ -1573,7 +1593,10 @@
if (stream_ != NULL) {
call_->DestroyVideoSendStream(stream_);
}
- stream_ = call_->CreateVideoSendStream(config_);
+
+ // TODO(pbos): Wire up encoder_parameters, webrtc:3424.
+ stream_ = call_->CreateVideoSendStream(
+ parameters_.config, parameters_.video_streams, NULL);
if (sending_) {
stream_->Start();
}
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index 10a1608..4287d28 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -83,11 +83,15 @@
class WebRtcVideoEncoderFactory2 {
public:
virtual ~WebRtcVideoEncoderFactory2();
- virtual bool CreateEncoderSettings(
- webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings,
+ virtual std::vector<webrtc::VideoStream> CreateVideoStreams(
+ const VideoCodec& codec,
const VideoOptions& options,
- const cricket::VideoCodec& codec,
size_t num_streams) = 0;
+
+ virtual webrtc::VideoEncoder* CreateVideoEncoder(
+ const VideoCodec& codec,
+ const VideoOptions& options) = 0;
+
virtual bool SupportsCodec(const cricket::VideoCodec& codec) = 0;
};
@@ -258,7 +262,7 @@
struct VideoCodecSettings {
VideoCodecSettings();
- cricket::VideoCodec codec;
+ VideoCodec codec;
webrtc::FecConfig fec;
int rtx_payload_type;
};
@@ -266,8 +270,11 @@
class WebRtcVideoSendStream : public sigslot::has_slots<> {
public:
WebRtcVideoSendStream(webrtc::Call* call,
- const webrtc::VideoSendStream::Config& config,
- WebRtcVideoEncoderFactory2* encoder_factory);
+ const webrtc::VideoSendStream::Config& config,
+ const VideoOptions& options,
+ const VideoCodec& codec,
+ const std::vector<webrtc::VideoStream>& video_streams,
+ WebRtcVideoEncoderFactory2* encoder_factory);
~WebRtcVideoSendStream();
void SetCodec(const VideoOptions& options, const VideoCodecSettings& codec);
@@ -281,6 +288,25 @@
void Stop();
private:
+ // Parameters needed to reconstruct the underlying stream.
+ // webrtc::VideoSendStream doesn't support setting a lot of options on the
+ // fly, so when those need to be changed we tear down and reconstruct with
+ // similar parameters depending on which options changed etc.
+ struct VideoSendStreamParameters {
+ VideoSendStreamParameters(
+ const webrtc::VideoSendStream::Config& config,
+ const VideoOptions& options,
+ const VideoCodec& codec,
+ const std::vector<webrtc::VideoStream>& video_streams);
+ webrtc::VideoSendStream::Config config;
+ VideoOptions options;
+ VideoCodec codec;
+ // Sent resolutions + bitrates etc. by the underlying VideoSendStream,
+ // typically changes when setting a new resolution or reconfiguring
+ // bitrates.
+ std::vector<webrtc::VideoStream> video_streams;
+ };
+
void RecreateWebRtcStream();
void SetDimensions(int width, int height);
@@ -289,7 +315,8 @@
talk_base::CriticalSection lock_;
webrtc::VideoSendStream* stream_ GUARDED_BY(lock_);
- webrtc::VideoSendStream::Config config_ GUARDED_BY(lock_);
+ VideoSendStreamParameters parameters_ GUARDED_BY(lock_);
+
VideoCapturer* capturer_ GUARDED_BY(lock_);
bool sending_ GUARDED_BY(lock_);
bool muted_ GUARDED_BY(lock_);
diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
index bba1455..c478b42 100644
--- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -52,12 +52,12 @@
namespace cricket {
class FakeVideoSendStream : public webrtc::VideoSendStream {
public:
- explicit FakeVideoSendStream(const webrtc::VideoSendStream::Config& config)
- : sending_(false) {
- config_ = config;
- }
+ FakeVideoSendStream(const webrtc::VideoSendStream::Config& config,
+ const std::vector<webrtc::VideoStream>& video_streams)
+ : sending_(false), config_(config), video_streams_(video_streams) {}
webrtc::VideoSendStream::Config GetConfig() { return config_; }
+ std::vector<webrtc::VideoStream> GetVideoStreams() { return video_streams_; }
bool IsSending() { return sending_; }
@@ -68,9 +68,8 @@
virtual bool ReconfigureVideoEncoder(
const std::vector<webrtc::VideoStream>& streams,
- void* encoder_specific) OVERRIDE {
- // TODO(pbos): Store encoder_specific ptr?
- config_.encoder_settings.streams = streams;
+ const void* encoder_specific) OVERRIDE {
+ video_streams_ = streams;
return true;
}
@@ -85,6 +84,7 @@
bool sending_;
webrtc::VideoSendStream::Config config_;
+ std::vector<webrtc::VideoStream> video_streams_;
};
class FakeVideoReceiveStream : public webrtc::VideoReceiveStream {
@@ -178,8 +178,11 @@
}
virtual webrtc::VideoSendStream* CreateVideoSendStream(
- const webrtc::VideoSendStream::Config& config) OVERRIDE {
- FakeVideoSendStream* fake_stream = new FakeVideoSendStream(config);
+ const webrtc::VideoSendStream::Config& config,
+ const std::vector<webrtc::VideoStream>& video_streams,
+ const void* encoder_settings) OVERRIDE {
+ FakeVideoSendStream* fake_stream =
+ new FakeVideoSendStream(config, video_streams);
video_send_streams_.push_back(fake_stream);
return fake_stream;
}
@@ -515,13 +518,10 @@
FakeVideoSendStream* stream = AddSendStream();
- webrtc::VideoSendStream::Config::EncoderSettings encoder_settings =
- stream->GetConfig().encoder_settings;
- ASSERT_EQ(1u, encoder_settings.streams.size());
- EXPECT_EQ(atoi(min_bitrate),
- encoder_settings.streams.back().min_bitrate_bps / 1000);
- EXPECT_EQ(atoi(max_bitrate),
- encoder_settings.streams.back().max_bitrate_bps / 1000);
+ std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
+ ASSERT_EQ(1u, video_streams.size());
+ EXPECT_EQ(atoi(min_bitrate), video_streams.back().min_bitrate_bps / 1000);
+ EXPECT_EQ(atoi(max_bitrate), video_streams.back().max_bitrate_bps / 1000);
VideoCodec codec;
EXPECT_TRUE(channel_->GetSendCodec(&codec));
@@ -556,15 +556,14 @@
const unsigned int kVideoTargetSendBitrateKbps = 300;
const unsigned int kVideoMaxSendBitrateKbps = 2000;
FakeVideoSendStream* stream = AddSendStream();
- webrtc::VideoSendStream::Config::EncoderSettings encoder_settings =
- stream->GetConfig().encoder_settings;
- ASSERT_EQ(1u, encoder_settings.streams.size());
+ std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
+ ASSERT_EQ(1u, video_streams.size());
EXPECT_EQ(kVideoMinSendBitrateKbps,
- encoder_settings.streams.back().min_bitrate_bps / 1000);
+ video_streams.back().min_bitrate_bps / 1000);
EXPECT_EQ(kVideoTargetSendBitrateKbps,
- encoder_settings.streams.back().target_bitrate_bps / 1000);
+ video_streams.back().target_bitrate_bps / 1000);
EXPECT_EQ(kVideoMaxSendBitrateKbps,
- encoder_settings.streams.back().max_bitrate_bps / 1000);
+ video_streams.back().max_bitrate_bps / 1000);
#if 0
// TODO(pbos): un-#if
VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
@@ -925,9 +924,8 @@
codecs.push_back(kVp8Codec);
codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
EXPECT_TRUE(channel_->SetSendCodecs(codecs));
- EXPECT_EQ(
- static_cast<unsigned int>(atoi(kMaxQuantization)),
- AddSendStream()->GetConfig().encoder_settings.streams.back().max_qp);
+ EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
+ AddSendStream()->GetVideoStreams().back().max_qp);
VideoCodec codec;
EXPECT_TRUE(channel_->GetSendCodec(&codec));
diff --git a/webrtc/call.h b/webrtc/call.h
index 53b17ed..1771ad8 100644
--- a/webrtc/call.h
+++ b/webrtc/call.h
@@ -83,7 +83,9 @@
virtual VideoSendStream::Config GetDefaultSendConfig() = 0;
virtual VideoSendStream* CreateVideoSendStream(
- const VideoSendStream::Config& config) = 0;
+ const VideoSendStream::Config& config,
+ const std::vector<VideoStream>& video_streams,
+ const void* encoder_settings) = 0;
virtual void DestroyVideoSendStream(VideoSendStream* send_stream) = 0;
diff --git a/webrtc/test/encoder_settings.cc b/webrtc/test/encoder_settings.cc
index d02c29f..5193be6 100644
--- a/webrtc/test/encoder_settings.cc
+++ b/webrtc/test/encoder_settings.cc
@@ -16,18 +16,14 @@
namespace webrtc {
namespace test {
-VideoSendStream::Config::EncoderSettings CreateEncoderSettings(
- VideoEncoder* encoder,
- const char* payload_name,
- int payload_type,
- size_t num_streams) {
+std::vector<VideoStream> CreateVideoStreams(size_t num_streams) {
assert(num_streams > 0);
// Add more streams to the settings above with reasonable values if required.
static const size_t kNumSettings = 3;
assert(num_streams <= kNumSettings);
- VideoStream stream_settings[kNumSettings];
+ std::vector<VideoStream> stream_settings(kNumSettings);
stream_settings[0].width = 320;
stream_settings[0].height = 180;
@@ -52,28 +48,20 @@
stream_settings[2].target_bitrate_bps = stream_settings[2].max_bitrate_bps =
1500000;
stream_settings[2].max_qp = 56;
-
- VideoSendStream::Config::EncoderSettings settings;
-
- for (size_t i = 0; i < num_streams; ++i)
- settings.streams.push_back(stream_settings[i]);
-
- settings.encoder = encoder;
- settings.payload_name = payload_name;
- settings.payload_type = payload_type;
- return settings;
+ stream_settings.resize(num_streams);
+ return stream_settings;
}
VideoCodec CreateDecoderVideoCodec(
- const VideoSendStream::Config::EncoderSettings& settings) {
- assert(settings.streams.size() > 0);
+ const VideoSendStream::Config::EncoderSettings& encoder_settings) {
VideoCodec codec;
memset(&codec, 0, sizeof(codec));
- codec.plType = settings.payload_type;
- strcpy(codec.plName, settings.payload_name.c_str());
+ codec.plType = encoder_settings.payload_type;
+ strcpy(codec.plName, encoder_settings.payload_name.c_str());
codec.codecType =
- (settings.payload_name == "VP8" ? kVideoCodecVP8 : kVideoCodecGeneric);
+ (encoder_settings.payload_name == "VP8" ? kVideoCodecVP8
+ : kVideoCodecGeneric);
if (codec.codecType == kVideoCodecVP8) {
codec.codecSpecific.VP8.resilience = kResilientStream;
@@ -85,33 +73,9 @@
codec.codecSpecific.VP8.keyFrameInterval = 3000;
}
- codec.minBitrate = settings.streams[0].min_bitrate_bps / 1000;
- for (size_t i = 0; i < settings.streams.size(); ++i) {
- const VideoStream& stream = settings.streams[i];
- if (stream.width > codec.width)
- codec.width = static_cast<unsigned short>(stream.width);
- if (stream.height > codec.height)
- codec.height = static_cast<unsigned short>(stream.height);
- if (static_cast<unsigned int>(stream.min_bitrate_bps / 1000) <
- codec.minBitrate)
- codec.minBitrate =
- static_cast<unsigned int>(stream.min_bitrate_bps / 1000);
- codec.maxBitrate += stream.max_bitrate_bps / 1000;
- if (static_cast<unsigned int>(stream.max_qp) > codec.qpMax)
- codec.qpMax = static_cast<unsigned int>(stream.max_qp);
- }
-
- if (codec.minBitrate < kViEMinCodecBitrate)
- codec.minBitrate = kViEMinCodecBitrate;
- if (codec.maxBitrate < kViEMinCodecBitrate)
- codec.maxBitrate = kViEMinCodecBitrate;
-
- codec.startBitrate = 300;
-
- if (codec.startBitrate < codec.minBitrate)
- codec.startBitrate = codec.minBitrate;
- if (codec.startBitrate > codec.maxBitrate)
- codec.startBitrate = codec.maxBitrate;
+ codec.width = 320;
+ codec.height = 180;
+ codec.startBitrate = codec.minBitrate = codec.maxBitrate = 300;
return codec;
}
diff --git a/webrtc/test/encoder_settings.h b/webrtc/test/encoder_settings.h
index 1d8e355..ea2be97 100644
--- a/webrtc/test/encoder_settings.h
+++ b/webrtc/test/encoder_settings.h
@@ -14,14 +14,10 @@
namespace webrtc {
namespace test {
-VideoSendStream::Config::EncoderSettings CreateEncoderSettings(
- VideoEncoder* encoder,
- const char* payload_name,
- int payload_type,
- size_t num_streams);
+std::vector<VideoStream> CreateVideoStreams(size_t num_streams);
VideoCodec CreateDecoderVideoCodec(
- const VideoSendStream::Config::EncoderSettings& settings);
+ const VideoSendStream::Config::EncoderSettings& encoder_settings);
} // namespace test
} // namespace webrtc
diff --git a/webrtc/video/bitrate_estimator_tests.cc b/webrtc/video/bitrate_estimator_tests.cc
index 7b74818..f8b9060 100644
--- a/webrtc/video/bitrate_estimator_tests.cc
+++ b/webrtc/video/bitrate_estimator_tests.cc
@@ -70,8 +70,10 @@
send_config_ = sender_call_->GetDefaultSendConfig();
send_config_.rtp.ssrcs.push_back(kSendSsrc);
// Encoders will be set separately per stream.
- send_config_.encoder_settings =
- test::CreateEncoderSettings(NULL, "FAKE", kSendPayloadType, 1);
+ send_config_.encoder_settings.encoder = NULL;
+ send_config_.encoder_settings.payload_name = "FAKE";
+ send_config_.encoder_settings.payload_type = kSendPayloadType;
+ video_streams_ = test::CreateVideoStreams(1);
receive_config_ = receiver_call_->GetDefaultReceiveConfig();
assert(receive_config_.codecs.empty());
@@ -169,15 +171,15 @@
fake_decoder_() {
test_->send_config_.rtp.ssrcs[0]++;
test_->send_config_.encoder_settings.encoder = &fake_encoder_;
- send_stream_ =
- test_->sender_call_->CreateVideoSendStream(test_->send_config_);
- assert(test_->send_config_.encoder_settings.streams.size() == 1);
- frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
- send_stream_->Input(),
- test_->send_config_.encoder_settings.streams[0].width,
- test_->send_config_.encoder_settings.streams[0].height,
- 30,
- Clock::GetRealTimeClock()));
+ send_stream_ = test_->sender_call_->CreateVideoSendStream(
+ test_->send_config_, test_->video_streams_, NULL);
+ assert(test_->video_streams_.size() == 1);
+ frame_generator_capturer_.reset(
+ test::FrameGeneratorCapturer::Create(send_stream_->Input(),
+ test_->video_streams_[0].width,
+ test_->video_streams_[0].height,
+ 30,
+ Clock::GetRealTimeClock()));
send_stream_->Start();
frame_generator_capturer_->Start();
@@ -227,6 +229,7 @@
scoped_ptr<Call> sender_call_;
scoped_ptr<Call> receiver_call_;
VideoSendStream::Config send_config_;
+ std::vector<VideoStream> video_streams_;
VideoReceiveStream::Config receive_config_;
std::vector<Stream*> streams_;
};
diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc
index 6adb0fc..6103074 100644
--- a/webrtc/video/call.cc
+++ b/webrtc/video/call.cc
@@ -70,7 +70,9 @@
virtual VideoSendStream::Config GetDefaultSendConfig() OVERRIDE;
virtual VideoSendStream* CreateVideoSendStream(
- const VideoSendStream::Config& config) OVERRIDE;
+ const VideoSendStream::Config& config,
+ const std::vector<VideoStream>& video_streams,
+ const void* encoder_settings) OVERRIDE;
virtual void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream)
OVERRIDE;
@@ -175,15 +177,19 @@
}
VideoSendStream* Call::CreateVideoSendStream(
- const VideoSendStream::Config& config) {
+ const VideoSendStream::Config& config,
+ const std::vector<VideoStream>& video_streams,
+ const void* encoder_settings) {
assert(config.rtp.ssrcs.size() > 0);
- VideoSendStream* send_stream = new VideoSendStream(
- config_.send_transport,
- overuse_observer_proxy_.get(),
- video_engine_,
- config,
- base_channel_id_);
+ VideoSendStream* send_stream =
+ new VideoSendStream(config_.send_transport,
+ overuse_observer_proxy_.get(),
+ video_engine_,
+ config,
+ video_streams,
+ encoder_settings,
+ base_channel_id_);
WriteLockScoped write_lock(*send_lock_);
for (size_t i = 0; i < config.rtp.ssrcs.size(); ++i) {
diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc
index bc0a1e0..f9e44ae 100644
--- a/webrtc/video/call_perf_tests.cc
+++ b/webrtc/video/call_perf_tests.cc
@@ -53,18 +53,19 @@
: send_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {}
protected:
- VideoSendStream::Config GetSendTestConfig(Call* call) {
- VideoSendStream::Config config = call->GetDefaultSendConfig();
- config.rtp.ssrcs.push_back(kSendSsrc);
- config.encoder_settings = test::CreateEncoderSettings(
- &fake_encoder_, "FAKE", kSendPayloadType, 1);
- return config;
+ void CreateTestConfig(Call* call) {
+ send_config_ = call->GetDefaultSendConfig();
+ send_config_.rtp.ssrcs.push_back(kSendSsrc);
+ send_config_.encoder_settings.encoder = &fake_encoder_;
+ send_config_.encoder_settings.payload_type = kSendPayloadType;
+ send_config_.encoder_settings.payload_name = "FAKE";
+ video_streams_ = test::CreateVideoStreams(1);
}
void RunVideoSendTest(Call* call,
const VideoSendStream::Config& config,
test::RtpRtcpObserver* observer) {
- send_stream_ = call->CreateVideoSendStream(config);
+ send_stream_ = call->CreateVideoSendStream(config, video_streams_, NULL);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
test::FrameGeneratorCapturer::Create(
send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -86,6 +87,8 @@
int start_time_ms,
int run_time_ms);
+ VideoSendStream::Config send_config_;
+ std::vector<VideoStream> video_streams_;
VideoSendStream* send_stream_;
test::FakeEncoder fake_encoder_;
};
@@ -288,35 +291,34 @@
test::FakeDecoder fake_decoder;
- VideoSendStream::Config send_config = GetSendTestConfig(sender_call.get());
+ CreateTestConfig(sender_call.get());
VideoReceiveStream::Config receive_config =
receiver_call->GetDefaultReceiveConfig();
assert(receive_config.codecs.empty());
VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config.encoder_settings);
+ test::CreateDecoderVideoCodec(send_config_.encoder_settings);
receive_config.codecs.push_back(codec);
assert(receive_config.external_decoders.empty());
ExternalVideoDecoder decoder;
decoder.decoder = &fake_decoder;
- decoder.payload_type = send_config.encoder_settings.payload_type;
+ decoder.payload_type = send_config_.encoder_settings.payload_type;
receive_config.external_decoders.push_back(decoder);
- receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
+ receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
receive_config.renderer = &observer;
receive_config.audio_channel_id = channel;
VideoSendStream* send_stream =
- sender_call->CreateVideoSendStream(send_config);
+ sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
VideoReceiveStream* receive_stream =
receiver_call->CreateVideoReceiveStream(receive_config);
scoped_ptr<test::FrameGeneratorCapturer> capturer(
- test::FrameGeneratorCapturer::Create(
- send_stream->Input(),
- send_config.encoder_settings.streams[0].width,
- send_config.encoder_settings.streams[0].height,
- 30,
- Clock::GetRealTimeClock()));
+ test::FrameGeneratorCapturer::Create(send_stream->Input(),
+ video_streams_[0].width,
+ video_streams_[0].height,
+ 30,
+ Clock::GetRealTimeClock()));
receive_stream->Start();
send_stream->Start();
capturer->Start();
@@ -465,16 +467,15 @@
observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
// Configure send stream.
- VideoSendStream::Config send_config = GetSendTestConfig(sender_call.get());
+ CreateTestConfig(sender_call.get());
VideoSendStream* send_stream =
- sender_call->CreateVideoSendStream(send_config);
+ sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
scoped_ptr<test::FrameGeneratorCapturer> capturer(
- test::FrameGeneratorCapturer::Create(
- send_stream->Input(),
- send_config.encoder_settings.streams[0].width,
- send_config.encoder_settings.streams[0].height,
- 30,
- Clock::GetRealTimeClock()));
+ test::FrameGeneratorCapturer::Create(send_stream->Input(),
+ video_streams_[0].width,
+ video_streams_[0].height,
+ 30,
+ Clock::GetRealTimeClock()));
observer.SetCapturer(capturer.get());
// Configure receive stream.
@@ -482,15 +483,15 @@
receiver_call->GetDefaultReceiveConfig();
assert(receive_config.codecs.empty());
VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config.encoder_settings);
+ test::CreateDecoderVideoCodec(send_config_.encoder_settings);
receive_config.codecs.push_back(codec);
assert(receive_config.external_decoders.empty());
ExternalVideoDecoder decoder;
test::FakeDecoder fake_decoder;
decoder.decoder = &fake_decoder;
- decoder.payload_type = send_config.encoder_settings.payload_type;
+ decoder.payload_type = send_config_.encoder_settings.payload_type;
receive_config.external_decoders.push_back(decoder);
- receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
+ receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
receive_config.renderer = &observer;
// Enable the receiver side rtt calculation.
@@ -559,8 +560,8 @@
call_config.overuse_callback = &observer;
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config = GetSendTestConfig(call.get());
- RunVideoSendTest(call.get(), send_config, &observer);
+ CreateTestConfig(call.get());
+ RunVideoSendTest(call.get(), send_config_, &observer);
}
void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
@@ -636,43 +637,42 @@
scoped_ptr<Call> receiver_call(
Call::Create(Call::Config(observer.ReceiveTransport())));
- VideoSendStream::Config send_config = GetSendTestConfig(sender_call.get());
+ CreateTestConfig(sender_call.get());
fake_encoder_.SetMaxBitrate(kMaxEncodeBitrateKbps);
observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
- send_config.pacing = true;
+ send_config_.pacing = true;
if (pad_to_min_bitrate) {
- send_config.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
+ send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
} else {
- assert(send_config.rtp.min_transmit_bitrate_bps == 0);
+ assert(send_config_.rtp.min_transmit_bitrate_bps == 0);
}
VideoReceiveStream::Config receive_config =
receiver_call->GetDefaultReceiveConfig();
receive_config.codecs.clear();
VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config.encoder_settings);
+ test::CreateDecoderVideoCodec(send_config_.encoder_settings);
receive_config.codecs.push_back(codec);
test::FakeDecoder fake_decoder;
ExternalVideoDecoder decoder;
decoder.decoder = &fake_decoder;
- decoder.payload_type = send_config.encoder_settings.payload_type;
+ decoder.payload_type = send_config_.encoder_settings.payload_type;
receive_config.external_decoders.push_back(decoder);
- receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
+ receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
VideoSendStream* send_stream =
- sender_call->CreateVideoSendStream(send_config);
+ sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
VideoReceiveStream* receive_stream =
receiver_call->CreateVideoReceiveStream(receive_config);
scoped_ptr<test::FrameGeneratorCapturer> capturer(
- test::FrameGeneratorCapturer::Create(
- send_stream->Input(),
- send_config.encoder_settings.streams[0].width,
- send_config.encoder_settings.streams[0].height,
- 30,
- Clock::GetRealTimeClock()));
+ test::FrameGeneratorCapturer::Create(send_stream->Input(),
+ video_streams_[0].width,
+ video_streams_[0].height,
+ 30,
+ Clock::GetRealTimeClock()));
observer.SetSendStream(send_stream);
receive_stream->Start();
send_stream->Start();
diff --git a/webrtc/video/call_tests.cc b/webrtc/video/call_tests.cc
index 7b78af3..5bcf115 100644
--- a/webrtc/video/call_tests.cc
+++ b/webrtc/video/call_tests.cc
@@ -73,8 +73,10 @@
receive_config_ = receiver_call_->GetDefaultReceiveConfig();
send_config_.rtp.ssrcs.push_back(kSendSsrc);
- send_config_.encoder_settings = test::CreateEncoderSettings(
- &fake_encoder_, "FAKE", kSendPayloadType, 1);
+ send_config_.encoder_settings.encoder = &fake_encoder_;
+ send_config_.encoder_settings.payload_name = "FAKE";
+ send_config_.encoder_settings.payload_type = kSendPayloadType;
+ video_streams_ = test::CreateVideoStreams(1);
assert(receive_config_.codecs.empty());
VideoCodec codec =
@@ -92,17 +94,18 @@
assert(send_stream_ == NULL);
assert(receive_stream_ == NULL);
- send_stream_ = sender_call_->CreateVideoSendStream(send_config_);
+ send_stream_ =
+ sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL);
receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_);
}
void CreateFrameGenerator() {
- frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
- send_stream_->Input(),
- send_config_.encoder_settings.streams[0].width,
- send_config_.encoder_settings.streams[0].height,
- 30,
- Clock::GetRealTimeClock()));
+ frame_generator_capturer_.reset(
+ test::FrameGeneratorCapturer::Create(send_stream_->Input(),
+ video_streams_[0].width,
+ video_streams_[0].height,
+ 30,
+ Clock::GetRealTimeClock()));
}
void StartSending() {
@@ -139,6 +142,7 @@
scoped_ptr<Call> receiver_call_;
VideoSendStream::Config send_config_;
+ std::vector<VideoStream> video_streams_;
VideoReceiveStream::Config receive_config_;
VideoSendStream* send_stream_;
@@ -350,8 +354,7 @@
StartSending();
scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
- send_config_.encoder_settings.streams[0].width,
- send_config_.encoder_settings.streams[0].height));
+ video_streams_[0].width, video_streams_[0].height));
send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
EXPECT_EQ(kEventSignaled, renderer.Wait())
@@ -701,10 +704,9 @@
scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
send_config_.encoder_settings.encoder = encoder.get();
send_config_.encoder_settings.payload_name = "VP8";
- ASSERT_EQ(1u, send_config_.encoder_settings.streams.size())
- << "Test setup error.";
- send_config_.encoder_settings.streams[0].width = kWidth;
- send_config_.encoder_settings.streams[0].height = kHeight;
+ ASSERT_EQ(1u, video_streams_.size()) << "Test setup error.";
+ video_streams_[0].width = kWidth;
+ video_streams_[0].height = kHeight;
send_config_.pre_encode_callback = &pre_encode_callback;
receive_config_.codecs.clear();
VideoCodec codec =
@@ -1055,15 +1057,18 @@
VideoSendStream::Config send_config = sender_call->GetDefaultSendConfig();
send_config.rtp.ssrcs.push_back(ssrc);
- send_config.encoder_settings =
- test::CreateEncoderSettings(encoders[i].get(), "VP8", 124, 1);
- VideoStream* stream = &send_config.encoder_settings.streams[0];
+ send_config.encoder_settings.encoder = encoders[i].get();
+ send_config.encoder_settings.payload_name = "VP8";
+ send_config.encoder_settings.payload_type = 124;
+ std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
+ VideoStream* stream = &video_streams[0];
stream->width = width;
stream->height = height;
stream->max_framerate = 5;
stream->min_bitrate_bps = stream->target_bitrate_bps =
stream->max_bitrate_bps = 100000;
- send_streams[i] = sender_call->CreateVideoSendStream(send_config);
+ send_streams[i] =
+ sender_call->CreateVideoSendStream(send_config, video_streams, NULL);
send_streams[i]->Start();
VideoReceiveStream::Config receive_config =
@@ -1154,8 +1159,7 @@
StartSending();
scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
- send_config_.encoder_settings.streams[0].width,
- send_config_.encoder_settings.streams[0].height));
+ video_streams_[0].width, video_streams_[0].height));
send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
diff --git a/webrtc/video/full_stack.cc b/webrtc/video/full_stack.cc
index cb97cd8..6b21cbe 100644
--- a/webrtc/video/full_stack.cc
+++ b/webrtc/video/full_stack.cc
@@ -398,16 +398,19 @@
send_config.rtp.ssrcs.push_back(kSendSsrc);
scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
- send_config.encoder_settings =
- test::CreateEncoderSettings(encoder.get(), "VP8", 124, 1);
- VideoStream* stream = &send_config.encoder_settings.streams[0];
+ send_config.encoder_settings.encoder = encoder.get();
+ send_config.encoder_settings.payload_name = "VP8";
+ send_config.encoder_settings.payload_type = 124;
+ std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
+ VideoStream* stream = &video_streams[0];
stream->width = params.clip.width;
stream->height = params.clip.height;
stream->min_bitrate_bps = stream->target_bitrate_bps =
stream->max_bitrate_bps = params.bitrate * 1000;
stream->max_framerate = params.clip.fps;
- VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+ VideoSendStream* send_stream =
+ call->CreateVideoSendStream(send_config, video_streams, NULL);
analyzer.input_ = send_stream->Input();
scoped_ptr<test::FrameGeneratorCapturer> file_capturer(
diff --git a/webrtc/video/loopback.cc b/webrtc/video/loopback.cc
index eb2d5ae..ecc2089 100644
--- a/webrtc/video/loopback.cc
+++ b/webrtc/video/loopback.cc
@@ -72,19 +72,21 @@
send_config.local_renderer = local_preview.get();
scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
- send_config.encoder_settings =
- test::CreateEncoderSettings(encoder.get(), "VP8", 124, 1);
- VideoStream* stream = &send_config.encoder_settings.streams[0];
+ send_config.encoder_settings.encoder = encoder.get();
+ send_config.encoder_settings.payload_name = "VP8";
+ send_config.encoder_settings.payload_type = 124;
+ std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
+ VideoStream* stream = &video_streams[0];
stream->width = flags::Width();
stream->height = flags::Height();
stream->min_bitrate_bps = static_cast<int>(flags::MinBitrate()) * 1000;
- stream->target_bitrate_bps =
- static_cast<int>(flags::MaxBitrate()) * 1000;
+ stream->target_bitrate_bps = static_cast<int>(flags::MaxBitrate()) * 1000;
stream->max_bitrate_bps = static_cast<int>(flags::MaxBitrate()) * 1000;
stream->max_framerate = 30;
stream->max_qp = 56;
- VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+ VideoSendStream* send_stream =
+ call->CreateVideoSendStream(send_config, video_streams, NULL);
Clock* test_clock = Clock::GetRealTimeClock();
diff --git a/webrtc/video/rampup_tests.cc b/webrtc/video/rampup_tests.cc
index c86963d..989deea 100644
--- a/webrtc/video/rampup_tests.cc
+++ b/webrtc/video/rampup_tests.cc
@@ -430,12 +430,15 @@
receiver_transport.SetReceiver(call->Receiver());
test::FakeEncoder encoder(Clock::GetRealTimeClock());
- send_config.encoder_settings =
- test::CreateEncoderSettings(&encoder, "FAKE", 125, num_streams);
+ send_config.encoder_settings.encoder = &encoder;
+ send_config.encoder_settings.payload_type = 125;
+ send_config.encoder_settings.payload_name = "FAKE";
+ std::vector<VideoStream> video_streams =
+ test::CreateVideoStreams(num_streams);
if (num_streams == 1) {
- send_config.encoder_settings.streams[0].target_bitrate_bps = 2000000;
- send_config.encoder_settings.streams[0].max_bitrate_bps = 2000000;
+ video_streams[0].target_bitrate_bps = 2000000;
+ video_streams[0].max_bitrate_bps = 2000000;
}
send_config.pacing = pacing;
@@ -455,25 +458,22 @@
// For multi stream rampup until all streams are being sent. That means
// enough birate to sent all the target streams plus the min bitrate of
// the last one.
- int expected_bitrate_bps =
- send_config.encoder_settings.streams.back().min_bitrate_bps;
- for (size_t i = 0; i < send_config.encoder_settings.streams.size() - 1;
- ++i) {
- expected_bitrate_bps +=
- send_config.encoder_settings.streams[i].target_bitrate_bps;
+ int expected_bitrate_bps = video_streams.back().min_bitrate_bps;
+ for (size_t i = 0; i < video_streams.size() - 1; ++i) {
+ expected_bitrate_bps += video_streams[i].target_bitrate_bps;
}
stream_observer.set_expected_bitrate_bps(expected_bitrate_bps);
}
- VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+ VideoSendStream* send_stream =
+ call->CreateVideoSendStream(send_config, video_streams, NULL);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
- test::FrameGeneratorCapturer::Create(
- send_stream->Input(),
- send_config.encoder_settings.streams.back().width,
- send_config.encoder_settings.streams.back().height,
- send_config.encoder_settings.streams.back().max_framerate,
- Clock::GetRealTimeClock()));
+ test::FrameGeneratorCapturer::Create(send_stream->Input(),
+ video_streams.back().width,
+ video_streams.back().height,
+ video_streams.back().max_framerate,
+ Clock::GetRealTimeClock()));
send_stream->Start();
frame_generator_capturer->Start();
@@ -504,23 +504,29 @@
receiver_transport.SetReceiver(call->Receiver());
test::FakeEncoder encoder(Clock::GetRealTimeClock());
- send_config.encoder_settings =
- test::CreateEncoderSettings(&encoder, "FAKE", 125, number_of_streams);
+ send_config.encoder_settings.encoder = &encoder;
+ send_config.encoder_settings.payload_type = 125;
+ send_config.encoder_settings.payload_name = "FAKE";
+ std::vector<VideoStream> video_streams =
+ test::CreateVideoStreams(number_of_streams);
+
send_config.rtp.nack.rtp_history_ms = 1000;
send_config.rtp.ssrcs.insert(
send_config.rtp.ssrcs.begin(), ssrcs.begin(), ssrcs.end());
send_config.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId));
send_config.suspend_below_min_bitrate = true;
+ send_config.pacing = true;
- VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+ VideoSendStream* send_stream =
+ call->CreateVideoSendStream(send_config, video_streams, NULL);
stream_observer.SetSendStream(send_stream);
size_t width = 0;
size_t height = 0;
- for (size_t i = 0; i < send_config.encoder_settings.streams.size(); ++i) {
- size_t stream_width = send_config.encoder_settings.streams[i].width;
- size_t stream_height = send_config.encoder_settings.streams[i].height;
+ for (size_t i = 0; i < video_streams.size(); ++i) {
+ size_t stream_width = video_streams[i].width;
+ size_t stream_height = video_streams[i].height;
if (stream_width > width)
width = stream_width;
if (stream_height > height)
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index 012ca68..9c3298c 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -150,13 +150,13 @@
external_codec_ = ViEExternalCodec::GetInterface(video_engine);
for (size_t i = 0; i < config_.external_decoders.size(); ++i) {
- ExternalVideoDecoder* decoder = &config_.external_decoders[i];
+ const ExternalVideoDecoder& decoder = config_.external_decoders[i];
if (external_codec_->RegisterExternalReceiveCodec(
channel_,
- decoder->payload_type,
- decoder->decoder,
- decoder->renderer,
- decoder->expected_delay_ms) != 0) {
+ decoder.payload_type,
+ decoder.decoder,
+ decoder.renderer,
+ decoder.expected_delay_ms) != 0) {
// TODO(pbos): Abort gracefully? Can this be a runtime error?
abort();
}
diff --git a/webrtc/video/video_receive_stream.h b/webrtc/video/video_receive_stream.h
index 4ff086a..2a3c6df 100644
--- a/webrtc/video/video_receive_stream.h
+++ b/webrtc/video/video_receive_stream.h
@@ -69,7 +69,7 @@
private:
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
- VideoReceiveStream::Config config_;
+ const VideoReceiveStream::Config config_;
Clock* const clock_;
ViEBase* video_engine_base_;
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 886e3dc..8a43387 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -15,6 +15,7 @@
#include <vector>
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
+#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/video_engine/include/vie_base.h"
#include "webrtc/video_engine/include/vie_capture.h"
#include "webrtc/video_engine/include/vie_codec.h"
@@ -32,18 +33,7 @@
ss << "{payload_name: " << payload_name;
ss << ", payload_type: " << payload_type;
if (encoder != NULL)
- ss << ", (encoder)";
- if (encoder_settings != NULL)
- ss << ", (encoder_settings)";
-
- ss << ", streams: {";
- for (size_t i = 0; i < streams.size(); ++i) {
- ss << streams[i].ToString();
- if (i != streams.size() - 1)
- ss << "}, {";
- }
- ss << '}';
-
+ ss << ", encoder: " << (encoder != NULL ? "(encoder)" : "NULL");
ss << '}';
return ss.str();
}
@@ -124,10 +114,11 @@
CpuOveruseObserver* overuse_observer,
webrtc::VideoEngine* video_engine,
const VideoSendStream::Config& config,
+ const std::vector<VideoStream> video_streams,
+ const void* encoder_settings,
int base_channel)
: transport_adapter_(transport),
encoded_frame_proxy_(config.post_encode_callback),
- codec_lock_(CriticalSectionWrapper::CreateCriticalSection()),
config_(config),
external_codec_(NULL),
channel_(-1),
@@ -141,7 +132,7 @@
assert(config_.rtp.ssrcs.size() > 0);
if (config_.suspend_below_min_bitrate)
- config_.pacing = true;
+ assert(config_.pacing);
rtp_rtcp_->SetTransmissionSmoothingStatus(channel_, config_.pacing);
assert(config_.rtp.min_transmit_bitrate_bps >= 0);
@@ -216,10 +207,8 @@
}
codec_ = ViECodec::GetInterface(video_engine);
- if (!ReconfigureVideoEncoder(config_.encoder_settings.streams,
- config_.encoder_settings.encoder_settings)) {
+ if (!ReconfigureVideoEncoder(video_streams, encoder_settings))
abort();
- }
if (overuse_observer)
video_engine_base_->RegisterCpuOveruseObserver(channel_, overuse_observer);
@@ -232,9 +221,8 @@
&encoded_frame_proxy_);
}
- if (config_.suspend_below_min_bitrate) {
+ if (config_.suspend_below_min_bitrate)
codec_->SuspendBelowMinBitrate(channel_);
- }
rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(channel_,
stats_proxy_.get());
@@ -304,15 +292,12 @@
bool VideoSendStream::ReconfigureVideoEncoder(
const std::vector<VideoStream>& streams,
- void* encoder_settings) {
+ const void* encoder_settings) {
assert(!streams.empty());
assert(config_.rtp.ssrcs.size() >= streams.size());
// TODO(pbos): Wire encoder_settings.
assert(encoder_settings == NULL);
- // VideoStreams in config_.encoder_settings need to be locked.
- CriticalSectionScoped crit(codec_lock_.get());
-
VideoCodec video_codec;
memset(&video_codec, 0, sizeof(video_codec));
video_codec.codecType =
@@ -383,8 +368,8 @@
if (video_codec.startBitrate > video_codec.maxBitrate)
video_codec.startBitrate = video_codec.maxBitrate;
- assert(config_.encoder_settings.streams[0].max_framerate > 0);
- video_codec.maxFramerate = config_.encoder_settings.streams[0].max_framerate;
+ assert(streams[0].max_framerate > 0);
+ video_codec.maxFramerate = streams[0].max_framerate;
if (codec_->SetSendCodec(channel_, video_codec) != 0)
return false;
@@ -396,9 +381,6 @@
static_cast<unsigned char>(i));
}
- config_.encoder_settings.streams = streams;
- config_.encoder_settings.encoder_settings = encoder_settings;
-
if (config_.rtp.rtx.ssrcs.empty())
return true;
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index a7e2267..125c7fd 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -42,6 +42,8 @@
CpuOveruseObserver* overuse_observer,
webrtc::VideoEngine* video_engine,
const VideoSendStream::Config& config,
+ const std::vector<VideoStream> video_streams,
+ const void* encoder_settings,
int base_channel);
virtual ~VideoSendStream();
@@ -50,7 +52,7 @@
virtual void Stop() OVERRIDE;
virtual bool ReconfigureVideoEncoder(const std::vector<VideoStream>& streams,
- void* encoder_settings) OVERRIDE;
+ const void* encoder_settings) OVERRIDE;
virtual Stats GetStats() const OVERRIDE;
@@ -70,8 +72,7 @@
private:
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
- scoped_ptr<CriticalSectionWrapper> codec_lock_;
- VideoSendStream::Config config_;
+ const VideoSendStream::Config config_;
ViEBase* video_engine_base_;
ViECapture* capture_;
diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc
index 6662866..db71f54 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -45,9 +45,9 @@
protected:
void RunSendTest(Call* call,
- const VideoSendStream::Config& config,
test::RtpRtcpObserver* observer) {
- send_stream_ = call->CreateVideoSendStream(config);
+ send_stream_ =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
test::FrameGeneratorCapturer::Create(
send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -62,17 +62,16 @@
call->DestroyVideoSendStream(send_stream_);
}
- VideoSendStream::Config GetSendTestConfig(Call* call, size_t num_streams) {
+ void CreateTestConfig(Call* call, size_t num_streams) {
assert(num_streams <= kNumSendSsrcs);
- VideoSendStream::Config config = call->GetDefaultSendConfig();
- config.encoder_settings = test::CreateEncoderSettings(
- &fake_encoder_, "FAKE", kFakeSendPayloadType, num_streams);
- config.encoder_settings.encoder = &fake_encoder_;
- config.encoder_settings.payload_type = kFakeSendPayloadType;
+ send_config_ = call->GetDefaultSendConfig();
+ send_config_.encoder_settings.encoder = &fake_encoder_;
+ send_config_.encoder_settings.payload_name = "FAKE";
+ send_config_.encoder_settings.payload_type = kFakeSendPayloadType;
+ video_streams_ = test::CreateVideoStreams(num_streams);
+ send_config_.encoder_settings.payload_type = kFakeSendPayloadType;
for (size_t i = 0; i < num_streams; ++i)
- config.rtp.ssrcs.push_back(kSendSsrcs[i]);
- config.pacing = true;
- return config;
+ send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]);
}
void TestNackRetransmission(uint32_t retransmit_ssrc,
@@ -91,6 +90,8 @@
static const uint32_t kSendRtxSsrc;
static const uint32_t kSendSsrcs[kNumSendSsrcs];
+ VideoSendStream::Config send_config_;
+ std::vector<VideoStream> video_streams_;
VideoSendStream* send_stream_;
test::FakeEncoder fake_encoder_;
};
@@ -158,24 +159,23 @@
Call::Config call_config(observer.SendTransport());
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config =
- GetSendTestConfig(call.get(), num_ssrcs);
+ CreateTestConfig(call.get(), num_ssrcs);
if (num_ssrcs > 1) {
// Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
- std::vector<VideoStream>* streams = &send_config.encoder_settings.streams;
- for (size_t i = 0; i < streams->size(); ++i) {
- (*streams)[i].min_bitrate_bps = 10000;
- (*streams)[i].target_bitrate_bps = 10000;
- (*streams)[i].max_bitrate_bps = 10000;
+ for (size_t i = 0; i < video_streams_.size(); ++i) {
+ video_streams_[i].min_bitrate_bps = 10000;
+ video_streams_[i].target_bitrate_bps = 10000;
+ video_streams_[i].max_bitrate_bps = 10000;
}
}
- std::vector<VideoStream> all_streams = send_config.encoder_settings.streams;
+ std::vector<VideoStream> all_streams = video_streams_;
if (send_single_ssrc_first)
- send_config.encoder_settings.streams.resize(1);
+ video_streams_.resize(1);
- send_stream_ = call->CreateVideoSendStream(send_config);
+ send_stream_ =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
test::FrameGeneratorCapturer::Create(
send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -204,8 +204,9 @@
Call::Config call_config(&transport);
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config config = GetSendTestConfig(call.get(), 1);
- VideoSendStream* stream = call->CreateVideoSendStream(config);
+ CreateTestConfig(call.get(), 1);
+ VideoSendStream* stream =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
stream->Start();
stream->Start();
call->DestroyVideoSendStream(stream);
@@ -216,8 +217,9 @@
Call::Config call_config(&transport);
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config config = GetSendTestConfig(call.get(), 1);
- VideoSendStream* stream = call->CreateVideoSendStream(config);
+ CreateTestConfig(call.get(), 1);
+ VideoSendStream* stream =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
stream->Stop();
stream->Stop();
call->DestroyVideoSendStream(stream);
@@ -260,10 +262,10 @@
Call::Config call_config(observer.SendTransport());
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.c_name = kCName;
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.c_name = kCName;
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
}
TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
@@ -292,11 +294,11 @@
Call::Config call_config(observer.SendTransport());
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.extensions.push_back(
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
}
TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
@@ -339,12 +341,12 @@
Call::Config call_config(observer.SendTransport());
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.encoder_settings.encoder = &encoder;
- send_config.rtp.extensions.push_back(
+ CreateTestConfig(call.get(), 1);
+ send_config_.encoder_settings.encoder = &encoder;
+ send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId));
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
}
class FakeReceiveStatistics : public NullReceiveStatistics {
@@ -413,8 +415,9 @@
Call::Config call_config(&transport);
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- VideoSendStream* video_send_stream = call->CreateVideoSendStream(send_config);
+ CreateTestConfig(call.get(), 1);
+ VideoSendStream* video_send_stream =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
video_send_stream->Start();
I420VideoFrame frame;
@@ -492,11 +495,11 @@
observer.SetReceivers(call->Receiver(), NULL);
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.fec.red_payload_type = kRedPayloadType;
- send_config.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.fec.red_payload_type = kRedPayloadType;
+ send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
}
void VideoSendStreamTest::TestNackRetransmission(
@@ -568,14 +571,14 @@
scoped_ptr<Call> call(Call::Create(call_config));
observer.SetReceivers(call->Receiver(), NULL);
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.nack.rtp_history_ms = 1000;
- send_config.rtp.rtx.payload_type = retransmit_payload_type;
- send_config.pacing = enable_pacing;
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.nack.rtp_history_ms = 1000;
+ send_config_.rtp.rtx.payload_type = retransmit_payload_type;
+ send_config_.pacing = enable_pacing;
if (retransmit_ssrc != kSendSsrc)
- send_config.rtp.rtx.ssrcs.push_back(retransmit_ssrc);
+ send_config_.rtp.rtx.ssrcs.push_back(retransmit_ssrc);
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
}
TEST_F(VideoSendStreamTest, RetransmitsNack) {
@@ -762,27 +765,27 @@
observer.SetReceivers(call->Receiver(), NULL);
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
+ CreateTestConfig(call.get(), 1);
if (with_fec) {
- send_config.rtp.fec.red_payload_type = kRedPayloadType;
- send_config.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
+ send_config_.rtp.fec.red_payload_type = kRedPayloadType;
+ send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
}
if (format == kVP8)
- send_config.encoder_settings.payload_name = "VP8";
+ send_config_.encoder_settings.payload_name = "VP8";
- send_config.pacing = false;
- send_config.encoder_settings.encoder = &encoder;
- send_config.rtp.max_packet_size = kMaxPacketSize;
- send_config.post_encode_callback = &observer;
+ send_config_.pacing = false;
+ send_config_.encoder_settings.encoder = &encoder;
+ send_config_.rtp.max_packet_size = kMaxPacketSize;
+ send_config_.post_encode_callback = &observer;
// Add an extension header, to make the RTP header larger than the base
// length of 12 bytes.
static const uint8_t kAbsSendTimeExtensionId = 13;
- send_config.rtp.extensions.push_back(
+ send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
}
// TODO(sprang): Is there any way of speeding up these tests?
@@ -948,18 +951,19 @@
scoped_ptr<Call> call(Call::Create(call_config));
observer.SetReceiver(call->Receiver());
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.nack.rtp_history_ms = 1000;
- send_config.pre_encode_callback = &observer;
- send_config.suspend_below_min_bitrate = true;
- int min_bitrate_bps = send_config.encoder_settings.streams[0].min_bitrate_bps;
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.nack.rtp_history_ms = 1000;
+ send_config_.pre_encode_callback = &observer;
+ send_config_.suspend_below_min_bitrate = true;
+ send_config_.pacing = true;
+ int min_bitrate_bps = video_streams_[0].min_bitrate_bps;
observer.set_low_remb_bps(min_bitrate_bps - 10000);
int threshold_window = std::max(min_bitrate_bps / 10, 10000);
- ASSERT_GT(send_config.encoder_settings.streams[0].max_bitrate_bps,
+ ASSERT_GT(video_streams_[0].max_bitrate_bps,
min_bitrate_bps + threshold_window + 5000);
observer.set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
- RunSendTest(call.get(), send_config, &observer);
+ RunSendTest(call.get(), &observer);
observer.Stop();
}
@@ -1022,9 +1026,10 @@
scoped_ptr<Call> call(Call::Create(call_config));
observer.SetReceivers(call->Receiver(), call->Receiver());
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 3);
+ CreateTestConfig(call.get(), 3);
- send_stream_ = call->CreateVideoSendStream(send_config);
+ send_stream_ =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
test::FrameGeneratorCapturer::Create(
send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -1107,11 +1112,13 @@
Call::Config call_config(observer.SendTransport());
scoped_ptr<Call> call(Call::Create(call_config));
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.c_name = kCName;
- observer.SetConfig(send_config);
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.c_name = kCName;
+ send_config_.pacing = true;
+ observer.SetConfig(send_config_);
- send_stream_ = call->CreateVideoSendStream(send_config);
+ send_stream_ =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
observer.SetSendStream(send_stream_);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
test::FrameGeneratorCapturer::Create(
@@ -1202,9 +1209,10 @@
scoped_ptr<Call> call(Call::Create(call_config));
observer.SetReceivers(&observer, call->Receiver());
- VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
- send_config.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
- send_stream_ = call->CreateVideoSendStream(send_config);
+ CreateTestConfig(call.get(), 1);
+ send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
+ send_stream_ =
+ call->CreateVideoSendStream(send_config_, video_streams_, NULL);
observer.SetSendStream(send_stream_);
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h
index e173e3b..b33f389 100644
--- a/webrtc/video_send_stream.h
+++ b/webrtc/video_send_stream.h
@@ -66,8 +66,7 @@
std::string ToString() const;
struct EncoderSettings {
- EncoderSettings()
- : payload_type(-1), encoder(NULL), encoder_settings(NULL) {}
+ EncoderSettings() : payload_type(-1), encoder(NULL) {}
std::string ToString() const;
std::string payload_name;
@@ -76,13 +75,6 @@
// Uninitialized VideoEncoder instance to be used for encoding. Will be
// initialized from inside the VideoSendStream.
webrtc::VideoEncoder* encoder;
- // TODO(pbos): Wire up encoder-specific settings.
- // Encoder-specific settings, will be passed to the encoder during
- // initialization.
- void* encoder_settings;
-
- // List of stream settings to encode (resolution, bitrates, framerate).
- std::vector<VideoStream> streams;
} encoder_settings;
static const size_t kDefaultMaxPacketSize = 1500 - 40; // TCP over IPv4.
@@ -155,8 +147,7 @@
// True if the stream should be suspended when the available bitrate fall
// below the minimum configured bitrate. If this variable is false, the
// stream may send at a rate higher than the estimated available bitrate.
- // Enabling suspend_below_min_bitrate will also enable pacing and padding,
- // otherwise, the video will be unable to recover from suspension.
+ // |suspend_below_min_bitrate| requires |pacing| to be enabled as well.
bool suspend_below_min_bitrate;
};
@@ -171,7 +162,7 @@
// in the config. Encoder settings are passed on to the encoder instance along
// with the VideoStream settings.
virtual bool ReconfigureVideoEncoder(const std::vector<VideoStream>& streams,
- void* encoder_settings) = 0;
+ const void* encoder_settings) = 0;
virtual Stats GetStats() const = 0;