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

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

Issue 680393003: Make setRemoteDescription, setLocalDescription et al async. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 6 years, 1 month 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
index 844e250113fe187285b26de5eeddfe1670e00b24..5d2481320878759165dffb0a964093ecd439e5d1 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -50,6 +50,7 @@ using webrtc::StatsReportCopyable;
using webrtc::StatsReports;
namespace content {
+namespace {
// Converter functions from libjingle types to WebKit types.
blink::WebRTCPeerConnectionHandlerClient::ICEGatheringState
@@ -69,7 +70,7 @@ GetWebKitIceGatheringState(
}
}
-static blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState
+blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState
GetWebKitIceConnectionState(
webrtc::PeerConnectionInterface::IceConnectionState ice_state) {
using blink::WebRTCPeerConnectionHandlerClient;
@@ -94,7 +95,7 @@ GetWebKitIceConnectionState(
}
}
-static blink::WebRTCPeerConnectionHandlerClient::SignalingState
+blink::WebRTCPeerConnectionHandlerClient::SignalingState
GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state) {
using blink::WebRTCPeerConnectionHandlerClient;
switch (state) {
@@ -117,29 +118,61 @@ GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state) {
}
}
-static blink::WebRTCSessionDescription
+blink::WebRTCSessionDescription CreateWebKitSessionDescription(
+ const std::string& sdp, const std::string& type) {
+ blink::WebRTCSessionDescription description;
+ description.initialize(base::UTF8ToUTF16(type), base::UTF8ToUTF16(sdp));
+ return description;
+}
+
+blink::WebRTCSessionDescription
CreateWebKitSessionDescription(
const webrtc::SessionDescriptionInterface* native_desc) {
- blink::WebRTCSessionDescription description;
if (!native_desc) {
LOG(ERROR) << "Native session description is null.";
- return description;
+ return blink::WebRTCSessionDescription();
}
std::string sdp;
if (!native_desc->ToString(&sdp)) {
LOG(ERROR) << "Failed to get SDP string of native session description.";
- return description;
+ return blink::WebRTCSessionDescription();
}
- description.initialize(base::UTF8ToUTF16(native_desc->type()),
- base::UTF8ToUTF16(sdp));
- return description;
+ return CreateWebKitSessionDescription(sdp, native_desc->type());
+}
+
+void RunClosureWithTrace(const base::Closure& closure,
+ const char* trace_event_name) {
+ TRACE_EVENT0("webrtc", trace_event_name);
+ closure.Run();
+}
+
+void RunSynchronousClosure(const base::Closure& closure,
+ const char* trace_event_name,
+ base::WaitableEvent* event) {
+ {
+ TRACE_EVENT0("webrtc", trace_event_name);
+ closure.Run();
+ }
+ event->Signal();
+}
+
+void GetSdpAndTypeFromSessionDescription(
+ const base::Callback<const webrtc::SessionDescriptionInterface*()>&
+ description_callback,
+ std::string* sdp, std::string* type) {
+ const webrtc::SessionDescriptionInterface* description =
+ description_callback.Run();
+ if (description) {
+ description->ToString(sdp);
+ *type = description->type();
+ }
}
// Converter functions from WebKit types to libjingle types.
-static void GetNativeRtcConfiguration(
+void GetNativeRtcConfiguration(
const blink::WebRTCConfiguration& server_configuration,
webrtc::PeerConnectionInterface::RTCConfiguration* config) {
if (server_configuration.isNull() || !config)
@@ -310,7 +343,7 @@ class StatsResponse : public webrtc::StatsObserver {
void OnComplete(const StatsReports& reports) override {
DCHECK(signaling_thread_checker_.CalledOnValidThread());
TRACE_EVENT0("webrtc", "StatsResponse::OnComplete");
- // TODO(tommi): Get rid of these string copies some how.
+ // TODO(tommi): Get rid of these string copies somehow.
// We can't use webkit objects directly since they use a single threaded
// heap allocator.
scoped_ptr<std::vector<StatsReportCopyable>> report_copies(
@@ -359,51 +392,6 @@ class StatsResponse : public webrtc::StatsObserver {
base::ThreadChecker signaling_thread_checker_;
};
-// Implementation of LocalRTCStatsRequest.
-LocalRTCStatsRequest::LocalRTCStatsRequest(blink::WebRTCStatsRequest impl)
- : impl_(impl) {
-}
-
-LocalRTCStatsRequest::LocalRTCStatsRequest() {}
-LocalRTCStatsRequest::~LocalRTCStatsRequest() {}
-
-bool LocalRTCStatsRequest::hasSelector() const {
- return impl_.hasSelector();
-}
-
-blink::WebMediaStreamTrack LocalRTCStatsRequest::component() const {
- return impl_.component();
-}
-
-scoped_refptr<LocalRTCStatsResponse> LocalRTCStatsRequest::createResponse() {
- return scoped_refptr<LocalRTCStatsResponse>(
- new rtc::RefCountedObject<LocalRTCStatsResponse>(impl_.createResponse()));
-}
-
-void LocalRTCStatsRequest::requestSucceeded(
- const LocalRTCStatsResponse* response) {
- impl_.requestSucceeded(response->webKitStatsResponse());
-}
-
-// Implementation of LocalRTCStatsResponse.
-blink::WebRTCStatsResponse LocalRTCStatsResponse::webKitStatsResponse() const {
- return impl_;
-}
-
-size_t LocalRTCStatsResponse::addReport(blink::WebString type,
- blink::WebString id,
- double timestamp) {
- return impl_.addReport(type, id, timestamp);
-}
-
-void LocalRTCStatsResponse::addStatistic(size_t report,
- blink::WebString name,
- blink::WebString value) {
- impl_.addStatistic(report, name, value);
-}
-
-namespace {
-
void GetStatsOnSignalingThread(
const scoped_refptr<webrtc::PeerConnectionInterface>& pc,
webrtc::PeerConnectionInterface::StatsOutputLevel level,
@@ -478,6 +466,49 @@ base::LazyInstance<std::set<RTCPeerConnectionHandler*> >::Leaky
} // namespace
+// Implementation of LocalRTCStatsRequest.
+LocalRTCStatsRequest::LocalRTCStatsRequest(blink::WebRTCStatsRequest impl)
+ : impl_(impl) {
+}
+
+LocalRTCStatsRequest::LocalRTCStatsRequest() {}
+LocalRTCStatsRequest::~LocalRTCStatsRequest() {}
+
+bool LocalRTCStatsRequest::hasSelector() const {
+ return impl_.hasSelector();
+}
+
+blink::WebMediaStreamTrack LocalRTCStatsRequest::component() const {
+ return impl_.component();
+}
+
+scoped_refptr<LocalRTCStatsResponse> LocalRTCStatsRequest::createResponse() {
+ return scoped_refptr<LocalRTCStatsResponse>(
+ new rtc::RefCountedObject<LocalRTCStatsResponse>(impl_.createResponse()));
+}
+
+void LocalRTCStatsRequest::requestSucceeded(
+ const LocalRTCStatsResponse* response) {
+ impl_.requestSucceeded(response->webKitStatsResponse());
+}
+
+// Implementation of LocalRTCStatsResponse.
+blink::WebRTCStatsResponse LocalRTCStatsResponse::webKitStatsResponse() const {
+ return impl_;
+}
+
+size_t LocalRTCStatsResponse::addReport(blink::WebString type,
+ blink::WebString id,
+ double timestamp) {
+ return impl_.addReport(type, id, timestamp);
+}
+
+void LocalRTCStatsResponse::addStatistic(size_t report,
+ blink::WebString name,
+ blink::WebString value) {
+ impl_.addStatistic(report, name, value);
+}
+
// Receives notifications from a PeerConnection object about state changes,
// track addition/removal etc. The callbacks we receive here come on the
// signaling thread, so this class takes care of delivering them to an
@@ -617,12 +648,10 @@ class RTCPeerConnectionHandler::Observer
RTCPeerConnectionHandler::RTCPeerConnectionHandler(
blink::WebRTCPeerConnectionHandlerClient* client,
- PeerConnectionDependencyFactory* dependency_factory,
- const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread)
+ PeerConnectionDependencyFactory* dependency_factory)
: client_(client),
dependency_factory_(dependency_factory),
frame_(NULL),
- signaling_thread_(signaling_thread),
num_data_channels_created_(0),
num_local_candidates_ipv4_(0),
num_local_candidates_ipv6_(0),
@@ -750,6 +779,7 @@ void RTCPeerConnectionHandler::createOffer(
weak_factory_.GetWeakPtr(), peer_connection_tracker_,
PeerConnectionTracker::ACTION_CREATE_OFFER));
+ // TODO(tommi): Do this asynchronously via e.g. PostTaskAndReply.
RTCMediaConstraints constraints(options);
native_peer_connection_->CreateOffer(description_request.get(), &constraints);
@@ -769,6 +799,7 @@ void RTCPeerConnectionHandler::createOffer(
weak_factory_.GetWeakPtr(), peer_connection_tracker_,
PeerConnectionTracker::ACTION_CREATE_OFFER));
+ // TODO(tommi): Do this asynchronously via e.g. PostTaskAndReply.
RTCMediaConstraints constraints;
ConvertOfferOptionsToConstraints(options, &constraints);
native_peer_connection_->CreateOffer(description_request.get(), &constraints);
@@ -787,6 +818,7 @@ void RTCPeerConnectionHandler::createAnswer(
base::ThreadTaskRunnerHandle::Get(), request,
weak_factory_.GetWeakPtr(), peer_connection_tracker_,
PeerConnectionTracker::ACTION_CREATE_ANSWER));
+ // TODO(tommi): Do this asynchronously via e.g. PostTaskAndReply.
RTCMediaConstraints constraints(options);
native_peer_connection_->CreateAnswer(description_request.get(),
&constraints);
@@ -830,8 +862,12 @@ void RTCPeerConnectionHandler::setLocalDescription(
weak_factory_.GetWeakPtr(), peer_connection_tracker_,
PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
- // TODO(tommi): Run this on the signaling thread.
- native_peer_connection_->SetLocalDescription(set_request.get(), native_desc);
+ signaling_thread()->PostTask(FROM_HERE,
+ base::Bind(&RunClosureWithTrace,
+ base::Bind(&webrtc::PeerConnectionInterface::SetLocalDescription,
+ native_peer_connection_, set_request,
+ base::Unretained(native_desc)),
+ "SetLocalDescription"));
}
void RTCPeerConnectionHandler::setRemoteDescription(
@@ -867,30 +903,53 @@ void RTCPeerConnectionHandler::setRemoteDescription(
base::ThreadTaskRunnerHandle::Get(), request,
weak_factory_.GetWeakPtr(), peer_connection_tracker_,
PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION));
- // TODO(tommi): Run this on the signaling thread.
- native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc);
+ signaling_thread()->PostTask(FROM_HERE,
+ base::Bind(&RunClosureWithTrace,
+ base::Bind(&webrtc::PeerConnectionInterface::SetRemoteDescription,
+ native_peer_connection_, set_request,
+ base::Unretained(native_desc)),
+ "SetRemoteDescription"));
}
blink::WebRTCSessionDescription
RTCPeerConnectionHandler::localDescription() {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::localDescription");
- const webrtc::SessionDescriptionInterface* native_desc =
- native_peer_connection_->local_description();
- blink::WebRTCSessionDescription description =
- CreateWebKitSessionDescription(native_desc);
- return description;
+
+ // Since local_description returns a pointer to a non-reference-counted object
+ // that lives on the signaling thread, we cannot fetch a pointer to it and use
+ // it directly here. Instead, we access the object completely on the signaling
+ // thread.
+ std::string sdp, type;
+ base::Callback<const webrtc::SessionDescriptionInterface*()> description_cb =
+ base::Bind(&webrtc::PeerConnectionInterface::local_description,
+ native_peer_connection_);
+ RunSynchronousClosureOnSignalingThread(
+ base::Bind(&GetSdpAndTypeFromSessionDescription, description_cb,
+ base::Unretained(&sdp), base::Unretained(&type)),
+ "localDescription");
+
+ return CreateWebKitSessionDescription(sdp, type);
}
blink::WebRTCSessionDescription
RTCPeerConnectionHandler::remoteDescription() {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::remoteDescription");
- const webrtc::SessionDescriptionInterface* native_desc =
- native_peer_connection_->remote_description();
- blink::WebRTCSessionDescription description =
- CreateWebKitSessionDescription(native_desc);
- return description;
+ // Since local_description returns a pointer to a non-reference-counted object
+ // that lives on the signaling thread, we cannot fetch a pointer to it and use
+ // it directly here. Instead, we access the object completely on the signaling
+ // thread.
+ std::string sdp, type;
+ base::Callback<const webrtc::SessionDescriptionInterface*()> description_cb =
+ base::Bind(&webrtc::PeerConnectionInterface::remote_description,
+ native_peer_connection_);
+ RunSynchronousClosureOnSignalingThread(
+ base::Bind(&GetSdpAndTypeFromSessionDescription, description_cb,
+ base::Unretained(&sdp), base::Unretained(&type)),
+ "remoteDescription");
+
+ return CreateWebKitSessionDescription(sdp, type);
}
bool RTCPeerConnectionHandler::updateICE(
@@ -915,6 +974,9 @@ bool RTCPeerConnectionHandler::addICECandidate(
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
// Libjingle currently does not accept callbacks for addICECandidate.
// For that reason we are going to call callbacks from here.
+
+ // TODO(tommi): Instead of calling addICECandidate here, we can do a
+ // PostTaskAndReply kind of a thing.
bool result = addICECandidate(candidate);
base::MessageLoop::current()->PostTask(
FROM_HERE,
@@ -1014,6 +1076,7 @@ void RTCPeerConnectionHandler::removeStream(
}
}
DCHECK(webrtc_stream.get());
+ // TODO(tommi): Make this async (PostTaskAndReply).
native_peer_connection_->RemoveStream(webrtc_stream.get());
if (peer_connection_tracker_) {
@@ -1061,7 +1124,7 @@ void RTCPeerConnectionHandler::GetStats(
const std::string& track_id,
blink::WebMediaStreamSource::Type track_type) {
DCHECK(thread_checker_.CalledOnValidThread());
- signaling_thread_->PostTask(FROM_HERE,
+ signaling_thread()->PostTask(FROM_HERE,
base::Bind(&GetStatsOnSignalingThread, native_peer_connection_, level,
make_scoped_refptr(observer), track_id, track_type));
}
@@ -1120,9 +1183,10 @@ blink::WebRTCDTMFSenderHandler* RTCPeerConnectionHandler::createDTMFSender(
return nullptr;
}
- webrtc::AudioTrackInterface* audio_track = native_track->GetAudioAdapter();
+ scoped_refptr<webrtc::AudioTrackInterface> audio_track =
+ native_track->GetAudioAdapter();
rtc::scoped_refptr<webrtc::DtmfSenderInterface> sender(
- native_peer_connection_->CreateDtmfSender(audio_track));
+ native_peer_connection_->CreateDtmfSender(audio_track.get()));
if (!sender) {
DLOG(ERROR) << "Could not create native DTMF sender.";
return nullptr;
@@ -1137,9 +1201,14 @@ void RTCPeerConnectionHandler::stop() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "RTCPeerConnectionHandler::stop";
+ if (!client_)
+ return; // Already stopped.
+
if (peer_connection_tracker_)
peer_connection_tracker_->TrackStop(this);
+
native_peer_connection_->Close();
+
// The client_ pointer is not considered valid after this point and no further
// callbacks must be made.
client_ = nullptr;
@@ -1339,4 +1408,28 @@ RTCPeerConnectionHandler::CreateNativeSessionDescription(
return native_desc;
}
+scoped_refptr<base::SingleThreadTaskRunner>
+RTCPeerConnectionHandler::signaling_thread() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return dependency_factory_->GetWebRtcSignalingThread();
+}
+
+void RTCPeerConnectionHandler::RunSynchronousClosureOnSignalingThread(
+ const base::Closure& closure,
+ const char* trace_event_name) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ scoped_refptr<base::SingleThreadTaskRunner> thread(signaling_thread());
+ if (!thread.get() || thread->BelongsToCurrentThread()) {
+ TRACE_EVENT0("webrtc", trace_event_name);
+ closure.Run();
+ } else {
+ base::WaitableEvent event(false, false);
+ thread->PostTask(FROM_HERE,
+ base::Bind(&RunSynchronousClosure, closure,
+ base::Unretained(trace_event_name),
+ base::Unretained(&event)));
+ event.Wait();
+ }
+}
+
} // namespace content
« 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