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" |
11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
12 #include "base/timer/timer.h" | 12 #include "base/timer/timer.h" |
13 #include "content/browser/browser_thread_impl.h" | 13 #include "content/browser/browser_thread_impl.h" |
| 14 #include "content/browser/frame_host/render_frame_host_impl.h" |
14 #include "content/browser/media/capture/video_capture_oracle.h" | 15 #include "content/browser/media/capture/video_capture_oracle.h" |
15 #include "content/browser/media/capture/web_contents_capture_util.h" | 16 #include "content/browser/media/capture/web_contents_capture_util.h" |
16 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 17 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
17 #include "content/browser/renderer_host/render_view_host_factory.h" | 18 #include "content/browser/renderer_host/render_view_host_factory.h" |
18 #include "content/browser/renderer_host/render_widget_host_impl.h" | 19 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 20 #include "content/browser/web_contents/web_contents_impl.h" |
19 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
20 #include "content/public/browser/notification_types.h" | 22 #include "content/public/browser/notification_types.h" |
21 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 23 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
22 #include "content/public/test/mock_render_process_host.h" | 24 #include "content/public/test/mock_render_process_host.h" |
23 #include "content/public/test/test_browser_context.h" | 25 #include "content/public/test/test_browser_context.h" |
24 #include "content/public/test/test_browser_thread_bundle.h" | 26 #include "content/public/test/test_browser_thread_bundle.h" |
25 #include "content/public/test/test_utils.h" | 27 #include "content/public/test/test_utils.h" |
26 #include "content/test/test_render_view_host.h" | 28 #include "content/test/test_render_view_host.h" |
27 #include "content/test/test_web_contents.h" | 29 #include "content/test/test_web_contents.h" |
28 #include "media/base/video_capture_types.h" | 30 #include "media/base/video_capture_types.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 yuv, yuv + 1, yuv + 2, 1, 1, 1, 1, 1); | 72 yuv, yuv + 1, yuv + 2, 1, 1, 1, 1, 1); |
71 return SkColorSetRGB(yuv[0], yuv[1], yuv[2]); | 73 return SkColorSetRGB(yuv[0], yuv[1], yuv[2]); |
72 } | 74 } |
73 | 75 |
74 // Thread-safe class that controls the source pattern to be captured by the | 76 // Thread-safe class that controls the source pattern to be captured by the |
75 // system under test. The lifetime of this class is greater than the lifetime | 77 // system under test. The lifetime of this class is greater than the lifetime |
76 // of all objects that reference it, so it does not need to be reference | 78 // of all objects that reference it, so it does not need to be reference |
77 // counted. | 79 // counted. |
78 class CaptureTestSourceController { | 80 class CaptureTestSourceController { |
79 public: | 81 public: |
80 | |
81 CaptureTestSourceController() | 82 CaptureTestSourceController() |
82 : color_(SK_ColorMAGENTA), | 83 : color_(SK_ColorMAGENTA), |
83 copy_result_size_(kTestWidth, kTestHeight), | 84 copy_result_size_(kTestWidth, kTestHeight), |
84 can_copy_to_video_frame_(false), | 85 can_copy_to_video_frame_(false), |
85 use_frame_subscriber_(false) {} | 86 use_frame_subscriber_(false) {} |
86 | 87 |
87 void SetSolidColor(SkColor color) { | 88 void SetSolidColor(SkColor color) { |
88 base::AutoLock guard(lock_); | 89 base::AutoLock guard(lock_); |
89 color_ = color; | 90 color_ = color; |
90 } | 91 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 156 |
156 // A stub implementation which returns solid-color bitmaps in calls to | 157 // A stub implementation which returns solid-color bitmaps in calls to |
157 // CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame | 158 // CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame |
158 // readback path to be switched on and off. The behavior is controlled by a | 159 // readback path to be switched on and off. The behavior is controlled by a |
159 // CaptureTestSourceController. | 160 // CaptureTestSourceController. |
160 class CaptureTestView : public TestRenderWidgetHostView { | 161 class CaptureTestView : public TestRenderWidgetHostView { |
161 public: | 162 public: |
162 explicit CaptureTestView(RenderWidgetHostImpl* rwh, | 163 explicit CaptureTestView(RenderWidgetHostImpl* rwh, |
163 CaptureTestSourceController* controller) | 164 CaptureTestSourceController* controller) |
164 : TestRenderWidgetHostView(rwh), | 165 : TestRenderWidgetHostView(rwh), |
165 controller_(controller) {} | 166 controller_(controller), |
| 167 fake_bounds_(100, 100, 100 + kTestWidth, 100 + kTestHeight) {} |
166 | 168 |
167 ~CaptureTestView() override {} | 169 ~CaptureTestView() override {} |
168 | 170 |
169 // TestRenderWidgetHostView overrides. | 171 // TestRenderWidgetHostView overrides. |
170 gfx::Rect GetViewBounds() const override { | 172 gfx::Rect GetViewBounds() const override { |
171 return gfx::Rect(100, 100, 100 + kTestWidth, 100 + kTestHeight); | 173 return fake_bounds_; |
| 174 } |
| 175 |
| 176 void SetSize(const gfx::Size& size) override { |
| 177 SetBounds(gfx::Rect(fake_bounds_.origin(), size)); |
| 178 } |
| 179 |
| 180 void SetBounds(const gfx::Rect& rect) override { |
| 181 fake_bounds_ = rect; |
172 } | 182 } |
173 | 183 |
174 bool CanCopyToVideoFrame() const override { | 184 bool CanCopyToVideoFrame() const override { |
175 return controller_->CanCopyToVideoFrame(); | 185 return controller_->CanCopyToVideoFrame(); |
176 } | 186 } |
177 | 187 |
178 void CopyFromCompositingSurfaceToVideoFrame( | 188 void CopyFromCompositingSurfaceToVideoFrame( |
179 const gfx::Rect& src_subrect, | 189 const gfx::Rect& src_subrect, |
180 const scoped_refptr<media::VideoFrame>& target, | 190 const scoped_refptr<media::VideoFrame>& target, |
181 const base::Callback<void(bool)>& callback) override { | 191 const base::Callback<void(bool)>& callback) override { |
(...skipping 24 matching lines...) Expand all Loading... |
206 BrowserThread::PostTask(BrowserThread::UI, | 216 BrowserThread::PostTask(BrowserThread::UI, |
207 FROM_HERE, | 217 FROM_HERE, |
208 base::Bind(callback, present_time, true)); | 218 base::Bind(callback, present_time, true)); |
209 controller_->SignalCopy(); | 219 controller_->SignalCopy(); |
210 } | 220 } |
211 } | 221 } |
212 | 222 |
213 private: | 223 private: |
214 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber_; | 224 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber_; |
215 CaptureTestSourceController* const controller_; | 225 CaptureTestSourceController* const controller_; |
| 226 gfx::Rect fake_bounds_; |
216 | 227 |
217 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView); | 228 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView); |
218 }; | 229 }; |
219 | 230 |
220 #if defined(COMPILER_MSVC) | 231 #if defined(COMPILER_MSVC) |
221 // MSVC warns on diamond inheritance. See comment for same warning on | 232 // MSVC warns on diamond inheritance. See comment for same warning on |
222 // RenderViewHostImpl. | 233 // RenderViewHostImpl. |
223 #pragma warning(push) | 234 #pragma warning(push) |
224 #pragma warning(disable: 4250) | 235 #pragma warning(disable: 4250) |
225 #endif | 236 #endif |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 private: | 312 private: |
302 CaptureTestSourceController* controller_; | 313 CaptureTestSourceController* controller_; |
303 | 314 |
304 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); | 315 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); |
305 }; | 316 }; |
306 | 317 |
307 // A stub consumer of captured video frames, which checks the output of | 318 // A stub consumer of captured video frames, which checks the output of |
308 // WebContentsVideoCaptureDevice. | 319 // WebContentsVideoCaptureDevice. |
309 class StubClient : public media::VideoCaptureDevice::Client { | 320 class StubClient : public media::VideoCaptureDevice::Client { |
310 public: | 321 public: |
311 StubClient(const base::Callback<void(SkColor)>& color_callback, | 322 StubClient( |
312 const base::Closure& error_callback) | 323 const base::Callback<void(SkColor, const gfx::Size&)>& report_callback, |
313 : color_callback_(color_callback), | 324 const base::Closure& error_callback) |
| 325 : report_callback_(report_callback), |
314 error_callback_(error_callback) { | 326 error_callback_(error_callback) { |
315 buffer_pool_ = new VideoCaptureBufferPool(2); | 327 buffer_pool_ = new VideoCaptureBufferPool(2); |
316 } | 328 } |
317 ~StubClient() override {} | 329 ~StubClient() override {} |
318 | 330 |
319 MOCK_METHOD5(OnIncomingCapturedData, | 331 MOCK_METHOD5(OnIncomingCapturedData, |
320 void(const uint8* data, | 332 void(const uint8* data, |
321 int length, | 333 int length, |
322 const media::VideoCaptureFormat& frame_format, | 334 const media::VideoCaptureFormat& frame_format, |
323 int rotation, | 335 int rotation, |
(...skipping 29 matching lines...) Expand all Loading... |
353 void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer, | 365 void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer, |
354 const media::VideoCaptureFormat& frame_format, | 366 const media::VideoCaptureFormat& frame_format, |
355 const base::TimeTicks& timestamp) override { | 367 const base::TimeTicks& timestamp) override { |
356 DoOnIncomingCapturedBuffer(); | 368 DoOnIncomingCapturedBuffer(); |
357 } | 369 } |
358 | 370 |
359 void OnIncomingCapturedVideoFrame( | 371 void OnIncomingCapturedVideoFrame( |
360 scoped_ptr<Buffer> buffer, | 372 scoped_ptr<Buffer> buffer, |
361 const scoped_refptr<media::VideoFrame>& frame, | 373 const scoped_refptr<media::VideoFrame>& frame, |
362 const base::TimeTicks& timestamp) override { | 374 const base::TimeTicks& timestamp) override { |
363 EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), frame->visible_rect().size()); | 375 EXPECT_FALSE(frame->visible_rect().IsEmpty()); |
364 EXPECT_EQ(media::VideoFrame::I420, frame->format()); | 376 EXPECT_EQ(media::VideoFrame::I420, frame->format()); |
365 double frame_rate = 0; | 377 double frame_rate = 0; |
366 EXPECT_TRUE( | 378 EXPECT_TRUE( |
367 frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, | 379 frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, |
368 &frame_rate)); | 380 &frame_rate)); |
369 EXPECT_EQ(kTestFramesPerSecond, frame_rate); | 381 EXPECT_EQ(kTestFramesPerSecond, frame_rate); |
370 uint8 yuv[3]; | 382 |
371 for (int plane = 0; plane < 3; ++plane) | 383 // TODO(miu): We just look at the center pixel presently, because if the |
372 yuv[plane] = frame->visible_data(plane)[0]; | 384 // analysis is too slow, the backlog of frames will grow without bound and |
373 // TODO(nick): We just look at the first pixel presently, because if | 385 // trouble erupts. http://crbug.com/174519 |
374 // the analysis is too slow, the backlog of frames will grow without bound | 386 using media::VideoFrame; |
375 // and trouble erupts. http://crbug.com/174519 | 387 const gfx::Point center = frame->visible_rect().CenterPoint(); |
376 color_callback_.Run((SkColorSetRGB(yuv[0], yuv[1], yuv[2]))); | 388 const int center_offset_y = |
| 389 (frame->stride(VideoFrame::kYPlane) * center.y()) + center.x(); |
| 390 const int center_offset_uv = |
| 391 (frame->stride(VideoFrame::kUPlane) * (center.y() / 2)) + |
| 392 (center.x() / 2); |
| 393 report_callback_.Run( |
| 394 SkColorSetRGB(frame->data(VideoFrame::kYPlane)[center_offset_y], |
| 395 frame->data(VideoFrame::kUPlane)[center_offset_uv], |
| 396 frame->data(VideoFrame::kVPlane)[center_offset_uv]), |
| 397 frame->visible_rect().size()); |
377 } | 398 } |
378 | 399 |
379 void OnError(const std::string& reason) override { error_callback_.Run(); } | 400 void OnError(const std::string& reason) override { error_callback_.Run(); } |
380 | 401 |
381 private: | 402 private: |
382 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { | 403 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { |
383 public: | 404 public: |
384 AutoReleaseBuffer( | 405 AutoReleaseBuffer( |
385 const scoped_refptr<VideoCaptureBufferPool>& pool, | 406 const scoped_refptr<VideoCaptureBufferPool>& pool, |
386 scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle, | 407 scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle, |
(...skipping 13 matching lines...) Expand all Loading... |
400 | 421 |
401 private: | 422 private: |
402 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); } | 423 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); } |
403 | 424 |
404 const int id_; | 425 const int id_; |
405 const scoped_refptr<VideoCaptureBufferPool> pool_; | 426 const scoped_refptr<VideoCaptureBufferPool> pool_; |
406 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_; | 427 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_; |
407 }; | 428 }; |
408 | 429 |
409 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; | 430 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; |
410 base::Callback<void(SkColor)> color_callback_; | 431 base::Callback<void(SkColor, const gfx::Size&)> report_callback_; |
411 base::Closure error_callback_; | 432 base::Closure error_callback_; |
412 | 433 |
413 DISALLOW_COPY_AND_ASSIGN(StubClient); | 434 DISALLOW_COPY_AND_ASSIGN(StubClient); |
414 }; | 435 }; |
415 | 436 |
416 class StubClientObserver { | 437 class StubClientObserver { |
417 public: | 438 public: |
418 StubClientObserver() | 439 StubClientObserver() |
419 : error_encountered_(false), | 440 : error_encountered_(false), |
420 wait_color_yuv_(0xcafe1950) { | 441 wait_color_yuv_(0xcafe1950), |
| 442 wait_size_(kTestWidth, kTestHeight) { |
421 client_.reset(new StubClient( | 443 client_.reset(new StubClient( |
422 base::Bind(&StubClientObserver::OnColor, base::Unretained(this)), | 444 base::Bind(&StubClientObserver::DidDeliverFrame, |
| 445 base::Unretained(this)), |
423 base::Bind(&StubClientObserver::OnError, base::Unretained(this)))); | 446 base::Bind(&StubClientObserver::OnError, base::Unretained(this)))); |
424 } | 447 } |
425 | 448 |
426 virtual ~StubClientObserver() {} | 449 virtual ~StubClientObserver() {} |
427 | 450 |
428 scoped_ptr<media::VideoCaptureDevice::Client> PassClient() { | 451 scoped_ptr<media::VideoCaptureDevice::Client> PassClient() { |
429 return client_.Pass(); | 452 return client_.Pass(); |
430 } | 453 } |
431 | 454 |
432 void QuitIfConditionMet(SkColor color) { | 455 void QuitIfConditionsMet(SkColor color, const gfx::Size& size) { |
433 base::AutoLock guard(lock_); | 456 base::AutoLock guard(lock_); |
434 if (wait_color_yuv_ == color || error_encountered_) | 457 if (error_encountered_) |
| 458 base::MessageLoop::current()->Quit(); |
| 459 else if (wait_color_yuv_ == color && wait_size_.IsEmpty()) |
| 460 base::MessageLoop::current()->Quit(); |
| 461 else if (wait_color_yuv_ == color && wait_size_ == size) |
435 base::MessageLoop::current()->Quit(); | 462 base::MessageLoop::current()->Quit(); |
436 } | 463 } |
437 | 464 |
| 465 // Run the current loop until a frame is delivered with the |expected_color| |
| 466 // and any non-empty frame size. |
438 void WaitForNextColor(SkColor expected_color) { | 467 void WaitForNextColor(SkColor expected_color) { |
| 468 WaitForNextColorAndFrameSize(expected_color, gfx::Size()); |
| 469 } |
| 470 |
| 471 // Run the current loop until a frame is delivered with the |expected_color| |
| 472 // and is of the |expected_size|. |
| 473 void WaitForNextColorAndFrameSize(SkColor expected_color, |
| 474 const gfx::Size& expected_size) { |
439 { | 475 { |
440 base::AutoLock guard(lock_); | 476 base::AutoLock guard(lock_); |
441 wait_color_yuv_ = ConvertRgbToYuv(expected_color); | 477 wait_color_yuv_ = ConvertRgbToYuv(expected_color); |
| 478 wait_size_ = expected_size; |
442 error_encountered_ = false; | 479 error_encountered_ = false; |
443 } | 480 } |
444 RunCurrentLoopWithDeadline(); | 481 RunCurrentLoopWithDeadline(); |
445 { | 482 { |
446 base::AutoLock guard(lock_); | 483 base::AutoLock guard(lock_); |
447 ASSERT_FALSE(error_encountered_); | 484 ASSERT_FALSE(error_encountered_); |
448 } | 485 } |
449 } | 486 } |
450 | 487 |
451 void WaitForError() { | 488 void WaitForError() { |
452 { | 489 { |
453 base::AutoLock guard(lock_); | 490 base::AutoLock guard(lock_); |
454 wait_color_yuv_ = kNotInterested; | 491 wait_color_yuv_ = kNotInterested; |
| 492 wait_size_ = gfx::Size(); |
455 error_encountered_ = false; | 493 error_encountered_ = false; |
456 } | 494 } |
457 RunCurrentLoopWithDeadline(); | 495 RunCurrentLoopWithDeadline(); |
458 { | 496 { |
459 base::AutoLock guard(lock_); | 497 base::AutoLock guard(lock_); |
460 ASSERT_TRUE(error_encountered_); | 498 ASSERT_TRUE(error_encountered_); |
461 } | 499 } |
462 } | 500 } |
463 | 501 |
464 bool HasError() { | 502 bool HasError() { |
465 base::AutoLock guard(lock_); | 503 base::AutoLock guard(lock_); |
466 return error_encountered_; | 504 return error_encountered_; |
467 } | 505 } |
468 | 506 |
469 void OnError() { | 507 void OnError() { |
470 { | 508 { |
471 base::AutoLock guard(lock_); | 509 base::AutoLock guard(lock_); |
472 error_encountered_ = true; | 510 error_encountered_ = true; |
473 } | 511 } |
474 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | 512 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
475 &StubClientObserver::QuitIfConditionMet, | 513 &StubClientObserver::QuitIfConditionsMet, |
476 base::Unretained(this), | 514 base::Unretained(this), |
477 kNothingYet)); | 515 kNothingYet, |
| 516 gfx::Size())); |
478 } | 517 } |
479 | 518 |
480 void OnColor(SkColor color) { | 519 void DidDeliverFrame(SkColor color, const gfx::Size& size) { |
481 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | 520 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
482 &StubClientObserver::QuitIfConditionMet, | 521 &StubClientObserver::QuitIfConditionsMet, |
483 base::Unretained(this), | 522 base::Unretained(this), |
484 color)); | 523 color, |
| 524 size)); |
485 } | 525 } |
486 | 526 |
487 private: | 527 private: |
488 base::Lock lock_; | 528 base::Lock lock_; |
489 bool error_encountered_; | 529 bool error_encountered_; |
490 SkColor wait_color_yuv_; | 530 SkColor wait_color_yuv_; |
| 531 gfx::Size wait_size_; |
491 scoped_ptr<StubClient> client_; | 532 scoped_ptr<StubClient> client_; |
492 | 533 |
493 DISALLOW_COPY_AND_ASSIGN(StubClientObserver); | 534 DISALLOW_COPY_AND_ASSIGN(StubClientObserver); |
494 }; | 535 }; |
495 | 536 |
496 // A dummy implementation of gfx::Screen, since WebContentsVideoCaptureDevice | 537 // A dummy implementation of gfx::Screen, since WebContentsVideoCaptureDevice |
497 // needs access to a gfx::Display's device scale factor. | 538 // needs access to a gfx::Display's device scale factor. |
498 class FakeScreen : public gfx::Screen { | 539 class FakeScreen : public gfx::Screen { |
499 public: | 540 public: |
500 FakeScreen() : the_one_display_(0x1337, gfx::Rect(0, 0, 2560, 1440)) { | 541 FakeScreen() : the_one_display_(0x1337, gfx::Rect(0, 0, 2560, 1440)) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 test_view->SimulateUpdate(); | 656 test_view->SimulateUpdate(); |
616 } else { | 657 } else { |
617 // Simulate a non-accelerated paint. | 658 // Simulate a non-accelerated paint. |
618 NotificationService::current()->Notify( | 659 NotificationService::current()->Notify( |
619 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | 660 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, |
620 Source<RenderWidgetHost>(web_contents_->GetRenderViewHost()), | 661 Source<RenderWidgetHost>(web_contents_->GetRenderViewHost()), |
621 NotificationService::NoDetails()); | 662 NotificationService::NoDetails()); |
622 } | 663 } |
623 } | 664 } |
624 | 665 |
| 666 void SimulateSourceSizeChange(const gfx::Size& size) { |
| 667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 668 CaptureTestView* test_view = static_cast<CaptureTestView*>( |
| 669 web_contents_->GetRenderViewHost()->GetView()); |
| 670 test_view->SetSize(size); |
| 671 // Normally, RenderWidgetHostImpl would notify WebContentsImpl that the size |
| 672 // has changed. However, in this test setup where there is no render |
| 673 // process, we must notify WebContentsImpl directly. |
| 674 WebContentsImpl* const as_web_contents_impl = |
| 675 static_cast<WebContentsImpl*>(web_contents_.get()); |
| 676 RenderWidgetHostDelegate* const as_rwh_delegate = |
| 677 static_cast<RenderWidgetHostDelegate*>(as_web_contents_impl); |
| 678 as_rwh_delegate->RenderWidgetWasResized( |
| 679 as_web_contents_impl->GetMainFrame()->GetRenderWidgetHost(), true); |
| 680 } |
| 681 |
625 void DestroyVideoCaptureDevice() { device_.reset(); } | 682 void DestroyVideoCaptureDevice() { device_.reset(); } |
626 | 683 |
627 StubClientObserver* client_observer() { | 684 StubClientObserver* client_observer() { |
628 return &client_observer_; | 685 return &client_observer_; |
629 } | 686 } |
630 | 687 |
631 private: | 688 private: |
632 FakeScreen fake_screen_; | 689 FakeScreen fake_screen_; |
633 | 690 |
634 StubClientObserver client_observer_; | 691 StubClientObserver client_observer_; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 // Now push some good frames through; they should be processed normally. | 929 // Now push some good frames through; they should be processed normally. |
873 source()->SetCopyResultSize(kTestWidth, kTestHeight); | 930 source()->SetCopyResultSize(kTestWidth, kTestHeight); |
874 source()->SetSolidColor(SK_ColorGREEN); | 931 source()->SetSolidColor(SK_ColorGREEN); |
875 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); | 932 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
876 source()->SetSolidColor(SK_ColorRED); | 933 source()->SetSolidColor(SK_ColorRED); |
877 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 934 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
878 | 935 |
879 device()->StopAndDeAllocate(); | 936 device()->StopAndDeAllocate(); |
880 } | 937 } |
881 | 938 |
| 939 // Tests that, when configured with the FIXED_ASPECT_RATIO resolution change |
| 940 // policy, the source size changes result in video frames of possibly varying |
| 941 // resolutions, but all with the same aspect ratio. |
| 942 TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_FixedAspectRatio) { |
| 943 media::VideoCaptureParams capture_params; |
| 944 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 945 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 946 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 947 capture_params.resolution_change_policy = |
| 948 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; |
| 949 |
| 950 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 951 |
| 952 for (int i = 0; i < 6; i++) { |
| 953 const char* name = NULL; |
| 954 switch (i % 3) { |
| 955 case 0: |
| 956 source()->SetCanCopyToVideoFrame(true); |
| 957 source()->SetUseFrameSubscriber(false); |
| 958 name = "VideoFrame"; |
| 959 break; |
| 960 case 1: |
| 961 source()->SetCanCopyToVideoFrame(false); |
| 962 source()->SetUseFrameSubscriber(true); |
| 963 name = "Subscriber"; |
| 964 break; |
| 965 case 2: |
| 966 source()->SetCanCopyToVideoFrame(false); |
| 967 source()->SetUseFrameSubscriber(false); |
| 968 name = "SkBitmap"; |
| 969 break; |
| 970 default: |
| 971 FAIL(); |
| 972 } |
| 973 |
| 974 SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
| 975 |
| 976 // Source size equals maximum size. Expect delivered frames to be |
| 977 // kTestWidth by kTestHeight. |
| 978 source()->SetSolidColor(SK_ColorRED); |
| 979 SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight)); |
| 980 SimulateDrawEvent(); |
| 981 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 982 SK_ColorRED, gfx::Size(kTestWidth, kTestHeight))); |
| 983 |
| 984 // Source size is half in both dimensions. Expect delivered frames to be of |
| 985 // the same aspect ratio as kTestWidth by kTestHeight, but larger than the |
| 986 // half size because the minimum height is 180 lines. |
| 987 source()->SetSolidColor(SK_ColorGREEN); |
| 988 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
| 989 SimulateDrawEvent(); |
| 990 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 991 SK_ColorGREEN, gfx::Size(180 * kTestWidth / kTestHeight, 180))); |
| 992 |
| 993 // Source size changes aspect ratio. Expect delivered frames to be padded |
| 994 // in the horizontal dimension to preserve aspect ratio. |
| 995 source()->SetSolidColor(SK_ColorBLUE); |
| 996 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight)); |
| 997 SimulateDrawEvent(); |
| 998 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 999 SK_ColorBLUE, gfx::Size(kTestWidth, kTestHeight))); |
| 1000 |
| 1001 // Source size changes aspect ratio again. Expect delivered frames to be |
| 1002 // padded in the vertical dimension to preserve aspect ratio. |
| 1003 source()->SetSolidColor(SK_ColorBLACK); |
| 1004 SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight / 2)); |
| 1005 SimulateDrawEvent(); |
| 1006 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 1007 SK_ColorBLACK, gfx::Size(kTestWidth, kTestHeight))); |
| 1008 } |
| 1009 |
| 1010 device()->StopAndDeAllocate(); |
| 1011 } |
| 1012 |
| 1013 // Tests that, when configured with the ANY_WITHIN_LIMIT resolution change |
| 1014 // policy, the source size changes result in video frames of possibly varying |
| 1015 // resolutions. |
| 1016 TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_AnyWithinLimits) { |
| 1017 media::VideoCaptureParams capture_params; |
| 1018 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 1019 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 1020 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 1021 capture_params.resolution_change_policy = |
| 1022 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; |
| 1023 |
| 1024 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 1025 |
| 1026 for (int i = 0; i < 6; i++) { |
| 1027 const char* name = NULL; |
| 1028 switch (i % 3) { |
| 1029 case 0: |
| 1030 source()->SetCanCopyToVideoFrame(true); |
| 1031 source()->SetUseFrameSubscriber(false); |
| 1032 name = "VideoFrame"; |
| 1033 break; |
| 1034 case 1: |
| 1035 source()->SetCanCopyToVideoFrame(false); |
| 1036 source()->SetUseFrameSubscriber(true); |
| 1037 name = "Subscriber"; |
| 1038 break; |
| 1039 case 2: |
| 1040 source()->SetCanCopyToVideoFrame(false); |
| 1041 source()->SetUseFrameSubscriber(false); |
| 1042 name = "SkBitmap"; |
| 1043 break; |
| 1044 default: |
| 1045 FAIL(); |
| 1046 } |
| 1047 |
| 1048 SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
| 1049 |
| 1050 // Source size equals maximum size. Expect delivered frames to be |
| 1051 // kTestWidth by kTestHeight. |
| 1052 source()->SetSolidColor(SK_ColorRED); |
| 1053 SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight)); |
| 1054 SimulateDrawEvent(); |
| 1055 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 1056 SK_ColorRED, gfx::Size(kTestWidth, kTestHeight))); |
| 1057 |
| 1058 // Source size is half in both dimensions. Expect delivered frames to also |
| 1059 // be half in both dimensions. |
| 1060 source()->SetSolidColor(SK_ColorGREEN); |
| 1061 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
| 1062 SimulateDrawEvent(); |
| 1063 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 1064 SK_ColorGREEN, gfx::Size(kTestWidth / 2, kTestHeight / 2))); |
| 1065 |
| 1066 // Source size changes to something arbitrary. Since the source size is |
| 1067 // less than the maximum size, expect delivered frames to be the same size |
| 1068 // as the source size. |
| 1069 source()->SetSolidColor(SK_ColorBLUE); |
| 1070 gfx::Size arbitrary_source_size(kTestWidth / 2 + 42, kTestHeight - 10); |
| 1071 SimulateSourceSizeChange(arbitrary_source_size); |
| 1072 SimulateDrawEvent(); |
| 1073 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 1074 SK_ColorBLUE, arbitrary_source_size)); |
| 1075 |
| 1076 // Source size changes to something arbitrary that exceeds the maximum frame |
| 1077 // size. Since the source size exceeds the maximum size, expect delivered |
| 1078 // frames to be downscaled. |
| 1079 source()->SetSolidColor(SK_ColorBLACK); |
| 1080 arbitrary_source_size = gfx::Size(kTestWidth * 2 + 99, kTestHeight / 2); |
| 1081 SimulateSourceSizeChange(arbitrary_source_size); |
| 1082 SimulateDrawEvent(); |
| 1083 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( |
| 1084 SK_ColorBLACK, gfx::Size(kTestWidth, |
| 1085 kTestWidth * arbitrary_source_size.height() / |
| 1086 arbitrary_source_size.width()))); |
| 1087 } |
| 1088 |
| 1089 device()->StopAndDeAllocate(); |
| 1090 } |
| 1091 |
882 } // namespace | 1092 } // namespace |
883 } // namespace content | 1093 } // namespace content |
OLD | NEW |