| 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
|
|
|