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

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

Issue 23551011: From Video Capture, abolish OnFrameInfo and enable resolution changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix constant declaration issue. Created 7 years, 2 months 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 | Annotate | Revision Log
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"
(...skipping 22 matching lines...) Expand all
33 : public VideoCaptureControllerEventHandler { 33 : public VideoCaptureControllerEventHandler {
34 public: 34 public:
35 explicit MockVideoCaptureControllerEventHandler( 35 explicit MockVideoCaptureControllerEventHandler(
36 VideoCaptureController* controller) 36 VideoCaptureController* controller)
37 : controller_(controller) {} 37 : controller_(controller) {}
38 virtual ~MockVideoCaptureControllerEventHandler() {} 38 virtual ~MockVideoCaptureControllerEventHandler() {}
39 39
40 // These mock methods are delegated to by our fake implementation of 40 // These mock methods are delegated to by our fake implementation of
41 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL(). 41 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL().
42 MOCK_METHOD1(DoBufferCreated, void(const VideoCaptureControllerID&)); 42 MOCK_METHOD1(DoBufferCreated, void(const VideoCaptureControllerID&));
43 MOCK_METHOD1(DoBufferDestroyed, void(const VideoCaptureControllerID&));
43 MOCK_METHOD1(DoBufferReady, void(const VideoCaptureControllerID&)); 44 MOCK_METHOD1(DoBufferReady, void(const VideoCaptureControllerID&));
44 MOCK_METHOD1(DoFrameInfo, void(const VideoCaptureControllerID&));
45 MOCK_METHOD1(DoEnded, void(const VideoCaptureControllerID&)); 45 MOCK_METHOD1(DoEnded, void(const VideoCaptureControllerID&));
46 MOCK_METHOD1(DoError, void(const VideoCaptureControllerID&)); 46 MOCK_METHOD1(DoError, void(const VideoCaptureControllerID&));
47 47
48 virtual void OnError(const VideoCaptureControllerID& id) OVERRIDE { 48 virtual void OnError(const VideoCaptureControllerID& id) OVERRIDE {
49 DoError(id); 49 DoError(id);
50 } 50 }
51 virtual void OnBufferCreated(const VideoCaptureControllerID& id, 51 virtual void OnBufferCreated(const VideoCaptureControllerID& id,
52 base::SharedMemoryHandle handle, 52 base::SharedMemoryHandle handle,
53 int length, int buffer_id) OVERRIDE { 53 int length, int buffer_id) OVERRIDE {
54 DoBufferCreated(id); 54 DoBufferCreated(id);
55 } 55 }
56 virtual void OnBufferDestroyed(const VideoCaptureControllerID& id,
57 int buffer_id) OVERRIDE {
58 DoBufferDestroyed(id);
59 }
56 virtual void OnBufferReady(const VideoCaptureControllerID& id, 60 virtual void OnBufferReady(const VideoCaptureControllerID& id,
57 int buffer_id, 61 int buffer_id,
58 base::Time timestamp) OVERRIDE { 62 base::Time timestamp,
63 const media::VideoCaptureFormat& format) OVERRIDE {
59 DoBufferReady(id); 64 DoBufferReady(id);
60 base::MessageLoop::current()->PostTask(FROM_HERE, 65 base::MessageLoop::current()->PostTask(FROM_HERE,
61 base::Bind(&VideoCaptureController::ReturnBuffer, 66 base::Bind(&VideoCaptureController::ReturnBuffer,
62 base::Unretained(controller_), id, this, buffer_id)); 67 base::Unretained(controller_), id, this, buffer_id));
63 } 68 }
64 virtual void OnFrameInfo(
65 const VideoCaptureControllerID& id,
66 const media::VideoCaptureCapability& format) OVERRIDE {
67 DoFrameInfo(id);
68 }
69 virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE { 69 virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE {
70 DoEnded(id); 70 DoEnded(id);
71 // OnEnded() must respond by (eventually) unregistering the client. 71 // OnEnded() must respond by (eventually) unregistering the client.
72 base::MessageLoop::current()->PostTask(FROM_HERE, 72 base::MessageLoop::current()->PostTask(FROM_HERE,
73 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient), 73 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient),
74 base::Unretained(controller_), id, this)); 74 base::Unretained(controller_), id, this));
75 } 75 }
76 76
77 VideoCaptureController* controller_; 77 VideoCaptureController* controller_;
78 }; 78 };
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 215
216 media::VideoCaptureParams session_200 = session_100; 216 media::VideoCaptureParams session_200 = session_100;
217 session_200.session_id = 200; 217 session_200.session_id = 200;
218 218
219 media::VideoCaptureParams session_300 = session_100; 219 media::VideoCaptureParams session_300 = session_100;
220 session_300.session_id = 300; 220 session_300.session_id = 300;
221 221
222 media::VideoCaptureParams session_1 = session_100; 222 media::VideoCaptureParams session_1 = session_100;
223 session_1.session_id = 1; 223 session_1.session_id = 1;
224 224
225 gfx::Size capture_resolution(444, 200);
226
225 // The device format needn't match the VideoCaptureParams (the camera can do 227 // The device format needn't match the VideoCaptureParams (the camera can do
226 // what it wants). Pick something random to use for OnFrameInfo. 228 // what it wants). Pick something random to use for OnFrameInfo.
227 media::VideoCaptureCapability device_format( 229 media::VideoCaptureCapability device_format(
228 10, 10, 25, media::PIXEL_FORMAT_RGB24, 10, false, 230 10, 10, 25, media::PIXEL_FORMAT_RGB24, 10, false,
229 media::ConstantResolutionVideoCaptureDevice); 231 media::ConstantResolutionVideoCaptureDevice);
230 232
231 const VideoCaptureControllerID client_a_route_1(0xa1a1a1a1); 233 const VideoCaptureControllerID client_a_route_1(0xa1a1a1a1);
232 const VideoCaptureControllerID client_a_route_2(0xa2a2a2a2); 234 const VideoCaptureControllerID client_a_route_2(0xa2a2a2a2);
233 const VideoCaptureControllerID client_b_route_1(0xb1b1b1b1); 235 const VideoCaptureControllerID client_b_route_1(0xb1b1b1b1);
234 const VideoCaptureControllerID client_b_route_2(0xb2b2b2b2); 236 const VideoCaptureControllerID client_b_route_2(0xb2b2b2b2);
235 237
236 // Start with two clients. 238 // Start with two clients.
237 controller_->AddClient(client_a_route_1, client_a_.get(), 239 controller_->AddClient(client_a_route_1, client_a_.get(),
238 base::kNullProcessHandle, session_100); 240 base::kNullProcessHandle, session_100);
239 controller_->AddClient(client_b_route_1, client_b_.get(), 241 controller_->AddClient(client_b_route_1, client_b_.get(),
240 base::kNullProcessHandle, session_300); 242 base::kNullProcessHandle, session_300);
241 ASSERT_EQ(2, controller_->GetClientCount()); 243 controller_->AddClient(client_a_route_2, client_a_.get(),
244 base::kNullProcessHandle, session_200);
245 ASSERT_EQ(3, controller_->GetClientCount());
242 246
243 // The OnFrameInfo() event from the device, when processed by the controller, 247 // Now, simulate an incoming captured frame from the capture device. As a side
244 // should generate client OnFrameInfo() and OnBufferCreated() events. 248 // effect this will cause the first buffer to be shared with clients.
249 uint8 frame_no = 1;
250 scoped_refptr<media::VideoFrame> frame;
251 frame = device_->ReserveOutputBuffer(capture_resolution);
252 ASSERT_TRUE(frame);
253 media::FillYUV(frame, frame_no++, 0x22, 0x44);
245 { 254 {
246 InSequence s; 255 InSequence s;
247 EXPECT_CALL(*client_a_, DoFrameInfo(client_a_route_1)).Times(1); 256 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1);
248 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(kPoolSize); 257 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1);
249 } 258 }
250 { 259 {
251 InSequence s; 260 InSequence s;
252 EXPECT_CALL(*client_b_, DoFrameInfo(client_b_route_1)).Times(1); 261 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(1);
253 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(kPoolSize); 262 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1);
254 } 263 }
255 device_->OnFrameInfo(device_format); 264 {
265 InSequence s;
266 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1);
267 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1);
268 }
269 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
270 frame = NULL;
271
256 base::RunLoop().RunUntilIdle(); 272 base::RunLoop().RunUntilIdle();
257 Mock::VerifyAndClearExpectations(client_a_.get()); 273 Mock::VerifyAndClearExpectations(client_a_.get());
258 Mock::VerifyAndClearExpectations(client_b_.get()); 274 Mock::VerifyAndClearExpectations(client_b_.get());
259 275
260 // When a third clients is subsequently added, the frame info and buffers 276 // Second frame which ought to use the same shared memory buffer. In this case
261 // should immediately be shared to the new clients. 277 // pretend that the VideoFrame pointer is held by the device for a long delay.
262 { 278 // This shouldn't affect anything.
263 InSequence s; 279 frame = device_->ReserveOutputBuffer(capture_resolution);
264 EXPECT_CALL(*client_a_, DoFrameInfo(client_a_route_2)).Times(1);
265 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(kPoolSize);
266 }
267 controller_->AddClient(client_a_route_2, client_a_.get(),
268 base::kNullProcessHandle, session_200);
269 Mock::VerifyAndClearExpectations(client_a_.get());
270
271 // Now, simulate an incoming captured frame from the capture device.
272 uint8 frame_no = 1;
273 scoped_refptr<media::VideoFrame> frame;
274 frame = device_->ReserveOutputBuffer();
275 ASSERT_TRUE(frame);
276 media::FillYUV(frame, frame_no++, 0x22, 0x44);
277 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
278 frame = NULL;
279
280 // The buffer should be delivered to the clients in any order.
281 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1);
282 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1);
283 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1);
284 base::RunLoop().RunUntilIdle();
285 Mock::VerifyAndClearExpectations(client_a_.get());
286 Mock::VerifyAndClearExpectations(client_b_.get());
287
288 // Second frame. In this case pretend that the VideoFrame pointer is held
289 // by the device for a long delay. This shouldn't affect anything.
290 frame = device_->ReserveOutputBuffer();
291 ASSERT_TRUE(frame); 280 ASSERT_TRUE(frame);
292 media::FillYUV(frame, frame_no++, 0x22, 0x44); 281 media::FillYUV(frame, frame_no++, 0x22, 0x44);
293 device_->OnIncomingCapturedVideoFrame(frame, base::Time()); 282 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
294 283
295 // The buffer should be delivered to the clients in any order. 284 // The buffer should be delivered to the clients in any order.
296 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1); 285 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1);
286 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1);
297 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1); 287 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1);
298 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1);
299 base::RunLoop().RunUntilIdle(); 288 base::RunLoop().RunUntilIdle();
300 Mock::VerifyAndClearExpectations(client_a_.get()); 289 Mock::VerifyAndClearExpectations(client_a_.get());
301 Mock::VerifyAndClearExpectations(client_b_.get()); 290 Mock::VerifyAndClearExpectations(client_b_.get());
302 frame = NULL; 291 frame = NULL;
303 292
304 // Add a fourth client now that some frames have come through. It should get 293 // Add a fourth client now that some frames have come through.
305 // the buffer info, but it won't get any frames until new ones are captured.
306 {
307 InSequence s;
308 EXPECT_CALL(*client_b_, DoFrameInfo(client_b_route_2)).Times(1);
309 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize);
310 }
311 controller_->AddClient(client_b_route_2, client_b_.get(), 294 controller_->AddClient(client_b_route_2, client_b_.get(),
312 base::kNullProcessHandle, session_1); 295 base::kNullProcessHandle, session_1);
313 Mock::VerifyAndClearExpectations(client_b_.get()); 296 Mock::VerifyAndClearExpectations(client_b_.get());
314 297
315 // Third, fourth, and fifth frames. Pretend they all arrive at the same time. 298 // Third, fourth, and fifth frames. Pretend they all arrive at the same time.
316 for (int i = 0; i < kPoolSize; i++) { 299 for (int i = 0; i < kPoolSize; i++) {
317 frame = device_->ReserveOutputBuffer(); 300 frame = device_->ReserveOutputBuffer(capture_resolution);
318 ASSERT_TRUE(frame); 301 ASSERT_TRUE(frame);
319 ASSERT_EQ(media::VideoFrame::I420, frame->format()); 302 ASSERT_EQ(media::VideoFrame::I420, frame->format());
320 media::FillYUV(frame, frame_no++, 0x22, 0x44); 303 media::FillYUV(frame, frame_no++, 0x22, 0x44);
321 device_->OnIncomingCapturedVideoFrame(frame, base::Time()); 304 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
322 305
323 } 306 }
324 // ReserveOutputBuffer ought to fail now, because the pool is depleted. 307 // ReserveOutputBuffer ought to fail now, because the pool is depleted.
325 ASSERT_FALSE(device_->ReserveOutputBuffer()); 308 ASSERT_FALSE(device_->ReserveOutputBuffer(capture_resolution));
309
310 // The new client needs to be told of 3 buffers; the old clients only 2.
311 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize);
312 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(kPoolSize);
313 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1))
314 .Times(kPoolSize - 1);
326 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(kPoolSize); 315 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(kPoolSize);
316 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2))
317 .Times(kPoolSize - 1);
327 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(kPoolSize); 318 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(kPoolSize);
319 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1))
320 .Times(kPoolSize - 1);
328 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(kPoolSize); 321 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(kPoolSize);
329 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(kPoolSize);
330 base::RunLoop().RunUntilIdle(); 322 base::RunLoop().RunUntilIdle();
331 Mock::VerifyAndClearExpectations(client_a_.get()); 323 Mock::VerifyAndClearExpectations(client_a_.get());
332 Mock::VerifyAndClearExpectations(client_b_.get()); 324 Mock::VerifyAndClearExpectations(client_b_.get());
333 325
334 // Now test the interaction of client shutdown and frame delivery. 326 // Now test the interaction of client shutdown and frame delivery.
335 // Kill A1 via renderer disconnect (synchronous). 327 // Kill A1 via renderer disconnect (synchronous).
336 controller_->RemoveClient(client_a_route_1, client_a_.get()); 328 controller_->RemoveClient(client_a_route_1, client_a_.get());
337 // Kill B1 via session close (posts a task to disconnect). 329 // Kill B1 via session close (posts a task to disconnect).
338 EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1); 330 EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1);
339 controller_->StopSession(300); 331 controller_->StopSession(300);
340 // Queue up another frame. 332 // Queue up another frame.
341 frame = device_->ReserveOutputBuffer(); 333 frame = device_->ReserveOutputBuffer(capture_resolution);
342 ASSERT_TRUE(frame); 334 ASSERT_TRUE(frame);
343 media::FillYUV(frame, frame_no++, 0x22, 0x44); 335 media::FillYUV(frame, frame_no++, 0x22, 0x44);
344 device_->OnIncomingCapturedVideoFrame(frame, base::Time()); 336 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
345 frame = device_->ReserveOutputBuffer(); 337 frame = device_->ReserveOutputBuffer(capture_resolution);
346 { 338 {
347 // Kill A2 via session close (posts a task to disconnect, but A2 must not 339 // Kill A2 via session close (posts a task to disconnect, but A2 must not
348 // be sent either of these two frames).. 340 // be sent either of these two frames)..
349 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); 341 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1);
350 controller_->StopSession(200); 342 controller_->StopSession(200);
351 } 343 }
352 ASSERT_TRUE(frame); 344 ASSERT_TRUE(frame);
353 media::FillYUV(frame, frame_no++, 0x22, 0x44); 345 media::FillYUV(frame, frame_no++, 0x22, 0x44);
354 device_->OnIncomingCapturedVideoFrame(frame, base::Time()); 346 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
355 // B2 is the only client left, and is the only one that should 347 // B2 is the only client left, and is the only one that should
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 const VideoCaptureControllerID route_id(0x99); 406 const VideoCaptureControllerID route_id(0x99);
415 407
416 // Start with one client. 408 // Start with one client.
417 controller_->AddClient(route_id, client_a_.get(), 409 controller_->AddClient(route_id, client_a_.get(),
418 base::kNullProcessHandle, session_100); 410 base::kNullProcessHandle, session_100);
419 // OnFrameInfo from the VCD should become a no-op after the error occurs. 411 // OnFrameInfo from the VCD should become a no-op after the error occurs.
420 media::VideoCaptureCapability device_format( 412 media::VideoCaptureCapability device_format(
421 10, 10, 25, media::PIXEL_FORMAT_ARGB, 10, false, 413 10, 10, 25, media::PIXEL_FORMAT_ARGB, 10, false,
422 media::ConstantResolutionVideoCaptureDevice); 414 media::ConstantResolutionVideoCaptureDevice);
423 415
424 // Start the device and get as far as exchanging buffers with the subprocess. 416 // Start the device. Then, before the first frame, signal an error and deliver
425 // Then, signal an error and deliver the frame. The error should be propagated 417 // the frame. The error should be propagated to clients; the frame should not
426 // to clients; the frame should not be. 418 // be.
427 device_->OnFrameInfo(device_format);
428 EXPECT_CALL(*client_a_, DoFrameInfo(route_id)).Times(1);
429 EXPECT_CALL(*client_a_, DoBufferCreated(route_id)).Times(kPoolSize);
430 base::RunLoop().RunUntilIdle(); 419 base::RunLoop().RunUntilIdle();
431 Mock::VerifyAndClearExpectations(client_a_.get()); 420 Mock::VerifyAndClearExpectations(client_a_.get());
432 421
433 scoped_refptr<media::VideoFrame> frame = device_->ReserveOutputBuffer(); 422 scoped_refptr<media::VideoFrame> frame =
423 device_->ReserveOutputBuffer(gfx::Size(320, 240));
434 ASSERT_TRUE(frame); 424 ASSERT_TRUE(frame);
435 425
436 device_->OnError(); 426 device_->OnError();
437 device_->OnIncomingCapturedVideoFrame(frame, base::Time()); 427 device_->OnIncomingCapturedVideoFrame(frame, base::Time());
438 frame = NULL; 428 frame = NULL;
439 429
440 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); 430 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
441 base::RunLoop().RunUntilIdle(); 431 base::RunLoop().RunUntilIdle();
442 Mock::VerifyAndClearExpectations(client_a_.get()); 432 Mock::VerifyAndClearExpectations(client_a_.get());
443 433
444 // Second client connects after the error state. It also should get told of 434 // Second client connects after the error state. It also should get told of
445 // the error. 435 // the error.
446 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); 436 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1);
447 controller_->AddClient(route_id, client_b_.get(), 437 controller_->AddClient(route_id, client_b_.get(),
448 base::kNullProcessHandle, session_200); 438 base::kNullProcessHandle, session_200);
449 Mock::VerifyAndClearExpectations(client_b_.get()); 439 Mock::VerifyAndClearExpectations(client_b_.get());
450 } 440 }
451 441
452 } // namespace content 442 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698