| Index: third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
|
| diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
|
| index e4d46030e55e6c5fdeb58076043f34c5ef75beda..63866d30253d725e3f5ecd2e1316ba3f93ab8503 100644
|
| --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
|
| +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
|
| @@ -1110,6 +1110,8 @@ void RTCPeerConnection::addStream(ScriptState* script_state,
|
| if (!valid)
|
| exception_state.ThrowDOMException(kSyntaxError,
|
| "Unable to add the provided stream.");
|
| + // Ensure |rtp_senders_| is up-to-date.
|
| + getSenders();
|
| }
|
|
|
| void RTCPeerConnection::removeStream(MediaStream* stream,
|
| @@ -1236,6 +1238,75 @@ HeapVector<Member<RTCRtpReceiver>> RTCPeerConnection::getReceivers() {
|
| return rtp_receivers;
|
| }
|
|
|
| +RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
|
| + MediaStreamVector streams,
|
| + ExceptionState& exception_state) {
|
| + DCHECK(track);
|
| + DCHECK(track->Component());
|
| + if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state))
|
| + return nullptr;
|
| + if (streams.size() >= 2) {
|
| + // TODO(hbos): Don't throw an exception when this is supported by the lower
|
| + // layers. https://crbug.com/webrtc/7932
|
| + exception_state.ThrowDOMException(
|
| + kNotSupportedError,
|
| + "Adding a track to multiple streams is not supported.");
|
| + return nullptr;
|
| + }
|
| + for (const auto sender_entry : rtp_senders_) {
|
| + RTCRtpSender* sender = sender_entry.value;
|
| + if (sender->track() == track) {
|
| + exception_state.ThrowDOMException(
|
| + kInvalidAccessError, "A sender already exists for the track.");
|
| + return nullptr;
|
| + }
|
| + }
|
| +
|
| + WebVector<WebMediaStream> web_streams(streams.size());
|
| + for (size_t i = 0; i < streams.size(); ++i) {
|
| + web_streams[i] = streams[i]->Descriptor();
|
| + }
|
| + std::unique_ptr<WebRTCRtpSender> web_rtp_sender =
|
| + peer_handler_->AddTrack(track->Component(), web_streams);
|
| + if (!web_rtp_sender) {
|
| + exception_state.ThrowDOMException(
|
| + kNotSupportedError, "A sender could not be created for this track.");
|
| + return nullptr;
|
| + }
|
| +
|
| + uintptr_t id = web_rtp_sender->Id();
|
| + DCHECK(rtp_senders_.find(id) == rtp_senders_.end());
|
| + RTCRtpSender* rtp_sender = new RTCRtpSender(std::move(web_rtp_sender), track);
|
| + tracks_.insert(track->Component(), track);
|
| + rtp_senders_.insert(id, rtp_sender);
|
| + return rtp_sender;
|
| +}
|
| +
|
| +void RTCPeerConnection::removeTrack(RTCRtpSender* sender,
|
| + ExceptionState& exception_state) {
|
| + DCHECK(sender);
|
| + if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state))
|
| + return;
|
| + if (rtp_senders_.find(sender->web_rtp_sender()->Id()) == rtp_senders_.end()) {
|
| + exception_state.ThrowDOMException(
|
| + kInvalidAccessError,
|
| + "The sender was not created by this peer connection.");
|
| + }
|
| +
|
| + if (!peer_handler_->RemoveTrack(sender->web_rtp_sender())) {
|
| + // Operation aborted. This indicates that the sender is no longer used by
|
| + // the peer connection, i.e. that it was removed due to setting a remote
|
| + // description of type "rollback".
|
| + // Note: Until the WebRTC library supports re-using senders, a sender will
|
| + // also stop being used as a result of being removed.
|
| + return;
|
| + }
|
| + // Successfully removing the track results in the sender's track property
|
| + // being nulled.
|
| + DCHECK(!sender->web_rtp_sender()->Track());
|
| + sender->SetTrack(nullptr);
|
| +}
|
| +
|
| RTCDataChannel* RTCPeerConnection::createDataChannel(
|
| ScriptState* script_state,
|
| String label,
|
|
|