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 // Unit test for VideoCaptureController. | 5 // Unit test for VideoCaptureController. |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "gpu/command_buffer/common/mailbox_holder.h" | 22 #include "gpu/command_buffer/common/mailbox_holder.h" |
23 #include "media/base/video_capture_types.h" | 23 #include "media/base/video_capture_types.h" |
24 #include "media/base/video_util.h" | 24 #include "media/base/video_util.h" |
25 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
27 | 27 |
28 #if !defined(OS_ANDROID) | 28 #if !defined(OS_ANDROID) |
29 #include "content/browser/compositor/test/no_transport_image_transport_factory.h
" | 29 #include "content/browser/compositor/test/no_transport_image_transport_factory.h
" |
30 #endif | 30 #endif |
31 | 31 |
| 32 using ::testing::_; |
32 using ::testing::InSequence; | 33 using ::testing::InSequence; |
33 using ::testing::Mock; | 34 using ::testing::Mock; |
| 35 using ::testing::SaveArg; |
34 | 36 |
35 namespace content { | 37 namespace content { |
36 | 38 |
37 class MockVideoCaptureControllerEventHandler | 39 class MockVideoCaptureControllerEventHandler |
38 : public VideoCaptureControllerEventHandler { | 40 : public VideoCaptureControllerEventHandler { |
39 public: | 41 public: |
40 explicit MockVideoCaptureControllerEventHandler( | 42 explicit MockVideoCaptureControllerEventHandler( |
41 VideoCaptureController* controller) | 43 VideoCaptureController* controller) |
42 : controller_(controller) {} | 44 : controller_(controller) {} |
43 virtual ~MockVideoCaptureControllerEventHandler() {} | 45 virtual ~MockVideoCaptureControllerEventHandler() {} |
44 | 46 |
45 // These mock methods are delegated to by our fake implementation of | 47 // These mock methods are delegated to by our fake implementation of |
46 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL(). | 48 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL(). |
47 MOCK_METHOD1(DoBufferCreated, void(VideoCaptureControllerID)); | 49 MOCK_METHOD1(DoBufferCreated, void(VideoCaptureControllerID)); |
48 MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID)); | 50 MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID)); |
49 MOCK_METHOD1(DoBufferReady, void(VideoCaptureControllerID)); | 51 MOCK_METHOD2(DoBufferReady, void(VideoCaptureControllerID, const gfx::Size&)); |
50 MOCK_METHOD1(DoMailboxBufferReady, void(VideoCaptureControllerID)); | 52 MOCK_METHOD1(DoMailboxBufferReady, void(VideoCaptureControllerID)); |
51 MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID)); | 53 MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID)); |
52 MOCK_METHOD1(DoError, void(VideoCaptureControllerID)); | 54 MOCK_METHOD1(DoError, void(VideoCaptureControllerID)); |
53 | 55 |
54 virtual void OnError(VideoCaptureControllerID id) override { | 56 virtual void OnError(VideoCaptureControllerID id) override { |
55 DoError(id); | 57 DoError(id); |
56 } | 58 } |
57 virtual void OnBufferCreated(VideoCaptureControllerID id, | 59 virtual void OnBufferCreated(VideoCaptureControllerID id, |
58 base::SharedMemoryHandle handle, | 60 base::SharedMemoryHandle handle, |
59 int length, int buffer_id) override { | 61 int length, int buffer_id) override { |
60 DoBufferCreated(id); | 62 DoBufferCreated(id); |
61 } | 63 } |
62 virtual void OnBufferDestroyed(VideoCaptureControllerID id, | 64 virtual void OnBufferDestroyed(VideoCaptureControllerID id, |
63 int buffer_id) override { | 65 int buffer_id) override { |
64 DoBufferDestroyed(id); | 66 DoBufferDestroyed(id); |
65 } | 67 } |
66 virtual void OnBufferReady( | 68 virtual void OnBufferReady( |
67 VideoCaptureControllerID id, | 69 VideoCaptureControllerID id, |
68 int buffer_id, | 70 int buffer_id, |
69 const gfx::Size& coded_size, | 71 const gfx::Size& coded_size, |
70 const gfx::Rect& visible_rect, | 72 const gfx::Rect& visible_rect, |
71 const base::TimeTicks& timestamp, | 73 const base::TimeTicks& timestamp, |
72 scoped_ptr<base::DictionaryValue> metadata) override { | 74 scoped_ptr<base::DictionaryValue> metadata) override { |
73 DoBufferReady(id); | 75 DoBufferReady(id, coded_size); |
74 base::MessageLoop::current()->PostTask( | 76 base::MessageLoop::current()->PostTask( |
75 FROM_HERE, | 77 FROM_HERE, |
76 base::Bind(&VideoCaptureController::ReturnBuffer, | 78 base::Bind(&VideoCaptureController::ReturnBuffer, |
77 base::Unretained(controller_), | 79 base::Unretained(controller_), |
78 id, | 80 id, |
79 this, | 81 this, |
80 buffer_id, | 82 buffer_id, |
81 0)); | 83 0)); |
82 } | 84 } |
83 virtual void OnMailboxBufferReady( | 85 virtual void OnMailboxBufferReady( |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 // side effect this will cause the first buffer to be shared with clients. | 326 // side effect this will cause the first buffer to be shared with clients. |
325 uint8 buffer_no = 1; | 327 uint8 buffer_no = 1; |
326 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer; | 328 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer; |
327 buffer = | 329 buffer = |
328 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); | 330 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); |
329 ASSERT_TRUE(buffer.get()); | 331 ASSERT_TRUE(buffer.get()); |
330 memset(buffer->data(), buffer_no++, buffer->size()); | 332 memset(buffer->data(), buffer_no++, buffer->size()); |
331 { | 333 { |
332 InSequence s; | 334 InSequence s; |
333 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1); | 335 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1); |
334 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1); | 336 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1); |
335 } | 337 } |
336 { | 338 { |
337 InSequence s; | 339 InSequence s; |
338 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(1); | 340 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(1); |
339 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1); | 341 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(1); |
340 } | 342 } |
341 { | 343 { |
342 InSequence s; | 344 InSequence s; |
343 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1); | 345 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1); |
344 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1); | 346 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1); |
345 } | 347 } |
346 device_->OnIncomingCapturedVideoFrame( | 348 device_->OnIncomingCapturedVideoFrame( |
347 buffer, | 349 buffer, |
348 WrapI420Buffer(buffer, capture_resolution), | 350 WrapI420Buffer(buffer, capture_resolution), |
349 base::TimeTicks()); | 351 base::TimeTicks()); |
350 buffer = NULL; | 352 buffer = NULL; |
351 | 353 |
352 base::RunLoop().RunUntilIdle(); | 354 base::RunLoop().RunUntilIdle(); |
353 Mock::VerifyAndClearExpectations(client_a_.get()); | 355 Mock::VerifyAndClearExpectations(client_a_.get()); |
354 Mock::VerifyAndClearExpectations(client_b_.get()); | 356 Mock::VerifyAndClearExpectations(client_b_.get()); |
355 | 357 |
356 // Second buffer which ought to use the same shared memory buffer. In this | 358 // Second buffer which ought to use the same shared memory buffer. In this |
357 // case pretend that the Buffer pointer is held by the device for a long | 359 // case pretend that the Buffer pointer is held by the device for a long |
358 // delay. This shouldn't affect anything. | 360 // delay. This shouldn't affect anything. |
359 buffer = | 361 buffer = |
360 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); | 362 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); |
361 ASSERT_TRUE(buffer.get()); | 363 ASSERT_TRUE(buffer.get()); |
362 memset(buffer->data(), buffer_no++, buffer->size()); | 364 memset(buffer->data(), buffer_no++, buffer->size()); |
363 device_->OnIncomingCapturedVideoFrame( | 365 device_->OnIncomingCapturedVideoFrame( |
364 buffer, | 366 buffer, |
365 WrapI420Buffer(buffer, capture_resolution), | 367 WrapI420Buffer(buffer, capture_resolution), |
366 base::TimeTicks()); | 368 base::TimeTicks()); |
367 buffer = NULL; | 369 buffer = NULL; |
368 | 370 |
369 // The buffer should be delivered to the clients in any order. | 371 // The buffer should be delivered to the clients in any order. |
370 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1); | 372 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1); |
371 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1); | 373 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(1); |
372 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1); | 374 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1); |
373 base::RunLoop().RunUntilIdle(); | 375 base::RunLoop().RunUntilIdle(); |
374 Mock::VerifyAndClearExpectations(client_a_.get()); | 376 Mock::VerifyAndClearExpectations(client_a_.get()); |
375 Mock::VerifyAndClearExpectations(client_b_.get()); | 377 Mock::VerifyAndClearExpectations(client_b_.get()); |
376 | 378 |
377 // Add a fourth client now that some buffers have come through. | 379 // Add a fourth client now that some buffers have come through. |
378 controller_->AddClient(client_b_route_2, | 380 controller_->AddClient(client_b_route_2, |
379 client_b_.get(), | 381 client_b_.get(), |
380 base::kNullProcessHandle, | 382 base::kNullProcessHandle, |
381 1, | 383 1, |
382 session_1); | 384 session_1); |
(...skipping 10 matching lines...) Expand all Loading... |
393 WrapI420Buffer(buffer, capture_resolution), | 395 WrapI420Buffer(buffer, capture_resolution), |
394 base::TimeTicks()); | 396 base::TimeTicks()); |
395 buffer = NULL; | 397 buffer = NULL; |
396 } | 398 } |
397 // ReserveOutputBuffer ought to fail now, because the pool is depleted. | 399 // ReserveOutputBuffer ought to fail now, because the pool is depleted. |
398 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, | 400 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, |
399 capture_resolution).get()); | 401 capture_resolution).get()); |
400 | 402 |
401 // The new client needs to be told of 3 buffers; the old clients only 2. | 403 // The new client needs to be told of 3 buffers; the old clients only 2. |
402 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); | 404 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); |
403 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(kPoolSize); | 405 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(kPoolSize); |
404 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)) | 406 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)) |
405 .Times(kPoolSize - 1); | 407 .Times(kPoolSize - 1); |
406 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(kPoolSize); | 408 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(kPoolSize); |
407 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)) | 409 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)) |
408 .Times(kPoolSize - 1); | 410 .Times(kPoolSize - 1); |
409 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(kPoolSize); | 411 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(kPoolSize); |
410 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)) | 412 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)) |
411 .Times(kPoolSize - 1); | 413 .Times(kPoolSize - 1); |
412 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(kPoolSize); | 414 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(kPoolSize); |
413 base::RunLoop().RunUntilIdle(); | 415 base::RunLoop().RunUntilIdle(); |
414 Mock::VerifyAndClearExpectations(client_a_.get()); | 416 Mock::VerifyAndClearExpectations(client_a_.get()); |
415 Mock::VerifyAndClearExpectations(client_b_.get()); | 417 Mock::VerifyAndClearExpectations(client_b_.get()); |
416 | 418 |
417 // Now test the interaction of client shutdown and buffer delivery. | 419 // Now test the interaction of client shutdown and buffer delivery. |
418 // Kill A1 via renderer disconnect (synchronous). | 420 // Kill A1 via renderer disconnect (synchronous). |
419 controller_->RemoveClient(client_a_route_1, client_a_.get()); | 421 controller_->RemoveClient(client_a_route_1, client_a_.get()); |
420 // Kill B1 via session close (posts a task to disconnect). | 422 // Kill B1 via session close (posts a task to disconnect). |
421 EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1); | 423 EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1); |
422 controller_->StopSession(300); | 424 controller_->StopSession(300); |
(...skipping 17 matching lines...) Expand all Loading... |
440 } | 442 } |
441 ASSERT_TRUE(buffer.get()); | 443 ASSERT_TRUE(buffer.get()); |
442 memset(buffer->data(), buffer_no++, buffer->size()); | 444 memset(buffer->data(), buffer_no++, buffer->size()); |
443 device_->OnIncomingCapturedVideoFrame( | 445 device_->OnIncomingCapturedVideoFrame( |
444 buffer, | 446 buffer, |
445 WrapI420Buffer(buffer, capture_resolution), | 447 WrapI420Buffer(buffer, capture_resolution), |
446 base::TimeTicks()); | 448 base::TimeTicks()); |
447 buffer = NULL; | 449 buffer = NULL; |
448 // B2 is the only client left, and is the only one that should | 450 // B2 is the only client left, and is the only one that should |
449 // get the buffer. | 451 // get the buffer. |
450 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(2); | 452 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(2); |
451 base::RunLoop().RunUntilIdle(); | 453 base::RunLoop().RunUntilIdle(); |
452 Mock::VerifyAndClearExpectations(client_a_.get()); | 454 Mock::VerifyAndClearExpectations(client_a_.get()); |
453 Mock::VerifyAndClearExpectations(client_b_.get()); | 455 Mock::VerifyAndClearExpectations(client_b_.get()); |
454 | 456 |
455 // Allocate all buffers from the buffer pool, half as SHM buffer and half as | 457 // Allocate all buffers from the buffer pool, half as SHM buffer and half as |
456 // mailbox buffers. Make sure of different counts though. | 458 // mailbox buffers. Make sure of different counts though. |
457 #if defined(OS_ANDROID) | 459 #if defined(OS_ANDROID) |
458 int mailbox_buffers = 0; | 460 int mailbox_buffers = 0; |
459 #else | 461 #else |
460 int mailbox_buffers = kPoolSize / 2; | 462 int mailbox_buffers = kPoolSize / 2; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 capture_resolution), | 495 capture_resolution), |
494 base::TimeTicks()); | 496 base::TimeTicks()); |
495 buffer = NULL; | 497 buffer = NULL; |
496 } | 498 } |
497 // ReserveOutputBuffers ought to fail now regardless of buffer format, because | 499 // ReserveOutputBuffers ought to fail now regardless of buffer format, because |
498 // the pool is depleted. | 500 // the pool is depleted. |
499 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, | 501 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, |
500 capture_resolution).get()); | 502 capture_resolution).get()); |
501 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::NATIVE_TEXTURE, | 503 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::NATIVE_TEXTURE, |
502 gfx::Size(0, 0)).get()); | 504 gfx::Size(0, 0)).get()); |
503 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(shm_buffers); | 505 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(shm_buffers); |
504 EXPECT_CALL(*client_b_, DoMailboxBufferReady(client_b_route_2)) | 506 EXPECT_CALL(*client_b_, DoMailboxBufferReady(client_b_route_2)) |
505 .Times(mailbox_buffers); | 507 .Times(mailbox_buffers); |
506 base::RunLoop().RunUntilIdle(); | 508 base::RunLoop().RunUntilIdle(); |
507 for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) { | 509 for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) { |
508 // A new release sync point must be inserted when the video frame is | 510 // A new release sync point must be inserted when the video frame is |
509 // returned to the Browser process. | 511 // returned to the Browser process. |
510 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and | 512 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and |
511 // VideoCaptureController::ReturnBuffer() | 513 // VideoCaptureController::ReturnBuffer() |
512 ASSERT_NE(mailbox_syncpoints[i], release_syncpoints[i]); | 514 ASSERT_NE(mailbox_syncpoints[i], release_syncpoints[i]); |
513 } | 515 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 TEST_F(VideoCaptureControllerTest, DataCaptureInEachVideoFormatInSequence) { | 613 TEST_F(VideoCaptureControllerTest, DataCaptureInEachVideoFormatInSequence) { |
612 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 614 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
613 // be used since it does not accept all pixel formats. The memory backed | 615 // be used since it does not accept all pixel formats. The memory backed |
614 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 616 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
615 // buffer. | 617 // buffer. |
616 const size_t kScratchpadSizeInBytes = 400; | 618 const size_t kScratchpadSizeInBytes = 400; |
617 unsigned char data[kScratchpadSizeInBytes]; | 619 unsigned char data[kScratchpadSizeInBytes]; |
618 const gfx::Size capture_resolution(10, 10); | 620 const gfx::Size capture_resolution(10, 10); |
619 ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u) | 621 ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u) |
620 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 622 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 623 |
| 624 const int kSessionId = 100; |
621 // This Test skips PIXEL_FORMAT_TEXTURE and PIXEL_FORMAT_UNKNOWN. | 625 // This Test skips PIXEL_FORMAT_TEXTURE and PIXEL_FORMAT_UNKNOWN. |
622 for (int format = 0; format < media::PIXEL_FORMAT_TEXTURE; ++format) { | 626 for (int format = 0; format < media::PIXEL_FORMAT_TEXTURE; ++format) { |
623 media::VideoCaptureParams params; | 627 media::VideoCaptureParams params; |
624 params.requested_format = media::VideoCaptureFormat( | 628 params.requested_format = media::VideoCaptureFormat( |
625 capture_resolution, 30, media::VideoPixelFormat(format)); | 629 capture_resolution, 30, media::VideoPixelFormat(format)); |
626 | 630 |
627 const gfx::Size capture_resolution(320, 240); | |
628 | |
629 const VideoCaptureControllerID route(0x99); | |
630 | |
631 // Start with one client. | 631 // Start with one client. |
632 controller_->AddClient(route, | 632 const VideoCaptureControllerID route_id(0x99); |
| 633 controller_->AddClient(route_id, |
633 client_a_.get(), | 634 client_a_.get(), |
634 base::kNullProcessHandle, | 635 base::kNullProcessHandle, |
635 100, | 636 kSessionId, |
636 params); | 637 params); |
637 ASSERT_EQ(1, controller_->GetClientCount()); | 638 ASSERT_EQ(1, controller_->GetClientCount()); |
638 device_->OnIncomingCapturedData( | 639 device_->OnIncomingCapturedData( |
639 data, | 640 data, |
640 params.requested_format.ImageAllocationSize(), | 641 params.requested_format.ImageAllocationSize(), |
641 params.requested_format, | 642 params.requested_format, |
642 0 /* rotation */, | 643 0 /* clockwise_rotation */, |
643 base::TimeTicks()); | 644 base::TimeTicks()); |
644 EXPECT_EQ(100, controller_->RemoveClient(route, client_a_.get())); | 645 EXPECT_EQ(kSessionId, controller_->RemoveClient(route_id, client_a_.get())); |
645 Mock::VerifyAndClearExpectations(client_a_.get()); | 646 Mock::VerifyAndClearExpectations(client_a_.get()); |
646 } | 647 } |
647 } | 648 } |
| 649 |
| 650 // Test that we receive the expected resolution for a given captured frame |
| 651 // resolution and rotation. Odd resolutions are also cropped. |
| 652 TEST_F(VideoCaptureControllerTest, CheckRotationsAndCrops) { |
| 653 const int kSessionId = 100; |
| 654 const struct SizeAndRotation { |
| 655 gfx::Size input_resolution; |
| 656 int rotation; |
| 657 gfx::Size output_resolution; |
| 658 } kSizeAndRotations[] = {{{6, 4}, 0, {6, 4}}, |
| 659 {{6, 4}, 90, {4, 6}}, |
| 660 {{6, 4}, 180, {6, 4}}, |
| 661 {{6, 4}, 270, {4, 6}}, |
| 662 {{7, 4}, 0, {6, 4}}, |
| 663 {{7, 4}, 90, {4, 6}}, |
| 664 {{7, 4}, 180, {6, 4}}, |
| 665 {{7, 4}, 270, {4, 6}}}; |
| 666 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
| 667 // be used since it does not resolve rotations or crops. The memory backed |
| 668 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
| 669 // buffer. |
| 670 const size_t kScratchpadSizeInBytes = 400; |
| 671 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 672 |
| 673 media::VideoCaptureParams params; |
| 674 for (const auto& size_and_rotation : kSizeAndRotations) { |
| 675 ASSERT_GE(kScratchpadSizeInBytes, |
| 676 size_and_rotation.input_resolution.GetArea() * 4u) |
| 677 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 678 |
| 679 params.requested_format = media::VideoCaptureFormat( |
| 680 size_and_rotation.input_resolution, 30, media::PIXEL_FORMAT_ARGB); |
| 681 |
| 682 const VideoCaptureControllerID route_id(0x99); |
| 683 controller_->AddClient(route_id, client_a_.get(), base::kNullProcessHandle, |
| 684 kSessionId, params); |
| 685 ASSERT_EQ(1, controller_->GetClientCount()); |
| 686 |
| 687 device_->OnIncomingCapturedData( |
| 688 data, |
| 689 params.requested_format.ImageAllocationSize(), |
| 690 params.requested_format, |
| 691 size_and_rotation.rotation, |
| 692 base::TimeTicks()); |
| 693 gfx::Size coded_size; |
| 694 { |
| 695 InSequence s; |
| 696 EXPECT_CALL(*client_a_, DoBufferCreated(route_id)).Times(1); |
| 697 EXPECT_CALL(*client_a_, DoBufferReady(route_id, _)) |
| 698 .Times(1) |
| 699 .WillOnce(SaveArg<1>(&coded_size)); |
| 700 } |
| 701 base::RunLoop().RunUntilIdle(); |
| 702 |
| 703 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); |
| 704 EXPECT_EQ(coded_size.height(), |
| 705 size_and_rotation.output_resolution.height()); |
| 706 |
| 707 EXPECT_EQ(kSessionId, controller_->RemoveClient(route_id, client_a_.get())); |
| 708 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 709 } |
| 710 } |
648 | 711 |
649 } // namespace content | 712 } // namespace content |
OLD | NEW |