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

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

Issue 8493020: Move code in src/remoting to the new callbacks. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: - Created 9 years, 1 month 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
« no previous file with comments | « remoting/client/rectangle_update_decoder.h ('k') | remoting/host/capturer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/logging.h" 8 #include "base/logging.h"
8 #include "base/message_loop.h" 9 #include "base/message_loop.h"
9 #include "remoting/base/decoder.h" 10 #include "remoting/base/decoder.h"
10 #include "remoting/base/decoder_row_based.h" 11 #include "remoting/base/decoder_row_based.h"
11 #include "remoting/base/decoder_vp8.h" 12 #include "remoting/base/decoder_vp8.h"
12 #include "remoting/base/util.h" 13 #include "remoting/base/util.h"
13 #include "remoting/client/frame_consumer.h" 14 #include "remoting/client/frame_consumer.h"
14 #include "remoting/protocol/session_config.h" 15 #include "remoting/protocol/session_config.h"
15 16
16 using remoting::protocol::ChannelConfig; 17 using remoting::protocol::ChannelConfig;
17 using remoting::protocol::SessionConfig; 18 using remoting::protocol::SessionConfig;
18 19
19 namespace remoting { 20 namespace remoting {
20 21
21 class PartialFrameCleanup : public Task {
22 public:
23 PartialFrameCleanup(media::VideoFrame* frame, RectVector* rects,
24 RectangleUpdateDecoder* decoder)
25 : frame_(frame), rects_(rects), decoder_(decoder) {
26 }
27
28 virtual void Run() {
29 delete rects_;
30 frame_ = NULL;
31
32 // There maybe pending request to refresh rectangles.
33 decoder_->OnFrameConsumed();
34 decoder_ = NULL;
35 }
36
37 private:
38 scoped_refptr<media::VideoFrame> frame_;
39 RectVector* rects_;
40 scoped_refptr<RectangleUpdateDecoder> decoder_;
41 };
42
43 RectangleUpdateDecoder::RectangleUpdateDecoder(MessageLoop* message_loop, 22 RectangleUpdateDecoder::RectangleUpdateDecoder(MessageLoop* message_loop,
44 FrameConsumer* consumer) 23 FrameConsumer* consumer)
45 : message_loop_(message_loop), 24 : message_loop_(message_loop),
46 consumer_(consumer), 25 consumer_(consumer),
47 frame_is_new_(false), 26 frame_is_new_(false),
48 frame_is_consuming_(false) { 27 frame_is_consuming_(false) {
49 } 28 }
50 29
51 RectangleUpdateDecoder::~RectangleUpdateDecoder() { 30 RectangleUpdateDecoder::~RectangleUpdateDecoder() {
52 } 31 }
53 32
54 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { 33 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) {
55 initial_screen_size_ = SkISize::Make(config.initial_resolution().width, 34 initial_screen_size_ = SkISize::Make(config.initial_resolution().width,
56 config.initial_resolution().height); 35 config.initial_resolution().height);
57 36
58 // Initialize decoder based on the selected codec. 37 // Initialize decoder based on the selected codec.
59 ChannelConfig::Codec codec = config.video_config().codec; 38 ChannelConfig::Codec codec = config.video_config().codec;
60 if (codec == ChannelConfig::CODEC_VERBATIM) { 39 if (codec == ChannelConfig::CODEC_VERBATIM) {
61 decoder_.reset(DecoderRowBased::CreateVerbatimDecoder()); 40 decoder_.reset(DecoderRowBased::CreateVerbatimDecoder());
62 } else if (codec == ChannelConfig::CODEC_ZIP) { 41 } else if (codec == ChannelConfig::CODEC_ZIP) {
63 decoder_.reset(DecoderRowBased::CreateZlibDecoder()); 42 decoder_.reset(DecoderRowBased::CreateZlibDecoder());
64 } else if (codec == ChannelConfig::CODEC_VP8) { 43 } else if (codec == ChannelConfig::CODEC_VP8) {
65 decoder_.reset(new DecoderVp8()); 44 decoder_.reset(new DecoderVp8());
66 } else { 45 } else {
67 NOTREACHED() << "Invalid Encoding found: " << codec; 46 NOTREACHED() << "Invalid Encoding found: " << codec;
68 } 47 }
69 } 48 }
70 49
71 void RectangleUpdateDecoder::DecodePacket(const VideoPacket* packet, 50 void RectangleUpdateDecoder::DecodePacket(const VideoPacket* packet,
72 Task* done) { 51 const base::Closure& done) {
73 if (message_loop_ != MessageLoop::current()) { 52 if (message_loop_ != MessageLoop::current()) {
74 message_loop_->PostTask( 53 message_loop_->PostTask(
75 FROM_HERE, 54 FROM_HERE, base::Bind(&RectangleUpdateDecoder::DecodePacket,
76 NewRunnableMethod(this, 55 this, packet, done));
77 &RectangleUpdateDecoder::DecodePacket, packet,
78 done));
79 return; 56 return;
80 } 57 }
81 base::ScopedTaskRunner done_runner(done); 58 AllocateFrame(packet, done);
82
83 AllocateFrame(packet, done_runner.Release());
84 } 59 }
85 60
86 void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet, 61 void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
87 Task* done) { 62 const base::Closure& done) {
88 if (message_loop_ != MessageLoop::current()) { 63 if (message_loop_ != MessageLoop::current()) {
89 message_loop_->PostTask( 64 message_loop_->PostTask(
90 FROM_HERE, 65 FROM_HERE, base::Bind(&RectangleUpdateDecoder::AllocateFrame,
91 NewRunnableMethod( 66 this, packet, done));
92 this,
93 &RectangleUpdateDecoder::AllocateFrame, packet, done));
94 return; 67 return;
95 } 68 }
96 base::ScopedTaskRunner done_runner(done); 69 base::ScopedClosureRunner done_runner(done);
97 70
98 // Find the required frame size. 71 // Find the required frame size.
99 bool has_screen_size = packet->format().has_screen_width() && 72 bool has_screen_size = packet->format().has_screen_width() &&
100 packet->format().has_screen_height(); 73 packet->format().has_screen_height();
101 SkISize screen_size(SkISize::Make(packet->format().screen_width(), 74 SkISize screen_size(SkISize::Make(packet->format().screen_width(),
102 packet->format().screen_height())); 75 packet->format().screen_height()));
103 if (!has_screen_size) 76 if (!has_screen_size)
104 screen_size = initial_screen_size_; 77 screen_size = initial_screen_size_;
105 78
106 // Find the current frame size. 79 // Find the current frame size.
107 int width = 0; 80 int width = 0;
108 int height = 0; 81 int height = 0;
109 if (frame_) { 82 if (frame_) {
110 width = static_cast<int>(frame_->width()); 83 width = static_cast<int>(frame_->width());
111 height = static_cast<int>(frame_->height()); 84 height = static_cast<int>(frame_->height());
112 } 85 }
113 86
114 SkISize frame_size(SkISize::Make(width, height)); 87 SkISize frame_size(SkISize::Make(width, height));
115 88
116 // Allocate a new frame, if necessary. 89 // Allocate a new frame, if necessary.
117 if ((!frame_) || (has_screen_size && (screen_size != frame_size))) { 90 if ((!frame_) || (has_screen_size && (screen_size != frame_size))) {
118 if (frame_) { 91 if (frame_) {
119 consumer_->ReleaseFrame(frame_); 92 consumer_->ReleaseFrame(frame_);
120 frame_ = NULL; 93 frame_ = NULL;
121 } 94 }
122 95
123 consumer_->AllocateFrame(media::VideoFrame::RGB32, 96 consumer_->AllocateFrame(
124 screen_size.width(), screen_size.height(), 97 media::VideoFrame::RGB32, screen_size, &frame_,
125 base::TimeDelta(), base::TimeDelta(), 98 base::Bind(&RectangleUpdateDecoder::ProcessPacketData,
126 &frame_, 99 this, packet, done_runner.Release()));
127 NewRunnableMethod(this,
128 &RectangleUpdateDecoder::ProcessPacketData,
129 packet, done_runner.Release()));
130 frame_is_new_ = true; 100 frame_is_new_ = true;
131 return; 101 return;
132 } 102 }
133 ProcessPacketData(packet, done_runner.Release()); 103 ProcessPacketData(packet, done_runner.Release());
134 } 104 }
135 105
136 void RectangleUpdateDecoder::ProcessPacketData( 106 void RectangleUpdateDecoder::ProcessPacketData(
137 const VideoPacket* packet, Task* done) { 107 const VideoPacket* packet, const base::Closure& done) {
138 if (message_loop_ != MessageLoop::current()) { 108 if (message_loop_ != MessageLoop::current()) {
139 message_loop_->PostTask( 109 message_loop_->PostTask(
140 FROM_HERE, 110 FROM_HERE, base::Bind(&RectangleUpdateDecoder::ProcessPacketData,
141 NewRunnableMethod(this, 111 this, packet, done));
142 &RectangleUpdateDecoder::ProcessPacketData, packet,
143 done));
144 return; 112 return;
145 } 113 }
146 base::ScopedTaskRunner done_runner(done); 114 base::ScopedClosureRunner done_runner(done);
147 115
148 if (frame_is_new_) { 116 if (frame_is_new_) {
149 decoder_->Reset(); 117 decoder_->Reset();
150 decoder_->Initialize(frame_); 118 decoder_->Initialize(frame_);
151 frame_is_new_ = false; 119 frame_is_new_ = false;
152 } 120 }
153 121
154 if (!decoder_->IsReadyForData()) { 122 if (!decoder_->IsReadyForData()) {
155 // TODO(ajwong): This whole thing should move into an invalid state. 123 // TODO(ajwong): This whole thing should move into an invalid state.
156 LOG(ERROR) << "Decoder is unable to process data. Dropping packet."; 124 LOG(ERROR) << "Decoder is unable to process data. Dropping packet.";
157 return; 125 return;
158 } 126 }
159 127
160 if (decoder_->DecodePacket(packet) == Decoder::DECODE_DONE) 128 if (decoder_->DecodePacket(packet) == Decoder::DECODE_DONE)
161 SubmitToConsumer(); 129 SubmitToConsumer();
162 } 130 }
163 131
164 void RectangleUpdateDecoder::SetScaleRatios(double horizontal_ratio, 132 void RectangleUpdateDecoder::SetScaleRatios(double horizontal_ratio,
165 double vertical_ratio) { 133 double vertical_ratio) {
166 if (message_loop_ != MessageLoop::current()) { 134 if (message_loop_ != MessageLoop::current()) {
167 message_loop_->PostTask( 135 message_loop_->PostTask(
168 FROM_HERE, 136 FROM_HERE, base::Bind(&RectangleUpdateDecoder::SetScaleRatios,
169 NewRunnableMethod(this, 137 this, horizontal_ratio, vertical_ratio));
170 &RectangleUpdateDecoder::SetScaleRatios,
171 horizontal_ratio,
172 vertical_ratio));
173 return; 138 return;
174 } 139 }
175 140
176 // TODO(hclam): If the scale ratio has changed we should reallocate a 141 // TODO(hclam): If the scale ratio has changed we should reallocate a
177 // VideoFrame of different size. However if the scale ratio is always 142 // VideoFrame of different size. However if the scale ratio is always
178 // smaller than 1.0 we can use the same video frame. 143 // smaller than 1.0 we can use the same video frame.
179 decoder_->SetScaleRatios(horizontal_ratio, vertical_ratio); 144 decoder_->SetScaleRatios(horizontal_ratio, vertical_ratio);
180 } 145 }
181 146
182 void RectangleUpdateDecoder::UpdateClipRect(const SkIRect& new_clip_rect) { 147 void RectangleUpdateDecoder::UpdateClipRect(const SkIRect& new_clip_rect) {
183 if (message_loop_ != MessageLoop::current()) { 148 if (message_loop_ != MessageLoop::current()) {
184 message_loop_->PostTask( 149 message_loop_->PostTask(
185 FROM_HERE, 150 FROM_HERE, base::Bind(&RectangleUpdateDecoder::UpdateClipRect,
186 NewRunnableMethod( 151 this, new_clip_rect));
187 this,
188 &RectangleUpdateDecoder::UpdateClipRect, new_clip_rect));
189 return; 152 return;
190 } 153 }
191 154
192 if (new_clip_rect == clip_rect_ || !decoder_.get()) 155 if (new_clip_rect == clip_rect_ || !decoder_.get())
193 return; 156 return;
194 157
195 // Find out the rectangles to show because of clip rect is updated. 158 // Find out the rectangles to show because of clip rect is updated.
196 if (new_clip_rect.fTop < clip_rect_.fTop) { 159 if (new_clip_rect.fTop < clip_rect_.fTop) {
197 refresh_rects_.push_back( 160 refresh_rects_.push_back(
198 SkIRect::MakeXYWH(new_clip_rect.fLeft, 161 SkIRect::MakeXYWH(new_clip_rect.fLeft,
(...skipping 27 matching lines...) Expand all
226 } 189 }
227 190
228 clip_rect_ = new_clip_rect; 191 clip_rect_ = new_clip_rect;
229 decoder_->SetClipRect(new_clip_rect); 192 decoder_->SetClipRect(new_clip_rect);
230 DoRefresh(); 193 DoRefresh();
231 } 194 }
232 195
233 void RectangleUpdateDecoder::RefreshFullFrame() { 196 void RectangleUpdateDecoder::RefreshFullFrame() {
234 if (message_loop_ != MessageLoop::current()) { 197 if (message_loop_ != MessageLoop::current()) {
235 message_loop_->PostTask( 198 message_loop_->PostTask(
236 FROM_HERE, 199 FROM_HERE, base::Bind(&RectangleUpdateDecoder::RefreshFullFrame, this));
237 NewRunnableMethod(this, &RectangleUpdateDecoder::RefreshFullFrame));
238 return; 200 return;
239 } 201 }
240 202
241 // If a video frame or the decoder is not allocated yet then don't 203 // If a video frame or the decoder is not allocated yet then don't
242 // save the refresh rectangle to avoid wasted computation. 204 // save the refresh rectangle to avoid wasted computation.
243 if (!frame_ || !decoder_.get()) 205 if (!frame_ || !decoder_.get())
244 return; 206 return;
245 207
246 refresh_rects_.push_back( 208 refresh_rects_.push_back(
247 SkIRect::MakeWH(static_cast<int>(frame_->width()), 209 SkIRect::MakeWH(static_cast<int>(frame_->width()),
248 static_cast<int>(frame_->height()))); 210 static_cast<int>(frame_->height())));
249 DoRefresh(); 211 DoRefresh();
250 } 212 }
251 213
252 void RectangleUpdateDecoder::SubmitToConsumer() { 214 void RectangleUpdateDecoder::SubmitToConsumer() {
253 // A frame is not allocated yet, we can reach here because of a refresh 215 // A frame is not allocated yet, we can reach here because of a refresh
254 // request. 216 // request.
255 if (!frame_) 217 if (!frame_)
256 return; 218 return;
257 219
258 RectVector* dirty_rects = new RectVector(); 220 RectVector* dirty_rects = new RectVector();
259 decoder_->GetUpdatedRects(dirty_rects); 221 decoder_->GetUpdatedRects(dirty_rects);
260 222
261 frame_is_consuming_ = true; 223 frame_is_consuming_ = true;
262 consumer_->OnPartialFrameOutput( 224 consumer_->OnPartialFrameOutput(frame_, dirty_rects, base::Bind(
263 frame_, dirty_rects, 225 &RectangleUpdateDecoder::OnFrameConsumed, this, dirty_rects));
264 new PartialFrameCleanup(frame_, dirty_rects, this));
265 } 226 }
266 227
267 void RectangleUpdateDecoder::DoRefresh() { 228 void RectangleUpdateDecoder::DoRefresh() {
268 DCHECK_EQ(message_loop_, MessageLoop::current()); 229 DCHECK_EQ(message_loop_, MessageLoop::current());
269 230
270 if (refresh_rects_.empty()) 231 if (refresh_rects_.empty())
271 return; 232 return;
272 233
273 decoder_->RefreshRects(refresh_rects_); 234 decoder_->RefreshRects(refresh_rects_);
274 refresh_rects_.clear(); 235 refresh_rects_.clear();
275 SubmitToConsumer(); 236 SubmitToConsumer();
276 } 237 }
277 238
278 void RectangleUpdateDecoder::OnFrameConsumed() { 239 void RectangleUpdateDecoder::OnFrameConsumed(RectVector* rects) {
279 if (message_loop_ != MessageLoop::current()) { 240 if (message_loop_ != MessageLoop::current()) {
280 message_loop_->PostTask( 241 message_loop_->PostTask(
281 FROM_HERE, 242 FROM_HERE, base::Bind(&RectangleUpdateDecoder::OnFrameConsumed,
282 NewRunnableMethod(this, &RectangleUpdateDecoder::OnFrameConsumed)); 243 this, rects));
283 return; 244 return;
284 } 245 }
285 246
247 delete rects;
248
286 frame_is_consuming_ = false; 249 frame_is_consuming_ = false;
287 DoRefresh(); 250 DoRefresh();
288 } 251 }
289 252
290 } // namespace remoting 253 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/rectangle_update_decoder.h ('k') | remoting/host/capturer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698