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

Side by Side Diff: content/browser/media/capture/web_contents_video_capture_device_unittest.cc

Issue 1135823004: Implement all resolution change policies for desktop and tab capture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@resolution_change_policy_constraints_ITEM1_CR1
Patch Set: Addressed Wez's third round comments. Created 5 years, 7 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 "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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698