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(); | |
Wez
2015/05/14 01:44:56
nit: Reimpl this in terms of SetBounds() via gfx::
miu
2015/05/14 21:12:27
Done.
| |
179 } | |
180 | |
181 void SetBounds(const gfx::Rect& rect) override { | |
182 fake_bounds_ = rect; | |
183 rwh_->WasResized(); | |
miu
2015/05/14 21:12:27
FYI--I found a bug, where WasResized() wasn't noti
| |
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. | |
Wez
2015/05/14 01:44:56
Bug # for that change?
Looking at the code, doesn
miu
2015/05/14 21:12:27
Done. http://crbug.com/487939
FYI--I reworked a
| |
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, | |
miu
2015/05/14 21:12:27
FYI--This was moved into StubClientObserver, since
| |
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_; | |
Wez
2015/05/14 01:44:56
This is a misleading name, since it's not the actu
miu
2015/05/14 21:12:27
Done.
| |
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 |