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 <list> | |
8 | |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/callback.h" | 10 #include "base/callback.h" |
9 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
10 #include "base/location.h" | 12 #include "base/location.h" |
11 #include "base/logging.h" | 13 #include "base/logging.h" |
12 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
13 #include "remoting/base/util.h" | 15 #include "remoting/base/util.h" |
14 #include "remoting/client/frame_consumer.h" | 16 #include "remoting/client/frame_consumer.h" |
15 #include "remoting/codec/video_decoder.h" | 17 #include "remoting/codec/video_decoder.h" |
16 #include "remoting/codec/video_decoder_verbatim.h" | 18 #include "remoting/codec/video_decoder_verbatim.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 } | 69 } |
68 | 70 |
69 virtual const webrtc::DesktopRegion* GetImageShape() OVERRIDE { | 71 virtual const webrtc::DesktopRegion* GetImageShape() OVERRIDE { |
70 return parent_->GetImageShape(); | 72 return parent_->GetImageShape(); |
71 } | 73 } |
72 | 74 |
73 private: | 75 private: |
74 scoped_ptr<VideoDecoder> parent_; | 76 scoped_ptr<VideoDecoder> parent_; |
75 }; | 77 }; |
76 | 78 |
77 RectangleUpdateDecoder::RectangleUpdateDecoder( | 79 class RectangleUpdateDecoder::Core : public base::RefCountedThreadSafe<Core> { |
80 public: | |
81 Core(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
82 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, | |
83 scoped_refptr<FrameConsumerProxy> consumer); | |
84 | |
85 // VideoProcessor implementation. | |
86 void Initialize(const protocol::SessionConfig& config); | |
87 ChromotingStats* GetStats(); | |
88 void ProcessVideoPacket(scoped_ptr<VideoPacket> packet, | |
89 const base::Closure& done); | |
90 | |
91 // FrameProducer implementation. These methods may be called before we are | |
92 // Initialize()d, or we know the source screen size. | |
93 void DrawBuffer(webrtc::DesktopFrame* buffer); | |
94 void InvalidateRegion(const webrtc::DesktopRegion& region); | |
95 void RequestReturnBuffers(const base::Closure& done); | |
96 void SetOutputSizeAndClip( | |
97 const webrtc::DesktopSize& view_size, | |
98 const webrtc::DesktopRect& clip_area); | |
99 const webrtc::DesktopRegion* GetBufferShape(); | |
100 | |
101 private: | |
102 friend class base::RefCountedThreadSafe<Core>; | |
103 virtual ~Core(); | |
104 | |
105 // Paints the invalidated region to the next available buffer and returns it | |
106 // to the consumer. | |
107 void SchedulePaint(); | |
108 void DoPaint(); | |
109 | |
110 // Decodes the contents of |packet|. DecodePacket may keep a reference to | |
111 // |packet| so the |packet| must remain alive and valid until |done| is | |
112 // executed. | |
113 void DecodePacket(scoped_ptr<VideoPacket> packet, const base::Closure& done); | |
114 | |
115 // Callback method when a VideoPacket is processed. |decode_start| contains | |
116 // the timestamp when the packet will start to be processed. | |
117 void OnPacketDone(base::Time decode_start, const base::Closure& done); | |
118 | |
119 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | |
120 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_; | |
121 scoped_refptr<FrameConsumerProxy> consumer_; | |
122 scoped_ptr<VideoDecoder> decoder_; | |
123 | |
124 // Remote screen size in pixels. | |
125 webrtc::DesktopSize source_size_; | |
126 | |
127 // Vertical and horizontal DPI of the remote screen. | |
128 webrtc::DesktopVector source_dpi_; | |
129 | |
130 // The current dimensions of the frame consumer view. | |
131 webrtc::DesktopSize view_size_; | |
132 webrtc::DesktopRect clip_area_; | |
133 | |
134 // The drawing buffers supplied by the frame consumer. | |
135 std::list<webrtc::DesktopFrame*> buffers_; | |
136 | |
137 // Flag used to coalesce runs of SchedulePaint()s into a single DoPaint(). | |
138 bool paint_scheduled_; | |
139 | |
140 ChromotingStats stats_; | |
Wez
2014/01/14 16:23:14
If you move ProcessVideoPacket and OnDecodeDone ba
Sergey Ulanov
2014/01/15 00:58:17
Done.
| |
141 | |
142 // Keep track of the most recent sequence number bounced back from the host. | |
143 int64 latest_sequence_number_; | |
144 }; | |
145 | |
146 RectangleUpdateDecoder::Core::Core( | |
78 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 147 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
79 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, | 148 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, |
80 scoped_refptr<FrameConsumerProxy> consumer) | 149 scoped_refptr<FrameConsumerProxy> consumer) |
81 : main_task_runner_(main_task_runner), | 150 : main_task_runner_(main_task_runner), |
82 decode_task_runner_(decode_task_runner), | 151 decode_task_runner_(decode_task_runner), |
83 consumer_(consumer), | 152 consumer_(consumer), |
84 paint_scheduled_(false), | 153 paint_scheduled_(false), |
85 latest_sequence_number_(0) { | 154 latest_sequence_number_(0) { |
86 } | 155 } |
87 | 156 |
88 RectangleUpdateDecoder::~RectangleUpdateDecoder() { | 157 RectangleUpdateDecoder::Core::~Core() { |
89 } | 158 } |
90 | 159 |
91 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { | 160 void RectangleUpdateDecoder::Core::Initialize(const SessionConfig& config) { |
92 if (!decode_task_runner_->BelongsToCurrentThread()) { | 161 if (!decode_task_runner_->BelongsToCurrentThread()) { |
Wez
2014/01/14 16:23:14
Since RUD runs on main thread and RUD::Core on dec
Sergey Ulanov
2014/01/15 00:58:17
Done.
| |
93 decode_task_runner_->PostTask( | 162 decode_task_runner_->PostTask( |
94 FROM_HERE, base::Bind(&RectangleUpdateDecoder::Initialize, this, | 163 FROM_HERE, base::Bind(&RectangleUpdateDecoder::Core::Initialize, this, |
95 config)); | 164 config)); |
96 return; | 165 return; |
97 } | 166 } |
98 | 167 |
99 // Initialize decoder based on the selected codec. | 168 // Initialize decoder based on the selected codec. |
100 ChannelConfig::Codec codec = config.video_config().codec; | 169 ChannelConfig::Codec codec = config.video_config().codec; |
101 if (codec == ChannelConfig::CODEC_VERBATIM) { | 170 if (codec == ChannelConfig::CODEC_VERBATIM) { |
102 decoder_.reset(new VideoDecoderVerbatim()); | 171 decoder_.reset(new VideoDecoderVerbatim()); |
103 } else if (codec == ChannelConfig::CODEC_VP8) { | 172 } else if (codec == ChannelConfig::CODEC_VP8) { |
104 decoder_ = VideoDecoderVpx::CreateForVP8(); | 173 decoder_ = VideoDecoderVpx::CreateForVP8(); |
105 } else if (codec == ChannelConfig::CODEC_VP9) { | 174 } else if (codec == ChannelConfig::CODEC_VP9) { |
106 decoder_ = VideoDecoderVpx::CreateForVP9(); | 175 decoder_ = VideoDecoderVpx::CreateForVP9(); |
107 } else { | 176 } else { |
108 NOTREACHED() << "Invalid Encoding found: " << codec; | 177 NOTREACHED() << "Invalid Encoding found: " << codec; |
109 } | 178 } |
110 | 179 |
111 if (consumer_->GetPixelFormat() == FrameConsumer::FORMAT_RGBA) { | 180 if (consumer_->GetPixelFormat() == FrameConsumer::FORMAT_RGBA) { |
112 scoped_ptr<VideoDecoder> wrapper( | 181 scoped_ptr<VideoDecoder> wrapper( |
113 new RgbToBgrVideoDecoderFilter(decoder_.Pass())); | 182 new RgbToBgrVideoDecoderFilter(decoder_.Pass())); |
114 decoder_ = wrapper.Pass(); | 183 decoder_ = wrapper.Pass(); |
115 } | 184 } |
116 } | 185 } |
117 | 186 |
118 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, | 187 void RectangleUpdateDecoder::Core::DecodePacket(scoped_ptr<VideoPacket> packet, |
119 const base::Closure& done) { | 188 const base::Closure& done) { |
120 DCHECK(decode_task_runner_->BelongsToCurrentThread()); | 189 DCHECK(decode_task_runner_->BelongsToCurrentThread()); |
121 | 190 |
122 base::ScopedClosureRunner done_runner(done); | 191 base::ScopedClosureRunner done_runner(done); |
123 | 192 |
124 bool decoder_needs_reset = false; | 193 bool decoder_needs_reset = false; |
125 bool notify_size_or_dpi_change = false; | 194 bool notify_size_or_dpi_change = false; |
126 | 195 |
127 // If the packet includes screen size or DPI information, store them. | 196 // If the packet includes screen size or DPI information, store them. |
128 if (packet->format().has_screen_width() && | 197 if (packet->format().has_screen_width() && |
(...skipping 24 matching lines...) Expand all Loading... | |
153 if (notify_size_or_dpi_change) | 222 if (notify_size_or_dpi_change) |
154 consumer_->SetSourceSize(source_size_, source_dpi_); | 223 consumer_->SetSourceSize(source_size_, source_dpi_); |
155 | 224 |
156 if (decoder_->DecodePacket(*packet.get())) { | 225 if (decoder_->DecodePacket(*packet.get())) { |
157 SchedulePaint(); | 226 SchedulePaint(); |
158 } else { | 227 } else { |
159 LOG(ERROR) << "DecodePacket() failed."; | 228 LOG(ERROR) << "DecodePacket() failed."; |
160 } | 229 } |
161 } | 230 } |
162 | 231 |
163 void RectangleUpdateDecoder::SchedulePaint() { | 232 void RectangleUpdateDecoder::Core::SchedulePaint() { |
164 if (paint_scheduled_) | 233 if (paint_scheduled_) |
165 return; | 234 return; |
166 paint_scheduled_ = true; | 235 paint_scheduled_ = true; |
167 decode_task_runner_->PostTask( | 236 decode_task_runner_->PostTask( |
168 FROM_HERE, base::Bind(&RectangleUpdateDecoder::DoPaint, this)); | 237 FROM_HERE, base::Bind(&RectangleUpdateDecoder::Core::DoPaint, this)); |
169 } | 238 } |
170 | 239 |
171 void RectangleUpdateDecoder::DoPaint() { | 240 void RectangleUpdateDecoder::Core::DoPaint() { |
172 DCHECK(paint_scheduled_); | 241 DCHECK(paint_scheduled_); |
173 paint_scheduled_ = false; | 242 paint_scheduled_ = false; |
174 | 243 |
175 // If the view size is empty or we have no output buffers ready, return. | 244 // If the view size is empty or we have no output buffers ready, return. |
176 if (buffers_.empty() || view_size_.is_empty()) | 245 if (buffers_.empty() || view_size_.is_empty()) |
177 return; | 246 return; |
178 | 247 |
179 // If no Decoder is initialized, or the host dimensions are empty, return. | 248 // If no Decoder is initialized, or the host dimensions are empty, return. |
180 if (!decoder_.get() || source_size_.is_empty()) | 249 if (!decoder_.get() || source_size_.is_empty()) |
181 return; | 250 return; |
182 | 251 |
183 // Draw the invalidated region to the buffer. | 252 // Draw the invalidated region to the buffer. |
184 webrtc::DesktopFrame* buffer = buffers_.front(); | 253 webrtc::DesktopFrame* buffer = buffers_.front(); |
185 webrtc::DesktopRegion output_region; | 254 webrtc::DesktopRegion output_region; |
186 decoder_->RenderFrame(view_size_, clip_area_, | 255 decoder_->RenderFrame(view_size_, clip_area_, |
187 buffer->data(), | 256 buffer->data(), buffer->stride(), &output_region); |
188 buffer->stride(), | |
189 &output_region); | |
190 | 257 |
191 // Notify the consumer that painting is done. | 258 // Notify the consumer that painting is done. |
192 if (!output_region.is_empty()) { | 259 if (!output_region.is_empty()) { |
193 buffers_.pop_front(); | 260 buffers_.pop_front(); |
194 consumer_->ApplyBuffer(view_size_, clip_area_, buffer, output_region); | 261 consumer_->ApplyBuffer(view_size_, clip_area_, buffer, output_region); |
195 } | 262 } |
196 } | 263 } |
197 | 264 |
198 void RectangleUpdateDecoder::RequestReturnBuffers(const base::Closure& done) { | 265 void RectangleUpdateDecoder::Core::RequestReturnBuffers( |
266 const base::Closure& done) { | |
199 if (!decode_task_runner_->BelongsToCurrentThread()) { | 267 if (!decode_task_runner_->BelongsToCurrentThread()) { |
200 decode_task_runner_->PostTask( | 268 decode_task_runner_->PostTask( |
201 FROM_HERE, base::Bind(&RectangleUpdateDecoder::RequestReturnBuffers, | 269 FROM_HERE, base::Bind( |
202 this, done)); | 270 &RectangleUpdateDecoder::Core::RequestReturnBuffers, this, done)); |
203 return; | 271 return; |
204 } | 272 } |
205 | 273 |
206 while (!buffers_.empty()) { | 274 while (!buffers_.empty()) { |
207 consumer_->ReturnBuffer(buffers_.front()); | 275 consumer_->ReturnBuffer(buffers_.front()); |
208 buffers_.pop_front(); | 276 buffers_.pop_front(); |
209 } | 277 } |
210 | 278 |
211 if (!done.is_null()) | 279 if (!done.is_null()) |
212 done.Run(); | 280 done.Run(); |
213 } | 281 } |
214 | 282 |
215 void RectangleUpdateDecoder::DrawBuffer(webrtc::DesktopFrame* buffer) { | 283 void RectangleUpdateDecoder::Core::DrawBuffer(webrtc::DesktopFrame* buffer) { |
216 if (!decode_task_runner_->BelongsToCurrentThread()) { | 284 if (!decode_task_runner_->BelongsToCurrentThread()) { |
217 decode_task_runner_->PostTask( | 285 decode_task_runner_->PostTask( |
218 FROM_HERE, base::Bind(&RectangleUpdateDecoder::DrawBuffer, | 286 FROM_HERE, base::Bind(&RectangleUpdateDecoder::Core::DrawBuffer, |
219 this, buffer)); | 287 this, buffer)); |
220 return; | 288 return; |
221 } | 289 } |
222 | 290 |
223 DCHECK(clip_area_.width() <= buffer->size().width() && | 291 DCHECK(clip_area_.width() <= buffer->size().width() && |
224 clip_area_.height() <= buffer->size().height()); | 292 clip_area_.height() <= buffer->size().height()); |
225 | 293 |
226 buffers_.push_back(buffer); | 294 buffers_.push_back(buffer); |
227 SchedulePaint(); | 295 SchedulePaint(); |
228 } | 296 } |
229 | 297 |
230 void RectangleUpdateDecoder::InvalidateRegion( | 298 void RectangleUpdateDecoder::Core::InvalidateRegion( |
231 const webrtc::DesktopRegion& region) { | 299 const webrtc::DesktopRegion& region) { |
232 if (!decode_task_runner_->BelongsToCurrentThread()) { | 300 if (!decode_task_runner_->BelongsToCurrentThread()) { |
233 decode_task_runner_->PostTask( | 301 decode_task_runner_->PostTask( |
234 FROM_HERE, base::Bind(&RectangleUpdateDecoder::InvalidateRegion, | 302 FROM_HERE, base::Bind(&RectangleUpdateDecoder::Core::InvalidateRegion, |
235 this, region)); | 303 this, region)); |
236 return; | 304 return; |
237 } | 305 } |
238 | 306 |
239 if (decoder_.get()) { | 307 if (decoder_.get()) { |
240 decoder_->Invalidate(view_size_, region); | 308 decoder_->Invalidate(view_size_, region); |
241 SchedulePaint(); | 309 SchedulePaint(); |
242 } | 310 } |
243 } | 311 } |
244 | 312 |
245 void RectangleUpdateDecoder::SetOutputSizeAndClip( | 313 void RectangleUpdateDecoder::Core::SetOutputSizeAndClip( |
246 const webrtc::DesktopSize& view_size, | 314 const webrtc::DesktopSize& view_size, |
247 const webrtc::DesktopRect& clip_area) { | 315 const webrtc::DesktopRect& clip_area) { |
248 if (!decode_task_runner_->BelongsToCurrentThread()) { | 316 if (!decode_task_runner_->BelongsToCurrentThread()) { |
249 decode_task_runner_->PostTask( | 317 decode_task_runner_->PostTask( |
250 FROM_HERE, base::Bind(&RectangleUpdateDecoder::SetOutputSizeAndClip, | 318 FROM_HERE, |
251 this, view_size, clip_area)); | 319 base::Bind(&RectangleUpdateDecoder::Core::SetOutputSizeAndClip, |
320 this, view_size, clip_area)); | |
252 return; | 321 return; |
253 } | 322 } |
254 | 323 |
255 // The whole frame needs to be repainted if the scaling factor has changed. | 324 // The whole frame needs to be repainted if the scaling factor has changed. |
256 if (!view_size_.equals(view_size) && decoder_.get()) { | 325 if (!view_size_.equals(view_size) && decoder_.get()) { |
257 webrtc::DesktopRegion region; | 326 webrtc::DesktopRegion region; |
258 region.AddRect(webrtc::DesktopRect::MakeSize(view_size)); | 327 region.AddRect(webrtc::DesktopRect::MakeSize(view_size)); |
259 decoder_->Invalidate(view_size, region); | 328 decoder_->Invalidate(view_size, region); |
260 } | 329 } |
261 | 330 |
(...skipping 12 matching lines...) Expand all Loading... | |
274 i = buffers_.erase(i); | 343 i = buffers_.erase(i); |
275 } else { | 344 } else { |
276 ++i; | 345 ++i; |
277 } | 346 } |
278 } | 347 } |
279 | 348 |
280 SchedulePaint(); | 349 SchedulePaint(); |
281 } | 350 } |
282 } | 351 } |
283 | 352 |
284 const webrtc::DesktopRegion* RectangleUpdateDecoder::GetBufferShape() { | 353 const webrtc::DesktopRegion* RectangleUpdateDecoder::Core::GetBufferShape() { |
285 return decoder_->GetImageShape(); | 354 return decoder_->GetImageShape(); |
286 } | 355 } |
287 | 356 |
288 void RectangleUpdateDecoder::ProcessVideoPacket(scoped_ptr<VideoPacket> packet, | 357 void RectangleUpdateDecoder::Core::ProcessVideoPacket( |
289 const base::Closure& done) { | 358 scoped_ptr<VideoPacket> packet, |
359 const base::Closure& done) { | |
290 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 360 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
291 | 361 |
292 // If the video packet is empty then drop it. Empty packets are used to | 362 // If the video packet is empty then drop it. Empty packets are used to |
293 // maintain activity on the network. | 363 // maintain activity on the network. |
294 if (!packet->has_data() || packet->data().size() == 0) { | 364 if (!packet->has_data() || packet->data().size() == 0) { |
295 done.Run(); | 365 done.Run(); |
296 return; | 366 return; |
297 } | 367 } |
298 | 368 |
299 // Add one frame to the counter. | 369 // Add one frame to the counter. |
(...skipping 11 matching lines...) Expand all Loading... | |
311 base::TimeDelta round_trip_latency = | 381 base::TimeDelta round_trip_latency = |
312 base::Time::Now() - | 382 base::Time::Now() - |
313 base::Time::FromInternalValue(packet->client_sequence_number()); | 383 base::Time::FromInternalValue(packet->client_sequence_number()); |
314 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds()); | 384 stats_.round_trip_ms()->Record(round_trip_latency.InMilliseconds()); |
315 } | 385 } |
316 | 386 |
317 // Measure the latency between the last packet being received and presented. | 387 // Measure the latency between the last packet being received and presented. |
318 base::Time decode_start = base::Time::Now(); | 388 base::Time decode_start = base::Time::Now(); |
319 | 389 |
320 base::Closure decode_done = base::Bind( | 390 base::Closure decode_done = base::Bind( |
321 &RectangleUpdateDecoder::OnPacketDone, this, decode_start, done); | 391 &RectangleUpdateDecoder::Core::OnPacketDone, this, decode_start, done); |
Wez
2014/01/14 16:23:14
You can put all this code in RectangleUpdateDecode
Sergey Ulanov
2014/01/15 00:58:17
Done.
| |
322 | 392 |
323 decode_task_runner_->PostTask(FROM_HERE, base::Bind( | 393 decode_task_runner_->PostTask(FROM_HERE, base::Bind( |
324 &RectangleUpdateDecoder::DecodePacket, this, | 394 &RectangleUpdateDecoder::Core::DecodePacket, this, |
325 base::Passed(&packet), decode_done)); | 395 base::Passed(&packet), decode_done)); |
326 } | 396 } |
327 | 397 |
328 void RectangleUpdateDecoder::OnPacketDone(base::Time decode_start, | 398 void RectangleUpdateDecoder::Core::OnPacketDone(base::Time decode_start, |
329 const base::Closure& done) { | 399 const base::Closure& done) { |
330 if (!main_task_runner_->BelongsToCurrentThread()) { | 400 if (!main_task_runner_->BelongsToCurrentThread()) { |
Wez
2014/01/14 16:23:14
Since this method just thread-hops back to |main_t
Sergey Ulanov
2014/01/15 00:58:17
Done.
| |
331 main_task_runner_->PostTask(FROM_HERE, base::Bind( | 401 main_task_runner_->PostTask(FROM_HERE, base::Bind( |
332 &RectangleUpdateDecoder::OnPacketDone, this, | 402 &RectangleUpdateDecoder::Core::OnPacketDone, this, |
333 decode_start, done)); | 403 decode_start, done)); |
334 return; | 404 return; |
335 } | 405 } |
336 | 406 |
337 // Record the latency between the packet being received and presented. | 407 // Record the latency between the packet being received and presented. |
338 stats_.video_decode_ms()->Record( | 408 stats_.video_decode_ms()->Record( |
339 (base::Time::Now() - decode_start).InMilliseconds()); | 409 (base::Time::Now() - decode_start).InMilliseconds()); |
340 | 410 |
341 done.Run(); | 411 done.Run(); |
342 } | 412 } |
343 | 413 |
344 ChromotingStats* RectangleUpdateDecoder::GetStats() { | 414 ChromotingStats* RectangleUpdateDecoder::Core::GetStats() { |
345 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 415 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
346 return &stats_; | 416 return &stats_; |
347 } | 417 } |
348 | 418 |
419 RectangleUpdateDecoder::RectangleUpdateDecoder( | |
420 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
421 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, | |
422 scoped_refptr<FrameConsumerProxy> consumer) | |
423 : core_(new Core(main_task_runner, decode_task_runner, consumer)) { | |
424 } | |
425 | |
426 void RectangleUpdateDecoder::Initialize(const protocol::SessionConfig& config) { | |
427 core_->Initialize(config); | |
428 } | |
429 | |
430 ChromotingStats* RectangleUpdateDecoder::GetStats() { | |
431 return core_->GetStats(); | |
432 } | |
433 | |
434 void RectangleUpdateDecoder::ProcessVideoPacket(scoped_ptr<VideoPacket> packet, | |
435 const base::Closure& done) { | |
436 core_->ProcessVideoPacket(packet.Pass(), done); | |
Wez
2014/01/14 16:23:14
As with Initialize, where we're just proxying call
Sergey Ulanov
2014/01/15 00:58:17
Done.
| |
437 } | |
438 | |
439 void RectangleUpdateDecoder::DrawBuffer(webrtc::DesktopFrame* buffer) { | |
440 core_->DrawBuffer(buffer); | |
441 } | |
442 | |
443 void RectangleUpdateDecoder::InvalidateRegion( | |
444 const webrtc::DesktopRegion& region) { | |
445 core_->InvalidateRegion(region); | |
446 } | |
447 | |
448 void RectangleUpdateDecoder::RequestReturnBuffers(const base::Closure& done) { | |
449 core_->RequestReturnBuffers(done); | |
450 } | |
451 | |
452 void RectangleUpdateDecoder::SetOutputSizeAndClip( | |
453 const webrtc::DesktopSize& view_size, | |
454 const webrtc::DesktopRect& clip_area) { | |
455 core_->SetOutputSizeAndClip(view_size, clip_area); | |
456 } | |
457 | |
458 const webrtc::DesktopRegion* RectangleUpdateDecoder::GetBufferShape() { | |
459 return core_->GetBufferShape(); | |
460 } | |
461 | |
462 | |
349 } // namespace remoting | 463 } // namespace remoting |
OLD | NEW |