| Index: remoting/host/client_session.cc
|
| diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
|
| index 540277ecc6d041fa2262597be002c0ee79d5833c..fd60e341a20c9a3062da12457605f7d40eca91d3 100644
|
| --- a/remoting/host/client_session.cc
|
| +++ b/remoting/host/client_session.cc
|
| @@ -7,6 +7,16 @@
|
| #include <algorithm>
|
|
|
| #include "base/message_loop_proxy.h"
|
| +#include "remoting/base/encoder.h"
|
| +#include "remoting/base/encoder_row_based.h"
|
| +#include "remoting/base/encoder_vp8.h"
|
| +#include "remoting/codec/audio_encoder.h"
|
| +#include "remoting/codec/audio_encoder_verbatim.h"
|
| +#include "remoting/host/audio_capturer.h"
|
| +#include "remoting/host/audio_scheduler.h"
|
| +#include "remoting/host/desktop_environment.h"
|
| +#include "remoting/host/event_executor.h"
|
| +#include "remoting/host/screen_recorder.h"
|
| #include "remoting/host/video_frame_capturer.h"
|
| #include "remoting/proto/control.pb.h"
|
| #include "remoting/proto/event.pb.h"
|
| @@ -17,23 +27,29 @@ namespace remoting {
|
|
|
| ClientSession::ClientSession(
|
| EventHandler* event_handler,
|
| + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
|
| scoped_ptr<protocol::ConnectionToClient> connection,
|
| - protocol::ClipboardStub* host_clipboard_stub,
|
| - protocol::InputStub* host_input_stub,
|
| - VideoFrameCapturer* capturer,
|
| + scoped_ptr<DesktopEnvironment> desktop_environment,
|
| const base::TimeDelta& max_duration)
|
| : event_handler_(event_handler),
|
| connection_(connection.Pass()),
|
| + desktop_environment_(desktop_environment.Pass()),
|
| client_jid_(connection_->session()->jid()),
|
| is_authenticated_(false),
|
| - host_clipboard_stub_(host_clipboard_stub),
|
| - host_input_stub_(host_input_stub),
|
| + host_clipboard_stub_(desktop_environment_->event_executor()),
|
| + host_input_stub_(desktop_environment_->event_executor()),
|
| input_tracker_(host_input_stub_),
|
| remote_input_filter_(&input_tracker_),
|
| mouse_input_filter_(&remote_input_filter_),
|
| client_clipboard_factory_(clipboard_echo_filter_.client_filter()),
|
| - capturer_(capturer),
|
| - max_duration_(max_duration) {
|
| + capturer_(desktop_environment_->video_capturer()),
|
| + max_duration_(max_duration),
|
| + capture_task_runner_(capture_task_runner),
|
| + encode_task_runner_(encode_task_runner),
|
| + network_task_runner_(network_task_runner),
|
| + active_recorders_(0) {
|
| connection_->SetEventHandler(this);
|
|
|
| // TODO(sergeyu): Currently ConnectionToClient expects stubs to be
|
| @@ -46,6 +62,7 @@ ClientSession::ClientSession(
|
| }
|
|
|
| ClientSession::~ClientSession() {
|
| + DCHECK(desktop_environment_.get() == NULL);
|
| }
|
|
|
| void ClientSession::InjectKeyEvent(const protocol::KeyEvent& event) {
|
| @@ -107,6 +124,34 @@ void ClientSession::OnConnectionChannelsConnected(
|
| DCHECK(CalledOnValidThread());
|
| DCHECK_EQ(connection_.get(), connection);
|
| SetDisableInputs(false);
|
| +
|
| + // Create a ScreenRecorder passing the message loops that it should run on.
|
| + Encoder* encoder = CreateEncoder(connection_->session()->config());
|
| + video_recorder_ = new ScreenRecorder(
|
| + capture_task_runner_,
|
| + encode_task_runner_,
|
| + network_task_runner_,
|
| + desktop_environment_->video_capturer(),
|
| + encoder);
|
| + ++active_recorders_;
|
| +
|
| + if (connection_->session()->config().is_audio_enabled()) {
|
| + scoped_ptr<AudioEncoder> audio_encoder =
|
| + CreateAudioEncoder(connection_->session()->config());
|
| + audio_scheduler_ = new AudioScheduler(
|
| + capture_task_runner_,
|
| + network_task_runner_,
|
| + desktop_environment_->audio_capturer(),
|
| + audio_encoder.Pass(),
|
| + connection_->audio_stub());
|
| + ++active_recorders_;
|
| + }
|
| +
|
| + // Start the session.
|
| + video_recorder_->AddConnection(connection_.get());
|
| + video_recorder_->Start();
|
| + desktop_environment_->Start(CreateClipboardProxy());
|
| +
|
| event_handler_->OnSessionChannelsConnected(this);
|
| }
|
|
|
| @@ -131,6 +176,10 @@ void ClientSession::OnSequenceNumberUpdated(
|
| protocol::ConnectionToClient* connection, int64 sequence_number) {
|
| DCHECK(CalledOnValidThread());
|
| DCHECK_EQ(connection_.get(), connection);
|
| +
|
| + if (video_recorder_.get())
|
| + video_recorder_->UpdateSequenceNumber(sequence_number);
|
| +
|
| event_handler_->OnSessionSequenceNumber(this, sequence_number);
|
| }
|
|
|
| @@ -153,6 +202,24 @@ void ClientSession::Disconnect() {
|
| connection_->Disconnect();
|
| }
|
|
|
| +void ClientSession::StopAndDelete() {
|
| + DCHECK(CalledOnValidThread());
|
| +
|
| + if (audio_scheduler_.get()) {
|
| + audio_scheduler_->OnClientDisconnected();
|
| + StopAudioScheduler();
|
| + }
|
| +
|
| + if (video_recorder_.get()) {
|
| + video_recorder_->RemoveConnection(connection_.get());
|
| + StopScreenRecorder();
|
| + }
|
| +
|
| + if (!active_recorders_) {
|
| + delete this;
|
| + }
|
| +}
|
| +
|
| void ClientSession::LocalMouseMoved(const SkIPoint& mouse_pos) {
|
| DCHECK(CalledOnValidThread());
|
| remote_input_filter_.LocalMouseMoved(mouse_pos);
|
| @@ -181,4 +248,67 @@ scoped_ptr<protocol::ClipboardStub> ClientSession::CreateClipboardProxy() {
|
| base::MessageLoopProxy::current()));
|
| }
|
|
|
| +// TODO(sergeyu): Move this to SessionManager?
|
| +// static
|
| +Encoder* ClientSession::CreateEncoder(const protocol::SessionConfig& config) {
|
| + const protocol::ChannelConfig& video_config = config.video_config();
|
| +
|
| + if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
|
| + return EncoderRowBased::CreateVerbatimEncoder();
|
| + } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) {
|
| + return EncoderRowBased::CreateZlibEncoder();
|
| + } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) {
|
| + return new remoting::EncoderVp8();
|
| + }
|
| +
|
| + return NULL;
|
| +}
|
| +
|
| +// static
|
| +scoped_ptr<AudioEncoder> ClientSession::CreateAudioEncoder(
|
| + const protocol::SessionConfig& config) {
|
| + const protocol::ChannelConfig& audio_config = config.audio_config();
|
| +
|
| + if (audio_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
|
| + return scoped_ptr<AudioEncoder>(new AudioEncoderVerbatim());
|
| + }
|
| +
|
| + NOTIMPLEMENTED();
|
| + return scoped_ptr<AudioEncoder>(NULL);
|
| +}
|
| +
|
| +void ClientSession::OnRecorderStopped() {
|
| + if (!network_task_runner_->BelongsToCurrentThread()) {
|
| + network_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&ClientSession::OnRecorderStopped,
|
| + base::Unretained(this)));
|
| + return;
|
| + }
|
| +
|
| + --active_recorders_;
|
| + DCHECK_GE(active_recorders_, 0);
|
| +
|
| + StopAndDelete();
|
| +}
|
| +
|
| +void ClientSession::StopAudioScheduler() {
|
| + DCHECK(CalledOnValidThread());
|
| + DCHECK(audio_scheduler_.get());
|
| +
|
| + scoped_refptr<AudioScheduler> audio_scheduler = audio_scheduler_;
|
| + audio_scheduler_ = NULL;
|
| + audio_scheduler->Stop(base::Bind(&ClientSession::OnRecorderStopped,
|
| + base::Unretained(this)));
|
| +}
|
| +
|
| +void ClientSession::StopScreenRecorder() {
|
| + DCHECK(CalledOnValidThread());
|
| + DCHECK(video_recorder_.get());
|
| +
|
| + scoped_refptr<ScreenRecorder> video_recorder = video_recorder_;
|
| + video_recorder_ = NULL;
|
| + video_recorder->Stop(base::Bind(&ClientSession::OnRecorderStopped,
|
| + base::Unretained(this)));
|
| +}
|
| +
|
| } // namespace remoting
|
|
|