• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 package org.webrtc;
12 
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertTrue;
15 
16 import android.os.Environment;
17 import androidx.test.filters.SmallTest;
18 import java.io.IOException;
19 import java.nio.ByteBuffer;
20 import java.nio.charset.Charset;
21 import java.util.ArrayList;
22 import org.junit.Before;
23 import org.junit.Test;
24 
25 public class FileVideoCapturerTest {
26   public static class MockCapturerObserver implements CapturerObserver {
27     private final ArrayList<VideoFrame> frames = new ArrayList<VideoFrame>();
28 
29     @Override
onCapturerStarted(boolean success)30     public void onCapturerStarted(boolean success) {
31       assertTrue(success);
32     }
33 
34     @Override
onCapturerStopped()35     public void onCapturerStopped() {
36       // Empty on purpose.
37     }
38 
39     @Override
40     // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
41     @SuppressWarnings("NoSynchronizedMethodCheck")
onFrameCaptured(VideoFrame frame)42     public synchronized void onFrameCaptured(VideoFrame frame) {
43       frame.retain();
44       frames.add(frame);
45       notify();
46     }
47 
48     // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
49     @SuppressWarnings("NoSynchronizedMethodCheck")
getMinimumFramesBlocking(int minFrames)50     public synchronized ArrayList<VideoFrame> getMinimumFramesBlocking(int minFrames)
51         throws InterruptedException {
52       while (frames.size() < minFrames) {
53         wait();
54       }
55       return new ArrayList<VideoFrame>(frames);
56     }
57   }
58 
59   @Before
setUp()60   public void setUp() {
61     NativeLibrary.initialize(new NativeLibrary.DefaultLoader(), TestConstants.NATIVE_LIBRARY);
62   }
63 
64   @Test
65   @SmallTest
testVideoCaptureFromFile()66   public void testVideoCaptureFromFile() throws InterruptedException, IOException {
67     final int FRAME_WIDTH = 4;
68     final int FRAME_HEIGHT = 4;
69     final int FRAME_CHROMA_WIDTH = (FRAME_WIDTH + 1) / 2;
70     final int FRAME_CHROMA_HEIGHT = (FRAME_HEIGHT + 1) / 2;
71     final int FRAME_SIZE_Y = FRAME_WIDTH * FRAME_HEIGHT;
72     final int FRAME_SIZE_CHROMA = FRAME_CHROMA_WIDTH * FRAME_CHROMA_HEIGHT;
73 
74     final FileVideoCapturer fileVideoCapturer =
75         new FileVideoCapturer(Environment.getExternalStorageDirectory().getPath()
76             + "/chromium_tests_root/sdk/android/instrumentationtests/src/org/webrtc/"
77             + "capturetestvideo.y4m");
78     final MockCapturerObserver capturerObserver = new MockCapturerObserver();
79     fileVideoCapturer.initialize(
80         null /* surfaceTextureHelper */, null /* applicationContext */, capturerObserver);
81     fileVideoCapturer.startCapture(FRAME_WIDTH, FRAME_HEIGHT, 33 /* fps */);
82 
83     final String[] expectedFrames = {
84         "THIS IS JUST SOME TEXT x", "THE SECOND FRAME qwerty.", "HERE IS THE THRID FRAME!"};
85 
86     final ArrayList<VideoFrame> frames =
87         capturerObserver.getMinimumFramesBlocking(expectedFrames.length);
88     assertEquals(expectedFrames.length, frames.size());
89 
90     fileVideoCapturer.stopCapture();
91     fileVideoCapturer.dispose();
92 
93     // Check the content of the frames.
94     for (int i = 0; i < expectedFrames.length; ++i) {
95       final VideoFrame frame = frames.get(i);
96       final VideoFrame.Buffer buffer = frame.getBuffer();
97       assertTrue(buffer instanceof VideoFrame.I420Buffer);
98       final VideoFrame.I420Buffer i420Buffer = (VideoFrame.I420Buffer) buffer;
99 
100       assertEquals(FRAME_WIDTH, i420Buffer.getWidth());
101       assertEquals(FRAME_HEIGHT, i420Buffer.getHeight());
102 
103       final ByteBuffer dataY = i420Buffer.getDataY();
104       final ByteBuffer dataU = i420Buffer.getDataU();
105       final ByteBuffer dataV = i420Buffer.getDataV();
106 
107       assertEquals(FRAME_SIZE_Y, dataY.remaining());
108       assertEquals(FRAME_SIZE_CHROMA, dataU.remaining());
109       assertEquals(FRAME_SIZE_CHROMA, dataV.remaining());
110 
111       ByteBuffer frameContents = ByteBuffer.allocate(FRAME_SIZE_Y + 2 * FRAME_SIZE_CHROMA);
112       frameContents.put(dataY);
113       frameContents.put(dataU);
114       frameContents.put(dataV);
115       frameContents.rewind(); // Move back to the beginning.
116 
117       assertByteBufferContents(
118           expectedFrames[i].getBytes(Charset.forName("US-ASCII")), frameContents);
119       frame.release();
120     }
121   }
122 
assertByteBufferContents(byte[] expected, ByteBuffer actual)123   private static void assertByteBufferContents(byte[] expected, ByteBuffer actual) {
124     assertEquals("Unexpected ByteBuffer size.", expected.length, actual.remaining());
125     for (int i = 0; i < expected.length; i++) {
126       assertEquals("Unexpected byte at index: " + i, expected[i], actual.get());
127     }
128   }
129 }
130