Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: remoting/client/chromoting_client.cc

Issue 10867039: Moved video stub implementation to RectangleUpdateDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added DCHECK Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/client/chromoting_client.h" 5 #include "remoting/client/chromoting_client.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "remoting/client/audio_decode_scheduler.h" 8 #include "remoting/client/audio_decode_scheduler.h"
9 #include "remoting/client/audio_player.h" 9 #include "remoting/client/audio_player.h"
10 #include "remoting/client/client_context.h" 10 #include "remoting/client/client_context.h"
11 #include "remoting/client/client_user_interface.h" 11 #include "remoting/client/client_user_interface.h"
12 #include "remoting/client/rectangle_update_decoder.h" 12 #include "remoting/client/rectangle_update_decoder.h"
13 #include "remoting/proto/audio.pb.h" 13 #include "remoting/proto/audio.pb.h"
14 #include "remoting/proto/video.pb.h" 14 #include "remoting/proto/video.pb.h"
15 #include "remoting/protocol/authentication_method.h" 15 #include "remoting/protocol/authentication_method.h"
16 #include "remoting/protocol/connection_to_host.h" 16 #include "remoting/protocol/connection_to_host.h"
17 #include "remoting/protocol/negotiating_authenticator.h" 17 #include "remoting/protocol/negotiating_authenticator.h"
18 #include "remoting/protocol/session_config.h" 18 #include "remoting/protocol/session_config.h"
19 #include "remoting/protocol/transport.h" 19 #include "remoting/protocol/transport.h"
20 20
21 namespace remoting { 21 namespace remoting {
22 22
23 using protocol::AuthenticationMethod; 23 using protocol::AuthenticationMethod;
24 24
25 ChromotingClient::QueuedVideoPacket::QueuedVideoPacket(
26 scoped_ptr<VideoPacket> packet, const base::Closure& done)
27 : packet(packet.release()), done(done) {
28 }
29
30 ChromotingClient::QueuedVideoPacket::~QueuedVideoPacket() {
31 }
32
33 ChromotingClient::ChromotingClient( 25 ChromotingClient::ChromotingClient(
34 const ClientConfig& config, 26 const ClientConfig& config,
35 ClientContext* client_context, 27 ClientContext* client_context,
36 protocol::ConnectionToHost* connection, 28 protocol::ConnectionToHost* connection,
37 ClientUserInterface* user_interface, 29 ClientUserInterface* user_interface,
38 RectangleUpdateDecoder* rectangle_decoder, 30 RectangleUpdateDecoder* rectangle_decoder,
39 scoped_ptr<AudioPlayer> audio_player) 31 scoped_ptr<AudioPlayer> audio_player)
40 : config_(config), 32 : config_(config),
41 task_runner_(client_context->main_task_runner()), 33 task_runner_(client_context->main_task_runner()),
42 connection_(connection), 34 connection_(connection),
43 user_interface_(user_interface), 35 user_interface_(user_interface),
44 rectangle_decoder_(rectangle_decoder), 36 rectangle_decoder_(rectangle_decoder),
45 packet_being_processed_(false),
46 last_sequence_number_(0),
47 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 37 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
48 audio_decode_scheduler_.reset(new AudioDecodeScheduler( 38 audio_decode_scheduler_.reset(new AudioDecodeScheduler(
49 client_context->main_task_runner(), 39 client_context->main_task_runner(),
50 client_context->audio_decode_task_runner(), 40 client_context->audio_decode_task_runner(),
51 audio_player.Pass())); 41 audio_player.Pass()));
52 } 42 }
53 43
54 ChromotingClient::~ChromotingClient() { 44 ChromotingClient::~ChromotingClient() {
55 } 45 }
56 46
57 void ChromotingClient::Start( 47 void ChromotingClient::Start(
58 scoped_refptr<XmppProxy> xmpp_proxy, 48 scoped_refptr<XmppProxy> xmpp_proxy,
59 scoped_ptr<protocol::TransportFactory> transport_factory) { 49 scoped_ptr<protocol::TransportFactory> transport_factory) {
60 DCHECK(task_runner_->BelongsToCurrentThread()); 50 DCHECK(task_runner_->BelongsToCurrentThread());
61 51
62 scoped_ptr<protocol::Authenticator> authenticator( 52 scoped_ptr<protocol::Authenticator> authenticator(
63 protocol::NegotiatingAuthenticator::CreateForClient( 53 protocol::NegotiatingAuthenticator::CreateForClient(
64 config_.authentication_tag, 54 config_.authentication_tag,
65 config_.shared_secret, config_.authentication_methods)); 55 config_.shared_secret, config_.authentication_methods));
66 56
67 // Create a WeakPtr to ourself for to use for all posted tasks. 57 // Create a WeakPtr to ourself for to use for all posted tasks.
68 weak_ptr_ = weak_factory_.GetWeakPtr(); 58 weak_ptr_ = weak_factory_.GetWeakPtr();
69 59
70 connection_->Connect(xmpp_proxy, config_.local_jid, config_.host_jid, 60 connection_->Connect(xmpp_proxy, config_.local_jid, config_.host_jid,
71 config_.host_public_key, transport_factory.Pass(), 61 config_.host_public_key, transport_factory.Pass(),
72 authenticator.Pass(), this, this, this, this, 62 authenticator.Pass(), this, this, this,
63 rectangle_decoder_,
73 audio_decode_scheduler_.get()); 64 audio_decode_scheduler_.get());
74 } 65 }
75 66
76 void ChromotingClient::Stop(const base::Closure& shutdown_task) { 67 void ChromotingClient::Stop(const base::Closure& shutdown_task) {
77 DCHECK(task_runner_->BelongsToCurrentThread()); 68 DCHECK(task_runner_->BelongsToCurrentThread());
78 69
79 // Drop all pending packets. 70 // Drop all pending packets.
80 while(!received_packets_.empty()) { 71 rectangle_decoder_->DropAllPackets();
81 delete received_packets_.front().packet;
82 received_packets_.front().done.Run();
83 received_packets_.pop_front();
84 }
85 72
86 connection_->Disconnect(base::Bind(&ChromotingClient::OnDisconnected, 73 connection_->Disconnect(base::Bind(&ChromotingClient::OnDisconnected,
87 weak_ptr_, shutdown_task)); 74 weak_ptr_, shutdown_task));
Wez 2012/08/23 22:10:48 nit: Not related to this CL as such but does the c
kxing 2012/08/24 17:05:22 Not sure. I'll let someone do that in a separate C
88 } 75 }
89 76
90 void ChromotingClient::OnDisconnected(const base::Closure& shutdown_task) { 77 void ChromotingClient::OnDisconnected(const base::Closure& shutdown_task) {
91 shutdown_task.Run(); 78 shutdown_task.Run();
92 } 79 }
93 80
94 ChromotingStats* ChromotingClient::GetStats() { 81 ChromotingStats* ChromotingClient::GetStats() {
95 DCHECK(task_runner_->BelongsToCurrentThread()); 82 DCHECK(task_runner_->BelongsToCurrentThread());
96 return &stats_; 83 return rectangle_decoder_->GetStats();
97 } 84 }
98 85
99 void ChromotingClient::InjectClipboardEvent( 86 void ChromotingClient::InjectClipboardEvent(
100 const protocol::ClipboardEvent& event) { 87 const protocol::ClipboardEvent& event) {
101 DCHECK(task_runner_->BelongsToCurrentThread()); 88 DCHECK(task_runner_->BelongsToCurrentThread());
102 user_interface_->GetClipboardStub()->InjectClipboardEvent(event); 89 user_interface_->GetClipboardStub()->InjectClipboardEvent(event);
103 } 90 }
104 91
105 void ChromotingClient::SetCursorShape( 92 void ChromotingClient::SetCursorShape(
106 const protocol::CursorShapeInfo& cursor_shape) { 93 const protocol::CursorShapeInfo& cursor_shape) {
107 user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape); 94 user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape);
108 } 95 }
109 96
110 void ChromotingClient::ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
111 const base::Closure& done) {
112 DCHECK(task_runner_->BelongsToCurrentThread());
113
114 // If the video packet is empty then drop it. Empty packets are used to
115 // maintain activity on the network.
116 if (!packet->has_data() || packet->data().size() == 0) {
117 done.Run();
118 return;
119 }
120
121 // Add one frame to the counter.
122 stats_.video_frame_rate()->Record(1);
123
124 // Record other statistics received from host.
125 stats_.video_bandwidth()->Record(packet->data().size());
126 if (packet->has_capture_time_ms())
127 stats_.video_capture_ms()->Record(packet->capture_time_ms());
128 if (packet->has_encode_time_ms())
129 stats_.video_encode_ms()->Record(packet->encode_time_ms());
130 if (packet->has_client_sequence_number() &&
131 packet->client_sequence_number() > last_sequence_number_) {
132 last_sequence_number_ = packet->client_sequence_number();
133 base::TimeDelta round_trip_latency =
134 base::Time::Now() -
135 base::Time::FromInternalValue(packet->client_sequence_number());
136 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds());
137 }
138
139 received_packets_.push_back(QueuedVideoPacket(packet.Pass(), done));
140 if (!packet_being_processed_)
141 DispatchPacket();
142 }
143
144 int ChromotingClient::GetPendingVideoPackets() {
145 DCHECK(task_runner_->BelongsToCurrentThread());
146 return received_packets_.size();
147 }
148
149 void ChromotingClient::DispatchPacket() {
150 DCHECK(task_runner_->BelongsToCurrentThread());
151 CHECK(!packet_being_processed_);
152
153 if (received_packets_.empty()) {
154 // Nothing to do!
155 return;
156 }
157
158 scoped_ptr<VideoPacket> packet(received_packets_.front().packet);
159 received_packets_.front().packet = NULL;
160 packet_being_processed_ = true;
161
162 // Measure the latency between the last packet being received and presented.
163 bool last_packet = (packet->flags() & VideoPacket::LAST_PACKET) != 0;
164 base::Time decode_start;
165 if (last_packet)
166 decode_start = base::Time::Now();
167
168 rectangle_decoder_->DecodePacket(
169 packet.Pass(),
170 base::Bind(&ChromotingClient::OnPacketDone, base::Unretained(this),
171 last_packet, decode_start));
172 }
173
174 void ChromotingClient::OnConnectionState( 97 void ChromotingClient::OnConnectionState(
175 protocol::ConnectionToHost::State state, 98 protocol::ConnectionToHost::State state,
176 protocol::ErrorCode error) { 99 protocol::ErrorCode error) {
177 DCHECK(task_runner_->BelongsToCurrentThread()); 100 DCHECK(task_runner_->BelongsToCurrentThread());
178 VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")"; 101 VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")";
179 if (state == protocol::ConnectionToHost::CONNECTED) 102 if (state == protocol::ConnectionToHost::CONNECTED)
180 Initialize(); 103 Initialize();
181 user_interface_->OnConnectionState(state, error); 104 user_interface_->OnConnectionState(state, error);
182 } 105 }
183 106
184 void ChromotingClient::OnConnectionReady(bool ready) { 107 void ChromotingClient::OnConnectionReady(bool ready) {
185 VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")"; 108 VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")";
186 user_interface_->OnConnectionReady(ready); 109 user_interface_->OnConnectionReady(ready);
187 } 110 }
188 111
189 void ChromotingClient::OnPacketDone(bool last_packet,
190 base::Time decode_start) {
191 if (!task_runner_->BelongsToCurrentThread()) {
192 task_runner_->PostTask(FROM_HERE, base::Bind(
193 &ChromotingClient::OnPacketDone, base::Unretained(this),
194 last_packet, decode_start));
195 return;
196 }
197
198 // Record the latency between the final packet being received and
199 // presented.
200 if (last_packet) {
201 stats_.video_decode_ms()->Record(
202 (base::Time::Now() - decode_start).InMilliseconds());
203 }
204
205 received_packets_.front().done.Run();
206 received_packets_.pop_front();
207
208 packet_being_processed_ = false;
209
210 // Process the next video packet.
211 DispatchPacket();
212 }
213
214 void ChromotingClient::Initialize() { 112 void ChromotingClient::Initialize() {
215 DCHECK(task_runner_->BelongsToCurrentThread()); 113 DCHECK(task_runner_->BelongsToCurrentThread());
216 114
217 // Initialize the decoder. 115 // Initialize the decoder.
218 rectangle_decoder_->Initialize(connection_->config()); 116 rectangle_decoder_->Initialize(connection_->config());
219 if (connection_->config().is_audio_enabled()) 117 if (connection_->config().is_audio_enabled())
220 audio_decode_scheduler_->Initialize(connection_->config()); 118 audio_decode_scheduler_->Initialize(connection_->config());
221 } 119 }
222 120
223 } // namespace remoting 121 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698