OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 30 matching lines...) Expand all Loading... |
41 static class RendererCallbacks implements VideoRenderer.Callbacks { | 41 static class RendererCallbacks implements VideoRenderer.Callbacks { |
42 private int framesRendered = 0; | 42 private int framesRendered = 0; |
43 private Object frameLock = 0; | 43 private Object frameLock = 0; |
44 | 44 |
45 @Override | 45 @Override |
46 public void renderFrame(I420Frame frame) { | 46 public void renderFrame(I420Frame frame) { |
47 synchronized (frameLock) { | 47 synchronized (frameLock) { |
48 ++framesRendered; | 48 ++framesRendered; |
49 frameLock.notify(); | 49 frameLock.notify(); |
50 } | 50 } |
| 51 VideoRenderer.renderFrameDone(frame); |
51 } | 52 } |
52 | 53 |
53 public int WaitForNextFrameToRender() throws InterruptedException { | 54 public int WaitForNextFrameToRender() throws InterruptedException { |
54 synchronized (frameLock) { | 55 synchronized (frameLock) { |
55 frameLock.wait(); | 56 frameLock.wait(); |
56 return framesRendered; | 57 return framesRendered; |
57 } | 58 } |
58 } | 59 } |
59 } | 60 } |
60 | 61 |
| 62 static class AsyncRenderer implements VideoRenderer.Callbacks { |
| 63 private final List<I420Frame> pendingFrames = new ArrayList<I420Frame>(); |
| 64 |
| 65 @Override |
| 66 public void renderFrame(I420Frame frame) { |
| 67 synchronized (pendingFrames) { |
| 68 pendingFrames.add(frame); |
| 69 pendingFrames.notifyAll(); |
| 70 } |
| 71 } |
| 72 |
| 73 // Wait until at least one frame have been received, before returning them. |
| 74 public List<I420Frame> WaitForFrames() { |
| 75 synchronized (pendingFrames) { |
| 76 while (pendingFrames.isEmpty()) { |
| 77 try { |
| 78 pendingFrames.wait(); |
| 79 } catch (InterruptedException e) { |
| 80 // Ignore. |
| 81 } |
| 82 } |
| 83 final List<I420Frame> frames = new ArrayList<I420Frame>(pendingFrames); |
| 84 pendingFrames.clear(); |
| 85 return frames; |
| 86 } |
| 87 } |
| 88 } |
| 89 |
61 static class FakeCapturerObserver implements | 90 static class FakeCapturerObserver implements |
62 VideoCapturerAndroid.CapturerObserver { | 91 VideoCapturerAndroid.CapturerObserver { |
63 private int framesCaptured = 0; | 92 private int framesCaptured = 0; |
64 private int frameSize = 0; | 93 private int frameSize = 0; |
65 private Object frameLock = 0; | 94 private Object frameLock = 0; |
66 private Object capturerStartLock = 0; | 95 private Object capturerStartLock = 0; |
67 private boolean captureStartResult = false; | 96 private boolean captureStartResult = false; |
68 private List<Long> timestamps = new ArrayList<Long>(); | 97 private List<Long> timestamps = new ArrayList<Long>(); |
69 | 98 |
70 @Override | 99 @Override |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 | 328 |
300 observer.WaitForNextCapturedFrame(); | 329 observer.WaitForNextCapturedFrame(); |
301 capturer.stopCapture(); | 330 capturer.stopCapture(); |
302 | 331 |
303 listOftimestamps = observer.getCopyAndResetListOftimeStamps(); | 332 listOftimestamps = observer.getCopyAndResetListOftimeStamps(); |
304 assertTrue(listOftimestamps.size() >= 2); | 333 assertTrue(listOftimestamps.size() >= 2); |
305 for (Long timeStamp : listOftimestamps) { | 334 for (Long timeStamp : listOftimestamps) { |
306 capturer.returnBuffer(timeStamp); | 335 capturer.returnBuffer(timeStamp); |
307 } | 336 } |
308 } | 337 } |
| 338 |
| 339 @SmallTest |
| 340 // This test that we can capture frames, stop capturing, keep the frames for r
endering, and then |
| 341 // return the frames. It tests both the Java and the C++ layer. |
| 342 public void testCaptureAndAsyncRender() { |
| 343 final VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null); |
| 344 // Helper class that sets everything up, captures at least one frame, and th
en shuts |
| 345 // everything down. |
| 346 class CaptureFramesRunnable implements Runnable { |
| 347 public List<I420Frame> frames; |
| 348 |
| 349 @Override |
| 350 public void run() { |
| 351 PeerConnectionFactory factory = new PeerConnectionFactory(); |
| 352 VideoSource source = factory.createVideoSource(capturer, new MediaConstr
aints()); |
| 353 VideoTrack track = factory.createVideoTrack("dummy", source); |
| 354 AsyncRenderer renderer = new AsyncRenderer(); |
| 355 track.addRenderer(new VideoRenderer(renderer)); |
| 356 |
| 357 // Wait until we get at least one frame. |
| 358 frames = renderer.WaitForFrames(); |
| 359 |
| 360 // Stop everything. |
| 361 track.dispose(); |
| 362 source.dispose(); |
| 363 factory.dispose(); |
| 364 } |
| 365 } |
| 366 |
| 367 // Capture frames on a separate thread. |
| 368 CaptureFramesRunnable captureFramesRunnable = new CaptureFramesRunnable(); |
| 369 Thread captureThread = new Thread(captureFramesRunnable); |
| 370 captureThread.start(); |
| 371 |
| 372 // Wait until frames are captured, and then kill the thread. |
| 373 try { |
| 374 captureThread.join(); |
| 375 } catch (InterruptedException e) { |
| 376 fail("Capture thread was interrupted"); |
| 377 } |
| 378 captureThread = null; |
| 379 |
| 380 // Assert that we have frames that have not been returned. |
| 381 assertTrue(!captureFramesRunnable.frames.isEmpty()); |
| 382 // Return the frame(s). |
| 383 for (I420Frame frame : captureFramesRunnable.frames) { |
| 384 VideoRenderer.renderFrameDone(frame); |
| 385 } |
| 386 assertEquals(capturer.pendingFramesTimeStamps(), "[]"); |
| 387 } |
309 } | 388 } |
OLD | NEW |