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
This commit is contained in:
parent
4b83a471de
commit
6ae48c6609
@ -197,22 +197,15 @@ WebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() {
|
||||
|
||||
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 @@ class DefaultVideoEncoderFactory : public WebRtcVideoEncoderFactory2 {
|
||||
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 @@ WebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() const {
|
||||
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 @@ bool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) {
|
||||
|
||||
// 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 @@ bool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) {
|
||||
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 @@ void WebRtcVideoChannel2::SetCodecForAllSendStreams(
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
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 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame(
|
||||
}
|
||||
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 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat(
|
||||
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 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec(
|
||||
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 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() {
|
||||
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();
|
||||
}
|
||||
|
@ -83,11 +83,15 @@ class WebRtcVideoChannel2;
|
||||
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 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler,
|
||||
struct VideoCodecSettings {
|
||||
VideoCodecSettings();
|
||||
|
||||
cricket::VideoCodec codec;
|
||||
VideoCodec codec;
|
||||
webrtc::FecConfig fec;
|
||||
int rtx_payload_type;
|
||||
};
|
||||
@ -266,8 +270,11 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler,
|
||||
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 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler,
|
||||
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 @@ class WebRtcVideoChannel2 : public talk_base::MessageHandler,
|
||||
|
||||
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_);
|
||||
|
@ -52,12 +52,12 @@ static const uint32 kRtxSsrcs1[] = {4};
|
||||
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 @@ class FakeVideoSendStream : public webrtc::VideoSendStream {
|
||||
|
||||
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 @@ class FakeVideoSendStream : public webrtc::VideoSendStream {
|
||||
|
||||
bool sending_;
|
||||
webrtc::VideoSendStream::Config config_;
|
||||
std::vector<webrtc::VideoStream> video_streams_;
|
||||
};
|
||||
|
||||
class FakeVideoReceiveStream : public webrtc::VideoReceiveStream {
|
||||
@ -178,8 +178,11 @@ class FakeCall : public webrtc::Call {
|
||||
}
|
||||
|
||||
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 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
|
||||
|
||||
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 @@ TEST_F(WebRtcVideoChannel2Test, DISABLED_StartSendBitrate) {
|
||||
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 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
|
||||
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));
|
||||
|
@ -83,7 +83,9 @@ class Call {
|
||||
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;
|
||||
|
||||
|
@ -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 @@ VideoSendStream::Config::EncoderSettings CreateEncoderSettings(
|
||||
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 @@ VideoCodec CreateDecoderVideoCodec(
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -70,8 +70,10 @@ class BitrateEstimatorTest : public ::testing::Test {
|
||||
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 @@ class BitrateEstimatorTest : public ::testing::Test {
|
||||
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 @@ class BitrateEstimatorTest : public ::testing::Test {
|
||||
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_;
|
||||
};
|
||||
|
@ -70,7 +70,9 @@ class Call : public webrtc::Call, public PacketReceiver {
|
||||
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::Config Call::GetDefaultSendConfig() {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -53,18 +53,19 @@ class CallPerfTest : public ::testing::Test {
|
||||
: 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 @@ class CallPerfTest : public ::testing::Test {
|
||||
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_F(CallPerfTest, PlaysOutAudioAndVideoInSync) {
|
||||
|
||||
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 @@ void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
|
||||
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 @@ void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_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;
|
||||
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 @@ TEST_F(CallPerfTest, RegisterCpuOveruseObserver) {
|
||||
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 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
|
||||
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();
|
||||
|
@ -73,8 +73,10 @@ class CallTest : public ::testing::Test {
|
||||
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 @@ class CallTest : public ::testing::Test {
|
||||
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 @@ class CallTest : public ::testing::Test {
|
||||
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 @@ TEST_F(CallTest, TransmitsFirstFrame) {
|
||||
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 @@ TEST_F(CallTest, UsesFrameCallbacks) {
|
||||
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 @@ TEST_F(CallTest, SendsAndReceivesMultipleStreams) {
|
||||
|
||||
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 @@ TEST_F(CallTest, ObserversEncodedFrames) {
|
||||
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())
|
||||
|
@ -398,16 +398,19 @@ TEST_P(FullStackTest, NoPacketLoss) {
|
||||
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(
|
||||
|
@ -72,19 +72,21 @@ void Loopback() {
|
||||
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();
|
||||
|
||||
|
@ -430,12 +430,15 @@ class RampUpTest : public ::testing::Test {
|
||||
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 @@ class RampUpTest : public ::testing::Test {
|
||||
// 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 @@ class RampUpTest : public ::testing::Test {
|
||||
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)
|
||||
|
@ -150,13 +150,13 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
||||
private:
|
||||
TransportAdapter transport_adapter_;
|
||||
EncodedFrameCallbackAdapter encoded_frame_proxy_;
|
||||
VideoReceiveStream::Config config_;
|
||||
const VideoReceiveStream::Config config_;
|
||||
Clock* const clock_;
|
||||
|
||||
ViEBase* video_engine_base_;
|
||||
|
@ -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 @@ VideoSendStream::Config::EncoderSettings::ToString() const {
|
||||
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 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
|
||||
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 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
|
||||
|
||||
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 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
|
||||
}
|
||||
|
||||
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 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
|
||||
&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 @@ void VideoSendStream::Stop() {
|
||||
|
||||
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 @@ bool VideoSendStream::ReconfigureVideoEncoder(
|
||||
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 @@ bool VideoSendStream::ReconfigureVideoEncoder(
|
||||
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;
|
||||
|
||||
|
@ -42,6 +42,8 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
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 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
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 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
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_;
|
||||
|
@ -45,9 +45,9 @@ class VideoSendStreamTest : public ::testing::Test {
|
||||
|
||||
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 @@ class VideoSendStreamTest : public ::testing::Test {
|
||||
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 @@ class VideoSendStreamTest : public ::testing::Test {
|
||||
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 @@ void VideoSendStreamTest::SendsSetSsrcs(size_t num_ssrcs,
|
||||
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 @@ TEST_F(VideoSendStreamTest, CanStartStartedStream) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, SupportsCName) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, SwapsI420VideoFrames) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, SupportsFec) {
|
||||
|
||||
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 @@ void VideoSendStreamTest::TestNackRetransmission(
|
||||
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 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
|
||||
|
||||
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 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, ProducesStats) {
|
||||
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 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
|
||||
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(
|
||||
|
@ -66,8 +66,7 @@ class VideoSendStream {
|
||||
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 @@ class VideoSendStream {
|
||||
// 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 @@ class VideoSendStream {
|
||||
// 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 @@ class VideoSendStream {
|
||||
// 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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user