summaryrefslogtreecommitdiffstats
path: root/remoting/protocol
diff options
context:
space:
mode:
authorsergeyu <sergeyu@chromium.org>2015-12-10 10:42:43 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-10 18:43:39 +0000
commit0fc40f9403a782b6fb01237fd1fe9d730e1206b2 (patch)
tree3374d992267a66a2e53a790420fa397e1eda12fb /remoting/protocol
parentb036e43221eac3ca8a22d7e96258ca056444cedd (diff)
downloadchromium_src-0fc40f9403a782b6fb01237fd1fe9d730e1206b2.zip
chromium_src-0fc40f9403a782b6fb01237fd1fe9d730e1206b2.tar.gz
chromium_src-0fc40f9403a782b6fb01237fd1fe9d730e1206b2.tar.bz2
Add WebrtcConnectionToClient.
The new WebrtcConnectionToClient implements ConnectionToClient for WebRTC-based protocol. BUG=547158 Review URL: https://codereview.chromium.org/1510343002 Cr-Commit-Position: refs/heads/master@{#364409}
Diffstat (limited to 'remoting/protocol')
-rw-r--r--remoting/protocol/BUILD.gn3
-rw-r--r--remoting/protocol/ice_connection_to_client.h1
-rw-r--r--remoting/protocol/jingle_session.cc3
-rw-r--r--remoting/protocol/transport.cc7
-rw-r--r--remoting/protocol/transport.h14
-rw-r--r--remoting/protocol/video_stream.h2
-rw-r--r--remoting/protocol/webrtc_connection_to_client.cc203
-rw-r--r--remoting/protocol/webrtc_connection_to_client.h71
-rw-r--r--remoting/protocol/webrtc_connection_to_client_unittest.cc95
-rw-r--r--remoting/protocol/webrtc_transport.cc4
-rw-r--r--remoting/protocol/webrtc_transport.h1
-rw-r--r--remoting/protocol/webrtc_video_capturer_adapter.cc4
-rw-r--r--remoting/protocol/webrtc_video_stream.cc49
-rw-r--r--remoting/protocol/webrtc_video_stream.h44
14 files changed, 494 insertions, 7 deletions
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn
index bb083d7..54224e8 100644
--- a/remoting/protocol/BUILD.gn
+++ b/remoting/protocol/BUILD.gn
@@ -46,8 +46,10 @@ source_set("protocol") {
]
} else {
sources -= [
+ "webrtc_connection_to_client.cc",
"webrtc_transport.cc",
"webrtc_video_capturer_adapter.cc",
+ "webrtc_video_stream.cc",
]
}
}
@@ -116,6 +118,7 @@ source_set("unit_tests") {
"third_party_authenticator_unittest.cc",
"v2_authenticator_unittest.cc",
"video_frame_pump_unittest.cc",
+ "webrtc_connection_to_client_unittest.cc",
"webrtc_transport_unittest.cc",
]
diff --git a/remoting/protocol/ice_connection_to_client.h b/remoting/protocol/ice_connection_to_client.h
index 8387b94..72d7691 100644
--- a/remoting/protocol/ice_connection_to_client.h
+++ b/remoting/protocol/ice_connection_to_client.h
@@ -73,7 +73,6 @@ class IceConnectionToClient : public ConnectionToClient,
// Event handler for handling events sent from this object.
ConnectionToClient::EventHandler* event_handler_;
- // The libjingle channel used to send and receive data from the remote client.
scoped_ptr<Session> session_;
scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_;
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index 92b56c8..47eab67 100644
--- a/remoting/protocol/jingle_session.cc
+++ b/remoting/protocol/jingle_session.cc
@@ -409,7 +409,8 @@ void JingleSession::OnIncomingMessage(const JingleMessage& message,
break;
case JingleMessage::TRANSPORT_INFO:
- if (transport_->ProcessTransportInfo(message.transport_info.get())) {
+ if (message.transport_info &&
+ transport_->ProcessTransportInfo(message.transport_info.get())) {
reply_callback.Run(JingleMessageReply::NONE);
} else {
reply_callback.Run(JingleMessageReply::BAD_REQUEST);
diff --git a/remoting/protocol/transport.cc b/remoting/protocol/transport.cc
index 13ed29f..41eef83 100644
--- a/remoting/protocol/transport.cc
+++ b/remoting/protocol/transport.cc
@@ -23,10 +23,11 @@ std::string TransportRoute::GetTypeString(RouteType type) {
return std::string();
}
-TransportRoute::TransportRoute() : type(DIRECT) {
-}
+TransportRoute::TransportRoute() : type(DIRECT) {}
+TransportRoute::~TransportRoute() {}
-TransportRoute::~TransportRoute() {
+WebrtcTransport* Transport::AsWebrtcTransport() {
+ return nullptr;
}
} // namespace protocol
diff --git a/remoting/protocol/transport.h b/remoting/protocol/transport.h
index b037c50..055381a 100644
--- a/remoting/protocol/transport.h
+++ b/remoting/protocol/transport.h
@@ -22,6 +22,10 @@ namespace buzz {
class XmlElement;
} // namespace buzz
+namespace webrtc {
+class PeerConnectionInterface;
+} // namespace webrtc
+
namespace remoting {
namespace protocol {
@@ -29,6 +33,7 @@ class Authenticator;
class DatagramChannelFactory;
class P2PDatagramSocket;
class StreamChannelFactory;
+class WebrtcTransport;
enum class TransportRole {
SERVER,
@@ -92,6 +97,15 @@ class Transport {
// channel.
virtual StreamChannelFactory* GetMultiplexedChannelFactory() = 0;
+ // Returns the transport as WebrtcTransport or nullptr if this is not a
+ // WebrtcTransport.
+ //
+ // TODO(sergeyu): Move creation and ownership of Transport objects to the
+ // Connection classes. That way the Connection classes will be able to ensure
+ // that correct transport implementation is used for the connection and this
+ // method will not be necessary.
+ virtual WebrtcTransport* AsWebrtcTransport();
+
private:
DISALLOW_COPY_AND_ASSIGN(Transport);
};
diff --git a/remoting/protocol/video_stream.h b/remoting/protocol/video_stream.h
index 000a1f2..31da0f7 100644
--- a/remoting/protocol/video_stream.h
+++ b/remoting/protocol/video_stream.h
@@ -5,6 +5,8 @@
#ifndef REMOTING_PROTOCOL_VIDEO_STREAM_H_
#define REMOTING_PROTOCOL_VIDEO_STREAM_H_
+#include <cstdint>
+
#include "base/callback_forward.h"
namespace webrtc {
diff --git a/remoting/protocol/webrtc_connection_to_client.cc b/remoting/protocol/webrtc_connection_to_client.cc
new file mode 100644
index 0000000..d36ac24
--- /dev/null
+++ b/remoting/protocol/webrtc_connection_to_client.cc
@@ -0,0 +1,203 @@
+// Copyright 2015 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 "remoting/protocol/webrtc_connection_to_client.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "net/base/io_buffer.h"
+#include "remoting/codec/video_encoder.h"
+#include "remoting/codec/video_encoder_verbatim.h"
+#include "remoting/codec/video_encoder_vpx.h"
+#include "remoting/protocol/audio_writer.h"
+#include "remoting/protocol/clipboard_stub.h"
+#include "remoting/protocol/host_control_dispatcher.h"
+#include "remoting/protocol/host_event_dispatcher.h"
+#include "remoting/protocol/host_stub.h"
+#include "remoting/protocol/input_stub.h"
+#include "remoting/protocol/webrtc_transport.h"
+#include "remoting/protocol/webrtc_video_capturer_adapter.h"
+#include "remoting/protocol/webrtc_video_stream.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
+#include "third_party/libjingle/source/talk/app/webrtc/test/fakeconstraints.h"
+#include "third_party/libjingle/source/talk/app/webrtc/videosourceinterface.h"
+
+namespace remoting {
+namespace protocol {
+
+const char kStreamLabel[] = "screen_stream";
+const char kVideoLabel[] = "screen_video";
+
+WebrtcConnectionToClient::WebrtcConnectionToClient(
+ scoped_ptr<protocol::Session> session)
+ : session_(session.Pass()) {
+ session_->SetEventHandler(this);
+}
+
+WebrtcConnectionToClient::~WebrtcConnectionToClient() {}
+
+void WebrtcConnectionToClient::SetEventHandler(
+ ConnectionToClient::EventHandler* event_handler) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ event_handler_ = event_handler;
+}
+
+protocol::Session* WebrtcConnectionToClient::session() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return session_.get();
+}
+
+void WebrtcConnectionToClient::Disconnect(ErrorCode error) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ control_dispatcher_.reset();
+ event_dispatcher_.reset();
+
+ // This should trigger OnConnectionClosed() event and this object
+ // may be destroyed as the result.
+ session_->Close(error);
+}
+
+void WebrtcConnectionToClient::OnInputEventReceived(int64_t timestamp) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ event_handler_->OnInputEventReceived(this, timestamp);
+}
+
+scoped_ptr<VideoStream> WebrtcConnectionToClient::StartVideoStream(
+ scoped_ptr<webrtc::DesktopCapturer> desktop_capturer) {
+ // TODO(sergeyu): Reconsider Transport interface and how it's used here.
+ WebrtcTransport* transport = session_->GetTransport()->AsWebrtcTransport();
+ CHECK(transport);
+
+ scoped_ptr<WebrtcVideoCapturerAdapter> video_capturer_adapter(
+ new WebrtcVideoCapturerAdapter(desktop_capturer.Pass()));
+
+ // Set video stream constraints.
+ webrtc::FakeConstraints video_constraints;
+ video_constraints.AddMandatory(
+ webrtc::MediaConstraintsInterface::kMinFrameRate, 5);
+
+ rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track =
+ transport->peer_connection_factory()->CreateVideoTrack(
+ kVideoLabel,
+ transport->peer_connection_factory()->CreateVideoSource(
+ video_capturer_adapter.release(), &video_constraints));
+
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> video_stream =
+ transport->peer_connection_factory()->CreateLocalMediaStream(
+ kStreamLabel);
+
+ if (!video_stream->AddTrack(video_track) ||
+ !transport->peer_connection()->AddStream(video_stream)) {
+ return nullptr;
+ }
+
+ scoped_ptr<VideoStream> result(
+ new WebrtcVideoStream(transport->peer_connection(), video_stream));
+ return result.Pass();
+}
+
+AudioStub* WebrtcConnectionToClient::audio_stub() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return nullptr;
+}
+
+// Return pointer to ClientStub.
+ClientStub* WebrtcConnectionToClient::client_stub() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return control_dispatcher_.get();
+}
+
+void WebrtcConnectionToClient::set_clipboard_stub(
+ protocol::ClipboardStub* clipboard_stub) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ control_dispatcher_->set_clipboard_stub(clipboard_stub);
+}
+
+void WebrtcConnectionToClient::set_host_stub(protocol::HostStub* host_stub) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ control_dispatcher_->set_host_stub(host_stub);
+}
+
+void WebrtcConnectionToClient::set_input_stub(protocol::InputStub* input_stub) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ event_dispatcher_->set_input_stub(input_stub);
+}
+
+void WebrtcConnectionToClient::OnSessionStateChange(Session::State state) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ DCHECK(event_handler_);
+ switch(state) {
+ case Session::INITIALIZING:
+ case Session::CONNECTING:
+ case Session::ACCEPTING:
+ case Session::ACCEPTED:
+ // Don't care about these events.
+ break;
+ case Session::AUTHENTICATING:
+ event_handler_->OnConnectionAuthenticating(this);
+ break;
+ case Session::AUTHENTICATED: {
+ // Initialize channels.
+ control_dispatcher_.reset(new HostControlDispatcher());
+ control_dispatcher_->Init(
+ session_.get(),
+ ChannelConfig(ChannelConfig::TRANSPORT_STREAM, kDefaultStreamVersion,
+ ChannelConfig::CODEC_UNDEFINED),
+ this);
+
+ event_dispatcher_.reset(new HostEventDispatcher());
+ event_dispatcher_->Init(
+ session_.get(),
+ ChannelConfig(ChannelConfig::TRANSPORT_STREAM, kDefaultStreamVersion,
+ ChannelConfig::CODEC_UNDEFINED),
+ this);
+ event_dispatcher_->set_on_input_event_callback(base::Bind(
+ &ConnectionToClient::OnInputEventReceived, base::Unretained(this)));
+
+ // Notify the handler after initializing the channels, so that
+ // ClientSession can get a client clipboard stub.
+ event_handler_->OnConnectionAuthenticated(this);
+ break;
+ }
+
+ case Session::CONNECTED:
+ event_handler_->OnConnectionChannelsConnected(this);
+ break;
+
+ case Session::CLOSED:
+ case Session::FAILED:
+ control_dispatcher_.reset();
+ event_dispatcher_.reset();
+ event_handler_->OnConnectionClosed(
+ this, state == Session::CLOSED ? OK : session_->error());
+ break;
+ }
+}
+
+void WebrtcConnectionToClient::OnSessionRouteChange(
+ const std::string& channel_name,
+ const TransportRoute& route) {
+ event_handler_->OnRouteChange(this, channel_name, route);
+}
+
+void WebrtcConnectionToClient::OnChannelInitialized(
+ ChannelDispatcherBase* channel_dispatcher) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void WebrtcConnectionToClient::OnChannelError(
+ ChannelDispatcherBase* channel_dispatcher,
+ ErrorCode error) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ LOG(ERROR) << "Failed to connect channel "
+ << channel_dispatcher->channel_name();
+ session_->Close(CHANNEL_CONNECTION_ERROR);
+}
+
+} // namespace protocol
+} // namespace remoting
diff --git a/remoting/protocol/webrtc_connection_to_client.h b/remoting/protocol/webrtc_connection_to_client.h
new file mode 100644
index 0000000..02919db
--- /dev/null
+++ b/remoting/protocol/webrtc_connection_to_client.h
@@ -0,0 +1,71 @@
+// Copyright 2015 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 REMOTING_PROTOCOL_WEBRTC_CONNECTION_TO_CLIENT_H_
+#define REMOTING_PROTOCOL_WEBRTC_CONNECTION_TO_CLIENT_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "remoting/protocol/channel_dispatcher_base.h"
+#include "remoting/protocol/connection_to_client.h"
+#include "remoting/protocol/session.h"
+
+namespace remoting {
+namespace protocol {
+
+class HostControlDispatcher;
+class HostEventDispatcher;
+
+class WebrtcConnectionToClient : public ConnectionToClient,
+ public Session::EventHandler,
+ public ChannelDispatcherBase::EventHandler {
+ public:
+ explicit WebrtcConnectionToClient(scoped_ptr<Session> session);
+ ~WebrtcConnectionToClient() override;
+
+ // ConnectionToClient interface.
+ void SetEventHandler(
+ ConnectionToClient::EventHandler* event_handler) override;
+ Session* session() override;
+ void Disconnect(ErrorCode error) override;
+ void OnInputEventReceived(int64_t timestamp) override;
+ scoped_ptr<VideoStream> StartVideoStream(
+ scoped_ptr<webrtc::DesktopCapturer> desktop_capturer) override;
+ AudioStub* audio_stub() override;
+ ClientStub* client_stub() override;
+ void set_clipboard_stub(ClipboardStub* clipboard_stub) override;
+ void set_host_stub(HostStub* host_stub) override;
+ void set_input_stub(InputStub* input_stub) override;
+
+ // Session::EventHandler interface.
+ void OnSessionStateChange(Session::State state) override;
+ void OnSessionRouteChange(const std::string& channel_name,
+ const TransportRoute& route) override;
+
+ // ChannelDispatcherBase::EventHandler interface.
+ void OnChannelInitialized(ChannelDispatcherBase* channel_dispatcher) override;
+ void OnChannelError(ChannelDispatcherBase* channel_dispatcher,
+ ErrorCode error) override;
+
+ private:
+ base::ThreadChecker thread_checker_;
+
+ // Event handler for handling events sent from this object.
+ ConnectionToClient::EventHandler* event_handler_ = nullptr;
+
+ scoped_ptr<Session> session_;
+
+ scoped_ptr<HostControlDispatcher> control_dispatcher_;
+ scoped_ptr<HostEventDispatcher> event_dispatcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebrtcConnectionToClient);
+};
+
+} // namespace protocol
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_WEBRTC_CONNECTION_TO_CLIENT_H_
diff --git a/remoting/protocol/webrtc_connection_to_client_unittest.cc b/remoting/protocol/webrtc_connection_to_client_unittest.cc
new file mode 100644
index 0000000..83232ce
--- /dev/null
+++ b/remoting/protocol/webrtc_connection_to_client_unittest.cc
@@ -0,0 +1,95 @@
+// Copyright 2015 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 "remoting/protocol/webrtc_connection_to_client.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "remoting/base/constants.h"
+#include "remoting/protocol/fake_session.h"
+#include "remoting/protocol/message_serialization.h"
+#include "remoting/protocol/protocol_mock_objects.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+namespace protocol {
+
+class WebrtcConnectionToClientTest : public testing::Test {
+ public:
+ WebrtcConnectionToClientTest() {}
+
+ protected:
+ void SetUp() override {
+ session_ = new FakeSession();
+
+ // Allocate a ClientConnection object with the mock objects.
+ connection_.reset(new WebrtcConnectionToClient(make_scoped_ptr(session_)));
+ connection_->SetEventHandler(&handler_);
+ EXPECT_CALL(handler_, OnConnectionAuthenticated(connection_.get()))
+ .WillOnce(InvokeWithoutArgs(
+ this, &WebrtcConnectionToClientTest::ConnectStubs));
+ EXPECT_CALL(handler_, OnConnectionChannelsConnected(connection_.get()));
+ session_->event_handler()->OnSessionStateChange(Session::ACCEPTED);
+ session_->event_handler()->OnSessionStateChange(Session::AUTHENTICATED);
+ session_->event_handler()->OnSessionStateChange(Session::CONNECTED);
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void TearDown() override {
+ connection_.reset();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void ConnectStubs() {
+ connection_->set_clipboard_stub(&clipboard_stub_);
+ connection_->set_host_stub(&host_stub_);
+ connection_->set_input_stub(&input_stub_);
+ }
+
+ base::MessageLoop message_loop_;
+ MockConnectionToClientEventHandler handler_;
+ MockClipboardStub clipboard_stub_;
+ MockHostStub host_stub_;
+ MockInputStub input_stub_;
+ scoped_ptr<ConnectionToClient> connection_;
+
+ FakeSession* session_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebrtcConnectionToClientTest);
+};
+
+TEST_F(WebrtcConnectionToClientTest, SendCapabilitesMessage) {
+ Capabilities capabilities;
+ connection_->client_stub()->SetCapabilities(capabilities);
+
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that something has been written.
+ // TODO(sergeyu): Verify that the correct data has been written.
+ FakeStreamSocket* channel =
+ session_->GetTransport()->GetStreamChannelFactory()->GetFakeChannel(
+ kControlChannelName);
+ ASSERT_TRUE(channel);
+ EXPECT_FALSE(channel->written_data().empty());
+
+ ControlMessage message;
+ message.mutable_capabilities()->CopyFrom(capabilities);
+ scoped_refptr<net::IOBufferWithSize> expected_message =
+ SerializeAndFrameMessage(message);
+ EXPECT_EQ(std::string(expected_message->data(), expected_message->size()),
+ channel->written_data());
+
+ // And then close the connection to ConnectionToClient.
+ connection_->Disconnect(protocol::OK);
+
+ base::RunLoop().RunUntilIdle();
+}
+
+// TODO(sergeyu): Add more tests here after Session is refactored not to own
+// Transport, which will allow to use real WebrtcTransport with FakeSession.
+
+} // namespace protocol
+} // namespace remoting
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc
index 6dcbb97..253293e 100644
--- a/remoting/protocol/webrtc_transport.cc
+++ b/remoting/protocol/webrtc_transport.cc
@@ -244,6 +244,10 @@ StreamChannelFactory* WebrtcTransport::GetMultiplexedChannelFactory() {
return GetStreamChannelFactory();
}
+WebrtcTransport* WebrtcTransport::AsWebrtcTransport() {
+ return this;
+}
+
void WebrtcTransport::OnLocalSessionDescriptionCreated(
scoped_ptr<webrtc::SessionDescriptionInterface> description,
const std::string& error) {
diff --git a/remoting/protocol/webrtc_transport.h b/remoting/protocol/webrtc_transport.h
index ae792f2..afba35e 100644
--- a/remoting/protocol/webrtc_transport.h
+++ b/remoting/protocol/webrtc_transport.h
@@ -45,6 +45,7 @@ class WebrtcTransport : public Transport,
bool ProcessTransportInfo(buzz::XmlElement* transport_info) override;
StreamChannelFactory* GetStreamChannelFactory() override;
StreamChannelFactory* GetMultiplexedChannelFactory() override;
+ WebrtcTransport* AsWebrtcTransport() override;
private:
void OnLocalSessionDescriptionCreated(
diff --git a/remoting/protocol/webrtc_video_capturer_adapter.cc b/remoting/protocol/webrtc_video_capturer_adapter.cc
index 9bf51ed..42442b3 100644
--- a/remoting/protocol/webrtc_video_capturer_adapter.cc
+++ b/remoting/protocol/webrtc_video_capturer_adapter.cc
@@ -9,7 +9,7 @@
namespace remoting {
// Number of frames to be captured per second.
-const int kFramesPerSec = 10;
+const int kFramesPerSec = 30;
WebrtcVideoCapturerAdapter::WebrtcVideoCapturerAdapter(
scoped_ptr<webrtc::DesktopCapturer> capturer)
@@ -157,6 +157,7 @@ void WebrtcVideoCapturerAdapter::Stop() {
DCHECK_NE(capture_state(), cricket::CS_STOPPED);
capture_timer_.reset();
+ desktop_capturer_.reset();
SetCaptureFormat(nullptr);
SetCaptureState(cricket::CS_STOPPED);
@@ -164,7 +165,6 @@ void WebrtcVideoCapturerAdapter::Stop() {
VLOG(1) << "WebrtcVideoCapturerAdapter stopped.";
}
-
bool WebrtcVideoCapturerAdapter::IsRunning() {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc
new file mode 100644
index 0000000..50c6ddd
--- /dev/null
+++ b/remoting/protocol/webrtc_video_stream.cc
@@ -0,0 +1,49 @@
+// Copyright 2015 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 "remoting/protocol/webrtc_video_stream.h"
+
+#include "base/logging.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
+#include "third_party/libjingle/source/talk/app/webrtc/videosourceinterface.h"
+
+namespace remoting {
+namespace protocol {
+
+WebrtcVideoStream::WebrtcVideoStream(
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection,
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> stream)
+ : connection_(connection), stream_(stream) {}
+
+WebrtcVideoStream::~WebrtcVideoStream() {
+ for (const auto& track : stream_->GetVideoTracks()) {
+ track->GetSource()->Stop();
+ stream_->RemoveTrack(track.get());
+ }
+ connection_->RemoveStream(stream_.get());
+}
+
+void WebrtcVideoStream::Pause(bool pause) {
+ NOTIMPLEMENTED();
+}
+
+void WebrtcVideoStream::OnInputEventReceived(int64_t event_timestamp) {
+ NOTIMPLEMENTED();
+}
+
+void WebrtcVideoStream::SetLosslessEncode(bool want_lossless) {
+ NOTIMPLEMENTED();
+}
+
+void WebrtcVideoStream::SetLosslessColor(bool want_lossless) {
+ NOTIMPLEMENTED();
+}
+
+void WebrtcVideoStream::SetSizeCallback(const SizeCallback& size_callback) {
+ NOTIMPLEMENTED();
+}
+
+} // namespace protocol
+} // namespace remoting
diff --git a/remoting/protocol/webrtc_video_stream.h b/remoting/protocol/webrtc_video_stream.h
new file mode 100644
index 0000000..ffb0791
--- /dev/null
+++ b/remoting/protocol/webrtc_video_stream.h
@@ -0,0 +1,44 @@
+// Copyright 2015 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 REMOTING_PROTOCOL_WEBRTC_VIDEO_STREAM_H_
+#define REMOTING_PROTOCOL_WEBRTC_VIDEO_STREAM_H_
+
+#include "base/macros.h"
+#include "remoting/protocol/video_stream.h"
+#include "third_party/webrtc/base/scoped_ref_ptr.h"
+
+namespace webrtc {
+class MediaStreamInterface;
+class PeerConnectionInterface;
+} // namespace webrtc
+
+namespace remoting {
+namespace protocol {
+
+class WebrtcVideoStream : public VideoStream {
+ public:
+ WebrtcVideoStream(
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection,
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> stream);
+ ~WebrtcVideoStream() override;
+
+ // VideoStream interface.
+ void Pause(bool pause) override;
+ void OnInputEventReceived(int64_t event_timestamp) override;
+ void SetLosslessEncode(bool want_lossless) override;
+ void SetLosslessColor(bool want_lossless) override;
+ void SetSizeCallback(const SizeCallback& size_callback) override;
+
+ private:
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection_;
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebrtcVideoStream);
+};
+
+} // namespace protocol
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_WEBRTC_VIDEO_STREAM_H_