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 "content/browser/media/capture/web_contents_video_capture_device.h" | 5 #include "content/browser/media/capture/web_contents_video_capture_device.h" |
6 | 6 |
7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
8 #include "base/debug/debugger.h" | 8 #include "base/debug/debugger.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 class CaptureTestView : public TestRenderWidgetHostView { | 159 class CaptureTestView : public TestRenderWidgetHostView { |
160 public: | 160 public: |
161 explicit CaptureTestView(RenderWidgetHostImpl* rwh, | 161 explicit CaptureTestView(RenderWidgetHostImpl* rwh, |
162 CaptureTestSourceController* controller) | 162 CaptureTestSourceController* controller) |
163 : TestRenderWidgetHostView(rwh), | 163 : TestRenderWidgetHostView(rwh), |
164 controller_(controller) {} | 164 controller_(controller) {} |
165 | 165 |
166 virtual ~CaptureTestView() {} | 166 virtual ~CaptureTestView() {} |
167 | 167 |
168 // TestRenderWidgetHostView overrides. | 168 // TestRenderWidgetHostView overrides. |
169 virtual gfx::Rect GetViewBounds() const OVERRIDE { | 169 virtual gfx::Rect GetViewBounds() const override { |
170 return gfx::Rect(100, 100, 100 + kTestWidth, 100 + kTestHeight); | 170 return gfx::Rect(100, 100, 100 + kTestWidth, 100 + kTestHeight); |
171 } | 171 } |
172 | 172 |
173 virtual bool CanCopyToVideoFrame() const OVERRIDE { | 173 virtual bool CanCopyToVideoFrame() const override { |
174 return controller_->CanCopyToVideoFrame(); | 174 return controller_->CanCopyToVideoFrame(); |
175 } | 175 } |
176 | 176 |
177 virtual void CopyFromCompositingSurfaceToVideoFrame( | 177 virtual void CopyFromCompositingSurfaceToVideoFrame( |
178 const gfx::Rect& src_subrect, | 178 const gfx::Rect& src_subrect, |
179 const scoped_refptr<media::VideoFrame>& target, | 179 const scoped_refptr<media::VideoFrame>& target, |
180 const base::Callback<void(bool)>& callback) OVERRIDE { | 180 const base::Callback<void(bool)>& callback) override { |
181 SkColor c = ConvertRgbToYuv(controller_->GetSolidColor()); | 181 SkColor c = ConvertRgbToYuv(controller_->GetSolidColor()); |
182 media::FillYUV( | 182 media::FillYUV( |
183 target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); | 183 target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); |
184 callback.Run(true); | 184 callback.Run(true); |
185 controller_->SignalCopy(); | 185 controller_->SignalCopy(); |
186 } | 186 } |
187 | 187 |
188 virtual void BeginFrameSubscription( | 188 virtual void BeginFrameSubscription( |
189 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) OVERRIDE { | 189 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override { |
190 subscriber_.reset(subscriber.release()); | 190 subscriber_.reset(subscriber.release()); |
191 } | 191 } |
192 | 192 |
193 virtual void EndFrameSubscription() OVERRIDE { | 193 virtual void EndFrameSubscription() override { |
194 subscriber_.reset(); | 194 subscriber_.reset(); |
195 } | 195 } |
196 | 196 |
197 // Simulate a compositor paint event for our subscriber. | 197 // Simulate a compositor paint event for our subscriber. |
198 void SimulateUpdate() { | 198 void SimulateUpdate() { |
199 const base::TimeTicks present_time = base::TimeTicks::Now(); | 199 const base::TimeTicks present_time = base::TimeTicks::Now(); |
200 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 200 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
201 scoped_refptr<media::VideoFrame> target; | 201 scoped_refptr<media::VideoFrame> target; |
202 if (subscriber_ && subscriber_->ShouldCaptureFrame( | 202 if (subscriber_ && subscriber_->ShouldCaptureFrame( |
203 gfx::Rect(), present_time, &target, &callback)) { | 203 gfx::Rect(), present_time, &target, &callback)) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 RenderWidgetHostView* old_view = GetView(); | 245 RenderWidgetHostView* old_view = GetView(); |
246 SetView(new CaptureTestView(this, controller)); | 246 SetView(new CaptureTestView(this, controller)); |
247 delete old_view; | 247 delete old_view; |
248 } | 248 } |
249 | 249 |
250 // TestRenderViewHost overrides. | 250 // TestRenderViewHost overrides. |
251 virtual void CopyFromBackingStore( | 251 virtual void CopyFromBackingStore( |
252 const gfx::Rect& src_rect, | 252 const gfx::Rect& src_rect, |
253 const gfx::Size& accelerated_dst_size, | 253 const gfx::Size& accelerated_dst_size, |
254 const base::Callback<void(bool, const SkBitmap&)>& callback, | 254 const base::Callback<void(bool, const SkBitmap&)>& callback, |
255 const SkColorType color_type) OVERRIDE { | 255 const SkColorType color_type) override { |
256 gfx::Size size = controller_->GetCopyResultSize(); | 256 gfx::Size size = controller_->GetCopyResultSize(); |
257 SkColor color = controller_->GetSolidColor(); | 257 SkColor color = controller_->GetSolidColor(); |
258 | 258 |
259 // Although it's not necessary, use a PlatformBitmap here (instead of a | 259 // Although it's not necessary, use a PlatformBitmap here (instead of a |
260 // regular SkBitmap) to exercise possible threading issues. | 260 // regular SkBitmap) to exercise possible threading issues. |
261 skia::PlatformBitmap output; | 261 skia::PlatformBitmap output; |
262 EXPECT_TRUE(output.Allocate(size.width(), size.height(), false)); | 262 EXPECT_TRUE(output.Allocate(size.width(), size.height(), false)); |
263 { | 263 { |
264 SkAutoLockPixels locker(output.GetBitmap()); | 264 SkAutoLockPixels locker(output.GetBitmap()); |
265 output.GetBitmap().eraseColor(color); | 265 output.GetBitmap().eraseColor(color); |
(...skipping 24 matching lines...) Expand all Loading... |
290 UnregisterFactory(); | 290 UnregisterFactory(); |
291 } | 291 } |
292 | 292 |
293 // RenderViewHostFactory implementation. | 293 // RenderViewHostFactory implementation. |
294 virtual RenderViewHost* CreateRenderViewHost( | 294 virtual RenderViewHost* CreateRenderViewHost( |
295 SiteInstance* instance, | 295 SiteInstance* instance, |
296 RenderViewHostDelegate* delegate, | 296 RenderViewHostDelegate* delegate, |
297 RenderWidgetHostDelegate* widget_delegate, | 297 RenderWidgetHostDelegate* widget_delegate, |
298 int routing_id, | 298 int routing_id, |
299 int main_frame_routing_id, | 299 int main_frame_routing_id, |
300 bool swapped_out) OVERRIDE { | 300 bool swapped_out) override { |
301 return new CaptureTestRenderViewHost(instance, delegate, widget_delegate, | 301 return new CaptureTestRenderViewHost(instance, delegate, widget_delegate, |
302 routing_id, main_frame_routing_id, | 302 routing_id, main_frame_routing_id, |
303 swapped_out, controller_); | 303 swapped_out, controller_); |
304 } | 304 } |
305 private: | 305 private: |
306 CaptureTestSourceController* controller_; | 306 CaptureTestSourceController* controller_; |
307 | 307 |
308 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); | 308 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); |
309 }; | 309 }; |
310 | 310 |
311 // A stub consumer of captured video frames, which checks the output of | 311 // A stub consumer of captured video frames, which checks the output of |
312 // WebContentsVideoCaptureDevice. | 312 // WebContentsVideoCaptureDevice. |
313 class StubClient : public media::VideoCaptureDevice::Client { | 313 class StubClient : public media::VideoCaptureDevice::Client { |
314 public: | 314 public: |
315 StubClient(const base::Callback<void(SkColor)>& color_callback, | 315 StubClient(const base::Callback<void(SkColor)>& color_callback, |
316 const base::Closure& error_callback) | 316 const base::Closure& error_callback) |
317 : color_callback_(color_callback), | 317 : color_callback_(color_callback), |
318 error_callback_(error_callback) { | 318 error_callback_(error_callback) { |
319 buffer_pool_ = new VideoCaptureBufferPool(2); | 319 buffer_pool_ = new VideoCaptureBufferPool(2); |
320 } | 320 } |
321 virtual ~StubClient() {} | 321 virtual ~StubClient() {} |
322 | 322 |
323 virtual scoped_refptr<media::VideoCaptureDevice::Client::Buffer> | 323 virtual scoped_refptr<media::VideoCaptureDevice::Client::Buffer> |
324 ReserveOutputBuffer(media::VideoFrame::Format format, | 324 ReserveOutputBuffer(media::VideoFrame::Format format, |
325 const gfx::Size& dimensions) OVERRIDE { | 325 const gfx::Size& dimensions) override { |
326 CHECK_EQ(format, media::VideoFrame::I420); | 326 CHECK_EQ(format, media::VideoFrame::I420); |
327 const size_t frame_bytes = | 327 const size_t frame_bytes = |
328 media::VideoFrame::AllocationSize(media::VideoFrame::I420, dimensions); | 328 media::VideoFrame::AllocationSize(media::VideoFrame::I420, dimensions); |
329 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; // Ignored. | 329 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; // Ignored. |
330 int buffer_id = | 330 int buffer_id = |
331 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop); | 331 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop); |
332 if (buffer_id == VideoCaptureBufferPool::kInvalidId) | 332 if (buffer_id == VideoCaptureBufferPool::kInvalidId) |
333 return NULL; | 333 return NULL; |
334 void* data; | 334 void* data; |
335 size_t size; | 335 size_t size; |
336 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); | 336 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); |
337 return scoped_refptr<media::VideoCaptureDevice::Client::Buffer>( | 337 return scoped_refptr<media::VideoCaptureDevice::Client::Buffer>( |
338 new PoolBuffer(buffer_pool_, buffer_id, data, size)); | 338 new PoolBuffer(buffer_pool_, buffer_id, data, size)); |
339 } | 339 } |
340 | 340 |
341 virtual void OnIncomingCapturedData( | 341 virtual void OnIncomingCapturedData( |
342 const uint8* data, | 342 const uint8* data, |
343 int length, | 343 int length, |
344 const media::VideoCaptureFormat& frame_format, | 344 const media::VideoCaptureFormat& frame_format, |
345 int rotation, | 345 int rotation, |
346 base::TimeTicks timestamp) OVERRIDE { | 346 base::TimeTicks timestamp) override { |
347 FAIL(); | 347 FAIL(); |
348 } | 348 } |
349 | 349 |
350 virtual void OnIncomingCapturedVideoFrame( | 350 virtual void OnIncomingCapturedVideoFrame( |
351 const scoped_refptr<Buffer>& buffer, | 351 const scoped_refptr<Buffer>& buffer, |
352 const media::VideoCaptureFormat& buffer_format, | 352 const media::VideoCaptureFormat& buffer_format, |
353 const scoped_refptr<media::VideoFrame>& frame, | 353 const scoped_refptr<media::VideoFrame>& frame, |
354 base::TimeTicks timestamp) OVERRIDE { | 354 base::TimeTicks timestamp) override { |
355 EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), buffer_format.frame_size); | 355 EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), buffer_format.frame_size); |
356 EXPECT_EQ(media::PIXEL_FORMAT_I420, buffer_format.pixel_format); | 356 EXPECT_EQ(media::PIXEL_FORMAT_I420, buffer_format.pixel_format); |
357 EXPECT_EQ(media::VideoFrame::I420, frame->format()); | 357 EXPECT_EQ(media::VideoFrame::I420, frame->format()); |
358 uint8 yuv[3]; | 358 uint8 yuv[3]; |
359 for (int plane = 0; plane < 3; ++plane) | 359 for (int plane = 0; plane < 3; ++plane) |
360 yuv[plane] = frame->data(plane)[0]; | 360 yuv[plane] = frame->data(plane)[0]; |
361 // TODO(nick): We just look at the first pixel presently, because if | 361 // TODO(nick): We just look at the first pixel presently, because if |
362 // the analysis is too slow, the backlog of frames will grow without bound | 362 // the analysis is too slow, the backlog of frames will grow without bound |
363 // and trouble erupts. http://crbug.com/174519 | 363 // and trouble erupts. http://crbug.com/174519 |
364 color_callback_.Run((SkColorSetRGB(yuv[0], yuv[1], yuv[2]))); | 364 color_callback_.Run((SkColorSetRGB(yuv[0], yuv[1], yuv[2]))); |
365 } | 365 } |
366 | 366 |
367 virtual void OnError(const std::string& reason) OVERRIDE { | 367 virtual void OnError(const std::string& reason) override { |
368 error_callback_.Run(); | 368 error_callback_.Run(); |
369 } | 369 } |
370 | 370 |
371 private: | 371 private: |
372 class PoolBuffer : public media::VideoCaptureDevice::Client::Buffer { | 372 class PoolBuffer : public media::VideoCaptureDevice::Client::Buffer { |
373 public: | 373 public: |
374 PoolBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, | 374 PoolBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, |
375 int buffer_id, | 375 int buffer_id, |
376 void* data, | 376 void* data, |
377 size_t size) | 377 size_t size) |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 // A dummy implementation of gfx::Screen, since WebContentsVideoCaptureDevice | 472 // A dummy implementation of gfx::Screen, since WebContentsVideoCaptureDevice |
473 // needs access to a gfx::Display's device scale factor. | 473 // needs access to a gfx::Display's device scale factor. |
474 class FakeScreen : public gfx::Screen { | 474 class FakeScreen : public gfx::Screen { |
475 public: | 475 public: |
476 FakeScreen() : the_one_display_(0x1337, gfx::Rect(0, 0, 2560, 1440)) { | 476 FakeScreen() : the_one_display_(0x1337, gfx::Rect(0, 0, 2560, 1440)) { |
477 the_one_display_.set_device_scale_factor(kTestDeviceScaleFactor); | 477 the_one_display_.set_device_scale_factor(kTestDeviceScaleFactor); |
478 } | 478 } |
479 virtual ~FakeScreen() {} | 479 virtual ~FakeScreen() {} |
480 | 480 |
481 // gfx::Screen implementation (only what's needed for testing). | 481 // gfx::Screen implementation (only what's needed for testing). |
482 virtual bool IsDIPEnabled() OVERRIDE { return true; } | 482 virtual bool IsDIPEnabled() override { return true; } |
483 virtual gfx::Point GetCursorScreenPoint() OVERRIDE { return gfx::Point(); } | 483 virtual gfx::Point GetCursorScreenPoint() override { return gfx::Point(); } |
484 virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE { return NULL; } | 484 virtual gfx::NativeWindow GetWindowUnderCursor() override { return NULL; } |
485 virtual gfx::NativeWindow GetWindowAtScreenPoint( | 485 virtual gfx::NativeWindow GetWindowAtScreenPoint( |
486 const gfx::Point& point) OVERRIDE { return NULL; } | 486 const gfx::Point& point) override { return NULL; } |
487 virtual int GetNumDisplays() const OVERRIDE { return 1; } | 487 virtual int GetNumDisplays() const override { return 1; } |
488 virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE { | 488 virtual std::vector<gfx::Display> GetAllDisplays() const override { |
489 return std::vector<gfx::Display>(1, the_one_display_); | 489 return std::vector<gfx::Display>(1, the_one_display_); |
490 } | 490 } |
491 virtual gfx::Display GetDisplayNearestWindow( | 491 virtual gfx::Display GetDisplayNearestWindow( |
492 gfx::NativeView view) const OVERRIDE { | 492 gfx::NativeView view) const override { |
493 return the_one_display_; | 493 return the_one_display_; |
494 } | 494 } |
495 virtual gfx::Display GetDisplayNearestPoint( | 495 virtual gfx::Display GetDisplayNearestPoint( |
496 const gfx::Point& point) const OVERRIDE { | 496 const gfx::Point& point) const override { |
497 return the_one_display_; | 497 return the_one_display_; |
498 } | 498 } |
499 virtual gfx::Display GetDisplayMatching( | 499 virtual gfx::Display GetDisplayMatching( |
500 const gfx::Rect& match_rect) const OVERRIDE { | 500 const gfx::Rect& match_rect) const override { |
501 return the_one_display_; | 501 return the_one_display_; |
502 } | 502 } |
503 virtual gfx::Display GetPrimaryDisplay() const OVERRIDE { | 503 virtual gfx::Display GetPrimaryDisplay() const override { |
504 return the_one_display_; | 504 return the_one_display_; |
505 } | 505 } |
506 virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE {} | 506 virtual void AddObserver(gfx::DisplayObserver* observer) override {} |
507 virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE {} | 507 virtual void RemoveObserver(gfx::DisplayObserver* observer) override {} |
508 | 508 |
509 private: | 509 private: |
510 gfx::Display the_one_display_; | 510 gfx::Display the_one_display_; |
511 | 511 |
512 DISALLOW_COPY_AND_ASSIGN(FakeScreen); | 512 DISALLOW_COPY_AND_ASSIGN(FakeScreen); |
513 }; | 513 }; |
514 | 514 |
515 // Test harness that sets up a minimal environment with necessary stubs. | 515 // Test harness that sets up a minimal environment with necessary stubs. |
516 class WebContentsVideoCaptureDeviceTest : public testing::Test { | 516 class WebContentsVideoCaptureDeviceTest : public testing::Test { |
517 public: | 517 public: |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 source()->SetSolidColor(SK_ColorGREEN); | 855 source()->SetSolidColor(SK_ColorGREEN); |
856 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); | 856 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
857 source()->SetSolidColor(SK_ColorRED); | 857 source()->SetSolidColor(SK_ColorRED); |
858 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 858 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
859 | 859 |
860 device()->StopAndDeAllocate(); | 860 device()->StopAndDeAllocate(); |
861 } | 861 } |
862 | 862 |
863 } // namespace | 863 } // namespace |
864 } // namespace content | 864 } // namespace content |
OLD | NEW |