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

Side by Side Diff: remoting/client/plugin/pepper_view.cc

Issue 23677011: Byte-swap the video frame pixels before passing them to Java. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove FrameConsumerProxy::Attach Created 7 years, 2 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
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/plugin/pepper_view.h" 5 #include "remoting/client/plugin/pepper_view.h"
6 6
7 #include <functional> 7 #include <functional>
8 8
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 namespace remoting { 54 namespace remoting {
55 55
56 namespace { 56 namespace {
57 57
58 // The maximum number of image buffers to be allocated at any point of time. 58 // The maximum number of image buffers to be allocated at any point of time.
59 const size_t kMaxPendingBuffersCount = 2; 59 const size_t kMaxPendingBuffersCount = 2;
60 60
61 } // namespace 61 } // namespace
62 62
63 PepperView::PepperView(ChromotingInstance* instance, 63 PepperView::PepperView(ChromotingInstance* instance,
64 ClientContext* context, 64 ClientContext* context)
65 FrameProducer* producer)
66 : instance_(instance), 65 : instance_(instance),
67 context_(context), 66 context_(context),
68 producer_(producer), 67 producer_(NULL),
69 merge_buffer_(NULL), 68 merge_buffer_(NULL),
70 dips_to_device_scale_(1.0f), 69 dips_to_device_scale_(1.0f),
71 dips_to_view_scale_(1.0f), 70 dips_to_view_scale_(1.0f),
72 flush_pending_(false), 71 flush_pending_(false),
73 is_initialized_(false), 72 is_initialized_(false),
74 frame_received_(false), 73 frame_received_(false),
75 callback_factory_(this) { 74 callback_factory_(this) {
76 InitiateDrawing();
77 } 75 }
78 76
79 PepperView::~PepperView() { 77 PepperView::~PepperView() {
80 // The producer should now return any pending buffers. At this point, however, 78 // The producer should now return any pending buffers. At this point, however,
81 // ReturnBuffer() tasks scheduled by the producer will not be delivered, 79 // ReturnBuffer() tasks scheduled by the producer will not be delivered,
82 // so we free all the buffers once the producer's queue is empty. 80 // so we free all the buffers once the producer's queue is empty.
83 base::WaitableEvent done_event(true, false); 81 base::WaitableEvent done_event(true, false);
84 producer_->RequestReturnBuffers( 82 producer_->RequestReturnBuffers(
85 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done_event))); 83 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done_event)));
86 done_event.Wait(); 84 done_event.Wait();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 view_changed = true; 141 view_changed = true;
144 142
145 // YUV to RGB conversion may require even X and Y coordinates for 143 // YUV to RGB conversion may require even X and Y coordinates for
146 // the top left corner of the clipping area. 144 // the top left corner of the clipping area.
147 clip_area_ = AlignRect(new_clip); 145 clip_area_ = AlignRect(new_clip);
148 clip_area_.IntersectWith(webrtc::DesktopRect::MakeSize(view_size_)); 146 clip_area_.IntersectWith(webrtc::DesktopRect::MakeSize(view_size_));
149 } 147 }
150 148
151 if (view_changed) { 149 if (view_changed) {
152 producer_->SetOutputSizeAndClip(view_size_, clip_area_); 150 producer_->SetOutputSizeAndClip(view_size_, clip_area_);
153 InitiateDrawing(); 151 InitiateDrawing(producer_);
154 } 152 }
155 } 153 }
156 154
157 void PepperView::ApplyBuffer(const webrtc::DesktopSize& view_size, 155 void PepperView::ApplyBuffer(const webrtc::DesktopSize& view_size,
158 const webrtc::DesktopRect& clip_area, 156 const webrtc::DesktopRect& clip_area,
159 webrtc::DesktopFrame* buffer, 157 webrtc::DesktopFrame* buffer,
160 const webrtc::DesktopRegion& region) { 158 const webrtc::DesktopRegion& region) {
161 DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); 159 DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
162 160
163 if (!frame_received_) { 161 if (!frame_received_) {
164 instance_->OnFirstFrameReceived(); 162 instance_->OnFirstFrameReceived();
165 frame_received_ = true; 163 frame_received_ = true;
166 } 164 }
167 // We cannot use the data in the buffer if its dimensions don't match the 165 // We cannot use the data in the buffer if its dimensions don't match the
168 // current view size. 166 // current view size.
169 // TODO(alexeypa): We could rescale and draw it (or even draw it without 167 // TODO(alexeypa): We could rescale and draw it (or even draw it without
170 // rescaling) to reduce the perceived lag while we are waiting for 168 // rescaling) to reduce the perceived lag while we are waiting for
171 // the properly scaled data. 169 // the properly scaled data.
172 if (!view_size_.equals(view_size)) { 170 if (!view_size_.equals(view_size)) {
173 FreeBuffer(buffer); 171 FreeBuffer(buffer);
174 InitiateDrawing(); 172 InitiateDrawing(producer_);
175 } else { 173 } else {
176 FlushBuffer(clip_area, buffer, region); 174 FlushBuffer(clip_area, buffer, region);
177 } 175 }
178 } 176 }
179 177
180 void PepperView::ReturnBuffer(webrtc::DesktopFrame* buffer) { 178 void PepperView::ReturnBuffer(webrtc::DesktopFrame* buffer) {
181 DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); 179 DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
182 180
183 // Reuse the buffer if it is large enough, otherwise drop it on the floor 181 // Reuse the buffer if it is large enough, otherwise drop it on the floor
184 // and allocate a new one. 182 // and allocate a new one.
185 if (buffer->size().width() >= clip_area_.width() && 183 if (buffer->size().width() >= clip_area_.width() &&
186 buffer->size().height() >= clip_area_.height()) { 184 buffer->size().height() >= clip_area_.height()) {
187 producer_->DrawBuffer(buffer); 185 producer_->DrawBuffer(buffer);
188 } else { 186 } else {
189 FreeBuffer(buffer); 187 FreeBuffer(buffer);
190 InitiateDrawing(); 188 InitiateDrawing(producer_);
191 } 189 }
192 } 190 }
193 191
194 void PepperView::SetSourceSize(const webrtc::DesktopSize& source_size, 192 void PepperView::SetSourceSize(const webrtc::DesktopSize& source_size,
195 const webrtc::DesktopVector& source_dpi) { 193 const webrtc::DesktopVector& source_dpi) {
196 DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); 194 DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
197 195
198 if (source_size_.equals(source_size) && source_dpi_.equals(source_dpi)) 196 if (source_size_.equals(source_size) && source_dpi_.equals(source_dpi))
199 return; 197 return;
200 198
201 source_size_ = source_size; 199 source_size_ = source_size;
202 source_dpi_ = source_dpi; 200 source_dpi_ = source_dpi;
203 201
204 // Notify JavaScript of the change in source size. 202 // Notify JavaScript of the change in source size.
205 instance_->SetDesktopSize(source_size, source_dpi); 203 instance_->SetDesktopSize(source_size, source_dpi);
206 } 204 }
207 205
206 FrameConsumer::PixelFormat PepperView::GetPixelFormat() {
207 return FORMAT_BGRA;
208 }
209
210 void PepperView::InitiateDrawing(FrameProducer* producer) {
211 producer_ = producer;
212 webrtc::DesktopFrame* buffer = AllocateBuffer();
213 while (buffer) {
214 producer_->DrawBuffer(buffer);
215 buffer = AllocateBuffer();
216 }
217 }
218
208 webrtc::DesktopFrame* PepperView::AllocateBuffer() { 219 webrtc::DesktopFrame* PepperView::AllocateBuffer() {
209 if (buffers_.size() >= kMaxPendingBuffersCount) 220 if (buffers_.size() >= kMaxPendingBuffersCount)
210 return NULL; 221 return NULL;
211 222
212 if (clip_area_.width()==0 || clip_area_.height()==0) 223 if (clip_area_.width()==0 || clip_area_.height()==0)
213 return NULL; 224 return NULL;
214 225
215 // Create an image buffer of the required size, but don't zero it. 226 // Create an image buffer of the required size, but don't zero it.
216 pp::ImageData buffer_data(instance_, 227 pp::ImageData buffer_data(instance_,
217 PP_IMAGEDATAFORMAT_BGRA_PREMUL, 228 PP_IMAGEDATAFORMAT_BGRA_PREMUL,
(...skipping 10 matching lines...) Expand all
228 return buffer; 239 return buffer;
229 } 240 }
230 241
231 void PepperView::FreeBuffer(webrtc::DesktopFrame* buffer) { 242 void PepperView::FreeBuffer(webrtc::DesktopFrame* buffer) {
232 DCHECK(std::find(buffers_.begin(), buffers_.end(), buffer) != buffers_.end()); 243 DCHECK(std::find(buffers_.begin(), buffers_.end(), buffer) != buffers_.end());
233 244
234 buffers_.remove(buffer); 245 buffers_.remove(buffer);
235 delete buffer; 246 delete buffer;
236 } 247 }
237 248
238 void PepperView::InitiateDrawing() {
239 webrtc::DesktopFrame* buffer = AllocateBuffer();
240 while (buffer) {
241 producer_->DrawBuffer(buffer);
242 buffer = AllocateBuffer();
243 }
244 }
245
246 void PepperView::FlushBuffer(const webrtc::DesktopRect& clip_area, 249 void PepperView::FlushBuffer(const webrtc::DesktopRect& clip_area,
247 webrtc::DesktopFrame* buffer, 250 webrtc::DesktopFrame* buffer,
248 const webrtc::DesktopRegion& region) { 251 const webrtc::DesktopRegion& region) {
249 // Defer drawing if the flush is already in progress. 252 // Defer drawing if the flush is already in progress.
250 if (flush_pending_) { 253 if (flush_pending_) {
251 // |merge_buffer_| is guaranteed to be free here because we allocate only 254 // |merge_buffer_| is guaranteed to be free here because we allocate only
252 // two buffers simultaneously. If more buffers are allowed this code should 255 // two buffers simultaneously. If more buffers are allowed this code should
253 // apply all pending changes to the screen. 256 // apply all pending changes to the screen.
254 DCHECK(merge_buffer_ == NULL); 257 DCHECK(merge_buffer_ == NULL);
255 258
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 324
322 // If there is a buffer queued for rendering then render it now. 325 // If there is a buffer queued for rendering then render it now.
323 if (merge_buffer_ != NULL) { 326 if (merge_buffer_ != NULL) {
324 buffer = merge_buffer_; 327 buffer = merge_buffer_;
325 merge_buffer_ = NULL; 328 merge_buffer_ = NULL;
326 FlushBuffer(merge_clip_area_, buffer, merge_region_); 329 FlushBuffer(merge_clip_area_, buffer, merge_region_);
327 } 330 }
328 } 331 }
329 332
330 } // namespace remoting 333 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698