Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: content/browser/renderer_host/media/video_capture_controller_unittest.cc

Issue 1439533004: Remove dead code paths around PIXEL_STORAGE_TEXTURE in capture pipeline. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mcasas's second round comments REBASE Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/run_loop.h" 14 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/thread_task_runner_handle.h" 16 #include "base/thread_task_runner_handle.h"
17 #include "content/browser/renderer_host/media/media_stream_provider.h" 17 #include "content/browser/renderer_host/media/media_stream_provider.h"
18 #include "content/browser/renderer_host/media/video_capture_controller.h" 18 #include "content/browser/renderer_host/media/video_capture_controller.h"
19 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" 19 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h"
20 #include "content/browser/renderer_host/media/video_capture_manager.h" 20 #include "content/browser/renderer_host/media/video_capture_manager.h"
21 #include "content/common/gpu/client/gl_helper.h"
22 #include "content/common/media/media_stream_options.h" 21 #include "content/common/media/media_stream_options.h"
23 #include "content/public/test/test_browser_thread_bundle.h" 22 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "gpu/command_buffer/common/mailbox_holder.h"
25 #include "media/base/video_capture_types.h" 23 #include "media/base/video_capture_types.h"
26 #include "media/base/video_frame_metadata.h" 24 #include "media/base/video_frame_metadata.h"
27 #include "media/base/video_util.h" 25 #include "media/base/video_util.h"
28 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
30 28
31 #if !defined(OS_ANDROID)
32 #include "content/browser/compositor/test/no_transport_image_transport_factory.h "
33 #endif
34
35 using ::testing::_; 29 using ::testing::_;
36 using ::testing::InSequence; 30 using ::testing::InSequence;
37 using ::testing::Mock; 31 using ::testing::Mock;
38 using ::testing::SaveArg; 32 using ::testing::SaveArg;
39 33
40 namespace content { 34 namespace content {
41 35
42 class MockVideoCaptureControllerEventHandler 36 class MockVideoCaptureControllerEventHandler
43 : public VideoCaptureControllerEventHandler { 37 : public VideoCaptureControllerEventHandler {
44 public: 38 public:
45 explicit MockVideoCaptureControllerEventHandler( 39 explicit MockVideoCaptureControllerEventHandler(
46 VideoCaptureController* controller) 40 VideoCaptureController* controller)
47 : controller_(controller), 41 : controller_(controller),
48 resource_utilization_(-1.0) {} 42 resource_utilization_(-1.0) {}
49 ~MockVideoCaptureControllerEventHandler() override {} 43 ~MockVideoCaptureControllerEventHandler() override {}
50 44
51 // These mock methods are delegated to by our fake implementation of 45 // These mock methods are delegated to by our fake implementation of
52 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL(). 46 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL().
53 MOCK_METHOD1(DoBufferCreated, void(VideoCaptureControllerID)); 47 MOCK_METHOD1(DoBufferCreated, void(VideoCaptureControllerID));
54 MOCK_METHOD1(DoBufferCreated2, void(VideoCaptureControllerID)); 48 MOCK_METHOD1(DoBufferCreated2, void(VideoCaptureControllerID));
55 MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID)); 49 MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID));
56 MOCK_METHOD2(DoI420BufferReady, 50 MOCK_METHOD2(DoI420BufferReady,
57 void(VideoCaptureControllerID, const gfx::Size&)); 51 void(VideoCaptureControllerID, const gfx::Size&));
58 MOCK_METHOD2(DoTextureBufferReady,
59 void(VideoCaptureControllerID, const gfx::Size&));
60 MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID)); 52 MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID));
61 MOCK_METHOD1(DoError, void(VideoCaptureControllerID)); 53 MOCK_METHOD1(DoError, void(VideoCaptureControllerID));
62 54
63 void OnError(VideoCaptureControllerID id) override { 55 void OnError(VideoCaptureControllerID id) override {
64 DoError(id); 56 DoError(id);
65 } 57 }
66 void OnBufferCreated(VideoCaptureControllerID id, 58 void OnBufferCreated(VideoCaptureControllerID id,
67 base::SharedMemoryHandle handle, 59 base::SharedMemoryHandle handle,
68 int length, int buffer_id) override { 60 int length, int buffer_id) override {
69 DoBufferCreated(id); 61 DoBufferCreated(id);
70 } 62 }
71 void OnBufferCreated2( 63 void OnBufferCreated2(
72 VideoCaptureControllerID id, 64 VideoCaptureControllerID id,
73 const std::vector<gfx::GpuMemoryBufferHandle>& handles, 65 const std::vector<gfx::GpuMemoryBufferHandle>& handles,
74 const gfx::Size& size, 66 const gfx::Size& size,
75 int buffer_id) override { 67 int buffer_id) override {
76 DoBufferCreated2(id); 68 DoBufferCreated2(id);
77 } 69 }
78 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override { 70 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override {
79 DoBufferDestroyed(id); 71 DoBufferDestroyed(id);
80 } 72 }
81 void OnBufferReady(VideoCaptureControllerID id, 73 void OnBufferReady(VideoCaptureControllerID id,
82 int buffer_id, 74 int buffer_id,
83 const scoped_refptr<media::VideoFrame>& frame, 75 const scoped_refptr<media::VideoFrame>& frame,
84 const base::TimeTicks& timestamp) override { 76 const base::TimeTicks& timestamp) override {
85 if (!frame->HasTextures()) {
86 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); 77 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420);
87 DoI420BufferReady(id, frame->coded_size()); 78 DoI420BufferReady(id, frame->coded_size());
88 base::ThreadTaskRunnerHandle::Get()->PostTask( 79 base::ThreadTaskRunnerHandle::Get()->PostTask(
89 FROM_HERE, 80 FROM_HERE,
90 base::Bind(&VideoCaptureController::ReturnBuffer, 81 base::Bind(&VideoCaptureController::ReturnBuffer,
91 base::Unretained(controller_), id, this, buffer_id, 82 base::Unretained(controller_), id, this, buffer_id,
92 gpu::SyncToken(), resource_utilization_)); 83 gpu::SyncToken(), resource_utilization_));
93 } else {
94 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_ARGB);
95 DoTextureBufferReady(id, frame->coded_size());
96 base::ThreadTaskRunnerHandle::Get()->PostTask(
97 FROM_HERE, base::Bind(&VideoCaptureController::ReturnBuffer,
98 base::Unretained(controller_), id, this,
99 buffer_id, frame->mailbox_holder(0).sync_token,
100 resource_utilization_));
101 }
102 } 84 }
103 void OnEnded(VideoCaptureControllerID id) override { 85 void OnEnded(VideoCaptureControllerID id) override {
104 DoEnded(id); 86 DoEnded(id);
105 // OnEnded() must respond by (eventually) unregistering the client. 87 // OnEnded() must respond by (eventually) unregistering the client.
106 base::ThreadTaskRunnerHandle::Get()->PostTask( 88 base::ThreadTaskRunnerHandle::Get()->PostTask(
107 FROM_HERE, 89 FROM_HERE,
108 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient), 90 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient),
109 base::Unretained(controller_), id, this)); 91 base::Unretained(controller_), id, this));
110 } 92 }
111 93
(...skipping 16 matching lines...) Expand all
128 client_a_.reset(new MockVideoCaptureControllerEventHandler( 110 client_a_.reset(new MockVideoCaptureControllerEventHandler(
129 controller_.get())); 111 controller_.get()));
130 client_b_.reset(new MockVideoCaptureControllerEventHandler( 112 client_b_.reset(new MockVideoCaptureControllerEventHandler(
131 controller_.get())); 113 controller_.get()));
132 } 114 }
133 115
134 void TearDown() override { base::RunLoop().RunUntilIdle(); } 116 void TearDown() override { base::RunLoop().RunUntilIdle(); }
135 117
136 scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions, 118 scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions,
137 uint8* data) { 119 uint8* data) {
138 return media::VideoFrame::WrapExternalData( 120 return media::VideoFrame::WrapExternalSharedMemory(
139 media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), dimensions, 121 media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), dimensions,
140 data, 122 data,
141 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, dimensions), 123 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, dimensions),
142 base::TimeDelta()); 124 base::SharedMemory::NULLHandle(), 0u, base::TimeDelta());
143 }
144
145 scoped_refptr<media::VideoFrame> WrapMailboxBuffer(
146 const gpu::MailboxHolder& holder,
147 const media::VideoFrame::ReleaseMailboxCB& release_cb,
148 gfx::Size dimensions) {
149 return media::VideoFrame::WrapNativeTexture(
150 media::PIXEL_FORMAT_ARGB, holder, release_cb, dimensions,
151 gfx::Rect(dimensions), dimensions, base::TimeDelta());
152 } 125 }
153 126
154 TestBrowserThreadBundle bundle_; 127 TestBrowserThreadBundle bundle_;
155 scoped_ptr<MockVideoCaptureControllerEventHandler> client_a_; 128 scoped_ptr<MockVideoCaptureControllerEventHandler> client_a_;
156 scoped_ptr<MockVideoCaptureControllerEventHandler> client_b_; 129 scoped_ptr<MockVideoCaptureControllerEventHandler> client_b_;
157 scoped_ptr<VideoCaptureController> controller_; 130 scoped_ptr<VideoCaptureController> controller_;
158 scoped_ptr<media::VideoCaptureDevice::Client> device_; 131 scoped_ptr<media::VideoCaptureDevice::Client> device_;
159 132
160 private: 133 private:
161 DISALLOW_COPY_AND_ASSIGN(VideoCaptureControllerTest); 134 DISALLOW_COPY_AND_ASSIGN(VideoCaptureControllerTest);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 ASSERT_EQ(1, controller_->GetClientCount()) 227 ASSERT_EQ(1, controller_->GetClientCount())
255 << "Removing non-existant session 200 should be a no-op."; 228 << "Removing non-existant session 200 should be a no-op.";
256 ASSERT_EQ(400, 229 ASSERT_EQ(400,
257 controller_->RemoveClient(client_b_route_2, client_b_.get())) 230 controller_->RemoveClient(client_b_route_2, client_b_.get()))
258 << "Removing client B/2 should return its session_id."; 231 << "Removing client B/2 should return its session_id.";
259 // Clients in controller: [] 232 // Clients in controller: []
260 ASSERT_EQ(0, controller_->GetClientCount()) 233 ASSERT_EQ(0, controller_->GetClientCount())
261 << "Client count should return to zero after all clients are gone."; 234 << "Client count should return to zero after all clients are gone.";
262 } 235 }
263 236
264 static void CacheSyncToken(gpu::SyncToken* called_release_sync_token,
265 const gpu::SyncToken& release_sync_token) {
266 *called_release_sync_token = release_sync_token;
267 }
268
269 // This test will connect and disconnect several clients while simulating an 237 // This test will connect and disconnect several clients while simulating an
270 // active capture device being started and generating frames. It runs on one 238 // active capture device being started and generating frames. It runs on one
271 // thread and is intended to behave deterministically. 239 // thread and is intended to behave deterministically.
272 TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { 240 TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
273 // VideoCaptureController::ReturnBuffer() uses ImageTransportFactory.
274 #if !defined(OS_ANDROID)
275 ImageTransportFactory::InitializeForUnitTests(
276 scoped_ptr<ImageTransportFactory>(new NoTransportImageTransportFactory));
277 #endif
278
279 media::VideoCaptureParams session_100; 241 media::VideoCaptureParams session_100;
280 session_100.requested_format = media::VideoCaptureFormat( 242 session_100.requested_format = media::VideoCaptureFormat(
281 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); 243 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
282 244
283 media::VideoCaptureParams session_200 = session_100; 245 media::VideoCaptureParams session_200 = session_100;
284 246
285 media::VideoCaptureParams session_300 = session_100; 247 media::VideoCaptureParams session_300 = session_100;
286 248
287 media::VideoCaptureParams session_1 = session_100; 249 media::VideoCaptureParams session_1 = session_100;
288 250
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 device_->OnIncomingCapturedVideoFrame(buffer4.Pass(), video_frame, 455 device_->OnIncomingCapturedVideoFrame(buffer4.Pass(), video_frame,
494 base::TimeTicks()); 456 base::TimeTicks());
495 // B2 is the only client left, and is the only one that should 457 // B2 is the only client left, and is the only one that should
496 // get the buffer. 458 // get the buffer.
497 EXPECT_CALL(*client_b_, 459 EXPECT_CALL(*client_b_,
498 DoI420BufferReady(client_b_route_2, capture_resolution)) 460 DoI420BufferReady(client_b_route_2, capture_resolution))
499 .Times(2); 461 .Times(2);
500 base::RunLoop().RunUntilIdle(); 462 base::RunLoop().RunUntilIdle();
501 Mock::VerifyAndClearExpectations(client_a_.get()); 463 Mock::VerifyAndClearExpectations(client_a_.get());
502 Mock::VerifyAndClearExpectations(client_b_.get()); 464 Mock::VerifyAndClearExpectations(client_b_.get());
503
504 // Allocate all buffers from the buffer pool, half as SHM buffer and half as
505 // mailbox buffers. Make sure of different counts though.
506 #if defined(OS_ANDROID)
507 int mailbox_buffers = 0;
508 #else
509 int mailbox_buffers = kPoolSize / 2;
510 #endif
511 int shm_buffers = kPoolSize - mailbox_buffers;
512 if (shm_buffers == mailbox_buffers) {
513 shm_buffers--;
514 mailbox_buffers++;
515 }
516
517 for (int i = 0; i < shm_buffers; ++i) {
518 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
519 device_->ReserveOutputBuffer(capture_resolution,
520 media::PIXEL_FORMAT_I420,
521 media::PIXEL_STORAGE_CPU);
522 ASSERT_TRUE(buffer.get());
523 video_frame =
524 WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
525 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
526 base::TimeTicks());
527 }
528 std::vector<gpu::SyncToken> mailbox_synctokens(mailbox_buffers);
529 std::vector<gpu::SyncToken> release_synctokens(mailbox_buffers);
530 for (int i = 0; i < mailbox_buffers; ++i) {
531 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
532 device_->ReserveOutputBuffer(capture_resolution,
533 media::PIXEL_FORMAT_ARGB,
534 media::PIXEL_STORAGE_TEXTURE);
535 ASSERT_TRUE(buffer.get());
536 #if !defined(OS_ANDROID)
537 ImageTransportFactory::GetInstance()->GetGLHelper()->GenerateSyncToken(
538 &mailbox_synctokens[i]);
539 #endif
540 device_->OnIncomingCapturedVideoFrame(
541 buffer.Pass(),
542 WrapMailboxBuffer(gpu::MailboxHolder(gpu::Mailbox::Generate(),
543 mailbox_synctokens[i], 0),
544 base::Bind(&CacheSyncToken, &release_synctokens[i]),
545 capture_resolution),
546 base::TimeTicks());
547 }
548 // ReserveOutputBuffers ought to fail now regardless of buffer format, because
549 // the pool is depleted.
550 ASSERT_FALSE(
551 device_->ReserveOutputBuffer(capture_resolution,
552 media::PIXEL_FORMAT_I420,
553 media::PIXEL_STORAGE_CPU).get());
554 ASSERT_FALSE(
555 device_->ReserveOutputBuffer(capture_resolution,
556 media::PIXEL_FORMAT_ARGB,
557 media::PIXEL_STORAGE_TEXTURE).get());
558 EXPECT_CALL(*client_b_,
559 DoI420BufferReady(client_b_route_2, capture_resolution))
560 .Times(shm_buffers);
561 EXPECT_CALL(*client_b_,
562 DoTextureBufferReady(client_b_route_2, capture_resolution))
563 .Times(mailbox_buffers);
564 #if !defined(OS_ANDROID)
565 EXPECT_CALL(*client_b_, DoBufferDestroyed(client_b_route_2));
566 #endif
567 base::RunLoop().RunUntilIdle();
568 for (size_t i = 0; i < mailbox_synctokens.size(); ++i) {
569 // A new release sync point must be inserted when the video frame is
570 // returned to the Browser process.
571 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and
572 // VideoCaptureController::ReturnBuffer()
573 ASSERT_NE(mailbox_synctokens[i], release_synctokens[i]);
574 }
575 Mock::VerifyAndClearExpectations(client_b_.get());
576
577 #if !defined(OS_ANDROID)
578 ImageTransportFactory::Terminate();
579 #endif
580 } 465 }
581 466
582 // Exercises the OnError() codepath of VideoCaptureController, and tests the 467 // Exercises the OnError() codepath of VideoCaptureController, and tests the
583 // behavior of various operations after the error state has been signalled. 468 // behavior of various operations after the error state has been signalled.
584 TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) { 469 TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
585 media::VideoCaptureParams session_100; 470 media::VideoCaptureParams session_100;
586 session_100.requested_format = media::VideoCaptureFormat( 471 session_100.requested_format = media::VideoCaptureFormat(
587 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); 472 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
588 473
589 media::VideoCaptureParams session_200 = session_100; 474 media::VideoCaptureParams session_200 = session_100;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 547
663 // Second client connects after the error state. It also should get told of 548 // Second client connects after the error state. It also should get told of
664 // the error. 549 // the error.
665 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); 550 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1);
666 controller_->AddClient( 551 controller_->AddClient(
667 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); 552 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200);
668 Mock::VerifyAndClearExpectations(client_b_.get()); 553 Mock::VerifyAndClearExpectations(client_b_.get());
669 } 554 }
670 555
671 } // namespace content 556 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698