OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.webrtc; | 11 package org.webrtc; |
12 | 12 |
13 import android.graphics.Point; | 13 import android.graphics.Point; |
14 import android.opengl.GLES20; | |
15 import android.opengl.Matrix; | 14 import android.opengl.Matrix; |
16 import android.view.View; | 15 import android.view.View; |
17 import java.nio.ByteBuffer; | |
18 | 16 |
19 /** | 17 /** |
20 * Static helper functions for renderer implementations. | 18 * Static helper functions for renderer implementations. |
21 */ | 19 */ |
22 public class RendererCommon { | 20 public class RendererCommon { |
23 /** Interface for reporting rendering events. */ | 21 /** Interface for reporting rendering events. */ |
24 public static interface RendererEvents { | 22 public static interface RendererEvents { |
25 /** | 23 /** |
26 * Callback fired once first frame is rendered. | 24 * Callback fired once first frame is rendered. |
27 */ | 25 */ |
(...skipping 19 matching lines...) Expand all Loading... |
47 void drawYuv(int[] yuvTextures, float[] texMatrix, int frameWidth, int frame
Height, | 45 void drawYuv(int[] yuvTextures, float[] texMatrix, int frameWidth, int frame
Height, |
48 int viewportX, int viewportY, int viewportWidth, int viewportHeight); | 46 int viewportX, int viewportY, int viewportWidth, int viewportHeight); |
49 | 47 |
50 /** | 48 /** |
51 * Release all GL resources. This needs to be done manually, otherwise resou
rces may leak. | 49 * Release all GL resources. This needs to be done manually, otherwise resou
rces may leak. |
52 */ | 50 */ |
53 void release(); | 51 void release(); |
54 } | 52 } |
55 | 53 |
56 /** | 54 /** |
57 * Draws a VideoFrame.TextureBuffer. Calls either drawer.drawOes or drawer.dra
wRgb | |
58 * depending on the type of the buffer. You can supply an additional render ma
trix. This is | |
59 * used multiplied together with the transformation matrix of the frame. (M =
renderMatrix * | |
60 * transformationMatrix) | |
61 */ | |
62 static void drawTexture(GlDrawer drawer, VideoFrame.TextureBuffer buffer, | |
63 android.graphics.Matrix renderMatrix, int frameWidth, int frameHeight, int
viewportX, | |
64 int viewportY, int viewportWidth, int viewportHeight) { | |
65 android.graphics.Matrix finalMatrix = new android.graphics.Matrix(buffer.get
TransformMatrix()); | |
66 finalMatrix.preConcat(renderMatrix); | |
67 float[] finalGlMatrix = convertMatrixFromAndroidGraphicsMatrix(finalMatrix); | |
68 switch (buffer.getType()) { | |
69 case OES: | |
70 drawer.drawOes(buffer.getTextureId(), finalGlMatrix, frameWidth, frameHe
ight, viewportX, | |
71 viewportY, viewportWidth, viewportHeight); | |
72 break; | |
73 case RGB: | |
74 drawer.drawRgb(buffer.getTextureId(), finalGlMatrix, frameWidth, frameHe
ight, viewportX, | |
75 viewportY, viewportWidth, viewportHeight); | |
76 break; | |
77 default: | |
78 throw new RuntimeException("Unknown texture type."); | |
79 } | |
80 } | |
81 | |
82 /** | |
83 * Helper class for uploading YUV bytebuffer frames to textures that handles s
tride > width. This | |
84 * class keeps an internal ByteBuffer to avoid unnecessary allocations for int
ermediate copies. | |
85 */ | |
86 public static class YuvUploader { | |
87 // Intermediate copy buffer for uploading yuv frames that are not packed, i.
e. stride > width. | |
88 // TODO(magjed): Investigate when GL_UNPACK_ROW_LENGTH is available, or make
a custom shader | |
89 // that handles stride and compare performance with intermediate copy. | |
90 private ByteBuffer copyBuffer; | |
91 private int[] yuvTextures; | |
92 | |
93 /** | |
94 * Upload |planes| into OpenGL textures, taking stride into consideration. | |
95 * | |
96 * @return Array of three texture indices corresponding to Y-, U-, and V-pla
ne respectively. | |
97 */ | |
98 public int[] uploadYuvData(int width, int height, int[] strides, ByteBuffer[
] planes) { | |
99 final int[] planeWidths = new int[] {width, width / 2, width / 2}; | |
100 final int[] planeHeights = new int[] {height, height / 2, height / 2}; | |
101 // Make a first pass to see if we need a temporary copy buffer. | |
102 int copyCapacityNeeded = 0; | |
103 for (int i = 0; i < 3; ++i) { | |
104 if (strides[i] > planeWidths[i]) { | |
105 copyCapacityNeeded = Math.max(copyCapacityNeeded, planeWidths[i] * pla
neHeights[i]); | |
106 } | |
107 } | |
108 // Allocate copy buffer if necessary. | |
109 if (copyCapacityNeeded > 0 | |
110 && (copyBuffer == null || copyBuffer.capacity() < copyCapacityNeeded))
{ | |
111 copyBuffer = ByteBuffer.allocateDirect(copyCapacityNeeded); | |
112 } | |
113 // Make sure YUV textures are allocated. | |
114 if (yuvTextures == null) { | |
115 yuvTextures = new int[3]; | |
116 for (int i = 0; i < 3; i++) { | |
117 yuvTextures[i] = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D); | |
118 } | |
119 } | |
120 // Upload each plane. | |
121 for (int i = 0; i < 3; ++i) { | |
122 GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i); | |
123 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yuvTextures[i]); | |
124 // GLES only accepts packed data, i.e. stride == planeWidth. | |
125 final ByteBuffer packedByteBuffer; | |
126 if (strides[i] == planeWidths[i]) { | |
127 // Input is packed already. | |
128 packedByteBuffer = planes[i]; | |
129 } else { | |
130 VideoRenderer.nativeCopyPlane( | |
131 planes[i], planeWidths[i], planeHeights[i], strides[i], copyBuffer
, planeWidths[i]); | |
132 packedByteBuffer = copyBuffer; | |
133 } | |
134 GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, planeW
idths[i], | |
135 planeHeights[i], 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, pa
ckedByteBuffer); | |
136 } | |
137 return yuvTextures; | |
138 } | |
139 | |
140 public int[] uploadFromBuffer(VideoFrame.I420Buffer buffer) { | |
141 int[] strides = {buffer.getStrideY(), buffer.getStrideU(), buffer.getStrid
eV()}; | |
142 ByteBuffer[] planes = {buffer.getDataY(), buffer.getDataU(), buffer.getDat
aV()}; | |
143 return uploadYuvData(buffer.getWidth(), buffer.getHeight(), strides, plane
s); | |
144 } | |
145 | |
146 /** | |
147 * Releases cached resources. Uploader can still be used and the resources w
ill be reallocated | |
148 * on first use. | |
149 */ | |
150 public void release() { | |
151 copyBuffer = null; | |
152 if (yuvTextures != null) { | |
153 GLES20.glDeleteTextures(3, yuvTextures, 0); | |
154 yuvTextures = null; | |
155 } | |
156 } | |
157 } | |
158 | |
159 /** | |
160 * Helper class for determining layout size based on layout requirements, scal
ing type, and video | 55 * Helper class for determining layout size based on layout requirements, scal
ing type, and video |
161 * aspect ratio. | 56 * aspect ratio. |
162 */ | 57 */ |
163 public static class VideoLayoutMeasure { | 58 public static class VideoLayoutMeasure { |
164 // The scaling type determines how the video will fill the allowed layout ar
ea in measure(). It | 59 // The scaling type determines how the video will fill the allowed layout ar
ea in measure(). It |
165 // can be specified separately for the case when video has matched orientati
on with layout size | 60 // can be specified separately for the case when video has matched orientati
on with layout size |
166 // and when there is an orientation mismatch. | 61 // and when there is an orientation mismatch. |
167 private ScalingType scalingTypeMatchOrientation = ScalingType.SCALE_ASPECT_B
ALANCED; | 62 private ScalingType scalingTypeMatchOrientation = ScalingType.SCALE_ASPECT_B
ALANCED; |
168 private ScalingType scalingTypeMismatchOrientation = ScalingType.SCALE_ASPEC
T_BALANCED; | 63 private ScalingType scalingTypeMismatchOrientation = ScalingType.SCALE_ASPEC
T_BALANCED; |
169 | 64 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 return new Point(maxDisplayWidth, maxDisplayHeight); | 281 return new Point(maxDisplayWidth, maxDisplayHeight); |
387 } | 282 } |
388 // Each dimension is constrained on max display size and how much we are all
owed to crop. | 283 // Each dimension is constrained on max display size and how much we are all
owed to crop. |
389 final int width = Math.min( | 284 final int width = Math.min( |
390 maxDisplayWidth, Math.round(maxDisplayHeight / minVisibleFraction * vide
oAspectRatio)); | 285 maxDisplayWidth, Math.round(maxDisplayHeight / minVisibleFraction * vide
oAspectRatio)); |
391 final int height = Math.min( | 286 final int height = Math.min( |
392 maxDisplayHeight, Math.round(maxDisplayWidth / minVisibleFraction / vide
oAspectRatio)); | 287 maxDisplayHeight, Math.round(maxDisplayWidth / minVisibleFraction / vide
oAspectRatio)); |
393 return new Point(width, height); | 288 return new Point(width, height); |
394 } | 289 } |
395 } | 290 } |
OLD | NEW |