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, |
11 * this list of conditions and the following disclaimer in the documentation | 11 * this list of conditions and the following disclaimer in the documentation |
12 * and/or other materials provided with the distribution. | 12 * and/or other materials provided with the distribution. |
13 * 3. The name of the author may not be used to endorse or promote products | 13 * 3. The name of the author may not be used to endorse or promote products |
14 * derived from this software without specific prior written permission. | 14 * derived from this software without specific prior written permission. |
15 * | 15 * |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 package org.webrtc; | 27 package org.webrtc; |
28 | 28 |
29 import java.nio.ByteBuffer; | 29 import android.annotation.TargetApi; |
30 | 30 import android.opengl.GLES11Ext; |
| 31 import android.opengl.GLES20; |
| 32 import android.os.Build; |
31 import android.test.ActivityTestCase; | 33 import android.test.ActivityTestCase; |
32 import android.test.suitebuilder.annotation.SmallTest; | 34 import android.test.suitebuilder.annotation.SmallTest; |
33 import android.util.Log; | 35 import android.util.Log; |
34 | 36 |
35 import org.webrtc.MediaCodecVideoEncoder.OutputBufferInfo; | 37 import org.webrtc.MediaCodecVideoEncoder.OutputBufferInfo; |
36 | 38 |
| 39 import java.nio.ByteBuffer; |
| 40 |
| 41 import javax.microedition.khronos.egl.EGL10; |
| 42 |
| 43 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) |
37 public final class MediaCodecVideoEncoderTest extends ActivityTestCase { | 44 public final class MediaCodecVideoEncoderTest extends ActivityTestCase { |
38 final static String TAG = "MediaCodecVideoEncoderTest"; | 45 final static String TAG = "MediaCodecVideoEncoderTest"; |
39 | 46 |
40 @SmallTest | 47 @SmallTest |
41 public static void testInitReleaseUsingByteBuffer() { | 48 public static void testInitializeUsingByteBuffer() { |
42 if (!MediaCodecVideoEncoder.isVp8HwSupported()) { | 49 if (!MediaCodecVideoEncoder.isVp8HwSupported()) { |
43 Log.i(TAG, | 50 Log.i(TAG, |
44 "Hardware does not support VP8 encoding, skipping testInitReleaseUsi
ngByteBuffer"); | 51 "Hardware does not support VP8 encoding, skipping testInitReleaseUsi
ngByteBuffer"); |
45 return; | 52 return; |
46 } | 53 } |
47 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); | 54 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); |
48 assertTrue(encoder.initEncode( | 55 assertTrue(encoder.initEncode( |
49 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, 640, 480, 300, 30
)); | 56 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, 640, 480, 300, 30
, null)); |
50 encoder.release(); | 57 encoder.release(); |
51 } | 58 } |
52 | 59 |
| 60 @SmallTest |
| 61 public static void testInitilizeUsingTextures() { |
| 62 if (!MediaCodecVideoEncoder.isVp8HwSupportedUsingTextures()) { |
| 63 Log.i(TAG, "hardware does not support VP8 encoding, skipping testEncoderUs
ingTextures"); |
| 64 return; |
| 65 } |
| 66 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); |
| 67 assertTrue(encoder.initEncode( |
| 68 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, 640, 480, 300, 30
, |
| 69 EGL10.EGL_NO_CONTEXT)); |
| 70 encoder.release(); |
| 71 } |
| 72 |
| 73 @SmallTest |
| 74 public static void testInitializeUsingByteBufferReInitilizeUsingTextures() { |
| 75 if (!MediaCodecVideoEncoder.isVp8HwSupportedUsingTextures()) { |
| 76 Log.i(TAG, "hardware does not support VP8 encoding, skipping testEncoderUs
ingTextures"); |
| 77 return; |
| 78 } |
| 79 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); |
| 80 assertTrue(encoder.initEncode( |
| 81 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, 640, 480, 300, 30
, |
| 82 null)); |
| 83 encoder.release(); |
| 84 assertTrue(encoder.initEncode( |
| 85 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, 640, 480, 300, 30
, |
| 86 EGL10.EGL_NO_CONTEXT)); |
| 87 encoder.release(); |
| 88 } |
| 89 |
53 @SmallTest | 90 @SmallTest |
54 public static void testEncoderUsingByteBuffer() throws InterruptedException { | 91 public static void testEncoderUsingByteBuffer() throws InterruptedException { |
55 if (!MediaCodecVideoEncoder.isVp8HwSupported()) { | 92 if (!MediaCodecVideoEncoder.isVp8HwSupported()) { |
56 Log.i(TAG, "Hardware does not support VP8 encoding, skipping testEncoderUs
ingByteBuffer"); | 93 Log.i(TAG, "Hardware does not support VP8 encoding, skipping testEncoderUs
ingByteBuffer"); |
57 return; | 94 return; |
58 } | 95 } |
59 | 96 |
60 final int width = 640; | 97 final int width = 640; |
61 final int height = 480; | 98 final int height = 480; |
62 final int min_size = width * height * 3 / 2; | 99 final int min_size = width * height * 3 / 2; |
63 final long presentationTimestampUs = 2; | 100 final long presentationTimestampUs = 2; |
64 | 101 |
65 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); | 102 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); |
66 | 103 |
67 assertTrue(encoder.initEncode( | 104 assertTrue(encoder.initEncode( |
68 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, width, height, 30
0, 30)); | 105 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, width, height, 30
0, 30, null)); |
69 ByteBuffer[] inputBuffers = encoder.getInputBuffers(); | 106 ByteBuffer[] inputBuffers = encoder.getInputBuffers(); |
70 assertNotNull(inputBuffers); | 107 assertNotNull(inputBuffers); |
71 assertTrue(min_size <= inputBuffers[0].capacity()); | 108 assertTrue(min_size <= inputBuffers[0].capacity()); |
72 | 109 |
73 int bufferIndex; | 110 int bufferIndex; |
74 do { | 111 do { |
75 Thread.sleep(10); | 112 Thread.sleep(10); |
76 bufferIndex = encoder.dequeueInputBuffer(); | 113 bufferIndex = encoder.dequeueInputBuffer(); |
77 } while (bufferIndex == -1); // |-1| is returned when there is no buffer ava
ilable yet. | 114 } while (bufferIndex == -1); // |-1| is returned when there is no buffer ava
ilable yet. |
78 | 115 |
79 assertTrue(bufferIndex >= 0); | 116 assertTrue(bufferIndex >= 0); |
80 assertTrue(bufferIndex < inputBuffers.length); | 117 assertTrue(bufferIndex < inputBuffers.length); |
81 assertTrue(encoder.encodeBuffer(true, bufferIndex, min_size, presentationTim
estampUs)); | 118 assertTrue(encoder.encodeBuffer(true, bufferIndex, min_size, presentationTim
estampUs)); |
82 | 119 |
83 OutputBufferInfo info; | 120 OutputBufferInfo info; |
84 do { | 121 do { |
85 info = encoder.dequeueOutputBuffer(); | 122 info = encoder.dequeueOutputBuffer(); |
86 Thread.sleep(10); | 123 Thread.sleep(10); |
87 } while (info == null); | 124 } while (info == null); |
88 assertTrue(info.index >= 0); | 125 assertTrue(info.index >= 0); |
89 assertEquals(presentationTimestampUs, info.presentationTimestampUs); | 126 assertEquals(presentationTimestampUs, info.presentationTimestampUs); |
90 assertTrue(info.buffer.capacity() > 0); | 127 assertTrue(info.buffer.capacity() > 0); |
91 encoder.releaseOutputBuffer(info.index); | 128 encoder.releaseOutputBuffer(info.index); |
92 | 129 |
93 encoder.release(); | 130 encoder.release(); |
94 } | 131 } |
| 132 |
| 133 @SmallTest |
| 134 public static void testEncoderUsingTextures() throws InterruptedException { |
| 135 if (!MediaCodecVideoEncoder.isVp8HwSupportedUsingTextures()) { |
| 136 Log.i(TAG, "Hardware does not support VP8 encoding, skipping testEncoderUs
ingTextures"); |
| 137 return; |
| 138 } |
| 139 |
| 140 final int width = 640; |
| 141 final int height = 480; |
| 142 final long presentationTs = 2; |
| 143 |
| 144 final EglBase eglOesBase = new EglBase(EGL10.EGL_NO_CONTEXT, EglBase.ConfigT
ype.PIXEL_BUFFER); |
| 145 eglOesBase.createDummyPbufferSurface(); |
| 146 eglOesBase.makeCurrent(); |
| 147 int oesTextureId = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES)
; |
| 148 |
| 149 // TODO(perkj): This test is week since we don't fill the texture with valid
data with correct |
| 150 // width and height and verify the encoded data. Fill the OES texture and fi
gure out a way to |
| 151 // verify that the output make sense. |
| 152 |
| 153 MediaCodecVideoEncoder encoder = new MediaCodecVideoEncoder(); |
| 154 |
| 155 assertTrue(encoder.initEncode( |
| 156 MediaCodecVideoEncoder.VideoCodecType.VIDEO_CODEC_VP8, width, height, 30
0, 30, |
| 157 eglOesBase.getContext())); |
| 158 assertTrue(encoder.encodeTexture(true, oesTextureId, RendererCommon.identity
Matrix(), |
| 159 presentationTs)); |
| 160 GlUtil.checkNoGLES2Error("encodeTexture"); |
| 161 |
| 162 // It should be Ok to delete the texture after calling encodeTexture. |
| 163 GLES20.glDeleteTextures(1, new int[] {oesTextureId}, 0); |
| 164 |
| 165 OutputBufferInfo info = encoder.dequeueOutputBuffer(); |
| 166 while (info == null) { |
| 167 info = encoder.dequeueOutputBuffer(); |
| 168 Thread.sleep(20); |
| 169 } |
| 170 assertTrue(info.index != -1); |
| 171 assertTrue(info.buffer.capacity() > 0); |
| 172 encoder.releaseOutputBuffer(info.index); |
| 173 |
| 174 encoder.release(); |
| 175 eglOesBase.release(); |
| 176 } |
95 } | 177 } |
OLD | NEW |