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

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: Fixed broken unittes. 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..0fe07d96061721230786597a511cfbcfdcc69994
--- /dev/null
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -0,0 +1,407 @@
+// 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;
+ }
+ NOTREACHED();
tommi (sloooow) - chröme 2012/09/13 12:20:14 nit: you can remove this since you have a default
perkj_chrome 2012/09/13 13:41:34 Done.
+}
+
+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;
+ }
+ NOTREACHED();
+}
+
+static WebKit::WebRTCSessionDescription
+ CreateWebKitSessionDescription(
tommi (sloooow) - chröme 2012/09/13 12:20:14 shouldn't this have zero indent like in other plac
perkj_chrome 2012/09/13 13:41:34 Done.
+ 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*/) {
tommi (sloooow) - chröme 2012/09/13 12:20:14 remove /* */
perkj_chrome 2012/09/13 13:41:34 Done.
+ }
+ ~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) {
+ talk_base::scoped_refptr<CreateSessionDescriptionRequest> description_request(
+ new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
+ request));
+ RTCMediaConstraints constraints(options);
+ native_peer_connection_->CreateOffer(
+ description_request.get(), &constraints);
+}
+
+void RTCPeerConnectionHandler::createAnswer(
+ const WebKit::WebRTCSessionDescriptionRequest& request,
+ const WebKit::WebMediaConstraints& options) {
+ talk_base::scoped_refptr<CreateSessionDescriptionRequest> description_request(
+ new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
+ request));
+ RTCMediaConstraints constraints(options);
+ native_peer_connection_->CreateAnswer(description_request.get(),
+ &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;
+ }
+ talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request(
+ new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
+ native_peer_connection_->SetLocalDescription(set_request.get(), 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;
+ }
+ talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request(
tommi (sloooow) - chröme 2012/09/13 12:20:14 can you use Chrome's scoped_refptr instead? (same
perkj_chrome 2012/09/13 13:41:34 Done.
+ new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
+ native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc);
tommi (sloooow) - chröme 2012/09/13 12:20:14 ...and then you don't need the .get() calls
perkj_chrome 2012/09/13 13:41:34 Done.
+}
+
+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());
+ if (!return_value)
+ LOG(ERROR) << "Error processing ICE candidate.";
tommi (sloooow) - chröme 2012/09/13 12:20:14 use LOG_IF
perkj_chrome 2012/09/13 13:41:34 Done.
+ 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) {
+ if (!stream) {
+ LOG(ERROR) << "OnAddStream: stream is null";
tommi (sloooow) - chröme 2012/09/13 12:20:14 should there just be a DCHECK at the top of the fu
perkj_chrome 2012/09/13 13:41:34 Done.
+ return;
+ }
+
+ 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) {
+ if (!stream) {
+ LOG(ERROR) << "OnRemoveStream: stream is null";
tommi (sloooow) - chröme 2012/09/13 12:20:14 DCHECK? same for similar cases throughout
perkj_chrome 2012/09/13 13:41:34 Done.
+ return;
+ }
+
+ 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) {
+ std::string sdp;
+ if (!candidate->ToString(&sdp)) {
+ LOG(ERROR) << "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);
+ if (!native_desc) {
tommi (sloooow) - chröme 2012/09/13 12:20:14 remove this if+return and just do this instead: L
perkj_chrome 2012/09/13 13:41:34 Done.
+ LOG(ERROR) << "Failed to create native session description. Type: "
+ << type << " SDP: " << sdp;
+ return NULL;
+ }
+
+ return native_desc;
+}

Powered by Google App Engine
This is Rietveld 408576698