 Chromium Code Reviews
 Chromium Code Reviews Issue 2415563002:
  Testing of VideoFileRenderer with byte frames  (Closed)
    
  
    Issue 2415563002:
  Testing of VideoFileRenderer with byte frames  (Closed) 
  | Index: webrtc/examples/androidtests/src/org/appspot/apprtc/test/VideoFileRendererTest.java | 
| diff --git a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/VideoFileRendererTest.java b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/VideoFileRendererTest.java | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..2acc7b7b65009fcf93bb58bf32895e63095d8469 | 
| --- /dev/null | 
| +++ b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/VideoFileRendererTest.java | 
| @@ -0,0 +1,89 @@ | 
| +/* | 
| + * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 
| + * | 
| + * Use of this source code is governed by a BSD-style license | 
| + * that can be found in the LICENSE file in the root of the source | 
| + * tree. An additional intellectual property rights grant can be found | 
| + * in the file PATENTS. All contributing project authors may | 
| + * be found in the AUTHORS file in the root of the source tree. | 
| + */ | 
| + | 
| +package org.webrtc; | 
| + | 
| +import android.test.InstrumentationTestCase; | 
| +import android.test.suitebuilder.annotation.SmallTest; | 
| + | 
| +import java.io.IOException; | 
| +import java.io.RandomAccessFile; | 
| +import java.lang.Thread; | 
| +import java.nio.ByteBuffer; | 
| +import java.util.ArrayList; | 
| +import java.util.Random; | 
| + | 
| +public class VideoFileRendererTest extends InstrumentationTestCase { | 
| + @SmallTest | 
| + public void testYuvRenderingToFile() throws InterruptedException, IOException { | 
| + EglBase eglBase = EglBase.create(); | 
| + final int outputWidth = 64; | 
| + final int outputHeight = 64; | 
| + final String videoOutpath = "/sdcard/chromium_tests_root/testvideoout.y4m"; | 
| + VideoFileRenderer videoFileRenderer = | 
| + new VideoFileRenderer(videoOutpath, outputWidth, outputHeight, eglBase.getEglBaseContext()); | 
| + | 
| + final int inputWidth = 32; | 
| + final int inputHeight = 32; | 
| + for (int frameIdx = 0; frameIdx < 4; frameIdx++) { | 
| + // Same seed everytime | 
| + Random random = new Random(frameIdx); | 
| 
magjed_webrtc
2016/10/20 14:21:07
You only need to seed once. Please declare the Ran
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| + ByteBuffer[] yuvPlanes = new ByteBuffer[3]; | 
| + int inputFrameSize = inputWidth * inputHeight * 3 / 2; | 
| + int[] planeSizes = { | 
| + inputWidth * inputWidth, inputWidth * inputHeight / 4, inputWidth * inputHeight / 4}; | 
| + int[] yuvStrides = {inputWidth, inputWidth / 2, inputWidth / 2}; | 
| 
magjed_webrtc
2016/10/20 14:21:07
Move this variable closer to where you use it.
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| + for (int i = 0; i < 3; i++) { | 
| + byte[] planeBytes = new byte[planeSizes[i]]; | 
| 
magjed_webrtc
2016/10/20 14:21:08
You can write this whole for loop body simpler wit
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| + random.nextBytes(planeBytes); | 
| + ByteBuffer buffer = ByteBuffer.allocateDirect(inputFrameSize); | 
| 
magjed_webrtc
2016/10/20 14:21:08
This should be planeSizes[i] instead of inputFrame
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| + buffer.put(planeBytes); | 
| + yuvPlanes[i] = buffer; | 
| + } | 
| + VideoRenderer.I420Frame frame = | 
| + new VideoRenderer.I420Frame(inputWidth, inputHeight, 0, yuvStrides, yuvPlanes, 0); | 
| + | 
| + videoFileRenderer.renderFrame(frame); | 
| + } | 
| + videoFileRenderer.release(); | 
| + | 
| + RandomAccessFile writtenFile = new RandomAccessFile(videoOutpath, "r"); | 
| + StringBuilder builder = new StringBuilder(); | 
| + // Same seed everytime | 
| + Random verificationRandom = new Random(0); | 
| + // The expected data at the pseudo randomly choosen positions | 
| + final String expectedData = "275E6B837FB545456E49A397DD139B68B84C9760806D798063"; | 
| 
magjed_webrtc
2016/10/20 14:21:07
What's this? Why isn't the expected data based on
 
mandermo
2016/10/24 17:37:20
Now it is re-designed and compares pixel by pixel.
 | 
| + for (int i = 0; i < expectedData.length() / 2; i++) { | 
| + int pos = verificationRandom.nextInt((int) writtenFile.length()); | 
| + writtenFile.seek(pos); | 
| + builder.append(String.format("%02X", writtenFile.readByte())); | 
| + } | 
| + | 
| + assertEquals(expectedData, builder.toString()); | 
| + | 
| + writtenFile.seek(0); | 
| + builder = new StringBuilder(); | 
| + for (;;) { | 
| 
magjed_webrtc
2016/10/20 14:41:03
It looks like you have implemented RandomAccessFil
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| + int c = writtenFile.read(); | 
| + if (c == -1) { | 
| + // End of file reached. | 
| + throw new RuntimeException("Found end of file before end of header for file"); | 
| + } | 
| + if (c == '\n') { | 
| + // End of header found. | 
| + break; | 
| + } | 
| + builder.append((char) c); | 
| + } | 
| + | 
| + // Assert that the header is correct | 
| + assertEquals("YUV4MPEG2 C420 W64 H64 Ip F30:1 A1:1", builder.toString()); | 
| 
magjed_webrtc
2016/10/20 14:21:08
It feels more natural to check the header before c
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| + } | 
| 
magjed_webrtc
2016/10/20 14:21:08
You need to clean up after the test and remove /sd
 
mandermo
2016/10/24 17:37:20
Done.
 | 
| +} |