Update stable to r5287.
git-svn-id: http://webrtc.googlecode.com/svn/stable/talk@5288 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/app/webrtc/statscollector.cc b/app/webrtc/statscollector.cc
index b00d19c..7e1e7ee 100644
--- a/app/webrtc/statscollector.cc
+++ b/app/webrtc/statscollector.cc
@@ -51,6 +51,8 @@
const char StatsReport::kStatsValueNameBucketDelay[] = "googBucketDelay";
const char StatsReport::kStatsValueNameBytesReceived[] = "bytesReceived";
const char StatsReport::kStatsValueNameBytesSent[] = "bytesSent";
+const char StatsReport::kStatsValueNameBandwidthLimitedResolution[] =
+ "googBandwidthLimitedResolution";
const char StatsReport::kStatsValueNameCaptureJitterMs[] =
"googCaptureJitterMs";
const char StatsReport::kStatsValueNameCaptureQueueDelayMsPerS[] =
@@ -59,6 +61,8 @@
const char StatsReport::kStatsValueNameCodecName[] = "googCodecName";
const char StatsReport::kStatsValueNameComponent[] = "googComponent";
const char StatsReport::kStatsValueNameContentName[] = "googContentName";
+const char StatsReport::kStatsValueNameCpuLimitedResolution[] =
+ "googCpuLimitedResolution";
const char StatsReport::kStatsValueNameDer[] = "googDerBase64";
// Echo metrics from the audio processing module.
const char StatsReport::kStatsValueNameEchoCancellationQualityMin[] =
@@ -135,6 +139,8 @@
const char StatsReport::kStatsValueNameTrackId[] = "googTrackId";
const char StatsReport::kStatsValueNameTypingNoiseState[] =
"googTypingNoiseState";
+const char StatsReport::kStatsValueNameViewLimitedResolution[] =
+ "googViewLimitedResolution";
const char StatsReport::kStatsValueNameWritable[] = "googWritable";
const char StatsReport::kStatsReportTypeSession[] = "googLibjingleSession";
@@ -299,6 +305,12 @@
info.framerate_sent);
report->AddValue(StatsReport::kStatsValueNameRtt, info.rtt_ms);
report->AddValue(StatsReport::kStatsValueNameCodecName, info.codec_name);
+ report->AddBoolean(StatsReport::kStatsValueNameCpuLimitedResolution,
+ (info.adapt_reason & 0x1) > 0);
+ report->AddBoolean(StatsReport::kStatsValueNameBandwidthLimitedResolution,
+ (info.adapt_reason & 0x2) > 0);
+ report->AddBoolean(StatsReport::kStatsValueNameViewLimitedResolution,
+ (info.adapt_reason & 0x4) > 0);
report->AddValue(StatsReport::kStatsValueNameAvgEncodeMs, info.avg_encode_ms);
report->AddValue(StatsReport::kStatsValueNameCaptureJitterMs,
info.capture_jitter_ms);
diff --git a/app/webrtc/statstypes.h b/app/webrtc/statstypes.h
index 6afc8d7..6890f9e 100644
--- a/app/webrtc/statstypes.h
+++ b/app/webrtc/statstypes.h
@@ -133,6 +133,9 @@
static const char kStatsValueNameCaptureJitterMs[];
static const char kStatsValueNameCaptureQueueDelayMsPerS[];
static const char kStatsValueNameCodecName[];
+ static const char kStatsValueNameBandwidthLimitedResolution[];
+ static const char kStatsValueNameCpuLimitedResolution[];
+ static const char kStatsValueNameViewLimitedResolution[];
static const char kStatsValueNameEchoCancellationQualityMin[];
static const char kStatsValueNameEchoDelayMedian[];
static const char kStatsValueNameEchoDelayStdDev[];
diff --git a/base/asyncpacketsocket.h b/base/asyncpacketsocket.h
index 8ee0a36..29ab55f 100644
--- a/base/asyncpacketsocket.h
+++ b/base/asyncpacketsocket.h
@@ -38,7 +38,7 @@
// This structure will have the information about when packet is actually
// received by socket.
struct PacketTime {
- PacketTime() : timestamp(0), not_before(0) {}
+ PacketTime() : timestamp(-1), not_before(-1) {}
PacketTime(int64 timestamp, int64 not_before)
: timestamp(timestamp), not_before(not_before) {
}
diff --git a/media/webrtc/fakewebrtcvideoengine.h b/media/webrtc/fakewebrtcvideoengine.h
index 070c731..bb75c2a 100644
--- a/media/webrtc/fakewebrtcvideoengine.h
+++ b/media/webrtc/fakewebrtcvideoengine.h
@@ -339,12 +339,14 @@
};
class Capturer : public webrtc::ViEExternalCapture {
public:
- Capturer() : channel_id_(-1), denoising_(false), last_capture_time_(0) { }
+ Capturer() : channel_id_(-1), denoising_(false),
+ last_capture_time_(0), incoming_frame_num_(0) { }
int channel_id() const { return channel_id_; }
void set_channel_id(int channel_id) { channel_id_ = channel_id; }
bool denoising() const { return denoising_; }
void set_denoising(bool denoising) { denoising_ = denoising; }
- int64 last_capture_time() { return last_capture_time_; }
+ int64 last_capture_time() const { return last_capture_time_; }
+ int incoming_frame_num() const { return incoming_frame_num_; }
// From ViEExternalCapture
virtual int IncomingFrame(unsigned char* videoFrame,
@@ -359,6 +361,7 @@
const webrtc::ViEVideoFrameI420& video_frame,
unsigned long long captureTime) {
last_capture_time_ = captureTime;
+ ++incoming_frame_num_;
return 0;
}
@@ -366,6 +369,7 @@
int channel_id_;
bool denoising_;
int64 last_capture_time_;
+ int incoming_frame_num_;
};
FakeWebRtcVideoEngine(const cricket::VideoCodec* const* codecs,
@@ -408,6 +412,16 @@
int GetLastCapturer() const { return last_capturer_; }
int GetNumCapturers() const { return static_cast<int>(capturers_.size()); }
+ int GetIncomingFrameNum(int channel_id) const {
+ for (std::map<int, Capturer*>::const_iterator iter = capturers_.begin();
+ iter != capturers_.end(); ++iter) {
+ Capturer* capturer = iter->second;
+ if (capturer->channel_id() == channel_id) {
+ return capturer->incoming_frame_num();
+ }
+ }
+ return -1;
+ }
void set_fail_alloc_capturer(bool fail_alloc_capturer) {
fail_alloc_capturer_ = fail_alloc_capturer;
}
diff --git a/media/webrtc/fakewebrtcvoiceengine.h b/media/webrtc/fakewebrtcvoiceengine.h
index 809816b..a68d65e 100644
--- a/media/webrtc/fakewebrtcvoiceengine.h
+++ b/media/webrtc/fakewebrtcvoiceengine.h
@@ -631,6 +631,13 @@
// webrtc::VoENetEqStats
WEBRTC_STUB(GetNetworkStatistics, (int, webrtc::NetworkStatistics&));
+#ifdef USE_WEBRTC_DEV_BRANCH
+ WEBRTC_FUNC_CONST(GetDecodingCallStatistics, (int channel,
+ webrtc::AudioDecodingCallStats*)) {
+ WEBRTC_CHECK_CHANNEL(channel);
+ return 0;
+ }
+#endif
// webrtc::VoENetwork
WEBRTC_FUNC(RegisterExternalTransport, (int channel,
diff --git a/media/webrtc/webrtcmediaengine.h b/media/webrtc/webrtcmediaengine.h
index 94e7a99..82abefa 100644
--- a/media/webrtc/webrtcmediaengine.h
+++ b/media/webrtc/webrtcmediaengine.h
@@ -145,6 +145,9 @@
virtual void SetVideoLogging(int min_sev, const char* filter) OVERRIDE {
delegate_->SetVideoLogging(min_sev, filter);
}
+ virtual bool StartAecDump(FILE* file) OVERRIDE {
+ return delegate_->StartAecDump(file);
+ }
virtual bool RegisterVoiceProcessor(
uint32 ssrc, VoiceProcessor* video_processor,
MediaProcessorDirection direction) OVERRIDE {
diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc
index 1c1ccc3..88e09fc 100644
--- a/media/webrtc/webrtcvideoengine.cc
+++ b/media/webrtc/webrtcvideoengine.cc
@@ -2119,18 +2119,6 @@
}
WebRtcVideoChannelSendInfo* WebRtcVideoMediaChannel::GetSendChannel(
- VideoCapturer* video_capturer) {
- for (SendChannelMap::iterator iter = send_channels_.begin();
- iter != send_channels_.end(); ++iter) {
- WebRtcVideoChannelSendInfo* send_channel = iter->second;
- if (send_channel->video_capturer() == video_capturer) {
- return send_channel;
- }
- }
- return NULL;
-}
-
-WebRtcVideoChannelSendInfo* WebRtcVideoMediaChannel::GetSendChannel(
uint32 local_ssrc) {
uint32 key;
if (!GetSendChannelKey(local_ssrc, &key)) {
@@ -2159,6 +2147,18 @@
return true;
}
+int WebRtcVideoMediaChannel::GetSendChannelNum(VideoCapturer* capturer) {
+ int num = 0;
+ for (SendChannelMap::iterator iter = send_channels_.begin();
+ iter != send_channels_.end(); ++iter) {
+ WebRtcVideoChannelSendInfo* send_channel = iter->second;
+ if (send_channel->video_capturer() == capturer) {
+ ++num;
+ }
+ }
+ return num;
+}
+
uint32 WebRtcVideoMediaChannel::GetDefaultChannelSsrc() {
WebRtcVideoChannelSendInfo* send_channel = send_channels_[0];
const StreamParams* sp = send_channel->stream_params();
@@ -2174,11 +2174,8 @@
return false;
}
WebRtcVideoChannelSendInfo* send_channel = send_channels_[ssrc_key];
- VideoCapturer* capturer = send_channel->video_capturer();
- if (capturer != NULL) {
- capturer->SignalVideoFrame.disconnect(this);
- send_channel->set_video_capturer(NULL);
- }
+ MaybeDisconnectCapturer(send_channel->video_capturer());
+ send_channel->set_video_capturer(NULL);
int channel_id = send_channel->channel_id();
int capture_id = send_channel->capture_id();
@@ -2217,7 +2214,7 @@
if (capturer == NULL) {
return false;
}
- capturer->SignalVideoFrame.disconnect(this);
+ MaybeDisconnectCapturer(capturer);
send_channel->set_video_capturer(NULL);
const int64 timestamp = send_channel->local_stream_info()->time_stamp();
if (send_codec_) {
@@ -2468,14 +2465,10 @@
return false;
}
VideoCapturer* old_capturer = send_channel->video_capturer();
- if (old_capturer) {
- old_capturer->SignalVideoFrame.disconnect(this);
- }
+ MaybeDisconnectCapturer(old_capturer);
send_channel->set_video_capturer(capturer);
- capturer->SignalVideoFrame.connect(
- this,
- &WebRtcVideoMediaChannel::SendFrame);
+ MaybeConnectCapturer(capturer);
if (!capturer->IsScreencast() && ratio_w_ != 0 && ratio_h_ != 0) {
capturer->UpdateAspectRatio(ratio_w_, ratio_h_);
}
@@ -2865,20 +2858,23 @@
return true;
}
-// TODO(zhurunz): Add unittests to test this function.
-// TODO(thorcarpenter): This is broken. One capturer registered on two ssrc
-// will not send any video to the second ssrc send channel. We should remove
-// GetSendChannel(capturer) and pass in an ssrc here.
void WebRtcVideoMediaChannel::SendFrame(VideoCapturer* capturer,
const VideoFrame* frame) {
- // If there's send channel registers to the |capturer|, then only send the
- // frame to that channel and return. Otherwise send the frame to the default
- // channel, which currently taking frames from the engine.
- WebRtcVideoChannelSendInfo* send_channel = GetSendChannel(capturer);
- if (send_channel) {
- SendFrame(send_channel, frame, capturer->IsScreencast());
+ // If the |capturer| is registered to any send channel, then send the frame
+ // to those send channels.
+ bool capturer_is_channel_owned = false;
+ for (SendChannelMap::iterator iter = send_channels_.begin();
+ iter != send_channels_.end(); ++iter) {
+ WebRtcVideoChannelSendInfo* send_channel = iter->second;
+ if (send_channel->video_capturer() == capturer) {
+ SendFrame(send_channel, frame, capturer->IsScreencast());
+ capturer_is_channel_owned = true;
+ }
+ }
+ if (capturer_is_channel_owned) {
return;
}
+
// TODO(hellner): Remove below for loop once the captured frame no longer
// come from the engine, i.e. the engine no longer owns a capturer.
for (SendChannelMap::iterator iter = send_channels_.begin();
@@ -3754,6 +3750,19 @@
return true;
}
+void WebRtcVideoMediaChannel::MaybeConnectCapturer(VideoCapturer* capturer) {
+ if (capturer != NULL && GetSendChannelNum(capturer) == 1) {
+ capturer->SignalVideoFrame.connect(this,
+ &WebRtcVideoMediaChannel::SendFrame);
+ }
+}
+
+void WebRtcVideoMediaChannel::MaybeDisconnectCapturer(VideoCapturer* capturer) {
+ if (capturer != NULL && GetSendChannelNum(capturer) == 1) {
+ capturer->SignalVideoFrame.disconnect(this);
+ }
+}
+
} // namespace cricket
#endif // HAVE_WEBRTC_VIDEO
diff --git a/media/webrtc/webrtcvideoengine.h b/media/webrtc/webrtcvideoengine.h
index 6278461..289903a 100644
--- a/media/webrtc/webrtcvideoengine.h
+++ b/media/webrtc/webrtcvideoengine.h
@@ -366,11 +366,12 @@
// If the local ssrc correspond to that of the default channel the key is 0.
// For all other channels the returned key will be the same as the local ssrc.
bool GetSendChannelKey(uint32 local_ssrc, uint32* key);
- WebRtcVideoChannelSendInfo* GetSendChannel(VideoCapturer* video_capturer);
WebRtcVideoChannelSendInfo* GetSendChannel(uint32 local_ssrc);
// Creates a new unique key that can be used for inserting a new send channel
// into |send_channels_|
bool CreateSendChannelKey(uint32 local_ssrc, uint32* key);
+ // Get the number of the send channels |capturer| registered with.
+ int GetSendChannelNum(VideoCapturer* capturer);
bool IsDefaultChannel(int channel_id) const {
return channel_id == vie_channel_;
@@ -404,6 +405,13 @@
bool SetLocalRtxSsrc(int channel_id, const StreamParams& send_params,
uint32 primary_ssrc, int stream_idx);
+ // Connect |capturer| to WebRtcVideoMediaChannel if it is only registered
+ // to one send channel, i.e. the first send channel.
+ void MaybeConnectCapturer(VideoCapturer* capturer);
+ // Disconnect |capturer| from WebRtcVideoMediaChannel if it is only registered
+ // to one send channel, i.e. the last send channel.
+ void MaybeDisconnectCapturer(VideoCapturer* capturer);
+
// Global state.
WebRtcVideoEngine* engine_;
VoiceMediaChannel* voice_channel_;
diff --git a/media/webrtc/webrtcvideoengine_unittest.cc b/media/webrtc/webrtcvideoengine_unittest.cc
index 2b83cce..d5886a1 100644
--- a/media/webrtc/webrtcvideoengine_unittest.cc
+++ b/media/webrtc/webrtcvideoengine_unittest.cc
@@ -1216,6 +1216,53 @@
EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id));
}
+TEST_F(WebRtcVideoEngineTestFake, MultipleSendStreamsWithOneCapturer) {
+ EXPECT_TRUE(SetupEngine());
+
+ // Start the capturer
+ cricket::FakeVideoCapturer capturer;
+ cricket::VideoFormat capture_format_vga = cricket::VideoFormat(640, 480,
+ cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
+ EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_vga));
+
+ // Add send streams and connect the capturer
+ for (unsigned int i = 0; i < sizeof(kSsrcs2)/sizeof(kSsrcs2[0]); ++i) {
+ EXPECT_TRUE(channel_->AddSendStream(
+ cricket::StreamParams::CreateLegacy(kSsrcs2[i])));
+ // Register the capturer to the ssrc.
+ EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[i], &capturer));
+ }
+
+ const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs2[0]);
+ ASSERT_NE(-1, channel0);
+ const int channel1 = vie_.GetChannelFromLocalSsrc(kSsrcs2[1]);
+ ASSERT_NE(-1, channel1);
+ ASSERT_NE(channel0, channel1);
+
+ // Set send codec.
+ std::vector<cricket::VideoCodec> codecs;
+ cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
+ codecs.push_back(send_codec);
+ EXPECT_TRUE(channel_->SetSendCodecs(codecs));
+
+ EXPECT_TRUE(capturer.CaptureFrame());
+ EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
+ EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel1));
+
+ EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[0]));
+ EXPECT_TRUE(capturer.CaptureFrame());
+ // channel0 is the default channel, so it won't be deleted.
+ // But it should be disconnected from the capturer.
+ EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
+ EXPECT_EQ(2, vie_.GetIncomingFrameNum(channel1));
+
+ EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[1]));
+ EXPECT_TRUE(capturer.CaptureFrame());
+ EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
+ // channel1 has already been deleted.
+ EXPECT_EQ(-1, vie_.GetIncomingFrameNum(channel1));
+}
+
// Disabled since its flaky: b/11288120
TEST_F(WebRtcVideoEngineTestFake, DISABLED_SendReceiveBitratesStats) {