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

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: Narrow the synchronization block 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
« no previous file with comments | « remoting/client/plugin/pepper_view.h ('k') | remoting/client/rectangle_update_decoder.cc » ('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) 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();
87 85
88 merge_buffer_ = NULL; 86 merge_buffer_ = NULL;
89 while (!buffers_.empty()) { 87 while (!buffers_.empty()) {
90 FreeBuffer(buffers_.front()); 88 FreeBuffer(buffers_.front());
91 } 89 }
92 } 90 }
93 91
92 void PepperView::Initialize(FrameProducer* producer) {
93 producer_ = producer;
94 webrtc::DesktopFrame* buffer = AllocateBuffer();
95 while (buffer) {
96 producer_->DrawBuffer(buffer);
97 buffer = AllocateBuffer();
98 }
99 }
100
94 void PepperView::SetView(const pp::View& view) { 101 void PepperView::SetView(const pp::View& view) {
95 bool view_changed = false; 102 bool view_changed = false;
96 103
97 pp::Rect pp_size = view.GetRect(); 104 pp::Rect pp_size = view.GetRect();
98 webrtc::DesktopSize new_dips_size(pp_size.width(), pp_size.height()); 105 webrtc::DesktopSize new_dips_size(pp_size.width(), pp_size.height());
99 float new_dips_to_device_scale = view.GetDeviceScale(); 106 float new_dips_to_device_scale = view.GetDeviceScale();
100 107
101 if (!dips_size_.equals(new_dips_size) || 108 if (!dips_size_.equals(new_dips_size) ||
102 dips_to_device_scale_ != new_dips_to_device_scale) { 109 dips_to_device_scale_ != new_dips_to_device_scale) {
103 view_changed = true; 110 view_changed = true;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 view_changed = true; 150 view_changed = true;
144 151
145 // YUV to RGB conversion may require even X and Y coordinates for 152 // YUV to RGB conversion may require even X and Y coordinates for
146 // the top left corner of the clipping area. 153 // the top left corner of the clipping area.
147 clip_area_ = AlignRect(new_clip); 154 clip_area_ = AlignRect(new_clip);
148 clip_area_.IntersectWith(webrtc::DesktopRect::MakeSize(view_size_)); 155 clip_area_.IntersectWith(webrtc::DesktopRect::MakeSize(view_size_));
149 } 156 }
150 157
151 if (view_changed) { 158 if (view_changed) {
152 producer_->SetOutputSizeAndClip(view_size_, clip_area_); 159 producer_->SetOutputSizeAndClip(view_size_, clip_area_);
153 InitiateDrawing(); 160 Initialize(producer_);
154 } 161 }
155 } 162 }
156 163
157 void PepperView::ApplyBuffer(const webrtc::DesktopSize& view_size, 164 void PepperView::ApplyBuffer(const webrtc::DesktopSize& view_size,
158 const webrtc::DesktopRect& clip_area, 165 const webrtc::DesktopRect& clip_area,
159 webrtc::DesktopFrame* buffer, 166 webrtc::DesktopFrame* buffer,
160 const webrtc::DesktopRegion& region) { 167 const webrtc::DesktopRegion& region) {
161 DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); 168 DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
162 169
163 if (!frame_received_) { 170 if (!frame_received_) {
164 instance_->OnFirstFrameReceived(); 171 instance_->OnFirstFrameReceived();
165 frame_received_ = true; 172 frame_received_ = true;
166 } 173 }
167 // We cannot use the data in the buffer if its dimensions don't match the 174 // We cannot use the data in the buffer if its dimensions don't match the
168 // current view size. 175 // current view size.
169 // TODO(alexeypa): We could rescale and draw it (or even draw it without 176 // 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 177 // rescaling) to reduce the perceived lag while we are waiting for
171 // the properly scaled data. 178 // the properly scaled data.
172 if (!view_size_.equals(view_size)) { 179 if (!view_size_.equals(view_size)) {
173 FreeBuffer(buffer); 180 FreeBuffer(buffer);
174 InitiateDrawing(); 181 Initialize(producer_);
175 } else { 182 } else {
176 FlushBuffer(clip_area, buffer, region); 183 FlushBuffer(clip_area, buffer, region);
177 } 184 }
178 } 185 }
179 186
180 void PepperView::ReturnBuffer(webrtc::DesktopFrame* buffer) { 187 void PepperView::ReturnBuffer(webrtc::DesktopFrame* buffer) {
181 DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); 188 DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
182 189
183 // Reuse the buffer if it is large enough, otherwise drop it on the floor 190 // Reuse the buffer if it is large enough, otherwise drop it on the floor
184 // and allocate a new one. 191 // and allocate a new one.
185 if (buffer->size().width() >= clip_area_.width() && 192 if (buffer->size().width() >= clip_area_.width() &&
186 buffer->size().height() >= clip_area_.height()) { 193 buffer->size().height() >= clip_area_.height()) {
187 producer_->DrawBuffer(buffer); 194 producer_->DrawBuffer(buffer);
188 } else { 195 } else {
189 FreeBuffer(buffer); 196 FreeBuffer(buffer);
190 InitiateDrawing(); 197 Initialize(producer_);
191 } 198 }
192 } 199 }
193 200
194 void PepperView::SetSourceSize(const webrtc::DesktopSize& source_size, 201 void PepperView::SetSourceSize(const webrtc::DesktopSize& source_size,
195 const webrtc::DesktopVector& source_dpi) { 202 const webrtc::DesktopVector& source_dpi) {
196 DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); 203 DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
197 204
198 if (source_size_.equals(source_size) && source_dpi_.equals(source_dpi)) 205 if (source_size_.equals(source_size) && source_dpi_.equals(source_dpi))
199 return; 206 return;
200 207
201 source_size_ = source_size; 208 source_size_ = source_size;
202 source_dpi_ = source_dpi; 209 source_dpi_ = source_dpi;
203 210
204 // Notify JavaScript of the change in source size. 211 // Notify JavaScript of the change in source size.
205 instance_->SetDesktopSize(source_size, source_dpi); 212 instance_->SetDesktopSize(source_size, source_dpi);
206 } 213 }
207 214
215 FrameConsumer::PixelFormat PepperView::GetPixelFormat() {
216 return FORMAT_BGRA;
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
« no previous file with comments | « remoting/client/plugin/pepper_view.h ('k') | remoting/client/rectangle_update_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698