summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/media/webrtc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/media/webrtc')
-rw-r--r--chromium/content/renderer/media/webrtc/audio_codec_factory.cc8
-rw-r--r--chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc193
-rw-r--r--chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h111
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc87
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h4
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc310
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics.h31
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc560
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc27
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h2
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc8
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc183
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h71
-rw-r--r--chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc23
-rw-r--r--chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h34
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc26
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h7
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker.cc251
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker.h51
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc364
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc47
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_certificate_generator.h7
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc1307
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h107
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc446
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc292
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h120
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc50
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc377
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender.h135
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc26
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc357
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h160
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc363
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_stats.cc19
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_stats.h3
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc45
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc20
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder.cc69
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc225
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h112
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc294
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc15
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc16
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.h8
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc292
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h182
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc227
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h168
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc206
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc400
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc28
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h2
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc29
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h3
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc40
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc41
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc166
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h186
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc (renamed from chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc)121
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc120
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h140
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_util.h35
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc40
69 files changed, 5298 insertions, 4115 deletions
diff --git a/chromium/content/renderer/media/webrtc/audio_codec_factory.cc b/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
index be2d15aa1c5..73abab19515 100644
--- a/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
+++ b/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
@@ -28,7 +28,7 @@ namespace {
template <typename T>
struct NotAdvertisedEncoder {
using Config = typename T::Config;
- static rtc::Optional<Config> SdpToConfig(
+ static absl::optional<Config> SdpToConfig(
const webrtc::SdpAudioFormat& audio_format) {
return T::SdpToConfig(audio_format);
}
@@ -42,7 +42,7 @@ struct NotAdvertisedEncoder {
static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
- rtc::Optional<webrtc::AudioCodecPairId> codec_pair_id) {
+ absl::optional<webrtc::AudioCodecPairId> codec_pair_id) {
return T::MakeAudioEncoder(config, payload_type, codec_pair_id);
}
};
@@ -51,7 +51,7 @@ struct NotAdvertisedEncoder {
template <typename T>
struct NotAdvertisedDecoder {
using Config = typename T::Config;
- static rtc::Optional<Config> SdpToConfig(
+ static absl::optional<Config> SdpToConfig(
const webrtc::SdpAudioFormat& audio_format) {
return T::SdpToConfig(audio_format);
}
@@ -61,7 +61,7 @@ struct NotAdvertisedDecoder {
}
static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
const Config& config,
- rtc::Optional<webrtc::AudioCodecPairId> codec_pair_id) {
+ absl::optional<webrtc::AudioCodecPairId> codec_pair_id) {
return T::MakeAudioDecoder(config, codec_pair_id);
}
};
diff --git a/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
new file mode 100644
index 00000000000..acb9937d405
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
@@ -0,0 +1,193 @@
+// Copyright 2018 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/webrtc/fake_rtc_rtp_transceiver.h"
+
+namespace content {
+
+blink::WebMediaStreamTrack CreateWebMediaStreamTrack(const std::string& id) {
+ blink::WebMediaStreamSource web_source;
+ web_source.Initialize(blink::WebString::FromUTF8(id),
+ blink::WebMediaStreamSource::kTypeAudio,
+ blink::WebString::FromUTF8("audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true);
+ // Takes ownership of |audio_source|.
+ web_source.SetExtraData(audio_source);
+
+ blink::WebMediaStreamTrack web_track;
+ web_track.Initialize(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(web_track);
+ return web_track;
+}
+
+FakeRTCRtpSender::FakeRTCRtpSender(base::Optional<std::string> track_id,
+ std::vector<std::string> stream_ids)
+ : track_id_(std::move(track_id)), stream_ids_(std::move(stream_ids)) {}
+
+FakeRTCRtpSender::FakeRTCRtpSender(const FakeRTCRtpSender&) = default;
+
+FakeRTCRtpSender::~FakeRTCRtpSender() {}
+
+FakeRTCRtpSender& FakeRTCRtpSender::operator=(const FakeRTCRtpSender&) =
+ default;
+
+std::unique_ptr<blink::WebRTCRtpSender> FakeRTCRtpSender::ShallowCopy() const {
+ return std::make_unique<FakeRTCRtpSender>(*this);
+}
+
+uintptr_t FakeRTCRtpSender::Id() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+blink::WebMediaStreamTrack FakeRTCRtpSender::Track() const {
+ return track_id_ ? CreateWebMediaStreamTrack(*track_id_)
+ : blink::WebMediaStreamTrack(); // null
+}
+
+blink::WebVector<blink::WebString> FakeRTCRtpSender::StreamIds() const {
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size());
+ for (size_t i = 0; i < stream_ids_.size(); ++i) {
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]);
+ }
+ return web_stream_ids;
+}
+
+void FakeRTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ blink::WebRTCVoidRequest request) {
+ NOTIMPLEMENTED();
+}
+
+std::unique_ptr<blink::WebRTCDTMFSenderHandler>
+FakeRTCRtpSender::GetDtmfSender() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+std::unique_ptr<webrtc::RtpParameters> FakeRTCRtpSender::GetParameters() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+void FakeRTCRtpSender::SetParameters(
+ blink::WebVector<webrtc::RtpEncodingParameters>,
+ webrtc::DegradationPreference,
+ blink::WebRTCVoidRequest) {
+ NOTIMPLEMENTED();
+}
+
+void FakeRTCRtpSender::GetStats(
+ std::unique_ptr<blink::WebRTCStatsReportCallback>) {
+ NOTIMPLEMENTED();
+}
+
+FakeRTCRtpReceiver::FakeRTCRtpReceiver(const std::string& track_id,
+ std::vector<std::string> stream_ids)
+ : track_(CreateWebMediaStreamTrack(track_id)),
+ stream_ids_(std::move(stream_ids)) {}
+
+FakeRTCRtpReceiver::FakeRTCRtpReceiver(const FakeRTCRtpReceiver&) = default;
+
+FakeRTCRtpReceiver::~FakeRTCRtpReceiver() {}
+
+FakeRTCRtpReceiver& FakeRTCRtpReceiver::operator=(const FakeRTCRtpReceiver&) =
+ default;
+
+std::unique_ptr<blink::WebRTCRtpReceiver> FakeRTCRtpReceiver::ShallowCopy()
+ const {
+ return std::make_unique<FakeRTCRtpReceiver>(*this);
+}
+
+uintptr_t FakeRTCRtpReceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+const blink::WebMediaStreamTrack& FakeRTCRtpReceiver::Track() const {
+ return track_;
+}
+
+blink::WebVector<blink::WebString> FakeRTCRtpReceiver::StreamIds() const {
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size());
+ for (size_t i = 0; i < stream_ids_.size(); ++i) {
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]);
+ }
+ return web_stream_ids;
+}
+
+blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
+FakeRTCRtpReceiver::GetSources() {
+ NOTIMPLEMENTED();
+ return {};
+}
+
+void FakeRTCRtpReceiver::GetStats(
+ std::unique_ptr<blink::WebRTCStatsReportCallback>) {
+ NOTIMPLEMENTED();
+}
+
+FakeRTCRtpTransceiver::FakeRTCRtpTransceiver(
+ base::Optional<std::string> mid,
+ FakeRTCRtpSender sender,
+ FakeRTCRtpReceiver receiver,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction)
+ : mid_(std::move(mid)),
+ sender_(std::move(sender)),
+ receiver_(std::move(receiver)),
+ stopped_(stopped),
+ direction_(std::move(direction)),
+ current_direction_(std::move(current_direction)) {}
+
+FakeRTCRtpTransceiver::~FakeRTCRtpTransceiver() {}
+
+blink::WebRTCRtpTransceiverImplementationType
+FakeRTCRtpTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver;
+}
+
+uintptr_t FakeRTCRtpTransceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+blink::WebString FakeRTCRtpTransceiver::Mid() const {
+ return mid_ ? blink::WebString::FromUTF8(*mid_) : blink::WebString();
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> FakeRTCRtpTransceiver::Sender() const {
+ return sender_.ShallowCopy();
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver> FakeRTCRtpTransceiver::Receiver()
+ const {
+ return receiver_.ShallowCopy();
+}
+
+bool FakeRTCRtpTransceiver::Stopped() const {
+ return stopped_;
+}
+
+webrtc::RtpTransceiverDirection FakeRTCRtpTransceiver::Direction() const {
+ return direction_;
+}
+
+void FakeRTCRtpTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ NOTIMPLEMENTED();
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+FakeRTCRtpTransceiver::CurrentDirection() const {
+ return current_direction_;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+FakeRTCRtpTransceiver::FiredDirection() const {
+ NOTIMPLEMENTED();
+ return base::nullopt;
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
new file mode 100644
index 00000000000..7f8dbfed61a
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
@@ -0,0 +1,111 @@
+// Copyright 2018 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.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_FAKE_RTC_RTP_TRANSCEIVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_FAKE_RTC_RTP_TRANSCEIVER_H_
+
+#include <memory>
+
+#include "content/renderer/media/stream/media_stream_audio_source.h"
+#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_contributing_source.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
+
+namespace content {
+
+// TODO(https://crbug.com/868868): Similar methods to this exist in many content
+// unittests. Move to a separate file and reuse it in all of them.
+blink::WebMediaStreamTrack CreateWebMediaStreamTrack(const std::string& id);
+
+class CONTENT_EXPORT FakeRTCRtpSender : public blink::WebRTCRtpSender {
+ public:
+ FakeRTCRtpSender(base::Optional<std::string> track_id,
+ std::vector<std::string> stream_ids);
+ FakeRTCRtpSender(const FakeRTCRtpSender&);
+ ~FakeRTCRtpSender() override;
+ FakeRTCRtpSender& operator=(const FakeRTCRtpSender&);
+
+ std::unique_ptr<blink::WebRTCRtpSender> ShallowCopy() const override;
+ uintptr_t Id() const override;
+ blink::WebMediaStreamTrack Track() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
+ void ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ blink::WebRTCVoidRequest request) override;
+ std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender()
+ const override;
+ std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
+ void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
+ webrtc::DegradationPreference,
+ blink::WebRTCVoidRequest) override;
+ void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
+
+ private:
+ base::Optional<std::string> track_id_;
+ std::vector<std::string> stream_ids_;
+};
+
+class CONTENT_EXPORT FakeRTCRtpReceiver : public blink::WebRTCRtpReceiver {
+ public:
+ FakeRTCRtpReceiver(const std::string& track_id,
+ std::vector<std::string> stream_ids);
+ FakeRTCRtpReceiver(const FakeRTCRtpReceiver&);
+ ~FakeRTCRtpReceiver() override;
+ FakeRTCRtpReceiver& operator=(const FakeRTCRtpReceiver&);
+
+ std::unique_ptr<blink::WebRTCRtpReceiver> ShallowCopy() const override;
+ uintptr_t Id() const override;
+ const blink::WebMediaStreamTrack& Track() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
+ blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
+ GetSources() override;
+ void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
+
+ private:
+ blink::WebMediaStreamTrack track_;
+ std::vector<std::string> stream_ids_;
+};
+
+class CONTENT_EXPORT FakeRTCRtpTransceiver
+ : public blink::WebRTCRtpTransceiver {
+ public:
+ FakeRTCRtpTransceiver(
+ base::Optional<std::string> mid,
+ FakeRTCRtpSender sender,
+ FakeRTCRtpReceiver receiver,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction);
+ ~FakeRTCRtpTransceiver() override;
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ base::Optional<std::string> mid_;
+ FakeRTCRtpSender sender_;
+ FakeRTCRtpReceiver receiver_;
+ bool stopped_;
+ webrtc::RtpTransceiverDirection direction_;
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_FAKE_RTC_RTP_TRANSCEIVER_H_
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
index eb85960b29c..0e810df0728 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -71,6 +71,7 @@ class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate
// Timestamp of the first received frame.
base::TimeDelta start_timestamp_;
+
// WebRTC Chromium timestamp diff
const base::TimeDelta time_diff_;
};
@@ -117,16 +118,16 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
scoped_refptr<media::VideoFrame> video_frame;
scoped_refptr<webrtc::VideoFrameBuffer> buffer(
incoming_frame.video_frame_buffer());
+ const gfx::Size size(buffer->width(), buffer->height());
- if (buffer->type() == webrtc::VideoFrameBuffer::Type::kNative) {
- video_frame = static_cast<WebRtcVideoFrameAdapter*>(buffer.get())
- ->getMediaVideoFrame();
- video_frame->set_timestamp(elapsed_timestamp);
- } else {
- const gfx::Size size(buffer->width(), buffer->height());
- const bool has_alpha =
- buffer->type() == webrtc::VideoFrameBuffer::Type::kI420A;
- if (has_alpha) {
+ switch (buffer->type()) {
+ case webrtc::VideoFrameBuffer::Type::kNative: {
+ video_frame = static_cast<WebRtcVideoFrameAdapter*>(buffer.get())
+ ->getMediaVideoFrame();
+ video_frame->set_timestamp(elapsed_timestamp);
+ break;
+ }
+ case webrtc::VideoFrameBuffer::Type::kI420A: {
const webrtc::I420ABufferInterface* yuva_buffer = buffer->GetI420A();
video_frame = media::VideoFrame::WrapExternalYuvaData(
media::PIXEL_FORMAT_I420A, size, gfx::Rect(size), size,
@@ -136,36 +137,64 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
const_cast<uint8_t*>(yuva_buffer->DataU()),
const_cast<uint8_t*>(yuva_buffer->DataV()),
const_cast<uint8_t*>(yuva_buffer->DataA()), elapsed_timestamp);
- } else {
- scoped_refptr<webrtc::PlanarYuvBuffer> yuv_buffer;
- media::VideoPixelFormat pixel_format;
- if (buffer->type() == webrtc::VideoFrameBuffer::Type::kI444) {
- yuv_buffer = buffer->GetI444();
- pixel_format = media::PIXEL_FORMAT_I444;
- } else {
- yuv_buffer = buffer->ToI420();
- pixel_format = media::PIXEL_FORMAT_I420;
- }
- // Make a shallow copy. Both |frame| and |video_frame| will share a single
- // reference counted frame buffer. Const cast and hope no one will
- // overwrite the data.
+ break;
+ }
+ case webrtc::VideoFrameBuffer::Type::kI420: {
+ rtc::scoped_refptr<webrtc::I420BufferInterface> yuv_buffer =
+ buffer->ToI420();
video_frame = media::VideoFrame::WrapExternalYuvData(
- pixel_format, size, gfx::Rect(size), size, yuv_buffer->StrideY(),
- yuv_buffer->StrideU(), yuv_buffer->StrideV(),
+ media::PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
+ yuv_buffer->StrideY(), yuv_buffer->StrideU(), yuv_buffer->StrideV(),
const_cast<uint8_t*>(yuv_buffer->DataY()),
const_cast<uint8_t*>(yuv_buffer->DataU()),
const_cast<uint8_t*>(yuv_buffer->DataV()), elapsed_timestamp);
+ break;
}
- if (!video_frame)
- return;
- // The bind ensures that we keep a reference to the underlying buffer.
- video_frame->AddDestructionObserver(base::BindOnce(&DoNothing, buffer));
+ case webrtc::VideoFrameBuffer::Type::kI444: {
+ webrtc::I444BufferInterface* yuv_buffer = buffer->GetI444();
+ video_frame = media::VideoFrame::WrapExternalYuvData(
+ media::PIXEL_FORMAT_I444, size, gfx::Rect(size), size,
+ yuv_buffer->StrideY(), yuv_buffer->StrideU(), yuv_buffer->StrideV(),
+ const_cast<uint8_t*>(yuv_buffer->DataY()),
+ const_cast<uint8_t*>(yuv_buffer->DataU()),
+ const_cast<uint8_t*>(yuv_buffer->DataV()), elapsed_timestamp);
+ break;
+ }
+ case webrtc::VideoFrameBuffer::Type::kI010: {
+ webrtc::I010BufferInterface* yuv_buffer = buffer->GetI010();
+ // WebRTC defines I010 data as uint16 whereas Chromium uses uint8 for all
+ // video formats, so conversion and cast is needed.
+ video_frame = media::VideoFrame::WrapExternalYuvData(
+ media::PIXEL_FORMAT_YUV420P10, size, gfx::Rect(size), size,
+ yuv_buffer->StrideY() * 2, yuv_buffer->StrideU() * 2,
+ yuv_buffer->StrideV() * 2,
+ const_cast<uint8_t*>(
+ reinterpret_cast<const uint8_t*>(yuv_buffer->DataY())),
+ const_cast<uint8_t*>(
+ reinterpret_cast<const uint8_t*>(yuv_buffer->DataU())),
+ const_cast<uint8_t*>(
+ reinterpret_cast<const uint8_t*>(yuv_buffer->DataV())),
+ elapsed_timestamp);
+ break;
+ }
+ default:
+ NOTREACHED();
}
+
+ if (!video_frame)
+ return;
+
+ // The bind ensures that we keep a reference to the underlying buffer.
+ if (buffer->type() != webrtc::VideoFrameBuffer::Type::kNative)
+ video_frame->AddDestructionObserver(base::BindOnce(&DoNothing, buffer));
+
+ // Rotation may be explicitly set sometimes.
if (incoming_frame.rotation() != webrtc::kVideoRotation_0) {
video_frame->metadata()->SetRotation(
media::VideoFrameMetadata::ROTATION,
WebRTCToMediaVideoRotation(incoming_frame.rotation()));
}
+
// Run render smoothness algorithm only when we don't have to render
// immediately.
if (!render_immediately) {
@@ -235,7 +264,7 @@ void MediaStreamRemoteVideoSource::StopSourceImpl() {
}
rtc::VideoSinkInterface<webrtc::VideoFrame>*
-MediaStreamRemoteVideoSource::SinkInterfaceForTest() {
+MediaStreamRemoteVideoSource::SinkInterfaceForTesting() {
return delegate_.get();
}
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h
index 494b11b8f45..f07b411c77c 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h
@@ -24,7 +24,7 @@ class TrackObserver;
// to make sure there is no difference between a video track where the source is
// a local source and a video track where the source is a remote video track.
class CONTENT_EXPORT MediaStreamRemoteVideoSource
- : public MediaStreamVideoSource {
+ : public MediaStreamVideoSource {
public:
explicit MediaStreamRemoteVideoSource(
std::unique_ptr<TrackObserver> observer);
@@ -44,7 +44,7 @@ class CONTENT_EXPORT MediaStreamRemoteVideoSource
// Used by tests to test that a frame can be received and that the
// MediaStreamRemoteVideoSource behaves as expected.
- rtc::VideoSinkInterface<webrtc::VideoFrame>* SinkInterfaceForTest();
+ rtc::VideoSinkInterface<webrtc::VideoFrame>* SinkInterfaceForTesting();
private:
void OnChanged(webrtc::MediaStreamTrackInterface::TrackState state);
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
index 34db57bbd4b..e721651a012 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
@@ -36,7 +36,7 @@ class MediaStreamRemoteVideoSourceUnderTest
explicit MediaStreamRemoteVideoSourceUnderTest(
std::unique_ptr<TrackObserver> observer)
: MediaStreamRemoteVideoSource(std::move(observer)) {}
- using MediaStreamRemoteVideoSource::SinkInterfaceForTest;
+ using MediaStreamRemoteVideoSource::SinkInterfaceForTesting;
};
class MediaStreamRemoteVideoSourceTest
@@ -171,7 +171,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
webrtc::I420Buffer::SetBlack(buffer);
- source()->SinkInterfaceForTest()->OnFrame(
+ source()->SinkInterfaceForTesting()->OnFrame(
webrtc::VideoFrame(buffer, webrtc::kVideoRotation_0, 1000));
run_loop.Run();
diff --git a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
index e84c5e83b71..30ea304614b 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
@@ -5,7 +5,6 @@
#include "content/renderer/media/webrtc/media_stream_track_metrics.h"
#include <inttypes.h>
-#include <set>
#include <string>
#include "base/md5.h"
@@ -14,133 +13,44 @@
#include "content/public/common/service_names.mojom.h"
#include "content/renderer/render_thread_impl.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "third_party/webrtc/api/mediastreaminterface.h"
-
-using webrtc::AudioTrackVector;
-using webrtc::MediaStreamInterface;
-using webrtc::MediaStreamTrackInterface;
-using webrtc::PeerConnectionInterface;
-using webrtc::VideoTrackVector;
namespace content {
-namespace {
-typedef std::set<std::string> IdSet;
-
-template <class T>
-IdSet GetTrackIds(const std::vector<rtc::scoped_refptr<T>>& tracks) {
- IdSet track_ids;
- for (const auto& track : tracks)
- track_ids.insert(track->id());
- return track_ids;
-}
-
-// TODO(tommi): Consolidate this and TrackObserver since these implementations
-// are fundamentally achieving the same thing (aside from specific logic inside
-// the OnChanged callbacks).
-class MediaStreamObserver
- : public base::RefCountedThreadSafe<MediaStreamObserver>,
- public webrtc::ObserverInterface {
- public:
- typedef base::Callback<
- void(const IdSet& audio_track_ids, const IdSet& video_track_ids)>
- OnChangedCallback;
-
- MediaStreamObserver(
- const OnChangedCallback& callback,
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- webrtc::MediaStreamInterface* stream)
- : main_thread_(main_thread), stream_(stream), callback_(callback) {
- signaling_thread_.DetachFromThread();
- stream_->RegisterObserver(this);
- }
-
- const scoped_refptr<webrtc::MediaStreamInterface>& stream() const {
- DCHECK(main_thread_->BelongsToCurrentThread());
- return stream_;
- }
-
- void Unregister() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- callback_.Reset();
- stream_->UnregisterObserver(this);
- stream_ = nullptr;
- }
-
- private:
- friend class base::RefCountedThreadSafe<MediaStreamObserver>;
- ~MediaStreamObserver() override {
- DCHECK(!stream_.get()) << "must have been unregistered before deleting";
- }
-
- // webrtc::ObserverInterface implementation.
- void OnChanged() override {
- DCHECK(signaling_thread_.CalledOnValidThread());
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&MediaStreamObserver::OnChangedOnMainThread,
- this, GetTrackIds(stream_->GetAudioTracks()),
- GetTrackIds(stream_->GetVideoTracks())));
- }
-
- void OnChangedOnMainThread(const IdSet& audio_track_ids,
- const IdSet& video_track_ids) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (!callback_.is_null())
- callback_.Run(audio_track_ids, video_track_ids);
- }
-
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<webrtc::MediaStreamInterface> stream_;
- OnChangedCallback callback_; // Only touched on the main thread.
- base::ThreadChecker signaling_thread_;
-};
-
-} // namespace
class MediaStreamTrackMetricsObserver {
public:
- MediaStreamTrackMetricsObserver(
- MediaStreamTrackMetrics::StreamType stream_type,
- MediaStreamInterface* stream,
- MediaStreamTrackMetrics* owner);
+ MediaStreamTrackMetricsObserver(MediaStreamTrackMetrics::Direction direction,
+ MediaStreamTrackMetrics::Kind kind,
+ std::string track_id,
+ MediaStreamTrackMetrics* owner);
~MediaStreamTrackMetricsObserver();
- // Sends begin/end messages for all tracks currently tracked.
- void SendLifetimeMessages(MediaStreamTrackMetrics::LifetimeEvent event);
+ // Sends begin/end messages for the track if not already reported.
+ void SendLifetimeMessageForTrack(
+ MediaStreamTrackMetrics::LifetimeEvent event);
- MediaStreamInterface* stream() {
+ MediaStreamTrackMetrics::Direction direction() {
DCHECK(thread_checker_.CalledOnValidThread());
- return observer_->stream().get();
+ return direction_;
}
- MediaStreamTrackMetrics::StreamType stream_type() {
+ MediaStreamTrackMetrics::Kind kind() {
DCHECK(thread_checker_.CalledOnValidThread());
- return stream_type_;
+ return kind_;
}
- private:
- void OnChanged(const IdSet& audio_track_ids, const IdSet& video_track_ids);
-
- void ReportAddedAndRemovedTracks(
- const IdSet& new_ids,
- const IdSet& old_ids,
- MediaStreamTrackMetrics::TrackType track_type);
-
- // Sends a lifetime message for the given tracks. OK to call with an
- // empty |ids|, in which case the method has no side effects.
- void ReportTracks(const IdSet& ids,
- MediaStreamTrackMetrics::TrackType track_type,
- MediaStreamTrackMetrics::LifetimeEvent event);
+ std::string track_id() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return track_id_;
+ }
+ private:
// False until start/end of lifetime messages have been sent.
bool has_reported_start_;
bool has_reported_end_;
- // IDs of audio and video tracks in the stream being observed.
- IdSet audio_track_ids_;
- IdSet video_track_ids_;
-
- MediaStreamTrackMetrics::StreamType stream_type_;
- scoped_refptr<MediaStreamObserver> observer_;
+ MediaStreamTrackMetrics::Direction direction_;
+ MediaStreamTrackMetrics::Kind kind_;
+ std::string track_id_;
// Non-owning.
MediaStreamTrackMetrics* owner_;
@@ -151,47 +61,46 @@ namespace {
// Used with std::find_if.
struct ObserverFinder {
- ObserverFinder(MediaStreamTrackMetrics::StreamType stream_type,
- MediaStreamInterface* stream)
- : stream_type(stream_type), stream_(stream) {}
+ ObserverFinder(MediaStreamTrackMetrics::Direction direction,
+ MediaStreamTrackMetrics::Kind kind,
+ const std::string& track_id)
+ : direction_(direction), kind_(kind), track_id_(track_id) {}
bool operator()(
const std::unique_ptr<MediaStreamTrackMetricsObserver>& observer) {
- return stream_ == observer->stream() &&
- stream_type == observer->stream_type();
+ return direction_ == observer->direction() && kind_ == observer->kind() &&
+ track_id_ == observer->track_id();
}
- MediaStreamTrackMetrics::StreamType stream_type;
- MediaStreamInterface* stream_;
+ MediaStreamTrackMetrics::Direction direction_;
+ MediaStreamTrackMetrics::Kind kind_;
+ std::string track_id_;
};
} // namespace
MediaStreamTrackMetricsObserver::MediaStreamTrackMetricsObserver(
- MediaStreamTrackMetrics::StreamType stream_type,
- MediaStreamInterface* stream,
+ MediaStreamTrackMetrics::Direction direction,
+ MediaStreamTrackMetrics::Kind kind,
+ std::string track_id,
MediaStreamTrackMetrics* owner)
: has_reported_start_(false),
has_reported_end_(false),
- audio_track_ids_(GetTrackIds(stream->GetAudioTracks())),
- video_track_ids_(GetTrackIds(stream->GetVideoTracks())),
- stream_type_(stream_type),
- observer_(new MediaStreamObserver(
- base::Bind(&MediaStreamTrackMetricsObserver::OnChanged,
- base::Unretained(this)),
- base::ThreadTaskRunnerHandle::Get(),
- stream)),
+ direction_(direction),
+ kind_(kind),
+ track_id_(std::move(track_id)),
owner_(owner) {
+ DCHECK(owner);
}
MediaStreamTrackMetricsObserver::~MediaStreamTrackMetricsObserver() {
DCHECK(thread_checker_.CalledOnValidThread());
- observer_->Unregister();
- SendLifetimeMessages(MediaStreamTrackMetrics::DISCONNECTED);
+ SendLifetimeMessageForTrack(
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected);
}
-void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
+void MediaStreamTrackMetricsObserver::SendLifetimeMessageForTrack(
MediaStreamTrackMetrics::LifetimeEvent event) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (event == MediaStreamTrackMetrics::CONNECTED) {
+ if (event == MediaStreamTrackMetrics::LifetimeEvent::kConnected) {
// Both ICE CONNECTED and COMPLETED can trigger the first
// start-of-life event, so we only report the first.
if (has_reported_start_)
@@ -199,7 +108,7 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
DCHECK(!has_reported_start_ && !has_reported_end_);
has_reported_start_ = true;
} else {
- DCHECK(event == MediaStreamTrackMetrics::DISCONNECTED);
+ DCHECK(event == MediaStreamTrackMetrics::LifetimeEvent::kDisconnected);
// We only report the first end-of-life event, since there are
// several cases where end-of-life can be reached. We also don't
@@ -209,10 +118,9 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
has_reported_end_ = true;
}
- ReportTracks(audio_track_ids_, MediaStreamTrackMetrics::AUDIO_TRACK, event);
- ReportTracks(video_track_ids_, MediaStreamTrackMetrics::VIDEO_TRACK, event);
+ owner_->SendLifetimeMessage(track_id_, kind_, event, direction_);
- if (event == MediaStreamTrackMetrics::DISCONNECTED) {
+ if (event == MediaStreamTrackMetrics::LifetimeEvent::kDisconnected) {
// After disconnection, we can get reconnected, so we need to
// forget that we've sent lifetime events, while retaining all
// other state.
@@ -222,76 +130,33 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
}
}
-void MediaStreamTrackMetricsObserver::OnChanged(
- const IdSet& audio_track_ids, const IdSet& video_track_ids) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // We only report changes after our initial report, and never after
- // our last report.
- if (has_reported_start_ && !has_reported_end_) {
- ReportAddedAndRemovedTracks(audio_track_ids,
- audio_track_ids_,
- MediaStreamTrackMetrics::AUDIO_TRACK);
- ReportAddedAndRemovedTracks(video_track_ids,
- video_track_ids_,
- MediaStreamTrackMetrics::VIDEO_TRACK);
- }
-
- // We always update our sets of tracks.
- audio_track_ids_ = audio_track_ids;
- video_track_ids_ = video_track_ids;
-}
-
-void MediaStreamTrackMetricsObserver::ReportAddedAndRemovedTracks(
- const IdSet& new_ids,
- const IdSet& old_ids,
- MediaStreamTrackMetrics::TrackType track_type) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(has_reported_start_ && !has_reported_end_);
-
- IdSet added_tracks = base::STLSetDifference<IdSet>(new_ids, old_ids);
- IdSet removed_tracks = base::STLSetDifference<IdSet>(old_ids, new_ids);
-
- ReportTracks(added_tracks, track_type, MediaStreamTrackMetrics::CONNECTED);
- ReportTracks(
- removed_tracks, track_type, MediaStreamTrackMetrics::DISCONNECTED);
-}
-
-void MediaStreamTrackMetricsObserver::ReportTracks(
- const IdSet& ids,
- MediaStreamTrackMetrics::TrackType track_type,
- MediaStreamTrackMetrics::LifetimeEvent event) {
- DCHECK(thread_checker_.CalledOnValidThread());
- for (IdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
- owner_->SendLifetimeMessage(*it, track_type, event, stream_type_);
- }
-}
-
MediaStreamTrackMetrics::MediaStreamTrackMetrics()
: ice_state_(webrtc::PeerConnectionInterface::kIceConnectionNew) {}
MediaStreamTrackMetrics::~MediaStreamTrackMetrics() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
for (const auto& observer : observers_) {
- observer->SendLifetimeMessages(DISCONNECTED);
+ observer->SendLifetimeMessageForTrack(LifetimeEvent::kDisconnected);
}
}
-void MediaStreamTrackMetrics::AddStream(StreamType type,
- MediaStreamInterface* stream) {
+void MediaStreamTrackMetrics::AddTrack(Direction direction,
+ Kind kind,
+ const std::string& track_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- observers_.push_back(
- std::make_unique<MediaStreamTrackMetricsObserver>(type, stream, this));
+ observers_.push_back(std::make_unique<MediaStreamTrackMetricsObserver>(
+ direction, kind, std::move(track_id), this));
SendLifeTimeMessageDependingOnIceState(observers_.back().get());
}
-void MediaStreamTrackMetrics::RemoveStream(StreamType type,
- MediaStreamInterface* stream) {
+void MediaStreamTrackMetrics::RemoveTrack(Direction direction,
+ Kind kind,
+ const std::string& track_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = std::find_if(observers_.begin(), observers_.end(),
- ObserverFinder(type, stream));
+ ObserverFinder(direction, kind, track_id));
if (it == observers_.end()) {
- // Since external apps could call removeStream with a stream they
+ // Since external apps could call removeTrack() with a stream they
// never added, this can happen without it being an error.
return;
}
@@ -300,40 +165,41 @@ void MediaStreamTrackMetrics::RemoveStream(StreamType type,
}
void MediaStreamTrackMetrics::IceConnectionChange(
- PeerConnectionInterface::IceConnectionState new_state) {
+ webrtc::PeerConnectionInterface::IceConnectionState new_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ice_state_ = new_state;
for (const auto& observer : observers_) {
SendLifeTimeMessageDependingOnIceState(observer.get());
}
}
+
void MediaStreamTrackMetrics::SendLifeTimeMessageDependingOnIceState(
MediaStreamTrackMetricsObserver* observer) {
// There is a state transition diagram for these states at
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceConnectionState
switch (ice_state_) {
- case PeerConnectionInterface::kIceConnectionConnected:
- case PeerConnectionInterface::kIceConnectionCompleted:
- observer->SendLifetimeMessages(CONNECTED);
+ case webrtc::PeerConnectionInterface::kIceConnectionConnected:
+ case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
+ observer->SendLifetimeMessageForTrack(LifetimeEvent::kConnected);
break;
- case PeerConnectionInterface::kIceConnectionFailed:
- // We don't really need to handle FAILED (it is only supposed
- // to be preceded by CHECKING so we wouldn't yet have sent a
- // lifetime message) but we might as well use belt and
- // suspenders and handle it the same as the other "end call"
- // states. It will be ignored anyway if the call is not
- // already connected.
- case PeerConnectionInterface::kIceConnectionNew:
- // It's a bit weird to count NEW as an end-lifetime event, but
- // it's possible to transition directly from a connected state
- // (CONNECTED or COMPLETED) to NEW, which can then be followed
- // by a new connection. The observer will ignore the end
- // lifetime event if it was not preceded by a begin-lifetime
- // event.
- case PeerConnectionInterface::kIceConnectionDisconnected:
- case PeerConnectionInterface::kIceConnectionClosed:
- observer->SendLifetimeMessages(DISCONNECTED);
+ case webrtc::PeerConnectionInterface::kIceConnectionFailed:
+ // We don't really need to handle FAILED (it is only supposed
+ // to be preceded by CHECKING so we wouldn't yet have sent a
+ // lifetime message) but we might as well use belt and
+ // suspenders and handle it the same as the other "end call"
+ // states. It will be ignored anyway if the call is not
+ // already connected.
+ case webrtc::PeerConnectionInterface::kIceConnectionNew:
+ // It's a bit weird to count NEW as an end-lifetime event, but
+ // it's possible to transition directly from a connected state
+ // (CONNECTED or COMPLETED) to NEW, which can then be followed
+ // by a new connection. The observer will ignore the end
+ // lifetime event if it was not preceded by a begin-lifetime
+ // event.
+ case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
+ case webrtc::PeerConnectionInterface::kIceConnectionClosed:
+ observer->SendLifetimeMessageForTrack(LifetimeEvent::kDisconnected);
break;
default:
@@ -345,28 +211,28 @@ void MediaStreamTrackMetrics::SendLifeTimeMessageDependingOnIceState(
}
void MediaStreamTrackMetrics::SendLifetimeMessage(const std::string& track_id,
- TrackType track_type,
+ Kind kind,
LifetimeEvent event,
- StreamType stream_type) {
+ Direction direction) {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
// |render_thread| can be NULL in certain cases when running as part
// |of a unit test.
if (render_thread) {
- if (event == CONNECTED) {
+ if (event == LifetimeEvent::kConnected) {
GetMediaStreamTrackMetricsHost()->AddTrack(
- MakeUniqueId(track_id, stream_type), track_type == AUDIO_TRACK,
- stream_type == RECEIVED_STREAM);
+ MakeUniqueId(track_id, direction), kind == Kind::kAudio,
+ direction == Direction::kReceive);
} else {
- DCHECK_EQ(DISCONNECTED, event);
+ DCHECK_EQ(LifetimeEvent::kDisconnected, event);
GetMediaStreamTrackMetricsHost()->RemoveTrack(
- MakeUniqueId(track_id, stream_type));
+ MakeUniqueId(track_id, direction));
}
}
}
uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
const std::string& track_id,
- StreamType stream_type) {
+ Direction direction) {
// We use a hash over the |track| pointer and the PeerConnection ID,
// plus a boolean flag indicating whether the track is remote (since
// you might conceivably have a remote track added back as a sent
@@ -376,10 +242,8 @@ uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
// no longer be considered), just one with virtually zero chance of
// collisions when faced with non-malicious data.
std::string unique_id_string =
- base::StringPrintf("%" PRIu64 " %s %d",
- pc_id,
- track_id.c_str(),
- stream_type == RECEIVED_STREAM ? 1 : 0);
+ base::StringPrintf("%" PRIu64 " %s %d", pc_id, track_id.c_str(),
+ direction == Direction::kReceive ? 1 : 0);
base::MD5Context ctx;
base::MD5Init(&ctx);
@@ -392,10 +256,10 @@ uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
}
uint64_t MediaStreamTrackMetrics::MakeUniqueId(const std::string& track_id,
- StreamType stream_type) {
+ Direction direction) {
return MakeUniqueIdImpl(
reinterpret_cast<uint64_t>(reinterpret_cast<void*>(this)), track_id,
- stream_type);
+ direction);
}
mojom::MediaStreamTrackMetricsHostPtr&
diff --git a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h
index 779318660ab..addd76a632b 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h
@@ -15,10 +15,6 @@
#include "content/common/media/media_stream.mojom.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
-namespace webrtc {
-class MediaStreamInterface;
-}
-
namespace content {
class MediaStreamTrackMetricsObserver;
@@ -36,19 +32,16 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
explicit MediaStreamTrackMetrics();
~MediaStreamTrackMetrics();
- enum StreamType { SENT_STREAM, RECEIVED_STREAM };
-
- enum TrackType { AUDIO_TRACK, VIDEO_TRACK };
-
- enum LifetimeEvent { CONNECTED, DISCONNECTED };
+ enum class Direction { kSend, kReceive };
+ enum class Kind { kAudio, kVideo };
+ enum class LifetimeEvent { kConnected, kDisconnected };
- // Starts tracking lifetimes of all the tracks in |stream| and any
- // tracks added or removed to/from the stream until |RemoveStream|
- // is called or this object's lifetime ends.
- void AddStream(StreamType type, webrtc::MediaStreamInterface* stream);
+ // Starts tracking the lifetime of the track until |RemoveTrack| is called
+ // or this object's lifetime ends.
+ void AddTrack(Direction direction, Kind kind, const std::string& track_id);
- // Stops tracking lifetimes of tracks in |stream|.
- void RemoveStream(StreamType type, webrtc::MediaStreamInterface* stream);
+ // Stops tracking the lifetime of the track.
+ void RemoveTrack(Direction direction, Kind kind, const std::string& track_id);
// Called to indicate changes in the ICE connection state for the
// PeerConnection this object is associated with. Used to generate
@@ -71,9 +64,9 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
// PeerConnection), false for local streams (sent over a
// PeerConnection).
virtual void SendLifetimeMessage(const std::string& track_id,
- TrackType track_type,
+ Kind kind,
LifetimeEvent lifetime_event,
- StreamType stream_type);
+ Direction direction);
protected:
// Calls SendLifetimeMessage for |observer| depending on |ice_state_|.
@@ -86,12 +79,12 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
// is a one-to-one relationship).
uint64_t MakeUniqueIdImpl(uint64_t pc_id,
const std::string& track,
- StreamType stream_type);
+ Direction direction);
private:
// Make a unique ID for the given track, that is valid while the
// track object and the PeerConnection it is attached to both exist.
- uint64_t MakeUniqueId(const std::string& track, StreamType stream_type);
+ uint64_t MakeUniqueId(const std::string& track_id, Direction direction);
mojom::MediaStreamTrackMetricsHostPtr& GetMediaStreamTrackMetricsHost();
diff --git a/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
index d8819aa62a5..4fb4ff31bc0 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
@@ -78,8 +78,7 @@ class MockMediaStreamTrackMetrics : public MediaStreamTrackMetrics {
virtual ~MockMediaStreamTrackMetrics() {}
MOCK_METHOD4(SendLifetimeMessage,
- void(const std::string&, TrackType, LifetimeEvent, StreamType));
-
+ void(const std::string&, Kind, LifetimeEvent, Direction));
using MediaStreamTrackMetrics::MakeUniqueIdImpl;
};
@@ -170,88 +169,82 @@ TEST_F(MediaStreamTrackMetricsTest, MakeUniqueId) {
// Lower 32 bits the same, upper 32 differ.
EXPECT_NE(
- metrics_->MakeUniqueIdImpl(
- 0x1000000000000001, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
- metrics_->MakeUniqueIdImpl(
- 0x2000000000000001, "x", MediaStreamTrackMetrics::RECEIVED_STREAM));
+ metrics_->MakeUniqueIdImpl(0x1000000000000001, "x",
+ MediaStreamTrackMetrics::Direction::kReceive),
+ metrics_->MakeUniqueIdImpl(0x2000000000000001, "x",
+ MediaStreamTrackMetrics::Direction::kReceive));
// Track ID differs.
EXPECT_NE(metrics_->MakeUniqueIdImpl(
- 42, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
+ 42, "x", MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(
- 42, "y", MediaStreamTrackMetrics::RECEIVED_STREAM));
+ 42, "y", MediaStreamTrackMetrics::Direction::kReceive));
// Remove vs. local track differs.
EXPECT_NE(metrics_->MakeUniqueIdImpl(
- 42, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
+ 42, "x", MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(
- 42, "x", MediaStreamTrackMetrics::SENT_STREAM));
+ 42, "x", MediaStreamTrackMetrics::Direction::kSend));
}
TEST_F(MediaStreamTrackMetricsTest, BasicRemoteStreams) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
}
TEST_F(MediaStreamTrackMetricsTest, BasicLocalStreams) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
}
@@ -259,341 +252,226 @@ TEST_F(MediaStreamTrackMetricsTest, LocalStreamAddedAferIceConnect) {
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
-
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamAddedAferIceConnect) {
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
-
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-}
-
-TEST_F(MediaStreamTrackMetricsTest, RemoteStreamTrackAdded) {
- scoped_refptr<MockAudioTrackInterface> initial(MakeAudioTrack("initial"));
- scoped_refptr<MockAudioTrackInterface> added(MakeAudioTrack("added"));
- stream_->AddTrack(initial.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("initial",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- metrics_->IceConnectionChange(
- PeerConnectionInterface::kIceConnectionConnected);
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("added",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- AddAudioTrack(added.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("initial",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("added",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamTrackRemoved) {
- scoped_refptr<MockAudioTrackInterface> first(MakeAudioTrack("first"));
- scoped_refptr<MockAudioTrackInterface> second(MakeAudioTrack("second"));
- stream_->AddTrack(first.get());
- stream_->AddTrack(second.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "first");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "second");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "first", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "second", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(first.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("first", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "first");
+
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("second", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
}
-TEST_F(MediaStreamTrackMetricsTest, LocalStreamModificationsBeforeAndAfter) {
- scoped_refptr<MockAudioTrackInterface> first(MakeAudioTrack("first"));
- scoped_refptr<MockAudioTrackInterface> second(MakeAudioTrack("second"));
- stream_->AddTrack(first.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- // This gets added after we start observing, but no lifetime message
- // should be sent at this point since the call is not connected. It
- // should get sent only once it gets connected.
- AddAudioTrack(second.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+TEST_F(MediaStreamTrackMetricsTest, RemoveAfterDisconnect) {
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
// This happens after the call is disconnected so no lifetime
// message should be sent.
- RemoveAudioTrack(first.get());
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamMultipleDisconnects) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- stream_->AddTrack(audio.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
- RemoveAudioTrack(audio.get());
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamConnectDisconnectTwice) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- stream_->AddTrack(audio.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
for (size_t i = 0; i < 2; ++i) {
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
}
- RemoveAudioTrack(audio.get());
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamRemovedNoDisconnect) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- metrics_->RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamLargerTest) {
- scoped_refptr<MockAudioTrackInterface> audio1(MakeAudioTrack("audio1"));
- scoped_refptr<MockAudioTrackInterface> audio2(MakeAudioTrack("audio2"));
- scoped_refptr<MockAudioTrackInterface> audio3(MakeAudioTrack("audio3"));
- scoped_refptr<MockVideoTrackInterface> video1(MakeVideoTrack("video1"));
- scoped_refptr<MockVideoTrackInterface> video2(MakeVideoTrack("video2"));
- scoped_refptr<MockVideoTrackInterface> video3(MakeVideoTrack("video3"));
- stream_->AddTrack(audio1.get());
- stream_->AddTrack(video1.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video1",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio2",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddAudioTrack(audio2.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video2",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddVideoTrack(video2.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveAudioTrack(audio1.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio3",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddAudioTrack(audio3.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video3",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddVideoTrack(video3.get());
-
- // Add back audio1
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddAudioTrack(audio1.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio2",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveAudioTrack(audio2.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video2",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveVideoTrack(video2.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveAudioTrack(audio1.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video1",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveVideoTrack(video1.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio3",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video3",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- metrics_->RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ // Add back audio
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
index be896490fc6..837f67cfe22 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
@@ -28,8 +28,8 @@ namespace content {
namespace {
-rtc::Optional<bool> ToRtcOptionalBool(const base::Optional<bool>& value) {
- return value ? rtc::Optional<bool>(*value) : rtc::Optional<bool>();
+absl::optional<bool> ToAbslOptionalBool(const base::Optional<bool>& value) {
+ return value ? absl::optional<bool>(*value) : absl::nullopt;
}
} // namespace
@@ -39,8 +39,8 @@ class MediaStreamVideoWebRtcSink::WebRtcVideoSource
public:
WebRtcVideoSource(WebRtcVideoCapturerAdapter* capture_adapter,
bool is_screencast,
- rtc::Optional<bool> needs_denoising)
- : VideoTrackSource(capture_adapter, false),
+ absl::optional<bool> needs_denoising)
+ : VideoTrackSource(false),
capture_adapter_(capture_adapter),
is_screencast_(is_screencast),
needs_denoising_(needs_denoising) {}
@@ -50,14 +50,19 @@ class MediaStreamVideoWebRtcSink::WebRtcVideoSource
}
bool is_screencast() const override { return is_screencast_; }
- rtc::Optional<bool> needs_denoising() const override {
+ absl::optional<bool> needs_denoising() const override {
return needs_denoising_;
}
+ protected:
+ rtc::VideoSourceInterface<webrtc::VideoFrame>* source() override {
+ return capture_adapter_.get();
+ }
+
private:
std::unique_ptr<WebRtcVideoCapturerAdapter> const capture_adapter_;
const bool is_screencast_;
- const rtc::Optional<bool> needs_denoising_;
+ const absl::optional<bool> needs_denoising_;
};
namespace {
@@ -84,6 +89,8 @@ webrtc::VideoTrackInterface::ContentHint ContentHintTypeToWebRtcContentHint(
return webrtc::VideoTrackInterface::ContentHint::kFluid;
case blink::WebMediaStreamTrack::ContentHintType::kVideoDetail:
return webrtc::VideoTrackInterface::ContentHint::kDetailed;
+ case blink::WebMediaStreamTrack::ContentHintType::kVideoText:
+ return webrtc::VideoTrackInterface::ContentHint::kText;
}
NOTREACHED();
return webrtc::VideoTrackInterface::ContentHint::kNone;
@@ -269,8 +276,8 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
MediaStreamVideoTrack::GetVideoTrack(track);
DCHECK(video_track);
- rtc::Optional<bool> needs_denoising =
- ToRtcOptionalBool(video_track->noise_reduction());
+ absl::optional<bool> needs_denoising =
+ ToAbslOptionalBool(video_track->noise_reduction());
bool is_screencast = video_track->is_screencast();
base::Optional<double> min_frame_rate = video_track->min_frame_rate();
@@ -364,8 +371,8 @@ void MediaStreamVideoWebRtcSink::RequestRefreshFrame() {
content::RequestRefreshFrameFromVideoTrack(connected_track());
}
-rtc::Optional<bool> MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting()
- const {
+absl::optional<bool>
+MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting() const {
return video_source_->needs_denoising();
}
diff --git a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
index 8ff0331d038..d8039286fa8 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
+++ b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
@@ -43,7 +43,7 @@ class CONTENT_EXPORT MediaStreamVideoWebRtcSink : public MediaStreamVideoSink {
return video_track_.get();
}
- rtc::Optional<bool> SourceNeedsDenoisingForTesting() const;
+ absl::optional<bool> SourceNeedsDenoisingForTesting() const;
protected:
// Implementation of MediaStreamSink.
diff --git a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
index 5265f9477fb..d33db26d3c6 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
@@ -25,8 +25,8 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
void SetVideoTrack() {
registry_.Init("stream URL");
registry_.AddVideoTrack("test video track");
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- registry_.test_stream().VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ registry_.test_stream().VideoTracks();
track_ = video_tracks[0];
// TODO(hta): Verify that track_ is valid. When constraints produce
// no valid format, using the track will cause a crash.
@@ -36,8 +36,8 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
registry_.Init("stream URL");
registry_.AddVideoTrack("test video track", VideoTrackAdapterSettings(),
noise_reduction, false, 0.0);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- registry_.test_stream().VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ registry_.test_stream().VideoTracks();
track_ = video_tracks[0];
// TODO(hta): Verify that track_ is valid. When constraints produce
// no valid format, using the track will cause a crash.
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
index ebc81901bd4..ee019112cb9 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
@@ -9,8 +9,10 @@
#include <vector>
#include "base/logging.h"
+#include "base/stl_util.h"
#include "content/renderer/media/webrtc/mock_data_channel_impl.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/webrtc_util.h"
#include "third_party/webrtc/api/rtpreceiverinterface.h"
#include "third_party/webrtc/rtc_base/refcountedobject.h"
@@ -58,19 +60,6 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
}
return nullptr;
}
- std::vector<webrtc::MediaStreamInterface*> FindStreamsOfTrack(
- webrtc::MediaStreamTrackInterface* track) {
- std::vector<webrtc::MediaStreamInterface*> streams_of_track;
- if (!track)
- return streams_of_track;
- for (size_t i = 0; i < streams_.size(); ++i) {
- if (streams_.at(i)->FindAudioTrack(track->id()) ||
- streams_.at(i)->FindVideoTrack(track->id())) {
- streams_of_track.push_back(streams_.at(i));
- }
- }
- return streams_of_track;
- }
void AddStream(MediaStreamInterface* stream) {
streams_.push_back(stream);
}
@@ -95,8 +84,6 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
class MockDtmfSender : public DtmfSenderInterface {
public:
- explicit MockDtmfSender(AudioTrackInterface* track)
- : track_(track), observer_(nullptr), duration_(0), inter_tone_gap_(0) {}
void RegisterObserver(DtmfSenderObserverInterface* observer) override {
observer_ = observer;
}
@@ -110,25 +97,21 @@ class MockDtmfSender : public DtmfSenderInterface {
inter_tone_gap_ = inter_tone_gap;
return true;
}
- const AudioTrackInterface* track() const override { return track_.get(); }
std::string tones() const override { return tones_; }
int duration() const override { return duration_; }
int inter_tone_gap() const override { return inter_tone_gap_; }
- protected:
- ~MockDtmfSender() override {}
-
private:
- rtc::scoped_refptr<AudioTrackInterface> track_;
- DtmfSenderObserverInterface* observer_;
+ DtmfSenderObserverInterface* observer_ = nullptr;
std::string tones_;
- int duration_;
- int inter_tone_gap_;
+ int duration_ = 0;
+ int inter_tone_gap_ = 0;
};
FakeRtpSender::FakeRtpSender(
- rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track)
- : track_(std::move(track)) {}
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids)
+ : track_(std::move(track)), stream_ids_(std::move(stream_ids)) {}
FakeRtpSender::~FakeRtpSender() {}
@@ -158,11 +141,10 @@ std::string FakeRtpSender::id() const {
}
std::vector<std::string> FakeRtpSender::stream_ids() const {
- NOTIMPLEMENTED();
- return {};
+ return stream_ids_;
}
-webrtc::RtpParameters FakeRtpSender::GetParameters() const {
+webrtc::RtpParameters FakeRtpSender::GetParameters() {
NOTIMPLEMENTED();
return webrtc::RtpParameters();
}
@@ -175,8 +157,7 @@ webrtc::RTCError FakeRtpSender::SetParameters(
rtc::scoped_refptr<webrtc::DtmfSenderInterface> FakeRtpSender::GetDtmfSender()
const {
- NOTIMPLEMENTED();
- return nullptr;
+ return new rtc::RefCountedObject<MockDtmfSender>();
}
FakeRtpReceiver::FakeRtpReceiver(
@@ -226,6 +207,69 @@ std::vector<webrtc::RtpSource> FakeRtpReceiver::GetSources() const {
return std::vector<webrtc::RtpSource>();
}
+FakeRtpTransceiver::FakeRtpTransceiver(
+ cricket::MediaType media_type,
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction)
+ : media_type_(media_type),
+ sender_(std::move(sender)),
+ receiver_(std::move(receiver)),
+ mid_(ToAbslOptional(mid)),
+ stopped_(stopped),
+ direction_(direction),
+ current_direction_(ToAbslOptional(current_direction)) {}
+
+FakeRtpTransceiver::~FakeRtpTransceiver() {}
+
+cricket::MediaType FakeRtpTransceiver::media_type() const {
+ return media_type_;
+}
+
+absl::optional<std::string> FakeRtpTransceiver::mid() const {
+ return mid_;
+}
+
+rtc::scoped_refptr<webrtc::RtpSenderInterface> FakeRtpTransceiver::sender()
+ const {
+ return sender_;
+}
+
+rtc::scoped_refptr<webrtc::RtpReceiverInterface> FakeRtpTransceiver::receiver()
+ const {
+ return receiver_;
+}
+
+bool FakeRtpTransceiver::stopped() const {
+ return stopped_;
+}
+
+webrtc::RtpTransceiverDirection FakeRtpTransceiver::direction() const {
+ return direction_;
+}
+
+void FakeRtpTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection new_direction) {
+ NOTIMPLEMENTED();
+}
+
+absl::optional<webrtc::RtpTransceiverDirection>
+FakeRtpTransceiver::current_direction() const {
+ return current_direction_;
+}
+
+void FakeRtpTransceiver::Stop() {
+ NOTIMPLEMENTED();
+}
+
+void FakeRtpTransceiver::SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
+ NOTIMPLEMENTED();
+}
+
const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer";
const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer";
@@ -233,7 +277,6 @@ MockPeerConnectionImpl::MockPeerConnectionImpl(
MockPeerConnectionDependencyFactory* factory,
webrtc::PeerConnectionObserver* observer)
: dependency_factory_(factory),
- local_streams_(new rtc::RefCountedObject<MockStreamCollection>),
remote_streams_(new rtc::RefCountedObject<MockStreamCollection>),
hint_audio_(false),
hint_video_(false),
@@ -257,73 +300,42 @@ MockPeerConnectionImpl::MockPeerConnectionImpl(
MockPeerConnectionImpl::~MockPeerConnectionImpl() {}
-rtc::scoped_refptr<webrtc::StreamCollectionInterface>
-MockPeerConnectionImpl::local_streams() {
- return local_streams_;
-}
-
-rtc::scoped_refptr<webrtc::StreamCollectionInterface>
-MockPeerConnectionImpl::remote_streams() {
- return remote_streams_;
-}
-
-rtc::scoped_refptr<webrtc::RtpSenderInterface> MockPeerConnectionImpl::AddTrack(
- webrtc::MediaStreamTrackInterface* track,
- std::vector<webrtc::MediaStreamInterface*> streams) {
+webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>
+MockPeerConnectionImpl::AddTrack(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids) {
DCHECK(track);
- DCHECK_EQ(1u, streams.size());
+ DCHECK_EQ(1u, stream_ids.size());
for (const auto& sender : senders_) {
if (sender->track() == track)
- return nullptr;
+ return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER);
}
- for (auto* stream : streams) {
- if (!local_streams_->find(stream->id())) {
- stream_label_ = stream->id();
- local_streams_->AddStream(stream);
+ for (const auto& stream_id : stream_ids) {
+ if (!base::ContainsValue(local_stream_ids_, stream_id)) {
+ stream_label_ = stream_id;
+ local_stream_ids_.push_back(stream_id);
}
}
- auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track);
+ auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track, stream_ids);
senders_.push_back(sender);
- return sender;
+ return rtc::scoped_refptr<webrtc::RtpSenderInterface>(sender);
}
-bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* sender) {
- auto it = std::find(senders_.begin(), senders_.end(),
- static_cast<FakeRtpSender*>(sender));
+bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* s) {
+ rtc::scoped_refptr<FakeRtpSender> sender = static_cast<FakeRtpSender*>(s);
+ auto it = std::find(senders_.begin(), senders_.end(), sender);
if (it == senders_.end())
return false;
senders_.erase(it);
auto track = sender->track();
- for (auto* stream : local_streams_->FindStreamsOfTrack(track)) {
- bool stream_has_senders = false;
- for (const auto& track : stream->GetAudioTracks()) {
- for (const auto& sender : senders_) {
- if (sender->track() == track) {
- stream_has_senders = true;
- break;
- }
- }
- }
- for (const auto& track : stream->GetVideoTracks()) {
- for (const auto& sender : senders_) {
- if (sender->track() == track) {
- stream_has_senders = true;
- break;
- }
- }
- }
- if (!stream_has_senders)
- local_streams_->RemoveStream(stream);
- }
- return true;
-}
-rtc::scoped_refptr<DtmfSenderInterface>
-MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) {
- if (!track) {
- return nullptr;
+ for (const auto& stream_id : sender->stream_ids()) {
+ auto local_stream_it = std::find(local_stream_ids_.begin(),
+ local_stream_ids_.end(), stream_id);
+ if (local_stream_it != local_stream_ids_.end())
+ local_stream_ids_.erase(local_stream_it);
}
- return new rtc::RefCountedObject<MockDtmfSender>(track);
+ return true;
}
std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>>
@@ -477,11 +489,6 @@ bool MockPeerConnectionImpl::AddIceCandidate(
return candidate->ToString(&ice_sdp_);
}
-void MockPeerConnectionImpl::RegisterUMAObserver(
- webrtc::UMAObserver* observer) {
- NOTIMPLEMENTED();
-}
-
webrtc::RTCError MockPeerConnectionImpl::SetBitrate(
const webrtc::BitrateSettings& bitrate) {
NOTIMPLEMENTED();
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
index da06e71438e..5d348e74b72 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/stats/rtcstatsreport.h"
@@ -22,7 +23,8 @@ class MockStreamCollection;
class FakeRtpSender : public webrtc::RtpSenderInterface {
public:
- FakeRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track);
+ FakeRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids);
~FakeRtpSender() override;
bool SetTrack(webrtc::MediaStreamTrackInterface* track) override;
@@ -31,7 +33,7 @@ class FakeRtpSender : public webrtc::RtpSenderInterface {
cricket::MediaType media_type() const override;
std::string id() const override;
std::vector<std::string> stream_ids() const override;
- webrtc::RtpParameters GetParameters() const override;
+ webrtc::RtpParameters GetParameters() override;
webrtc::RTCError SetParameters(
const webrtc::RtpParameters& parameters) override;
rtc::scoped_refptr<webrtc::DtmfSenderInterface> GetDtmfSender()
@@ -39,6 +41,7 @@ class FakeRtpSender : public webrtc::RtpSenderInterface {
private:
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
+ std::vector<std::string> stream_ids_;
};
class FakeRtpReceiver : public webrtc::RtpReceiverInterface {
@@ -63,6 +66,43 @@ class FakeRtpReceiver : public webrtc::RtpReceiverInterface {
std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams_;
};
+class FakeRtpTransceiver : public webrtc::RtpTransceiverInterface {
+ public:
+ FakeRtpTransceiver(
+ cricket::MediaType media_type,
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction);
+ ~FakeRtpTransceiver() override;
+
+ FakeRtpTransceiver& operator=(const FakeRtpTransceiver& other) = default;
+
+ cricket::MediaType media_type() const override;
+ absl::optional<std::string> mid() const override;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override;
+ bool stopped() const override;
+ webrtc::RtpTransceiverDirection direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection new_direction) override;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction()
+ const override;
+ void Stop() override;
+ void SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
+
+ private:
+ cricket::MediaType media_type_;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_;
+ absl::optional<std::string> mid_;
+ bool stopped_;
+ webrtc::RtpTransceiverDirection direction_;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction_;
+};
+
// TODO(hbos): The use of fakes and mocks is the wrong approach for testing of
// this. It introduces complexity, is error prone (not testing the right thing
// and bugs in the mocks). This class is a maintenance burden and should be
@@ -73,10 +113,16 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
webrtc::PeerConnectionObserver* observer);
// PeerConnectionInterface implementation.
- rtc::scoped_refptr<webrtc::StreamCollectionInterface>
- local_streams() override;
- rtc::scoped_refptr<webrtc::StreamCollectionInterface>
- remote_streams() override;
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams()
+ override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams()
+ override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
bool AddStream(webrtc::MediaStreamInterface* local_stream) override {
NOTIMPLEMENTED();
return false;
@@ -84,14 +130,10 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
void RemoveStream(webrtc::MediaStreamInterface* local_stream) override {
NOTIMPLEMENTED();
}
- // TODO(hbos): Use AddTrack() taking stream labels instead of stream pointers.
- // https://crbug.com/810708
- rtc::scoped_refptr<webrtc::RtpSenderInterface> AddTrack(
- webrtc::MediaStreamTrackInterface* track,
- std::vector<webrtc::MediaStreamInterface*> streams) override;
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> AddTrack(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids) override;
bool RemoveTrack(webrtc::RtpSenderInterface* sender) override;
- rtc::scoped_refptr<webrtc::DtmfSenderInterface>
- CreateDtmfSender(webrtc::AudioTrackInterface* track) override;
std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> GetSenders()
const override;
std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> GetReceivers()
@@ -174,7 +216,6 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
bool SetConfiguration(const RTCConfiguration& configuration,
webrtc::RTCError* error) override;
bool AddIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
- void RegisterUMAObserver(webrtc::UMAObserver* observer) override;
webrtc::RTCError SetBitrate(const webrtc::BitrateSettings& bitrate) override;
@@ -207,7 +248,7 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
MockPeerConnectionDependencyFactory* dependency_factory_;
std::string stream_label_;
- rtc::scoped_refptr<MockStreamCollection> local_streams_;
+ std::vector<std::string> local_stream_ids_;
rtc::scoped_refptr<MockStreamCollection> remote_streams_;
std::vector<rtc::scoped_refptr<FakeRtpSender>> senders_;
std::unique_ptr<webrtc::SessionDescriptionInterface> local_desc_;
diff --git a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
index 6d8afca21d7..a1ec79ef9f7 100644
--- a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
+++ b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
@@ -20,14 +20,13 @@ MockWebRTCPeerConnectionHandlerClient()
.WillByDefault(
testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient::
didGenerateICECandidateWorker));
- ON_CALL(*this, DidAddRemoteTrackForMock(_))
+ ON_CALL(*this, DidAddReceiverPlanBForMock(_))
.WillByDefault(testing::Invoke(
- this,
- &MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker));
- ON_CALL(*this, DidRemoveRemoteTrackForMock(_))
+ this, &MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker));
+ ON_CALL(*this, DidRemoveReceiverPlanBForMock(_))
.WillByDefault(testing::Invoke(
this,
- &MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker));
+ &MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker));
}
MockWebRTCPeerConnectionHandlerClient::
@@ -40,17 +39,17 @@ void MockWebRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker(
candidate_mid_ = candidate->SdpMid().Utf8();
}
-void MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker(
+void MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) {
- blink::WebVector<blink::WebMediaStream> web_streams =
- (*web_rtp_receiver)->Streams();
- DCHECK_EQ(1u, web_streams.size());
- remote_stream_ = web_streams[0];
+ blink::WebVector<blink::WebString> stream_ids =
+ (*web_rtp_receiver)->StreamIds();
+ DCHECK_EQ(1u, stream_ids.size());
+ remote_stream_id_ = stream_ids[0];
}
-void MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker(
+void MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) {
- remote_stream_.Reset();
+ remote_stream_id_ = blink::WebString();
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
index 6958818c8c2..32ec4d023d4 100644
--- a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
+++ b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
@@ -14,6 +14,7 @@
#include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
namespace content {
@@ -27,33 +28,42 @@ class MockWebRTCPeerConnectionHandlerClient
MOCK_METHOD0(NegotiationNeeded, void());
MOCK_METHOD1(DidGenerateICECandidate,
void(scoped_refptr<blink::WebRTCICECandidate> candidate));
- MOCK_METHOD1(DidChangeSignalingState, void(SignalingState state));
+ MOCK_METHOD1(DidChangeSignalingState,
+ void(webrtc::PeerConnectionInterface::SignalingState state));
MOCK_METHOD1(DidChangeICEGatheringState, void(ICEGatheringState state));
MOCK_METHOD1(DidChangeICEConnectionState, void(ICEConnectionState state));
- void DidAddRemoteTrack(
+ void DidAddReceiverPlanB(
std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) override {
- DidAddRemoteTrackForMock(&web_rtp_receiver);
+ DidAddReceiverPlanBForMock(&web_rtp_receiver);
}
- void DidRemoveRemoteTrack(
+ void DidRemoveReceiverPlanB(
std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) override {
- DidRemoveRemoteTrackForMock(&web_rtp_receiver);
+ DidRemoveReceiverPlanBForMock(&web_rtp_receiver);
+ }
+ void DidModifyTransceivers(
+ std::vector<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ web_transceivers,
+ bool is_remote_description) override {
+ DidModifyTransceiversForMock(&web_transceivers, is_remote_description);
}
MOCK_METHOD1(DidAddRemoteDataChannel, void(blink::WebRTCDataChannelHandler*));
MOCK_METHOD0(ReleasePeerConnectionHandler, void());
- MOCK_METHOD0(GetOriginTrials, WebRTCOriginTrials());
// Move-only arguments do not play nicely with MOCK, the workaround is to
// EXPECT_CALL with these instead.
- MOCK_METHOD1(DidAddRemoteTrackForMock,
+ MOCK_METHOD1(DidAddReceiverPlanBForMock,
void(std::unique_ptr<blink::WebRTCRtpReceiver>*));
- MOCK_METHOD1(DidRemoveRemoteTrackForMock,
+ MOCK_METHOD1(DidRemoveReceiverPlanBForMock,
void(std::unique_ptr<blink::WebRTCRtpReceiver>*));
+ MOCK_METHOD2(DidModifyTransceiversForMock,
+ void(std::vector<std::unique_ptr<blink::WebRTCRtpTransceiver>>*,
+ bool));
void didGenerateICECandidateWorker(
scoped_refptr<blink::WebRTCICECandidate> candidate);
- void didAddRemoteTrackWorker(
+ void didAddReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
- void didRemoveRemoteTrackWorker(
+ void didRemoveReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
const std::string& candidate_sdp() const { return candidate_sdp_; }
@@ -61,10 +71,10 @@ class MockWebRTCPeerConnectionHandlerClient
return candidate_mline_index_;
}
const std::string& candidate_mid() const { return candidate_mid_ ; }
- const blink::WebMediaStream& remote_stream() const { return remote_stream_; }
+ const blink::WebString& remote_stream_id() const { return remote_stream_id_; }
private:
- blink::WebMediaStream remote_stream_;
+ blink::WebString remote_stream_id_;
std::string candidate_sdp_;
int candidate_mline_index_;
std::string candidate_mid_;
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index d57e983c03b..d0c4b1b96f9 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -620,4 +620,30 @@ void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() {
audio_device_ = new rtc::RefCountedObject<WebRtcAudioDeviceImpl>();
}
+std::unique_ptr<webrtc::RtpCapabilities>
+PeerConnectionDependencyFactory::GetSenderCapabilities(
+ const std::string& kind) {
+ if (kind == "audio") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO));
+ } else if (kind == "video") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO));
+ }
+ return nullptr;
+}
+
+std::unique_ptr<webrtc::RtpCapabilities>
+PeerConnectionDependencyFactory::GetReceiverCapabilities(
+ const std::string& kind) {
+ if (kind == "audio") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO));
+ } else if (kind == "video") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO));
+ }
+ return nullptr;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index 8f1cbd22a8c..db7919fe1e5 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -94,6 +94,13 @@ class CONTENT_EXPORT PeerConnectionDependencyFactory
int sdp_mline_index,
const std::string& sdp);
+ // Returns the most optimistic view of the capabilities of the system for
+ // sending or receiving media of the given kind ("audio" or "video").
+ virtual std::unique_ptr<webrtc::RtpCapabilities> GetSenderCapabilities(
+ const std::string& kind);
+ virtual std::unique_ptr<webrtc::RtpCapabilities> GetReceiverCapabilities(
+ const std::string& kind);
+
WebRtcAudioDeviceImpl* GetWebRtcAudioDevice();
void EnsureInitialized();
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc b/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
index 85ce26f5918..4566c247f7b 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
@@ -87,39 +87,111 @@ static std::string SerializeAnswerOptions(
return result.str();
}
-static std::string SerializeMediaStreamComponent(
- const blink::WebMediaStreamTrack& component) {
- return component.Source().Id().Utf8();
-}
-
-static std::string SerializeMediaDescriptor(
- const blink::WebMediaStream& stream) {
- std::string id = stream.Id().Utf8();
- std::string result = "id: " + id;
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- stream.AudioTracks(tracks);
- if (!tracks.IsEmpty()) {
- result += ", audio: [";
- for (size_t i = 0; i < tracks.size(); ++i) {
- result += SerializeMediaStreamComponent(tracks[i]);
- if (i != tracks.size() - 1)
- result += ", ";
- }
- result += "]";
+static std::string SerializeMediaStreamIds(
+ const blink::WebVector<blink::WebString>& stream_ids) {
+ if (!stream_ids.size())
+ return "[]";
+ std::string result = "[";
+ for (const auto& stream_id : stream_ids) {
+ if (result.size() > 2u)
+ result += ",";
+ result += "'" + stream_id.Utf8() + "'";
}
- stream.VideoTracks(tracks);
- if (!tracks.IsEmpty()) {
- result += ", video: [";
- for (size_t i = 0; i < tracks.size(); ++i) {
- result += SerializeMediaStreamComponent(tracks[i]);
- if (i != tracks.size() - 1)
- result += ", ";
- }
- result += "]";
+ result += "]";
+ return result;
+}
+
+static const char* SerializeDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ switch (direction) {
+ case webrtc::RtpTransceiverDirection::kSendRecv:
+ return "'sendrecv'";
+ case webrtc::RtpTransceiverDirection::kSendOnly:
+ return "'sendonly'";
+ case webrtc::RtpTransceiverDirection::kRecvOnly:
+ return "'recvonly'";
+ case webrtc::RtpTransceiverDirection::kInactive:
+ return "'inactive'";
+ }
+}
+
+static const char* SerializeOptionalDirection(
+ const base::Optional<webrtc::RtpTransceiverDirection>& direction) {
+ return direction ? SerializeDirection(*direction) : "null";
+}
+
+static std::string SerializeSender(const std::string& indent,
+ const blink::WebRTCRtpSender& sender) {
+ std::string result = "{\n";
+ // track:'id',
+ result += indent + " track:";
+ if (sender.Track().IsNull()) {
+ result += "null";
+ } else {
+ result += "'" + sender.Track().Source().Id().Utf8() + "'";
}
+ result += ",\n";
+ // streams:['id,'id'],
+ result += indent +
+ " streams:" + SerializeMediaStreamIds(sender.StreamIds()) + ",\n";
+ result += indent + "}";
+ return result;
+}
+
+static std::string SerializeReceiver(const std::string& indent,
+ const blink::WebRTCRtpReceiver& receiver) {
+ std::string result = "{\n";
+ // track:'id',
+ DCHECK(!receiver.Track().IsNull());
+ result +=
+ indent + " track:'" + receiver.Track().Source().Id().Utf8() + "',\n";
+ // streams:['id,'id'],
+ result += indent +
+ " streams:" + SerializeMediaStreamIds(receiver.StreamIds()) +
+ ",\n";
+ result += indent + "}";
return result;
}
+static std::string SerializeTransceiver(
+ const blink::WebRTCRtpTransceiver& transceiver) {
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ std::string result = "{\n";
+ // mid:'foo',
+ if (transceiver.Mid().IsNull())
+ result += " mid:null,\n";
+ else
+ result += " mid:'" + transceiver.Mid().Utf8() + "',\n";
+ // sender:{...},
+ result +=
+ " sender:" + SerializeSender(" ", *transceiver.Sender()) + ",\n";
+ // receiver:{...},
+ result += " receiver:" + SerializeReceiver(" ", *transceiver.Receiver()) +
+ ",\n";
+ // stopped:false,
+ result += " stopped:" +
+ std::string(SerializeBoolean(transceiver.Stopped())) + ",\n";
+ // direction:'sendrecv',
+ result += " direction:" +
+ std::string(SerializeDirection(transceiver.Direction())) + ",\n";
+ // currentDirection:null,
+ result += " currentDirection:" +
+ std::string(
+ SerializeOptionalDirection(transceiver.CurrentDirection())) +
+ ",\n";
+ result += "}";
+ return result;
+ }
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ return SerializeSender("", *transceiver.Sender());
+ }
+ DCHECK(transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ return SerializeReceiver("", *transceiver.Receiver());
+}
+
static const char* SerializeIceTransportType(
webrtc::PeerConnectionInterface::IceTransportsType type) {
const char* transport_type = "";
@@ -216,15 +288,21 @@ static std::string SerializeConfiguration(
// strings on chrome://webrtc-internals.
static const char* GetSignalingStateString(
- WebRTCPeerConnectionHandlerClient::SignalingState state) {
+ webrtc::PeerConnectionInterface::SignalingState state) {
const char* result = "";
switch (state) {
- GET_STRING_OF_STATE(SignalingStateStable)
- GET_STRING_OF_STATE(SignalingStateHaveLocalOffer)
- GET_STRING_OF_STATE(SignalingStateHaveRemoteOffer)
- GET_STRING_OF_STATE(SignalingStateHaveLocalPrAnswer)
- GET_STRING_OF_STATE(SignalingStateHaveRemotePrAnswer)
- GET_STRING_OF_STATE(SignalingStateClosed)
+ case webrtc::PeerConnectionInterface::SignalingState::kStable:
+ return "SignalingStateStable";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveLocalOffer:
+ return "SignalingStateHaveLocalOffer";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveRemoteOffer:
+ return "SignalingStateHaveRemoteOffer";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveLocalPrAnswer:
+ return "SignalingStateHaveLocalPrAnswer";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveRemotePrAnswer:
+ return "SignalingStateHaveRemotePrAnswer";
+ case webrtc::PeerConnectionInterface::SignalingState::kClosed:
+ return "SignalingStateClosed";
default:
NOTREACHED();
break;
@@ -264,6 +342,24 @@ static const char* GetIceGatheringStateString(
return result;
}
+static const char* GetTransceiverUpdatedReasonString(
+ PeerConnectionTracker::TransceiverUpdatedReason reason) {
+ switch (reason) {
+ case PeerConnectionTracker::TransceiverUpdatedReason::kAddTransceiver:
+ return "addTransceiver";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack:
+ return "addTrack";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack:
+ return "removeTrack";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kSetLocalDescription:
+ return "setLocalDescription";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription:
+ return "setRemoteDescription";
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
// Builds a DictionaryValue from the StatsReport.
// Note:
// The format must be consistent with what webrtc_internals.js expects.
@@ -613,30 +709,73 @@ void PeerConnectionTracker::TrackAddIceCandidate(
SendPeerConnectionUpdate(id, event, value);
}
-void PeerConnectionTracker::TrackAddStream(
+void PeerConnectionTracker::TrackAddTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source) {
- DCHECK(main_thread_.CalledOnValidThread());
- int id = GetLocalIDForHandler(pc_handler);
- if (id == -1)
- return;
- SendPeerConnectionUpdate(
- id, source == SOURCE_LOCAL ? "addStream" : "onAddStream",
- SerializeMediaDescriptor(stream));
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
+ TrackTransceiver("Added", pc_handler, reason, transceiver, transceiver_index);
}
-void PeerConnectionTracker::TrackRemoveStream(
+void PeerConnectionTracker::TrackModifyTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source) {
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
+ TrackTransceiver("Modified", pc_handler, reason, transceiver,
+ transceiver_index);
+}
+
+void PeerConnectionTracker::TrackRemoveTransceiver(
+ RTCPeerConnectionHandler* pc_handler,
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
+ TrackTransceiver("Removed", pc_handler, reason, transceiver,
+ transceiver_index);
+}
+
+void PeerConnectionTracker::TrackTransceiver(
+ const char* callback_type_ending,
+ RTCPeerConnectionHandler* pc_handler,
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
DCHECK(main_thread_.CalledOnValidThread());
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
return;
- SendPeerConnectionUpdate(
- id, source == SOURCE_LOCAL ? "removeStream" : "onRemoveStream",
- SerializeMediaDescriptor(stream));
+ std::string callback_type;
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ callback_type = "transceiver";
+ } else if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ callback_type = "sender";
+ } else {
+ callback_type = "receiver";
+ }
+ callback_type += callback_type_ending;
+
+ std::string result;
+ result += "Caused by: ";
+ result += GetTransceiverUpdatedReasonString(reason);
+ result += "\n\n";
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ result += "getTransceivers()";
+ } else if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ result += "getSenders()";
+ } else {
+ DCHECK_EQ(
+ transceiver.ImplementationType(),
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ result += "getReceivers()";
+ }
+ result += "[" + base::UintToString(transceiver_index) + "]:";
+ result += SerializeTransceiver(transceiver);
+ SendPeerConnectionUpdate(id, callback_type, result);
}
void PeerConnectionTracker::TrackCreateDataChannel(
@@ -664,8 +803,8 @@ void PeerConnectionTracker::TrackStop(RTCPeerConnectionHandler* pc_handler) {
}
void PeerConnectionTracker::TrackSignalingStateChange(
- RTCPeerConnectionHandler* pc_handler,
- WebRTCPeerConnectionHandlerClient::SignalingState state) {
+ RTCPeerConnectionHandler* pc_handler,
+ webrtc::PeerConnectionInterface::SignalingState state) {
DCHECK(main_thread_.CalledOnValidThread());
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
@@ -779,11 +918,11 @@ int PeerConnectionTracker::GetLocalIDForHandler(
void PeerConnectionTracker::SendPeerConnectionUpdate(
int local_id,
- const char* callback_type,
+ const std::string& callback_type,
const std::string& value) {
DCHECK(main_thread_.CalledOnValidThread());
GetPeerConnectionTrackerHost().get()->UpdatePeerConnection(
- local_id, std::string(callback_type), value);
+ local_id, callback_type, value);
}
void PeerConnectionTracker::OverrideSendTargetForTesting(RenderThread* target) {
@@ -797,6 +936,6 @@ PeerConnectionTracker::GetPeerConnectionTrackerHost() {
&peer_connection_tracker_host_ptr_);
}
return peer_connection_tracker_host_ptr_;
-};
+}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker.h b/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
index 0c35de2047e..24e0fd85e1c 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
@@ -16,6 +16,7 @@
#include "ipc/ipc_platform_file.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_session_description.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
@@ -60,6 +61,16 @@ class CONTENT_EXPORT PeerConnectionTracker
ACTION_CREATE_ANSWER
};
+ // In Plan B: "Transceiver" refers to RTCRtpSender or RTCRtpReceiver.
+ // In Unified Plan: "Transceiver" refers to RTCRtpTransceiver.
+ enum class TransceiverUpdatedReason {
+ kAddTransceiver,
+ kAddTrack,
+ kRemoveTrack,
+ kSetLocalDescription,
+ kSetRemoteDescription,
+ };
+
// RenderThreadObserver implementation.
bool OnControlMessageReceived(const IPC::Message& message) override;
@@ -116,15 +127,31 @@ class CONTENT_EXPORT PeerConnectionTracker
Source source,
bool succeeded);
- // Sends an update when a media stream is added.
- virtual void TrackAddStream(
+ // Sends an update when a transceiver is added, modified or removed. This can
+ // happen as a result of any of the methods indicated by |reason|.
+ // In Plan B: |transceiver| refers to its Sender() or Receiver() depending on
+ // ImplementationType(). Example events: "senderAdded", "receiverRemoved".
+ // In Plan B: |transceiver| has a fully implemented ImplementationType().
+ // Example events: "transceiverAdded", "transceiverModified".
+ // See peer_connection_tracker_unittest.cc for expected resulting event
+ // strings.
+ virtual void TrackAddTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream, Source source);
-
- // Sends an update when a media stream is removed.
- virtual void TrackRemoveStream(
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
+ virtual void TrackModifyTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream, Source source);
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
+ // TODO(hbos): When Plan B is removed this is no longer applicable.
+ // https://crbug.com/857004
+ virtual void TrackRemoveTransceiver(
+ RTCPeerConnectionHandler* pc_handler,
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
// Sends an update when a DataChannel is created.
virtual void TrackCreateDataChannel(
@@ -137,7 +164,7 @@ class CONTENT_EXPORT PeerConnectionTracker
// Sends an update when the signaling state of a PeerConnection has changed.
virtual void TrackSignalingStateChange(
RTCPeerConnectionHandler* pc_handler,
- blink::WebRTCPeerConnectionHandlerClient::SignalingState state);
+ webrtc::PeerConnectionInterface::SignalingState state);
// Sends an update when the Ice connection state
// of a PeerConnection has changed.
@@ -180,6 +207,12 @@ class CONTENT_EXPORT PeerConnectionTracker
// is not registered, the return value will be -1.
int GetLocalIDForHandler(RTCPeerConnectionHandler* handler) const;
+ void TrackTransceiver(const char* callback_type_ending,
+ RTCPeerConnectionHandler* pc_handler,
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
+
// IPC Message handler for getting all stats.
void OnGetAllStats();
@@ -211,7 +244,7 @@ class CONTENT_EXPORT PeerConnectionTracker
// |value| - A json serialized string containing all the information for the
// update event.
void SendPeerConnectionUpdate(int local_id,
- const char* callback_type,
+ const std::string& callback_type,
const std::string& value);
RenderThread* SendTarget();
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc b/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
index 647a6462d8c..84865974755 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
@@ -8,6 +8,7 @@
#include "content/common/media/peer_connection_tracker.mojom.h"
#include "content/common/media/peer_connection_tracker_messages.h"
#include "content/public/test/mock_render_thread.h"
+#include "content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h"
#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
@@ -18,11 +19,42 @@
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_rtc_offer_options.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
using ::testing::_;
namespace content {
+const char* kDefaultTransceiverString =
+ "getTransceivers()[0]:{\n"
+ " mid:null,\n"
+ " sender:{\n"
+ " track:'senderTrackId',\n"
+ " streams:['senderStreamId'],\n"
+ " },\n"
+ " receiver:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:['receiverStreamId'],\n"
+ " },\n"
+ " stopped:false,\n"
+ " direction:'sendonly',\n"
+ " currentDirection:null,\n"
+ "}";
+
+const char* kDefaultSenderString =
+ "getSenders()[0]:{\n"
+ " track:'senderTrackId',\n"
+ " streams:['senderStreamId'],\n"
+ "}";
+
+const char* kDefaultReceiverString =
+ "getReceivers()[0]:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:['receiverStreamId'],\n"
+ "}";
+
class MockPeerConnectionTrackerHost : public mojom::PeerConnectionTrackerHost {
public:
MockPeerConnectionTrackerHost() : binding_(this) {}
@@ -47,7 +79,41 @@ class MockPeerConnectionTrackerHost : public mojom::PeerConnectionTrackerHost {
mojo::AssociatedBinding<mojom::PeerConnectionTrackerHost> binding_;
};
+// Creates a transceiver that is expected to be logged as
+// |kDefaultTransceiverString|, |kDefaultSenderString| or
+// |kDefaultReceiverString| depending on if |implementation_type| refers to a
+// fully implemented, sender-only or receiver-only transceiver.
+//
+// This is used in unittests that don't care about the specific attributes of
+// the transceiver.
+std::unique_ptr<blink::WebRTCRtpTransceiver> CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType implementation_type) {
+ std::unique_ptr<blink::WebRTCRtpTransceiver> transceiver;
+ FakeRTCRtpSender sender("senderTrackId", {"senderStreamId"});
+ FakeRTCRtpReceiver receiver("receiverTrackId", {"receiverStreamId"});
+ if (implementation_type ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ transceiver = std::make_unique<FakeRTCRtpTransceiver>(
+ base::nullopt, std::move(sender), std::move(receiver),
+ false /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendOnly /* direction */,
+ base::nullopt /* current_direction */);
+ } else if (implementation_type ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ transceiver = std::make_unique<RTCRtpSenderOnlyTransceiver>(
+ std::make_unique<FakeRTCRtpSender>(sender));
+ } else {
+ DCHECK_EQ(
+ implementation_type,
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ transceiver = std::make_unique<RTCRtpReceiverOnlyTransceiver>(
+ std::make_unique<FakeRTCRtpReceiver>(receiver));
+ }
+ return transceiver;
+}
+
namespace {
+
class MockSendTargetThread : public MockRenderThread {
public:
MOCK_METHOD1(OnAddPeerConnection, void(PeerConnectionInfo));
@@ -66,6 +132,7 @@ bool MockSendTargetThread::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
+// TODO(https://crbug.com/868868): Move this into a separate file.
class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
public:
MockPeerConnectionHandler()
@@ -81,8 +148,30 @@ class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
};
class PeerConnectionTrackerTest : public ::testing::Test {
- private:
+ public:
+ void CreateTrackerWithMocks() {
+ mock_host_.reset(new MockPeerConnectionTrackerHost());
+ tracker_.reset(
+ new PeerConnectionTracker(mock_host_->CreateInterfacePtrAndBind()));
+ target_thread_.reset(new MockSendTargetThread());
+ tracker_->OverrideSendTargetForTesting(target_thread_.get());
+ }
+
+ void CreateAndRegisterPeerConnectionHandler() {
+ mock_handler_.reset(new MockPeerConnectionHandler());
+ EXPECT_CALL(*target_thread_, OnAddPeerConnection(_));
+ tracker_->RegisterPeerConnection(
+ mock_handler_.get(),
+ webrtc::PeerConnectionInterface::RTCConfiguration(),
+ blink::WebMediaConstraints(), nullptr);
+ }
+
+ protected:
base::MessageLoop message_loop_;
+ std::unique_ptr<MockPeerConnectionTrackerHost> mock_host_;
+ std::unique_ptr<PeerConnectionTracker> tracker_;
+ std::unique_ptr<MockSendTargetThread> target_thread_;
+ std::unique_ptr<MockPeerConnectionHandler> mock_handler_;
};
} // namespace
@@ -92,47 +181,258 @@ TEST_F(PeerConnectionTrackerTest, CreatingObject) {
}
TEST_F(PeerConnectionTrackerTest, TrackCreateOffer) {
- MockPeerConnectionTrackerHost mock_peer_connection_tracker_host;
- PeerConnectionTracker tracker(
- mock_peer_connection_tracker_host.CreateInterfacePtrAndBind());
- // mojom::PeerConnectionTrackerHostAssociatedPtr
- // mock_peer_connection_tracker_host_ptr_
- // = mock_peer_connection_tracker_host.CreateInterfacePtrAndBind();
- // tracker.SetPeerConnectionTrackerHostForTesting(std::move(ptr1));
- // Note: blink::WebRTCOfferOptions is not mockable. So we can't write
- // tests for anything but a null options parameter.
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ // Note: blink::WebRTCOfferOptions is not mockable. So we can't write tests
+ // for anything but a null options parameter.
blink::WebRTCOfferOptions options(0, 0, false, false);
- // Initialization stuff. This can be separated into a test class.
- MockPeerConnectionHandler pc_handler;
- MockSendTargetThread target_thread;
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- blink::WebMediaConstraints constraints;
- tracker.OverrideSendTargetForTesting(&target_thread);
- EXPECT_CALL(target_thread, OnAddPeerConnection(_));
- tracker.RegisterPeerConnection(&pc_handler, config, constraints, nullptr);
- // Back to the test.
- EXPECT_CALL(mock_peer_connection_tracker_host,
+ EXPECT_CALL(*mock_host_,
UpdatePeerConnection(
_, "createOffer",
"options: {offerToReceiveVideo: 0, offerToReceiveAudio: 0, "
"voiceActivityDetection: false, iceRestart: false}"));
- tracker.TrackCreateOffer(&pc_handler, options);
+ tracker_->TrackCreateOffer(mock_handler_.get(), options);
base::RunLoop().RunUntilIdle();
}
TEST_F(PeerConnectionTrackerTest, OnSuspend) {
- PeerConnectionTracker tracker;
- // Initialization stuff.
- MockPeerConnectionHandler pc_handler;
- MockSendTargetThread target_thread;
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- blink::WebMediaConstraints constraints;
- tracker.OverrideSendTargetForTesting(&target_thread);
- EXPECT_CALL(target_thread, OnAddPeerConnection(_));
- tracker.RegisterPeerConnection(&pc_handler, config, constraints, nullptr);
- EXPECT_CALL(pc_handler, CloseClientPeerConnection());
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ EXPECT_CALL(*mock_handler_, CloseClientPeerConnection());
std::unique_ptr<IPC::Message> message(new PeerConnectionTracker_OnSuspend());
- tracker.OnControlMessageReceived(*message.get());
+ tracker_->OnControlMessageReceived(*message.get());
+}
+
+TEST_F(PeerConnectionTrackerTest, AddTransceiverWithOptionalValuesPresent) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ FakeRTCRtpTransceiver transceiver(
+ "midValue", FakeRTCRtpSender("senderTrackId", {"streamIdA", "streamIdB"}),
+ FakeRTCRtpReceiver("receiverTrackId", {"streamIdC"}), true /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendRecv /* direction */,
+ webrtc::RtpTransceiverDirection::kInactive /* current_direction */);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, transceiver,
+ 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: addTrack\n"
+ "\n"
+ "getTransceivers()[0]:{\n"
+ " mid:'midValue',\n"
+ " sender:{\n"
+ " track:'senderTrackId',\n"
+ " streams:['streamIdA','streamIdB'],\n"
+ " },\n"
+ " receiver:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:['streamIdC'],\n"
+ " },\n"
+ " stopped:true,\n"
+ " direction:'sendrecv',\n"
+ " currentDirection:'inactive',\n"
+ "}",
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, AddTransceiverWithOptionalValuesNull) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ FakeRTCRtpTransceiver transceiver(
+ base::nullopt, FakeRTCRtpSender(base::nullopt, {}),
+ FakeRTCRtpReceiver("receiverTrackId", {}), false /* stopped */,
+ webrtc::RtpTransceiverDirection::kInactive /* direction */,
+ base::nullopt /* current_direction */);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTransceiver,
+ transceiver, 1u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: addTransceiver\n"
+ "\n"
+ "getTransceivers()[1]:{\n"
+ " mid:null,\n"
+ " sender:{\n"
+ " track:null,\n"
+ " streams:[],\n"
+ " },\n"
+ " receiver:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:[],\n"
+ " },\n"
+ " stopped:false,\n"
+ " direction:'inactive',\n"
+ " currentDirection:null,\n"
+ "}",
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, ModifyTransceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto transceiver = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverModified", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackModifyTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetLocalDescription,
+ *transceiver, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setLocalDescription\n"
+ "\n" +
+ std::string(kDefaultTransceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, RemoveTransceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto transceiver = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverRemoved", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackRemoveTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack,
+ *transceiver, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: removeTrack\n"
+ "\n" +
+ std::string(kDefaultTransceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, AddSender) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto sender_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "senderAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetLocalDescription,
+ *sender_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setLocalDescription\n"
+ "\n" +
+ std::string(kDefaultSenderString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, ModifySender) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto sender_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "senderModified", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackModifyTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *sender_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultSenderString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, RemoveSender) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto sender_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "senderRemoved", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackRemoveTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *sender_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultSenderString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, AddReceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "receiverAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultReceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, ModifyReceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "receiverModified", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackModifyTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultReceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, RemoveReceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "receiverRemoved", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackRemoveTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultReceiverString),
+ update_value);
}
// TODO(hta): Write tests for the other tracking functions.
diff --git a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc
index 8eb3a817560..4f5ff473c80 100644
--- a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc
@@ -39,7 +39,7 @@ rtc::KeyParams WebRTCKeyParamsToKeyParams(
}
// A certificate generation request spawned by
-// |RTCCertificateGenerator::generateCertificateWithOptionalExpiration|. This
+// |GenerateCertificateWithOptionalExpiration|. This
// is handled by a separate class so that reference counting can keep the
// request alive independently of the |RTCCertificateGenerator| that spawned it.
class RTCCertificateGeneratorRequest
@@ -60,7 +60,7 @@ class RTCCertificateGeneratorRequest
void GenerateCertificateAsync(
const blink::WebRTCKeyParams& key_params,
- const rtc::Optional<uint64_t>& expires_ms,
+ const absl::optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(observer);
@@ -80,7 +80,7 @@ class RTCCertificateGeneratorRequest
void GenerateCertificateOnWorkerThread(
const blink::WebRTCKeyParams key_params,
- const rtc::Optional<uint64_t> expires_ms,
+ const absl::optional<uint64_t> expires_ms,
CertificateCallbackPtr observer) {
DCHECK(worker_thread_->BelongsToCurrentThread());
@@ -114,41 +114,40 @@ class RTCCertificateGeneratorRequest
const scoped_refptr<base::SingleThreadTaskRunner> worker_thread_;
};
-} // namespace
-
-void RTCCertificateGenerator::GenerateCertificate(
+void GenerateCertificateWithOptionalExpiration(
const blink::WebRTCKeyParams& key_params,
+ const absl::optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- generateCertificateWithOptionalExpiration(
- key_params, rtc::Optional<uint64_t>(), std::move(observer), task_runner);
+ DCHECK(WebRTCKeyParamsToKeyParams(key_params).IsValid());
+ PeerConnectionDependencyFactory* pc_dependency_factory =
+ RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
+ pc_dependency_factory->EnsureInitialized();
+
+ scoped_refptr<RTCCertificateGeneratorRequest> request =
+ new RTCCertificateGeneratorRequest(
+ task_runner, pc_dependency_factory->GetWebRtcWorkerThread());
+ request->GenerateCertificateAsync(key_params, expires_ms,
+ std::move(observer));
}
-void RTCCertificateGenerator::GenerateCertificateWithExpiration(
+} // namespace
+
+void RTCCertificateGenerator::GenerateCertificate(
const blink::WebRTCKeyParams& key_params,
- uint64_t expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- generateCertificateWithOptionalExpiration(key_params,
- rtc::Optional<uint64_t>(expires_ms),
+ GenerateCertificateWithOptionalExpiration(key_params, absl::nullopt,
std::move(observer), task_runner);
}
-void RTCCertificateGenerator::generateCertificateWithOptionalExpiration(
+void RTCCertificateGenerator::GenerateCertificateWithExpiration(
const blink::WebRTCKeyParams& key_params,
- const rtc::Optional<uint64_t>& expires_ms,
+ uint64_t expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(IsSupportedKeyParams(key_params));
- PeerConnectionDependencyFactory* pc_dependency_factory =
- RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
- pc_dependency_factory->EnsureInitialized();
-
- scoped_refptr<RTCCertificateGeneratorRequest> request =
- new RTCCertificateGeneratorRequest(
- task_runner, pc_dependency_factory->GetWebRtcWorkerThread());
- request->GenerateCertificateAsync(
- key_params, expires_ms, std::move(observer));
+ GenerateCertificateWithOptionalExpiration(key_params, expires_ms,
+ std::move(observer), task_runner);
}
bool RTCCertificateGenerator::IsSupportedKeyParams(
diff --git a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h
index 248cd21846c..5e29c7f62d4 100644
--- a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h
+++ b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h
@@ -10,7 +10,6 @@
#include "third_party/blink/public/platform/web_rtc_certificate.h"
#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
#include "third_party/blink/public/platform/web_rtc_key_params.h"
-#include "third_party/webrtc/api/optional.h"
namespace content {
@@ -38,12 +37,6 @@ class RTCCertificateGenerator : public blink::WebRTCCertificateGenerator {
blink::WebString pem_certificate) override;
private:
- void generateCertificateWithOptionalExpiration(
- const blink::WebRTCKeyParams& key_params,
- const rtc::Optional<uint64_t>& expires_ms,
- std::unique_ptr<blink::WebRTCCertificateCallback> observer,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
DISALLOW_COPY_AND_ASSIGN(RTCCertificateGenerator);
};
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
index e972ef0a8dd..64bf108735c 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
@@ -18,6 +18,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -36,8 +37,7 @@
#include "content/renderer/media/webrtc/rtc_event_log_output_sink_proxy.h"
#include "content/renderer/media/webrtc/rtc_stats.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
-#include "content/renderer/media/webrtc/webrtc_set_remote_description_observer.h"
+#include "content/renderer/media/webrtc/webrtc_set_description_observer.h"
#include "content/renderer/media/webrtc/webrtc_uma_histograms.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/media_switches.h"
@@ -49,6 +49,7 @@
#include "third_party/blink/public/platform/web_rtc_legacy_stats.h"
#include "third_party/blink/public/platform/web_rtc_offer_options.h"
#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_session_description.h"
#include "third_party/blink/public/platform/web_rtc_session_description_request.h"
#include "third_party/blink/public/platform/web_rtc_void_request.h"
@@ -119,30 +120,6 @@ GetWebKitIceConnectionState(
}
}
-blink::WebRTCPeerConnectionHandlerClient::SignalingState
-GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state) {
- using blink::WebRTCPeerConnectionHandlerClient;
- switch (state) {
- case webrtc::PeerConnectionInterface::kStable:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateStable;
- case webrtc::PeerConnectionInterface::kHaveLocalOffer:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalOffer;
- case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
- return WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveLocalPrAnswer;
- case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateHaveRemoteOffer;
- case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
- return WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveRemotePrAnswer;
- case webrtc::PeerConnectionInterface::kClosed:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateClosed;
- default:
- NOTREACHED();
- return WebRTCPeerConnectionHandlerClient::kSignalingStateClosed;
- }
-}
-
blink::WebRTCSessionDescription CreateWebKitSessionDescription(
const std::string& sdp, const std::string& type) {
blink::WebRTCSessionDescription description;
@@ -257,14 +234,13 @@ void GetNativeRtcConfiguration(
}
switch (blink_config.sdp_semantics) {
- case blink::WebRTCSdpSemantics::kDefault:
case blink::WebRTCSdpSemantics::kPlanB:
webrtc_config->sdp_semantics = webrtc::SdpSemantics::kPlanB;
break;
case blink::WebRTCSdpSemantics::kUnifiedPlan:
webrtc_config->sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
break;
- default:
+ case blink::WebRTCSdpSemantics::kDefault:
NOTREACHED();
}
@@ -279,6 +255,16 @@ void GetNativeRtcConfiguration(
webrtc_config->ice_candidate_pool_size = blink_config.ice_candidate_pool_size;
}
+absl::optional<bool> ConstraintToOptional(
+ const blink::WebMediaConstraints& constraints,
+ const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker) {
+ bool value;
+ if (GetConstraintValueAsBoolean(constraints, picker, &value)) {
+ return absl::optional<bool>(value);
+ }
+ return absl::nullopt;
+}
+
void CopyConstraintsIntoRtcConfiguration(
const blink::WebMediaConstraints constraints,
webrtc::PeerConnectionInterface::RTCConfiguration* configuration) {
@@ -329,7 +315,7 @@ void CopyConstraintsIntoRtcConfiguration(
constraints,
&blink::WebMediaTrackConstraintSet::goog_screencast_min_bitrate,
&rate)) {
- configuration->screencast_min_bitrate = rtc::Optional<int>(rate);
+ configuration->screencast_min_bitrate = rate;
}
configuration->combined_audio_video_bwe = ConstraintToOptional(
constraints,
@@ -338,42 +324,6 @@ void CopyConstraintsIntoRtcConfiguration(
constraints, &blink::WebMediaTrackConstraintSet::enable_dtls_srtp);
}
-class SessionDescriptionRequestTracker {
- public:
- SessionDescriptionRequestTracker(
- const base::WeakPtr<RTCPeerConnectionHandler>& handler,
- const base::WeakPtr<PeerConnectionTracker>& tracker,
- PeerConnectionTracker::Action action)
- : handler_(handler), tracker_(tracker), action_(action) {}
-
- void TrackOnSuccess(const webrtc::SessionDescriptionInterface* desc) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (tracker_ && handler_) {
- std::string value;
- if (desc) {
- desc->ToString(&value);
- value = "type: " + desc->type() + ", sdp: " + value;
- }
- tracker_->TrackSessionDescriptionCallback(
- handler_.get(), action_, "OnSuccess", value);
- }
- }
-
- void TrackOnFailure(const webrtc::RTCError& error) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (handler_ && tracker_) {
- tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
- "OnFailure", error.message());
- }
- }
-
- private:
- const base::WeakPtr<RTCPeerConnectionHandler> handler_;
- const base::WeakPtr<PeerConnectionTracker> tracker_;
- PeerConnectionTracker::Action action_;
- base::ThreadChecker thread_checker_;
-};
-
// Class mapping responses from calls to libjingle CreateOffer/Answer and
// the blink::WebRTCSessionDescriptionRequest.
class CreateSessionDescriptionRequest
@@ -387,8 +337,9 @@ class CreateSessionDescriptionRequest
PeerConnectionTracker::Action action)
: main_thread_(main_thread),
webkit_request_(request),
- tracker_(handler, tracker, action) {
- }
+ handler_(handler),
+ tracker_(tracker),
+ action_(action) {}
void OnSuccess(webrtc::SessionDescriptionInterface* desc) override {
if (!main_thread_->BelongsToCurrentThread()) {
@@ -398,7 +349,15 @@ class CreateSessionDescriptionRequest
return;
}
- tracker_.TrackOnSuccess(desc);
+ if (tracker_ && handler_) {
+ std::string value;
+ if (desc) {
+ desc->ToString(&value);
+ value = "type: " + desc->type() + ", sdp: " + value;
+ }
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnSuccess", value);
+ }
webkit_request_.RequestSucceeded(CreateWebKitSessionDescription(desc));
webkit_request_.Reset();
delete desc;
@@ -411,7 +370,10 @@ class CreateSessionDescriptionRequest
return;
}
- tracker_.TrackOnFailure(error);
+ if (handler_ && tracker_) {
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnFailure", error.message());
+ }
// TODO(hta): Convert CreateSessionDescriptionRequest.OnFailure
webkit_request_.RequestFailed(error);
webkit_request_.Reset();
@@ -430,62 +392,9 @@ class CreateSessionDescriptionRequest
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
blink::WebRTCSessionDescriptionRequest webkit_request_;
- SessionDescriptionRequestTracker tracker_;
-};
-
-// Class mapping responses from calls to libjingle SetLocalDescription and a
-// blink::WebRTCVoidRequest.
-class SetLocalDescriptionRequest
- : public webrtc::SetSessionDescriptionObserver {
- public:
- explicit SetLocalDescriptionRequest(
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- const blink::WebRTCVoidRequest& request,
- const base::WeakPtr<RTCPeerConnectionHandler>& handler,
- const base::WeakPtr<PeerConnectionTracker>& tracker,
- PeerConnectionTracker::Action action)
- : main_thread_(main_thread),
- webkit_request_(request),
- tracker_(handler, tracker, action) {}
-
- void OnSuccess() override {
- if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&SetLocalDescriptionRequest::OnSuccess, this));
- return;
- }
- tracker_.TrackOnSuccess(nullptr);
- webkit_request_.RequestSucceeded();
- webkit_request_.Reset();
- }
- void OnFailure(webrtc::RTCError error) override {
- if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&SetLocalDescriptionRequest::OnFailure,
- this, std::move(error)));
- return;
- }
- tracker_.TrackOnFailure(error);
- webkit_request_.RequestFailed(error);
- webkit_request_.Reset();
- }
-
- protected:
- ~SetLocalDescriptionRequest() override {
- // This object is reference counted and its callback methods |OnSuccess| and
- // |OnFailure| will be invoked on libjingle's signaling thread and posted to
- // the main thread. Since the main thread may complete before the signaling
- // thread has deferenced this object there is no guarantee that this object
- // is destructed on the main thread.
- DLOG_IF(ERROR, !webkit_request_.IsNull())
- << "SetLocalDescriptionRequest not completed. Shutting down?";
- }
-
- private:
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- blink::WebRTCVoidRequest webkit_request_;
- SessionDescriptionRequestTracker tracker_;
+ const base::WeakPtr<RTCPeerConnectionHandler> handler_;
+ const base::WeakPtr<PeerConnectionTracker> tracker_;
+ PeerConnectionTracker::Action action_;
};
blink::WebRTCLegacyStatsMemberType
@@ -704,139 +613,6 @@ void GetRTCStatsOnSignalingThread(
RTCStatsCollectorCallbackImpl::Create(main_thread, std::move(callback)));
}
-class PeerConnectionUMAObserver : public webrtc::UMAObserver {
- public:
- PeerConnectionUMAObserver() {}
- ~PeerConnectionUMAObserver() override {}
- void IncrementEnumCounter(webrtc::PeerConnectionEnumCounterType counter_type,
- int counter,
- int counter_max) override {
- switch (counter_type) {
- case webrtc::kEnumCounterAddressFamily:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.IPMetrics", counter,
- counter_max);
- break;
- case webrtc::kEnumCounterIceCandidatePairTypeUdp:
- UMA_HISTOGRAM_EXACT_LINEAR(
- "WebRTC.PeerConnection.CandidatePairType_UDP", counter,
- counter_max);
- break;
- case webrtc::kEnumCounterIceCandidatePairTypeTcp:
- UMA_HISTOGRAM_EXACT_LINEAR(
- "WebRTC.PeerConnection.CandidatePairType_TCP", counter,
- counter_max);
- break;
- case webrtc::kEnumCounterDtlsHandshakeError:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.DtlsHandshakeError",
- counter, counter_max);
- break;
- case webrtc::kEnumCounterIceRestart:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.IceRestartState",
- counter, counter_max);
- break;
- case webrtc::kEnumCounterIceRegathering:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.IceRegatheringReason",
- counter, counter_max);
- break;
- case webrtc::kEnumCounterKeyProtocol:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.KeyProtocol",
- static_cast<webrtc::KeyExchangeProtocolType>(counter),
- webrtc::kEnumCounterKeyProtocolMax);
- break;
- case webrtc::kEnumCounterSdpSemanticNegotiated:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.SdpSemanticNegotiated",
- static_cast<webrtc::SdpSemanticNegotiated>(counter),
- webrtc::kSdpSemanticNegotiatedMax);
- break;
- case webrtc::kEnumCounterKeyProtocolMediaType:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.KeyProtocolByMedia",
- static_cast<webrtc::KeyExchangeProtocolMedia>(counter),
- webrtc::kEnumCounterKeyProtocolMediaTypeMax);
- break;
- case webrtc::kEnumCounterSdpFormatReceived:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.SdpFormatReceived",
- static_cast<webrtc::SdpFormatReceived>(counter),
- webrtc::kSdpFormatReceivedMax);
- break;
- default:
- // The default clause is expected to be reached when new enum types are
- // added.
- break;
- }
- }
-
- void IncrementSparseEnumCounter(
- webrtc::PeerConnectionEnumCounterType counter_type,
- int counter) override {
- switch (counter_type) {
- case webrtc::kEnumCounterAudioSrtpCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
- counter);
- break;
- case webrtc::kEnumCounterAudioSslCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SslCipherSuite.Audio",
- counter);
- break;
- case webrtc::kEnumCounterVideoSrtpCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpCryptoSuite.Video",
- counter);
- break;
- case webrtc::kEnumCounterVideoSslCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SslCipherSuite.Video",
- counter);
- break;
- case webrtc::kEnumCounterDataSrtpCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpCryptoSuite.Data",
- counter);
- break;
- case webrtc::kEnumCounterDataSslCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SslCipherSuite.Data",
- counter);
- break;
- case webrtc::kEnumCounterSrtpUnprotectError:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpUnprotectError",
- counter);
- break;
- case webrtc::kEnumCounterSrtcpUnprotectError:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtcpUnprotectError",
- counter);
- break;
- default:
- // The default clause is expected to reach when new enum types are
- // added.
- break;
- }
- }
-
- void AddHistogramSample(webrtc::PeerConnectionUMAMetricsName type,
- int value) override {
- // Runs on libjingle's signaling thread.
- switch (type) {
- case webrtc::kTimeToConnect:
- UMA_HISTOGRAM_MEDIUM_TIMES(
- "WebRTC.PeerConnection.TimeToConnect",
- base::TimeDelta::FromMilliseconds(value));
- break;
- case webrtc::kNetworkInterfaces_IPv4:
- UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4Interfaces",
- value);
- break;
- case webrtc::kNetworkInterfaces_IPv6:
- UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv6Interfaces",
- value);
- break;
- default:
- // The default clause is expected to reach when new enum types are
- // added.
- break;
- }
- }
-};
-
void ConvertOfferOptionsToWebrtcOfferOptions(
const blink::WebRTCOfferOptions& options,
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions* output) {
@@ -890,15 +666,14 @@ std::set<RTCPeerConnectionHandler*>* GetPeerConnectionHandlers() {
return handlers;
}
-// Counts the number of senders that have |web_stream| as an associated stream.
+// Counts the number of senders that have |stream_id| as an associated stream.
size_t GetLocalStreamUsageCount(
const std::vector<std::unique_ptr<RTCRtpSender>>& rtp_senders,
- const blink::WebMediaStream& web_stream) {
+ const std::string stream_id) {
size_t usage_count = 0;
for (const auto& sender : rtp_senders) {
- for (const auto& stream_ref : sender->stream_refs()) {
- if (stream_ref->adapter().web_stream().UniqueId() ==
- web_stream.UniqueId()) {
+ for (const auto& sender_stream_id : sender->state().stream_ids()) {
+ if (sender_stream_id == stream_id) {
++usage_count;
break;
}
@@ -907,17 +682,16 @@ size_t GetLocalStreamUsageCount(
return usage_count;
}
-// Counts the number of receivers that have |webrtc_stream| as an associated
-// stream.
-size_t GetRemoteStreamUsageCount(
- const std::map<uintptr_t, std::unique_ptr<RTCRtpReceiver>>& rtp_receivers,
- const webrtc::MediaStreamInterface* webrtc_stream) {
- size_t usage_count = 0;
- for (const auto& receiver_entry : rtp_receivers) {
- if (receiver_entry.second->HasStream(webrtc_stream))
- ++usage_count;
+bool IsRemoteStream(
+ const std::vector<std::unique_ptr<RTCRtpReceiver>>& rtp_receivers,
+ const std::string& stream_id) {
+ for (const auto& receiver : rtp_receivers) {
+ for (const auto& receiver_stream_id : receiver->state().stream_ids()) {
+ if (stream_id == receiver_stream_id)
+ return true;
+ }
}
- return usage_count;
+ return false;
}
enum SdpSemanticRequested {
@@ -941,6 +715,13 @@ SdpSemanticRequested GetSdpSemanticRequested(
return kSdpSemanticRequestedDefault;
}
+MediaStreamTrackMetrics::Kind MediaStreamTrackMetricsKind(
+ const blink::WebMediaStreamTrack& track) {
+ return track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio
+ ? MediaStreamTrackMetrics::Kind::kAudio
+ : MediaStreamTrackMetrics::Kind::kVideo;
+}
+
} // namespace
// Implementation of LocalRTCStatsRequest.
@@ -978,175 +759,146 @@ void LocalRTCStatsResponse::addStats(const blink::WebRTCLegacyStats& stats) {
impl_.AddStats(stats);
}
-// Processes the resulting state changes of a SetRemoteDescription call.
-class RTCPeerConnectionHandler::WebRtcSetRemoteDescriptionObserverImpl
- : public WebRtcSetRemoteDescriptionObserver {
+// Processes the resulting state changes of a SetLocalDescription() or
+// SetRemoteDescription() call.
+class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl
+ : public WebRtcSetDescriptionObserver {
public:
- WebRtcSetRemoteDescriptionObserverImpl(
+ WebRtcSetDescriptionObserverImpl(
base::WeakPtr<RTCPeerConnectionHandler> handler,
blink::WebRTCVoidRequest web_request,
base::WeakPtr<PeerConnectionTracker> tracker,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ PeerConnectionTracker::Action action,
+ blink::WebRTCSdpSemantics sdp_semantics)
: handler_(handler),
main_thread_(task_runner),
web_request_(web_request),
- tracker_(tracker) {}
+ tracker_(tracker),
+ action_(action),
+ sdp_semantics_(sdp_semantics) {
+ DCHECK(sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB ||
+ sdp_semantics_ == blink::WebRTCSdpSemantics::kUnifiedPlan);
+ }
- void OnSetRemoteDescriptionComplete(
- webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
- states_or_error) override {
- if (!states_or_error.ok()) {
- auto& error = states_or_error.error();
+ void OnSetDescriptionComplete(
+ webrtc::RTCError error,
+ WebRtcSetDescriptionObserver::States states) override {
+ if (!error.ok()) {
if (tracker_ && handler_) {
- tracker_->TrackSessionDescriptionCallback(
- handler_.get(),
- PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION, "OnFailure",
- error.message());
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnFailure", error.message());
}
web_request_.RequestFailed(error);
web_request_.Reset();
return;
}
- auto& states = states_or_error.value();
if (handler_) {
- // Determine which receivers have been removed before processing the
- // removal as to not invalidate the iterator.
- std::vector<RTCRtpReceiver*> removed_receivers;
- for (auto it = handler_->rtp_receivers_.begin();
- it != handler_->rtp_receivers_.end(); ++it) {
- if (ReceiverWasRemoved(*it->second, states.receiver_states))
- removed_receivers.push_back(it->second.get());
- }
-
- // Update stream states (which tracks belong to which streams).
- for (auto& stream_state : GetStreamStates(states, removed_receivers)) {
- stream_state.stream_ref->adapter().SetTracks(
- std::move(stream_state.track_refs));
+ handler_->OnSignalingChange(states.signaling_state);
+
+ // Process the rest of the state changes differently depending on SDP
+ // semantics.
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ ProcessStateChangesPlanB(std::move(states));
+ } else {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ ProcessStateChangesUnifiedPlan(std::move(states));
}
- // Process the addition of remote receivers/tracks.
- for (auto& receiver_state : states.receiver_states) {
- if (ReceiverWasAdded(receiver_state)) {
- handler_->OnAddRemoteTrack(receiver_state.receiver,
- std::move(receiver_state.track_ref),
- std::move(receiver_state.stream_refs));
- }
- }
- // Process the removal of remote receivers/tracks.
- for (auto* removed_receiver : removed_receivers)
- handler_->OnRemoveRemoteTrack(removed_receiver->webrtc_receiver());
if (tracker_) {
- tracker_->TrackSessionDescriptionCallback(
- handler_.get(),
- PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION, "OnSuccess",
- "");
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnSuccess", "");
}
}
- // Resolve the promise in a post to ensure any events scheduled for
- // dispatching will have fired by the time the promise is resolved.
- // TODO(hbos): Don't schedule/post to fire events/resolve the promise.
- // Instead, do it all synchronously. This must happen as the last step
- // before returning so that all effects of SRD have occurred when the event
- // executes. https://crbug.com/788558
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::WebRtcSetRemoteDescriptionObserverImpl::
- ResolvePromise,
- this));
+ if (action_ == PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION) {
+ // Resolve the promise in a post to ensure any events scheduled for
+ // dispatching will have fired by the time the promise is resolved.
+ // TODO(hbos): Don't schedule/post to fire events/resolve the promise.
+ // Instead, do it all synchronously. This must happen as the last step
+ // before returning so that all effects of SRD have occurred when the
+ // event executes. https://crbug.com/788558
+ main_thread_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RTCPeerConnectionHandler::
+ WebRtcSetDescriptionObserverImpl::ResolvePromise,
+ this));
+ } else {
+ // Resolve promise immediately if we can. https://crbug.com/788558 still
+ // needs to be addressed for "setLocalDescription(answer)" rejecting a
+ // transceiver in Unified Plan, but this is a minor edge-case.
+ ResolvePromise();
+ }
}
private:
- ~WebRtcSetRemoteDescriptionObserverImpl() override {}
-
- // Describes which tracks belong to a stream in terms of AdapterRefs.
- struct StreamState {
- StreamState(
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> stream_ref)
- : stream_ref(std::move(stream_ref)) {}
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> stream_ref;
- std::vector<std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
- track_refs;
- };
+ ~WebRtcSetDescriptionObserverImpl() override {}
void ResolvePromise() {
web_request_.RequestSucceeded();
web_request_.Reset();
}
- bool ReceiverWasAdded(const WebRtcReceiverState& receiver_state) {
- return handler_->rtp_receivers_.find(
- RTCRtpReceiver::getId(receiver_state.receiver.get())) ==
- handler_->rtp_receivers_.end();
+ void ProcessStateChangesPlanB(WebRtcSetDescriptionObserver::States states) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kPlanB);
+ // Determine which receivers have been removed before processing the
+ // removal as to not invalidate the iterator.
+ std::vector<RTCRtpReceiver*> removed_receivers;
+ for (auto it = handler_->rtp_receivers_.begin();
+ it != handler_->rtp_receivers_.end(); ++it) {
+ if (ReceiverWasRemoved(*(*it), states.transceiver_states))
+ removed_receivers.push_back(it->get());
+ }
+
+ // Process the addition of remote receivers/tracks.
+ for (auto& transceiver_state : states.transceiver_states) {
+ if (ReceiverWasAdded(transceiver_state)) {
+ handler_->OnAddReceiverPlanB(transceiver_state.MoveReceiverState());
+ }
+ }
+ // Process the removal of remote receivers/tracks.
+ for (auto* removed_receiver : removed_receivers) {
+ handler_->OnRemoveReceiverPlanB(RTCRtpReceiver::getId(
+ removed_receiver->state().webrtc_receiver().get()));
+ }
}
- bool ReceiverWasRemoved(
- const RTCRtpReceiver& receiver,
- const std::vector<WebRtcReceiverState>& receiver_states) {
- for (const auto& receiver_state : receiver_states) {
- if (receiver_state.receiver == receiver.webrtc_receiver())
+ bool ReceiverWasAdded(const RtpTransceiverState& transceiver_state) {
+ uintptr_t receiver_id = RTCRtpReceiver::getId(
+ transceiver_state.receiver_state()->webrtc_receiver().get());
+ for (const auto& receiver : handler_->rtp_receivers_) {
+ if (receiver->Id() == receiver_id)
return false;
}
return true;
}
- // Determines the stream states from the current state of receivers and the
- // receivers that are about to be removed. Produces a stable order of streams.
- std::vector<StreamState> GetStreamStates(
- const WebRtcSetRemoteDescriptionObserver::States& states,
- const std::vector<RTCRtpReceiver*>& removed_receivers) {
- states.CheckInvariants();
- std::vector<StreamState> stream_states;
- // The receiver's track belongs to all of its streams. A stream may be
- // associated with multiple tracks (multiple receivers).
- for (auto& receiver_state : states.receiver_states) {
- for (auto& stream_ref : receiver_state.stream_refs) {
- CHECK(stream_ref);
- CHECK(stream_ref->adapter().is_initialized());
- CHECK(!stream_ref->adapter().web_stream().IsNull());
- CHECK(stream_ref->adapter().webrtc_stream());
- auto* stream_state =
- GetOrAddStreamStateForStream(*stream_ref, &stream_states);
- auto track_ref = receiver_state.track_ref->Copy();
- CHECK(!track_ref->web_track().IsNull());
- CHECK(track_ref->webrtc_track());
- stream_state->track_refs.push_back(std::move(track_ref));
- }
- }
- // The track of removed receivers do not belong to any stream. Make sure we
- // have a stream state for any streams belonging to receivers about to be
- // removed in case it was the last receiver referencing that stream.
- for (auto* removed_receiver : removed_receivers) {
- for (auto& stream_ref : removed_receiver->StreamAdapterRefs()) {
- CHECK(!stream_ref->adapter().web_stream().IsNull());
- CHECK(stream_ref->adapter().webrtc_stream());
- GetOrAddStreamStateForStream(*stream_ref, &stream_states);
- }
- }
- states.CheckInvariants();
- return stream_states;
- }
-
- StreamState* GetOrAddStreamStateForStream(
- const WebRtcMediaStreamAdapterMap::AdapterRef& stream_ref,
- std::vector<StreamState>* stream_states) {
- auto* webrtc_stream = stream_ref.adapter().webrtc_stream().get();
- for (auto& stream_state : *stream_states) {
- if (stream_state.stream_ref->adapter().webrtc_stream().get() ==
- webrtc_stream) {
- return &stream_state;
+ bool ReceiverWasRemoved(
+ const RTCRtpReceiver& receiver,
+ const std::vector<RtpTransceiverState>& transceiver_states) {
+ for (const auto& transceiver_state : transceiver_states) {
+ if (transceiver_state.receiver_state()->webrtc_receiver() ==
+ receiver.state().webrtc_receiver()) {
+ return false;
}
}
- stream_states->push_back(StreamState(stream_ref.Copy()));
- return &stream_states->back();
+ return true;
+ }
+
+ void ProcessStateChangesUnifiedPlan(
+ WebRtcSetDescriptionObserver::States states) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ handler_->OnModifyTransceivers(
+ std::move(states.transceiver_states),
+ action_ == PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION);
}
base::WeakPtr<RTCPeerConnectionHandler> handler_;
scoped_refptr<base::SequencedTaskRunner> main_thread_;
blink::WebRTCVoidRequest web_request_;
base::WeakPtr<PeerConnectionTracker> tracker_;
+ PeerConnectionTracker::Action action_;
+ blink::WebRTCSdpSemantics sdp_semantics_;
};
// Receives notifications from a PeerConnection object about state changes. The
@@ -1181,19 +933,8 @@ class RTCPeerConnectionHandler::Observer
friend class base::RefCountedThreadSafe<RTCPeerConnectionHandler::Observer>;
~Observer() override = default;
- void OnSignalingChange(
- PeerConnectionInterface::SignalingState new_state) override {
- if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCPeerConnectionHandler::Observer::OnSignalingChange,
- this, new_state));
- } else if (handler_) {
- handler_->OnSignalingChange(new_state);
- }
- }
-
// TODO(hbos): Remove once no longer mandatory to implement.
+ void OnSignalingChange(PeerConnectionInterface::SignalingState) override {}
void OnAddStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
@@ -1293,9 +1034,8 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
track_adapter_map_(
new WebRtcMediaStreamTrackAdapterMap(dependency_factory_,
task_runner)),
- stream_adapter_map_(new WebRtcMediaStreamAdapterMap(dependency_factory_,
- task_runner,
- track_adapter_map_)),
+ // This will be overwritten to the actual value used at Initialize().
+ sdp_semantics_(blink::WebRTCSdpSemantics::kDefault),
task_runner_(std::move(task_runner)),
weak_factory_(this) {
CHECK(client_);
@@ -1304,7 +1044,7 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
}
RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
Stop();
@@ -1317,15 +1057,16 @@ RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
}
void RTCPeerConnectionHandler::associateWithFrame(blink::WebLocalFrame* frame) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(frame);
frame_ = frame;
}
bool RTCPeerConnectionHandler::Initialize(
const blink::WebRTCConfiguration& server_configuration,
- const blink::WebMediaConstraints& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ const blink::WebMediaConstraints& options,
+ blink::WebRTCSdpSemantics original_sdp_semantics_value) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(frame_);
CHECK(!initialize_called_);
@@ -1334,6 +1075,9 @@ bool RTCPeerConnectionHandler::Initialize(
peer_connection_tracker_ =
RenderThreadImpl::current()->peer_connection_tracker()->AsWeakPtr();
+ sdp_semantics_ = server_configuration.sdp_semantics;
+ DCHECK(sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB ||
+ sdp_semantics_ == blink::WebRTCSdpSemantics::kUnifiedPlan);
GetNativeRtcConfiguration(server_configuration, &configuration_);
// Choose between RTC smoothness algorithm and prerenderer smoothing.
@@ -1363,12 +1107,9 @@ bool RTCPeerConnectionHandler::Initialize(
options, frame_);
}
- uma_observer_ = new rtc::RefCountedObject<PeerConnectionUMAObserver>();
- native_peer_connection_->RegisterUMAObserver(uma_observer_.get());
-
UMA_HISTOGRAM_ENUMERATION(
"WebRTC.PeerConnection.SdpSemanticRequested",
- GetSdpSemanticRequested(server_configuration.sdp_semantics),
+ GetSdpSemanticRequested(original_sdp_semantics_value),
kSdpSemanticRequestedMax);
return true;
@@ -1378,11 +1119,14 @@ bool RTCPeerConnectionHandler::InitializeForTest(
const blink::WebRTCConfiguration& server_configuration,
const blink::WebMediaConstraints& options,
const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
CHECK(!initialize_called_);
initialize_called_ = true;
+ sdp_semantics_ = server_configuration.sdp_semantics;
+ DCHECK(sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB ||
+ sdp_semantics_ == blink::WebRTCSdpSemantics::kUnifiedPlan);
GetNativeRtcConfiguration(server_configuration, &configuration_);
peer_connection_observer_ =
@@ -1402,7 +1146,7 @@ bool RTCPeerConnectionHandler::InitializeForTest(
void RTCPeerConnectionHandler::CreateOffer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebMediaConstraints& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createOffer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
@@ -1424,7 +1168,7 @@ void RTCPeerConnectionHandler::CreateOffer(
void RTCPeerConnectionHandler::CreateOffer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebRTCOfferOptions& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createOffer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
@@ -1446,7 +1190,7 @@ void RTCPeerConnectionHandler::CreateOffer(
void RTCPeerConnectionHandler::CreateAnswer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebMediaConstraints& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
@@ -1466,7 +1210,7 @@ void RTCPeerConnectionHandler::CreateAnswer(
void RTCPeerConnectionHandler::CreateAnswer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebRTCAnswerOptions& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
@@ -1491,7 +1235,7 @@ bool IsOfferOrAnswer(const webrtc::SessionDescriptionInterface* native_desc) {
void RTCPeerConnectionHandler::SetLocalDescription(
const blink::WebRTCVoidRequest& request,
const blink::WebRTCSessionDescription& description) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setLocalDescription");
std::string sdp = description.Sdp().Utf8();
@@ -1532,18 +1276,27 @@ void RTCPeerConnectionHandler::SetLocalDescription(
}
}
- scoped_refptr<SetLocalDescriptionRequest> set_request(
- new rtc::RefCountedObject<SetLocalDescriptionRequest>(
- task_runner_, request, weak_factory_.GetWeakPtr(),
- peer_connection_tracker_,
- PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
+ scoped_refptr<WebRtcSetDescriptionObserverImpl> content_observer(
+ new WebRtcSetDescriptionObserverImpl(
+ weak_factory_.GetWeakPtr(), request, peer_connection_tracker_,
+ task_runner_, PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION,
+ sdp_semantics_));
+
+ bool surface_receivers_only =
+ (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB);
+ scoped_refptr<webrtc::SetSessionDescriptionObserver> webrtc_observer(
+ WebRtcSetLocalDescriptionObserverHandler::Create(
+ task_runner_, signaling_thread(), native_peer_connection_,
+ track_adapter_map_, content_observer, surface_receivers_only)
+ .get());
signaling_thread()->PostTask(
FROM_HERE,
base::BindOnce(
&RunClosureWithTrace,
base::Bind(&webrtc::PeerConnectionInterface::SetLocalDescription,
- native_peer_connection_, base::RetainedRef(set_request),
+ native_peer_connection_,
+ base::RetainedRef(webrtc_observer),
base::Unretained(native_desc)),
"SetLocalDescription"));
}
@@ -1551,7 +1304,7 @@ void RTCPeerConnectionHandler::SetLocalDescription(
void RTCPeerConnectionHandler::SetRemoteDescription(
const blink::WebRTCVoidRequest& request,
const blink::WebRTCSessionDescription& description) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setRemoteDescription");
std::string sdp = description.Sdp().Utf8();
std::string type = description.GetType().Utf8();
@@ -1592,15 +1345,19 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
}
}
- scoped_refptr<WebRtcSetRemoteDescriptionObserverImpl> content_observer(
- new WebRtcSetRemoteDescriptionObserverImpl(
+ scoped_refptr<WebRtcSetDescriptionObserverImpl> content_observer(
+ new WebRtcSetDescriptionObserverImpl(
weak_factory_.GetWeakPtr(), request, peer_connection_tracker_,
- task_runner_));
+ task_runner_, PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION,
+ sdp_semantics_));
+ bool surface_receivers_only =
+ (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB);
rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>
webrtc_observer(WebRtcSetRemoteDescriptionObserverHandler::Create(
- task_runner_, native_peer_connection_,
- stream_adapter_map_, content_observer)
+ task_runner_, signaling_thread(),
+ native_peer_connection_, track_adapter_map_,
+ content_observer, surface_receivers_only)
.get());
signaling_thread()->PostTask(
@@ -1619,7 +1376,7 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
}
blink::WebRTCSessionDescription RTCPeerConnectionHandler::LocalDescription() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::localDescription");
// Since local_description returns a pointer to a non-reference-counted object
@@ -1640,7 +1397,7 @@ blink::WebRTCSessionDescription RTCPeerConnectionHandler::LocalDescription() {
}
blink::WebRTCSessionDescription RTCPeerConnectionHandler::RemoteDescription() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::remoteDescription");
// 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
@@ -1661,7 +1418,7 @@ blink::WebRTCSessionDescription RTCPeerConnectionHandler::RemoteDescription() {
webrtc::RTCErrorType RTCPeerConnectionHandler::SetConfiguration(
const blink::WebRTCConfiguration& blink_config) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setConfiguration");
GetNativeRtcConfiguration(blink_config, &configuration_);
@@ -1680,7 +1437,7 @@ webrtc::RTCErrorType RTCPeerConnectionHandler::SetConfiguration(
bool RTCPeerConnectionHandler::AddICECandidate(
const blink::WebRTCVoidRequest& request,
scoped_refptr<blink::WebRTCICECandidate> candidate) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
// Libjingle currently does not accept callbacks for addICECandidate.
// For that reason we are going to call callbacks from here.
@@ -1698,7 +1455,7 @@ bool RTCPeerConnectionHandler::AddICECandidate(
bool RTCPeerConnectionHandler::AddICECandidate(
scoped_refptr<blink::WebRTCICECandidate> candidate) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
dependency_factory_->CreateIceCandidate(candidate->SdpMid().Utf8(),
@@ -1724,7 +1481,7 @@ bool RTCPeerConnectionHandler::AddICECandidate(
void RTCPeerConnectionHandler::OnaddICECandidateResult(
const blink::WebRTCVoidRequest& webkit_request, bool result) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnaddICECandidateResult");
if (!result) {
// We don't have the actual error code from the libjingle, so for now
@@ -1739,7 +1496,7 @@ void RTCPeerConnectionHandler::OnaddICECandidateResult(
void RTCPeerConnectionHandler::GetStats(
const blink::WebRTCStatsRequest& request) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<LocalRTCStatsRequest> inner_request(
new rtc::RefCountedObject<LocalRTCStatsRequest>(request));
getStats(inner_request);
@@ -1747,7 +1504,7 @@ void RTCPeerConnectionHandler::GetStats(
void RTCPeerConnectionHandler::getStats(
const scoped_refptr<LocalRTCStatsRequest>& request) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::getStats");
rtc::scoped_refptr<webrtc::StatsObserver> observer(
@@ -1777,7 +1534,7 @@ void RTCPeerConnectionHandler::GetStats(
webrtc::StatsObserver* observer,
webrtc::PeerConnectionInterface::StatsOutputLevel level,
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> selector) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
signaling_thread()->PostTask(
FROM_HERE,
base::BindOnce(&GetStatsOnSignalingThread, native_peer_connection_, level,
@@ -1786,96 +1543,347 @@ void RTCPeerConnectionHandler::GetStats(
void RTCPeerConnectionHandler::GetStats(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
signaling_thread()->PostTask(
FROM_HERE, base::BindOnce(&GetRTCStatsOnSignalingThread, task_runner_,
native_peer_connection_, std::move(callback)));
}
-std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::AddTransceiverWithTrack(
+ const blink::WebMediaStreamTrack& web_track,
+ const webrtc::RtpTransceiverInit& init) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
+ track_adapter_map_->GetOrCreateLocalTrackAdapter(web_track);
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ error_or_transceiver;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(
+ &RTCPeerConnectionHandler::AddTransceiverWithTrackOnSignalingThread,
+ base::Unretained(this), base::RetainedRef(track_ref->webrtc_track()),
+ base::ConstRef(init), base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&error_or_transceiver)),
+ "AddTransceiverWithTrackOnSignalingThread");
+ if (!error_or_transceiver.ok()) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ return error_or_transceiver.MoveError();
+ }
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ auto transceiver =
+ CreateOrUpdateTransceiver(std::move(transceiver_states[0]));
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver =
+ std::move(transceiver);
+ return std::move(web_transceiver);
+}
+
+void RTCPeerConnectionHandler::AddTransceiverWithTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver) {
+ *error_or_transceiver =
+ native_peer_connection_->AddTransceiver(webrtc_track, init);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (error_or_transceiver->ok())
+ transceivers.push_back(error_or_transceiver->value());
+ transceiver_state_surfacer->Initialize(track_adapter_map_, transceivers);
+}
+
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::AddTransceiverWithKind(
+ std::string kind,
+ const webrtc::RtpTransceiverInit& init) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ cricket::MediaType media_type;
+ if (kind == webrtc::MediaStreamTrackInterface::kAudioKind) {
+ media_type = cricket::MEDIA_TYPE_AUDIO;
+ } else {
+ DCHECK_EQ(kind, webrtc::MediaStreamTrackInterface::kVideoKind);
+ media_type = cricket::MEDIA_TYPE_VIDEO;
+ }
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ error_or_transceiver;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(&RTCPeerConnectionHandler::
+ AddTransceiverWithMediaTypeOnSignalingThread,
+ base::Unretained(this), base::ConstRef(media_type),
+ base::ConstRef(init),
+ base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&error_or_transceiver)),
+ "AddTransceiverWithMediaTypeOnSignalingThread");
+ if (!error_or_transceiver.ok()) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ return error_or_transceiver.MoveError();
+ }
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ auto transceiver =
+ CreateOrUpdateTransceiver(std::move(transceiver_states[0]));
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver =
+ std::move(transceiver);
+ return std::move(web_transceiver);
+}
+
+void RTCPeerConnectionHandler::AddTransceiverWithMediaTypeOnSignalingThread(
+ cricket::MediaType media_type,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver) {
+ *error_or_transceiver =
+ native_peer_connection_->AddTransceiver(media_type, init);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (error_or_transceiver->ok())
+ transceivers.push_back(error_or_transceiver->value());
+ transceiver_state_surfacer->Initialize(track_adapter_map_, transceivers);
+}
+
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::AddTrack(
const blink::WebMediaStreamTrack& track,
const blink::WebVector<blink::WebMediaStream>& streams) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::AddTrack");
- // Get or create the associated track and stream adapters.
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter =
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
track_adapter_map_->GetOrCreateLocalTrackAdapter(track);
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapters(streams.size());
- std::vector<webrtc::MediaStreamInterface*> webrtc_streams(streams.size());
- for (size_t i = 0; i < streams.size(); ++i) {
- stream_adapters[i] =
- stream_adapter_map_->GetOrCreateLocalStreamAdapter(streams[i]);
- webrtc_streams[i] = stream_adapters[i]->adapter().webrtc_stream().get();
- }
-
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender =
- native_peer_connection_->AddTrack(track_adapter->webrtc_track(),
- webrtc_streams);
- if (!webrtc_sender)
- return nullptr;
- DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender)) == rtp_senders_.end());
- rtp_senders_.push_back(std::make_unique<RTCRtpSender>(
- native_peer_connection_, task_runner_, signaling_thread(),
- stream_adapter_map_, std::move(webrtc_sender), std::move(track_adapter),
- std::move(stream_adapters)));
- for (const auto& stream_ref : rtp_senders_.back()->stream_refs()) {
- if (GetLocalStreamUsageCount(rtp_senders_,
- stream_ref->adapter().web_stream()) == 1u) {
+ std::vector<std::string> stream_ids(streams.size());
+ for (size_t i = 0; i < streams.size(); ++i)
+ stream_ids[i] = streams[i].Id().Utf8();
+
+ // Invoke native AddTrack() on the signaling thread and surface the resulting
+ // transceiver (Plan B: sender only).
+ // TODO(hbos): Implement and surface full transceiver support under Unified
+ // Plan. https://crbug.com/777617
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>
+ error_or_sender;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(
+ &RTCPeerConnectionHandler::AddTrackOnSignalingThread,
+ base::Unretained(this), base::RetainedRef(track_ref->webrtc_track()),
+ std::move(stream_ids), base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&error_or_sender)),
+ "AddTrackOnSignalingThread");
+ DCHECK(transceiver_state_surfacer.is_initialized());
+ if (!error_or_sender.ok()) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ return error_or_sender.MoveError();
+ }
+ track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetricsKind(track),
+ track.Id().Utf8());
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ DCHECK_EQ(transceiver_states.size(), 1u);
+ auto transceiver_state = std::move(transceiver_states[0]);
+
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver;
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ // Plan B: Create sender only.
+ DCHECK(transceiver_state.sender_state());
+ auto webrtc_sender = transceiver_state.sender_state()->webrtc_sender();
+ DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender.get())) ==
+ rtp_senders_.end());
+ RtpSenderState sender_state = transceiver_state.MoveSenderState();
+ DCHECK(sender_state.is_initialized());
+ rtp_senders_.push_back(std::make_unique<RTCRtpSender>(
+ native_peer_connection_, track_adapter_map_, std::move(sender_state)));
+ web_transceiver = std::make_unique<RTCRtpSenderOnlyTransceiver>(
+ std::make_unique<RTCRtpSender>(*rtp_senders_.back().get()));
+ } else {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ // Unified Plan: Create or recycle a transceiver.
+ auto transceiver = CreateOrUpdateTransceiver(std::move(transceiver_state));
+ web_transceiver = std::move(transceiver);
+ }
+ if (peer_connection_tracker_) {
+ size_t transceiver_index = GetTransceiverIndex(*web_transceiver.get());
+ peer_connection_tracker_->TrackAddTransceiver(
+ this, PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack,
+ *web_transceiver.get(), transceiver_index);
+ }
+ for (const auto& stream_id : rtp_senders_.back()->state().stream_ids()) {
+ if (GetLocalStreamUsageCount(rtp_senders_, stream_id) == 1u) {
// This is the first occurrence of this stream.
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackAddStream(
- this, stream_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_LOCAL);
- }
PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
- track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM,
- stream_ref->adapter().webrtc_stream().get());
}
}
- return rtp_senders_.back()->ShallowCopy();
+ return web_transceiver;
+}
+
+void RTCPeerConnectionHandler::AddTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>*
+ error_or_sender) {
+ *error_or_sender = native_peer_connection_->AddTrack(track, stream_ids);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (error_or_sender->ok()) {
+ auto sender = error_or_sender->value();
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ transceivers = {new SurfaceSenderStateOnly(sender)};
+ } else {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface>
+ transceiver_for_sender = nullptr;
+ for (const auto& transceiver :
+ native_peer_connection_->GetTransceivers()) {
+ if (transceiver->sender() == sender) {
+ transceiver_for_sender = transceiver;
+ break;
+ }
+ }
+ DCHECK(transceiver_for_sender);
+ transceivers = {transceiver_for_sender};
+ }
+ }
+ transceiver_state_surfacer->Initialize(track_adapter_map_,
+ std::move(transceivers));
}
-bool RTCPeerConnectionHandler::RemoveTrack(blink::WebRTCRtpSender* web_sender) {
- DCHECK(thread_checker_.CalledOnValidThread());
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::RemoveTrack(blink::WebRTCRtpSender* web_sender) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::RemoveTrack");
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ if (RemoveTrackPlanB(web_sender)) {
+ // In Plan B, null indicates success.
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver = nullptr;
+ return std::move(web_transceiver);
+ }
+ // TODO(hbos): Surface RTCError from third_party/webrtc when
+ // peerconnectioninterface.h is updated. https://crbug.com/webrtc/9534
+ return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE);
+ }
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ return RemoveTrackUnifiedPlan(web_sender);
+}
+
+bool RTCPeerConnectionHandler::RemoveTrackPlanB(
+ blink::WebRTCRtpSender* web_sender) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kPlanB);
+ auto web_track = web_sender->Track();
auto it = FindSender(web_sender->Id());
if (it == rtp_senders_.end())
return false;
if (!(*it)->RemoveFromPeerConnection(native_peer_connection_.get()))
return false;
- auto stream_refs = (*it)->stream_refs();
- // TODO(hbos): In Unified Plan, senders are never removed. The lower layer
- // needs to tell us what to do with the sender: Update its states and/or
- // remove it. https://crbug.com/799030
+ track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetricsKind(web_track),
+ web_track.Id().Utf8());
+ if (peer_connection_tracker_) {
+ auto sender_only_transceiver =
+ std::make_unique<RTCRtpSenderOnlyTransceiver>(
+ std::make_unique<RTCRtpSender>(*it->get()));
+ size_t sender_index = GetTransceiverIndex(*sender_only_transceiver);
+ peer_connection_tracker_->TrackRemoveTransceiver(
+ this, PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack,
+ *sender_only_transceiver.get(), sender_index);
+ }
+ std::vector<std::string> stream_ids = (*it)->state().stream_ids();
rtp_senders_.erase(it);
- for (const auto& stream_ref : stream_refs) {
- if (GetLocalStreamUsageCount(rtp_senders_,
- stream_ref->adapter().web_stream()) == 0u) {
+ for (const auto& stream_id : stream_ids) {
+ if (GetLocalStreamUsageCount(rtp_senders_, stream_id) == 0u) {
// This was the last occurrence of this stream.
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackRemoveStream(
- this, stream_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_LOCAL);
- }
PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
- track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM,
- stream_ref->adapter().webrtc_stream().get());
}
}
return true;
}
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::RemoveTrackUnifiedPlan(
+ blink::WebRTCRtpSender* web_sender) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ auto it = FindSender(web_sender->Id());
+ if (it == rtp_senders_.end())
+ return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER);
+ const auto& sender = *it;
+ auto webrtc_sender = sender->state().webrtc_sender();
+
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ bool result;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(
+ &RTCPeerConnectionHandler::RemoveTrackUnifiedPlanOnSignalingThread,
+ base::Unretained(this), base::RetainedRef(webrtc_sender),
+ base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&result)),
+ "RemoveTrackUnifiedPlanOnSignalingThread");
+ DCHECK(transceiver_state_surfacer.is_initialized());
+ if (!result) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ // TODO(hbos): Surface RTCError from third_party/webrtc when
+ // peerconnectioninterface.h is updated. https://crbug.com/webrtc/9534
+ return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR);
+ }
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ DCHECK_EQ(transceiver_states.size(), 1u);
+ auto transceiver_state = std::move(transceiver_states[0]);
+
+ // Update the transceiver.
+ auto transceiver = CreateOrUpdateTransceiver(std::move(transceiver_state));
+ if (peer_connection_tracker_) {
+ size_t transceiver_index = GetTransceiverIndex(*transceiver);
+ peer_connection_tracker_->TrackModifyTransceiver(
+ this, PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack,
+ *transceiver.get(), transceiver_index);
+ }
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver =
+ std::move(transceiver);
+ return web_transceiver;
+}
+
+void RTCPeerConnectionHandler::RemoveTrackUnifiedPlanOnSignalingThread(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ bool* result) {
+ *result = native_peer_connection_->RemoveTrack(sender);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (*result) {
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver_for_sender =
+ nullptr;
+ for (const auto& transceiver : native_peer_connection_->GetTransceivers()) {
+ if (transceiver->sender() == sender) {
+ transceiver_for_sender = transceiver;
+ break;
+ }
+ }
+ DCHECK(transceiver_for_sender);
+ transceivers = {transceiver_for_sender};
+ }
+ transceiver_state_surfacer->Initialize(track_adapter_map_,
+ std::move(transceivers));
+}
+
void RTCPeerConnectionHandler::CloseClientPeerConnection() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (!is_closed_)
client_->ClosePeerConnection();
}
void RTCPeerConnectionHandler::StartEventLog(IPC::PlatformFileForTransit file,
int64_t max_file_size_bytes) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(file != IPC::InvalidPlatformFileForTransit());
// TODO(eladalon): StartRtcEventLog() return value is not useful; remove it
// or find a way to be able to use it.
@@ -1885,7 +1893,7 @@ void RTCPeerConnectionHandler::StartEventLog(IPC::PlatformFileForTransit file,
}
void RTCPeerConnectionHandler::StartEventLog() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
// TODO(eladalon): StartRtcEventLog() return value is not useful; remove it
// or find a way to be able to use it.
// https://crbug.com/775415
@@ -1896,13 +1904,13 @@ void RTCPeerConnectionHandler::StartEventLog() {
}
void RTCPeerConnectionHandler::StopEventLog() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
native_peer_connection_->StopRtcEventLog();
}
void RTCPeerConnectionHandler::OnWebRtcEventLogWrite(
const std::string& output) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackRtcEventLogWrite(this, output);
}
@@ -1911,7 +1919,7 @@ void RTCPeerConnectionHandler::OnWebRtcEventLogWrite(
blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::CreateDataChannel(
const blink::WebString& label,
const blink::WebRTCDataChannelInit& init) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createDataChannel");
DVLOG(1) << "createDataChannel label " << label.Utf8();
@@ -1943,7 +1951,7 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::CreateDataChannel(
}
void RTCPeerConnectionHandler::Stop() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DVLOG(1) << "RTCPeerConnectionHandler::stop";
if (is_closed_ || !native_peer_connection_.get())
@@ -1964,22 +1972,20 @@ blink::WebString RTCPeerConnectionHandler::Id() const {
void RTCPeerConnectionHandler::OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnSignalingChange");
- blink::WebRTCPeerConnectionHandlerClient::SignalingState state =
- GetWebKitSignalingState(new_state);
if (peer_connection_tracker_)
- peer_connection_tracker_->TrackSignalingStateChange(this, state);
+ peer_connection_tracker_->TrackSignalingStateChange(this, new_state);
if (!is_closed_)
- client_->DidChangeSignalingState(state);
+ client_->DidChangeSignalingState(new_state);
}
// Called any time the IceConnectionState changes
void RTCPeerConnectionHandler::OnIceConnectionChange(
webrtc::PeerConnectionInterface::IceConnectionState new_state) {
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceConnectionChange");
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
ReportICEState(new_state);
if (new_state == webrtc::PeerConnectionInterface::kIceConnectionChecking) {
ice_connection_checking_start_ = base::TimeTicks::Now();
@@ -2014,7 +2020,7 @@ void RTCPeerConnectionHandler::OnIceConnectionChange(
// Called any time the IceGatheringState changes
void RTCPeerConnectionHandler::OnIceGatheringChange(
webrtc::PeerConnectionInterface::IceGatheringState new_state) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceGatheringChange");
if (new_state == webrtc::PeerConnectionInterface::kIceGatheringComplete) {
@@ -2039,7 +2045,7 @@ void RTCPeerConnectionHandler::OnIceGatheringChange(
}
void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRenegotiationNeeded");
if (peer_connection_tracker_)
peer_connection_tracker_->TrackOnRenegotiationNeeded(this);
@@ -2047,89 +2053,129 @@ void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
client_->NegotiationNeeded();
}
-void RTCPeerConnectionHandler::OnAddRemoteTrack(
- scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- remote_track_adapter_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- remote_stream_adapter_refs) {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddRemoteTrack");
-
- for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) {
+void RTCPeerConnectionHandler::OnAddReceiverPlanB(
+ RtpReceiverState receiver_state) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(receiver_state.is_initialized());
+ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddReceiverPlanB");
+ auto web_track = receiver_state.track_ref()->web_track();
+ // Update metrics.
+ track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetricsKind(web_track),
+ web_track.Id().Utf8());
+ for (const auto& stream_id : receiver_state.stream_ids()) {
// New remote stream?
- if (GetRemoteStreamUsageCount(
- rtp_receivers_,
- remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) {
- // Update metrics.
- // TODO(hbos): Update metrics to correspond to track added/removed events,
- // not streams. https://crbug.com/765170
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackAddStream(
- this, remote_stream_adapter_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_REMOTE);
- }
+ if (!IsRemoteStream(rtp_receivers_, stream_id))
PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
- track_metrics_.AddStream(
- MediaStreamTrackMetrics::RECEIVED_STREAM,
- remote_stream_adapter_ref->adapter().webrtc_stream().get());
- }
}
-
- uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get());
- DCHECK(rtp_receivers_.find(receiver_id) == rtp_receivers_.end());
- const std::unique_ptr<RTCRtpReceiver>& rtp_receiver =
- rtp_receivers_
- .insert(std::make_pair(
- receiver_id,
- std::make_unique<RTCRtpReceiver>(
- native_peer_connection_, task_runner_, signaling_thread(),
- webrtc_receiver.get(), std::move(remote_track_adapter_ref),
- std::move(remote_stream_adapter_refs))))
- .first->second;
+ uintptr_t receiver_id =
+ RTCRtpReceiver::getId(receiver_state.webrtc_receiver().get());
+ DCHECK(FindReceiver(receiver_id) == rtp_receivers_.end());
+ auto rtp_receiver = std::make_unique<RTCRtpReceiver>(
+ native_peer_connection_, std::move(receiver_state));
+ rtp_receivers_.push_back(std::make_unique<RTCRtpReceiver>(*rtp_receiver));
+ if (peer_connection_tracker_) {
+ auto receiver_only_transceiver =
+ std::make_unique<RTCRtpReceiverOnlyTransceiver>(
+ std::make_unique<RTCRtpReceiver>(*rtp_receiver));
+ size_t receiver_index = GetTransceiverIndex(*receiver_only_transceiver);
+ peer_connection_tracker_->TrackAddTransceiver(
+ this,
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only_transceiver.get(), receiver_index);
+ }
if (!is_closed_)
- client_->DidAddRemoteTrack(rtp_receiver->ShallowCopy());
+ client_->DidAddReceiverPlanB(rtp_receiver->ShallowCopy());
}
-void RTCPeerConnectionHandler::OnRemoveRemoteTrack(
- scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver) {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveRemoteTrack");
+void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveReceiverPlanB");
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- remote_stream_adapter_refs;
- {
- uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get());
- auto it = rtp_receivers_.find(receiver_id);
- DCHECK(it != rtp_receivers_.end());
- remote_stream_adapter_refs = it->second->StreamAdapterRefs();
- if (!is_closed_)
- client_->DidRemoveRemoteTrack(it->second->ShallowCopy());
- rtp_receivers_.erase(it);
- }
-
- for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) {
- // Was this the last usage of the remote stream?
- if (GetRemoteStreamUsageCount(
- rtp_receivers_,
- remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) {
- // Update metrics.
- track_metrics_.RemoveStream(
- MediaStreamTrackMetrics::RECEIVED_STREAM,
- remote_stream_adapter_ref->adapter().webrtc_stream().get());
- PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackRemoveStream(
- this, remote_stream_adapter_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_REMOTE);
+ auto it = FindReceiver(receiver_id);
+ DCHECK(it != rtp_receivers_.end());
+ auto receiver = std::make_unique<RTCRtpReceiver>(*(*it));
+ // Update metrics.
+ track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetricsKind(receiver->Track()),
+ receiver->Track().Id().Utf8());
+ if (peer_connection_tracker_) {
+ auto receiver_only_transceiver =
+ std::make_unique<RTCRtpReceiverOnlyTransceiver>(
+ std::make_unique<RTCRtpReceiver>(*receiver));
+ size_t receiver_index = GetTransceiverIndex(*receiver_only_transceiver);
+ peer_connection_tracker_->TrackRemoveTransceiver(
+ this,
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only_transceiver.get(), receiver_index);
+ }
+ rtp_receivers_.erase(it);
+ for (const auto& stream_id : receiver->state().stream_ids()) {
+ // This was the last occurence of the stream?
+ if (!IsRemoteStream(rtp_receivers_, stream_id))
+ PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
+ }
+ if (!is_closed_)
+ client_->DidRemoveReceiverPlanB(std::move(receiver));
+}
+
+void RTCPeerConnectionHandler::OnModifyTransceivers(
+ std::vector<RtpTransceiverState> transceiver_states,
+ bool is_remote_description) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ std::vector<std::unique_ptr<blink::WebRTCRtpTransceiver>> web_transceivers(
+ transceiver_states.size());
+ PeerConnectionTracker::TransceiverUpdatedReason update_reason =
+ !is_remote_description ? PeerConnectionTracker::TransceiverUpdatedReason::
+ kSetLocalDescription
+ : PeerConnectionTracker::TransceiverUpdatedReason::
+ kSetRemoteDescription;
+ for (size_t i = 0; i < transceiver_states.size(); ++i) {
+ // Figure out if this transceiver is new or if setting the state modified
+ // the transceiver such that it should be logged by the
+ // |peer_connection_tracker_|.
+ uintptr_t transceiver_id = RTCRtpTransceiver::GetId(
+ transceiver_states[i].webrtc_transceiver().get());
+ auto it = FindTransceiver(transceiver_id);
+ bool transceiver_is_new = (it == rtp_transceivers_.end());
+ bool transceiver_was_modified = false;
+ if (!transceiver_is_new) {
+ const auto& previous_state = (*it)->state();
+ transceiver_was_modified =
+ previous_state.mid() != transceiver_states[i].mid() ||
+ previous_state.stopped() != transceiver_states[i].stopped() ||
+ previous_state.direction() != transceiver_states[i].direction() ||
+ previous_state.current_direction() !=
+ transceiver_states[i].current_direction();
+ }
+
+ // Update the transceiver.
+ web_transceivers[i] =
+ CreateOrUpdateTransceiver(std::move(transceiver_states[i]));
+
+ // Log a "transcieverAdded" or "transceiverModified" event in
+ // chrome://webrtc-internals if new or modified.
+ if (peer_connection_tracker_ &&
+ (transceiver_is_new || transceiver_was_modified)) {
+ size_t transceiver_index = GetTransceiverIndex(*web_transceivers[i]);
+ if (transceiver_is_new) {
+ peer_connection_tracker_->TrackAddTransceiver(
+ this, update_reason, *web_transceivers[i].get(), transceiver_index);
+ } else if (transceiver_was_modified) {
+ peer_connection_tracker_->TrackModifyTransceiver(
+ this, update_reason, *web_transceivers[i].get(), transceiver_index);
}
}
}
+ if (!is_closed_) {
+ client_->DidModifyTransceivers(std::move(web_transceivers),
+ is_remote_description);
+ }
}
void RTCPeerConnectionHandler::OnDataChannel(
std::unique_ptr<RtcDataChannelHandler> handler) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnDataChannelImpl");
if (peer_connection_tracker_) {
@@ -2144,7 +2190,7 @@ void RTCPeerConnectionHandler::OnDataChannel(
void RTCPeerConnectionHandler::OnIceCandidate(
const std::string& sdp, const std::string& sdp_mid, int sdp_mline_index,
int component, int address_family) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
scoped_refptr<blink::WebRTCICECandidate> web_candidate =
blink::WebRTCICECandidate::Create(blink::WebString::FromUTF8(sdp),
@@ -2224,16 +2270,103 @@ RTCPeerConnectionHandler::FindSender(uintptr_t id) {
return rtp_senders_.end();
}
+std::vector<std::unique_ptr<RTCRtpReceiver>>::iterator
+RTCPeerConnectionHandler::FindReceiver(uintptr_t id) {
+ for (auto it = rtp_receivers_.begin(); it != rtp_receivers_.end(); ++it) {
+ if ((*it)->Id() == id)
+ return it;
+ }
+ return rtp_receivers_.end();
+}
+
+std::vector<std::unique_ptr<RTCRtpTransceiver>>::iterator
+RTCPeerConnectionHandler::FindTransceiver(uintptr_t id) {
+ for (auto it = rtp_transceivers_.begin(); it != rtp_transceivers_.end();
+ ++it) {
+ if ((*it)->Id() == id)
+ return it;
+ }
+ return rtp_transceivers_.end();
+}
+
+size_t RTCPeerConnectionHandler::GetTransceiverIndex(
+ const blink::WebRTCRtpTransceiver& web_transceiver) {
+ if (web_transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ for (size_t i = 0; i < rtp_transceivers_.size(); ++i) {
+ if (web_transceiver.Id() == rtp_transceivers_[i]->Id())
+ return i;
+ }
+ } else if (web_transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ const auto web_sender = web_transceiver.Sender();
+ for (size_t i = 0; i < rtp_senders_.size(); ++i) {
+ if (web_sender->Id() == rtp_senders_[i]->Id())
+ return i;
+ }
+ } else {
+ RTC_DCHECK(
+ web_transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ const auto web_receiver = web_transceiver.Receiver();
+ for (size_t i = 0; i < rtp_receivers_.size(); ++i) {
+ if (web_receiver->Id() == rtp_receivers_[i]->Id())
+ return i;
+ }
+ }
+ NOTREACHED();
+ return 0u;
+}
+
+std::unique_ptr<RTCRtpTransceiver>
+RTCPeerConnectionHandler::CreateOrUpdateTransceiver(
+ RtpTransceiverState transceiver_state) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK(transceiver_state.is_initialized());
+ DCHECK(transceiver_state.sender_state());
+ DCHECK(transceiver_state.receiver_state());
+ auto webrtc_transceiver = transceiver_state.webrtc_transceiver();
+ auto webrtc_sender = transceiver_state.sender_state()->webrtc_sender();
+ auto webrtc_receiver = transceiver_state.receiver_state()->webrtc_receiver();
+
+ std::unique_ptr<RTCRtpTransceiver> transceiver;
+ auto it = FindTransceiver(RTCRtpTransceiver::GetId(webrtc_transceiver.get()));
+ if (it == rtp_transceivers_.end()) {
+ // Create a new transceiver, including a sender and a receiver.
+ transceiver = std::make_unique<RTCRtpTransceiver>(
+ native_peer_connection_, track_adapter_map_,
+ std::move(transceiver_state));
+ rtp_transceivers_.push_back(transceiver->ShallowCopy());
+ DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender.get())) ==
+ rtp_senders_.end());
+ rtp_senders_.push_back(
+ std::make_unique<RTCRtpSender>(*transceiver->content_sender()));
+ DCHECK(FindReceiver(RTCRtpReceiver::getId(webrtc_receiver.get())) ==
+ rtp_receivers_.end());
+ rtp_receivers_.push_back(
+ std::make_unique<RTCRtpReceiver>(*transceiver->content_receiver()));
+ } else {
+ // Update the transceiver. This also updates the sender and receiver.
+ transceiver = (*it)->ShallowCopy();
+ transceiver->set_state(std::move(transceiver_state));
+ DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender.get())) !=
+ rtp_senders_.end());
+ DCHECK(FindReceiver(RTCRtpReceiver::getId(webrtc_receiver.get())) !=
+ rtp_receivers_.end());
+ }
+ return transceiver;
+}
+
scoped_refptr<base::SingleThreadTaskRunner>
RTCPeerConnectionHandler::signaling_thread() const {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
return dependency_factory_->GetWebRtcSignalingThread();
}
void RTCPeerConnectionHandler::RunSynchronousClosureOnSignalingThread(
const base::Closure& closure,
const char* trace_event_name) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<base::SingleThreadTaskRunner> thread(signaling_thread());
if (!thread.get() || thread->BelongsToCurrentThread()) {
TRACE_EVENT0("webrtc", trace_event_name);
@@ -2251,7 +2384,7 @@ void RTCPeerConnectionHandler::RunSynchronousClosureOnSignalingThread(
void RTCPeerConnectionHandler::ReportICEState(
webrtc::PeerConnectionInterface::IceConnectionState new_state) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (ice_state_seen_[new_state])
return;
ice_state_seen_[new_state] = true;
@@ -2260,7 +2393,7 @@ void RTCPeerConnectionHandler::ReportICEState(
}
void RTCPeerConnectionHandler::ResetUMAStats() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
num_local_candidates_ipv6_ = 0;
num_local_candidates_ipv4_ = 0;
ice_connection_checking_start_ = base::TimeTicks();
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h
index a4b038365d2..74cb1b77c1a 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h
@@ -18,15 +18,15 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/renderer/media/webrtc/media_stream_track_metrics.h"
#include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
#include "content/renderer/media/webrtc/rtc_rtp_sender.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
+#include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "ipc/ipc_platform_file.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_rtc_configuration.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_rtc_stats_request.h"
#include "third_party/blink/public/platform/web_rtc_stats_response.h"
@@ -45,6 +45,7 @@ namespace content {
class PeerConnectionDependencyFactory;
class PeerConnectionTracker;
class RtcDataChannelHandler;
+class SetLocalDescriptionRequest;
// Mockable wrapper for blink::WebRTCStatsResponse
class CONTENT_EXPORT LocalRTCStatsResponse : public rtc::RefCountInterface {
@@ -107,8 +108,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker);
// blink::WebRTCPeerConnectionHandler implementation
- bool Initialize(const blink::WebRTCConfiguration& server_configuration,
- const blink::WebMediaConstraints& options) override;
+ bool Initialize(
+ const blink::WebRTCConfiguration& server_configuration,
+ const blink::WebMediaConstraints& options,
+ blink::WebRTCSdpSemantics original_sdp_semantics_value) override;
void CreateOffer(const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebMediaConstraints& options) override;
@@ -143,10 +146,17 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void GetStats(const blink::WebRTCStatsRequest& request) override;
void GetStats(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) override;
- std::unique_ptr<blink::WebRTCRtpSender> AddTrack(
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ AddTransceiverWithTrack(const blink::WebMediaStreamTrack& web_track,
+ const webrtc::RtpTransceiverInit& init) override;
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ AddTransceiverWithKind(std::string kind,
+ const webrtc::RtpTransceiverInit& init) override;
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>> AddTrack(
const blink::WebMediaStreamTrack& web_track,
const blink::WebVector<blink::WebMediaStream>& web_streams) override;
- bool RemoveTrack(blink::WebRTCRtpSender* web_sender) override;
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>> RemoveTrack(
+ blink::WebRTCRtpSender* web_sender) override;
blink::WebRTCDataChannelHandler* CreateDataChannel(
const blink::WebString& label,
@@ -185,8 +195,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
class Observer;
friend class Observer;
- class WebRtcSetRemoteDescriptionObserverImpl;
- friend class WebRtcSetRemoteDescriptionObserverImpl;
+ class WebRtcSetDescriptionObserverImpl;
+ friend class WebRtcSetDescriptionObserverImpl;
+ class SetLocalDescriptionRequest;
+ friend class SetLocalDescriptionRequest;
void OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state);
@@ -195,14 +207,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void OnIceGatheringChange(
webrtc::PeerConnectionInterface::IceGatheringState new_state);
void OnRenegotiationNeeded();
- void OnAddRemoteTrack(
- scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- remote_track_adapter_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- remote_stream_adapter_refs);
- void OnRemoveRemoteTrack(
- scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver);
+ void OnAddReceiverPlanB(RtpReceiverState receiver_state);
+ void OnRemoveReceiverPlanB(uintptr_t receiver_id);
+ void OnModifyTransceivers(std::vector<RtpTransceiverState> transceiver_states,
+ bool is_remote_description);
void OnDataChannel(std::unique_ptr<RtcDataChannelHandler> handler);
void OnIceCandidate(const std::string& sdp,
const std::string& sdp_mid,
@@ -240,7 +248,47 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void ReportFirstSessionDescriptions(const FirstSessionDescription& local,
const FirstSessionDescription& remote);
+ void AddTransceiverWithTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver);
+ void AddTransceiverWithMediaTypeOnSignalingThread(
+ cricket::MediaType media_type,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver);
+ void AddTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>*
+ error_or_sender);
+ bool RemoveTrackPlanB(blink::WebRTCRtpSender* web_sender);
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ RemoveTrackUnifiedPlan(blink::WebRTCRtpSender* web_sender);
+ void RemoveTrackUnifiedPlanOnSignalingThread(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ bool* result);
std::vector<std::unique_ptr<RTCRtpSender>>::iterator FindSender(uintptr_t id);
+ std::vector<std::unique_ptr<RTCRtpReceiver>>::iterator FindReceiver(
+ uintptr_t id);
+ std::vector<std::unique_ptr<RTCRtpTransceiver>>::iterator FindTransceiver(
+ uintptr_t id);
+ // For full transceiver implementations, returns the index of
+ // |rtp_transceivers_| that correspond to |web_transceiver|.
+ // For sender-only transceiver implementations, returns the index of
+ // |rtp_senders_| that correspond to |web_transceiver.Sender()|.
+ // For receiver-only transceiver implementations, returns the index of
+ // |rtp_receivers_| that correspond to |web_transceiver.Receiver()|.
+ // NOTREACHED()-crashes if no correspondent is found.
+ size_t GetTransceiverIndex(
+ const blink::WebRTCRtpTransceiver& web_transceiver);
+ std::unique_ptr<RTCRtpTransceiver> CreateOrUpdateTransceiver(
+ RtpTransceiverState transceiver_state);
scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const;
@@ -254,8 +302,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// first call fails.
bool initialize_called_;
- base::ThreadChecker thread_checker_;
-
// |client_| is a weak pointer to the blink object (blink::RTCPeerConnection)
// that owns this object.
// It is valid for the lifetime of this object.
@@ -279,20 +325,20 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// needs to reference it, and automatically disposed when there are no longer
// any components referencing it.
scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
- // Map and owners of stream adapters. Every stream that is in use by the peer
- // connection has an associated blink and webrtc layer representation of it.
- // The map keeps track of the relationship between |blink::WebMediaStream|s
- // and |webrtc::MediaStreamInterface|s. Stream adapters are created on the fly
- // when a component (such as a sender or receiver) needs to reference it, and
- // automatically disposed when there are no longer any components referencing
- // it.
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map_;
+ // In Plan B, senders and receivers are added or removed independently of one
+ // another. In Unified Plan, senders and receivers are created in pairs as
+ // transceivers. Transceivers may become inactive, but are never removed.
+ // The value of this member affects the behavior of some methods and what
+ // information is surfaced from webrtc. After Initialize(), this is the actual
+ // mode used, meaning "kDefault" is no longer a valid value.
+ // TODO(hbos): Implement transceiver behaviors. https://crbug.com/777617
+ blink::WebRTCSdpSemantics sdp_semantics_;
// Content layer correspondents of |webrtc::RtpSenderInterface|.
std::vector<std::unique_ptr<RTCRtpSender>> rtp_senders_;
- // Maps |RTCRtpReceiver::getId|s of |webrtc::RtpReceiverInterface|s to the
- // corresponding content layer receivers. The set of receivers is needed in
- // order to keep its associated track's and streams' adapters alive.
- std::map<uintptr_t, std::unique_ptr<RTCRtpReceiver>> rtp_receivers_;
+ // Content layer correspondents of |webrtc::RtpReceiverInterface|.
+ std::vector<std::unique_ptr<RTCRtpReceiver>> rtp_receivers_;
+ // Content layer correspondents of |webrtc::RtpTransceiverInterface|.
+ std::vector<std::unique_ptr<RTCRtpTransceiver>> rtp_transceivers_;
base::WeakPtr<PeerConnectionTracker> peer_connection_tracker_;
@@ -308,7 +354,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// To make sure the observers are released after native_peer_connection_,
// they have to come first.
scoped_refptr<Observer> peer_connection_observer_;
- scoped_refptr<webrtc::UMAObserver> uma_observer_;
// |native_peer_connection_| is the libjingle native PeerConnection object.
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
index 3d9ade84d75..51a6af48d59 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -23,7 +23,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "content/child/child_process.h"
-#include "content/renderer/media/mock_audio_device_factory.h"
+#include "content/renderer/media/audio/mock_audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_source.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "content/renderer/media/stream/media_stream_source.h"
@@ -171,14 +171,21 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
scoped_refptr<blink::WebRTCICECandidate> candidate,
Source source,
bool succeeded));
- MOCK_METHOD3(TrackAddStream,
+ MOCK_METHOD4(TrackAddTransceiver,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source));
- MOCK_METHOD3(TrackRemoveStream,
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index));
+ MOCK_METHOD4(TrackModifyTransceiver,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source));
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index));
+ MOCK_METHOD4(TrackRemoveTransceiver,
+ void(RTCPeerConnectionHandler* pc_handler,
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index));
MOCK_METHOD1(TrackOnIceComplete,
void(RTCPeerConnectionHandler* pc_handler));
MOCK_METHOD3(TrackCreateDataChannel,
@@ -188,11 +195,11 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
MOCK_METHOD1(TrackStop, void(RTCPeerConnectionHandler* pc_handler));
MOCK_METHOD2(TrackSignalingStateChange,
void(RTCPeerConnectionHandler* pc_handler,
- WebRTCPeerConnectionHandlerClient::SignalingState state));
+ webrtc::PeerConnectionInterface::SignalingState state));
MOCK_METHOD2(
TrackIceConnectionStateChange,
void(RTCPeerConnectionHandler* pc_handler,
- WebRTCPeerConnectionHandlerClient::ICEConnectionState state));
+ MockWebRTCPeerConnectionHandlerClient::ICEConnectionState state));
MOCK_METHOD2(
TrackIceGatheringStateChange,
void(RTCPeerConnectionHandler* pc_handler,
@@ -273,6 +280,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
pc_handler_ = CreateRTCPeerConnectionHandlerUnderTest();
mock_tracker_.reset(new NiceMock<MockPeerConnectionTracker>());
blink::WebRTCConfiguration config;
+ config.sdp_semantics = blink::WebRTCSdpSemantics::kPlanB;
blink::WebMediaConstraints constraints;
EXPECT_TRUE(pc_handler_->InitializeForTest(
config, constraints, mock_tracker_.get()->AsWeakPtr()));
@@ -373,14 +381,9 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
}
void StopAllTracks(const blink::WebMediaStream& stream) {
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- stream.AudioTracks(audio_tracks);
- for (const auto& track : audio_tracks)
+ for (const auto& track : stream.AudioTracks())
MediaStreamAudioTrack::From(track)->Stop();
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- stream.VideoTracks(video_tracks);
- for (const auto& track : video_tracks)
+ for (const auto& track : stream.VideoTracks())
MediaStreamVideoTrack::GetVideoTrack(track)->Stop();
}
@@ -390,22 +393,26 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
bool AddStream(const blink::WebMediaStream& web_stream) {
size_t senders_size_before_add = senders_.size();
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- web_stream.AudioTracks(web_audio_tracks);
- for (const auto& web_audio_track : web_audio_tracks) {
- auto sender = pc_handler_->AddTrack(
+ for (const auto& web_audio_track : web_stream.AudioTracks()) {
+ auto error_or_transceiver = pc_handler_->AddTrack(
web_audio_track, std::vector<blink::WebMediaStream>({web_stream}));
- if (sender) {
+ if (error_or_transceiver.ok()) {
+ DCHECK_EQ(
+ error_or_transceiver.value()->ImplementationType(),
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ auto sender = error_or_transceiver.value()->Sender();
senders_.push_back(std::unique_ptr<RTCRtpSender>(
static_cast<RTCRtpSender*>(sender.release())));
}
}
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- web_stream.VideoTracks(web_video_tracks);
- for (const auto& web_video_track : web_video_tracks) {
- auto sender = pc_handler_->AddTrack(
+ for (const auto& web_video_track : web_stream.VideoTracks()) {
+ auto error_or_transceiver = pc_handler_->AddTrack(
web_video_track, std::vector<blink::WebMediaStream>({web_stream}));
- if (sender) {
+ if (error_or_transceiver.ok()) {
+ DCHECK_EQ(
+ error_or_transceiver.value()->ImplementationType(),
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ auto sender = error_or_transceiver.value()->Sender();
senders_.push_back(std::unique_ptr<RTCRtpSender>(
static_cast<RTCRtpSender*>(sender.release())));
}
@@ -424,20 +431,16 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
bool RemoveStream(const blink::WebMediaStream& web_stream) {
size_t senders_size_before_remove = senders_.size();
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- web_stream.AudioTracks(web_audio_tracks);
// TODO(hbos): With Unified Plan senders are not removed.
// https://crbug.com/799030
- for (const auto& web_audio_track : web_audio_tracks) {
+ for (const auto& web_audio_track : web_stream.AudioTracks()) {
auto it = FindSenderForTrack(web_audio_track);
- if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()))
+ if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()).ok())
senders_.erase(it);
}
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- web_stream.VideoTracks(web_video_tracks);
- for (const auto& web_video_track : web_video_tracks) {
+ for (const auto& web_video_track : web_stream.VideoTracks()) {
auto it = FindSenderForTrack(web_video_track);
- if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()))
+ if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()).ok())
senders_.erase(it);
}
return senders_size_before_remove > senders_.size();
@@ -607,12 +610,12 @@ TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
pc_handler_->observer()->OnIceConnectionChange(
webrtc::PeerConnectionInterface::kIceConnectionDisconnected);
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)).Times(0);
+ EXPECT_CALL(*mock_client_.get(), DidAddReceiverPlanBForMock(_)).Times(0);
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream("remote_stream", "video", "audio"));
InvokeOnAddStream(remote_stream);
- EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_)).Times(0);
+ EXPECT_CALL(*mock_client_.get(), DidRemoveReceiverPlanBForMock(_)).Times(0);
InvokeOnRemoveStream(remote_stream);
EXPECT_CALL(*mock_client_.get(), DidAddRemoteDataChannel(_)).Times(0);
@@ -762,6 +765,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescriptionParseError) {
TEST_F(RTCPeerConnectionHandlerTest, setConfiguration) {
blink::WebRTCConfiguration config;
+ config.sdp_semantics = blink::WebRTCSdpSemantics::kPlanB;
EXPECT_CALL(*mock_tracker_.get(),
TrackSetConfiguration(pc_handler_.get(), _));
@@ -775,6 +779,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setConfiguration) {
// blink error and false is returned.
TEST_F(RTCPeerConnectionHandlerTest, setConfigurationError) {
blink::WebRTCConfiguration config;
+ config.sdp_semantics = blink::WebRTCSdpSemantics::kPlanB;
mock_peer_connection_->set_setconfiguration_error_type(
webrtc::RTCErrorType::INVALID_MODIFICATION);
@@ -802,22 +807,25 @@ TEST_F(RTCPeerConnectionHandlerTest, addAndRemoveStream) {
blink::WebMediaStream local_stream(
CreateLocalMediaStream(stream_label));
- EXPECT_CALL(*mock_tracker_.get(),
- TrackAddStream(pc_handler_.get(), _,
- PeerConnectionTracker::SOURCE_LOCAL));
- EXPECT_CALL(*mock_tracker_.get(),
- TrackRemoveStream(pc_handler_.get(), _,
- PeerConnectionTracker::SOURCE_LOCAL));
+ EXPECT_CALL(
+ *mock_tracker_.get(),
+ TrackAddTransceiver(
+ pc_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, _, _))
+ .Times(2);
+ EXPECT_CALL(
+ *mock_tracker_.get(),
+ TrackRemoveTransceiver(
+ pc_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack, _, _))
+ .Times(2);
EXPECT_TRUE(AddStream(local_stream));
EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
- EXPECT_EQ(1u,
- mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
- EXPECT_EQ(1u,
- mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());
+ EXPECT_EQ(2u, mock_peer_connection_->GetSenders().size());
EXPECT_FALSE(AddStream(local_stream));
EXPECT_TRUE(RemoveStream(local_stream));
- EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count());
+ EXPECT_EQ(0u, mock_peer_connection_->GetSenders().size());
StopAllTracks(local_stream);
}
@@ -827,14 +835,14 @@ TEST_F(RTCPeerConnectionHandlerTest, addStreamWithStoppedAudioAndVideoTrack) {
blink::WebMediaStream local_stream(
CreateLocalMediaStream(stream_label));
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- local_stream.AudioTracks(audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ local_stream.AudioTracks();
MediaStreamAudioSource* native_audio_source =
MediaStreamAudioSource::From(audio_tracks[0].Source());
native_audio_source->StopSource();
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- local_stream.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ local_stream.VideoTracks();
MediaStreamVideoSource* native_video_source =
static_cast<MediaStreamVideoSource*>(
video_tracks[0].Source().GetExtraData());
@@ -842,12 +850,7 @@ TEST_F(RTCPeerConnectionHandlerTest, addStreamWithStoppedAudioAndVideoTrack) {
EXPECT_TRUE(AddStream(local_stream));
EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
- EXPECT_EQ(
- 1u,
- mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
- EXPECT_EQ(
- 1u,
- mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());
+ EXPECT_EQ(2u, mock_peer_connection_->GetSenders().size());
StopAllTracks(local_stream);
}
@@ -876,8 +879,8 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
blink::WebMediaStream local_stream(
CreateLocalMediaStream("local_stream"));
EXPECT_TRUE(AddStream(local_stream));
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- local_stream.AudioTracks(tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> tracks =
+ local_stream.AudioTracks();
ASSERT_LE(1ul, tracks.size());
scoped_refptr<MockRTCStatsRequest> request(
@@ -890,45 +893,13 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
StopAllTracks(local_stream);
}
-// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
-TEST_F(RTCPeerConnectionHandlerTest, DISABLED_GetStatsWithRemoteSelector) {
- rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
- // Grab the added receivers and media stream when it's been successfully added
- // to the PC.
- blink::WebMediaStream webkit_stream;
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
- .WillRepeatedly(
- Invoke([&webkit_stream, &receivers](
- std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
- webkit_stream = (*receiver)->Streams()[0];
- receivers.push_back(std::move(*receiver));
- }));
- InvokeOnAddStream(remote_stream);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- webkit_stream.AudioTracks(tracks);
- ASSERT_LE(1ul, tracks.size());
-
- scoped_refptr<MockRTCStatsRequest> request(
- new rtc::RefCountedObject<MockRTCStatsRequest>());
- request->setSelector(tracks[0]);
- pc_handler_->getStats(request.get());
- RunMessageLoopsUntilIdle();
- EXPECT_EQ(1, request->result()->report_count());
-}
-
TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) {
// The setup is the same as GetStatsWithLocalSelector, but the stream is not
// added to the PeerConnection.
blink::WebMediaStream local_stream(
CreateLocalMediaStream("local_stream_2"));
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
-
- local_stream.AudioTracks(tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> tracks =
+ local_stream.AudioTracks();
blink::WebMediaStreamTrack component = tracks[0];
mock_peer_connection_->SetGetStatsResult(false);
@@ -1063,67 +1034,6 @@ TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) {
EXPECT_EQ(defined_stats_count, 1);
}
-TEST_F(RTCPeerConnectionHandlerTest, OnSignalingChange) {
- testing::InSequence sequence;
-
- webrtc::PeerConnectionInterface::SignalingState new_state =
- webrtc::PeerConnectionInterface::kHaveRemoteOffer;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveRemoteOffer));
- EXPECT_CALL(
- *mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveRemoteOffer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalPrAnswer));
- EXPECT_CALL(
- *mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalPrAnswer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kHaveLocalOffer;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalOffer));
- EXPECT_CALL(
- *mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalOffer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
- EXPECT_CALL(*mock_tracker_.get(),
- TrackSignalingStateChange(pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveRemotePrAnswer));
- EXPECT_CALL(*mock_client_.get(),
- DidChangeSignalingState(WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveRemotePrAnswer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kClosed;
- EXPECT_CALL(*mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateClosed));
- EXPECT_CALL(*mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateClosed));
- pc_handler_->observer()->OnSignalingChange(new_state);
-}
-
TEST_F(RTCPeerConnectionHandlerTest, OnIceConnectionChange) {
testing::InSequence sequence;
@@ -1263,28 +1173,27 @@ TEST_F(RTCPeerConnectionHandlerTest, DISABLED_OnAddAndOnRemoveStream) {
AddRemoteMockMediaStream("remote_stream", "video", "audio"));
// Grab the added receivers when it's been successfully added to the PC.
std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers_added;
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ EXPECT_CALL(*mock_client_.get(), DidAddReceiverPlanBForMock(_))
.WillRepeatedly(
Invoke([&receivers_added](
std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
receivers_added.push_back(std::move(*receiver));
}));
- EXPECT_CALL(*mock_tracker_.get(),
- TrackAddStream(pc_handler_.get(),
- testing::Property(
- &blink::WebMediaStream::Id,
- blink::WebString::FromASCII("remote_stream")),
- PeerConnectionTracker::SOURCE_REMOTE));
+ EXPECT_CALL(
+ *mock_tracker_.get(),
+ TrackAddTransceiver(
+ pc_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, _, _))
+ .Times(2);
// Grab the removed receivers when it's been successfully added to the PC.
std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers_removed;
EXPECT_CALL(
*mock_tracker_.get(),
- TrackRemoveStream(
+ TrackRemoveTransceiver(
pc_handler_.get(),
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII("remote_stream")),
- PeerConnectionTracker::SOURCE_REMOTE));
- EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_))
+ PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack, _, _))
+ .Times(2);
+ EXPECT_CALL(*mock_client_.get(), DidRemoveReceiverPlanBForMock(_))
.WillRepeatedly(
Invoke([&receivers_removed](
std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
@@ -1303,211 +1212,6 @@ TEST_F(RTCPeerConnectionHandlerTest, DISABLED_OnAddAndOnRemoveStream) {
EXPECT_EQ(receivers_added[1]->Id(), receivers_removed[1]->Id());
}
-// This test that WebKit is notified about remote track state changes.
-// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
-TEST_F(RTCPeerConnectionHandlerTest, DISABLED_RemoteTrackState) {
- rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
- // Grab the added receivers and media stream when it's been successfully added
- // to the PC.
- blink::WebMediaStream webkit_stream;
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
- .WillRepeatedly(
- Invoke([&webkit_stream, &receivers](
- std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
- webkit_stream = (*receiver)->Streams()[0];
- receivers.push_back(std::move(*receiver));
- }));
- InvokeOnAddStream(remote_stream);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
- audio_tracks[0].Source().GetReadyState());
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
- video_tracks[0].Source().GetReadyState());
-
- InvokeOnSignalingThread(
- base::Bind(&MockWebRtcAudioTrack::SetEnded,
- base::Unretained(static_cast<MockWebRtcAudioTrack*>(
- remote_stream->GetAudioTracks()[0].get()))));
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
- audio_tracks[0].Source().GetReadyState());
-
- InvokeOnSignalingThread(
- base::Bind(&MockWebRtcVideoTrack::SetEnded,
- base::Unretained(static_cast<MockWebRtcVideoTrack*>(
- remote_stream->GetVideoTracks()[0].get()))));
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
- video_tracks[0].Source().GetReadyState());
-}
-
-// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
-TEST_F(RTCPeerConnectionHandlerTest,
- DISABLED_RemoveAndAddAudioTrackFromRemoteStream) {
- rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
- // Grab the added receivers and media stream when it's been successfully added
- // to the PC.
- blink::WebMediaStream webkit_stream;
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
- .WillRepeatedly(
- Invoke([&webkit_stream, &receivers](
- std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
- webkit_stream = (*receiver)->Streams()[0];
- receivers.push_back(std::move(*receiver));
- }));
- InvokeOnAddStream(remote_stream);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- {
- // Test in a small scope so that |audio_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- }
-
- // Remove the Webrtc audio track from the Webrtc MediaStream.
- scoped_refptr<webrtc::AudioTrackInterface> webrtc_track =
- remote_stream->GetAudioTracks()[0].get();
- InvokeRemoveTrack(remote_stream, webrtc_track.get());
-
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks1;
- webkit_stream.AudioTracks(modified_audio_tracks1);
- EXPECT_EQ(0u, modified_audio_tracks1.size());
- }
-
- blink::WebHeap::CollectGarbageForTesting();
-
- // Add the WebRtc audio track again.
- InvokeAddTrack(remote_stream, webrtc_track.get());
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks2;
- webkit_stream.AudioTracks(modified_audio_tracks2);
- EXPECT_EQ(1u, modified_audio_tracks2.size());
-}
-
-// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
-TEST_F(RTCPeerConnectionHandlerTest,
- DISABLED_RemoveAndAddVideoTrackFromRemoteStream) {
- rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
- // Grab the added receivers and media stream when it's been successfully added
- // to the PC.
- blink::WebMediaStream webkit_stream;
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
- .WillRepeatedly(
- Invoke([&webkit_stream, &receivers](
- std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
- webkit_stream = (*receiver)->Streams()[0];
- receivers.push_back(std::move(*receiver));
- }));
- InvokeOnAddStream(remote_stream);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- {
- // Test in a small scope so that |video_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
- }
-
- // Remove the Webrtc video track from the Webrtc MediaStream.
- scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
- remote_stream->GetVideoTracks()[0].get();
- InvokeRemoveTrack(remote_stream, webrtc_track.get());
- RunMessageLoopsUntilIdle();
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks1;
- webkit_stream.VideoTracks(modified_video_tracks1);
- EXPECT_EQ(0u, modified_video_tracks1.size());
- }
-
- blink::WebHeap::CollectGarbageForTesting();
-
- // Add the WebRtc video track again.
- InvokeAddTrack(remote_stream, webrtc_track.get());
- RunMessageLoopsUntilIdle();
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks2;
- webkit_stream.VideoTracks(modified_video_tracks2);
- EXPECT_EQ(1u, modified_video_tracks2.size());
-}
-
-// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
-TEST_F(RTCPeerConnectionHandlerTest,
- DISABLED_RemoveAndAddTracksFromRemoteStream) {
- rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
- // Grab the added receivers and media stream when it's been successfully added
- // to the PC.
- blink::WebMediaStream webkit_stream;
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
- .WillRepeatedly(
- Invoke([&webkit_stream, &receivers](
- std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
- webkit_stream = (*receiver)->Streams()[0];
- receivers.push_back(std::move(*receiver));
- }));
- InvokeOnAddStream(remote_stream);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- {
- // Test in a small scope so that |audio_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
- }
-
- // Remove the Webrtc tracks from the MediaStream.
- auto audio_track = remote_stream->GetAudioTracks()[0];
- InvokeRemoveTrack(remote_stream, audio_track.get());
- auto video_track = remote_stream->GetVideoTracks()[0];
- InvokeRemoveTrack(remote_stream, video_track.get());
- RunMessageLoopsUntilIdle();
-
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks;
- webkit_stream.AudioTracks(modified_audio_tracks);
- EXPECT_EQ(0u, modified_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks;
- webkit_stream.VideoTracks(modified_video_tracks);
- EXPECT_EQ(0u, modified_video_tracks.size());
- }
-
- blink::WebHeap::CollectGarbageForTesting();
-
- // Add the tracks again.
- InvokeAddTrack(remote_stream, audio_track.get());
- InvokeAddTrack(remote_stream, video_track.get());
-
- blink::WebHeap::CollectGarbageForTesting();
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
-}
-
TEST_F(RTCPeerConnectionHandlerTest, OnIceCandidate) {
testing::InSequence sequence;
EXPECT_CALL(*mock_tracker_.get(),
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
index a988bd10bb5..200b00beb9e 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
@@ -11,6 +11,96 @@
namespace content {
+RtpReceiverState::RtpReceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_id)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ webrtc_receiver_(std::move(webrtc_receiver)),
+ is_initialized_(false),
+ track_ref_(std::move(track_ref)),
+ stream_ids_(std::move(stream_id)) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+ DCHECK(webrtc_receiver_);
+ DCHECK(track_ref_);
+}
+
+RtpReceiverState::RtpReceiverState(RtpReceiverState&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ webrtc_receiver_(std::move(other.webrtc_receiver_)),
+ is_initialized_(other.is_initialized_),
+ track_ref_(std::move(other.track_ref_)),
+ stream_ids_(std::move(other.stream_ids_)) {
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+RtpReceiverState::~RtpReceiverState() {
+ // It's OK to not be on the main thread if this state has been moved, in which
+ // case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+RtpReceiverState& RtpReceiverState::operator=(RtpReceiverState&& other) {
+ DCHECK_EQ(main_task_runner_, other.main_task_runner_);
+ DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_);
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ webrtc_receiver_ = std::move(other.webrtc_receiver_);
+ track_ref_ = std::move(other.track_ref_);
+ stream_ids_ = std::move(other.stream_ids_);
+ return *this;
+}
+
+bool RtpReceiverState::is_initialized() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return is_initialized_;
+}
+
+void RtpReceiverState::Initialize() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (is_initialized_)
+ return;
+ track_ref_->InitializeOnMainThread();
+ is_initialized_ = true;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> RtpReceiverState::main_task_runner()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return main_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpReceiverState::signaling_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return signaling_task_runner_;
+}
+
+scoped_refptr<webrtc::RtpReceiverInterface> RtpReceiverState::webrtc_receiver()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return webrtc_receiver_;
+}
+
+const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+RtpReceiverState::track_ref() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return track_ref_;
+}
+
+const std::vector<std::string>& RtpReceiverState::stream_ids() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return stream_ids_;
+}
+
class RTCRtpReceiver::RTCRtpReceiverInternal
: public base::RefCountedThreadSafe<
RTCRtpReceiver::RTCRtpReceiverInternal,
@@ -18,37 +108,34 @@ class RTCRtpReceiver::RTCRtpReceiverInternal
public:
RTCRtpReceiverInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- track_adapter,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs)
+ RtpReceiverState state)
: native_peer_connection_(std::move(native_peer_connection)),
- main_thread_(std::move(main_thread)),
- signaling_thread_(std::move(signaling_thread)),
- webrtc_receiver_(std::move(webrtc_receiver)),
- track_adapter_(std::move(track_adapter)),
- stream_adapter_refs_(std::move(stream_adapter_refs)) {
- DCHECK(webrtc_receiver_);
- DCHECK(track_adapter_);
+ main_task_runner_(state.main_task_runner()),
+ signaling_task_runner_(state.signaling_task_runner()),
+ webrtc_receiver_(state.webrtc_receiver()),
+ state_(std::move(state)) {
+ DCHECK(native_peer_connection_);
+ DCHECK(state_.is_initialized());
}
- const blink::WebMediaStreamTrack& Track() const {
- return track_adapter_->web_track();
+ const RtpReceiverState& state() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return state_;
}
- blink::WebVector<blink::WebMediaStream> Streams() const {
- blink::WebVector<blink::WebMediaStream> web_streams(
- stream_adapter_refs_.size());
- for (size_t i = 0; i < stream_adapter_refs_.size(); ++i)
- web_streams[i] = stream_adapter_refs_[i]->adapter().web_stream();
- return web_streams;
+ void set_state(RtpReceiverState state) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(state.main_task_runner() == main_task_runner_);
+ DCHECK(state.signaling_task_runner() == signaling_task_runner_);
+ DCHECK(state.webrtc_receiver() == webrtc_receiver_);
+ DCHECK(state.is_initialized());
+ state_ = std::move(state);
}
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
GetSources() {
+ // The webrtc_recever_ is a proxy, so this is a blocking call to the webrtc
+ // signalling thread.
auto webrtc_sources = webrtc_receiver_->GetSources();
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
sources(webrtc_sources.size());
@@ -60,64 +147,34 @@ class RTCRtpReceiver::RTCRtpReceiverInternal
}
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpReceiverInternal::GetStatsOnSignalingThread, this,
std::move(callback)));
}
- webrtc::RtpReceiverInterface* webrtc_receiver() const {
- return webrtc_receiver_.get();
- }
-
- const webrtc::MediaStreamTrackInterface& webrtc_track() const {
- DCHECK(track_adapter_->webrtc_track());
- return *track_adapter_->webrtc_track();
- }
-
- bool HasStream(const webrtc::MediaStreamInterface* webrtc_stream) const {
- for (const auto& stream_adapter : stream_adapter_refs_) {
- if (webrtc_stream == stream_adapter->adapter().webrtc_stream().get())
- return true;
- }
- return false;
- }
-
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- StreamAdapterRefs() const {
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_copies;
- stream_adapter_copies.reserve(stream_adapter_refs_.size());
- for (const auto& stream_adapter : stream_adapter_refs_) {
- stream_adapter_copies.push_back(stream_adapter->Copy());
- }
- return stream_adapter_copies;
- }
-
private:
friend struct RTCRtpReceiver::RTCRtpReceiverInternalTraits;
- ~RTCRtpReceiverInternal() { DCHECK(main_thread_->BelongsToCurrentThread()); }
+ ~RTCRtpReceiverInternal() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ }
void GetStatsOnSignalingThread(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- native_peer_connection_->GetStats(webrtc_receiver_,
- RTCStatsCollectorCallbackImpl::Create(
- main_thread_, std::move(callback)));
+ native_peer_connection_->GetStats(
+ webrtc_receiver_.get(), RTCStatsCollectorCallbackImpl::Create(
+ main_task_runner_, std::move(callback)));
}
const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
- const rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
- // The track adapter is the glue between blink and webrtc layer tracks.
- // Keeping a reference to the adapter ensures it is not disposed, as is
- // required as long as the webrtc layer track is in use by the receiver.
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter_;
- // Similarly, references needs to be kept to the stream adapters of streams
- // associated with the receiver.
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs_;
+ // Task runners and webrtc receiver: Same information as stored in
+ // |state_| but const and safe to touch on the signaling thread to
+ // avoid race with set_state().
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ const scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
+ RtpReceiverState state_;
};
struct RTCRtpReceiver::RTCRtpReceiverInternalTraits {
@@ -128,8 +185,8 @@ struct RTCRtpReceiver::RTCRtpReceiverInternalTraits {
static void Destruct(const RTCRtpReceiverInternal* receiver) {
// RTCRtpReceiverInternal owns AdapterRefs which have to be destroyed on the
// main thread, this ensures delete always happens there.
- if (!receiver->main_thread_->BelongsToCurrentThread()) {
- receiver->main_thread_->PostTask(
+ if (!receiver->main_task_runner_->BelongsToCurrentThread()) {
+ receiver->main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpReceiver::RTCRtpReceiverInternalTraits::Destruct,
@@ -147,18 +204,9 @@ uintptr_t RTCRtpReceiver::getId(
RTCRtpReceiver::RTCRtpReceiver(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs)
+ RtpReceiverState state)
: internal_(new RTCRtpReceiverInternal(std::move(native_peer_connection),
- std::move(main_thread),
- std::move(signaling_thread),
- std::move(webrtc_receiver),
- std::move(track_adapter),
- std::move(stream_adapter_refs))) {}
+ std::move(state))) {}
RTCRtpReceiver::RTCRtpReceiver(const RTCRtpReceiver& other)
: internal_(other.internal_) {}
@@ -170,20 +218,32 @@ RTCRtpReceiver& RTCRtpReceiver::operator=(const RTCRtpReceiver& other) {
return *this;
}
-std::unique_ptr<RTCRtpReceiver> RTCRtpReceiver::ShallowCopy() const {
+const RtpReceiverState& RTCRtpReceiver::state() const {
+ return internal_->state();
+}
+
+void RTCRtpReceiver::set_state(RtpReceiverState state) {
+ internal_->set_state(std::move(state));
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver> RTCRtpReceiver::ShallowCopy() const {
return std::make_unique<RTCRtpReceiver>(*this);
}
uintptr_t RTCRtpReceiver::Id() const {
- return getId(internal_->webrtc_receiver());
+ return getId(internal_->state().webrtc_receiver().get());
}
const blink::WebMediaStreamTrack& RTCRtpReceiver::Track() const {
- return internal_->Track();
+ return internal_->state().track_ref()->web_track();
}
-blink::WebVector<blink::WebMediaStream> RTCRtpReceiver::Streams() const {
- return internal_->Streams();
+blink::WebVector<blink::WebString> RTCRtpReceiver::StreamIds() const {
+ const auto& stream_ids = internal_->state().stream_ids();
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size());
+ for (size_t i = 0; i < stream_ids.size(); ++i)
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]);
+ return web_stream_ids;
}
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
@@ -196,22 +256,66 @@ void RTCRtpReceiver::GetStats(
internal_->GetStats(std::move(callback));
}
-webrtc::RtpReceiverInterface* RTCRtpReceiver::webrtc_receiver() const {
- return internal_->webrtc_receiver();
+RTCRtpReceiverOnlyTransceiver::RTCRtpReceiverOnlyTransceiver(
+ std::unique_ptr<blink::WebRTCRtpReceiver> receiver)
+ : receiver_(std::move(receiver)) {
+ DCHECK(receiver_);
+}
+
+RTCRtpReceiverOnlyTransceiver::~RTCRtpReceiverOnlyTransceiver() {}
+
+blink::WebRTCRtpTransceiverImplementationType
+RTCRtpReceiverOnlyTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly;
+}
+
+uintptr_t RTCRtpReceiverOnlyTransceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+blink::WebString RTCRtpReceiverOnlyTransceiver::Mid() const {
+ NOTIMPLEMENTED();
+ return blink::WebString();
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpReceiverOnlyTransceiver::Sender()
+ const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver>
+RTCRtpReceiverOnlyTransceiver::Receiver() const {
+ return receiver_->ShallowCopy();
+}
+
+bool RTCRtpReceiverOnlyTransceiver::Stopped() const {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+webrtc::RtpTransceiverDirection RTCRtpReceiverOnlyTransceiver::Direction()
+ const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
}
-const webrtc::MediaStreamTrackInterface& RTCRtpReceiver::webrtc_track() const {
- return internal_->webrtc_track();
+void RTCRtpReceiverOnlyTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ NOTIMPLEMENTED();
}
-bool RTCRtpReceiver::HasStream(
- const webrtc::MediaStreamInterface* webrtc_stream) const {
- return internal_->HasStream(webrtc_stream);
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpReceiverOnlyTransceiver::CurrentDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
}
-std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
-RTCRtpReceiver::StreamAdapterRefs() const {
- return internal_->StreamAdapterRefs();
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpReceiverOnlyTransceiver::FiredDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
index 29420ae5220..1eb373ad13f 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
@@ -9,17 +9,88 @@
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/rtpreceiverinterface.h"
namespace content {
+// This class represents the state of a receiver; a snapshot of what a
+// webrtc-layer receiver looked like when it was inspected on the signaling
+// thread such that this information can be moved to the main thread in a single
+// PostTask. It is used to surface state changes to make the blink-layer
+// receiver up-to-date.
+//
+// Blink objects live on the main thread and webrtc objects live on the
+// signaling thread. If multiple asynchronous operations begin execution on the
+// main thread they are posted and executed in order on the signaling thread.
+// For example, operation A and operation B are called in JavaScript. When A is
+// done on the signaling thread, webrtc object states will be updated. A
+// callback is posted to the main thread so that blink objects can be updated to
+// match the result of operation A. But if callback A tries to inspect the
+// webrtc objects from the main thread this requires posting back to the
+// signaling thread and waiting, which also includes waiting for the previously
+// posted task: operation B. Inspecting the webrtc object like this does not
+// guarantee you to get the state of operation A.
+//
+// As such, all state changes associated with an operation have to be surfaced
+// in the same callback. This includes copying any states into a separate object
+// so that it can be inspected on the main thread without any additional thread
+// hops.
+//
+// The RtpReceiverState is a snapshot of what the webrtc::RtpReceiverInterface
+// looked like when the RtpReceiverState was created on the signaling thread. It
+// also takes care of initializing track adapters, such that we have access to a
+// blink track corresponding to the webrtc track of the receiver.
+//
+// Except for initialization logic and operator=(), the RtpReceiverState is
+// immutable and only accessible on the main thread.
+//
+// TODO(hbos): [Onion Soup] When the sender implementation is moved to blink
+// this will be part of the blink sender instead of the content sender.
+// https://crbug.com/787254
+class CONTENT_EXPORT RtpReceiverState {
+ public:
+ RtpReceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_ids);
+ RtpReceiverState(RtpReceiverState&&);
+ RtpReceiverState(const RtpReceiverState&) = delete;
+ ~RtpReceiverState();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ RtpReceiverState& operator=(RtpReceiverState&&);
+ RtpReceiverState& operator=(const RtpReceiverState&) = delete;
+
+ bool is_initialized() const;
+ void Initialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const;
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver() const;
+ const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+ track_ref() const;
+ const std::vector<std::string>& stream_ids() const;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
+ bool is_initialized_;
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
+ std::vector<std::string> stream_ids_;
+};
+
// Used to surface |webrtc::RtpReceiverInterface| to blink. Multiple
// |RTCRtpReceiver|s could reference the same webrtc receiver; |id| is the value
// of the pointer to the webrtc receiver.
@@ -30,35 +101,23 @@ class CONTENT_EXPORT RTCRtpReceiver : public blink::WebRTCRtpReceiver {
RTCRtpReceiver(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- track_adapter,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs);
+ RtpReceiverState state);
RTCRtpReceiver(const RTCRtpReceiver& other);
~RTCRtpReceiver() override;
RTCRtpReceiver& operator=(const RTCRtpReceiver& other);
- // Creates a shallow copy of the receiver, representing the same underlying
- // webrtc receiver as the original.
- std::unique_ptr<RTCRtpReceiver> ShallowCopy() const;
+ const RtpReceiverState& state() const;
+ void set_state(RtpReceiverState state);
+ std::unique_ptr<blink::WebRTCRtpReceiver> ShallowCopy() const override;
uintptr_t Id() const override;
const blink::WebMediaStreamTrack& Track() const override;
- blink::WebVector<blink::WebMediaStream> Streams() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
GetSources() override;
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
- webrtc::RtpReceiverInterface* webrtc_receiver() const;
- const webrtc::MediaStreamTrackInterface& webrtc_track() const;
- bool HasStream(const webrtc::MediaStreamInterface* webrtc_stream) const;
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- StreamAdapterRefs() const;
-
private:
class RTCRtpReceiverInternal;
struct RTCRtpReceiverInternalTraits;
@@ -66,6 +125,31 @@ class CONTENT_EXPORT RTCRtpReceiver : public blink::WebRTCRtpReceiver {
scoped_refptr<RTCRtpReceiverInternal> internal_;
};
+class CONTENT_EXPORT RTCRtpReceiverOnlyTransceiver
+ : public blink::WebRTCRtpTransceiver {
+ public:
+ RTCRtpReceiverOnlyTransceiver(
+ std::unique_ptr<blink::WebRTCRtpReceiver> receiver);
+ ~RTCRtpReceiverOnlyTransceiver() override;
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ std::unique_ptr<blink::WebRTCRtpReceiver> receiver_;
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_RECEIVER_H_
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
index f55c2b22c4c..ebe77e3780c 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
@@ -16,7 +16,6 @@
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
#include "content/renderer/media/webrtc/test/webrtc_stats_report_obtainer.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -34,10 +33,8 @@ class RTCRtpReceiverTest : public ::testing::Test {
void SetUp() override {
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- stream_map_ = new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
+ track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_thread_);
peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
dependency_factory_.get(), nullptr);
}
@@ -63,23 +60,23 @@ class RTCRtpReceiverTest : public ::testing::Test {
std::unique_ptr<RTCRtpReceiver> CreateReceiver(
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) {
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter;
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
base::RunLoop run_loop;
dependency_factory_->GetWebRtcSignalingThread()->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpReceiverTest::CreateReceiverOnSignalingThread,
base::Unretained(this), std::move(webrtc_track),
- base::Unretained(&track_adapter),
+ base::Unretained(&track_ref),
base::Unretained(&run_loop)));
run_loop.Run();
DCHECK(mock_webrtc_receiver_);
- DCHECK(track_adapter);
- return std::make_unique<RTCRtpReceiver>(
- peer_connection_.get(), main_thread_,
- dependency_factory_->GetWebRtcSignalingThread(),
- mock_webrtc_receiver_.get(), std::move(track_adapter),
- std::vector<
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>());
+ DCHECK(track_ref);
+ RtpReceiverState state(
+ main_thread_, dependency_factory_->GetWebRtcSignalingThread(),
+ mock_webrtc_receiver_.get(), std::move(track_ref), {});
+ state.Initialize();
+ return std::make_unique<RTCRtpReceiver>(peer_connection_.get(),
+ std::move(state));
}
scoped_refptr<WebRTCStatsReportObtainer> GetStats() {
@@ -92,14 +89,11 @@ class RTCRtpReceiverTest : public ::testing::Test {
protected:
void CreateReceiverOnSignalingThread(
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>*
- track_adapter,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref,
base::RunLoop* run_loop) {
mock_webrtc_receiver_ =
new rtc::RefCountedObject<webrtc::MockRtpReceiver>();
- *track_adapter =
- stream_map_->track_adapter_map()->GetOrCreateRemoteTrackAdapter(
- webrtc_track);
+ *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track);
run_loop->Quit();
}
@@ -110,7 +104,7 @@ class RTCRtpReceiverTest : public ::testing::Test {
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
rtc::scoped_refptr<webrtc::MockRtpReceiver> mock_webrtc_receiver_;
std::unique_ptr<RTCRtpReceiver> receiver_;
@@ -122,25 +116,25 @@ TEST_F(RTCRtpReceiverTest, CreateReceiver) {
receiver_ = CreateReceiver(webrtc_track);
EXPECT_FALSE(receiver_->Track().IsNull());
EXPECT_EQ(receiver_->Track().Id().Utf8(), webrtc_track->id());
- EXPECT_EQ(&receiver_->webrtc_track(), webrtc_track);
+ EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
}
TEST_F(RTCRtpReceiverTest, ShallowCopy) {
scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
MockWebRtcAudioTrack::Create("webrtc_track");
receiver_ = CreateReceiver(webrtc_track);
- auto copy = receiver_->ShallowCopy();
- EXPECT_EQ(&receiver_->webrtc_track(), webrtc_track);
- auto* webrtc_receiver = receiver_->webrtc_receiver();
+ auto copy = std::make_unique<RTCRtpReceiver>(*receiver_);
+ EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
+ const auto& webrtc_receiver = receiver_->state().webrtc_receiver();
auto web_track_unique_id = receiver_->Track().UniqueId();
// Copy is identical to original.
- EXPECT_EQ(copy->webrtc_receiver(), webrtc_receiver);
- EXPECT_EQ(&copy->webrtc_track(), webrtc_track);
+ EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
+ EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id);
// Copy keeps the internal state alive.
receiver_.reset();
- EXPECT_EQ(copy->webrtc_receiver(), webrtc_receiver);
- EXPECT_EQ(&copy->webrtc_track(), webrtc_track);
+ EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
+ EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id);
}
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
index 528c8d26a15..a2d16ec7de7 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -36,6 +36,100 @@ void OnSetParametersCompleted(blink::WebRTCVoidRequest request,
} // namespace
+RtpSenderState::RtpSenderState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_ids)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ webrtc_sender_(std::move(webrtc_sender)),
+ is_initialized_(false),
+ track_ref_(std::move(track_ref)),
+ stream_ids_(std::move(stream_ids)) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+ DCHECK(webrtc_sender_);
+}
+
+RtpSenderState::RtpSenderState(RtpSenderState&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ webrtc_sender_(std::move(other.webrtc_sender_)),
+ is_initialized_(other.is_initialized_),
+ track_ref_(std::move(other.track_ref_)),
+ stream_ids_(std::move(other.stream_ids_)) {
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+RtpSenderState::~RtpSenderState() {
+ // It's OK to not be on the main thread if this state has been moved, in which
+ // case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+RtpSenderState& RtpSenderState::operator=(RtpSenderState&& other) {
+ DCHECK_EQ(main_task_runner_, other.main_task_runner_);
+ DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_);
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ webrtc_sender_ = std::move(other.webrtc_sender_);
+ is_initialized_ = other.is_initialized_;
+ track_ref_ = std::move(other.track_ref_);
+ stream_ids_ = std::move(other.stream_ids_);
+ return *this;
+}
+
+bool RtpSenderState::is_initialized() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return is_initialized_;
+}
+
+void RtpSenderState::Initialize() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (track_ref_)
+ track_ref_->InitializeOnMainThread();
+ is_initialized_ = true;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> RtpSenderState::main_task_runner()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return main_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpSenderState::signaling_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return signaling_task_runner_;
+}
+
+scoped_refptr<webrtc::RtpSenderInterface> RtpSenderState::webrtc_sender()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return webrtc_sender_;
+}
+
+const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+RtpSenderState::track_ref() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return track_ref_;
+}
+
+void RtpSenderState::set_track_ref(
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(!is_initialized_ || !track_ref || track_ref->is_initialized());
+ track_ref_ = std::move(track_ref);
+}
+
+std::vector<std::string> RtpSenderState::stream_ids() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return stream_ids_;
+}
+
class RTCRtpSender::RTCRtpSenderInternal
: public base::RefCountedThreadSafe<
RTCRtpSender::RTCRtpSenderInternal,
@@ -43,86 +137,42 @@ class RTCRtpSender::RTCRtpSenderInternal
public:
RTCRtpSenderInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- blink::WebMediaStreamTrack web_track,
- std::vector<blink::WebMediaStream> web_streams)
- : native_peer_connection_(std::move(native_peer_connection)),
- main_thread_(std::move(main_thread)),
- signaling_thread_(std::move(signaling_thread)),
- stream_map_(std::move(stream_map)),
- webrtc_sender_(std::move(webrtc_sender)) {
- DCHECK(main_thread_);
- DCHECK(signaling_thread_);
- DCHECK(stream_map_);
- DCHECK(webrtc_sender_);
- if (!web_track.IsNull()) {
- track_ref_ =
- stream_map_->track_adapter_map()->GetOrCreateLocalTrackAdapter(
- web_track);
- }
- for (size_t i = 0; i < web_streams.size(); ++i) {
- if (!web_streams[i].IsNull()) {
- stream_refs_.push_back(
- stream_map_->GetOrCreateLocalStreamAdapter(web_streams[i]));
- }
- }
- }
-
- RTCRtpSenderInternal(
- scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs)
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpSenderState state)
: native_peer_connection_(std::move(native_peer_connection)),
- main_thread_(std::move(main_thread)),
- signaling_thread_(std::move(signaling_thread)),
- stream_map_(std::move(stream_map)),
- webrtc_sender_(std::move(webrtc_sender)),
- track_ref_(std::move(track_ref)),
- stream_refs_(std::move(stream_refs)) {
- DCHECK(main_thread_);
- DCHECK(signaling_thread_);
- DCHECK(stream_map_);
- DCHECK(webrtc_sender_);
- }
-
- webrtc::RtpSenderInterface* webrtc_sender() const {
- return webrtc_sender_.get();
+ track_map_(std::move(track_map)),
+ main_task_runner_(state.main_task_runner()),
+ signaling_task_runner_(state.signaling_task_runner()),
+ webrtc_sender_(state.webrtc_sender()),
+ state_(std::move(state)) {
+ DCHECK(track_map_);
+ DCHECK(state_.is_initialized());
}
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref()
- const {
- return track_ref_ ? track_ref_->Copy() : nullptr;
+ const RtpSenderState& state() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return state_;
}
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs() const {
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_ref_copies(stream_refs_.size());
- for (size_t i = 0; i < stream_refs_.size(); ++i)
- stream_ref_copies[i] = stream_refs_[i]->Copy();
- return stream_ref_copies;
+ void set_state(RtpSenderState state) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK_EQ(state.main_task_runner(), main_task_runner_);
+ DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_);
+ DCHECK(state.webrtc_sender() == webrtc_sender_);
+ DCHECK(state.is_initialized());
+ state_ = std::move(state);
}
void ReplaceTrack(blink::WebMediaStreamTrack with_track,
base::OnceCallback<void(bool)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
webrtc::MediaStreamTrackInterface* webrtc_track = nullptr;
if (!with_track.IsNull()) {
- track_ref =
- stream_map_->track_adapter_map()->GetOrCreateLocalTrackAdapter(
- with_track);
+ track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track);
webrtc_track = track_ref->webrtc_track();
}
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::ReplaceTrackOnSignalingThread,
@@ -131,14 +181,16 @@ class RTCRtpSender::RTCRtpSenderInternal
}
std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender() const {
- // The webrtc_sender is a proxy, so this is a blocking call to the
+ // The webrtc_sender() is a proxy, so this is a blocking call to the
// webrtc signalling thread.
- DCHECK(main_thread_->BelongsToCurrentThread());
- auto dtmf_sender = webrtc_sender()->GetDtmfSender();
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ auto dtmf_sender = webrtc_sender_->GetDtmfSender();
return std::make_unique<RtcDtmfSenderHandler>(dtmf_sender);
}
std::unique_ptr<webrtc::RtpParameters> GetParameters() {
+ // The webrtc_sender() is a proxy, so this is a blocking call to the
+ // webrtc signalling thread.
parameters_ = webrtc_sender_->GetParameters();
return std::make_unique<webrtc::RtpParameters>(parameters_);
}
@@ -146,7 +198,7 @@ class RTCRtpSender::RTCRtpSenderInternal
void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters> encodings,
webrtc::DegradationPreference degradation_preference,
base::OnceCallback<void(webrtc::RTCError)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
webrtc::RtpParameters new_parameters = parameters_;
@@ -171,7 +223,7 @@ class RTCRtpSender::RTCRtpSenderInternal
encoding.scale_resolution_down_by;
}
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::SetParametersOnSignalingThread,
@@ -179,7 +231,7 @@ class RTCRtpSender::RTCRtpSenderInternal
}
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::GetStatsOnSignalingThread,
@@ -187,13 +239,14 @@ class RTCRtpSender::RTCRtpSenderInternal
}
bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc) {
- if (!pc->RemoveTrack(webrtc_sender_))
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (!pc->RemoveTrack(webrtc_sender_.get()))
return false;
// TODO(hbos): Removing the track should null the sender's track, or we
// should do |webrtc_sender_->SetTrack(null)| but that is not allowed on a
// stopped sender. In the meantime, there is a discrepancy between layers.
// https://crbug.com/webrtc/7945
- track_ref_.reset();
+ state_.set_track_ref(nullptr);
return true;
}
@@ -202,7 +255,7 @@ class RTCRtpSender::RTCRtpSenderInternal
~RTCRtpSenderInternal() {
// Ensured by destructor traits.
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
}
// |webrtc_track| is passed as an argument because |track_ref->webrtc_track()|
@@ -211,9 +264,9 @@ class RTCRtpSender::RTCRtpSenderInternal
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
webrtc::MediaStreamTrackInterface* webrtc_track,
base::OnceCallback<void(bool)> callback) {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
+ DCHECK(signaling_task_runner_->BelongsToCurrentThread());
bool result = webrtc_sender_->SetTrack(webrtc_track);
- main_thread_->PostTask(
+ main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::ReplaceTrackCallback, this,
@@ -224,25 +277,25 @@ class RTCRtpSender::RTCRtpSenderInternal
bool result,
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
base::OnceCallback<void(bool)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
if (result)
- track_ref_ = std::move(track_ref);
+ state_.set_track_ref(std::move(track_ref));
std::move(callback).Run(result);
}
void GetStatsOnSignalingThread(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- native_peer_connection_->GetStats(webrtc_sender_,
- RTCStatsCollectorCallbackImpl::Create(
- main_thread_, std::move(callback)));
+ native_peer_connection_->GetStats(
+ webrtc_sender_.get(), RTCStatsCollectorCallbackImpl::Create(
+ main_task_runner_, std::move(callback)));
}
void SetParametersOnSignalingThread(
webrtc::RtpParameters parameters,
base::OnceCallback<void(webrtc::RTCError)> callback) {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
+ DCHECK(signaling_task_runner_->BelongsToCurrentThread());
webrtc::RTCError result = webrtc_sender_->SetParameters(parameters);
- main_thread_->PostTask(
+ main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::SetParametersCallback, this,
@@ -252,23 +305,19 @@ class RTCRtpSender::RTCRtpSenderInternal
void SetParametersCallback(
webrtc::RTCError result,
base::OnceCallback<void(webrtc::RTCError)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
std::move(callback).Run(std::move(result));
}
const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
- const scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_;
- const rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
- // The track adapter is the glue between blink and webrtc layer tracks.
- // Keeping a reference to the adapter ensures it is not disposed, as is
- // required as long as the webrtc layer track is in use by the sender.
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
- // Similarly, reference needs to be kept to the stream adapters of the
- // sender's associated set of streams.
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs_;
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+ // Task runners and webrtc sender: Same information as stored in
+ // |state_| but const and safe to touch on the signaling thread to
+ // avoid race with set_state().
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ const scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
+ RtpSenderState state_;
webrtc::RtpParameters parameters_;
};
@@ -280,8 +329,8 @@ struct RTCRtpSender::RTCRtpSenderInternalTraits {
static void Destruct(const RTCRtpSenderInternal* sender) {
// RTCRtpSenderInternal owns AdapterRefs which have to be destroyed on the
// main thread, this ensures delete always happens there.
- if (!sender->main_thread_->BelongsToCurrentThread()) {
- sender->main_thread_->PostTask(
+ if (!sender->main_task_runner_->BelongsToCurrentThread()) {
+ sender->main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpSender::RTCRtpSenderInternalTraits::Destruct,
base::Unretained(sender)));
@@ -297,36 +346,11 @@ uintptr_t RTCRtpSender::getId(const webrtc::RtpSenderInterface* webrtc_sender) {
RTCRtpSender::RTCRtpSender(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- blink::WebMediaStreamTrack web_track,
- std::vector<blink::WebMediaStream> web_streams)
- : internal_(new RTCRtpSenderInternal(std::move(native_peer_connection),
- std::move(main_thread),
- std::move(signaling_thread),
- std::move(stream_map),
- std::move(webrtc_sender),
- std::move(web_track),
- std::move(web_streams))) {}
-
-RTCRtpSender::RTCRtpSender(
- scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs)
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpSenderState state)
: internal_(new RTCRtpSenderInternal(std::move(native_peer_connection),
- std::move(main_thread),
- std::move(signaling_thread),
- std::move(stream_map),
- std::move(webrtc_sender),
- std::move(track_ref),
- std::move(stream_refs))) {}
+ std::move(track_map),
+ std::move(state))) {}
RTCRtpSender::RTCRtpSender(const RTCRtpSender& other)
: internal_(other.internal_) {}
@@ -338,19 +362,35 @@ RTCRtpSender& RTCRtpSender::operator=(const RTCRtpSender& other) {
return *this;
}
-std::unique_ptr<RTCRtpSender> RTCRtpSender::ShallowCopy() const {
+const RtpSenderState& RTCRtpSender::state() const {
+ return internal_->state();
+}
+
+void RTCRtpSender::set_state(RtpSenderState state) {
+ internal_->set_state(std::move(state));
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpSender::ShallowCopy() const {
return std::make_unique<RTCRtpSender>(*this);
}
uintptr_t RTCRtpSender::Id() const {
- return getId(internal_->webrtc_sender());
+ return getId(internal_->state().webrtc_sender().get());
}
blink::WebMediaStreamTrack RTCRtpSender::Track() const {
- auto track_ref = internal_->track_ref();
+ const auto& track_ref = internal_->state().track_ref();
return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack();
}
+blink::WebVector<blink::WebString> RTCRtpSender::StreamIds() const {
+ const auto& stream_ids = internal_->state().stream_ids();
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size());
+ for (size_t i = 0; i < stream_ids.size(); ++i)
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]);
+ return web_stream_ids;
+}
+
void RTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track,
blink::WebRTCVoidRequest request) {
internal_->ReplaceTrack(
@@ -381,20 +421,6 @@ void RTCRtpSender::GetStats(
internal_->GetStats(std::move(callback));
}
-webrtc::RtpSenderInterface* RTCRtpSender::webrtc_sender() const {
- return internal_->webrtc_sender();
-}
-
-const webrtc::MediaStreamTrackInterface* RTCRtpSender::webrtc_track() const {
- auto track_ref = internal_->track_ref();
- return track_ref ? track_ref->webrtc_track() : nullptr;
-}
-
-std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
-RTCRtpSender::stream_refs() const {
- return internal_->stream_refs();
-}
-
void RTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track,
base::OnceCallback<void(bool)> callback) {
internal_->ReplaceTrack(std::move(with_track), std::move(callback));
@@ -405,4 +431,65 @@ bool RTCRtpSender::RemoveFromPeerConnection(
return internal_->RemoveFromPeerConnection(pc);
}
+RTCRtpSenderOnlyTransceiver::RTCRtpSenderOnlyTransceiver(
+ std::unique_ptr<blink::WebRTCRtpSender> sender)
+ : sender_(std::move(sender)) {
+ DCHECK(sender_);
+}
+
+RTCRtpSenderOnlyTransceiver::~RTCRtpSenderOnlyTransceiver() {}
+
+blink::WebRTCRtpTransceiverImplementationType
+RTCRtpSenderOnlyTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly;
+}
+
+uintptr_t RTCRtpSenderOnlyTransceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+blink::WebString RTCRtpSenderOnlyTransceiver::Mid() const {
+ NOTIMPLEMENTED();
+ return blink::WebString();
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpSenderOnlyTransceiver::Sender()
+ const {
+ return sender_->ShallowCopy();
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver>
+RTCRtpSenderOnlyTransceiver::Receiver() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+bool RTCRtpSenderOnlyTransceiver::Stopped() const {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+webrtc::RtpTransceiverDirection RTCRtpSenderOnlyTransceiver::Direction() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
+void RTCRtpSenderOnlyTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ NOTIMPLEMENTED();
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpSenderOnlyTransceiver::CurrentDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpSenderOnlyTransceiver::FiredDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h
index 990b21fb64c..7a96b39e38f 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h
@@ -11,10 +11,10 @@
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/rtpsenderinterface.h"
@@ -22,43 +22,108 @@
namespace content {
+// This class represents the state of a sender; a snapshot of what a
+// webrtc-layer sender looked like when it was inspected on the signaling thread
+// such that this information can be moved to the main thread in a single
+// PostTask. It is used to surface state changes to make the blink-layer sender
+// up-to-date.
+//
+// Blink objects live on the main thread and webrtc objects live on the
+// signaling thread. If multiple asynchronous operations begin execution on the
+// main thread they are posted and executed in order on the signaling thread.
+// For example, operation A and operation B are called in JavaScript. When A is
+// done on the signaling thread, webrtc object states will be updated. A
+// callback is posted to the main thread so that blink objects can be updated to
+// match the result of operation A. But if callback A tries to inspect the
+// webrtc objects from the main thread this requires posting back to the
+// signaling thread and waiting, which also includes waiting for the previously
+// posted task: operation B. Inspecting the webrtc object like this does not
+// guarantee you to get the state of operation A.
+//
+// As such, all state changes associated with an operation have to be surfaced
+// in the same callback. This includes copying any states into a separate object
+// so that it can be inspected on the main thread without any additional thread
+// hops.
+//
+// The RtpSenderState is a snapshot of what the webrtc::RtpSenderInterface
+// looked like when the RtpSenderState was created on the signaling thread. It
+// also takes care of initializing track adapters, such that we have access to a
+// blink track corresponding to the webrtc track of the sender.
+//
+// Except for initialization logic and operator=(), the RtpSenderState is
+// immutable and only accessible on the main thread.
+//
+// TODO(hbos): [Onion Soup] When the sender implementation is moved to blink
+// this will be part of the blink sender instead of the content sender.
+// https://crbug.com/787254
+class CONTENT_EXPORT RtpSenderState {
+ public:
+ RtpSenderState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_ids);
+ RtpSenderState(RtpSenderState&&);
+ RtpSenderState(const RtpSenderState&) = delete;
+ ~RtpSenderState();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ RtpSenderState& operator=(RtpSenderState&&);
+ RtpSenderState& operator=(const RtpSenderState&) = delete;
+
+ bool is_initialized() const;
+ void Initialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const;
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender() const;
+ const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+ track_ref() const;
+ void set_track_ref(
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref);
+ std::vector<std::string> stream_ids() const;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
+ bool is_initialized_;
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
+ std::vector<std::string> stream_ids_;
+};
+
// Used to surface |webrtc::RtpSenderInterface| to blink. Multiple
// |RTCRtpSender|s could reference the same webrtc sender; |id| is the value
// of the pointer to the webrtc sender.
+// TODO(hbos): [Onion Soup] Move all of the implementation inside the blink
+// object and remove this class and interface. The blink object is reference
+// counted and we can get rid of this "Web"-copyable with "internal" nonsense,
+// all the blink object will need is the RtpSenderState. Requires coordination
+// with transceivers and receivers since these are tightly coupled.
+// https://crbug.com/787254
class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender {
public:
static uintptr_t getId(const webrtc::RtpSenderInterface* webrtc_sender);
RTCRtpSender(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- blink::WebMediaStreamTrack web_track,
- std::vector<blink::WebMediaStream> web_streams);
- RTCRtpSender(
- scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs);
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpSenderState state);
RTCRtpSender(const RTCRtpSender& other);
~RTCRtpSender() override;
-
RTCRtpSender& operator=(const RTCRtpSender& other);
- // Creates a shallow copy of the sender, representing the same underlying
- // webrtc sender as the original.
- // TODO(hbos): Remove in favor of constructor. https://crbug.com/790007
- std::unique_ptr<RTCRtpSender> ShallowCopy() const;
+ const RtpSenderState& state() const;
+ void set_state(RtpSenderState state);
// blink::WebRTCRtpSender.
+ std::unique_ptr<blink::WebRTCRtpSender> ShallowCopy() const override;
uintptr_t Id() const override;
blink::WebMediaStreamTrack Track() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
void ReplaceTrack(blink::WebMediaStreamTrack with_track,
blink::WebRTCVoidRequest request) override;
std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender()
@@ -69,10 +134,6 @@ class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender {
blink::WebRTCVoidRequest) override;
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
- webrtc::RtpSenderInterface* webrtc_sender() const;
- const webrtc::MediaStreamTrackInterface* webrtc_track() const;
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs() const;
// The ReplaceTrack() that takes a blink::WebRTCVoidRequest is implemented on
// top of this, which returns the result in a callback instead. Allows doing
// ReplaceTrack() without having a blink::WebRTCVoidRequest, which can only be
@@ -88,6 +149,30 @@ class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender {
scoped_refptr<RTCRtpSenderInternal> internal_;
};
+class CONTENT_EXPORT RTCRtpSenderOnlyTransceiver
+ : public blink::WebRTCRtpTransceiver {
+ public:
+ RTCRtpSenderOnlyTransceiver(std::unique_ptr<blink::WebRTCRtpSender> sender);
+ ~RTCRtpSenderOnlyTransceiver() override;
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ std::unique_ptr<blink::WebRTCRtpSender> sender_;
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_SENDER_H_
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
index eb086d2e0d2..0f3f27f9dad 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
@@ -16,7 +16,6 @@
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
#include "content/renderer/media/webrtc/test/webrtc_stats_report_obtainer.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -40,10 +39,8 @@ class RTCRtpSenderTest : public ::testing::Test {
void SetUp() override {
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- stream_map_ = new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
+ track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_thread_);
peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
dependency_factory_.get(), nullptr);
mock_webrtc_sender_ = new rtc::RefCountedObject<webrtc::MockRtpSender>();
@@ -84,11 +81,18 @@ class RTCRtpSenderTest : public ::testing::Test {
std::unique_ptr<RTCRtpSender> CreateSender(
blink::WebMediaStreamTrack web_track) {
- return std::make_unique<RTCRtpSender>(
- peer_connection_.get(), main_thread_,
- dependency_factory_->GetWebRtcSignalingThread(), stream_map_,
- mock_webrtc_sender_.get(), std::move(web_track),
- std::vector<blink::WebMediaStream>());
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+ if (!web_track.IsNull()) {
+ track_ref = track_map_->GetOrCreateLocalTrackAdapter(web_track);
+ DCHECK(track_ref->is_initialized());
+ }
+ RtpSenderState sender_state(main_thread_,
+ dependency_factory_->GetWebRtcSignalingThread(),
+ mock_webrtc_sender_.get(), std::move(track_ref),
+ std::vector<std::string>());
+ sender_state.Initialize();
+ return std::make_unique<RTCRtpSender>(peer_connection_.get(), track_map_,
+ std::move(sender_state));
}
// Calls replaceTrack(), which is asynchronous, returning a callback that when
@@ -139,7 +143,7 @@ class RTCRtpSenderTest : public ::testing::Test {
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
rtc::scoped_refptr<webrtc::MockRtpSender> mock_webrtc_sender_;
std::unique_ptr<RTCRtpSender> sender_;
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
new file mode 100644
index 00000000000..7bdda93416d
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
@@ -0,0 +1,357 @@
+// Copyright 2018 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/webrtc/rtc_rtp_transceiver.h"
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+
+namespace content {
+
+RtpTransceiverState::RtpTransceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
+ base::Optional<RtpSenderState> sender_state,
+ base::Optional<RtpReceiverState> receiver_state,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction,
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ webrtc_transceiver_(std::move(webrtc_transceiver)),
+ is_initialized_(false),
+ sender_state_(std::move(sender_state)),
+ receiver_state_(std::move(receiver_state)),
+ mid_(std::move(mid)),
+ stopped_(std::move(stopped)),
+ direction_(std::move(direction)),
+ current_direction_(std::move(current_direction)),
+ fired_direction_(std::move(fired_direction)) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+ DCHECK(webrtc_transceiver_);
+}
+
+RtpTransceiverState::RtpTransceiverState(RtpTransceiverState&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ webrtc_transceiver_(std::move(other.webrtc_transceiver_)),
+ is_initialized_(other.is_initialized_),
+ sender_state_(std::move(other.sender_state_)),
+ receiver_state_(std::move(other.receiver_state_)),
+ mid_(std::move(other.mid_)),
+ stopped_(std::move(other.stopped_)),
+ direction_(std::move(other.direction_)),
+ current_direction_(std::move(other.current_direction_)),
+ fired_direction_(std::move(other.fired_direction_)) {
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+RtpTransceiverState::~RtpTransceiverState() {
+ // It's OK to not be on the main thread if this state has been moved, in which
+ // case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+RtpTransceiverState& RtpTransceiverState::operator=(
+ RtpTransceiverState&& other) {
+ DCHECK_EQ(main_task_runner_, other.main_task_runner_);
+ DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_);
+ // Need to be on main thread for sender/receiver state's destructor that can
+ // be triggered by replacing .
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ webrtc_transceiver_ = std::move(other.webrtc_transceiver_);
+ is_initialized_ = other.is_initialized_;
+ sender_state_ = std::move(other.sender_state_);
+ receiver_state_ = std::move(other.receiver_state_);
+ mid_ = std::move(other.mid_);
+ stopped_ = std::move(other.stopped_);
+ direction_ = std::move(other.direction_);
+ current_direction_ = std::move(other.current_direction_);
+ fired_direction_ = std::move(other.fired_direction_);
+ return *this;
+}
+
+bool RtpTransceiverState::is_initialized() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return is_initialized_;
+}
+
+void RtpTransceiverState::Initialize() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (sender_state_)
+ sender_state_->Initialize();
+ if (receiver_state_)
+ receiver_state_->Initialize();
+ is_initialized_ = true;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpTransceiverState::main_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return main_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpTransceiverState::signaling_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return signaling_task_runner_;
+}
+
+scoped_refptr<webrtc::RtpTransceiverInterface>
+RtpTransceiverState::webrtc_transceiver() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return webrtc_transceiver_;
+}
+
+const base::Optional<RtpSenderState>& RtpTransceiverState::sender_state()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return sender_state_;
+}
+
+RtpSenderState RtpTransceiverState::MoveSenderState() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ base::Optional<RtpSenderState> temp(base::nullopt);
+ sender_state_.swap(temp);
+ return *std::move(temp);
+}
+
+const base::Optional<RtpReceiverState>& RtpTransceiverState::receiver_state()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return receiver_state_;
+}
+
+RtpReceiverState RtpTransceiverState::MoveReceiverState() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ base::Optional<RtpReceiverState> temp(base::nullopt);
+ receiver_state_.swap(temp);
+ return *std::move(temp);
+}
+
+base::Optional<std::string> RtpTransceiverState::mid() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return mid_;
+}
+
+bool RtpTransceiverState::stopped() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return stopped_;
+}
+
+webrtc::RtpTransceiverDirection RtpTransceiverState::direction() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return direction_;
+}
+
+void RtpTransceiverState::set_direction(
+ webrtc::RtpTransceiverDirection direction) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ direction_ = direction;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RtpTransceiverState::current_direction() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return current_direction_;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RtpTransceiverState::fired_direction() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return fired_direction_;
+}
+
+class RTCRtpTransceiver::RTCRtpTransceiverInternal
+ : public base::RefCountedThreadSafe<
+ RTCRtpTransceiver::RTCRtpTransceiverInternal,
+ RTCRtpTransceiver::RTCRtpTransceiverInternalTraits> {
+ public:
+ RTCRtpTransceiverInternal(
+ scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpTransceiverState state)
+ : main_task_runner_(state.main_task_runner()),
+ signaling_task_runner_(state.signaling_task_runner()),
+ webrtc_transceiver_(state.webrtc_transceiver()),
+ state_(std::move(state)) {
+ sender_ = std::make_unique<RTCRtpSender>(native_peer_connection, track_map,
+ state_.MoveSenderState());
+ receiver_ = std::make_unique<RTCRtpReceiver>(native_peer_connection,
+ state_.MoveReceiverState());
+ }
+
+ const RtpTransceiverState& state() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return state_;
+ }
+
+ void set_state(RtpTransceiverState state) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK_EQ(state.main_task_runner(), main_task_runner_);
+ DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_);
+ DCHECK(state.webrtc_transceiver() == webrtc_transceiver_);
+ DCHECK(state.is_initialized());
+ state_ = std::move(state);
+ sender_->set_state(state_.MoveSenderState());
+ receiver_->set_state(state_.MoveReceiverState());
+ }
+
+ RTCRtpSender* content_sender() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return sender_.get();
+ }
+
+ RTCRtpReceiver* content_receiver() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return receiver_.get();
+ }
+
+ void SetDirection(webrtc::RtpTransceiverDirection direction) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ // This implicitly performs a blocking invoke on the webrtc signaling thread
+ // due to use of PROXY references for |webrtc_transceiver_|.
+ webrtc_transceiver_->SetDirection(direction);
+ state_.set_direction(webrtc_transceiver_->direction());
+ }
+
+ private:
+ friend struct RTCRtpTransceiver::RTCRtpTransceiverInternalTraits;
+
+ ~RTCRtpTransceiverInternal() {
+ // Ensured by destructor traits.
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ }
+
+ // Task runners and webrtc transceiver: Same information as stored in |state_|
+ // but const and safe to touch on the signaling thread to avoid race with
+ // set_state().
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ const scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver_;
+ RtpTransceiverState state_;
+ std::unique_ptr<RTCRtpSender> sender_;
+ std::unique_ptr<RTCRtpReceiver> receiver_;
+};
+
+struct RTCRtpTransceiver::RTCRtpTransceiverInternalTraits {
+ private:
+ friend class base::RefCountedThreadSafe<RTCRtpTransceiverInternal,
+ RTCRtpTransceiverInternalTraits>;
+
+ static void Destruct(const RTCRtpTransceiverInternal* transceiver) {
+ // RTCRtpTransceiverInternal owns AdapterRefs which have to be destroyed on
+ // the main thread, this ensures delete always happens there.
+ if (!transceiver->main_task_runner_->BelongsToCurrentThread()) {
+ transceiver->main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &RTCRtpTransceiver::RTCRtpTransceiverInternalTraits::Destruct,
+ base::Unretained(transceiver)));
+ return;
+ }
+ delete transceiver;
+ }
+};
+
+uintptr_t RTCRtpTransceiver::GetId(
+ const webrtc::RtpTransceiverInterface* webrtc_transceiver) {
+ return reinterpret_cast<uintptr_t>(webrtc_transceiver);
+}
+
+RTCRtpTransceiver::RTCRtpTransceiver(
+ scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpTransceiverState transceiver_state)
+ : internal_(new RTCRtpTransceiverInternal(std::move(native_peer_connection),
+ std::move(track_map),
+ std::move(transceiver_state))) {}
+
+RTCRtpTransceiver::RTCRtpTransceiver(const RTCRtpTransceiver& other)
+ : internal_(other.internal_) {}
+
+RTCRtpTransceiver::~RTCRtpTransceiver() {}
+
+RTCRtpTransceiver& RTCRtpTransceiver::operator=(
+ const RTCRtpTransceiver& other) {
+ internal_ = other.internal_;
+ return *this;
+}
+
+std::unique_ptr<RTCRtpTransceiver> RTCRtpTransceiver::ShallowCopy() const {
+ return std::make_unique<RTCRtpTransceiver>(*this);
+}
+
+const RtpTransceiverState& RTCRtpTransceiver::state() const {
+ return internal_->state();
+}
+
+RTCRtpSender* RTCRtpTransceiver::content_sender() {
+ return internal_->content_sender();
+}
+
+RTCRtpReceiver* RTCRtpTransceiver::content_receiver() {
+ return internal_->content_receiver();
+}
+
+void RTCRtpTransceiver::set_state(RtpTransceiverState transceiver_state) {
+ internal_->set_state(std::move(transceiver_state));
+}
+
+blink::WebRTCRtpTransceiverImplementationType
+RTCRtpTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver;
+}
+
+uintptr_t RTCRtpTransceiver::Id() const {
+ return GetId(internal_->state().webrtc_transceiver().get());
+}
+
+blink::WebString RTCRtpTransceiver::Mid() const {
+ const auto& mid = internal_->state().mid();
+ return mid ? blink::WebString::FromUTF8(*mid)
+ : blink::WebString(); // IsNull()
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpTransceiver::Sender() const {
+ return internal_->content_sender()->ShallowCopy();
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver> RTCRtpTransceiver::Receiver() const {
+ return internal_->content_receiver()->ShallowCopy();
+}
+
+bool RTCRtpTransceiver::Stopped() const {
+ return internal_->state().stopped();
+}
+
+webrtc::RtpTransceiverDirection RTCRtpTransceiver::Direction() const {
+ return internal_->state().direction();
+}
+
+void RTCRtpTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ internal_->SetDirection(direction);
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpTransceiver::CurrentDirection() const {
+ return internal_->state().current_direction();
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpTransceiver::FiredDirection() const {
+ return internal_->state().fired_direction();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h
new file mode 100644
index 00000000000..5eadedf1955
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h
@@ -0,0 +1,160 @@
+// Copyright 2018 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.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/optional.h"
+#include "base/single_thread_task_runner.h"
+#include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
+#include "content/renderer/media/webrtc/rtc_rtp_sender.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
+#include "third_party/webrtc/api/rtptransceiverinterface.h"
+
+namespace content {
+
+// This class represents the state of a transceiver; a snapshot of what a
+// webrtc-layer transceiver looked like when it was inspected on the signaling
+// thread such that this information can be moved to the main thread in a single
+// PostTask. It is used to surface state changes to make the blink-layer
+// transceiver up-to-date.
+//
+// Blink objects live on the main thread and webrtc objects live on the
+// signaling thread. If multiple asynchronous operations begin execution on the
+// main thread they are posted and executed in order on the signaling thread.
+// For example, operation A and operation B are called in JavaScript. When A is
+// done on the signaling thread, webrtc object states will be updated. A
+// callback is posted to the main thread so that blink objects can be updated to
+// match the result of operation A. But if callback A tries to inspect the
+// webrtc objects from the main thread this requires posting back to the
+// signaling thread and waiting, which also includes waiting for the previously
+// posted task: operation B. Inspecting the webrtc object like this does not
+// guarantee you to get the state of operation A.
+//
+// As such, all state changes associated with an operation have to be surfaced
+// in the same callback. This includes copying any states into a separate object
+// so that it can be inspected on the main thread without any additional thread
+// hops.
+//
+// The RtpTransceiverState is a snapshot of what the
+// webrtc::RtpTransceiverInterface looked like when the RtpTransceiverState was
+// created on the signaling thread. It also takes care of initializing sender
+// and receiver states, including their track adapters such that we have access
+// to a blink track corresponding to the webrtc tracks of the sender and
+// receiver.
+//
+// Except for initialization logic and operator=(), the RtpTransceiverState is
+// immutable and only accessible on the main thread.
+//
+// TODO(hbos): [Onion Soup] When the transceiver implementation is moved to
+// blink this will be part of the blink transceiver instead of the content
+// transceiver. https://crbug.com/787254
+class CONTENT_EXPORT RtpTransceiverState {
+ public:
+ RtpTransceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
+ base::Optional<RtpSenderState> sender_state,
+ base::Optional<RtpReceiverState> receiver_state,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction,
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction);
+ RtpTransceiverState(RtpTransceiverState&&);
+ RtpTransceiverState(const RtpTransceiverState&) = delete;
+ ~RtpTransceiverState();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ RtpTransceiverState& operator=(RtpTransceiverState&&);
+ RtpTransceiverState& operator=(const RtpTransceiverState&) = delete;
+
+ bool is_initialized() const;
+ void Initialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const;
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver() const;
+ const base::Optional<RtpSenderState>& sender_state() const;
+ RtpSenderState MoveSenderState();
+ const base::Optional<RtpReceiverState>& receiver_state() const;
+ RtpReceiverState MoveReceiverState();
+ base::Optional<std::string> mid() const;
+ bool stopped() const;
+ webrtc::RtpTransceiverDirection direction() const;
+ void set_direction(webrtc::RtpTransceiverDirection);
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction() const;
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction() const;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver_;
+ bool is_initialized_;
+ base::Optional<RtpSenderState> sender_state_;
+ base::Optional<RtpReceiverState> receiver_state_;
+ base::Optional<std::string> mid_;
+ bool stopped_;
+ webrtc::RtpTransceiverDirection direction_;
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction_;
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction_;
+};
+
+// Used to surface |webrtc::RtpTransceiverInterface| to blink. Multiple
+// |RTCRtpTransceiver|s could reference the same webrtc transceiver; |id| is
+// unique per webrtc transceiver.
+// Its methods are accessed on the main thread, internally also performs
+// operations on the signaling thread.
+// TODO(hbos): [Onion Soup] Remove the content layer versions of this class and
+// rely on webrtc directly from blink. Requires coordination with senders and
+// receivers. https://crbug.com/787254
+class CONTENT_EXPORT RTCRtpTransceiver : public blink::WebRTCRtpTransceiver {
+ public:
+ static uintptr_t GetId(
+ const webrtc::RtpTransceiverInterface* webrtc_transceiver);
+
+ RTCRtpTransceiver(
+ scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpTransceiverState state);
+ RTCRtpTransceiver(const RTCRtpTransceiver& other);
+ ~RTCRtpTransceiver() override;
+
+ RTCRtpTransceiver& operator=(const RTCRtpTransceiver& other);
+ std::unique_ptr<RTCRtpTransceiver> ShallowCopy() const;
+
+ const RtpTransceiverState& state() const;
+ void set_state(RtpTransceiverState state);
+ RTCRtpSender* content_sender();
+ RTCRtpReceiver* content_receiver();
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ class RTCRtpTransceiverInternal;
+ struct RTCRtpTransceiverInternalTraits;
+
+ scoped_refptr<RTCRtpTransceiverInternal> internal_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
new file mode 100644
index 00000000000..3690936bfc8
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
@@ -0,0 +1,363 @@
+// Copyright 2018 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/webrtc/rtc_rtp_transceiver.h"
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/optional.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
+#include "content/child/child_process.h"
+#include "content/renderer/media/stream/media_stream_audio_source.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "content/renderer/media/webrtc/webrtc_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_heap.h"
+#include "third_party/webrtc/api/test/mock_rtpreceiver.h"
+#include "third_party/webrtc/api/test/mock_rtpsender.h"
+
+namespace content {
+
+class RTCRtpTransceiverTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
+ main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
+ track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_task_runner_);
+ peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
+ dependency_factory_.get(), nullptr);
+ }
+
+ void TearDown() override {
+ // Syncing up with the signaling thread ensures any pending operations on
+ // that thread are executed. If they post back to the main thread, such as
+ // the sender or receiver destructor traits, this is allowed to execute
+ // before the test shuts down the threads.
+ SyncWithSignalingThread();
+ blink::WebHeap::CollectAllGarbageForTesting();
+ }
+
+ // Wait for the signaling thread to perform any queued tasks, executing tasks
+ // posted to the current thread in the meantime while waiting.
+ void SyncWithSignalingThread() const {
+ base::RunLoop run_loop;
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE, run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const {
+ return dependency_factory_->GetWebRtcSignalingThread();
+ }
+
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ CreateLocalTrackAndAdapter(const std::string& id) {
+ return track_map_->GetOrCreateLocalTrackAdapter(CreateBlinkLocalTrack(id));
+ }
+
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ CreateRemoteTrackAndAdapter(const std::string& id) {
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track =
+ MockWebRtcAudioTrack::Create(id).get();
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+ base::RunLoop run_loop;
+ signaling_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &RTCRtpTransceiverTest::CreateRemoteTrackAdapterOnSignalingThread,
+ base::Unretained(this), std::move(webrtc_track),
+ base::Unretained(&track_ref), base::Unretained(&run_loop)));
+ run_loop.Run();
+ DCHECK(track_ref);
+ return track_ref;
+ }
+
+ rtc::scoped_refptr<FakeRtpSender> CreateWebRtcSender(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::string& stream_id) {
+ return new rtc::RefCountedObject<FakeRtpSender>(
+ std::move(track), std::vector<std::string>({stream_id}));
+ }
+
+ rtc::scoped_refptr<FakeRtpReceiver> CreateWebRtcReceiver(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::string& stream_id) {
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ new rtc::RefCountedObject<MockMediaStream>(stream_id));
+ return new rtc::RefCountedObject<FakeRtpReceiver>(
+ track.get(),
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>(
+ {remote_stream}));
+ }
+
+ rtc::scoped_refptr<FakeRtpTransceiver> CreateWebRtcTransceiver(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction) {
+ DCHECK(!sender->track() ||
+ sender->track()->kind() == receiver->track()->kind());
+ return new rtc::RefCountedObject<FakeRtpTransceiver>(
+ receiver->track()->kind() ==
+ webrtc::MediaStreamTrackInterface::kAudioKind
+ ? cricket::MEDIA_TYPE_AUDIO
+ : cricket::MEDIA_TYPE_VIDEO,
+ std::move(sender), std::move(receiver), std::move(mid), stopped,
+ direction, std::move(current_direction));
+ }
+
+ RtpTransceiverState CreateTransceiverState(
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ sender_track_ref,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ receiver_track_ref) {
+ std::vector<std::string> receiver_stream_ids;
+ for (const auto& stream : webrtc_transceiver->receiver()->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ return RtpTransceiverState(
+ main_task_runner_, signaling_task_runner(), webrtc_transceiver.get(),
+ RtpSenderState(main_task_runner_, signaling_task_runner(),
+ webrtc_transceiver->sender().get(),
+ std::move(sender_track_ref),
+ webrtc_transceiver->sender()->stream_ids()),
+ RtpReceiverState(main_task_runner_, signaling_task_runner(),
+ webrtc_transceiver->receiver().get(),
+ std::move(receiver_track_ref),
+ std::move(receiver_stream_ids)),
+ ToBaseOptional(webrtc_transceiver->mid()),
+ webrtc_transceiver->stopped(), webrtc_transceiver->direction(),
+ ToBaseOptional(webrtc_transceiver->current_direction()),
+ ToBaseOptional(webrtc_transceiver->fired_direction()));
+ }
+
+ protected:
+ blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) {
+ blink::WebMediaStreamSource web_source;
+ web_source.Initialize(
+ blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio,
+ blink::WebString::FromUTF8("local_audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true);
+ // Takes ownership of |audio_source|.
+ web_source.SetExtraData(audio_source);
+
+ blink::WebMediaStreamTrack web_track;
+ web_track.Initialize(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(web_track);
+ return web_track;
+ }
+
+ void CreateRemoteTrackAdapterOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref,
+ base::RunLoop* run_loop) {
+ *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track.get());
+ run_loop->Quit();
+ }
+
+ private:
+ base::MessageLoop message_loop_;
+
+ protected:
+ std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+ rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
+};
+
+TEST_F(RTCRtpTransceiverTest, InitializeTransceiverState) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"),
+ CreateWebRtcReceiver(remote_track_adapter->webrtc_track(),
+ "remote_stream"),
+ base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv,
+ base::nullopt);
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter),
+ std::move(remote_track_adapter));
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+
+ EXPECT_TRUE(transceiver_state.is_initialized());
+ // Inspect sender states.
+ const auto& sender_state = transceiver_state.sender_state();
+ EXPECT_TRUE(sender_state);
+ EXPECT_TRUE(sender_state->is_initialized());
+ const auto& webrtc_sender = webrtc_transceiver->sender();
+ EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get());
+ EXPECT_TRUE(sender_state->track_ref()->is_initialized());
+ EXPECT_EQ(sender_state->track_ref()->webrtc_track(),
+ webrtc_sender->track().get());
+ EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids());
+ // Inspect receiver states.
+ const auto& receiver_state = transceiver_state.receiver_state();
+ EXPECT_TRUE(receiver_state);
+ EXPECT_TRUE(receiver_state->is_initialized());
+ const auto& webrtc_receiver = webrtc_transceiver->receiver();
+ EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get());
+ EXPECT_TRUE(receiver_state->track_ref()->is_initialized());
+ EXPECT_EQ(receiver_state->track_ref()->webrtc_track(),
+ webrtc_receiver->track().get());
+ std::vector<std::string> receiver_stream_ids;
+ for (const auto& stream : webrtc_receiver->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids);
+ // Inspect transceiver states.
+ EXPECT_TRUE(
+ OptionalEquals(transceiver_state.mid(), webrtc_transceiver->mid()));
+ EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped());
+ EXPECT_TRUE(transceiver_state.direction() == webrtc_transceiver->direction());
+ EXPECT_TRUE(OptionalEquals(transceiver_state.current_direction(),
+ webrtc_transceiver->current_direction()));
+ EXPECT_TRUE(OptionalEquals(transceiver_state.fired_direction(),
+ webrtc_transceiver->fired_direction()));
+}
+
+TEST_F(RTCRtpTransceiverTest, CreateTranceiver) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"),
+ CreateWebRtcReceiver(remote_track_adapter->webrtc_track(),
+ "remote_stream"),
+ base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv,
+ base::nullopt);
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter),
+ std::move(remote_track_adapter));
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+
+ RTCRtpTransceiver transceiver(peer_connection_.get(), track_map_,
+ std::move(transceiver_state));
+ EXPECT_TRUE(transceiver.Mid().IsNull());
+ EXPECT_TRUE(transceiver.Sender());
+ EXPECT_TRUE(transceiver.Receiver());
+ EXPECT_FALSE(transceiver.Stopped());
+ EXPECT_EQ(transceiver.Direction(),
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ EXPECT_FALSE(transceiver.CurrentDirection());
+ EXPECT_FALSE(transceiver.FiredDirection());
+}
+
+TEST_F(RTCRtpTransceiverTest, ModifyTransceiver) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_sender =
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream");
+ auto webrtc_receiver = CreateWebRtcReceiver(
+ remote_track_adapter->webrtc_track(), "remote_stream");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ webrtc_sender, webrtc_receiver, base::nullopt, false,
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+
+ // Create initial state.
+ RtpTransceiverState initial_transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(initial_transceiver_state.is_initialized());
+ initial_transceiver_state.Initialize();
+
+ // Modify the webrtc transceiver and create a new state object for the
+ // modified state.
+ *webrtc_transceiver =
+ *CreateWebRtcTransceiver(webrtc_sender, webrtc_receiver, "MidyMacMidface",
+ true, webrtc::RtpTransceiverDirection::kInactive,
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ RtpTransceiverState modified_transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(modified_transceiver_state.is_initialized());
+ modified_transceiver_state.Initialize();
+
+ // Modifying the webrtc transceiver after the initial state was created should
+ // not have affected the transceiver state.
+ RTCRtpTransceiver transceiver(peer_connection_.get(), track_map_,
+ std::move(initial_transceiver_state));
+ EXPECT_TRUE(transceiver.Mid().IsNull());
+ EXPECT_TRUE(transceiver.Sender());
+ EXPECT_TRUE(transceiver.Receiver());
+ EXPECT_FALSE(transceiver.Stopped());
+ EXPECT_EQ(transceiver.Direction(),
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ EXPECT_FALSE(transceiver.CurrentDirection());
+ EXPECT_FALSE(transceiver.FiredDirection());
+
+ // Setting the state should make the transceiver state up-to-date.
+ transceiver.set_state(std::move(modified_transceiver_state));
+ EXPECT_EQ(transceiver.Mid(), "MidyMacMidface");
+ EXPECT_TRUE(transceiver.Sender());
+ EXPECT_TRUE(transceiver.Receiver());
+ EXPECT_TRUE(transceiver.Stopped());
+ EXPECT_EQ(transceiver.Direction(),
+ webrtc::RtpTransceiverDirection::kInactive);
+ EXPECT_TRUE(transceiver.CurrentDirection() ==
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ EXPECT_FALSE(transceiver.FiredDirection());
+}
+
+TEST_F(RTCRtpTransceiverTest, ShallowCopy) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_sender =
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream");
+ auto webrtc_receiver = CreateWebRtcReceiver(
+ remote_track_adapter->webrtc_track(), "remote_stream");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ webrtc_sender, webrtc_receiver, base::nullopt, false /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+
+ std::unique_ptr<RTCRtpTransceiver> transceiver;
+ // Create transceiver.
+ {
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+ transceiver.reset(new RTCRtpTransceiver(peer_connection_.get(), track_map_,
+ std::move(transceiver_state)));
+ }
+ DCHECK(transceiver);
+ EXPECT_FALSE(transceiver->Stopped());
+
+ std::unique_ptr<RTCRtpTransceiver> shallow_copy = transceiver->ShallowCopy();
+ // Modifying the shallow copy should modify the original too since they have a
+ // shared internal state.
+ {
+ // Modify webrtc transceiver to be stopped.
+ *webrtc_transceiver = *CreateWebRtcTransceiver(
+ webrtc_sender, webrtc_receiver, base::nullopt, true /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+ // Set the state of the shallow copy.
+ shallow_copy->set_state(std::move(transceiver_state));
+ }
+ EXPECT_TRUE(shallow_copy->Stopped());
+ EXPECT_TRUE(transceiver->Stopped());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_stats.cc b/chromium/content/renderer/media/webrtc/rtc_stats.cc
index 0c7478f8646..a24ef5bc613 100644
--- a/chromium/content/renderer/media/webrtc/rtc_stats.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_stats.cc
@@ -4,6 +4,7 @@
#include "content/renderer/media/webrtc/rtc_stats.h"
+#include <algorithm>
#include <set>
#include <string>
@@ -57,6 +58,22 @@ bool IsWhitelistedStats(const webrtc::RTCStats& stats) {
return GetStatsWhitelist()->IsWhitelisted(stats);
}
+// Filters out any unstandardized members; stats should only be surfaced to JS
+// if they're standardized.
+std::vector<const webrtc::RTCStatsMemberInterface*> StandardizedMembers(
+ std::vector<const webrtc::RTCStatsMemberInterface*> stats_members) {
+ // Note that using "is_standarized" avoids having to maintain a whitelist of
+ // every single standardized member, as we do at the "stats object" level
+ // with "RTCStatsWhitelist".
+ stats_members.erase(
+ std::remove_if(stats_members.begin(), stats_members.end(),
+ [](const webrtc::RTCStatsMemberInterface* member) {
+ return !member->is_standardized();
+ }),
+ stats_members.end());
+ return stats_members;
+}
+
} // namespace
RTCStatsReport::RTCStatsReport(
@@ -105,7 +122,7 @@ RTCStats::RTCStats(
const webrtc::RTCStats* stats)
: stats_owner_(stats_owner),
stats_(stats),
- stats_members_(stats->Members()) {
+ stats_members_(StandardizedMembers(stats->Members())) {
DCHECK(stats_owner_);
DCHECK(stats_);
DCHECK(stats_owner_->Get(stats_->id()));
diff --git a/chromium/content/renderer/media/webrtc/rtc_stats.h b/chromium/content/renderer/media/webrtc/rtc_stats.h
index 937cb25f3f0..370ab41d587 100644
--- a/chromium/content/renderer/media/webrtc/rtc_stats.h
+++ b/chromium/content/renderer/media/webrtc/rtc_stats.h
@@ -15,6 +15,9 @@
namespace content {
+// Wrapper around a webrtc::RTCStatsReport that also filters out any stats
+// objects that aren't whitelisted, and any members that aren't standardized
+// (using RTCStatsMemberInterface::is_standardized).
class CONTENT_EXPORT RTCStatsReport : public blink::WebRTCStatsReport {
public:
RTCStatsReport(
diff --git a/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc
index 379f3bc0918..6cf1d5bd49b 100644
--- a/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include "content/renderer/media/webrtc/rtc_stats.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,4 +47,47 @@ TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_Iteration) {
EXPECT_FALSE(report.Next());
}
+// Stats object with both a standard and non-standard member, used for the test
+// below.
+namespace {
+class TestStats : public webrtc::RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ TestStats(const std::string& id, int64_t timestamp_us);
+ ~TestStats() override = default;
+
+ webrtc::RTCStatsMember<int32_t> standardized;
+ webrtc::RTCNonStandardStatsMember<int32_t> non_standardized;
+};
+
+WEBRTC_RTCSTATS_IMPL(TestStats,
+ webrtc::RTCStats,
+ "teststats",
+ &standardized,
+ &non_standardized);
+
+TestStats::TestStats(const std::string& id, int64_t timestamp_us)
+ : RTCStats(id, timestamp_us),
+ standardized("standardized"),
+ non_standardized("non_standardized") {}
+} // namespace
+
+// Similar to how only whitelisted stats objects should be surfaced, only
+// standardized members of the whitelisted objects should be surfaced.
+TEST(RTCStatsTest, OnlyIncludeStandarizedMembers) {
+ rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
+ webrtc::RTCStatsReport::Create(42);
+ WhitelistStatsForTesting(TestStats::kType);
+ webrtc_report->AddStats(std::make_unique<TestStats>("id", 0));
+
+ // TestStats has two members, but the non-standard member should be filtered
+ // out.
+ RTCStatsReport report(webrtc_report.get());
+ std::unique_ptr<blink::WebRTCStats> stats = report.Next();
+ ASSERT_NE(nullptr, stats);
+ ASSERT_EQ(1u, stats->MembersCount());
+ EXPECT_EQ("standardized", stats->GetMember(0)->GetName());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc
index 050c9f61d84..864cb65f90c 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc
@@ -70,6 +70,8 @@ class RTCVideoDecoderTest
capabilities_.supported_profiles.push_back(supported_profile);
supported_profile.profile = media::VP8PROFILE_ANY;
capabilities_.supported_profiles.push_back(supported_profile);
+ supported_profile.profile = media::VP9PROFILE_MIN;
+ capabilities_.supported_profiles.push_back(supported_profile);
EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner())
.WillRepeatedly(Return(vda_task_runner_));
@@ -231,6 +233,24 @@ TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) {
rtc_decoder_->Decode(input_image, missingFrames, nullptr, 0));
}
+TEST_F(RTCVideoDecoderTest, FallBackToSoftwareOnVp9Svc) {
+ // HW VP9 decoders don't handle more than one spatial layer. See
+ // https://crbug.com/webrtc/9304, https://crbug.com/webrtc/9518 for details.
+ // The RTC video decoder triggers software fallback if it receives stream
+ // with more than one spatial layer.
+ CreateDecoder(webrtc::kVideoCodecVP9);
+ Initialize();
+
+ webrtc::CodecSpecificInfo codec_specific_info;
+ codec_specific_info.codecType = webrtc::kVideoCodecVP9;
+ codec_specific_info.codecSpecific.VP9.ss_data_available = true;
+ codec_specific_info.codecSpecific.VP9.num_spatial_layers = 2;
+
+ webrtc::EncodedImage input_image;
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
+ rtc_decoder_->Decode(input_image, false, &codec_specific_info, 0));
+}
+
TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) {
CreateDecoder(webrtc::kVideoCodecVP8);
Initialize();
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
index bfa722c5fc2..69f49db28bc 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
@@ -17,7 +17,6 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
-#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
@@ -115,7 +114,8 @@ class RTCVideoEncoder::Impl
public base::RefCountedThreadSafe<RTCVideoEncoder::Impl> {
public:
Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
- webrtc::VideoCodecType video_codec_type);
+ webrtc::VideoCodecType video_codec_type,
+ webrtc::VideoContentType video_content_type);
// Create the VEA and call Initialize() on it. Called once per instantiation,
// and then the instance is bound forevermore to whichever thread made the
@@ -163,10 +163,9 @@ class RTCVideoEncoder::Impl
void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size,
size_t output_buffer_size) override;
- void BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta timestamp) override;
+ void BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
private:
@@ -206,8 +205,7 @@ class RTCVideoEncoder::Impl
// Return an encoded output buffer to WebRTC.
void ReturnEncodedImage(const webrtc::EncodedImage& image,
- int32_t bitstream_buffer_id,
- uint16_t picture_id);
+ int32_t bitstream_buffer_id);
void SetStatus(int32_t status);
@@ -262,15 +260,15 @@ class RTCVideoEncoder::Impl
// encoder.
int output_buffers_free_count_;
- // 15 bits running index of the VP8 frames. See VP8 RTP spec for details.
- uint16_t picture_id_;
-
// webrtc::VideoEncoder encode complete callback.
webrtc::EncodedImageCallback* encoded_image_callback_;
// The video codec type, as reported to WebRTC.
const webrtc::VideoCodecType video_codec_type_;
+ // The content type, as reported to WebRTC (screenshare vs realtime video).
+ const webrtc::VideoContentType video_content_type_;
+
// Protect |status_|. |status_| is read or written on |gpu_task_runner_| in
// Impl. It can be read in RTCVideoEncoder on other threads.
mutable base::Lock status_lock_;
@@ -285,7 +283,8 @@ class RTCVideoEncoder::Impl
};
RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
- webrtc::VideoCodecType video_codec_type)
+ webrtc::VideoCodecType video_codec_type,
+ webrtc::VideoContentType video_content_type)
: gpu_factories_(gpu_factories),
async_waiter_(nullptr),
async_retval_(nullptr),
@@ -295,10 +294,9 @@ RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
output_buffers_free_count_(0),
encoded_image_callback_(nullptr),
video_codec_type_(video_codec_type),
+ video_content_type_(video_content_type),
status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
thread_checker_.DetachFromThread();
- // Picture ID should start on a random number.
- picture_id_ = static_cast<uint16_t>(base::RandInt(0, 0x7FFF));
}
void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
@@ -505,13 +503,13 @@ void RTCVideoEncoder::Impl::RequireBitstreamBuffers(
SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK);
}
-void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta timestamp) {
+void RTCVideoEncoder::Impl::BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) {
DVLOG(3) << __func__ << " bitstream_buffer_id=" << bitstream_buffer_id
- << ", payload_size=" << payload_size << ", key_frame=" << key_frame
- << ", timestamp ms=" << timestamp.InMilliseconds();
+ << ", payload_size=" << metadata.payload_size_bytes
+ << ", key_frame=" << metadata.key_frame
+ << ", timestamp ms=" << metadata.timestamp.InMilliseconds();
DCHECK(thread_checker_.CalledOnValidThread());
if (bitstream_buffer_id < 0 ||
@@ -522,7 +520,7 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
}
base::SharedMemory* output_buffer =
output_buffers_[bitstream_buffer_id].get();
- if (payload_size > output_buffer->mapped_size()) {
+ if (metadata.payload_size_bytes > output_buffer->mapped_size()) {
LogAndNotifyError(FROM_HERE, "invalid payload_size",
media::VideoEncodeAccelerator::kPlatformFailureError);
return;
@@ -537,7 +535,7 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
// Pop timestamps until we have a match.
while (!pending_timestamps_.empty()) {
const auto& front_timestamps = pending_timestamps_.front();
- if (front_timestamps.media_timestamp_ == timestamp) {
+ if (front_timestamps.media_timestamp_ == metadata.timestamp) {
rtp_timestamp = front_timestamps.rtp_timestamp;
capture_timestamp_ms = front_timestamps.capture_time_ms;
pending_timestamps_.pop_front();
@@ -558,19 +556,18 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
}
webrtc::EncodedImage image(
- reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size,
- output_buffer->mapped_size());
+ reinterpret_cast<uint8_t*>(output_buffer->memory()),
+ metadata.payload_size_bytes, output_buffer->mapped_size());
image._encodedWidth = input_visible_size_.width();
image._encodedHeight = input_visible_size_.height();
image._timeStamp = rtp_timestamp.value();
image.capture_time_ms_ = capture_timestamp_ms.value();
image._frameType =
- (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
+ (metadata.key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
+ image.content_type_ = video_content_type_;
image._completeFrame = true;
- ReturnEncodedImage(image, bitstream_buffer_id, picture_id_);
- // Picture ID must wrap after reaching the maximum.
- picture_id_ = (picture_id_ + 1) & 0x7FFF;
+ ReturnEncodedImage(image, bitstream_buffer_id);
}
void RTCVideoEncoder::Impl::NotifyError(
@@ -759,11 +756,9 @@ void RTCVideoEncoder::Impl::RegisterEncodeCompleteCallback(
void RTCVideoEncoder::Impl::ReturnEncodedImage(
const webrtc::EncodedImage& image,
- int32_t bitstream_buffer_id,
- uint16_t picture_id) {
+ int32_t bitstream_buffer_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- DVLOG(3) << __func__ << " bitstream_buffer_id=" << bitstream_buffer_id
- << ", picture_id=" << picture_id;
+ DVLOG(3) << __func__ << " bitstream_buffer_id=" << bitstream_buffer_id;
if (!encoded_image_callback_)
return;
@@ -798,8 +793,6 @@ void RTCVideoEncoder::Impl::ReturnEncodedImage(
info.codecType = video_codec_type_;
info.codec_name = ImplementationName();
if (video_codec_type_ == webrtc::kVideoCodecVP8) {
- info.codecSpecific.VP8.pictureId = picture_id;
- info.codecSpecific.VP8.tl0PicIdx = -1;
info.codecSpecific.VP8.keyIdx = -1;
}
@@ -840,7 +833,7 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
Release();
if (codec_settings->codecType == webrtc::kVideoCodecVP8 &&
- codec_settings->mode == webrtc::kScreensharing &&
+ codec_settings->mode == webrtc::VideoCodecMode::kScreensharing &&
codec_settings->VP8().numberOfTemporalLayers > 1) {
// This is a VP8 stream with screensharing using temporal layers for
// temporal scalability. Since this implementation does not yet implement
@@ -854,7 +847,11 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
}
}
- impl_ = new Impl(gpu_factories_, ProfileToWebRtcVideoCodecType(profile_));
+ impl_ =
+ new Impl(gpu_factories_, ProfileToWebRtcVideoCodecType(profile_),
+ (codec_settings->mode == webrtc::VideoCodecMode::kScreensharing)
+ ? webrtc::VideoContentType::SCREENSHARE
+ : webrtc::VideoContentType::UNSPECIFIED);
base::WaitableEvent initialization_waiter(
base::WaitableEvent::ResetPolicy::MANUAL,
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc
index 3307c40e0b8..7b89e610a23 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc
@@ -73,7 +73,7 @@ base::Optional<cricket::VideoCodec> VEAToWebRTCCodec(
const int fps = profile.max_framerate_numerator;
DCHECK_EQ(1u, profile.max_framerate_denominator);
- const rtc::Optional<webrtc::H264::Level> h264_level =
+ const absl::optional<webrtc::H264::Level> h264_level =
webrtc::H264::SupportedLevel(width * height, fps);
const webrtc::H264::ProfileLevelId profile_level_id(
h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
index d3defba9124..2d142d5aa82 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
@@ -180,7 +180,9 @@ class RTCVideoEncoderTest
void ReturnFrameWithTimeStamp(const scoped_refptr<media::VideoFrame>& frame,
bool force_keyframe) {
- client_->BitstreamBufferReady(0, 0, force_keyframe, frame->timestamp());
+ client_->BitstreamBufferReady(
+ 0,
+ media::BitstreamBufferMetadata(0, force_keyframe, frame->timestamp()));
}
void VerifyTimestamp(uint32_t rtp_timestamp,
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
new file mode 100644
index 00000000000..4792cefac27
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
@@ -0,0 +1,225 @@
+// Copyright 2018 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/webrtc/transceiver_state_surfacer.h"
+
+#include "content/renderer/media/webrtc/webrtc_util.h"
+#include "third_party/webrtc/api/rtptransceiverinterface.h"
+
+namespace content {
+
+TransceiverStateSurfacer::TransceiverStateSurfacer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ is_initialized_(false),
+ states_obtained_(false) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+}
+
+TransceiverStateSurfacer::TransceiverStateSurfacer(
+ TransceiverStateSurfacer&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ is_initialized_(other.is_initialized_),
+ states_obtained_(other.states_obtained_),
+ transceiver_states_(std::move(other.transceiver_states_)) {
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+TransceiverStateSurfacer::~TransceiverStateSurfacer() {
+ // It's OK to not be on the main thread if this object has been moved, in
+ // which case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+TransceiverStateSurfacer& TransceiverStateSurfacer::operator=(
+ TransceiverStateSurfacer&& other) {
+ main_task_runner_ = other.main_task_runner_;
+ signaling_task_runner_ = other.signaling_task_runner_;
+ states_obtained_ = other.states_obtained_;
+ transceiver_states_ = std::move(other.transceiver_states_);
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ return *this;
+}
+
+void TransceiverStateSurfacer::Initialize(
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ webrtc_transceivers) {
+ DCHECK(signaling_task_runner_->BelongsToCurrentThread());
+ DCHECK(!is_initialized_);
+ for (auto& webrtc_transceiver : webrtc_transceivers) {
+ // Create the sender state.
+ base::Optional<RtpSenderState> sender_state;
+ auto webrtc_sender = webrtc_transceiver->sender();
+ if (webrtc_sender) {
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ sender_track_ref;
+ if (webrtc_sender->track()) {
+ // The track adapter for this track must already exist for us to obtain
+ // it, since this cannot be created from the signaling thread.
+ // TODO(hbos): Consider either making it possible to create local track
+ // adapters on the signaling thread for initialization on the main
+ // thread or wait for Onion Souping to simplify this.
+ // https://crbug.com/787254
+ sender_track_ref =
+ track_adapter_map->GetLocalTrackAdapter(webrtc_sender->track());
+ CHECK(sender_track_ref);
+ }
+ sender_state = RtpSenderState(
+ main_task_runner_, signaling_task_runner_, webrtc_sender.get(),
+ std::move(sender_track_ref), webrtc_sender->stream_ids());
+ }
+ // Create the receiver state.
+ base::Optional<RtpReceiverState> receiver_state;
+ auto webrtc_receiver = webrtc_transceiver->receiver();
+ if (webrtc_receiver) {
+ DCHECK(webrtc_receiver->track());
+ auto receiver_track_ref =
+ track_adapter_map->GetOrCreateRemoteTrackAdapter(
+ webrtc_receiver->track().get());
+ DCHECK(receiver_track_ref);
+ std::vector<std::string> receiver_stream_ids;
+ for (auto& stream : webrtc_receiver->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ receiver_state = RtpReceiverState(
+ main_task_runner_, signaling_task_runner_, webrtc_receiver.get(),
+ std::move(receiver_track_ref), std::move(receiver_stream_ids));
+ }
+ // Create the transceiver state.
+ transceiver_states_.push_back(RtpTransceiverState(
+ main_task_runner_, signaling_task_runner_, webrtc_transceiver.get(),
+ std::move(sender_state), std::move(receiver_state),
+ ToBaseOptional(webrtc_transceiver->mid()),
+ webrtc_transceiver->stopped(), webrtc_transceiver->direction(),
+ ToBaseOptional(webrtc_transceiver->current_direction()),
+ ToBaseOptional(webrtc_transceiver->fired_direction())));
+ }
+ is_initialized_ = true;
+}
+
+std::vector<RtpTransceiverState> TransceiverStateSurfacer::ObtainStates() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(is_initialized_);
+ for (auto& transceiver_state : transceiver_states_)
+ transceiver_state.Initialize();
+ states_obtained_ = true;
+ return std::move(transceiver_states_);
+}
+
+SurfaceSenderStateOnly::SurfaceSenderStateOnly(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender)
+ : sender_(std::move(sender)) {
+ DCHECK(sender_);
+}
+
+SurfaceSenderStateOnly::~SurfaceSenderStateOnly() {}
+
+cricket::MediaType SurfaceSenderStateOnly::media_type() const {
+ return sender_->media_type();
+}
+
+absl::optional<std::string> SurfaceSenderStateOnly::mid() const {
+ return absl::nullopt;
+}
+
+rtc::scoped_refptr<webrtc::RtpSenderInterface> SurfaceSenderStateOnly::sender()
+ const {
+ return sender_;
+}
+
+rtc::scoped_refptr<webrtc::RtpReceiverInterface>
+SurfaceSenderStateOnly::receiver() const {
+ return nullptr;
+}
+
+bool SurfaceSenderStateOnly::stopped() const {
+ return false;
+}
+
+webrtc::RtpTransceiverDirection SurfaceSenderStateOnly::direction() const {
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
+void SurfaceSenderStateOnly::SetDirection(
+ webrtc::RtpTransceiverDirection new_direction) {
+ NOTIMPLEMENTED();
+}
+
+absl::optional<webrtc::RtpTransceiverDirection>
+SurfaceSenderStateOnly::current_direction() const {
+ return absl::nullopt;
+}
+
+void SurfaceSenderStateOnly::Stop() {
+ NOTIMPLEMENTED();
+}
+
+void SurfaceSenderStateOnly::SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
+ NOTIMPLEMENTED();
+}
+
+SurfaceReceiverStateOnly::SurfaceReceiverStateOnly(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
+ : receiver_(std::move(receiver)) {
+ DCHECK(receiver_);
+}
+
+SurfaceReceiverStateOnly::~SurfaceReceiverStateOnly() {}
+
+cricket::MediaType SurfaceReceiverStateOnly::media_type() const {
+ return receiver_->media_type();
+}
+
+absl::optional<std::string> SurfaceReceiverStateOnly::mid() const {
+ return absl::nullopt;
+}
+
+rtc::scoped_refptr<webrtc::RtpSenderInterface>
+SurfaceReceiverStateOnly::sender() const {
+ return nullptr;
+}
+
+rtc::scoped_refptr<webrtc::RtpReceiverInterface>
+SurfaceReceiverStateOnly::receiver() const {
+ return receiver_;
+}
+
+bool SurfaceReceiverStateOnly::stopped() const {
+ return false;
+}
+
+webrtc::RtpTransceiverDirection SurfaceReceiverStateOnly::direction() const {
+ return webrtc::RtpTransceiverDirection::kRecvOnly;
+}
+
+void SurfaceReceiverStateOnly::SetDirection(
+ webrtc::RtpTransceiverDirection new_direction) {
+ NOTIMPLEMENTED();
+}
+
+absl::optional<webrtc::RtpTransceiverDirection>
+SurfaceReceiverStateOnly::current_direction() const {
+ return absl::nullopt;
+}
+
+void SurfaceReceiverStateOnly::Stop() {
+ NOTIMPLEMENTED();
+}
+
+void SurfaceReceiverStateOnly::SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
+ NOTIMPLEMENTED();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
new file mode 100644
index 00000000000..ab7cdfeb695
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
@@ -0,0 +1,112 @@
+// Copyright 2018 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.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
+
+#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/webrtc/api/rtptransceiverinterface.h"
+#include "third_party/webrtc/rtc_base/refcount.h"
+#include "third_party/webrtc/rtc_base/refcountedobject.h"
+
+namespace content {
+
+// Takes care of creating and initializing transceiver states (including sender
+// and receiver states). This is usable for both blocking and non-blocking calls
+// to the webrtc signaling thread.
+//
+// The surfacer is initialized on the signaling thread and states are obtained
+// on the main thread. It is designed to be initialized and handed off; it is
+// not thread safe for concurrent thread usage.
+class CONTENT_EXPORT TransceiverStateSurfacer {
+ public:
+ TransceiverStateSurfacer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner);
+ TransceiverStateSurfacer(TransceiverStateSurfacer&&);
+ TransceiverStateSurfacer(const TransceiverStateSurfacer&) = delete;
+ ~TransceiverStateSurfacer();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ TransceiverStateSurfacer& operator=(TransceiverStateSurfacer&&);
+ TransceiverStateSurfacer& operator=(const TransceiverStateSurfacer&) = delete;
+
+ bool is_initialized() const { return is_initialized_; }
+
+ // Must be invoked on the signaling thread.
+ void Initialize(
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers);
+
+ // Must be invoked on the main thread.
+ std::vector<RtpTransceiverState> ObtainStates();
+
+ protected:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ bool is_initialized_;
+ bool states_obtained_;
+ std::vector<RtpTransceiverState> transceiver_states_;
+};
+
+// A dummy implementation of a transceiver used to surface sender state
+// information only. It is not thread safe, only designed to be passed on to
+// TransceiverStateSurfacer::Initialize().
+class CONTENT_EXPORT SurfaceSenderStateOnly
+ : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> {
+ public:
+ SurfaceSenderStateOnly(rtc::scoped_refptr<webrtc::RtpSenderInterface> sender);
+ ~SurfaceSenderStateOnly() override;
+
+ cricket::MediaType media_type() const override;
+ absl::optional<std::string> mid() const override;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override;
+ bool stopped() const override;
+ webrtc::RtpTransceiverDirection direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection new_direction) override;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction()
+ const override;
+ void Stop() override;
+ void SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
+
+ private:
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_;
+};
+
+// A dummy implementation of a transceiver used to surface receiver state
+// information only. It is not thread safe, only designed to be passed on to
+// TransceiverStateSurfacer::Initialize().
+class CONTENT_EXPORT SurfaceReceiverStateOnly
+ : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> {
+ public:
+ SurfaceReceiverStateOnly(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver);
+ ~SurfaceReceiverStateOnly() override;
+
+ cricket::MediaType media_type() const override;
+ absl::optional<std::string> mid() const override;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override;
+ bool stopped() const override;
+ webrtc::RtpTransceiverDirection direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection new_direction) override;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction()
+ const override;
+ void Stop() override;
+ void SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
+
+ private:
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
new file mode 100644
index 00000000000..7f469865324
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
@@ -0,0 +1,294 @@
+// Copyright 2018 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/webrtc/transceiver_state_surfacer.h"
+
+#include <memory>
+#include <tuple>
+
+#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
+#include "content/child/child_process.h"
+#include "content/renderer/media/stream/media_stream_audio_source.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
+#include "content/renderer/media/webrtc/webrtc_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_heap.h"
+
+namespace content {
+
+class TransceiverStateSurfacerTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
+ main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
+ track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap(
+ dependency_factory_.get(), main_task_runner_);
+ surfacer_.reset(new TransceiverStateSurfacer(main_task_runner_,
+ signaling_task_runner()));
+ }
+
+ void TearDown() override {
+ // Make sure posted tasks get a chance to execute or else the stuff is
+ // teared down while things are in flight.
+ base::RunLoop().RunUntilIdle();
+ blink::WebHeap::CollectAllGarbageForTesting();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const {
+ return dependency_factory_->GetWebRtcSignalingThread();
+ }
+
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ CreateLocalTrackAndAdapter(const std::string& id) {
+ return track_adapter_map_->GetOrCreateLocalTrackAdapter(
+ CreateBlinkLocalTrack(id));
+ }
+
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> CreateWebRtcTransceiver(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> local_track,
+ const std::string& local_stream_id,
+ const std::string& remote_track_id,
+ const std::string& remote_stream_id) {
+ return new rtc::RefCountedObject<FakeRtpTransceiver>(
+ local_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind
+ ? cricket::MEDIA_TYPE_AUDIO
+ : cricket::MEDIA_TYPE_VIDEO,
+ CreateWebRtcSender(local_track, local_stream_id),
+ CreateWebRtcReceiver(remote_track_id, remote_stream_id), base::nullopt,
+ false, webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+ }
+
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> CreateWebRtcSender(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::string& stream_id) {
+ return new rtc::RefCountedObject<FakeRtpSender>(
+ std::move(track), std::vector<std::string>({stream_id}));
+ }
+
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> CreateWebRtcReceiver(
+ const std::string& track_id,
+ const std::string& stream_id) {
+ rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_track =
+ MockWebRtcAudioTrack::Create(track_id).get();
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ new rtc::RefCountedObject<MockMediaStream>(stream_id));
+ return new rtc::RefCountedObject<FakeRtpReceiver>(
+ remote_track.get(),
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>(
+ {remote_stream}));
+ }
+
+ // Initializes the surfacer on the signaling thread and signals the waitable
+ // event when done. The WaitableEvent's Wait() blocks the main thread until
+ // initialization occurs.
+ std::unique_ptr<base::WaitableEvent> AsyncInitializeSurfacerWithWaitableEvent(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers) {
+ std::unique_ptr<base::WaitableEvent> waitable_event(new base::WaitableEvent(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED));
+ signaling_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &TransceiverStateSurfacerTest::
+ AsyncInitializeSurfacerWithWaitableEventOnSignalingThread,
+ base::Unretained(this), std::move(transceivers),
+ waitable_event.get()));
+ return waitable_event;
+ }
+
+ // Initializes the surfacer on the signaling thread and posts back to the main
+ // thread to execute the callback when done. The RunLoop quits after the
+ // callback is executed. Use the RunLoop's Run() method to allow the posted
+ // task (such as the callback) to be executed while waiting. The caller must
+ // let the loop Run() before destroying it.
+ std::unique_ptr<base::RunLoop> AsyncInitializeSurfacerWithCallback(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers,
+ base::OnceCallback<void()> callback) {
+ std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop());
+ signaling_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&TransceiverStateSurfacerTest::
+ AsyncInitializeSurfacerWithCallbackOnSignalingThread,
+ base::Unretained(this), std::move(transceivers),
+ std::move(callback), run_loop.get()));
+ return run_loop;
+ }
+
+ void ObtainStatesAndExpectInitialized(
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver) {
+ auto transceiver_states = surfacer_->ObtainStates();
+ EXPECT_EQ(1u, transceiver_states.size());
+ auto& transceiver_state = transceiver_states[0];
+ EXPECT_EQ(transceiver_state.webrtc_transceiver().get(),
+ webrtc_transceiver.get());
+ // Inspect sender states.
+ const auto& sender_state = transceiver_state.sender_state();
+ EXPECT_TRUE(sender_state);
+ EXPECT_TRUE(sender_state->is_initialized());
+ const auto& webrtc_sender = webrtc_transceiver->sender();
+ EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get());
+ EXPECT_TRUE(sender_state->track_ref()->is_initialized());
+ EXPECT_EQ(sender_state->track_ref()->webrtc_track(),
+ webrtc_sender->track().get());
+ EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids());
+ // Inspect receiver states.
+ const auto& receiver_state = transceiver_state.receiver_state();
+ EXPECT_TRUE(receiver_state);
+ EXPECT_TRUE(receiver_state->is_initialized());
+ const auto& webrtc_receiver = webrtc_transceiver->receiver();
+ EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get());
+ EXPECT_TRUE(receiver_state->track_ref()->is_initialized());
+ EXPECT_EQ(receiver_state->track_ref()->webrtc_track(),
+ webrtc_receiver->track().get());
+ std::vector<std::string> receiver_stream_ids;
+ for (const auto& stream : webrtc_receiver->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids);
+ // Inspect transceiver states.
+ EXPECT_TRUE(
+ OptionalEquals(transceiver_state.mid(), webrtc_transceiver->mid()));
+ EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped());
+ EXPECT_TRUE(transceiver_state.direction() ==
+ webrtc_transceiver->direction());
+ EXPECT_TRUE(OptionalEquals(transceiver_state.current_direction(),
+ webrtc_transceiver->current_direction()));
+ }
+
+ private:
+ blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) {
+ blink::WebMediaStreamSource web_source;
+ web_source.Initialize(
+ blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio,
+ blink::WebString::FromUTF8("local_audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true);
+ // Takes ownership of |audio_source|.
+ web_source.SetExtraData(audio_source);
+
+ blink::WebMediaStreamTrack web_track;
+ web_track.Initialize(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(web_track);
+ return web_track;
+ }
+
+ void AsyncInitializeSurfacerWithWaitableEventOnSignalingThread(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers,
+ base::WaitableEvent* waitable_event) {
+ DCHECK(signaling_task_runner()->BelongsToCurrentThread());
+ surfacer_->Initialize(track_adapter_map_, std::move(transceivers));
+ waitable_event->Signal();
+ }
+
+ void AsyncInitializeSurfacerWithCallbackOnSignalingThread(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers,
+ base::OnceCallback<void()> callback,
+ base::RunLoop* run_loop) {
+ DCHECK(signaling_task_runner()->BelongsToCurrentThread());
+ surfacer_->Initialize(track_adapter_map_, std::move(transceivers));
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&TransceiverStateSurfacerTest::
+ AsyncInitializeSurfacerWithCallbackOnMainThread,
+ base::Unretained(this), std::move(callback), run_loop));
+ }
+
+ void AsyncInitializeSurfacerWithCallbackOnMainThread(
+ base::OnceCallback<void()> callback,
+ base::RunLoop* run_loop) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(surfacer_->is_initialized());
+ std::move(callback).Run();
+ run_loop->Quit();
+ }
+
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+ protected:
+ std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+ std::unique_ptr<TransceiverStateSurfacer> surfacer_;
+};
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverBlockingly) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_transceiver =
+ CreateWebRtcTransceiver(local_track_adapter->webrtc_track(),
+ "local_stream", "remote_track", "remote_stream");
+ auto waitable_event =
+ AsyncInitializeSurfacerWithWaitableEvent({webrtc_transceiver});
+ waitable_event->Wait();
+ ObtainStatesAndExpectInitialized(webrtc_transceiver);
+}
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverInCallback) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_transceiver =
+ CreateWebRtcTransceiver(local_track_adapter->webrtc_track(),
+ "local_stream", "remote_track", "remote_stream");
+ auto run_loop = AsyncInitializeSurfacerWithCallback(
+ {webrtc_transceiver},
+ base::BindOnce(
+ &TransceiverStateSurfacerTest::ObtainStatesAndExpectInitialized,
+ base::Unretained(this), webrtc_transceiver));
+ run_loop->Run();
+}
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceSenderStateOnly) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_sender =
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream");
+ auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent(
+ {new SurfaceSenderStateOnly(webrtc_sender)});
+ waitable_event->Wait();
+ auto transceiver_states = surfacer_->ObtainStates();
+ EXPECT_EQ(1u, transceiver_states.size());
+ auto& transceiver_state = transceiver_states[0];
+ EXPECT_TRUE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.sender_state()->is_initialized());
+ EXPECT_FALSE(transceiver_state.receiver_state());
+ // Expect transceiver members be be missing for optional members and have
+ // sensible values for non-optional members.
+ EXPECT_FALSE(transceiver_state.mid());
+ EXPECT_FALSE(transceiver_state.stopped());
+ EXPECT_EQ(transceiver_state.direction(),
+ webrtc::RtpTransceiverDirection::kSendOnly);
+ EXPECT_FALSE(transceiver_state.current_direction());
+}
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceReceiverStateOnly) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_receiver = CreateWebRtcReceiver("remote_track", "remote_stream");
+ auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent(
+ {new SurfaceReceiverStateOnly(webrtc_receiver)});
+ waitable_event->Wait();
+ auto transceiver_states = surfacer_->ObtainStates();
+ EXPECT_EQ(1u, transceiver_states.size());
+ auto& transceiver_state = transceiver_states[0];
+ EXPECT_FALSE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.receiver_state());
+ EXPECT_TRUE(transceiver_state.receiver_state()->is_initialized());
+ // Expect transceiver members be be missing for optional members and have
+ // sensible values for non-optional members.
+ EXPECT_FALSE(transceiver_state.mid());
+ EXPECT_FALSE(transceiver_state.stopped());
+ EXPECT_EQ(transceiver_state.direction(),
+ webrtc::RtpTransceiverDirection::kRecvOnly);
+ EXPECT_FALSE(transceiver_state.current_direction());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
index b18f49d21f8..c1ea561596d 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
@@ -11,10 +11,11 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "content/renderer/media/webrtc/peer_connection_remote_audio_source.h"
#include "content/renderer/media/webrtc_logging.h"
@@ -93,8 +94,7 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
void Play() override {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(started_);
- if (playing_state_.playing())
+ if (!started_ || playing_state_.playing())
return;
playing_state_.set_playing(true);
on_play_state_changed_.Run(media_stream_, &playing_state_);
@@ -102,8 +102,7 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
void Pause() override {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(started_);
- if (!playing_state_.playing())
+ if (!started_ || !playing_state_.playing())
return;
playing_state_.set_playing(false);
on_play_state_changed_.Run(media_stream_, &playing_state_);
@@ -549,7 +548,7 @@ bool WebRtcAudioRenderer::AddPlayingState(
DCHECK(state->playing());
// Look up or add the |source| to the map.
PlayingStates& array = source_playing_states_[source];
- if (std::find(array.begin(), array.end(), state) != array.end())
+ if (base::ContainsValue(array, state))
return false;
array.push_back(state);
@@ -584,8 +583,8 @@ void WebRtcAudioRenderer::OnPlayStateChanged(
const blink::WebMediaStream& media_stream,
PlayingState* state) {
DCHECK(thread_checker_.CalledOnValidThread());
- blink::WebVector<blink::WebMediaStreamTrack> web_tracks;
- media_stream.AudioTracks(web_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> web_tracks =
+ media_stream.AudioTracks();
for (const blink::WebMediaStreamTrack& web_track : web_tracks) {
// WebRtcAudioRenderer can only render audio tracks received from a remote
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
index 7e886d27945..e3e2cce259b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
@@ -13,7 +13,7 @@
#include "base/run_loop.h"
#include "build/build_config.h"
#include "content/public/renderer/media_stream_audio_renderer.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/mock_audio_renderer_sink.h"
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
index ba37c80ba94..b5a59a0e32e 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
@@ -27,26 +27,26 @@ WebRtcAudioSink::WebRtcAudioSink(
}
WebRtcAudioSink::~WebRtcAudioSink() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DVLOG(1) << "WebRtcAudioSink::~WebRtcAudioSink()";
}
void WebRtcAudioSink::SetAudioProcessor(
scoped_refptr<MediaStreamAudioProcessor> processor) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(processor.get());
adapter_->set_processor(std::move(processor));
}
void WebRtcAudioSink::SetLevel(
scoped_refptr<MediaStreamAudioLevelCalculator::Level> level) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(level.get());
adapter_->set_level(std::move(level));
}
void WebRtcAudioSink::OnEnabledChanged(bool enabled) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
adapter_->signaling_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(base::IgnoreResult(&WebRtcAudioSink::Adapter::set_enabled),
@@ -55,17 +55,14 @@ void WebRtcAudioSink::OnEnabledChanged(bool enabled) {
void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
base::TimeTicks estimated_capture_time) {
- DCHECK(audio_thread_checker_.CalledOnValidThread());
+ // No thread check: OnData might be called on different threads (but not
+ // concurrently).
// The following will result in zero, one, or multiple synchronous calls to
// DeliverRebufferedAudio().
fifo_.Push(audio_bus);
}
void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
- // On a format change, the thread delivering audio might have also changed.
- audio_thread_checker_.DetachFromThread();
- DCHECK(audio_thread_checker_.CalledOnValidThread());
-
DCHECK(params.IsValid());
params_ = params;
// Make sure that our params always reflect a buffer size of 10ms.
@@ -78,7 +75,6 @@ void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
void WebRtcAudioSink::DeliverRebufferedAudio(const media::AudioBus& audio_bus,
int frame_delay) {
- DCHECK(audio_thread_checker_.CalledOnValidThread());
DCHECK(params_.IsValid());
// TODO(miu): Why doesn't a WebRTC sink care about reference time passed to
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
index d330bcd1d2f..fee1d51f999 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
@@ -8,6 +8,8 @@
#include <stdint.h>
#include <memory>
+#include <string>
+#include <utility>
#include <vector>
#include "base/macros.h"
@@ -166,11 +168,7 @@ class CONTENT_EXPORT WebRtcAudioSink : public MediaStreamAudioSink {
// In debug builds, check that WebRtcAudioSink's public methods are all being
// called on the main render thread.
- base::ThreadChecker thread_checker_;
-
- // Used to DCHECK that OnSetFormat() and OnData() are called on the same
- // thread.
- base::ThreadChecker audio_thread_checker_;
+ THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(WebRtcAudioSink);
};
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
deleted file mode 100644
index 835d6194e24..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2014 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/webrtc/webrtc_media_stream_adapter.h"
-
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/media/stream/media_stream_audio_track.h"
-#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-namespace content {
-
-// static
-std::unique_ptr<WebRtcMediaStreamAdapter>
-WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream) {
- return std::make_unique<LocalWebRtcMediaStreamAdapter>(
- factory, std::move(track_adapter_map), web_stream);
-}
-
-// static
-std::unique_ptr<WebRtcMediaStreamAdapter>
-WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream) {
- return std::make_unique<RemoteWebRtcMediaStreamAdapter>(
- std::move(main_thread), std::move(track_adapter_map),
- std::move(webrtc_stream));
-}
-
-WebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream,
- const blink::WebMediaStream& web_stream)
- : main_thread_(std::move(main_thread)),
- track_adapter_map_(std::move(track_adapter_map)),
- webrtc_stream_(std::move(webrtc_stream)),
- web_stream_(web_stream) {
- DCHECK(main_thread_);
- DCHECK(track_adapter_map_);
-}
-
-WebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() {
- DCHECK(main_thread_->BelongsToCurrentThread());
-}
-
-LocalWebRtcMediaStreamAdapter::LocalWebRtcMediaStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream)
- : WebRtcMediaStreamAdapter(base::ThreadTaskRunnerHandle::Get(),
- std::move(track_adapter_map),
- nullptr,
- web_stream),
- factory_(factory) {
- webrtc_stream_ = factory_->CreateLocalMediaStream(web_stream.Id().Utf8());
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream_.AudioTracks(audio_tracks);
- for (blink::WebMediaStreamTrack& audio_track : audio_tracks)
- TrackAdded(audio_track);
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream_.VideoTracks(video_tracks);
- for (blink::WebMediaStreamTrack& video_track : video_tracks)
- TrackAdded(video_track);
-
- web_stream_.AddObserver(this);
-}
-
-LocalWebRtcMediaStreamAdapter::~LocalWebRtcMediaStreamAdapter() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- web_stream_.RemoveObserver(this);
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream_.AudioTracks(audio_tracks);
- for (blink::WebMediaStreamTrack& audio_track : audio_tracks)
- TrackRemoved(audio_track);
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream_.VideoTracks(video_tracks);
- for (blink::WebMediaStreamTrack& video_track : video_tracks)
- TrackRemoved(video_track);
-}
-
-bool LocalWebRtcMediaStreamAdapter::is_initialized() const {
- return true;
-}
-
-const scoped_refptr<webrtc::MediaStreamInterface>&
-LocalWebRtcMediaStreamAdapter::webrtc_stream() const {
- return webrtc_stream_;
-}
-
-const blink::WebMediaStream& LocalWebRtcMediaStreamAdapter::web_stream() const {
- return web_stream_;
-}
-
-void LocalWebRtcMediaStreamAdapter::SetTracks(
- WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs) {
- NOTIMPLEMENTED() << "Not supported for local stream adapters.";
-}
-
-void LocalWebRtcMediaStreamAdapter::TrackAdded(
- const blink::WebMediaStreamTrack& web_track) {
- DCHECK(adapter_refs_.find(web_track.UniqueId()) == adapter_refs_.end());
- bool is_audio_track =
- (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio);
- if (is_audio_track && !MediaStreamAudioTrack::From(web_track)) {
- DLOG(ERROR) << "No native track for blink audio track.";
- return;
- }
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
- track_adapter_map_->GetOrCreateLocalTrackAdapter(web_track);
- if (is_audio_track) {
- webrtc_stream_->AddTrack(
- static_cast<webrtc::AudioTrackInterface*>(adapter_ref->webrtc_track()));
- } else {
- webrtc_stream_->AddTrack(
- static_cast<webrtc::VideoTrackInterface*>(adapter_ref->webrtc_track()));
- }
- adapter_refs_.insert(
- std::make_pair(web_track.UniqueId(), std::move(adapter_ref)));
-}
-
-void LocalWebRtcMediaStreamAdapter::TrackRemoved(
- const blink::WebMediaStreamTrack& web_track) {
- auto it = adapter_refs_.find(web_track.UniqueId());
- if (it == adapter_refs_.end()) {
- // This can happen for audio tracks that don't have a source, these would
- // never be added in the first place.
- return;
- }
- if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio) {
- webrtc_stream_->RemoveTrack(
- static_cast<webrtc::AudioTrackInterface*>(it->second->webrtc_track()));
- } else {
- webrtc_stream_->RemoveTrack(
- static_cast<webrtc::VideoTrackInterface*>(it->second->webrtc_track()));
- }
- adapter_refs_.erase(it);
-}
-
-// static
-bool RemoteWebRtcMediaStreamAdapter::RemoteAdapterRefsContainsTrack(
- const RemoteAdapterRefs& adapter_refs,
- webrtc::MediaStreamTrackInterface* webrtc_track) {
- for (const auto& adapter_ref : adapter_refs) {
- if (adapter_ref->webrtc_track() == webrtc_track)
- return true;
- }
- return false;
-}
-
-// static
-RemoteWebRtcMediaStreamAdapter::RemoteAdapterRefs
-RemoteWebRtcMediaStreamAdapter::GetRemoteAdapterRefsFromWebRtcStream(
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
- webrtc::MediaStreamInterface* webrtc_stream) {
- // TODO(hbos): When adapter's |webrtc_track| can be called from any thread so
- // can RemoteAdapterRefsContainsTrack and we can DCHECK here that we don't end
- // up with duplicate entries. https://crbug.com/756436
- RemoteAdapterRefs adapter_refs;
- for (auto& webrtc_audio_track : webrtc_stream->GetAudioTracks()) {
- adapter_refs.push_back(track_adapter_map->GetOrCreateRemoteTrackAdapter(
- webrtc_audio_track.get()));
- }
- for (auto& webrtc_video_track : webrtc_stream->GetVideoTracks()) {
- adapter_refs.push_back(track_adapter_map->GetOrCreateRemoteTrackAdapter(
- webrtc_video_track.get()));
- }
- return adapter_refs;
-}
-
-RemoteWebRtcMediaStreamAdapter::RemoteWebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream)
- : WebRtcMediaStreamAdapter(std::move(main_thread),
- std::move(track_adapter_map),
- std::move(webrtc_stream),
- // "null" |WebMediaStream|
- blink::WebMediaStream()),
- is_initialized_(false),
- weak_factory_(this) {
- CHECK(!main_thread_->BelongsToCurrentThread());
- CHECK(track_adapter_map_);
-
- RemoteAdapterRefs adapter_refs = GetRemoteAdapterRefsFromWebRtcStream(
- track_adapter_map_, webrtc_stream_.get());
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread,
- weak_factory_.GetWeakPtr(), webrtc_stream_->id(),
- std::move(adapter_refs),
- webrtc_stream_->GetAudioTracks().size(),
- webrtc_stream_->GetVideoTracks().size()));
-}
-
-RemoteWebRtcMediaStreamAdapter::~RemoteWebRtcMediaStreamAdapter() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- SetTracks(RemoteAdapterRefs());
-}
-
-bool RemoteWebRtcMediaStreamAdapter::is_initialized() const {
- base::AutoLock scoped_lock(lock_);
- return is_initialized_;
-}
-
-const scoped_refptr<webrtc::MediaStreamInterface>&
-RemoteWebRtcMediaStreamAdapter::webrtc_stream() const {
- base::AutoLock scoped_lock(lock_);
- DCHECK(is_initialized_);
- return webrtc_stream_;
-}
-
-const blink::WebMediaStream& RemoteWebRtcMediaStreamAdapter::web_stream()
- const {
- base::AutoLock scoped_lock(lock_);
- DCHECK(is_initialized_);
- return web_stream_;
-}
-
-void RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread(
- const std::string& label,
- RemoteAdapterRefs adapter_refs,
- size_t audio_track_count,
- size_t video_track_count) {
- CHECK(main_thread_->BelongsToCurrentThread());
- CHECK_EQ(audio_track_count + video_track_count, adapter_refs.size());
-
- adapter_refs_ = std::move(adapter_refs);
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks(
- audio_track_count);
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
- video_track_count);
- size_t audio_i = 0;
- size_t video_i = 0;
- for (const auto& adapter_ref : adapter_refs_) {
- const blink::WebMediaStreamTrack& web_track = adapter_ref->web_track();
- if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio)
- web_audio_tracks[audio_i++] = web_track;
- else
- web_video_tracks[video_i++] = web_track;
- }
-
- web_stream_.Initialize(blink::WebString::FromUTF8(label), web_audio_tracks,
- web_video_tracks);
- CHECK(!web_stream_.IsNull());
-
- base::AutoLock scoped_lock(lock_);
- is_initialized_ = true;
-}
-
-void RemoteWebRtcMediaStreamAdapter::SetTracks(
- WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs) {
- DCHECK(main_thread_->BelongsToCurrentThread());
-
- // Find removed tracks.
- base::EraseIf(
- adapter_refs_,
- [this, &track_refs](
- const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
- track_ref) {
- bool erase = !RemoteAdapterRefsContainsTrack(track_refs,
- track_ref->webrtc_track());
- if (erase)
- web_stream_.RemoveTrack(track_ref->web_track());
- return erase;
- });
- // Find added tracks.
- for (auto& track_ref : track_refs) {
- if (!RemoteAdapterRefsContainsTrack(adapter_refs_,
- track_ref->webrtc_track())) {
- web_stream_.AddTrack(track_ref->web_track());
- adapter_refs_.push_back(std::move(track_ref));
- }
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
deleted file mode 100644
index 49c6388ec5a..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/webrtc/api/mediastreaminterface.h"
-
-namespace content {
-
-class PeerConnectionDependencyFactory;
-
-// An adapter is the glue between webrtc and blink media streams. Adapters of
-// local media streams are created from a blink stream and get a webrtc stream
-// correspondent. Adapters of remote media streams are created from a webrtc
-// stream and get a blink stream correspondent. The adapter makes sure that when
-// the stream it was created from is modified the correspondent is updated to
-// reflect the new state.
-// The adapters are thread safe but must be constructed on the correct thread
-// (local adapters: main thread, remote adapters: webrtc signaling thread) and
-// destroyed on the main thread.
-class CONTENT_EXPORT WebRtcMediaStreamAdapter {
- public:
- using TrackAdapterRefs = std::vector<
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>;
-
- // Creates an adapter for a local media stream. The adapter is already
- // initialized. Invoked on the main thread.
- static std::unique_ptr<WebRtcMediaStreamAdapter> CreateLocalStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream);
- // Creates an adapter for a remote media stream. Invoked on the webrtc
- // signaling thread. The adapter is initialized in a post to the main thread.
- static std::unique_ptr<WebRtcMediaStreamAdapter> CreateRemoteStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream);
- // Invoke on the main thread.
- virtual ~WebRtcMediaStreamAdapter();
-
- // Once initialized, |webrtc_stream| and |web_stream| are accessible. An
- // initialized adapter remains initialized until destroyed.
- virtual bool is_initialized() const = 0;
- virtual const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
- const = 0;
- virtual const blink::WebMediaStream& web_stream() const = 0;
- bool IsEqual(const blink::WebMediaStream& stream) const {
- return (web_stream_.IsNull() && stream.IsNull()) ||
- (web_stream_.Id() == stream.Id());
- }
-
- virtual void SetTracks(TrackAdapterRefs track_refs) = 0;
-
- protected:
- WebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream,
- const blink::WebMediaStream& web_stream);
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- // The map and owner of all track adapters for the associated peer connection.
- // When a track is added or removed from this stream, the map provides us with
- // a reference to the corresponding track adapter, creating a new one if
- // necessary.
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
-
- // If |is_initialized()| both of these need to be set and remain constant.
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
- blink::WebMediaStream web_stream_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRtcMediaStreamAdapter);
-};
-
-// Adapter implementation for a local |blink::WebMediaStream|. Created and
-// destroyed on the main thread.
-class LocalWebRtcMediaStreamAdapter : public WebRtcMediaStreamAdapter,
- blink::WebMediaStreamObserver {
- public:
- LocalWebRtcMediaStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream);
- ~LocalWebRtcMediaStreamAdapter() override;
-
- // |WebRtcMediaStreamAdapter| implementation.
- bool is_initialized() const override;
- const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
- const override;
- const blink::WebMediaStream& web_stream() const override;
- void SetTracks(TrackAdapterRefs track_refs) override;
-
- private:
- // A map between web track UniqueIDs and references to track adapters.
- using LocalAdapterRefMap =
- std::map<int, // blink::WebMediaStreamTrack::UniqueId()
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>;
-
- // |MediaStreamObserver| implementation. Also used as a helper functions when
- // adding/removing all tracks in the constructor/destructor.
- void TrackAdded(const blink::WebMediaStreamTrack& web_track) override;
- void TrackRemoved(const blink::WebMediaStreamTrack& web_track) override;
-
- // Pointer to a |PeerConnectionDependencyFactory|, owned by the
- // |RenderThread|. It's valid for the lifetime of |RenderThread|.
- PeerConnectionDependencyFactory* const factory_;
-
- // Track adapters belonging to this stream. Keeping adapter references alive
- // ensures the adapters are not disposed by the |track_adapter_map_| as long
- // as the webrtc layer track is in use by the webrtc layer stream.
- LocalAdapterRefMap adapter_refs_;
-
- DISALLOW_COPY_AND_ASSIGN(LocalWebRtcMediaStreamAdapter);
-};
-
-// Adapter implementation for a remote |webrtc::MediaStreamInterface|. Created
-// on the the webrtc signaling thread, initialized on the main thread where it
-// must be destroyed.
-class RemoteWebRtcMediaStreamAdapter : public WebRtcMediaStreamAdapter {
- public:
- RemoteWebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream);
- ~RemoteWebRtcMediaStreamAdapter() override;
-
- // |WebRtcMediaStreamAdapter| implementation.
- bool is_initialized() const override;
- const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
- const override;
- const blink::WebMediaStream& web_stream() const override;
- void SetTracks(TrackAdapterRefs track_refs) override;
-
- private:
- // Track adapters for the remote webrtc tracks of a stream.
- using RemoteAdapterRefs = WebRtcMediaStreamAdapter::TrackAdapterRefs;
-
- static bool RemoteAdapterRefsContainsTrack(
- const RemoteAdapterRefs& adapter_refs,
- webrtc::MediaStreamTrackInterface* track);
-
- // Gets the adapters for the tracks that are members of the webrtc stream.
- // Invoke on webrtc signaling thread. New adapters are initialized in a post
- // to the main thread after which their |web_track| becomes available.
- static RemoteAdapterRefs GetRemoteAdapterRefsFromWebRtcStream(
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
- webrtc::MediaStreamInterface* webrtc_stream);
-
- void InitializeOnMainThread(const std::string& label,
- RemoteAdapterRefs track_adapter_refs,
- size_t audio_track_count,
- size_t video_track_count);
-
- mutable base::Lock lock_;
- bool is_initialized_;
- // Track adapters belonging to this stream. Keeping adapter references alive
- // ensures the adapters are not disposed by the |track_adapter_map_| as long
- // as the webrtc layer track is in use by the webrtc layer stream.
- RemoteAdapterRefs adapter_refs_;
- base::WeakPtrFactory<RemoteWebRtcMediaStreamAdapter> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoteWebRtcMediaStreamAdapter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
deleted file mode 100644
index b445ce8c893..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2017 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/webrtc/webrtc_media_stream_adapter_map.h"
-
-namespace content {
-
-WebRtcMediaStreamAdapterMap::AdapterEntry::AdapterEntry(
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter)
- : adapter(std::move(adapter)), ref_count(0) {
- DCHECK(this->adapter);
-}
-
-WebRtcMediaStreamAdapterMap::AdapterEntry::AdapterEntry(AdapterEntry&& other)
- : adapter(other.adapter.release()), ref_count(other.ref_count) {}
-
-WebRtcMediaStreamAdapterMap::AdapterEntry::~AdapterEntry() {
- // |ref_count| is allowed to be non-zero only if this entry has been moved
- // which is the case if the |adapter| has already been released.
- DCHECK(!ref_count || !adapter);
-}
-
-WebRtcMediaStreamAdapterMap::AdapterRef::AdapterRef(
- scoped_refptr<WebRtcMediaStreamAdapterMap> map,
- Type type,
- AdapterEntry* adapter_entry)
- : map_(std::move(map)), type_(type), adapter_entry_(adapter_entry) {
- DCHECK(map_);
- DCHECK(adapter_entry_);
- map_->lock_.AssertAcquired();
- ++adapter_entry_->ref_count;
-}
-
-WebRtcMediaStreamAdapterMap::AdapterRef::~AdapterRef() {
- DCHECK(map_->main_thread_->BelongsToCurrentThread());
- std::unique_ptr<WebRtcMediaStreamAdapter> removed_adapter;
- {
- base::AutoLock scoped_lock(map_->lock_);
- --adapter_entry_->ref_count;
- if (adapter_entry_->ref_count == 0) {
- removed_adapter = std::move(adapter_entry_->adapter);
- // "GetOrCreate..." ensures the adapter is initialized and the secondary
- // key is set before the last |AdapterRef| is destroyed. We can use either
- // the primary or secondary key for removal.
- if (type_ == Type::kLocal) {
- map_->local_stream_adapters_.EraseByPrimary(
- removed_adapter->web_stream().UniqueId());
- } else {
- map_->remote_stream_adapters_.EraseByPrimary(
- removed_adapter->webrtc_stream().get());
- }
- }
- }
- // Destroy the adapter whilst not holding the lock so that it is safe for
- // destructors to use the signaling thread synchronously without any risk of
- // deadlock.
- removed_adapter.reset();
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::AdapterRef::Copy() const {
- base::AutoLock scoped_lock(map_->lock_);
- return base::WrapUnique(new AdapterRef(map_, type_, adapter_entry_));
-}
-
-WebRtcMediaStreamAdapterMap::WebRtcMediaStreamAdapterMap(
- PeerConnectionDependencyFactory* const factory,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map)
- : factory_(factory),
- main_thread_(std::move(main_thread)),
- track_adapter_map_(std::move(track_adapter_map)) {
- DCHECK(factory_);
- DCHECK(main_thread_);
- DCHECK(track_adapter_map_);
-}
-
-WebRtcMediaStreamAdapterMap::~WebRtcMediaStreamAdapterMap() {
- DCHECK(local_stream_adapters_.empty());
- DCHECK(remote_stream_adapters_.empty());
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetLocalStreamAdapter(
- const blink::WebMediaStream& web_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- local_stream_adapters_.FindByPrimary(web_stream.UniqueId());
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kLocal, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetLocalStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- local_stream_adapters_.FindBySecondary(webrtc_stream);
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kLocal, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetOrCreateLocalStreamAdapter(
- const blink::WebMediaStream& web_stream) {
- CHECK(main_thread_->BelongsToCurrentThread());
- CHECK(!web_stream.IsNull());
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- local_stream_adapters_.FindByPrimary(web_stream.UniqueId());
- if (!adapter_entry) {
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
- {
- // Make sure we don't hold the lock while calling out to
- // CreateLocalStreamAdapter(). The reason is that constructing a local
- // stream adapter, will synchronize with WebRTC's signaling thread and
- // callbacks on the signaling thread might end up coming back to us
- // and we might need the lock then.
- base::AutoUnlock scoped_unlock(lock_);
- adapter = WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- factory_, track_adapter_map_, web_stream);
- }
-
- adapter_entry = local_stream_adapters_.Insert(web_stream.UniqueId(),
- std::move(adapter));
- CHECK(adapter_entry->adapter->is_initialized());
- CHECK(adapter_entry->adapter->webrtc_stream());
- local_stream_adapters_.SetSecondaryKey(
- web_stream.UniqueId(), adapter_entry->adapter->webrtc_stream().get());
- }
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kLocal, adapter_entry));
-}
-
-size_t WebRtcMediaStreamAdapterMap::GetLocalStreamCount() const {
- base::AutoLock scoped_lock(lock_);
- return local_stream_adapters_.PrimarySize();
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetRemoteStreamAdapter(
- const blink::WebMediaStream& web_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- remote_stream_adapters_.FindBySecondary(web_stream.UniqueId());
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetRemoteStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- remote_stream_adapters_.FindByPrimary(webrtc_stream);
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetOrCreateRemoteStreamAdapter(
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream) {
- CHECK(!main_thread_->BelongsToCurrentThread());
- CHECK(webrtc_stream);
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- remote_stream_adapters_.FindByPrimary(webrtc_stream.get());
- if (!adapter_entry) {
- // Make sure we don't hold the lock while calling out to
- // CreateRemoteStreamAdapter(). The reason is that it might synchronize
- // with other threads, possibly the main thread, where we might need to grab
- // the lock (e.g. inside of GetOrCreateLocalStreamAdapter()).
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
- {
- base::AutoUnlock scoped_unlock(lock_);
- adapter = WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
- main_thread_, track_adapter_map_, webrtc_stream.get());
- }
-
- adapter_entry =
- remote_stream_adapters_.Insert(webrtc_stream.get(), std::move(adapter));
-
- // The new adapter is initialized in a post to the main thread. As soon as
- // it is initialized we map its |webrtc_stream| to the
- // |remote_stream_adapters_| entry as its secondary key. This ensures that
- // there is at least one |AdapterRef| alive until after the adapter is
- // initialized and its secondary key is set.
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &WebRtcMediaStreamAdapterMap::OnRemoteStreamAdapterInitialized,
- this,
- base::WrapUnique(new AdapterRef(this, AdapterRef::Type::kRemote,
- adapter_entry))));
- }
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
-}
-
-size_t WebRtcMediaStreamAdapterMap::GetRemoteStreamCount() const {
- base::AutoLock scoped_lock(lock_);
- return remote_stream_adapters_.PrimarySize();
-}
-
-void WebRtcMediaStreamAdapterMap::OnRemoteStreamAdapterInitialized(
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref) {
- CHECK(main_thread_->BelongsToCurrentThread());
- CHECK(adapter_ref->is_initialized());
- CHECK(!adapter_ref->adapter().web_stream().IsNull());
- {
- base::AutoLock scoped_lock(lock_);
- remote_stream_adapters_.SetSecondaryKey(
- adapter_ref->adapter().webrtc_stream().get(),
- adapter_ref->adapter().web_stream().UniqueId());
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
deleted file mode 100644
index 1d9c40b6692..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2017 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.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
-
-#include <map>
-#include <memory>
-
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/two_keys_adapter_map.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/webrtc/api/mediastreaminterface.h"
-
-namespace content {
-
-// A map and owner of |WebRtcMediaStreamAdapter|s. Adapters are the glue between
-// blink and webrtc layer versions of streams. As long as a stream is in use by
-// a peer connection there has to exist an adapter for it. The map takes care of
-// creating and disposing stream adapters. Adapters are accessed via
-// |AdapterRef|s, when all references to an adapter are destroyed it is
-// destroyed and removed from the map.
-class CONTENT_EXPORT WebRtcMediaStreamAdapterMap
- : public base::RefCountedThreadSafe<WebRtcMediaStreamAdapterMap> {
- private:
- // The map's entries are reference counted in order to remove the adapter when
- // all |AdapterRef|s referencing an entry are destroyed.
- // Private section needed here due to |AdapterRef|'s usage of |AdapterEntry|.
- struct AdapterEntry {
- AdapterEntry(std::unique_ptr<WebRtcMediaStreamAdapter> adapter);
- AdapterEntry(AdapterEntry&& other);
- ~AdapterEntry();
-
- AdapterEntry(const AdapterEntry&) = delete;
- AdapterEntry& operator=(const AdapterEntry&) = delete;
-
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
- size_t ref_count;
- };
-
- public:
- // Accessor to an adapter to take care of reference counting. When the last
- // |AdapterRef| is destroyed, the corresponding adapter is destroyed and
- // removed from the map.
- class CONTENT_EXPORT AdapterRef {
- public:
- // Must be invoked on the main thread. If this was the last reference to the
- // adapter it will be disposed and removed from the map.
- ~AdapterRef();
-
- std::unique_ptr<AdapterRef> Copy() const;
- bool is_initialized() const { return adapter().is_initialized(); }
- const WebRtcMediaStreamAdapter& adapter() const {
- return *adapter_entry_->adapter;
- }
- WebRtcMediaStreamAdapter& adapter() { return *adapter_entry_->adapter; }
-
- private:
- friend class WebRtcMediaStreamAdapterMap;
-
- enum class Type { kLocal, kRemote };
-
- // Increments the |AdapterEntry::ref_count|. Assumes map's |lock_| is held.
- AdapterRef(scoped_refptr<WebRtcMediaStreamAdapterMap> map,
- Type type,
- AdapterEntry* adapter_entry);
-
- scoped_refptr<WebRtcMediaStreamAdapterMap> map_;
- Type type_;
- AdapterEntry* adapter_entry_;
- };
-
- // Must be invoked on the main thread.
- WebRtcMediaStreamAdapterMap(
- PeerConnectionDependencyFactory* const factory,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map);
-
- // Gets a new reference to the local stream adapter, or null if no such
- // adapter was found. When all references are destroyed the adapter is
- // destroyed and removed from the map. This can be called on any thread, but
- // references must be destroyed on the main thread.
- // The adapter is a associated with a blink and webrtc stream, lookup works by
- // either stream.
- std::unique_ptr<AdapterRef> GetLocalStreamAdapter(
- const blink::WebMediaStream& web_stream);
- std::unique_ptr<AdapterRef> GetLocalStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream);
- // Invoke on the main thread. Gets a new reference to the local stream adapter
- // for the web stream. If no adapter exists for the stream one is created.
- // When all references are destroyed the adapter is destroyed and removed from
- // the map. References must be destroyed on the main thread.
- std::unique_ptr<AdapterRef> GetOrCreateLocalStreamAdapter(
- const blink::WebMediaStream& web_stream);
- size_t GetLocalStreamCount() const;
-
- // Gets a new reference to the remote stream adapter by ID, or null if no such
- // adapter was found. When all references are destroyed the adapter is
- // destroyed and removed from the map. This can be called on any thread, but
- // references must be destroyed on the main thread. The adapter is a
- // associated with a blink and webrtc stream, lookup works by either stream.
- // First variety: If an adapter exists it will already be initialized, if one
- // does not exist null is returned.
- std::unique_ptr<AdapterRef> GetRemoteStreamAdapter(
- const blink::WebMediaStream& web_stream);
- // Second variety: If an adapter exists it may or may not be initialized, see
- // |AdapterRef::is_initialized|. If an adapter does not exist null is
- // returned.
- std::unique_ptr<AdapterRef> GetRemoteStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream);
- // Invoke on the webrtc signaling thread. Gets a new reference to the remote
- // stream adapter for the webrtc stream. If no adapter exists for the stream
- // one is created and initialization completes on the main thread in a post.
- // When all references are destroyed the adapter is destroyed and removed from
- // the map. References must be destroyed on the main thread.
- std::unique_ptr<AdapterRef> GetOrCreateRemoteStreamAdapter(
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream);
- size_t GetRemoteStreamCount() const;
-
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map()
- const {
- return track_adapter_map_;
- }
-
- private:
- friend class base::RefCountedThreadSafe<WebRtcMediaStreamAdapterMap>;
-
- // "(blink::WebMediaStream, webrtc::MediaStreamInterface) -> AdapterEntry"
- // maps. The primary key is based on the object used to create the adapter.
- // Local streams are created from |blink::WebMediaStream|s, remote streams are
- // created from |webrtc::MediaStreamInterface|s.
- // The adapter keeps the |webrtc::MediaStreamInterface| alive with ref
- // counting making it safe to use a raw pointer for key.
- using LocalStreamAdapterMap =
- TwoKeysAdapterMap<int, // blink::WebMediaStream::UniqueId()
- webrtc::MediaStreamInterface*,
- AdapterEntry>;
- using RemoteStreamAdapterMap =
- TwoKeysAdapterMap<webrtc::MediaStreamInterface*,
- int, // blink::WebMediaStream::UniqueId()
- AdapterEntry>;
-
- // Invoke on the main thread.
- virtual ~WebRtcMediaStreamAdapterMap();
-
- void OnRemoteStreamAdapterInitialized(
- std::unique_ptr<AdapterRef> adapter_ref);
-
- // Pointer to a |PeerConnectionDependencyFactory| owned by the |RenderThread|.
- // It's valid for the lifetime of |RenderThread|.
- PeerConnectionDependencyFactory* const factory_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- // Takes care of creating and owning track adapters, used by stream adapters.
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
-
- mutable base::Lock lock_;
- LocalStreamAdapterMap local_stream_adapters_;
- RemoteStreamAdapterMap remote_stream_adapters_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc
deleted file mode 100644
index 87f0032a8bd..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright (c) 2017 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/webrtc/webrtc_media_stream_adapter_map.h"
-
-#include <memory>
-#include <string>
-
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/scoped_task_environment.h"
-#include "content/child/child_process.h"
-#include "content/renderer/media/mock_audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_heap.h"
-
-using ::testing::_;
-
-namespace content {
-
-class WebRtcMediaStreamAdapterMapTest : public ::testing::Test {
- public:
- void SetUp() override {
- dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
- main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- map_ = new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
- }
-
- void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); }
-
- blink::WebMediaStream CreateLocalStream(const std::string& id) {
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
- static_cast<size_t>(1));
- blink::WebMediaStreamSource video_source;
- video_source.Initialize("video_source",
- blink::WebMediaStreamSource::kTypeVideo,
- "video_source", false /* remote */);
- MediaStreamVideoSource* native_source = new MockMediaStreamVideoSource();
- video_source.SetExtraData(native_source);
- web_video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
- native_source, MediaStreamVideoSource::ConstraintsCallback(), true);
-
- blink::WebMediaStream web_stream;
- web_stream.Initialize(blink::WebString::FromUTF8(id),
- blink::WebVector<blink::WebMediaStreamTrack>(),
- web_video_tracks);
- return web_stream;
- }
-
- scoped_refptr<webrtc::MediaStreamInterface> CreateRemoteStream(
- const std::string& id) {
- scoped_refptr<webrtc::MediaStreamInterface> stream(
- new rtc::RefCountedObject<MockMediaStream>(id));
- stream->AddTrack(MockWebRtcAudioTrack::Create("remote_audio_track").get());
- stream->AddTrack(MockWebRtcVideoTrack::Create("remote_video_track").get());
- return stream;
- }
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- GetOrCreateRemoteStreamAdapter(webrtc::MediaStreamInterface* webrtc_stream) {
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref;
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcMediaStreamAdapterMapTest::
- GetOrCreateRemoteStreamAdapterOnSignalingThread,
- base::Unretained(this), base::Unretained(webrtc_stream),
- base::Unretained(&adapter_ref)));
- RunMessageLoopsUntilIdle();
- DCHECK(adapter_ref);
- return adapter_ref;
- }
-
- protected:
- void GetOrCreateRemoteStreamAdapterOnSignalingThread(
- webrtc::MediaStreamInterface* webrtc_stream,
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>* adapter_ref) {
- *adapter_ref = map_->GetOrCreateRemoteStreamAdapter(webrtc_stream);
- EXPECT_TRUE(*adapter_ref);
- }
-
- // Runs message loops on the webrtc signaling thread and the main thread until
- // idle.
- void RunMessageLoopsUntilIdle() {
- base::WaitableEvent waitable_event(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE, base::BindOnce(&WebRtcMediaStreamAdapterMapTest::SignalEvent,
- base::Unretained(this), &waitable_event));
- waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
- }
-
- void SignalEvent(base::WaitableEvent* waitable_event) {
- waitable_event->Signal();
- }
-
- // Message loop and child processes is needed for task queues and threading to
- // work, as is necessary to create tracks and adapters.
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- ChildProcess child_process_;
-
- std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> map_;
-};
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, AddAndRemoveLocalStreamAdapter) {
- blink::WebMediaStream local_web_stream = CreateLocalStream("local_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- map_->GetOrCreateLocalStreamAdapter(local_web_stream);
- EXPECT_TRUE(adapter_ref);
- EXPECT_TRUE(adapter_ref->adapter().IsEqual(local_web_stream));
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetLocalStreamAdapter(local_web_stream);
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
-
- adapter_ref.reset();
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
- adapter_ref2.reset();
- EXPECT_EQ(0u, map_->GetLocalStreamCount());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, LookUpLocalAdapterByWebRtcStream) {
- blink::WebMediaStream local_web_stream = CreateLocalStream("local_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- map_->GetOrCreateLocalStreamAdapter(local_web_stream);
- EXPECT_TRUE(adapter_ref);
- EXPECT_TRUE(adapter_ref->adapter().IsEqual(local_web_stream));
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetLocalStreamAdapter(adapter_ref->adapter().web_stream());
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, GetLocalStreamAdapterInvalidID) {
- blink::WebMediaStream local_web_stream = CreateLocalStream("missing");
- EXPECT_FALSE(map_->GetLocalStreamAdapter(local_web_stream));
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, AddAndRemoveRemoteStreamAdapter) {
- scoped_refptr<webrtc::MediaStreamInterface> remote_webrtc_stream =
- CreateRemoteStream("remote_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- GetOrCreateRemoteStreamAdapter(remote_webrtc_stream.get());
- EXPECT_EQ(remote_webrtc_stream, adapter_ref->adapter().webrtc_stream());
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetRemoteStreamAdapter(remote_webrtc_stream.get());
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
-
- adapter_ref.reset();
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
- adapter_ref2.reset();
- EXPECT_EQ(0u, map_->GetRemoteStreamCount());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, LookUpRemoteAdapterByWebStream) {
- scoped_refptr<webrtc::MediaStreamInterface> remote_webrtc_stream =
- CreateRemoteStream("remote_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- GetOrCreateRemoteStreamAdapter(remote_webrtc_stream.get());
- EXPECT_EQ(remote_webrtc_stream, adapter_ref->adapter().webrtc_stream());
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetRemoteStreamAdapter(
- adapter_ref->adapter().webrtc_stream().get());
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, GetRemoteStreamAdapterInvalidID) {
- scoped_refptr<webrtc::MediaStreamInterface> remote_webrtc_stream =
- CreateRemoteStream("missing");
- EXPECT_FALSE(map_->GetRemoteStreamAdapter(remote_webrtc_stream.get()));
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
deleted file mode 100644
index ec8ffdca628..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright 2014 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/webrtc/webrtc_media_stream_adapter.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/child_process.h"
-#include "content/renderer/media/mock_audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/media/stream/mock_constraint_factory.h"
-#include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/stream/processed_local_audio_source.h"
-#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_heap.h"
-
-using ::testing::_;
-
-namespace content {
-
-class WebRtcMediaStreamAdapterTest : public ::testing::Test {
- public:
- void SetUp() override {
- dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
- track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap(
- dependency_factory_.get(),
- blink::scheduler::GetSingleThreadTaskRunnerForTesting());
- }
-
- void TearDown() override {
- track_adapter_map_ = nullptr;
- blink::WebHeap::CollectAllGarbageForTesting();
- }
-
- protected:
- // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
- // TaskScheduler.
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- ChildProcess child_process_;
- std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
-};
-
-class LocalWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
- public:
- blink::WebMediaStream CreateWebMediaStream(
- const std::string& audio_track_id,
- const std::string& video_track_id) {
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks(
- static_cast<size_t>(1u));
- blink::WebMediaStreamSource audio_source;
- audio_source.Initialize(blink::WebString::FromUTF8(audio_track_id),
- blink::WebMediaStreamSource::kTypeAudio,
- blink::WebString::FromUTF8(audio_track_id),
- false /* remote */);
- ProcessedLocalAudioSource* const source = new ProcessedLocalAudioSource(
- -1 /* consumer_render_frame_id is N/A for non-browser tests */,
- MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "mock_audio_device_id",
- "Mock audio device",
- media::AudioParameters::kAudioCDSampleRate,
- media::CHANNEL_LAYOUT_STEREO,
- media::AudioParameters::kAudioCDSampleRate / 50),
- false /* hotword_enabled */, false /* disable_local_echo */,
- AudioProcessingProperties(),
- base::Bind(&LocalWebRtcMediaStreamAdapterTest::OnAudioSourceStarted),
- dependency_factory_.get());
- source->SetAllowInvalidRenderFrameIdForTesting(true);
- audio_source.SetExtraData(source); // Takes ownership.
- audio_tracks[0].Initialize(blink::WebString::FromUTF8(audio_track_id),
- audio_source);
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(),
- Initialize(_, _));
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(),
- SetAutomaticGainControl(true));
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(), Start());
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(), Stop());
- CHECK(source->ConnectToTrack(audio_tracks[0]));
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
- static_cast<size_t>(1u));
- MediaStreamSource::SourceStoppedCallback dummy_callback;
- blink::WebMediaStreamSource video_source;
- video_source.Initialize(blink::WebString::FromUTF8(video_track_id),
- blink::WebMediaStreamSource::kTypeVideo,
- blink::WebString::FromUTF8(video_track_id),
- false /* remote */);
- MediaStreamVideoSource* native_source = new MockMediaStreamVideoSource();
- video_source.SetExtraData(native_source);
- video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
- blink::WebString::FromUTF8(video_track_id), native_source,
- MediaStreamVideoSource::ConstraintsCallback(), true);
-
- blink::WebMediaStream stream_desc;
- stream_desc.Initialize("stream_id", audio_tracks, video_tracks);
- return stream_desc;
- }
-
- private:
- static void OnAudioSourceStarted(MediaStreamSource* source,
- MediaStreamRequestResult result,
- const blink::WebString& result_name) {}
-
- MockAudioDeviceFactory mock_audio_device_factory_;
-};
-
-class RemoteWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
- public:
- scoped_refptr<webrtc::MediaStreamInterface> CreateWebRtcMediaStream(
- const std::string& audio_track_id,
- const std::string& video_track_id) {
- scoped_refptr<webrtc::MediaStreamInterface> stream(
- new rtc::RefCountedObject<MockMediaStream>("remote_stream"));
- stream->AddTrack(MockWebRtcAudioTrack::Create(audio_track_id).get());
- stream->AddTrack(MockWebRtcVideoTrack::Create(video_track_id).get());
- return stream;
- }
-
- std::unique_ptr<WebRtcMediaStreamAdapter> CreateRemoteStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream) {
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RemoteWebRtcMediaStreamAdapterTest::
- CreateRemoteStreamAdapterOnSignalingThread,
- base::Unretained(this),
- base::Unretained(
- blink::scheduler::GetSingleThreadTaskRunnerForTesting().get()),
- base::Unretained(webrtc_stream), base::Unretained(&adapter)));
- RunMessageLoopsUntilIdle();
- DCHECK(adapter);
- return adapter;
- }
-
- // Adds the track and gets the adapters for the stream's resulting tracks.
- template <typename TrackType>
- WebRtcMediaStreamAdapter::TrackAdapterRefs AddTrack(
- webrtc::MediaStreamInterface* webrtc_stream,
- TrackType* webrtc_track) {
- typedef bool (webrtc::MediaStreamInterface::*AddTrack)(TrackType*);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE, base::BindOnce(base::IgnoreResult<AddTrack>(
- &webrtc::MediaStreamInterface::AddTrack),
- base::Unretained(webrtc_stream),
- base::Unretained(webrtc_track)));
- WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs;
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(&RemoteWebRtcMediaStreamAdapterTest::
- GetStreamTrackRefsOnSignalingThread,
- base::Unretained(this), base::Unretained(webrtc_stream),
- base::Unretained(&track_refs)));
- RunMessageLoopsUntilIdle();
- return track_refs;
- }
-
- // Removes the track and gets the adapters for the stream's resulting tracks.
- template <typename TrackType>
- WebRtcMediaStreamAdapter::TrackAdapterRefs RemoveTrack(
- webrtc::MediaStreamInterface* webrtc_stream,
- TrackType* webrtc_track) {
- typedef bool (webrtc::MediaStreamInterface::*RemoveTrack)(TrackType*);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(base::IgnoreResult<RemoveTrack>(
- &webrtc::MediaStreamInterface::RemoveTrack),
- base::Unretained(webrtc_stream),
- base::Unretained(webrtc_track)));
- WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs;
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(&RemoteWebRtcMediaStreamAdapterTest::
- GetStreamTrackRefsOnSignalingThread,
- base::Unretained(this), base::Unretained(webrtc_stream),
- base::Unretained(&track_refs)));
- RunMessageLoopsUntilIdle();
- return track_refs;
- }
-
- private:
- void CreateRemoteStreamAdapterOnSignalingThread(
- base::SingleThreadTaskRunner* main_thread,
- webrtc::MediaStreamInterface* webrtc_stream,
- std::unique_ptr<WebRtcMediaStreamAdapter>* adapter) {
- *adapter = WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
- main_thread, track_adapter_map_, webrtc_stream);
- EXPECT_FALSE((*adapter)->is_initialized());
- }
-
- void GetStreamTrackRefsOnSignalingThread(
- webrtc::MediaStreamInterface* webrtc_stream,
- WebRtcMediaStreamAdapter::TrackAdapterRefs* out_track_refs) {
- WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs;
- for (auto& audio_track : webrtc_stream->GetAudioTracks()) {
- track_refs.push_back(
- track_adapter_map_->GetOrCreateRemoteTrackAdapter(audio_track.get()));
- }
- for (auto& video_track : webrtc_stream->GetVideoTracks()) {
- track_refs.push_back(
- track_adapter_map_->GetOrCreateRemoteTrackAdapter(video_track.get()));
- }
- *out_track_refs = std::move(track_refs);
- }
-
- // Runs message loops on the webrtc signaling thread and the main thread until
- // idle.
- void RunMessageLoopsUntilIdle() {
- base::WaitableEvent waitable_event(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(&RemoteWebRtcMediaStreamAdapterTest::SignalEvent,
- base::Unretained(this), &waitable_event));
- // TODO(hbos): Use base::RunLoop instead of WaitableEvent.
- waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
- }
-
- void SignalEvent(base::WaitableEvent* waitable_event) {
- waitable_event->Signal();
- }
-};
-
-TEST_F(LocalWebRtcMediaStreamAdapterTest, CreateStreamAdapter) {
- blink::WebMediaStream web_stream =
- CreateWebMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-}
-
-TEST_F(LocalWebRtcMediaStreamAdapterTest,
- CreateStreamAdapterWithSharedTrackIds) {
- blink::WebMediaStream web_stream =
- CreateWebMediaStream("shared_track_id", "shared_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-}
-
-// It should not crash if |MediaStream| is created in blink with an unknown
-// audio source. This can happen if a |MediaStream| is created with remote audio
-// track.
-TEST_F(LocalWebRtcMediaStreamAdapterTest,
- AdapterForWebStreamWithoutAudioSource) {
- // Create a blink MediaStream description.
- blink::WebMediaStreamSource audio_source;
- audio_source.Initialize("audio source",
- blink::WebMediaStreamSource::kTypeAudio, "something",
- false /* remote */);
- // Without |audio_source.SetExtraData()| it is possible to initialize tracks
- // and streams but the source is a dummy.
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks(
- static_cast<size_t>(1));
- audio_tracks[0].Initialize(audio_source.Id(), audio_source);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
- static_cast<size_t>(0));
-
- blink::WebMediaStream web_stream;
- web_stream.Initialize("stream_id", audio_tracks, video_tracks);
-
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(0u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(0u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-}
-
-TEST_F(LocalWebRtcMediaStreamAdapterTest, RemoveAndAddTrack) {
- blink::WebMediaStream web_stream =
- CreateWebMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-
- // Modify the web layer stream, make sure the webrtc layer stream is updated.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream.AudioTracks(audio_tracks);
-
- web_stream.RemoveTrack(audio_tracks[0]);
- EXPECT_TRUE(adapter->webrtc_stream()->GetAudioTracks().empty());
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream.VideoTracks(video_tracks);
-
- web_stream.RemoveTrack(video_tracks[0]);
- EXPECT_TRUE(adapter->webrtc_stream()->GetVideoTracks().empty());
-
- web_stream.AddTrack(audio_tracks[0]);
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
-
- web_stream.AddTrack(video_tracks[0]);
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
-}
-
-TEST_F(RemoteWebRtcMediaStreamAdapterTest, CreateStreamAdapter) {
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream =
- CreateWebRtcMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- CreateRemoteStreamAdapter(webrtc_stream.get());
- EXPECT_TRUE(adapter->is_initialized());
- EXPECT_EQ(webrtc_stream, adapter->webrtc_stream());
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-}
-
-TEST_F(RemoteWebRtcMediaStreamAdapterTest,
- CreateStreamAdapterWithSharedTrackIds) {
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream =
- CreateWebRtcMediaStream("shared_track_id", "shared_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- CreateRemoteStreamAdapter(webrtc_stream.get());
- EXPECT_TRUE(adapter->is_initialized());
- EXPECT_EQ(webrtc_stream, adapter->webrtc_stream());
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-}
-
-TEST_F(RemoteWebRtcMediaStreamAdapterTest, RemoveAndAddTrack) {
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream =
- CreateWebRtcMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- CreateRemoteStreamAdapter(webrtc_stream.get());
- EXPECT_TRUE(adapter->is_initialized());
- EXPECT_EQ(webrtc_stream, adapter->webrtc_stream());
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-
- // Modify the webrtc layer stream, make sure the web layer stream is updated.
- rtc::scoped_refptr<webrtc::AudioTrackInterface> webrtc_audio_track =
- webrtc_stream->GetAudioTracks()[0];
- adapter->SetTracks(
- RemoveTrack(webrtc_stream.get(), webrtc_audio_track.get()));
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(0u, web_audio_tracks.size());
-
- rtc::scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track =
- webrtc_stream->GetVideoTracks()[0];
- adapter->SetTracks(
- RemoveTrack(webrtc_stream.get(), webrtc_video_track.get()));
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(0u, web_video_tracks.size());
-
- adapter->SetTracks(AddTrack(webrtc_stream.get(), webrtc_audio_track.get()));
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
-
- adapter->SetTracks(AddTrack(webrtc_stream.get(), webrtc_video_track.get()));
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
index e03d1719ee0..a20adaaae7b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
@@ -63,22 +63,24 @@ WebRtcMediaStreamTrackAdapter::WebRtcMediaStreamTrackAdapter(
remote_track_can_complete_initialization_(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
- is_initialized_(false) {
+ is_initialized_(false),
+ is_disposed_(false) {
DCHECK(factory_);
DCHECK(main_thread_);
}
WebRtcMediaStreamTrackAdapter::~WebRtcMediaStreamTrackAdapter() {
DCHECK(!remote_track_can_complete_initialization_.IsSignaled());
- DCHECK(!is_initialized_);
+ DCHECK(is_disposed_);
}
void WebRtcMediaStreamTrackAdapter::Dispose() {
DCHECK(main_thread_->BelongsToCurrentThread());
- if (!is_initialized_)
+ DCHECK(is_initialized_);
+ if (is_disposed_)
return;
remote_track_can_complete_initialization_.Reset();
- is_initialized_ = false;
+ is_disposed_ = true;
if (web_track_.Source().GetType() ==
blink::WebMediaStreamSource::kTypeAudio) {
if (local_track_audio_sink_)
@@ -99,10 +101,19 @@ bool WebRtcMediaStreamTrackAdapter::is_initialized() const {
return is_initialized_;
}
+void WebRtcMediaStreamTrackAdapter::InitializeOnMainThread() {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ if (is_initialized_)
+ return;
+ // TODO(hbos): Only ever initialize explicitly,
+ // remove EnsureTrackIsInitialized(). https://crbug.com/857458
+ EnsureTrackIsInitialized();
+}
+
const blink::WebMediaStreamTrack& WebRtcMediaStreamTrackAdapter::web_track() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!web_track_.IsNull());
EnsureTrackIsInitialized();
+ DCHECK(!web_track_.IsNull());
return web_track_;
}
@@ -231,6 +242,7 @@ void WebRtcMediaStreamTrackAdapter::
}
void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() {
+ DCHECK(main_thread_->BelongsToCurrentThread());
if (is_initialized_)
return;
@@ -242,7 +254,6 @@ void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() {
void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(local_track_audio_sink_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeAudio);
@@ -256,7 +267,6 @@ void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(local_track_video_sink_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeVideo);
@@ -267,7 +277,6 @@ void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(remote_audio_track_adapter_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeAudio);
@@ -280,7 +289,6 @@ void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(remote_video_track_adapter_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeVideo);
@@ -300,7 +308,7 @@ void WebRtcMediaStreamTrackAdapter::
void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
+ DCHECK(is_disposed_);
remote_audio_track_adapter_ = nullptr;
remote_video_track_adapter_ = nullptr;
webrtc_track_ = nullptr;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
index 722738c3950..8be75b5b895 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
@@ -53,6 +53,7 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
void Dispose();
bool is_initialized() const;
+ void InitializeOnMainThread();
// These methods must be called on the main thread.
// TODO(hbos): Allow these methods to be called on any thread and make them
// const. https://crbug.com/756436
@@ -116,6 +117,7 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
// completed on the main thread.
base::WaitableEvent remote_track_can_complete_initialization_;
bool is_initialized_;
+ bool is_disposed_;
blink::WebMediaStreamTrack web_track_;
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
// If the track is local, a sink is added to the local webrtc track that is
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
index 28d6c1713a4..de3f036beff 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
@@ -59,6 +59,17 @@ WebRtcMediaStreamTrackAdapterMap::AdapterRef::Copy() const {
return base::WrapUnique(new AdapterRef(map_, type_, adapter_));
}
+void WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread() {
+ adapter_->InitializeOnMainThread();
+ if (type_ == WebRtcMediaStreamTrackAdapterMap::AdapterRef::Type::kRemote) {
+ base::AutoLock scoped_lock(map_->lock_);
+ if (!map_->remote_track_adapters_.FindBySecondary(web_track().UniqueId())) {
+ map_->remote_track_adapters_.SetSecondaryKey(webrtc_track(),
+ web_track().UniqueId());
+ }
+ }
+}
+
WebRtcMediaStreamTrackAdapterMap::WebRtcMediaStreamTrackAdapterMap(
PeerConnectionDependencyFactory* const factory,
scoped_refptr<base::SingleThreadTaskRunner> main_thread)
@@ -182,13 +193,13 @@ WebRtcMediaStreamTrackAdapterMap::GetOrCreateRemoteTrackAdapter(
// entry as its secondary key. This ensures that there is at least one
// |AdapterRef| alive until after the adapter is initialized and its secondary
// key is set.
+ auto adapter_ref = base::WrapUnique(
+ new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter));
main_thread_->PostTask(
FROM_HERE,
base::BindOnce(
- &WebRtcMediaStreamTrackAdapterMap::OnRemoteTrackAdapterInitialized,
- this,
- base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter))));
+ &WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread,
+ std::move(adapter_ref)));
return base::WrapUnique(
new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter));
}
@@ -198,14 +209,4 @@ size_t WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackCount() const {
return remote_track_adapters_.PrimarySize();
}
-void WebRtcMediaStreamTrackAdapterMap::OnRemoteTrackAdapterInitialized(
- std::unique_ptr<AdapterRef> adapter_ref) {
- DCHECK(adapter_ref->is_initialized());
- {
- base::AutoLock scoped_lock(lock_);
- remote_track_adapters_.SetSecondaryKey(adapter_ref->webrtc_track(),
- adapter_ref->web_track().UniqueId());
- }
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
index c7ef9ed9b92..8c9cbf17c0d 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
@@ -38,6 +38,7 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapterMap
std::unique_ptr<AdapterRef> Copy() const;
bool is_initialized() const { return adapter_->is_initialized(); }
+ void InitializeOnMainThread();
const blink::WebMediaStreamTrack& web_track() const {
return adapter_->web_track();
}
@@ -137,8 +138,6 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapterMap
// Invoke on the main thread.
virtual ~WebRtcMediaStreamTrackAdapterMap();
- void OnRemoteTrackAdapterInitialized(std::unique_ptr<AdapterRef> adapter_ref);
-
// Pointer to a |PeerConnectionDependencyFactory| owned by the |RenderThread|.
// It's valid for the lifetime of |RenderThread|.
PeerConnectionDependencyFactory* const factory_;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
index 8c5fd3e426f..a141ce50156 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
@@ -53,8 +53,8 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
}
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- GetOrCreateRemoteTrackAdapter(
- webrtc::MediaStreamTrackInterface* webrtc_track) {
+ GetOrCreateRemoteTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track,
+ bool wait_for_initialization = true) {
DCHECK(main_thread_->BelongsToCurrentThread());
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter;
signaling_thread()->PostTask(
@@ -63,7 +63,13 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
GetOrCreateRemoteTrackAdapterOnSignalingThread,
base::Unretained(this), base::Unretained(webrtc_track),
&adapter));
- RunMessageLoopsUntilIdle();
+ RunMessageLoopsUntilIdle(wait_for_initialization);
+ DCHECK(adapter);
+ if (wait_for_initialization) {
+ DCHECK(adapter->is_initialized());
+ } else {
+ DCHECK(!adapter->is_initialized());
+ }
return adapter;
}
@@ -76,7 +82,7 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
// Runs message loops on the webrtc signaling thread and the main thread until
// idle.
- void RunMessageLoopsUntilIdle() {
+ void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) {
DCHECK(main_thread_->BelongsToCurrentThread());
base::WaitableEvent waitable_event(
base::WaitableEvent::ResetPolicy::MANUAL,
@@ -86,7 +92,8 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
RunMessageLoopUntilIdleOnSignalingThread,
base::Unretained(this), &waitable_event));
waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
+ if (run_loop_on_main_thread)
+ base::RunLoop().RunUntilIdle();
}
void RunMessageLoopUntilIdleOnSignalingThread(
@@ -168,6 +175,29 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveRemoteTrackAdapter) {
}
TEST_F(WebRtcMediaStreamTrackAdapterMapTest,
+ InitializeRemoteTrackAdapterExplicitly) {
+ scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
+ MockWebRtcAudioTrack::Create("remote_track");
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
+ GetOrCreateRemoteTrackAdapter(webrtc_track.get(), false);
+ EXPECT_FALSE(adapter_ref->is_initialized());
+ adapter_ref->InitializeOnMainThread();
+ EXPECT_TRUE(adapter_ref->is_initialized());
+
+ EXPECT_EQ(1u, map_->GetRemoteTrackCount());
+ // Ensure the implicit initialization's posted task is run after it is already
+ // initialized.
+ RunMessageLoopsUntilIdle();
+ // Destroying all references to the adapter should remove it from the map and
+ // dispose it.
+ adapter_ref.reset();
+ EXPECT_EQ(0u, map_->GetRemoteTrackCount());
+ EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(webrtc_track.get()));
+ // Allow the disposing of track to occur.
+ RunMessageLoopsUntilIdle();
+}
+
+TEST_F(WebRtcMediaStreamTrackAdapterMapTest,
LocalAndRemoteTrackAdaptersWithSameID) {
// Local and remote tracks should be able to use the same id without conflict.
const char* id = "id";
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
index 7ca513bc07f..74f586d44b1 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
@@ -37,7 +37,6 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
if (track_adapter_) {
EXPECT_TRUE(track_adapter_->is_initialized());
track_adapter_->Dispose();
- EXPECT_FALSE(track_adapter_->is_initialized());
track_adapter_ = nullptr;
RunMessageLoopsUntilIdle();
}
@@ -80,9 +79,9 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
dependency_factory_.get(), main_thread_, webrtc_track);
}
- // Runs message loops on the webrtc signaling thread and the main thread until
- // idle.
- void RunMessageLoopsUntilIdle() {
+ // Runs message loops on the webrtc signaling thread and optionally the main
+ // thread until idle.
+ void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) {
base::WaitableEvent waitable_event(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -91,7 +90,8 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
RunMessageLoopUntilIdleOnSignalingThread,
base::Unretained(this), &waitable_event));
waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
+ if (run_loop_on_main_thread)
+ base::RunLoop().RunUntilIdle();
}
void RunMessageLoopUntilIdleOnSignalingThread(
@@ -157,6 +157,7 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteAudioTrack) {
base::BindOnce(
&WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // The adapter is initialized implicitly in a PostTask, allow it to run.
RunMessageLoopsUntilIdle();
DCHECK(track_adapter_);
EXPECT_TRUE(track_adapter_->is_initialized());
@@ -181,6 +182,7 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) {
base::BindOnce(
&WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // The adapter is initialized implicitly in a PostTask, allow it to run.
RunMessageLoopsUntilIdle();
DCHECK(track_adapter_);
EXPECT_TRUE(track_adapter_->is_initialized());
@@ -197,4 +199,33 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) {
track_adapter_->GetRemoteVideoTrackAdapterForTesting()->initialized());
}
+TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteTrackExplicitlyInitialized) {
+ scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
+ MockWebRtcAudioTrack::Create("remote_audio_track");
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
+ base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // Wait for the CreateRemoteTrackAdapter() call, but don't run the main thread
+ // loop that would have implicitly initialized the adapter.
+ RunMessageLoopsUntilIdle(false);
+ DCHECK(track_adapter_);
+ EXPECT_FALSE(track_adapter_->is_initialized());
+ // Explicitly initialize before the main thread loop has a chance to run.
+ track_adapter_->InitializeOnMainThread();
+ EXPECT_TRUE(track_adapter_->is_initialized());
+ EXPECT_TRUE(!track_adapter_->web_track().IsNull());
+ EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
+ blink::WebMediaStreamSource::kTypeAudio);
+ EXPECT_TRUE(track_adapter_->webrtc_track());
+ EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
+ webrtc::MediaStreamTrackInterface::kAudioKind);
+ EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
+ track_adapter_->web_track().Id());
+ EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting());
+ EXPECT_TRUE(
+ track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc
new file mode 100644
index 00000000000..f36ef07ad97
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc
@@ -0,0 +1,166 @@
+// Copyright (c) 2017 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/webrtc/webrtc_set_description_observer.h"
+
+#include "base/logging.h"
+
+namespace content {
+
+WebRtcSetDescriptionObserver::States::States()
+ : signaling_state(
+ webrtc::PeerConnectionInterface::SignalingState::kClosed) {}
+
+WebRtcSetDescriptionObserver::States::States(States&& other)
+ : signaling_state(other.signaling_state),
+ transceiver_states(std::move(other.transceiver_states)) {}
+
+WebRtcSetDescriptionObserver::States::~States() = default;
+
+WebRtcSetDescriptionObserver::States& WebRtcSetDescriptionObserver::States::
+operator=(States&& other) {
+ signaling_state = other.signaling_state;
+ transceiver_states = std::move(other.transceiver_states);
+ return *this;
+}
+
+WebRtcSetDescriptionObserver::WebRtcSetDescriptionObserver() = default;
+
+WebRtcSetDescriptionObserver::~WebRtcSetDescriptionObserver() = default;
+
+WebRtcSetDescriptionObserverHandlerImpl::
+ WebRtcSetDescriptionObserverHandlerImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ pc_(std::move(pc)),
+ track_adapter_map_(std::move(track_adapter_map)),
+ observer_(std::move(observer)),
+ surface_receivers_only_(surface_receivers_only) {}
+
+WebRtcSetDescriptionObserverHandlerImpl::
+ ~WebRtcSetDescriptionObserverHandlerImpl() = default;
+
+void WebRtcSetDescriptionObserverHandlerImpl::OnSetDescriptionComplete(
+ webrtc::RTCError error) {
+ CHECK(signaling_task_runner_->BelongsToCurrentThread());
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ receiver_only_transceivers;
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (surface_receivers_only_) {
+ for (const auto& receiver : pc_->GetReceivers()) {
+ transceivers.push_back(new SurfaceReceiverStateOnly(receiver));
+ }
+ } else {
+ transceivers = pc_->GetTransceivers();
+ }
+ TransceiverStateSurfacer transceiver_state_surfacer(main_task_runner_,
+ signaling_task_runner_);
+ transceiver_state_surfacer.Initialize(track_adapter_map_,
+ std::move(transceivers));
+ main_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&WebRtcSetDescriptionObserverHandlerImpl::
+ OnSetDescriptionCompleteOnMainThread,
+ this, std::move(error), pc_->signaling_state(),
+ std::move(transceiver_state_surfacer)));
+}
+
+void WebRtcSetDescriptionObserverHandlerImpl::
+ OnSetDescriptionCompleteOnMainThread(
+ webrtc::RTCError error,
+ webrtc::PeerConnectionInterface::SignalingState signaling_state,
+ TransceiverStateSurfacer transceiver_state_surfacer) {
+ CHECK(main_task_runner_->BelongsToCurrentThread());
+ WebRtcSetDescriptionObserver::States states;
+ states.signaling_state = signaling_state;
+ states.transceiver_states = transceiver_state_surfacer.ObtainStates();
+ observer_->OnSetDescriptionComplete(std::move(error), std::move(states));
+}
+
+scoped_refptr<WebRtcSetLocalDescriptionObserverHandler>
+WebRtcSetLocalDescriptionObserverHandler::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only) {
+ return new rtc::RefCountedObject<WebRtcSetLocalDescriptionObserverHandler>(
+ std::move(main_task_runner), std::move(signaling_task_runner),
+ std::move(pc), std::move(track_adapter_map), std::move(observer),
+ surface_receivers_only);
+}
+
+WebRtcSetLocalDescriptionObserverHandler::
+ WebRtcSetLocalDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only)
+ : handler_impl_(new WebRtcSetDescriptionObserverHandlerImpl(
+ std::move(main_task_runner),
+ std::move(signaling_task_runner),
+ std::move(pc),
+ std::move(track_adapter_map),
+ std::move(observer),
+ surface_receivers_only)) {}
+
+WebRtcSetLocalDescriptionObserverHandler::
+ ~WebRtcSetLocalDescriptionObserverHandler() = default;
+
+void WebRtcSetLocalDescriptionObserverHandler::OnSuccess() {
+ handler_impl_->OnSetDescriptionComplete(webrtc::RTCError::OK());
+}
+
+void WebRtcSetLocalDescriptionObserverHandler::OnFailure(
+ webrtc::RTCError error) {
+ handler_impl_->OnSetDescriptionComplete(std::move(error));
+}
+
+scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler>
+WebRtcSetRemoteDescriptionObserverHandler::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only) {
+ return new rtc::RefCountedObject<WebRtcSetRemoteDescriptionObserverHandler>(
+ std::move(main_task_runner), std::move(signaling_task_runner),
+ std::move(pc), std::move(track_adapter_map), std::move(observer),
+ surface_receivers_only);
+}
+
+WebRtcSetRemoteDescriptionObserverHandler::
+ WebRtcSetRemoteDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only)
+ : handler_impl_(new WebRtcSetDescriptionObserverHandlerImpl(
+ std::move(main_task_runner),
+ std::move(signaling_task_runner),
+ std::move(pc),
+ std::move(track_adapter_map),
+ std::move(observer),
+ surface_receivers_only)) {}
+
+WebRtcSetRemoteDescriptionObserverHandler::
+ ~WebRtcSetRemoteDescriptionObserverHandler() = default;
+
+void WebRtcSetRemoteDescriptionObserverHandler::OnSetRemoteDescriptionComplete(
+ webrtc::RTCError error) {
+ handler_impl_->OnSetDescriptionComplete(std::move(error));
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h
new file mode 100644
index 00000000000..41e84950259
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h
@@ -0,0 +1,186 @@
+// Copyright (c) 2017 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.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_DESCRIPTION_OBSERVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_DESCRIPTION_OBSERVER_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/common/content_export.h"
+#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
+#include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
+#include "content/renderer/media/webrtc/rtc_rtp_sender.h"
+#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
+#include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/webrtc/api/jsep.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
+#include "third_party/webrtc/api/rtcerror.h"
+#include "third_party/webrtc/api/rtpreceiverinterface.h"
+#include "third_party/webrtc/api/setremotedescriptionobserverinterface.h"
+#include "third_party/webrtc/rtc_base/refcount.h"
+#include "third_party/webrtc/rtc_base/refcountedobject.h"
+#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace content {
+
+// The content layer correspondent of the setLocalDescription() observer
+// (webrtc::SetSessionDescriptionObserver) and setRemoteDescription() observer
+// (webrtc::SetRemoteDescriptionObserverInterface). The implementation should
+// process the state changes of the Set[Local/Remote]Description() by inspecting
+// the updated States.
+class CONTENT_EXPORT WebRtcSetDescriptionObserver
+ : public base::RefCountedThreadSafe<WebRtcSetDescriptionObserver> {
+ public:
+ // The states as they were when the operation finished on the webrtc signaling
+ // thread. Note that other operations may have occurred while jumping back to
+ // the main thread, but these must be handled separately.
+ struct CONTENT_EXPORT States {
+ States();
+ States(States&& other);
+ ~States();
+
+ States& operator=(States&& other);
+
+ webrtc::PeerConnectionInterface::SignalingState signaling_state;
+ std::vector<RtpTransceiverState> transceiver_states;
+
+ DISALLOW_COPY_AND_ASSIGN(States);
+ };
+
+ WebRtcSetDescriptionObserver();
+
+ // Invoked in a PostTask() on the main thread after the SetLocalDescription()
+ // or SetRemoteDescription() operation completed on the webrtc signaling
+ // thread.
+ virtual void OnSetDescriptionComplete(webrtc::RTCError error,
+ States states) = 0;
+
+ protected:
+ friend class base::RefCountedThreadSafe<WebRtcSetDescriptionObserver>;
+ virtual ~WebRtcSetDescriptionObserver();
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetDescriptionObserver);
+};
+
+// Takes care of surfacing WebRtcSetDescriptionObserver::State information from
+// the webrtc signaling thread to the main thread. With the state information
+// obtained, invokes |observer_|'s
+// WebRtcSetDescriptionObserver::OnSetDescriptionComplete() on the main thread.
+//
+// This implements the behavior
+// of both WebRtcSetLocalDescriptionObserverHandler and
+// WebRtcSetRemoteDescriptionObserverHandler, but these are put in different
+// classes because local and remote description observers have different
+// interfaces in webrtc.
+class CONTENT_EXPORT WebRtcSetDescriptionObserverHandlerImpl
+ : public base::RefCountedThreadSafe<
+ WebRtcSetDescriptionObserverHandlerImpl> {
+ public:
+ WebRtcSetDescriptionObserverHandlerImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+
+ // Must be called on the webrtc signaling thread internally by the handler
+ // when the Set[Local/Remote]Description() operation finishes.
+ void OnSetDescriptionComplete(webrtc::RTCError error);
+
+ private:
+ friend class base::RefCountedThreadSafe<
+ WebRtcSetDescriptionObserverHandlerImpl>;
+ virtual ~WebRtcSetDescriptionObserverHandlerImpl();
+
+ void OnSetDescriptionCompleteOnMainThread(
+ webrtc::RTCError error,
+ webrtc::PeerConnectionInterface::SignalingState signaling_state,
+ TransceiverStateSurfacer transceiver_state_surfacer);
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::PeerConnectionInterface> pc_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+ scoped_refptr<WebRtcSetDescriptionObserver> observer_;
+ bool surface_receivers_only_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetDescriptionObserverHandlerImpl);
+};
+
+// An implementation of webrtc::SetSessionDescriptionObserver for performing the
+// operations of WebRtcSetDescriptionObserverHandlerImpl.
+class CONTENT_EXPORT WebRtcSetLocalDescriptionObserverHandler
+ : public webrtc::SetSessionDescriptionObserver {
+ public:
+ static scoped_refptr<WebRtcSetLocalDescriptionObserverHandler> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+
+ // webrtc::SetSessionDescriptionObserver implementation. Implementation calls
+ // WebRtcSetDescriptionObserverHandlerImpl::OnSetDescriptionComplete().
+ void OnSuccess() override;
+ void OnFailure(webrtc::RTCError error) override;
+
+ protected:
+ WebRtcSetLocalDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+ ~WebRtcSetLocalDescriptionObserverHandler() override;
+
+ scoped_refptr<WebRtcSetDescriptionObserverHandlerImpl> handler_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetLocalDescriptionObserverHandler);
+};
+
+// An implementation of webrtc::SetRemoteDescriptionObserverInterface for
+// performing the operations of WebRtcSetDescriptionObserverHandlerImpl.
+class CONTENT_EXPORT WebRtcSetRemoteDescriptionObserverHandler
+ : public webrtc::SetRemoteDescriptionObserverInterface {
+ public:
+ static scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+
+ // webrtc::SetRemoteDescriptionObserverInterface implementation.
+ // Implementation calls
+ // WebRtcSetDescriptionObserverHandlerImpl::OnSetDescriptionComplete().
+ void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override;
+
+ protected:
+ WebRtcSetRemoteDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+ ~WebRtcSetRemoteDescriptionObserverHandler() override;
+
+ scoped_refptr<WebRtcSetDescriptionObserverHandlerImpl> handler_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserverHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_DESCRIPTION_OBSERVER_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc
index 5b861458a11..c2f7dc786b0 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/webrtc/webrtc_set_remote_description_observer.h"
+#include "content/renderer/media/webrtc/webrtc_set_description_observer.h"
#include <memory>
#include <utility>
@@ -16,7 +16,6 @@
#include "content/child/child_process.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -29,35 +28,41 @@ using ::testing::Return;
namespace content {
-class WebRtcSetRemoteDescriptionObserverForTest
- : public WebRtcSetRemoteDescriptionObserver {
+class WebRtcSetDescriptionObserverForTest
+ : public WebRtcSetDescriptionObserver {
public:
- bool called() const { return states_or_error_.has_value(); }
- bool result() const { return states_or_error_->ok(); }
+ bool called() const { return called_; }
- const WebRtcSetRemoteDescriptionObserver::States& states() const {
- DCHECK(called() && result());
- return states_or_error_->value();
+ const WebRtcSetDescriptionObserver::States& states() const {
+ DCHECK(called_);
+ return states_;
}
const webrtc::RTCError& error() const {
- DCHECK(called() && !result());
- return states_or_error_->error();
+ DCHECK(called_);
+ return error_;
}
- // WebRtcSetRemoteDescriptionObserver implementation.
- void OnSetRemoteDescriptionComplete(
- webrtc::RTCErrorOr<States> states_or_error) override {
- states_or_error_ = std::move(states_or_error);
+ // WebRtcSetDescriptionObserver implementation.
+ void OnSetDescriptionComplete(
+ webrtc::RTCError error,
+ WebRtcSetDescriptionObserver::States states) override {
+ called_ = true;
+ error_ = std::move(error);
+ states_ = std::move(states);
}
private:
- ~WebRtcSetRemoteDescriptionObserverForTest() override {}
+ ~WebRtcSetDescriptionObserverForTest() override {}
- base::Optional<webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>>
- states_or_error_;
- WebRtcSetRemoteDescriptionObserver::States states_;
+ bool called_ = false;
+ webrtc::RTCError error_;
+ WebRtcSetDescriptionObserver::States states_;
};
+// TODO(hbos): This only tests WebRtcSetRemoteDescriptionObserverHandler,
+// parameterize the test to make it also test
+// WebRtcSetLocalDescriptionObserverHandler and with "surface_receivers_only" as
+// both true and false. https://crbug.com/865006
class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
public:
void SetUp() override {
@@ -66,14 +71,13 @@ class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
new cricket::FakeMediaEngine())));
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- scoped_refptr<WebRtcMediaStreamAdapterMap> map =
- new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
- observer_ = new WebRtcSetRemoteDescriptionObserverForTest();
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map =
+ new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_thread_);
+ observer_ = new WebRtcSetDescriptionObserverForTest();
observer_handler_ = WebRtcSetRemoteDescriptionObserverHandler::Create(
- main_thread_, pc_, map, observer_);
+ main_thread_, dependency_factory_->GetWebRtcSignalingThread(), pc_, map,
+ observer_, true /* surface_receivers_only*/);
}
void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); }
@@ -106,7 +110,7 @@ class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
scoped_refptr<webrtc::MockPeerConnection> pc_;
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcSetRemoteDescriptionObserverForTest> observer_;
+ scoped_refptr<WebRtcSetDescriptionObserverForTest> observer_;
scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> observer_handler_;
std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> receivers_;
@@ -124,28 +128,65 @@ TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnSuccess) {
{added_stream.get()})));
receivers_.push_back(added_receiver.get());
+ EXPECT_CALL(*pc_, signaling_state())
+ .WillRepeatedly(Return(webrtc::PeerConnectionInterface::kStable));
EXPECT_CALL(*pc_, GetReceivers()).WillRepeatedly(Return(receivers_));
InvokeOnSetRemoteDescriptionComplete(webrtc::RTCError::OK());
EXPECT_TRUE(observer_->called());
- EXPECT_TRUE(observer_->result());
-
- EXPECT_EQ(1u, observer_->states().receiver_states.size());
- const WebRtcReceiverState& receiver_state =
- observer_->states().receiver_states[0];
- EXPECT_EQ(added_receiver, receiver_state.receiver);
- EXPECT_EQ(added_track, receiver_state.track_ref->webrtc_track());
- EXPECT_EQ(1u, receiver_state.stream_refs.size());
- EXPECT_EQ(added_stream,
- receiver_state.stream_refs[0]->adapter().webrtc_stream());
+ EXPECT_TRUE(observer_->error().ok());
+
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kStable,
+ observer_->states().signaling_state);
+
+ EXPECT_EQ(1u, observer_->states().transceiver_states.size());
+ const RtpTransceiverState& transceiver_state =
+ observer_->states().transceiver_states[0];
+ EXPECT_FALSE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.receiver_state());
+ const RtpReceiverState& receiver_state = *transceiver_state.receiver_state();
+ EXPECT_EQ(added_receiver, receiver_state.webrtc_receiver());
+ EXPECT_EQ(added_track, receiver_state.track_ref()->webrtc_track());
+ EXPECT_EQ(1u, receiver_state.stream_ids().size());
+ EXPECT_EQ(added_stream->id(), receiver_state.stream_ids()[0]);
}
TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnFailure) {
- webrtc::RTCError error(webrtc::RTCErrorType::INVALID_PARAMETER, "Oh noes!");
- InvokeOnSetRemoteDescriptionComplete(std::move(error));
+ scoped_refptr<MockWebRtcAudioTrack> added_track =
+ MockWebRtcAudioTrack::Create("added_track");
+ scoped_refptr<webrtc::MediaStreamInterface> added_stream(
+ new rtc::RefCountedObject<MockMediaStream>("added_stream"));
+ scoped_refptr<webrtc::RtpReceiverInterface> added_receiver(
+ new rtc::RefCountedObject<FakeRtpReceiver>(
+ added_track.get(),
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>(
+ {added_stream.get()})));
+
+ receivers_.push_back(added_receiver.get());
+ EXPECT_CALL(*pc_, signaling_state())
+ .WillRepeatedly(Return(webrtc::PeerConnectionInterface::kStable));
+ EXPECT_CALL(*pc_, GetReceivers()).WillRepeatedly(Return(receivers_));
+
+ InvokeOnSetRemoteDescriptionComplete(
+ webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Oh noes!"));
EXPECT_TRUE(observer_->called());
- EXPECT_FALSE(observer_->result());
+ EXPECT_FALSE(observer_->error().ok());
EXPECT_EQ(std::string("Oh noes!"), observer_->error().message());
+
+ // Verify states were surfaced even though we got an error.
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kStable,
+ observer_->states().signaling_state);
+
+ EXPECT_EQ(1u, observer_->states().transceiver_states.size());
+ const RtpTransceiverState& transceiver_state =
+ observer_->states().transceiver_states[0];
+ EXPECT_FALSE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.receiver_state());
+ const RtpReceiverState& receiver_state = *transceiver_state.receiver_state();
+ EXPECT_EQ(added_receiver, receiver_state.webrtc_receiver());
+ EXPECT_EQ(added_track, receiver_state.track_ref()->webrtc_track());
+ EXPECT_EQ(1u, receiver_state.stream_ids().size());
+ EXPECT_EQ(added_stream->id(), receiver_state.stream_ids()[0]);
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc
deleted file mode 100644
index 0ebb644548b..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2017 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/webrtc/webrtc_set_remote_description_observer.h"
-
-#include "base/logging.h"
-
-namespace content {
-
-WebRtcReceiverState::WebRtcReceiverState(
- scoped_refptr<webrtc::RtpReceiverInterface> receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs)
- : receiver(std::move(receiver)),
- track_ref(std::move(track_ref)),
- stream_refs(std::move(stream_refs)) {}
-
-WebRtcReceiverState::WebRtcReceiverState(WebRtcReceiverState&& other) = default;
-
-WebRtcReceiverState& WebRtcReceiverState::operator=(
- WebRtcReceiverState&& other) = default;
-
-WebRtcReceiverState::~WebRtcReceiverState() {}
-
-WebRtcSetRemoteDescriptionObserver::States::States() {}
-
-WebRtcSetRemoteDescriptionObserver::States::States(States&& other)
- : receiver_states(std::move(other.receiver_states)) {}
-
-WebRtcSetRemoteDescriptionObserver::States::~States() {}
-
-WebRtcSetRemoteDescriptionObserver::States&
-WebRtcSetRemoteDescriptionObserver::States::operator=(States&& other) {
- receiver_states = std::move(other.receiver_states);
- return *this;
-}
-
-void WebRtcSetRemoteDescriptionObserver::States::CheckInvariants() const {
- // Invariants:
- // - All receiver states have a stream ref
- // - All receiver states refer to streams that are non-null.
- for (auto& receiver_state : receiver_states) {
- for (auto& stream_ref : receiver_state.stream_refs) {
- CHECK(stream_ref);
- CHECK(!stream_ref->adapter().web_stream().IsNull());
- }
- }
-}
-
-WebRtcSetRemoteDescriptionObserver::WebRtcSetRemoteDescriptionObserver() {}
-
-WebRtcSetRemoteDescriptionObserver::~WebRtcSetRemoteDescriptionObserver() {}
-
-scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler>
-WebRtcSetRemoteDescriptionObserverHandler::Create(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<webrtc::PeerConnectionInterface> pc,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
- scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer) {
- return new rtc::RefCountedObject<WebRtcSetRemoteDescriptionObserverHandler>(
- std::move(main_thread), std::move(pc), std::move(stream_adapter_map),
- std::move(observer));
-}
-
-WebRtcSetRemoteDescriptionObserverHandler::
- WebRtcSetRemoteDescriptionObserverHandler(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<webrtc::PeerConnectionInterface> pc,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
- scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer)
- : main_thread_(std::move(main_thread)),
- pc_(std::move(pc)),
- stream_adapter_map_(std::move(stream_adapter_map)),
- observer_(std::move(observer)) {}
-
-WebRtcSetRemoteDescriptionObserverHandler::
- ~WebRtcSetRemoteDescriptionObserverHandler() {}
-
-void WebRtcSetRemoteDescriptionObserverHandler::OnSetRemoteDescriptionComplete(
- webrtc::RTCError error) {
- CHECK(!main_thread_->BelongsToCurrentThread());
-
- webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
- states_or_error;
- if (error.ok()) {
- WebRtcSetRemoteDescriptionObserver::States states;
- for (const auto& webrtc_receiver : pc_->GetReceivers()) {
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
- track_adapter_map()->GetOrCreateRemoteTrackAdapter(
- webrtc_receiver->track().get());
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs;
- for (const auto& stream : webrtc_receiver->streams()) {
- stream_refs.push_back(
- stream_adapter_map_->GetOrCreateRemoteStreamAdapter(stream.get()));
- }
- states.receiver_states.push_back(WebRtcReceiverState(
- webrtc_receiver.get(), std::move(track_ref), std::move(stream_refs)));
- }
- states_or_error = std::move(states);
- } else {
- states_or_error = std::move(error);
- }
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&WebRtcSetRemoteDescriptionObserverHandler::
- OnSetRemoteDescriptionCompleteOnMainThread,
- this, std::move(states_or_error)));
-}
-
-void WebRtcSetRemoteDescriptionObserverHandler::
- OnSetRemoteDescriptionCompleteOnMainThread(
- webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
- states_or_error) {
- CHECK(main_thread_->BelongsToCurrentThread());
- observer_->OnSetRemoteDescriptionComplete(std::move(states_or_error));
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h
deleted file mode 100644
index 1102c415990..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2017 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.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_REMOTE_DESCRIPTION_OBSERVER_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_REMOTE_DESCRIPTION_OBSERVER_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
-#include "third_party/webrtc/api/rtcerror.h"
-#include "third_party/webrtc/api/rtpreceiverinterface.h"
-#include "third_party/webrtc/api/setremotedescriptionobserverinterface.h"
-#include "third_party/webrtc/rtc_base/refcount.h"
-#include "third_party/webrtc/rtc_base/refcountedobject.h"
-#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
-
-namespace content {
-
-// Describes an instance of a receiver at the time the SRD call was completed.
-// Because webrtc and content operate on different threads, webrtc objects may
-// have been modified by the time we synchronize the receivers on the main
-// thread, and members of this class should be inspected rather than members of
-// |receiver|.
-struct CONTENT_EXPORT WebRtcReceiverState {
- WebRtcReceiverState(
- scoped_refptr<webrtc::RtpReceiverInterface> receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs);
- WebRtcReceiverState(WebRtcReceiverState&& other);
- ~WebRtcReceiverState();
-
- WebRtcReceiverState& operator=(WebRtcReceiverState&& other);
-
- scoped_refptr<webrtc::RtpReceiverInterface> receiver;
- // The receiver's track when the SRD occurred.
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
- // The receiver's associated set of streams when the SRD occurred.
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs;
-
- DISALLOW_COPY_AND_ASSIGN(WebRtcReceiverState);
-};
-
-// The content layer correspondent of
-// webrtc::SetRemoteDescriptionObserverInterface. It's an interface with
-// callbacks for handling the result of SetRemoteDescription on the main thread.
-// The implementation should process the state changes of the
-// SetRemoteDescription by inspecting the updated States.
-class CONTENT_EXPORT WebRtcSetRemoteDescriptionObserver
- : public base::RefCountedThreadSafe<WebRtcSetRemoteDescriptionObserver> {
- public:
- // The relevant peer connection states as they were when the
- // SetRemoteDescription call completed. This is used instead of inspecting the
- // PeerConnection and other webrtc objects directly because they may have been
- // modified before we reach the main thread.
- struct CONTENT_EXPORT States {
- States();
- States(States&& other);
- ~States();
-
- States& operator=(States&& other);
-
- // The receivers at the time of the event.
- std::vector<WebRtcReceiverState> receiver_states;
- // Check that the invariants for this structure hold.
- void CheckInvariants() const;
-
- DISALLOW_COPY_AND_ASSIGN(States);
- };
-
- WebRtcSetRemoteDescriptionObserver();
-
- // Invoked asynchronously on the main thread after the SetRemoteDescription
- // completed on the webrtc signaling thread.
- virtual void OnSetRemoteDescriptionComplete(
- webrtc::RTCErrorOr<States> states_or_error) = 0;
-
- protected:
- friend class base::RefCountedThreadSafe<WebRtcSetRemoteDescriptionObserver>;
- virtual ~WebRtcSetRemoteDescriptionObserver();
-
- DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserver);
-};
-
-// The glue between webrtc and content layer observers listening to
-// SetRemoteDescription. This observer listens on the webrtc signaling thread
-// for the result of SetRemoteDescription, copies any relevant webrtc peer
-// connection states such that they can be processed on the main thread, and
-// invokes the WebRtcSetRemoteDescriptionObserver on the main thread with the
-// state changes.
-class CONTENT_EXPORT WebRtcSetRemoteDescriptionObserverHandler
- : public webrtc::SetRemoteDescriptionObserverInterface {
- public:
- static scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> Create(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<webrtc::PeerConnectionInterface> pc,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
- scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer);
-
- // webrtc::SetRemoteDescriptionObserverInterface implementation.
- void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override;
-
- protected:
- WebRtcSetRemoteDescriptionObserverHandler(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<webrtc::PeerConnectionInterface> pc,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
- scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer);
- ~WebRtcSetRemoteDescriptionObserverHandler() override;
-
- private:
- void OnSetRemoteDescriptionCompleteOnMainThread(
- webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
- states_or_error);
-
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map() const {
- return stream_adapter_map_->track_adapter_map();
- }
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<webrtc::PeerConnectionInterface> pc_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map_;
- scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserverHandler);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_REMOTE_DESCRIPTION_OBSERVER_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_util.h b/chromium/content/renderer/media/webrtc/webrtc_util.h
new file mode 100644
index 00000000000..425c0ec9373
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_util.h
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
+
+#include "base/optional.h"
+
+namespace content {
+
+template <typename OptionalT>
+base::Optional<typename OptionalT::value_type> ToBaseOptional(
+ const OptionalT& optional) {
+ return optional ? base::make_optional(*optional) : base::nullopt;
+}
+
+template <typename OptionalT>
+absl::optional<typename OptionalT::value_type> ToAbslOptional(
+ const OptionalT& optional) {
+ return optional ? absl::make_optional(*optional) : absl::nullopt;
+}
+
+template <typename OptionalT1, typename OptionalT2>
+bool OptionalEquals(const OptionalT1& lhs, const OptionalT2& rhs) {
+ if (!lhs)
+ return !rhs;
+ if (!rhs)
+ return false;
+ return *lhs == *rhs;
+}
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
index 95357d45e98..57ae21ee241 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -209,7 +209,9 @@ bool WebRtcVideoCapturerAdapter::ShouldAdaptResolution() const {
return true;
}
if (content_hint_ ==
- blink::WebMediaStreamTrack::ContentHintType::kVideoDetail) {
+ blink::WebMediaStreamTrack::ContentHintType::kVideoDetail ||
+ content_hint_ ==
+ blink::WebMediaStreamTrack::ContentHintType::kVideoText) {
return false;
}
// Screencast does not adapt by default.
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
index e076b3de238..ce1208152d4 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
@@ -117,44 +117,4 @@ TEST_F(WebRtcVideoCapturerAdapterTest, Scale720To640360) {
TestSourceCropFrame(1280, 720, 1280, 720, 640, 360);
}
-TEST_F(WebRtcVideoCapturerAdapterTest,
- NonScreencastAdapterDoesNotAdaptContentHintDetail) {
- // Non-screenshare adapter should not adapt frames when detail is set.
- TestContentHintResolutionAdaptation(
- false, blink::WebMediaStreamTrack::ContentHintType::kNone, true,
- blink::WebMediaStreamTrack::ContentHintType::kVideoDetail, false);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest,
- NonScreencastAdapterAdaptsContentHintFluid) {
- // Non-screenshare adapter should still adapt frames when motion is set.
- TestContentHintResolutionAdaptation(
- false, blink::WebMediaStreamTrack::ContentHintType::kNone, true,
- blink::WebMediaStreamTrack::ContentHintType::kVideoMotion, true);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest,
- ScreencastAdapterAdaptsContentHintFluid) {
- // Screenshare adapter should adapt frames when motion is set.
- TestContentHintResolutionAdaptation(
- true, blink::WebMediaStreamTrack::ContentHintType::kNone, false,
- blink::WebMediaStreamTrack::ContentHintType::kVideoMotion, true);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest,
- ScreencastAdapterDoesNotAdaptContentHintDetailed) {
- // Screenshare adapter should still not adapt frames when detail is set.
- TestContentHintResolutionAdaptation(
- true, blink::WebMediaStreamTrack::ContentHintType::kNone, false,
- blink::WebMediaStreamTrack::ContentHintType::kVideoDetail, false);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest, RespectsConstructionTimeContentHint) {
- // Non-screenshare adapter constructed with detail content hint should not
- // adapt before SetContentHint is run.
- TestContentHintResolutionAdaptation(
- false, blink::WebMediaStreamTrack::ContentHintType::kVideoDetail, false,
- blink::WebMediaStreamTrack::ContentHintType::kVideoMotion, true);
-}
-
} // namespace content