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