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 "content/browser/renderer_host/media/video_capture_controller.h" |
| 8 |
7 #include <stdint.h> | 9 #include <stdint.h> |
8 #include <string.h> | 10 #include <string.h> |
9 | |
10 #include <string> | 11 #include <string> |
| 12 #include <utility> |
11 | 13 |
12 #include "base/bind.h" | 14 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
14 #include "base/location.h" | 16 #include "base/location.h" |
15 #include "base/macros.h" | 17 #include "base/macros.h" |
16 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
17 #include "base/memory/scoped_ptr.h" | 19 #include "base/memory/scoped_ptr.h" |
18 #include "base/run_loop.h" | 20 #include "base/run_loop.h" |
19 #include "base/single_thread_task_runner.h" | 21 #include "base/single_thread_task_runner.h" |
20 #include "base/thread_task_runner_handle.h" | 22 #include "base/thread_task_runner_handle.h" |
21 #include "content/browser/renderer_host/media/media_stream_provider.h" | 23 #include "content/browser/renderer_host/media/media_stream_provider.h" |
22 #include "content/browser/renderer_host/media/video_capture_controller.h" | |
23 #include "content/browser/renderer_host/media/video_capture_controller_event_han
dler.h" | 24 #include "content/browser/renderer_host/media/video_capture_controller_event_han
dler.h" |
24 #include "content/browser/renderer_host/media/video_capture_manager.h" | 25 #include "content/browser/renderer_host/media/video_capture_manager.h" |
25 #include "content/common/media/media_stream_options.h" | 26 #include "content/common/media/media_stream_options.h" |
26 #include "content/public/test/test_browser_thread_bundle.h" | 27 #include "content/public/test/test_browser_thread_bundle.h" |
27 #include "media/base/video_capture_types.h" | 28 #include "media/base/video_capture_types.h" |
28 #include "media/base/video_frame_metadata.h" | 29 #include "media/base/video_frame_metadata.h" |
29 #include "media/base/video_util.h" | 30 #include "media/base/video_util.h" |
30 #include "testing/gmock/include/gmock/gmock.h" | 31 #include "testing/gmock/include/gmock/gmock.h" |
31 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
32 | 33 |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 EXPECT_CALL(*client_a_, | 314 EXPECT_CALL(*client_a_, |
314 DoI420BufferReady(client_a_route_2, capture_resolution)) | 315 DoI420BufferReady(client_a_route_2, capture_resolution)) |
315 .Times(1); | 316 .Times(1); |
316 } | 317 } |
317 scoped_refptr<media::VideoFrame> video_frame = | 318 scoped_refptr<media::VideoFrame> video_frame = |
318 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 319 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
319 ASSERT_FALSE(video_frame->metadata()->HasKey( | 320 ASSERT_FALSE(video_frame->metadata()->HasKey( |
320 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); | 321 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); |
321 client_a_->resource_utilization_ = 0.5; | 322 client_a_->resource_utilization_ = 0.5; |
322 client_b_->resource_utilization_ = -1.0; | 323 client_b_->resource_utilization_ = -1.0; |
323 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, | 324 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
324 base::TimeTicks()); | 325 base::TimeTicks()); |
325 | 326 |
326 base::RunLoop().RunUntilIdle(); | 327 base::RunLoop().RunUntilIdle(); |
327 Mock::VerifyAndClearExpectations(client_a_.get()); | 328 Mock::VerifyAndClearExpectations(client_a_.get()); |
328 Mock::VerifyAndClearExpectations(client_b_.get()); | 329 Mock::VerifyAndClearExpectations(client_b_.get()); |
329 // Expect VideoCaptureController set the metadata in |video_frame| to hold a | 330 // Expect VideoCaptureController set the metadata in |video_frame| to hold a |
330 // resource utilization of 0.5 (the largest of all reported values). | 331 // resource utilization of 0.5 (the largest of all reported values). |
331 double resource_utilization_in_metadata = -1.0; | 332 double resource_utilization_in_metadata = -1.0; |
332 ASSERT_TRUE(video_frame->metadata()->GetDouble( | 333 ASSERT_TRUE(video_frame->metadata()->GetDouble( |
333 media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 334 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
334 &resource_utilization_in_metadata)); | 335 &resource_utilization_in_metadata)); |
335 ASSERT_EQ(0.5, resource_utilization_in_metadata); | 336 ASSERT_EQ(0.5, resource_utilization_in_metadata); |
336 | 337 |
337 // Second buffer which ought to use the same shared memory buffer. In this | 338 // Second buffer which ought to use the same shared memory buffer. In this |
338 // case pretend that the Buffer pointer is held by the device for a long | 339 // case pretend that the Buffer pointer is held by the device for a long |
339 // delay. This shouldn't affect anything. | 340 // delay. This shouldn't affect anything. |
340 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 = | 341 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 = |
341 device_->ReserveOutputBuffer(capture_resolution, | 342 device_->ReserveOutputBuffer(capture_resolution, |
342 media::PIXEL_FORMAT_I420, | 343 media::PIXEL_FORMAT_I420, |
343 media::PIXEL_STORAGE_CPU); | 344 media::PIXEL_STORAGE_CPU); |
344 ASSERT_TRUE(buffer2.get()); | 345 ASSERT_TRUE(buffer2.get()); |
345 memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); | 346 memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); |
346 video_frame = WrapI420Buffer(capture_resolution, | 347 video_frame = WrapI420Buffer(capture_resolution, |
347 static_cast<uint8_t*>(buffer2->data())); | 348 static_cast<uint8_t*>(buffer2->data())); |
348 ASSERT_FALSE(video_frame->metadata()->HasKey( | 349 ASSERT_FALSE(video_frame->metadata()->HasKey( |
349 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); | 350 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); |
350 client_a_->resource_utilization_ = 0.5; | 351 client_a_->resource_utilization_ = 0.5; |
351 client_b_->resource_utilization_ = 3.14; | 352 client_b_->resource_utilization_ = 3.14; |
352 device_->OnIncomingCapturedVideoFrame(buffer2.Pass(), video_frame, | 353 device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame, |
353 base::TimeTicks()); | 354 base::TimeTicks()); |
354 | 355 |
355 // The buffer should be delivered to the clients in any order. | 356 // The buffer should be delivered to the clients in any order. |
356 EXPECT_CALL(*client_a_, | 357 EXPECT_CALL(*client_a_, |
357 DoI420BufferReady(client_a_route_1, capture_resolution)) | 358 DoI420BufferReady(client_a_route_1, capture_resolution)) |
358 .Times(1); | 359 .Times(1); |
359 EXPECT_CALL(*client_b_, | 360 EXPECT_CALL(*client_b_, |
360 DoI420BufferReady(client_b_route_1, capture_resolution)) | 361 DoI420BufferReady(client_b_route_1, capture_resolution)) |
361 .Times(1); | 362 .Times(1); |
362 EXPECT_CALL(*client_a_, | 363 EXPECT_CALL(*client_a_, |
(...skipping 21 matching lines...) Expand all Loading... |
384 // Third, fourth, and fifth buffers. Pretend they all arrive at the same time. | 385 // Third, fourth, and fifth buffers. Pretend they all arrive at the same time. |
385 for (int i = 0; i < kPoolSize; i++) { | 386 for (int i = 0; i < kPoolSize; i++) { |
386 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = | 387 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = |
387 device_->ReserveOutputBuffer(capture_resolution, | 388 device_->ReserveOutputBuffer(capture_resolution, |
388 media::PIXEL_FORMAT_I420, | 389 media::PIXEL_FORMAT_I420, |
389 media::PIXEL_STORAGE_CPU); | 390 media::PIXEL_STORAGE_CPU); |
390 ASSERT_TRUE(buffer.get()); | 391 ASSERT_TRUE(buffer.get()); |
391 memset(buffer->data(), buffer_no++, buffer->mapped_size()); | 392 memset(buffer->data(), buffer_no++, buffer->mapped_size()); |
392 video_frame = WrapI420Buffer(capture_resolution, | 393 video_frame = WrapI420Buffer(capture_resolution, |
393 static_cast<uint8_t*>(buffer->data())); | 394 static_cast<uint8_t*>(buffer->data())); |
394 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, | 395 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
395 base::TimeTicks()); | 396 base::TimeTicks()); |
396 } | 397 } |
397 // ReserveOutputBuffer ought to fail now, because the pool is depleted. | 398 // ReserveOutputBuffer ought to fail now, because the pool is depleted. |
398 ASSERT_FALSE( | 399 ASSERT_FALSE( |
399 device_->ReserveOutputBuffer(capture_resolution, | 400 device_->ReserveOutputBuffer(capture_resolution, |
400 media::PIXEL_FORMAT_I420, | 401 media::PIXEL_FORMAT_I420, |
401 media::PIXEL_STORAGE_CPU).get()); | 402 media::PIXEL_STORAGE_CPU).get()); |
402 | 403 |
403 // 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. |
404 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); | 405 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); |
(...skipping 27 matching lines...) Expand all Loading... |
432 controller_->StopSession(300); | 433 controller_->StopSession(300); |
433 // Queue up another buffer. | 434 // Queue up another buffer. |
434 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 = | 435 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 = |
435 device_->ReserveOutputBuffer(capture_resolution, | 436 device_->ReserveOutputBuffer(capture_resolution, |
436 media::PIXEL_FORMAT_I420, | 437 media::PIXEL_FORMAT_I420, |
437 media::PIXEL_STORAGE_CPU); | 438 media::PIXEL_STORAGE_CPU); |
438 ASSERT_TRUE(buffer3.get()); | 439 ASSERT_TRUE(buffer3.get()); |
439 memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); | 440 memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); |
440 video_frame = WrapI420Buffer(capture_resolution, | 441 video_frame = WrapI420Buffer(capture_resolution, |
441 static_cast<uint8_t*>(buffer3->data())); | 442 static_cast<uint8_t*>(buffer3->data())); |
442 device_->OnIncomingCapturedVideoFrame(buffer3.Pass(), video_frame, | 443 device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame, |
443 base::TimeTicks()); | 444 base::TimeTicks()); |
444 | 445 |
445 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 = | 446 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 = |
446 device_->ReserveOutputBuffer(capture_resolution, | 447 device_->ReserveOutputBuffer(capture_resolution, |
447 media::PIXEL_FORMAT_I420, | 448 media::PIXEL_FORMAT_I420, |
448 media::PIXEL_STORAGE_CPU); | 449 media::PIXEL_STORAGE_CPU); |
449 { | 450 { |
450 // Kill A2 via session close (posts a task to disconnect, but A2 must not | 451 // Kill A2 via session close (posts a task to disconnect, but A2 must not |
451 // be sent either of these two buffers). | 452 // be sent either of these two buffers). |
452 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); | 453 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); |
453 controller_->StopSession(200); | 454 controller_->StopSession(200); |
454 } | 455 } |
455 ASSERT_TRUE(buffer4.get()); | 456 ASSERT_TRUE(buffer4.get()); |
456 memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); | 457 memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); |
457 video_frame = WrapI420Buffer(capture_resolution, | 458 video_frame = WrapI420Buffer(capture_resolution, |
458 static_cast<uint8_t*>(buffer4->data())); | 459 static_cast<uint8_t*>(buffer4->data())); |
459 device_->OnIncomingCapturedVideoFrame(buffer4.Pass(), video_frame, | 460 device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame, |
460 base::TimeTicks()); | 461 base::TimeTicks()); |
461 // B2 is the only client left, and is the only one that should | 462 // B2 is the only client left, and is the only one that should |
462 // get the buffer. | 463 // get the buffer. |
463 EXPECT_CALL(*client_b_, | 464 EXPECT_CALL(*client_b_, |
464 DoI420BufferReady(client_b_route_2, capture_resolution)) | 465 DoI420BufferReady(client_b_route_2, capture_resolution)) |
465 .Times(2); | 466 .Times(2); |
466 base::RunLoop().RunUntilIdle(); | 467 base::RunLoop().RunUntilIdle(); |
467 Mock::VerifyAndClearExpectations(client_a_.get()); | 468 Mock::VerifyAndClearExpectations(client_a_.get()); |
468 Mock::VerifyAndClearExpectations(client_b_.get()); | 469 Mock::VerifyAndClearExpectations(client_b_.get()); |
469 } | 470 } |
(...skipping 27 matching lines...) Expand all Loading... |
497 base::RunLoop().RunUntilIdle(); | 498 base::RunLoop().RunUntilIdle(); |
498 Mock::VerifyAndClearExpectations(client_b_.get()); | 499 Mock::VerifyAndClearExpectations(client_b_.get()); |
499 | 500 |
500 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 501 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
501 device_->ReserveOutputBuffer(capture_resolution, | 502 device_->ReserveOutputBuffer(capture_resolution, |
502 media::PIXEL_FORMAT_I420, | 503 media::PIXEL_FORMAT_I420, |
503 media::PIXEL_STORAGE_CPU)); | 504 media::PIXEL_STORAGE_CPU)); |
504 ASSERT_TRUE(buffer.get()); | 505 ASSERT_TRUE(buffer.get()); |
505 scoped_refptr<media::VideoFrame> video_frame = | 506 scoped_refptr<media::VideoFrame> video_frame = |
506 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 507 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
507 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, | 508 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
508 base::TimeTicks()); | 509 base::TimeTicks()); |
509 | 510 |
510 base::RunLoop().RunUntilIdle(); | 511 base::RunLoop().RunUntilIdle(); |
511 } | 512 } |
512 | 513 |
513 // Exercises the OnError() codepath of VideoCaptureController, and tests the | 514 // Exercises the OnError() codepath of VideoCaptureController, and tests the |
514 // behavior of various operations after the error state has been signalled. | 515 // behavior of various operations after the error state has been signalled. |
515 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { | 516 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { |
516 media::VideoCaptureParams session_100; | 517 media::VideoCaptureParams session_100; |
517 session_100.requested_format = media::VideoCaptureFormat( | 518 session_100.requested_format = media::VideoCaptureFormat( |
(...skipping 17 matching lines...) Expand all Loading... |
535 | 536 |
536 const gfx::Size dims(320, 240); | 537 const gfx::Size dims(320, 240); |
537 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 538 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
538 device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420, | 539 device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420, |
539 media::PIXEL_STORAGE_CPU)); | 540 media::PIXEL_STORAGE_CPU)); |
540 ASSERT_TRUE(buffer.get()); | 541 ASSERT_TRUE(buffer.get()); |
541 | 542 |
542 scoped_refptr<media::VideoFrame> video_frame = | 543 scoped_refptr<media::VideoFrame> video_frame = |
543 WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); | 544 WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); |
544 device_->OnError(FROM_HERE, "Test Error"); | 545 device_->OnError(FROM_HERE, "Test Error"); |
545 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, | 546 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
546 base::TimeTicks()); | 547 base::TimeTicks()); |
547 | 548 |
548 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); | 549 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); |
549 base::RunLoop().RunUntilIdle(); | 550 base::RunLoop().RunUntilIdle(); |
550 Mock::VerifyAndClearExpectations(client_a_.get()); | 551 Mock::VerifyAndClearExpectations(client_a_.get()); |
551 | 552 |
552 // Second client connects after the error state. It also should get told of | 553 // Second client connects after the error state. It also should get told of |
553 // the error. | 554 // the error. |
554 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); | 555 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); |
555 controller_->AddClient( | 556 controller_->AddClient( |
556 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); | 557 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); |
557 Mock::VerifyAndClearExpectations(client_b_.get()); | 558 Mock::VerifyAndClearExpectations(client_b_.get()); |
558 } | 559 } |
559 | 560 |
560 } // namespace content | 561 } // namespace content |
OLD | NEW |