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