Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Unified Diff: content/renderer/media/rtc_peer_connection_handler.cc

Issue 10703095: New PeerConnection handler in Chrome to support latest PeerConnection draft (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed code review issues found by Tommi. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/rtc_peer_connection_handler.cc
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ba33ed70bafb986689b829cec3a46e60d355b453
--- /dev/null
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -0,0 +1,392 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/rtc_peer_connection_handler.h"
+
+#include <string>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCICECandidate.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectionHandlerClient.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescription.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescriptionRequest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCVoidRequest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
+
+// Converter functions from libjingle types to WebKit types.
+
+static WebKit::WebRTCPeerConnectionHandlerClient::ICEState
+GetWebKitIceState(webrtc::PeerConnectionInterface::IceState ice_state) {
+ switch (ice_state) {
+ case webrtc::PeerConnectionInterface::kIceNew:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateNew;
+ case webrtc::PeerConnectionInterface::kIceGathering:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateGathering;
+ case webrtc::PeerConnectionInterface::kIceWaiting:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateWaiting;
+ case webrtc::PeerConnectionInterface::kIceChecking:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateChecking;
+ case webrtc::PeerConnectionInterface::kIceConnected:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateConnected;
+ case webrtc::PeerConnectionInterface::kIceCompleted:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateCompleted;
+ case webrtc::PeerConnectionInterface::kIceFailed:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateFailed;
+ case webrtc::PeerConnectionInterface::kIceClosed:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateClosed;
+ default:
+ NOTREACHED();
+ return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateClosed;
+ }
+}
+
+static WebKit::WebRTCPeerConnectionHandlerClient::ReadyState
+GetWebKitReadyState(webrtc::PeerConnectionInterface::ReadyState ready_state) {
+ switch (ready_state) {
+ case webrtc::PeerConnectionInterface::kNew:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateNew;
+ case webrtc::PeerConnectionInterface::kOpening:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateOpening;
+ case webrtc::PeerConnectionInterface::kActive:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateActive;
+ case webrtc::PeerConnectionInterface::kClosing:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosing;
+ case webrtc::PeerConnectionInterface::kClosed:
+ return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed;
+ default:
+ NOTREACHED();
+ return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed;
+ }
+}
+
+static WebKit::WebRTCSessionDescription
+CreateWebKitSessionDescription(
+ const webrtc::SessionDescriptionInterface* native_desc) {
+ WebKit::WebRTCSessionDescription description;
+ if (!native_desc) {
+ LOG(ERROR) << "Native session description is null.";
+ return description;
+ }
+
+ std::string sdp;
+ if (!native_desc->ToString(&sdp)) {
+ LOG(ERROR) << "Failed to get SDP string of native session description.";
+ return description;
+ }
+
+ description.initialize(UTF8ToUTF16(native_desc->type()), UTF8ToUTF16(sdp));
+ return description;
+}
+
+// Converter functions from WebKit types to libjingle types.
+
+static void GetNativeIceServers(
+ const WebKit::WebRTCConfiguration& server_configuration,
+ webrtc::JsepInterface::IceServers* servers) {
+ if (server_configuration.isNull() || !servers)
+ return;
+ for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) {
+ webrtc::JsepInterface::IceServer server;
+ const WebKit::WebRTCICEServer& webkit_server =
+ server_configuration.server(i);
+ server.password = UTF16ToUTF8(webkit_server.credential());
+ server.uri = webkit_server.uri().spec();
+ servers->push_back(server);
+ }
+}
+
+// Class mapping responses from calls to libjingle CreateOffer/Answer and
+// the WebKit::WebRTCSessionDescriptionRequest.
+class CreateSessionDescriptionRequest
+ : public webrtc::CreateSessionDescriptionObserver {
+ public:
+ explicit CreateSessionDescriptionRequest(
+ const WebKit::WebRTCSessionDescriptionRequest& request)
+ : webkit_request_(request) {}
+
+ virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE {
+ webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc));
+ }
+ virtual void OnFailure(const std::string& error) OVERRIDE {
+ webkit_request_.requestFailed(UTF8ToUTF16(error));
+ }
+
+ protected:
+ virtual ~CreateSessionDescriptionRequest() {}
+
+ private:
+ WebKit::WebRTCSessionDescriptionRequest webkit_request_;
+};
+
+// Class mapping responses from calls to libjingle
+// SetLocalDescription/SetRemoteDescription and a WebKit::WebRTCVoidRequest.
+class SetSessionDescriptionRequest
+ : public webrtc::SetSessionDescriptionObserver {
+ public:
+ explicit SetSessionDescriptionRequest(
+ const WebKit::WebRTCVoidRequest& request)
+ : webkit_request_(request) {}
+
+ virtual void OnSuccess() OVERRIDE {
+ webkit_request_.requestSucceeded();
+ }
+ virtual void OnFailure(const std::string& error) OVERRIDE {
+ webkit_request_.requestFailed(UTF8ToUTF16(error));
+ }
+
+ protected:
+ virtual ~SetSessionDescriptionRequest() {}
+
+ private:
+ WebKit::WebRTCVoidRequest webkit_request_;
+};
+
+// TODO(perkj): Implement MediaConstraints when WebKit have done so.
+class RTCMediaConstraints : public webrtc::MediaConstraintsInterface {
+ public:
+ explicit RTCMediaConstraints(
+ const WebKit::WebMediaConstraints& constraints) {
+ }
+ ~RTCMediaConstraints() {}
+};
+
+RTCPeerConnectionHandler::RTCPeerConnectionHandler(
+ WebKit::WebRTCPeerConnectionHandlerClient* client,
+ MediaStreamDependencyFactory* dependency_factory)
+ : PeerConnectionHandlerBase(dependency_factory),
+ client_(client) {
+}
+
+RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
+}
+
+bool RTCPeerConnectionHandler::initialize(
+ const WebKit::WebRTCConfiguration& server_configuration,
+ const WebKit::WebMediaConstraints& options ) {
+ webrtc::JsepInterface::IceServers servers;
+ GetNativeIceServers(server_configuration, &servers);
+
+ RTCMediaConstraints constraints(options);
+ native_peer_connection_ =
+ dependency_factory_->CreatePeerConnection(
+ servers, &constraints, this);
+ if (!native_peer_connection_) {
+ LOG(ERROR) << "Failed to initialize native PeerConnection.";
+ return false;
+ }
+ return true;
+}
+
+void RTCPeerConnectionHandler::createOffer(
+ const WebKit::WebRTCSessionDescriptionRequest& request,
+ const WebKit::WebMediaConstraints& options) {
+ scoped_refptr<CreateSessionDescriptionRequest> description_request(
+ new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
+ request));
+ RTCMediaConstraints constraints(options);
+ native_peer_connection_->CreateOffer(description_request, &constraints);
+}
+
+void RTCPeerConnectionHandler::createAnswer(
+ const WebKit::WebRTCSessionDescriptionRequest& request,
+ const WebKit::WebMediaConstraints& options) {
+ scoped_refptr<CreateSessionDescriptionRequest> description_request(
+ new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
+ request));
+ RTCMediaConstraints constraints(options);
+ native_peer_connection_->CreateAnswer(description_request, &constraints);
+}
+
+void RTCPeerConnectionHandler::setLocalDescription(
+ const WebKit::WebRTCVoidRequest& request,
+ const WebKit::WebRTCSessionDescription& description) {
+ webrtc::SessionDescriptionInterface* native_desc =
+ CreateNativeSessionDescription(description);
+ if (!native_desc) {
+ const char kReason[] = "Failed to parse SessionDescription.";
+ LOG(ERROR) << kReason;
+ WebKit::WebString reason(kReason);
+ request.requestFailed(reason);
+ return;
+ }
+ scoped_refptr<SetSessionDescriptionRequest> set_request(
+ new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
+ native_peer_connection_->SetLocalDescription(set_request, native_desc);
+}
+
+void RTCPeerConnectionHandler::setRemoteDescription(
+ const WebKit::WebRTCVoidRequest& request,
+ const WebKit::WebRTCSessionDescription& description) {
+ webrtc::SessionDescriptionInterface* native_desc =
+ CreateNativeSessionDescription(description);
+ if (!native_desc) {
+ const char kReason[] = "Failed to parse SessionDescription.";
+ LOG(ERROR) << kReason;
+ WebKit::WebString reason(kReason);
+ request.requestFailed(reason);
+ return;
+ }
+ scoped_refptr<SetSessionDescriptionRequest> set_request(
+ new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
+ native_peer_connection_->SetRemoteDescription(set_request, native_desc);
+}
+
+WebKit::WebRTCSessionDescription
+RTCPeerConnectionHandler::localDescription() {
+ const webrtc::SessionDescriptionInterface* native_desc =
+ native_peer_connection_->local_description();
+ WebKit::WebRTCSessionDescription description =
+ CreateWebKitSessionDescription(native_desc);
+ return description;
+}
+
+WebKit::WebRTCSessionDescription
+RTCPeerConnectionHandler::remoteDescription() {
+ const webrtc::SessionDescriptionInterface* native_desc =
+ native_peer_connection_->remote_description();
+ WebKit::WebRTCSessionDescription description =
+ CreateWebKitSessionDescription(native_desc);
+ return description;
+}
+
+bool RTCPeerConnectionHandler::updateICE(
+ const WebKit::WebRTCConfiguration& server_configuration,
+ const WebKit::WebMediaConstraints& options) {
+ webrtc::JsepInterface::IceServers servers;
+ GetNativeIceServers(server_configuration, &servers);
+ RTCMediaConstraints constraints(options);
+ return native_peer_connection_->UpdateIce(servers,
+ &constraints);
+}
+
+bool RTCPeerConnectionHandler::addICECandidate(
+ const WebKit::WebRTCICECandidate& candidate) {
+ scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
+ dependency_factory_->CreateIceCandidate(
+ UTF16ToUTF8(candidate.sdpMid()),
+ candidate.sdpMLineIndex(),
+ UTF16ToUTF8(candidate.candidate())));
+ if (!native_candidate.get()) {
+ LOG(ERROR) << "Could not create native ICE candidate.";
+ return false;
+ }
+
+ bool return_value =
+ native_peer_connection_->AddIceCandidate(native_candidate.get());
+ LOG_IF(ERROR, !return_value) << "Error processing ICE candidate.";
+ return return_value;
+}
+
+bool RTCPeerConnectionHandler::addStream(
+ const WebKit::WebMediaStreamDescriptor& stream,
+ const WebKit::WebMediaConstraints& options) {
+ RTCMediaConstraints constraints(options);
+ return AddStream(stream, &constraints);
+}
+
+void RTCPeerConnectionHandler::removeStream(
+ const WebKit::WebMediaStreamDescriptor& stream) {
+ RemoveStream(stream);
+}
+
+void RTCPeerConnectionHandler::stop() {
+ DVLOG(1) << "RTCPeerConnectionHandler::stop";
+ native_peer_connection_ = NULL;
+}
+
+void RTCPeerConnectionHandler::OnError() {
+ // TODO(perkj): Implement.
+ NOTIMPLEMENTED();
+}
+
+void RTCPeerConnectionHandler::OnStateChange(StateType state_changed) {
+ switch (state_changed) {
+ case kReadyState: {
+ WebKit::WebRTCPeerConnectionHandlerClient::ReadyState ready_state =
+ GetWebKitReadyState(native_peer_connection_->ready_state());
+ client_->didChangeReadyState(ready_state);
+ break;
+ }
+ case kIceState: {
+ WebKit::WebRTCPeerConnectionHandlerClient::ICEState ice_state =
+ GetWebKitIceState(native_peer_connection_->ice_state());
+ client_->didChangeICEState(ice_state);
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void RTCPeerConnectionHandler::OnAddStream(
+ webrtc::MediaStreamInterface* stream) {
+ DCHECK(stream);
+ DCHECK(remote_streams_.find(stream) == remote_streams_.end());
+ WebKit::WebMediaStreamDescriptor descriptor =
+ CreateWebKitStreamDescriptor(stream);
+ remote_streams_.insert(
+ std::pair<webrtc::MediaStreamInterface*,
+ WebKit::WebMediaStreamDescriptor>(stream, descriptor));
+ client_->didAddRemoteStream(descriptor);
+}
+
+void RTCPeerConnectionHandler::OnRemoveStream(
+ webrtc::MediaStreamInterface* stream) {
+ DCHECK(stream);
+ RemoteStreamMap::iterator it = remote_streams_.find(stream);
+ if (it == remote_streams_.end()) {
+ NOTREACHED() << "Stream not found";
+ return;
+ }
+ WebKit::WebMediaStreamDescriptor descriptor = it->second;
+ DCHECK(!descriptor.isNull());
+ remote_streams_.erase(it);
+ client_->didRemoveRemoteStream(descriptor);
+}
+
+void RTCPeerConnectionHandler::OnIceCandidate(
+ const webrtc::IceCandidateInterface* candidate) {
+ DCHECK(candidate);
tommi (sloooow) - chröme 2012/09/13 14:48:45 nit: can skip this since it's dereferenced right a
+ std::string sdp;
+ if (!candidate->ToString(&sdp)) {
+ NOTREACHED() << "OnIceCandidate: Could not get SDP string.";
+ return;
+ }
+ WebKit::WebRTCICECandidate web_candidate;
+ web_candidate.initialize(UTF8ToUTF16(sdp),
+ UTF8ToUTF16(candidate->sdp_mid()),
+ candidate->sdp_mline_index());
+ client_->didGenerateICECandidate(web_candidate);
+}
+
+void RTCPeerConnectionHandler::OnIceComplete() {
+ // Generates a NULL ice candidate object.
+ WebKit::WebRTCICECandidate web_candidate;
+ client_->didGenerateICECandidate(web_candidate);
+}
+
+void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
+ client_->negotiationNeeded();
+}
+
+webrtc::SessionDescriptionInterface*
+RTCPeerConnectionHandler::CreateNativeSessionDescription(
+ const WebKit::WebRTCSessionDescription& description) {
+ std::string sdp = UTF16ToUTF8(description.sdp());
+ std::string type = UTF16ToUTF8(description.type());
+ webrtc::SessionDescriptionInterface* native_desc =
+ dependency_factory_->CreateSessionDescription(type, sdp);
+
+ LOG_IF(ERROR, !native_desc) << "Failed to create native session description."
+ << " Type: " << type << " SDP: " << sdp;
+
+ return native_desc;
+}
« no previous file with comments | « content/renderer/media/rtc_peer_connection_handler.h ('k') | content/renderer/media/rtc_peer_connection_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698