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