OLD | NEW |
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/rectangle_update_decoder.h" | 5 #include "remoting/client/rectangle_update_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" |
9 #include "base/location.h" | 10 #include "base/location.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/message_loop_proxy.h" | 12 #include "base/single_thread_task_runner.h" |
12 #include "ppapi/cpp/image_data.h" | 13 #include "ppapi/cpp/image_data.h" |
13 #include "remoting/base/util.h" | 14 #include "remoting/base/util.h" |
14 #include "remoting/codec/video_decoder.h" | 15 #include "remoting/codec/video_decoder.h" |
15 #include "remoting/codec/video_decoder_row_based.h" | 16 #include "remoting/codec/video_decoder_row_based.h" |
16 #include "remoting/codec/video_decoder_vp8.h" | 17 #include "remoting/codec/video_decoder_vp8.h" |
17 #include "remoting/client/frame_consumer.h" | 18 #include "remoting/client/frame_consumer.h" |
18 #include "remoting/protocol/session_config.h" | 19 #include "remoting/protocol/session_config.h" |
19 | 20 |
20 using base::Passed; | 21 using base::Passed; |
21 using remoting::protocol::ChannelConfig; | 22 using remoting::protocol::ChannelConfig; |
22 using remoting::protocol::SessionConfig; | 23 using remoting::protocol::SessionConfig; |
23 | 24 |
24 namespace remoting { | 25 namespace remoting { |
25 | 26 |
26 RectangleUpdateDecoder::QueuedVideoPacket::QueuedVideoPacket( | |
27 scoped_ptr<VideoPacket> packet, | |
28 const base::Closure& done) | |
29 : packet(packet.release()), | |
30 done(done) { | |
31 } | |
32 | |
33 RectangleUpdateDecoder::QueuedVideoPacket::~QueuedVideoPacket() { | |
34 } | |
35 | |
36 RectangleUpdateDecoder::RectangleUpdateDecoder( | 27 RectangleUpdateDecoder::RectangleUpdateDecoder( |
37 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 28 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
38 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, | 29 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, |
39 scoped_refptr<FrameConsumerProxy> consumer) | 30 scoped_refptr<FrameConsumerProxy> consumer) |
40 : main_task_runner_(main_task_runner), | 31 : main_task_runner_(main_task_runner), |
41 decode_task_runner_(decode_task_runner), | 32 decode_task_runner_(decode_task_runner), |
42 consumer_(consumer), | 33 consumer_(consumer), |
43 source_size_(SkISize::Make(0, 0)), | 34 source_size_(SkISize::Make(0, 0)), |
44 source_dpi_(SkIPoint::Make(0, 0)), | 35 source_dpi_(SkIPoint::Make(0, 0)), |
45 view_size_(SkISize::Make(0, 0)), | 36 view_size_(SkISize::Make(0, 0)), |
46 clip_area_(SkIRect::MakeEmpty()), | 37 clip_area_(SkIRect::MakeEmpty()), |
47 paint_scheduled_(false), | 38 paint_scheduled_(false), |
48 packet_being_processed_(false), | |
49 latest_sequence_number_(0) { | 39 latest_sequence_number_(0) { |
50 } | 40 } |
51 | 41 |
52 RectangleUpdateDecoder::~RectangleUpdateDecoder() { | 42 RectangleUpdateDecoder::~RectangleUpdateDecoder() { |
53 } | 43 } |
54 | 44 |
55 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { | 45 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { |
56 // Initialize decoder based on the selected codec. | 46 // Initialize decoder based on the selected codec. |
57 ChannelConfig::Codec codec = config.video_config().codec; | 47 ChannelConfig::Codec codec = config.video_config().codec; |
58 if (codec == ChannelConfig::CODEC_VERBATIM) { | 48 if (codec == ChannelConfig::CODEC_VERBATIM) { |
59 decoder_.reset(VideoDecoderRowBased::CreateVerbatimDecoder()); | 49 decoder_.reset(VideoDecoderRowBased::CreateVerbatimDecoder()); |
60 } else if (codec == ChannelConfig::CODEC_ZIP) { | 50 } else if (codec == ChannelConfig::CODEC_ZIP) { |
61 decoder_.reset(VideoDecoderRowBased::CreateZlibDecoder()); | 51 decoder_.reset(VideoDecoderRowBased::CreateZlibDecoder()); |
62 } else if (codec == ChannelConfig::CODEC_VP8) { | 52 } else if (codec == ChannelConfig::CODEC_VP8) { |
63 decoder_.reset(new VideoDecoderVp8()); | 53 decoder_.reset(new VideoDecoderVp8()); |
64 } else { | 54 } else { |
65 NOTREACHED() << "Invalid Encoding found: " << codec; | 55 NOTREACHED() << "Invalid Encoding found: " << codec; |
66 } | 56 } |
67 } | 57 } |
68 | 58 |
69 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, | 59 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, |
70 const base::Closure& done) { | 60 const base::Closure& done) { |
71 DCHECK(decode_task_runner_->BelongsToCurrentThread()); | 61 DCHECK(decode_task_runner_->BelongsToCurrentThread()); |
72 | 62 |
73 base::ScopedClosureRunner done_runner(done); | 63 base::ScopedClosureRunner done_runner(done); |
| 64 |
74 bool decoder_needs_reset = false; | 65 bool decoder_needs_reset = false; |
75 bool notify_size_or_dpi_change = false; | 66 bool notify_size_or_dpi_change = false; |
76 | 67 |
77 // If the packet includes screen size or DPI information, store them. | 68 // If the packet includes screen size or DPI information, store them. |
78 if (packet->format().has_screen_width() && | 69 if (packet->format().has_screen_width() && |
79 packet->format().has_screen_height()) { | 70 packet->format().has_screen_height()) { |
80 SkISize source_size = SkISize::Make(packet->format().screen_width(), | 71 SkISize source_size = SkISize::Make(packet->format().screen_width(), |
81 packet->format().screen_height()); | 72 packet->format().screen_height()); |
82 if (source_size_ != source_size) { | 73 if (source_size_ != source_size) { |
83 source_size_ = source_size; | 74 source_size_ = source_size; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 stats_.video_encode_ms()->Record(packet->encode_time_ms()); | 246 stats_.video_encode_ms()->Record(packet->encode_time_ms()); |
256 if (packet->has_client_sequence_number() && | 247 if (packet->has_client_sequence_number() && |
257 packet->client_sequence_number() > latest_sequence_number_) { | 248 packet->client_sequence_number() > latest_sequence_number_) { |
258 latest_sequence_number_ = packet->client_sequence_number(); | 249 latest_sequence_number_ = packet->client_sequence_number(); |
259 base::TimeDelta round_trip_latency = | 250 base::TimeDelta round_trip_latency = |
260 base::Time::Now() - | 251 base::Time::Now() - |
261 base::Time::FromInternalValue(packet->client_sequence_number()); | 252 base::Time::FromInternalValue(packet->client_sequence_number()); |
262 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds()); | 253 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds()); |
263 } | 254 } |
264 | 255 |
265 received_packets_.push_back(QueuedVideoPacket(packet.Pass(), done)); | |
266 if (!packet_being_processed_) | |
267 ProcessNextPacket(); | |
268 } | |
269 | |
270 int RectangleUpdateDecoder::GetPendingVideoPackets() { | |
271 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
272 return received_packets_.size(); | |
273 } | |
274 | |
275 void RectangleUpdateDecoder::DropAllPackets() { | |
276 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
277 | |
278 while(!received_packets_.empty()) { | |
279 delete received_packets_.front().packet; | |
280 received_packets_.front().done.Run(); | |
281 received_packets_.pop_front(); | |
282 } | |
283 } | |
284 | |
285 void RectangleUpdateDecoder::ProcessNextPacket() { | |
286 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
287 CHECK(!packet_being_processed_); | |
288 | |
289 if (received_packets_.empty()) { | |
290 // Nothing to do! | |
291 return; | |
292 } | |
293 | |
294 scoped_ptr<VideoPacket> packet(received_packets_.front().packet); | |
295 received_packets_.front().packet = NULL; | |
296 packet_being_processed_ = true; | |
297 | |
298 // Measure the latency between the last packet being received and presented. | 256 // Measure the latency between the last packet being received and presented. |
299 bool last_packet = (packet->flags() & VideoPacket::LAST_PACKET) != 0; | 257 bool last_packet = (packet->flags() & VideoPacket::LAST_PACKET) != 0; |
300 base::Time decode_start; | 258 base::Time decode_start; |
301 if (last_packet) | 259 if (last_packet) |
302 decode_start = base::Time::Now(); | 260 decode_start = base::Time::Now(); |
303 | 261 |
304 base::Closure callback = base::Bind(&RectangleUpdateDecoder::OnPacketDone, | 262 base::Closure decode_done = |
305 this, | 263 base::Bind(&RectangleUpdateDecoder::OnPacketDone, this, |
306 last_packet, | 264 last_packet, decode_start, done); |
307 decode_start); | |
308 | 265 |
309 decode_task_runner_->PostTask(FROM_HERE, base::Bind( | 266 decode_task_runner_->PostTask(FROM_HERE, base::Bind( |
310 &RectangleUpdateDecoder::DecodePacket, this, | 267 &RectangleUpdateDecoder::DecodePacket, this, |
311 base::Passed(&packet), callback)); | 268 base::Passed(&packet), decode_done)); |
312 } | 269 } |
313 | 270 |
314 void RectangleUpdateDecoder::OnPacketDone(bool last_packet, | 271 void RectangleUpdateDecoder::OnPacketDone(bool last_packet, |
315 base::Time decode_start) { | 272 base::Time decode_start, |
| 273 const base::Closure& done) { |
316 if (!main_task_runner_->BelongsToCurrentThread()) { | 274 if (!main_task_runner_->BelongsToCurrentThread()) { |
317 main_task_runner_->PostTask(FROM_HERE, base::Bind( | 275 main_task_runner_->PostTask(FROM_HERE, base::Bind( |
318 &RectangleUpdateDecoder::OnPacketDone, this, | 276 &RectangleUpdateDecoder::OnPacketDone, this, |
319 last_packet, decode_start)); | 277 last_packet, decode_start, done)); |
320 return; | 278 return; |
321 } | 279 } |
322 | 280 |
323 // Record the latency between the final packet being received and | 281 // Record the latency between the final packet being received and |
324 // presented. | 282 // presented. |
325 if (last_packet) { | 283 if (last_packet) { |
326 stats_.video_decode_ms()->Record( | 284 stats_.video_decode_ms()->Record( |
327 (base::Time::Now() - decode_start).InMilliseconds()); | 285 (base::Time::Now() - decode_start).InMilliseconds()); |
328 } | 286 } |
329 | 287 |
330 received_packets_.front().done.Run(); | 288 done.Run(); |
331 received_packets_.pop_front(); | |
332 | |
333 packet_being_processed_ = false; | |
334 | |
335 // Process the next video packet. | |
336 ProcessNextPacket(); | |
337 } | 289 } |
338 | 290 |
339 ChromotingStats* RectangleUpdateDecoder::GetStats() { | 291 ChromotingStats* RectangleUpdateDecoder::GetStats() { |
340 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 292 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
341 return &stats_; | 293 return &stats_; |
342 } | 294 } |
343 | 295 |
344 } // namespace remoting | 296 } // namespace remoting |
OLD | NEW |