diff options
Diffstat (limited to 'chromium/content/renderer/media/rtc_peer_connection_handler.cc')
-rw-r--r-- | chromium/content/renderer/media/rtc_peer_connection_handler.cc | 229 |
1 files changed, 181 insertions, 48 deletions
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler.cc b/chromium/content/renderer/media/rtc_peer_connection_handler.cc index 1536ec30188..b8c39be0ce6 100644 --- a/chromium/content/renderer/media/rtc_peer_connection_handler.cc +++ b/chromium/content/renderer/media/rtc_peer_connection_handler.cc @@ -9,34 +9,35 @@ #include <vector> #include "base/command_line.h" +#include "base/debug/trace_event.h" +#include "base/lazy_instance.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/metrics/histogram.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "content/public/common/content_switches.h" -#include "content/renderer/media/media_stream_dependency_factory.h" +#include "content/renderer/media/media_stream_track.h" #include "content/renderer/media/peer_connection_tracker.h" #include "content/renderer/media/remote_media_stream_impl.h" #include "content/renderer/media/rtc_data_channel_handler.h" #include "content/renderer/media/rtc_dtmf_sender_handler.h" #include "content/renderer/media/rtc_media_constraints.h" +#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h" #include "content/renderer/media/webrtc_audio_capturer.h" #include "content/renderer/media/webrtc_audio_device_impl.h" +#include "content/renderer/media/webrtc_uma_histograms.h" #include "content/renderer/render_thread_impl.h" #include "third_party/WebKit/public/platform/WebMediaConstraints.h" -// TODO(hta): Move the following include to WebRTCStatsRequest.h file. #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" -#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" #include "third_party/WebKit/public/platform/WebRTCConfiguration.h" #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h" #include "third_party/WebKit/public/platform/WebRTCICECandidate.h" -#include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h" #include "third_party/WebKit/public/platform/WebRTCSessionDescription.h" #include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h" -#include "third_party/WebKit/public/platform/WebRTCStatsRequest.h" #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h" #include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/web/WebFrame.h" namespace content { @@ -121,7 +122,8 @@ CreateWebKitSessionDescription( return description; } - description.initialize(UTF8ToUTF16(native_desc->type()), UTF8ToUTF16(sdp)); + description.initialize(base::UTF8ToUTF16(native_desc->type()), + base::UTF8ToUTF16(sdp)); return description; } @@ -136,8 +138,8 @@ static void GetNativeIceServers( webrtc::PeerConnectionInterface::IceServer server; const blink::WebRTCICEServer& webkit_server = server_configuration.server(i); - server.username = UTF16ToUTF8(webkit_server.username()); - server.password = UTF16ToUTF8(webkit_server.credential()); + server.username = base::UTF16ToUTF8(webkit_server.username()); + server.password = base::UTF16ToUTF8(webkit_server.credential()); server.uri = webkit_server.uri().spec(); servers->push_back(server); } @@ -185,10 +187,11 @@ class CreateSessionDescriptionRequest virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE { tracker_.TrackOnSuccess(desc); webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc)); + delete desc; } virtual void OnFailure(const std::string& error) OVERRIDE { tracker_.TrackOnFailure(error); - webkit_request_.requestFailed(UTF8ToUTF16(error)); + webkit_request_.requestFailed(base::UTF8ToUTF16(error)); } protected: @@ -216,7 +219,7 @@ class SetSessionDescriptionRequest } virtual void OnFailure(const std::string& error) OVERRIDE { tracker_.TrackOnFailure(error); - webkit_request_.requestFailed(UTF8ToUTF16(error)); + webkit_request_.requestFailed(base::UTF8ToUTF16(error)); } protected: @@ -232,16 +235,26 @@ class SetSessionDescriptionRequest class StatsResponse : public webrtc::StatsObserver { public: explicit StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request) - : request_(request.get()), response_(request_->createResponse().get()) {} + : request_(request.get()), response_(request_->createResponse().get()) { + // Measure the overall time it takes to satisfy a getStats request. + TRACE_EVENT_ASYNC_BEGIN0("webrtc", "getStats_Native", this); + } virtual void OnComplete( const std::vector<webrtc::StatsReport>& reports) OVERRIDE { + TRACE_EVENT0("webrtc", "StatsResponse::OnComplete") for (std::vector<webrtc::StatsReport>::const_iterator it = reports.begin(); it != reports.end(); ++it) { if (it->values.size() > 0) { AddReport(*it); } } + + // Record the getSync operation as done before calling into Blink so that + // we don't skew the perf measurements of the native code with whatever the + // callback might be doing. + TRACE_EVENT_ASYNC_END0("webrtc", "getStats_Native", this); + request_->requestSucceeded(response_); } @@ -314,19 +327,78 @@ void LocalRTCStatsResponse::addStatistic(size_t report, impl_.addStatistic(report, name, value); } +namespace { + +class PeerConnectionUMAObserver : public webrtc::UMAObserver { + public: + PeerConnectionUMAObserver() {} + virtual ~PeerConnectionUMAObserver() {} + + virtual void IncrementCounter( + webrtc::PeerConnectionUMAMetricsCounter counter) OVERRIDE { + UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", + counter, + webrtc::kBoundary); + } + + virtual void AddHistogramSample( + webrtc::PeerConnectionUMAMetricsName type, int value) OVERRIDE { + switch (type) { + case webrtc::kTimeToConnect: + UMA_HISTOGRAM_MEDIUM_TIMES( + "WebRTC.PeerConnection.TimeToConnect", + base::TimeDelta::FromMilliseconds(value)); + break; + case webrtc::kNetworkInterfaces_IPv4: + UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4Interfaces", + value); + break; + case webrtc::kNetworkInterfaces_IPv6: + UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv6Interfaces", + value); + break; + default: + NOTREACHED(); + } + } +}; + +base::LazyInstance<std::set<RTCPeerConnectionHandler*> >::Leaky + g_peer_connection_handlers = LAZY_INSTANCE_INITIALIZER; + +} // namespace + RTCPeerConnectionHandler::RTCPeerConnectionHandler( blink::WebRTCPeerConnectionHandlerClient* client, - MediaStreamDependencyFactory* dependency_factory) - : PeerConnectionHandlerBase(dependency_factory), - client_(client), + PeerConnectionDependencyFactory* dependency_factory) + : client_(client), + dependency_factory_(dependency_factory), frame_(NULL), - peer_connection_tracker_(NULL) { + peer_connection_tracker_(NULL), + num_data_channels_created_(0) { + g_peer_connection_handlers.Get().insert(this); } RTCPeerConnectionHandler::~RTCPeerConnectionHandler() { + g_peer_connection_handlers.Get().erase(this); if (peer_connection_tracker_) peer_connection_tracker_->UnregisterPeerConnection(this); STLDeleteValues(&remote_streams_); + + UMA_HISTOGRAM_COUNTS_10000( + "WebRTC.NumDataChannelsPerPeerConnection", num_data_channels_created_); +} + +// static +void RTCPeerConnectionHandler::DestructAllHandlers() { + std::set<RTCPeerConnectionHandler*> handlers( + g_peer_connection_handlers.Get().begin(), + g_peer_connection_handlers.Get().end()); + for (std::set<RTCPeerConnectionHandler*>::iterator handler = handlers.begin(); + handler != handlers.end(); + ++handler) { + (*handler)->client_->releasePeerConnectionHandler(); + } } void RTCPeerConnectionHandler::associateWithFrame(blink::WebFrame* frame) { @@ -358,6 +430,8 @@ bool RTCPeerConnectionHandler::initialize( peer_connection_tracker_->RegisterPeerConnection( this, servers, constraints, frame_); + uma_observer_ = new talk_base::RefCountedObject<PeerConnectionUMAObserver>(); + native_peer_connection_->RegisterUMAObserver(uma_observer_.get()); return true; } @@ -507,9 +581,9 @@ bool RTCPeerConnectionHandler::addICECandidate( const blink::WebRTCICECandidate& candidate) { scoped_ptr<webrtc::IceCandidateInterface> native_candidate( dependency_factory_->CreateIceCandidate( - UTF16ToUTF8(candidate.sdpMid()), + base::UTF16ToUTF8(candidate.sdpMid()), candidate.sdpMLineIndex(), - UTF16ToUTF8(candidate.candidate()))); + base::UTF16ToUTF8(candidate.candidate()))); if (!native_candidate) { LOG(ERROR) << "Could not create native ICE candidate."; return false; @@ -532,7 +606,7 @@ void RTCPeerConnectionHandler::OnaddICECandidateResult( // We don't have the actual error code from the libjingle, so for now // using a generic error string. return webkit_request.requestFailed( - UTF8ToUTF16("Error processing ICE candidate")); + base::UTF8ToUTF16("Error processing ICE candidate")); } return webkit_request.requestSucceeded(); @@ -541,31 +615,57 @@ void RTCPeerConnectionHandler::OnaddICECandidateResult( bool RTCPeerConnectionHandler::addStream( const blink::WebMediaStream& stream, const blink::WebMediaConstraints& options) { - RTCMediaConstraints constraints(options); + + for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it = + local_streams_.begin(); adapter_it != local_streams_.end(); + ++adapter_it) { + if ((*adapter_it)->IsEqual(stream)) { + DVLOG(1) << "RTCPeerConnectionHandler::addStream called with the same " + << "stream twice. id=" << stream.id().utf8(); + return false; + } + } if (peer_connection_tracker_) peer_connection_tracker_->TrackAddStream( this, stream, PeerConnectionTracker::SOURCE_LOCAL); - // A media stream is connected to a peer connection, enable the - // peer connection mode for the capturer. - WebRtcAudioDeviceImpl* audio_device = - dependency_factory_->GetWebRtcAudioDevice(); - if (audio_device) { - WebRtcAudioCapturer* capturer = audio_device->GetDefaultCapturer(); - if (capturer) - capturer->EnablePeerConnectionMode(); - } + PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter(); + + WebRtcMediaStreamAdapter* adapter = + new WebRtcMediaStreamAdapter(stream, dependency_factory_); + local_streams_.push_back(adapter); - return AddStream(stream, &constraints); + webrtc::MediaStreamInterface* webrtc_stream = adapter->webrtc_media_stream(); + track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM, + webrtc_stream); + + RTCMediaConstraints constraints(options); + return native_peer_connection_->AddStream(webrtc_stream, &constraints); } void RTCPeerConnectionHandler::removeStream( const blink::WebMediaStream& stream) { - RemoveStream(stream); + // Find the webrtc stream. + scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream; + for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it = + local_streams_.begin(); adapter_it != local_streams_.end(); + ++adapter_it) { + if ((*adapter_it)->IsEqual(stream)) { + webrtc_stream = (*adapter_it)->webrtc_media_stream(); + local_streams_.erase(adapter_it); + break; + } + } + DCHECK(webrtc_stream); + native_peer_connection_->RemoveStream(webrtc_stream); + if (peer_connection_tracker_) peer_connection_tracker_->TrackRemoveStream( this, stream, PeerConnectionTracker::SOURCE_LOCAL); + PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter(); + track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, + webrtc_stream); } void RTCPeerConnectionHandler::getStats( @@ -580,8 +680,25 @@ void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) { new talk_base::RefCountedObject<StatsResponse>(request)); webrtc::MediaStreamTrackInterface* track = NULL; if (request->hasSelector()) { - track = MediaStreamDependencyFactory::GetNativeMediaStreamTrack( - request->component()); + blink::WebMediaStreamSource::Type type = + request->component().source().type(); + std::string track_id = request->component().id().utf8(); + if (type == blink::WebMediaStreamSource::TypeAudio) { + track = + native_peer_connection_->local_streams()->FindAudioTrack(track_id); + if (!track) { + track = + native_peer_connection_->remote_streams()->FindAudioTrack(track_id); + } + } else { + DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, type); + track = + native_peer_connection_->local_streams()->FindVideoTrack(track_id); + if (!track) { + track = + native_peer_connection_->remote_streams()->FindVideoTrack(track_id); + } + } if (!track) { DVLOG(1) << "GetStats: Track not found."; // TODO(hta): Consider how to get an error back. @@ -590,13 +707,17 @@ void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) { return; } } - GetStats(observer, track); + GetStats(observer, + track, + webrtc::PeerConnectionInterface::kStatsOutputLevelStandard); } void RTCPeerConnectionHandler::GetStats( webrtc::StatsObserver* observer, - webrtc::MediaStreamTrackInterface* track) { - if (!native_peer_connection_->GetStats(observer, track)) { + webrtc::MediaStreamTrackInterface* track, + webrtc::PeerConnectionInterface::StatsOutputLevel level) { + TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::GetStats"); + if (!native_peer_connection_->GetStats(observer, track, level)) { DVLOG(1) << "GetStats failed."; // TODO(hta): Consider how to get an error back. std::vector<webrtc::StatsReport> no_reports; @@ -607,7 +728,7 @@ void RTCPeerConnectionHandler::GetStats( blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel( const blink::WebString& label, const blink::WebRTCDataChannelInit& init) { - DVLOG(1) << "createDataChannel label " << UTF16ToUTF8(label); + DVLOG(1) << "createDataChannel label " << base::UTF16ToUTF8(label); webrtc::DataChannelInit config; // TODO(jiayl): remove the deprecated reliable field once Libjingle is updated @@ -618,10 +739,11 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel( config.negotiated = init.negotiated; config.maxRetransmits = init.maxRetransmits; config.maxRetransmitTime = init.maxRetransmitTime; - config.protocol = UTF16ToUTF8(init.protocol); + config.protocol = base::UTF16ToUTF8(init.protocol); talk_base::scoped_refptr<webrtc::DataChannelInterface> webrtc_channel( - native_peer_connection_->CreateDataChannel(UTF16ToUTF8(label), &config)); + native_peer_connection_->CreateDataChannel(base::UTF16ToUTF8(label), + &config)); if (!webrtc_channel) { DLOG(ERROR) << "Could not create native data channel."; return NULL; @@ -630,6 +752,8 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel( peer_connection_tracker_->TrackCreateDataChannel( this, webrtc_channel.get(), PeerConnectionTracker::SOURCE_LOCAL); + ++num_data_channels_created_; + return new RtcDataChannelHandler(webrtc_channel); } @@ -637,15 +761,14 @@ blink::WebRTCDTMFSenderHandler* RTCPeerConnectionHandler::createDTMFSender( const blink::WebMediaStreamTrack& track) { DVLOG(1) << "createDTMFSender."; - if (track.source().type() != blink::WebMediaStreamSource::TypeAudio) { + MediaStreamTrack* native_track = MediaStreamTrack::GetTrack(track); + if (!native_track || + track.source().type() != blink::WebMediaStreamSource::TypeAudio) { DLOG(ERROR) << "Could not create DTMF sender from a non-audio track."; return NULL; } - webrtc::AudioTrackInterface* audio_track = - static_cast<webrtc::AudioTrackInterface*>( - MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track)); - + webrtc::AudioTrackInterface* audio_track = native_track->GetAudioAdapter(); talk_base::scoped_refptr<webrtc::DtmfSenderInterface> sender( native_peer_connection_->CreateDtmfSender(audio_track)); if (!sender) { @@ -683,6 +806,7 @@ void RTCPeerConnectionHandler::OnSignalingChange( // Called any time the IceConnectionState changes void RTCPeerConnectionHandler::OnIceConnectionChange( webrtc::PeerConnectionInterface::IceConnectionState new_state) { + track_metrics_.IceConnectionChange(new_state); blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState state = GetWebKitIceConnectionState(new_state); if (peer_connection_tracker_) @@ -723,6 +847,11 @@ void RTCPeerConnectionHandler::OnAddStream( this, remote_stream->webkit_stream(), PeerConnectionTracker::SOURCE_REMOTE); + PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter(); + + track_metrics_.AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, + stream_interface); + client_->didAddRemoteStream(remote_stream->webkit_stream()); } @@ -735,6 +864,10 @@ void RTCPeerConnectionHandler::OnRemoveStream( return; } + track_metrics_.RemoveStream(MediaStreamTrackMetrics::RECEIVED_STREAM, + stream_interface); + PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter(); + scoped_ptr<RemoteMediaStreamImpl> remote_stream(it->second); const blink::WebMediaStream& webkit_stream = remote_stream->webkit_stream(); DCHECK(!webkit_stream.isNull()); @@ -756,8 +889,8 @@ void RTCPeerConnectionHandler::OnIceCandidate( return; } blink::WebRTCICECandidate web_candidate; - web_candidate.initialize(UTF8ToUTF16(sdp), - UTF8ToUTF16(candidate->sdp_mid()), + web_candidate.initialize(base::UTF8ToUTF16(sdp), + base::UTF8ToUTF16(candidate->sdp_mid()), candidate->sdp_mline_index()); if (peer_connection_tracker_) peer_connection_tracker_->TrackAddIceCandidate( @@ -791,8 +924,8 @@ webrtc::SessionDescriptionInterface* RTCPeerConnectionHandler::CreateNativeSessionDescription( const blink::WebRTCSessionDescription& description, webrtc::SdpParseError* error) { - std::string sdp = UTF16ToUTF8(description.sdp()); - std::string type = UTF16ToUTF8(description.type()); + std::string sdp = base::UTF16ToUTF8(description.sdp()); + std::string type = base::UTF16ToUTF8(description.type()); webrtc::SessionDescriptionInterface* native_desc = dependency_factory_->CreateSessionDescription(type, sdp, error); |