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

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

Issue 10879085: Cleanup RectangleUpdateDecoder and VideoStub (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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/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), 39 stopped_(false),
49 latest_sequence_number_(0) { 40 latest_sequence_number_(0) {
50 } 41 }
51 42
52 RectangleUpdateDecoder::~RectangleUpdateDecoder() { 43 RectangleUpdateDecoder::~RectangleUpdateDecoder() {
53 } 44 }
54 45
55 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { 46 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) {
56 // Initialize decoder based on the selected codec. 47 // Initialize decoder based on the selected codec.
57 ChannelConfig::Codec codec = config.video_config().codec; 48 ChannelConfig::Codec codec = config.video_config().codec;
58 if (codec == ChannelConfig::CODEC_VERBATIM) { 49 if (codec == ChannelConfig::CODEC_VERBATIM) {
59 decoder_.reset(VideoDecoderRowBased::CreateVerbatimDecoder()); 50 decoder_.reset(VideoDecoderRowBased::CreateVerbatimDecoder());
60 } else if (codec == ChannelConfig::CODEC_ZIP) { 51 } else if (codec == ChannelConfig::CODEC_ZIP) {
61 decoder_.reset(VideoDecoderRowBased::CreateZlibDecoder()); 52 decoder_.reset(VideoDecoderRowBased::CreateZlibDecoder());
62 } else if (codec == ChannelConfig::CODEC_VP8) { 53 } else if (codec == ChannelConfig::CODEC_VP8) {
63 decoder_.reset(new VideoDecoderVp8()); 54 decoder_.reset(new VideoDecoderVp8());
64 } else { 55 } else {
65 NOTREACHED() << "Invalid Encoding found: " << codec; 56 NOTREACHED() << "Invalid Encoding found: " << codec;
66 } 57 }
67 } 58 }
68 59
60 void RectangleUpdateDecoder::Stop() {
61 DCHECK(main_task_runner_->BelongsToCurrentThread());
Wez 2012/08/28 16:42:27 nit: Blank line after DCHECK.
Sergey Ulanov 2012/08/28 18:30:27 Done.
62 // |stopped_| is used on the decode thread, but changed only here on the main
63 // thread. Don't need any synchronization here because it's not an issue
64 // if the decode thread sees false instead of true.
Wez 2012/08/28 16:42:27 Why not just re-post the Stop() to set this on the
Sergey Ulanov 2012/08/28 18:30:27 Posting a task on the decoder thread will not do w
Wez 2012/08/29 23:18:05 OK, but you've stated that we don't need to lock h
Sergey Ulanov 2012/08/29 23:31:10 Actually after thinking more about it I think we d
65 stopped_ = true;
66 }
67
69 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, 68 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet,
70 const base::Closure& done) { 69 const base::Closure& done) {
71 DCHECK(decode_task_runner_->BelongsToCurrentThread()); 70 DCHECK(decode_task_runner_->BelongsToCurrentThread());
72 71
73 base::ScopedClosureRunner done_runner(done); 72 base::ScopedClosureRunner done_runner(done);
73
74 if (stopped_)
75 return;
76
74 bool decoder_needs_reset = false; 77 bool decoder_needs_reset = false;
75 bool notify_size_or_dpi_change = false; 78 bool notify_size_or_dpi_change = false;
76 79
77 // If the packet includes screen size or DPI information, store them. 80 // If the packet includes screen size or DPI information, store them.
78 if (packet->format().has_screen_width() && 81 if (packet->format().has_screen_width() &&
79 packet->format().has_screen_height()) { 82 packet->format().has_screen_height()) {
80 SkISize source_size = SkISize::Make(packet->format().screen_width(), 83 SkISize source_size = SkISize::Make(packet->format().screen_width(),
81 packet->format().screen_height()); 84 packet->format().screen_height());
82 if (source_size_ != source_size) { 85 if (source_size_ != source_size) {
83 source_size_ = source_size; 86 source_size_ = source_size;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 stats_.video_encode_ms()->Record(packet->encode_time_ms()); 258 stats_.video_encode_ms()->Record(packet->encode_time_ms());
256 if (packet->has_client_sequence_number() && 259 if (packet->has_client_sequence_number() &&
257 packet->client_sequence_number() > latest_sequence_number_) { 260 packet->client_sequence_number() > latest_sequence_number_) {
258 latest_sequence_number_ = packet->client_sequence_number(); 261 latest_sequence_number_ = packet->client_sequence_number();
259 base::TimeDelta round_trip_latency = 262 base::TimeDelta round_trip_latency =
260 base::Time::Now() - 263 base::Time::Now() -
261 base::Time::FromInternalValue(packet->client_sequence_number()); 264 base::Time::FromInternalValue(packet->client_sequence_number());
262 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds()); 265 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds());
263 } 266 }
264 267
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. 268 // Measure the latency between the last packet being received and presented.
299 bool last_packet = (packet->flags() & VideoPacket::LAST_PACKET) != 0; 269 bool last_packet = (packet->flags() & VideoPacket::LAST_PACKET) != 0;
300 base::Time decode_start; 270 base::Time decode_start;
301 if (last_packet) 271 if (last_packet)
302 decode_start = base::Time::Now(); 272 decode_start = base::Time::Now();
303 273
304 base::Closure callback = base::Bind(&RectangleUpdateDecoder::OnPacketDone, 274 base::Closure callback =
Wez 2012/08/28 16:42:27 nit: callback -> decode_done? (More consistent wit
Sergey Ulanov 2012/08/28 18:30:27 Done.
305 this, 275 base::Bind(&RectangleUpdateDecoder::OnPacketDone, this,
306 last_packet, 276 last_packet, decode_start, done);
307 decode_start);
308 277
309 decode_task_runner_->PostTask(FROM_HERE, base::Bind( 278 decode_task_runner_->PostTask(FROM_HERE, base::Bind(
310 &RectangleUpdateDecoder::DecodePacket, this, 279 &RectangleUpdateDecoder::DecodePacket, this,
311 base::Passed(&packet), callback)); 280 base::Passed(&packet), callback));
312 } 281 }
313 282
314 void RectangleUpdateDecoder::OnPacketDone(bool last_packet, 283 void RectangleUpdateDecoder::OnPacketDone(bool last_packet,
315 base::Time decode_start) { 284 base::Time decode_start,
285 const base::Closure& done) {
316 if (!main_task_runner_->BelongsToCurrentThread()) { 286 if (!main_task_runner_->BelongsToCurrentThread()) {
317 main_task_runner_->PostTask(FROM_HERE, base::Bind( 287 main_task_runner_->PostTask(FROM_HERE, base::Bind(
318 &RectangleUpdateDecoder::OnPacketDone, this, 288 &RectangleUpdateDecoder::OnPacketDone, this,
319 last_packet, decode_start)); 289 last_packet, decode_start, done));
320 return; 290 return;
321 } 291 }
322 292
323 // Record the latency between the final packet being received and 293 // Record the latency between the final packet being received and
324 // presented. 294 // presented.
325 if (last_packet) { 295 if (last_packet) {
326 stats_.video_decode_ms()->Record( 296 stats_.video_decode_ms()->Record(
327 (base::Time::Now() - decode_start).InMilliseconds()); 297 (base::Time::Now() - decode_start).InMilliseconds());
328 } 298 }
329 299
330 received_packets_.front().done.Run(); 300 done.Run();
331 received_packets_.pop_front();
332
333 packet_being_processed_ = false;
334
335 // Process the next video packet.
336 ProcessNextPacket();
337 } 301 }
338 302
339 ChromotingStats* RectangleUpdateDecoder::GetStats() { 303 ChromotingStats* RectangleUpdateDecoder::GetStats() {
340 DCHECK(main_task_runner_->BelongsToCurrentThread()); 304 DCHECK(main_task_runner_->BelongsToCurrentThread());
341 return &stats_; 305 return &stats_;
342 } 306 }
343 307
344 } // namespace remoting 308 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698