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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 155 |
156 // A stub implementation which returns solid-color bitmaps in calls to | 156 // A stub implementation which returns solid-color bitmaps in calls to |
157 // CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame | 157 // CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame |
158 // readback path to be switched on and off. The behavior is controlled by a | 158 // readback path to be switched on and off. The behavior is controlled by a |
159 // CaptureTestSourceController. | 159 // CaptureTestSourceController. |
160 class CaptureTestView : public TestRenderWidgetHostView { | 160 class CaptureTestView : public TestRenderWidgetHostView { |
161 public: | 161 public: |
162 explicit CaptureTestView(RenderWidgetHostImpl* rwh, | 162 explicit CaptureTestView(RenderWidgetHostImpl* rwh, |
163 CaptureTestSourceController* controller) | 163 CaptureTestSourceController* controller) |
164 : TestRenderWidgetHostView(rwh), | 164 : TestRenderWidgetHostView(rwh), |
165 controller_(controller) {} | 165 rwh_(rwh), |
| 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 fake_bounds_.set_size(size); |
| 178 rwh_->WasResized(); |
| 179 } |
| 180 |
| 181 void SetBounds(const gfx::Rect& rect) override { |
| 182 fake_bounds_ = rect; |
| 183 rwh_->WasResized(); |
172 } | 184 } |
173 | 185 |
174 bool CanCopyToVideoFrame() const override { | 186 bool CanCopyToVideoFrame() const override { |
175 return controller_->CanCopyToVideoFrame(); | 187 return controller_->CanCopyToVideoFrame(); |
176 } | 188 } |
177 | 189 |
178 void CopyFromCompositingSurfaceToVideoFrame( | 190 void CopyFromCompositingSurfaceToVideoFrame( |
179 const gfx::Rect& src_subrect, | 191 const gfx::Rect& src_subrect, |
180 const scoped_refptr<media::VideoFrame>& target, | 192 const scoped_refptr<media::VideoFrame>& target, |
181 const base::Callback<void(bool)>& callback) override { | 193 const base::Callback<void(bool)>& callback) override { |
(...skipping 23 matching lines...) Expand all Loading... |
205 target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); | 217 target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); |
206 BrowserThread::PostTask(BrowserThread::UI, | 218 BrowserThread::PostTask(BrowserThread::UI, |
207 FROM_HERE, | 219 FROM_HERE, |
208 base::Bind(callback, present_time, true)); | 220 base::Bind(callback, present_time, true)); |
209 controller_->SignalCopy(); | 221 controller_->SignalCopy(); |
210 } | 222 } |
211 } | 223 } |
212 | 224 |
213 private: | 225 private: |
214 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber_; | 226 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber_; |
| 227 // TODO(miu): Investigate why TestRenderWidgetHostView::GetRenderWidgetHost() |
| 228 // always returns null, and perhaps fix it in order to remove this |rwh_| |
| 229 // member. |
| 230 RenderWidgetHostImpl* const rwh_; |
215 CaptureTestSourceController* const controller_; | 231 CaptureTestSourceController* const controller_; |
| 232 gfx::Rect fake_bounds_; |
216 | 233 |
217 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView); | 234 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView); |
218 }; | 235 }; |
219 | 236 |
220 #if defined(COMPILER_MSVC) | 237 #if defined(COMPILER_MSVC) |
221 // MSVC warns on diamond inheritance. See comment for same warning on | 238 // MSVC warns on diamond inheritance. See comment for same warning on |
222 // RenderViewHostImpl. | 239 // RenderViewHostImpl. |
223 #pragma warning(push) | 240 #pragma warning(push) |
224 #pragma warning(disable: 4250) | 241 #pragma warning(disable: 4250) |
225 #endif | 242 #endif |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); | 321 DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); |
305 }; | 322 }; |
306 | 323 |
307 // A stub consumer of captured video frames, which checks the output of | 324 // A stub consumer of captured video frames, which checks the output of |
308 // WebContentsVideoCaptureDevice. | 325 // WebContentsVideoCaptureDevice. |
309 class StubClient : public media::VideoCaptureDevice::Client { | 326 class StubClient : public media::VideoCaptureDevice::Client { |
310 public: | 327 public: |
311 StubClient(const base::Callback<void(SkColor)>& color_callback, | 328 StubClient(const base::Callback<void(SkColor)>& color_callback, |
312 const base::Closure& error_callback) | 329 const base::Closure& error_callback) |
313 : color_callback_(color_callback), | 330 : color_callback_(color_callback), |
314 error_callback_(error_callback) { | 331 error_callback_(error_callback), |
| 332 expected_frame_size_(kTestWidth, kTestHeight), |
| 333 resolution_change_policy_(media::RESOLUTION_POLICY_FIXED_RESOLUTION) { |
315 buffer_pool_ = new VideoCaptureBufferPool(2); | 334 buffer_pool_ = new VideoCaptureBufferPool(2); |
316 } | 335 } |
317 ~StubClient() override {} | 336 ~StubClient() override {} |
318 | 337 |
319 MOCK_METHOD5(OnIncomingCapturedData, | 338 MOCK_METHOD5(OnIncomingCapturedData, |
320 void(const uint8* data, | 339 void(const uint8* data, |
321 int length, | 340 int length, |
322 const media::VideoCaptureFormat& frame_format, | 341 const media::VideoCaptureFormat& frame_format, |
323 int rotation, | 342 int rotation, |
324 const base::TimeTicks& timestamp)); | 343 const base::TimeTicks& timestamp)); |
325 MOCK_METHOD9(OnIncomingCapturedYuvData, | 344 MOCK_METHOD9(OnIncomingCapturedYuvData, |
326 void (const uint8* y_data, | 345 void (const uint8* y_data, |
327 const uint8* u_data, | 346 const uint8* u_data, |
328 const uint8* v_data, | 347 const uint8* v_data, |
329 size_t y_stride, | 348 size_t y_stride, |
330 size_t u_stride, | 349 size_t u_stride, |
331 size_t v_stride, | 350 size_t v_stride, |
332 const media::VideoCaptureFormat& frame_format, | 351 const media::VideoCaptureFormat& frame_format, |
333 int clockwise_rotation, | 352 int clockwise_rotation, |
334 const base::TimeTicks& timestamp)); | 353 const base::TimeTicks& timestamp)); |
335 | 354 |
336 MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void)); | 355 MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void)); |
337 | 356 |
| 357 void SetExpectedFrameSizeProperties(const gfx::Size& max_size, |
| 358 media::ResolutionChangePolicy policy) { |
| 359 expected_frame_size_ = max_size; |
| 360 resolution_change_policy_ = policy; |
| 361 } |
| 362 |
338 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer( | 363 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer( |
339 media::VideoPixelFormat format, | 364 media::VideoPixelFormat format, |
340 const gfx::Size& dimensions) override { | 365 const gfx::Size& dimensions) override { |
341 CHECK_EQ(format, media::PIXEL_FORMAT_I420); | 366 CHECK_EQ(format, media::PIXEL_FORMAT_I420); |
342 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; // Ignored. | 367 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; // Ignored. |
343 int buffer_id = buffer_pool_->ReserveForProducer(format, dimensions, | 368 int buffer_id = buffer_pool_->ReserveForProducer(format, dimensions, |
344 &buffer_id_to_drop); | 369 &buffer_id_to_drop); |
345 if (buffer_id == VideoCaptureBufferPool::kInvalidId) | 370 if (buffer_id == VideoCaptureBufferPool::kInvalidId) |
346 return NULL; | 371 return NULL; |
347 | 372 |
348 return scoped_ptr<media::VideoCaptureDevice::Client::Buffer>( | 373 return scoped_ptr<media::VideoCaptureDevice::Client::Buffer>( |
349 new AutoReleaseBuffer( | 374 new AutoReleaseBuffer( |
350 buffer_pool_, buffer_pool_->GetBufferHandle(buffer_id), buffer_id)); | 375 buffer_pool_, buffer_pool_->GetBufferHandle(buffer_id), buffer_id)); |
351 } | 376 } |
352 // Trampoline method to workaround GMOCK problems with scoped_ptr<>. | 377 // Trampoline method to workaround GMOCK problems with scoped_ptr<>. |
353 void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer, | 378 void OnIncomingCapturedBuffer(scoped_ptr<Buffer> buffer, |
354 const media::VideoCaptureFormat& frame_format, | 379 const media::VideoCaptureFormat& frame_format, |
355 const base::TimeTicks& timestamp) override { | 380 const base::TimeTicks& timestamp) override { |
356 DoOnIncomingCapturedBuffer(); | 381 DoOnIncomingCapturedBuffer(); |
357 } | 382 } |
358 | 383 |
359 void OnIncomingCapturedVideoFrame( | 384 void OnIncomingCapturedVideoFrame( |
360 scoped_ptr<Buffer> buffer, | 385 scoped_ptr<Buffer> buffer, |
361 const scoped_refptr<media::VideoFrame>& frame, | 386 const scoped_refptr<media::VideoFrame>& frame, |
362 const base::TimeTicks& timestamp) override { | 387 const base::TimeTicks& timestamp) override { |
363 EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), frame->visible_rect().size()); | 388 switch (resolution_change_policy_) { |
| 389 case media::RESOLUTION_POLICY_FIXED_RESOLUTION: |
| 390 EXPECT_EQ(expected_frame_size_, frame->visible_rect().size()); |
| 391 break; |
| 392 case media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO: |
| 393 EXPECT_FALSE(frame->visible_rect().IsEmpty()); |
| 394 EXPECT_GE(expected_frame_size_.width(), frame->visible_rect().width()); |
| 395 EXPECT_GE(expected_frame_size_.height(), |
| 396 frame->visible_rect().height()); |
| 397 EXPECT_NEAR(static_cast<double>(expected_frame_size_.width()) / |
| 398 expected_frame_size_.height(), |
| 399 static_cast<double>(frame->visible_rect().width()) / |
| 400 frame->visible_rect().height(), |
| 401 0.01); |
| 402 break; |
| 403 case media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT: |
| 404 EXPECT_FALSE(frame->visible_rect().IsEmpty()); |
| 405 EXPECT_GE(expected_frame_size_.width(), frame->visible_rect().width()); |
| 406 EXPECT_GE(expected_frame_size_.height(), |
| 407 frame->visible_rect().height()); |
| 408 break; |
| 409 default: |
| 410 FAIL(); |
| 411 break; |
| 412 } |
364 EXPECT_EQ(media::VideoFrame::I420, frame->format()); | 413 EXPECT_EQ(media::VideoFrame::I420, frame->format()); |
365 double frame_rate = 0; | 414 double frame_rate = 0; |
366 EXPECT_TRUE( | 415 EXPECT_TRUE( |
367 frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, | 416 frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, |
368 &frame_rate)); | 417 &frame_rate)); |
369 EXPECT_EQ(kTestFramesPerSecond, frame_rate); | 418 EXPECT_EQ(kTestFramesPerSecond, frame_rate); |
370 uint8 yuv[3]; | 419 uint8 yuv[3]; |
371 for (int plane = 0; plane < 3; ++plane) | 420 for (int plane = 0; plane < 3; ++plane) |
372 yuv[plane] = frame->visible_data(plane)[0]; | 421 yuv[plane] = frame->visible_data(plane)[0]; |
373 // TODO(nick): We just look at the first pixel presently, because if | 422 // TODO(nick): We just look at the first pixel presently, because if |
(...skipping 29 matching lines...) Expand all Loading... |
403 | 452 |
404 const int id_; | 453 const int id_; |
405 const scoped_refptr<VideoCaptureBufferPool> pool_; | 454 const scoped_refptr<VideoCaptureBufferPool> pool_; |
406 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_; | 455 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_; |
407 }; | 456 }; |
408 | 457 |
409 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; | 458 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; |
410 base::Callback<void(SkColor)> color_callback_; | 459 base::Callback<void(SkColor)> color_callback_; |
411 base::Closure error_callback_; | 460 base::Closure error_callback_; |
412 | 461 |
| 462 gfx::Size expected_frame_size_; |
| 463 media::ResolutionChangePolicy resolution_change_policy_; |
| 464 |
413 DISALLOW_COPY_AND_ASSIGN(StubClient); | 465 DISALLOW_COPY_AND_ASSIGN(StubClient); |
414 }; | 466 }; |
415 | 467 |
416 class StubClientObserver { | 468 class StubClientObserver { |
417 public: | 469 public: |
418 StubClientObserver() | 470 StubClientObserver() |
419 : error_encountered_(false), | 471 : error_encountered_(false), |
420 wait_color_yuv_(0xcafe1950) { | 472 wait_color_yuv_(0xcafe1950) { |
421 client_.reset(new StubClient( | 473 client_.reset(new StubClient( |
422 base::Bind(&StubClientObserver::OnColor, base::Unretained(this)), | 474 base::Bind(&StubClientObserver::OnColor, base::Unretained(this)), |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 test_view->SimulateUpdate(); | 667 test_view->SimulateUpdate(); |
616 } else { | 668 } else { |
617 // Simulate a non-accelerated paint. | 669 // Simulate a non-accelerated paint. |
618 NotificationService::current()->Notify( | 670 NotificationService::current()->Notify( |
619 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | 671 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, |
620 Source<RenderWidgetHost>(web_contents_->GetRenderViewHost()), | 672 Source<RenderWidgetHost>(web_contents_->GetRenderViewHost()), |
621 NotificationService::NoDetails()); | 673 NotificationService::NoDetails()); |
622 } | 674 } |
623 } | 675 } |
624 | 676 |
| 677 void SimulateSourceSizeChange(const gfx::Size& size) { |
| 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 679 CaptureTestView* test_view = static_cast<CaptureTestView*>( |
| 680 web_contents_->GetRenderViewHost()->GetView()); |
| 681 test_view->SetSize(size); |
| 682 } |
| 683 |
625 void DestroyVideoCaptureDevice() { device_.reset(); } | 684 void DestroyVideoCaptureDevice() { device_.reset(); } |
626 | 685 |
627 StubClientObserver* client_observer() { | 686 StubClientObserver* client_observer() { |
628 return &client_observer_; | 687 return &client_observer_; |
629 } | 688 } |
630 | 689 |
631 private: | 690 private: |
632 FakeScreen fake_screen_; | 691 FakeScreen fake_screen_; |
633 | 692 |
634 StubClientObserver client_observer_; | 693 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. | 931 // Now push some good frames through; they should be processed normally. |
873 source()->SetCopyResultSize(kTestWidth, kTestHeight); | 932 source()->SetCopyResultSize(kTestWidth, kTestHeight); |
874 source()->SetSolidColor(SK_ColorGREEN); | 933 source()->SetSolidColor(SK_ColorGREEN); |
875 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); | 934 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
876 source()->SetSolidColor(SK_ColorRED); | 935 source()->SetSolidColor(SK_ColorRED); |
877 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 936 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
878 | 937 |
879 device()->StopAndDeAllocate(); | 938 device()->StopAndDeAllocate(); |
880 } | 939 } |
881 | 940 |
| 941 // Tests that, when configured with the FIXED_ASPECT_RATIO resolution change |
| 942 // policy, the source size changes result in video frames of possibly varying |
| 943 // resolutions, but all with the same aspect ratio. |
| 944 TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_FixedAspectRatio) { |
| 945 media::VideoCaptureParams capture_params; |
| 946 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 947 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 948 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 949 capture_params.resolution_change_policy = |
| 950 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; |
| 951 |
| 952 scoped_ptr<media::VideoCaptureDevice::Client> client = |
| 953 client_observer()->PassClient(); |
| 954 StubClient* const stub_client = static_cast<StubClient*>(client.get()); |
| 955 stub_client->SetExpectedFrameSizeProperties( |
| 956 gfx::Size(kTestWidth, kTestHeight), |
| 957 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO); |
| 958 device()->AllocateAndStart(capture_params, client.Pass()); |
| 959 |
| 960 for (int i = 0; i < 6; i++) { |
| 961 const char* name = NULL; |
| 962 switch (i % 3) { |
| 963 case 0: |
| 964 source()->SetCanCopyToVideoFrame(true); |
| 965 source()->SetUseFrameSubscriber(false); |
| 966 name = "VideoFrame"; |
| 967 break; |
| 968 case 1: |
| 969 source()->SetCanCopyToVideoFrame(false); |
| 970 source()->SetUseFrameSubscriber(true); |
| 971 name = "Subscriber"; |
| 972 break; |
| 973 case 2: |
| 974 source()->SetCanCopyToVideoFrame(false); |
| 975 source()->SetUseFrameSubscriber(false); |
| 976 name = "SkBitmap"; |
| 977 break; |
| 978 default: |
| 979 FAIL(); |
| 980 } |
| 981 |
| 982 SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
| 983 |
| 984 // Source size equals maximum size. StubClient will expect frames to be |
| 985 // kTestWidth by kTestHeight. |
| 986 SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight)); |
| 987 source()->SetSolidColor(SK_ColorRED); |
| 988 SimulateDrawEvent(); |
| 989 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 990 |
| 991 // Source size is half in both dimensions. StubClient will confirm the |
| 992 // aspect ratio of the resulting frames is correct. |
| 993 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
| 994 source()->SetSolidColor(SK_ColorGREEN); |
| 995 SimulateDrawEvent(); |
| 996 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
| 997 |
| 998 // Source size changes aspect ratio. StubClient will confirm the aspect |
| 999 // ratio of the resulting frames is correct. |
| 1000 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight)); |
| 1001 source()->SetSolidColor(SK_ColorBLUE); |
| 1002 SimulateDrawEvent(); |
| 1003 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLUE)); |
| 1004 |
| 1005 // Source size changes aspect ratio again. StubClient will confirm the |
| 1006 // aspect ratio of the resulting frames is correct. |
| 1007 SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight / 2)); |
| 1008 source()->SetSolidColor(SK_ColorBLACK); |
| 1009 SimulateDrawEvent(); |
| 1010 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLACK)); |
| 1011 } |
| 1012 |
| 1013 device()->StopAndDeAllocate(); |
| 1014 } |
| 1015 |
| 1016 // Tests that, when configured with the ANY_WITHIN_LIMIT resolution change |
| 1017 // policy, the source size changes result in video frames of possibly varying |
| 1018 // resolutions. |
| 1019 TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_AnyWithinLimits) { |
| 1020 media::VideoCaptureParams capture_params; |
| 1021 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 1022 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 1023 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 1024 capture_params.resolution_change_policy = |
| 1025 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; |
| 1026 |
| 1027 scoped_ptr<media::VideoCaptureDevice::Client> client = |
| 1028 client_observer()->PassClient(); |
| 1029 StubClient* const stub_client = static_cast<StubClient*>(client.get()); |
| 1030 stub_client->SetExpectedFrameSizeProperties( |
| 1031 gfx::Size(kTestWidth, kTestHeight), |
| 1032 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT); |
| 1033 device()->AllocateAndStart(capture_params, client.Pass()); |
| 1034 |
| 1035 for (int i = 0; i < 6; i++) { |
| 1036 const char* name = NULL; |
| 1037 switch (i % 3) { |
| 1038 case 0: |
| 1039 source()->SetCanCopyToVideoFrame(true); |
| 1040 source()->SetUseFrameSubscriber(false); |
| 1041 name = "VideoFrame"; |
| 1042 break; |
| 1043 case 1: |
| 1044 source()->SetCanCopyToVideoFrame(false); |
| 1045 source()->SetUseFrameSubscriber(true); |
| 1046 name = "Subscriber"; |
| 1047 break; |
| 1048 case 2: |
| 1049 source()->SetCanCopyToVideoFrame(false); |
| 1050 source()->SetUseFrameSubscriber(false); |
| 1051 name = "SkBitmap"; |
| 1052 break; |
| 1053 default: |
| 1054 FAIL(); |
| 1055 } |
| 1056 |
| 1057 SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
| 1058 |
| 1059 // Source size equals maximum size. StubClient will expect frames to be |
| 1060 // kTestWidth by kTestHeight. |
| 1061 SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight)); |
| 1062 source()->SetSolidColor(SK_ColorRED); |
| 1063 SimulateDrawEvent(); |
| 1064 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 1065 |
| 1066 // Source size is half in both dimensions. StubClient will confirm the |
| 1067 // resulting frame is also half in both dimensions. |
| 1068 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
| 1069 source()->SetSolidColor(SK_ColorGREEN); |
| 1070 SimulateDrawEvent(); |
| 1071 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
| 1072 |
| 1073 // Source size changes to something arbitrary. StubClient will confirm the |
| 1074 // resulting frame has the same dimensions. |
| 1075 SimulateSourceSizeChange(gfx::Size(kTestWidth / 2 + 42, |
| 1076 kTestHeight * 2 - 10)); |
| 1077 source()->SetSolidColor(SK_ColorBLUE); |
| 1078 SimulateDrawEvent(); |
| 1079 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLUE)); |
| 1080 |
| 1081 // Source size changes to something arbitrary that exceeds the maximum frame |
| 1082 // size. StubClient will confirm the resulting frame has dimensions within |
| 1083 // the maximum limit. |
| 1084 SimulateSourceSizeChange(gfx::Size(kTestWidth * 2 + 99, kTestHeight / 2)); |
| 1085 source()->SetSolidColor(SK_ColorBLACK); |
| 1086 SimulateDrawEvent(); |
| 1087 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLACK)); |
| 1088 } |
| 1089 |
| 1090 device()->StopAndDeAllocate(); |
| 1091 } |
| 1092 |
882 } // namespace | 1093 } // namespace |
883 } // namespace content | 1094 } // namespace content |
OLD | NEW |