Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: webrtc/sdk/android/api/org/webrtc/RendererCommon.java

Issue 3008423002: Android: Add helper class VideoFrameDrawer that can render VideoFrames (Closed)
Patch Set: similarity=10 Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « webrtc/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java ('k') | webrtc/sdk/android/api/org/webrtc/VideoFrameDrawer.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698