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

Side by Side Diff: talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java

Issue 1257043004: AppRTCDemo: Render each video in a separate SurfaceView (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Change license header for PercentFrameLayout.java Created 5 years, 4 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 * libjingle 2 * libjingle
3 * Copyright 2014 Google Inc. 3 * Copyright 2014 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,
(...skipping 24 matching lines...) Expand all
35 import javax.microedition.khronos.opengles.GL10; 35 import javax.microedition.khronos.opengles.GL10;
36 36
37 import android.annotation.SuppressLint; 37 import android.annotation.SuppressLint;
38 import android.graphics.Point; 38 import android.graphics.Point;
39 import android.graphics.Rect; 39 import android.graphics.Rect;
40 import android.graphics.SurfaceTexture; 40 import android.graphics.SurfaceTexture;
41 import android.opengl.EGL14; 41 import android.opengl.EGL14;
42 import android.opengl.EGLContext; 42 import android.opengl.EGLContext;
43 import android.opengl.GLES20; 43 import android.opengl.GLES20;
44 import android.opengl.GLSurfaceView; 44 import android.opengl.GLSurfaceView;
45 import android.opengl.Matrix;
46 import android.util.Log; 45 import android.util.Log;
47 46
48 import org.webrtc.VideoRenderer.I420Frame; 47 import org.webrtc.VideoRenderer.I420Frame;
49 48
50 /** 49 /**
51 * Efficiently renders YUV frames using the GPU for CSC. 50 * Efficiently renders YUV frames using the GPU for CSC.
52 * Clients will want first to call setView() to pass GLSurfaceView 51 * Clients will want first to call setView() to pass GLSurfaceView
53 * and then for each video stream either create instance of VideoRenderer using 52 * and then for each video stream either create instance of VideoRenderer using
54 * createGui() call or VideoRenderer.Callbacks interface using create() call. 53 * createGui() call or VideoRenderer.Callbacks interface using create() call.
55 * Only one instance of the class can be created. 54 * Only one instance of the class can be created.
56 */ 55 */
57 public class VideoRendererGui implements GLSurfaceView.Renderer { 56 public class VideoRendererGui implements GLSurfaceView.Renderer {
58 private static VideoRendererGui instance = null; 57 private static VideoRendererGui instance = null;
59 private static Runnable eglContextReady = null; 58 private static Runnable eglContextReady = null;
60 private static final String TAG = "VideoRendererGui"; 59 private static final String TAG = "VideoRendererGui";
61 private GLSurfaceView surface; 60 private GLSurfaceView surface;
62 private static EGLContext eglContext = null; 61 private static EGLContext eglContext = null;
63 // Indicates if SurfaceView.Renderer.onSurfaceCreated was called. 62 // Indicates if SurfaceView.Renderer.onSurfaceCreated was called.
64 // If true then for every newly created yuv image renderer createTexture() 63 // If true then for every newly created yuv image renderer createTexture()
65 // should be called. The variable is accessed on multiple threads and 64 // should be called. The variable is accessed on multiple threads and
66 // all accesses are synchronized on yuvImageRenderers' object lock. 65 // all accesses are synchronized on yuvImageRenderers' object lock.
67 private boolean onSurfaceCreatedCalled; 66 private boolean onSurfaceCreatedCalled;
68 private int screenWidth; 67 private int screenWidth;
69 private int screenHeight; 68 private int screenHeight;
70 // List of yuv renderers. 69 // List of yuv renderers.
71 private ArrayList<YuvImageRenderer> yuvImageRenderers; 70 private ArrayList<YuvImageRenderer> yuvImageRenderers;
72 private GlRectDrawer drawer; 71 private GlRectDrawer drawer;
73 // The minimum fraction of the frame content that will be shown for |SCALE_ASP ECT_BALANCED|.
74 // This limits excessive cropping when adjusting display size.
75 private static float BALANCED_VISIBLE_FRACTION = 0.56f;
76 // Types of video scaling:
77 // SCALE_ASPECT_FIT - video frame is scaled to fit the size of the view by
78 // maintaining the aspect ratio (black borders may be displayed).
79 // SCALE_ASPECT_FILL - video frame is scaled to fill the size of the view by
80 // maintaining the aspect ratio. Some portion of the video frame may be
81 // clipped.
82 // SCALE_ASPECT_BALANCED - Compromise between FIT and FILL. Video frame will f ill as much as
83 // possible of the view while maintaining aspect ratio, under the constraint t hat at least
84 // |BALANCED_VISIBLE_FRACTION| of the frame content will be shown.
85 public static enum ScalingType
86 { SCALE_ASPECT_FIT, SCALE_ASPECT_FILL, SCALE_ASPECT_BALANCED }
87 private static final int EGL14_SDK_VERSION = 72 private static final int EGL14_SDK_VERSION =
88 android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; 73 android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
89 // Current SDK version. 74 // Current SDK version.
90 private static final int CURRENT_SDK_VERSION = 75 private static final int CURRENT_SDK_VERSION =
91 android.os.Build.VERSION.SDK_INT; 76 android.os.Build.VERSION.SDK_INT;
92 77
93 private VideoRendererGui(GLSurfaceView surface) { 78 private VideoRendererGui(GLSurfaceView surface) {
94 this.surface = surface; 79 this.surface = surface;
95 // Create an OpenGL ES 2.0 context. 80 // Create an OpenGL ES 2.0 context.
96 surface.setPreserveEGLContextOnPause(true); 81 surface.setPreserveEGLContextOnPause(true);
(...skipping 19 matching lines...) Expand all
116 // an offer (writing I420Frame to render) and early-returns (recording 101 // an offer (writing I420Frame to render) and early-returns (recording
117 // a dropped frame) if that queue is full. draw() call does a peek(), 102 // a dropped frame) if that queue is full. draw() call does a peek(),
118 // copies frame to texture and then removes it from a queue using poll(). 103 // copies frame to texture and then removes it from a queue using poll().
119 LinkedBlockingQueue<I420Frame> frameToRenderQueue; 104 LinkedBlockingQueue<I420Frame> frameToRenderQueue;
120 // Local copy of incoming video frame. 105 // Local copy of incoming video frame.
121 private I420Frame yuvFrameToRender; 106 private I420Frame yuvFrameToRender;
122 private I420Frame textureFrameToRender; 107 private I420Frame textureFrameToRender;
123 // Type of video frame used for recent frame rendering. 108 // Type of video frame used for recent frame rendering.
124 private static enum RendererType { RENDERER_YUV, RENDERER_TEXTURE }; 109 private static enum RendererType { RENDERER_YUV, RENDERER_TEXTURE };
125 private RendererType rendererType; 110 private RendererType rendererType;
126 private ScalingType scalingType; 111 private RendererCommon.ScalingType scalingType;
127 private boolean mirror; 112 private boolean mirror;
128 // Flag if renderFrame() was ever called. 113 // Flag if renderFrame() was ever called.
129 boolean seenFrame; 114 boolean seenFrame;
130 // Total number of video frames received in renderFrame() call. 115 // Total number of video frames received in renderFrame() call.
131 private int framesReceived; 116 private int framesReceived;
132 // Number of video frames dropped by renderFrame() because previous 117 // Number of video frames dropped by renderFrame() because previous
133 // frame has not been rendered yet. 118 // frame has not been rendered yet.
134 private int framesDropped; 119 private int framesDropped;
135 // Number of rendered video frames. 120 // Number of rendered video frames.
136 private int framesRendered; 121 private int framesRendered;
(...skipping 22 matching lines...) Expand all
159 private int videoWidth; 144 private int videoWidth;
160 private int videoHeight; 145 private int videoHeight;
161 146
162 // This is the degree that the frame should be rotated clockwisely to have 147 // This is the degree that the frame should be rotated clockwisely to have
163 // it rendered up right. 148 // it rendered up right.
164 private int rotationDegree; 149 private int rotationDegree;
165 150
166 private YuvImageRenderer( 151 private YuvImageRenderer(
167 GLSurfaceView surface, int id, 152 GLSurfaceView surface, int id,
168 int x, int y, int width, int height, 153 int x, int y, int width, int height,
169 ScalingType scalingType, boolean mirror) { 154 RendererCommon.ScalingType scalingType, boolean mirror) {
170 Log.d(TAG, "YuvImageRenderer.Create id: " + id); 155 Log.d(TAG, "YuvImageRenderer.Create id: " + id);
171 this.surface = surface; 156 this.surface = surface;
172 this.id = id; 157 this.id = id;
173 this.scalingType = scalingType; 158 this.scalingType = scalingType;
174 this.mirror = mirror; 159 this.mirror = mirror;
175 frameToRenderQueue = new LinkedBlockingQueue<I420Frame>(1); 160 frameToRenderQueue = new LinkedBlockingQueue<I420Frame>(1);
176 layoutInPercentage = new Rect(x, y, Math.min(100, x + width), Math.min(100 , y + height)); 161 layoutInPercentage = new Rect(x, y, Math.min(100, x + width), Math.min(100 , y + height));
177 updateTextureProperties = false; 162 updateTextureProperties = false;
178 rotationDegree = 0; 163 rotationDegree = 0;
179 } 164 }
(...skipping 12 matching lines...) Expand all
192 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 177 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
193 GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 178 GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
194 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 179 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
195 GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 180 GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
196 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 181 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
197 GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 182 GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
198 } 183 }
199 GlUtil.checkNoGLES2Error("y/u/v glGenTextures"); 184 GlUtil.checkNoGLES2Error("y/u/v glGenTextures");
200 } 185 }
201 186
202 private static float convertScalingTypeToVisibleFraction(ScalingType scaling Type) {
203 switch (scalingType) {
204 case SCALE_ASPECT_FIT:
205 return 1.0f;
206 case SCALE_ASPECT_FILL:
207 return 0.0f;
208 case SCALE_ASPECT_BALANCED:
209 return BALANCED_VISIBLE_FRACTION;
210 default:
211 throw new IllegalArgumentException();
212 }
213 }
214
215 private static Point getDisplaySize(float minVisibleFraction, float videoAsp ectRatio,
216 int maxDisplayWidth, int maxDisplayHeight) {
217 // If there is no constraint on the amount of cropping, fill the allowed d isplay area.
218 if (minVisibleFraction == 0) {
219 return new Point(maxDisplayWidth, maxDisplayHeight);
220 }
221 // Each dimension is constrained on max display size and how much we are a llowed to crop.
222 final int width = Math.min(maxDisplayWidth,
223 (int) (maxDisplayHeight / minVisibleFraction * videoAspectRatio));
224 final int height = Math.min(maxDisplayHeight,
225 (int) (maxDisplayWidth / minVisibleFraction / videoAspectRatio));
226 return new Point(width, height);
227 }
228
229 private void checkAdjustTextureCoords() { 187 private void checkAdjustTextureCoords() {
230 synchronized(updateTextureLock) { 188 synchronized(updateTextureLock) {
231 if (!updateTextureProperties) { 189 if (!updateTextureProperties) {
232 return; 190 return;
233 } 191 }
234 // Initialize to maximum allowed area. Round to integer coordinates inwa rds the layout 192 // Initialize to maximum allowed area. Round to integer coordinates inwa rds the layout
235 // bounding box (ceil left/top and floor right/bottom) to not break cons traints. 193 // bounding box (ceil left/top and floor right/bottom) to not break cons traints.
236 displayLayout.set( 194 displayLayout.set(
237 (screenWidth * layoutInPercentage.left + 99) / 100, 195 (screenWidth * layoutInPercentage.left + 99) / 100,
238 (screenHeight * layoutInPercentage.top + 99) / 100, 196 (screenHeight * layoutInPercentage.top + 99) / 100,
239 (screenWidth * layoutInPercentage.right) / 100, 197 (screenWidth * layoutInPercentage.right) / 100,
240 (screenHeight * layoutInPercentage.bottom) / 100); 198 (screenHeight * layoutInPercentage.bottom) / 100);
241 Log.d(TAG, "ID: " + id + ". AdjustTextureCoords. Allowed display size: " 199 Log.d(TAG, "ID: " + id + ". AdjustTextureCoords. Allowed display size: "
242 + displayLayout.width() + " x " + displayLayout.height() + ". Video: " + videoWidth 200 + displayLayout.width() + " x " + displayLayout.height() + ". Video: " + videoWidth
243 + " x " + videoHeight + ". Rotation: " + rotationDegree + ". Mirror: " + mirror); 201 + " x " + videoHeight + ". Rotation: " + rotationDegree + ". Mirror: " + mirror);
244 final float videoAspectRatio = (rotationDegree % 180 == 0) 202 final float videoAspectRatio = (rotationDegree % 180 == 0)
245 ? (float) videoWidth / videoHeight 203 ? (float) videoWidth / videoHeight
246 : (float) videoHeight / videoWidth; 204 : (float) videoHeight / videoWidth;
247 // Adjust display size based on |scalingType|. 205 // Adjust display size based on |scalingType|.
248 final float minVisibleFraction = convertScalingTypeToVisibleFraction(sca lingType); 206 final Point displaySize = RendererCommon.getDisplaySize(scalingType,
249 final Point displaySize = getDisplaySize(minVisibleFraction, videoAspect Ratio, 207 videoAspectRatio, displayLayout.width(), displayLayout.height());
250 displayLayout.width(), displayLayout.height());
251 displayLayout.inset((displayLayout.width() - displaySize.x) / 2, 208 displayLayout.inset((displayLayout.width() - displaySize.x) / 2,
252 (displayLayout.height() - displaySize.y) / 2); 209 (displayLayout.height() - displaySize.y) / 2);
253 Log.d(TAG, " Adjusted display size: " + displayLayout.width() + " x " 210 Log.d(TAG, " Adjusted display size: " + displayLayout.width() + " x "
254 + displayLayout.height()); 211 + displayLayout.height());
255 // The matrix stack is using post-multiplication, which means that matri x operations: 212 RendererCommon.getTextureMatrix(texMatrix, rotationDegree, mirror, video AspectRatio,
256 // A; B; C; will end up as A * B * C. When you apply this to a vertex, i t will result in: 213 (float) displayLayout.width() / displayLayout.height());
257 // v' = A * B * C * v, i.e. the last matrix operation is the first thing that affects the
258 // vertex. This is the opposite of what you might expect.
259 Matrix.setIdentityM(texMatrix, 0);
260 // Move coordinates back to [0,1]x[0,1].
261 Matrix.translateM(texMatrix, 0, 0.5f, 0.5f, 0.0f);
262 // Rotate frame clockwise in the XY-plane (around the Z-axis).
263 Matrix.rotateM(texMatrix, 0, -rotationDegree, 0, 0, 1);
264 // Scale one dimension until video and display size have same aspect rat io.
265 final float displayAspectRatio = (float) displayLayout.width() / display Layout.height();
266 if (displayAspectRatio > videoAspectRatio) {
267 Matrix.scaleM(texMatrix, 0, 1, videoAspectRatio / displayAspectRatio , 1);
268 } else {
269 Matrix.scaleM(texMatrix, 0, displayAspectRatio / videoAspectRatio, 1 , 1);
270 }
271 // TODO(magjed): We currently ignore the texture transform matrix from t he SurfaceTexture.
272 // It contains a vertical flip that is hardcoded here instead.
273 Matrix.scaleM(texMatrix, 0, 1, -1, 1);
274 // Apply optional horizontal flip.
275 if (mirror) {
276 Matrix.scaleM(texMatrix, 0, -1, 1, 1);
277 }
278 // Center coordinates around origin.
279 Matrix.translateM(texMatrix, 0, -0.5f, -0.5f, 0.0f);
280 updateTextureProperties = false; 214 updateTextureProperties = false;
281 Log.d(TAG, " AdjustTextureCoords done"); 215 Log.d(TAG, " AdjustTextureCoords done");
282 } 216 }
283 } 217 }
284 218
285 private void draw(GlRectDrawer drawer) { 219 private void draw(GlRectDrawer drawer) {
286 if (!seenFrame) { 220 if (!seenFrame) {
287 // No frame received yet - nothing to render. 221 // No frame received yet - nothing to render.
288 return; 222 return;
289 } 223 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 } 302 }
369 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setScreenSize: " + 303 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setScreenSize: " +
370 screenWidth + " x " + screenHeight); 304 screenWidth + " x " + screenHeight);
371 this.screenWidth = screenWidth; 305 this.screenWidth = screenWidth;
372 this.screenHeight = screenHeight; 306 this.screenHeight = screenHeight;
373 updateTextureProperties = true; 307 updateTextureProperties = true;
374 } 308 }
375 } 309 }
376 310
377 public void setPosition(int x, int y, int width, int height, 311 public void setPosition(int x, int y, int width, int height,
378 ScalingType scalingType, boolean mirror) { 312 RendererCommon.ScalingType scalingType, boolean mirror) {
379 final Rect layoutInPercentage = 313 final Rect layoutInPercentage =
380 new Rect(x, y, Math.min(100, x + width), Math.min(100, y + height)); 314 new Rect(x, y, Math.min(100, x + width), Math.min(100, y + height));
381 synchronized(updateTextureLock) { 315 synchronized(updateTextureLock) {
382 if (layoutInPercentage.equals(this.layoutInPercentage) && scalingType == this.scalingType 316 if (layoutInPercentage.equals(this.layoutInPercentage) && scalingType == this.scalingType
383 && mirror == this.mirror) { 317 && mirror == this.mirror) {
384 return; 318 return;
385 } 319 }
386 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setPosition: (" + x + ", " + y + 320 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setPosition: (" + x + ", " + y +
387 ") " + width + " x " + height + ". Scaling: " + scalingType + 321 ") " + width + " x " + height + ". Scaling: " + scalingType +
388 ". Mirror: " + mirror); 322 ". Mirror: " + mirror);
(...skipping 19 matching lines...) Expand all
408 342
409 this.videoWidth = videoWidth; 343 this.videoWidth = videoWidth;
410 this.videoHeight = videoHeight; 344 this.videoHeight = videoHeight;
411 rotationDegree = rotation; 345 rotationDegree = rotation;
412 int[] strides = { videoWidth, videoWidth / 2, videoWidth / 2 }; 346 int[] strides = { videoWidth, videoWidth / 2, videoWidth / 2 };
413 347
414 // Clear rendering queue. 348 // Clear rendering queue.
415 frameToRenderQueue.poll(); 349 frameToRenderQueue.poll();
416 // Re-allocate / allocate the frame. 350 // Re-allocate / allocate the frame.
417 yuvFrameToRender = new I420Frame(videoWidth, videoHeight, rotationDegree , 351 yuvFrameToRender = new I420Frame(videoWidth, videoHeight, rotationDegree ,
418 strides, null); 352 strides, null, 0);
419 textureFrameToRender = new I420Frame(videoWidth, videoHeight, rotationDe gree, 353 textureFrameToRender = new I420Frame(videoWidth, videoHeight, rotationDe gree,
420 null, -1); 354 null, -1, 0);
421 updateTextureProperties = true; 355 updateTextureProperties = true;
422 Log.d(TAG, " YuvImageRenderer.setSize done."); 356 Log.d(TAG, " YuvImageRenderer.setSize done.");
423 } 357 }
424 } 358 }
425 359
426 @Override 360 @Override
427 public synchronized void renderFrame(I420Frame frame) { 361 public synchronized void renderFrame(I420Frame frame) {
428 setSize(frame.width, frame.height, frame.rotationDegree); 362 setSize(frame.width, frame.height, frame.rotationDegree);
429 long now = System.nanoTime(); 363 long now = System.nanoTime();
430 framesReceived++; 364 framesReceived++;
431 // Skip rendering of this frame if setSize() was not called. 365 // Skip rendering of this frame if setSize() was not called.
432 if (yuvFrameToRender == null || textureFrameToRender == null) { 366 if (yuvFrameToRender == null || textureFrameToRender == null) {
433 framesDropped++; 367 framesDropped++;
368 VideoRenderer.renderFrameDone(frame);
434 return; 369 return;
435 } 370 }
436 // Check input frame parameters. 371 // Check input frame parameters.
437 if (frame.yuvFrame) { 372 if (frame.yuvFrame) {
438 if (frame.yuvStrides[0] < frame.width || 373 if (frame.yuvStrides[0] < frame.width ||
439 frame.yuvStrides[1] < frame.width / 2 || 374 frame.yuvStrides[1] < frame.width / 2 ||
440 frame.yuvStrides[2] < frame.width / 2) { 375 frame.yuvStrides[2] < frame.width / 2) {
441 Log.e(TAG, "Incorrect strides " + frame.yuvStrides[0] + ", " + 376 Log.e(TAG, "Incorrect strides " + frame.yuvStrides[0] + ", " +
442 frame.yuvStrides[1] + ", " + frame.yuvStrides[2]); 377 frame.yuvStrides[1] + ", " + frame.yuvStrides[2]);
378 VideoRenderer.renderFrameDone(frame);
443 return; 379 return;
444 } 380 }
445 // Check incoming frame dimensions. 381 // Check incoming frame dimensions.
446 if (frame.width != yuvFrameToRender.width || 382 if (frame.width != yuvFrameToRender.width ||
447 frame.height != yuvFrameToRender.height) { 383 frame.height != yuvFrameToRender.height) {
448 throw new RuntimeException("Wrong frame size " + 384 throw new RuntimeException("Wrong frame size " +
449 frame.width + " x " + frame.height); 385 frame.width + " x " + frame.height);
450 } 386 }
451 } 387 }
452 388
453 if (frameToRenderQueue.size() > 0) { 389 if (frameToRenderQueue.size() > 0) {
454 // Skip rendering of this frame if previous frame was not rendered yet. 390 // Skip rendering of this frame if previous frame was not rendered yet.
455 framesDropped++; 391 framesDropped++;
392 VideoRenderer.renderFrameDone(frame);
456 return; 393 return;
457 } 394 }
458 395
459 // Create a local copy of the frame. 396 // Create a local copy of the frame.
460 if (frame.yuvFrame) { 397 if (frame.yuvFrame) {
461 yuvFrameToRender.copyFrom(frame); 398 yuvFrameToRender.copyFrom(frame);
462 rendererType = RendererType.RENDERER_YUV; 399 rendererType = RendererType.RENDERER_YUV;
463 frameToRenderQueue.offer(yuvFrameToRender); 400 frameToRenderQueue.offer(yuvFrameToRender);
464 } else { 401 } else {
465 textureFrameToRender.copyFrom(frame); 402 textureFrameToRender.copyFrom(frame);
466 rendererType = RendererType.RENDERER_TEXTURE; 403 rendererType = RendererType.RENDERER_TEXTURE;
467 frameToRenderQueue.offer(textureFrameToRender); 404 frameToRenderQueue.offer(textureFrameToRender);
468 } 405 }
469 copyTimeNs += (System.nanoTime() - now); 406 copyTimeNs += (System.nanoTime() - now);
470 seenFrame = true; 407 seenFrame = true;
408 VideoRenderer.renderFrameDone(frame);
471 409
472 // Request rendering. 410 // Request rendering.
473 surface.requestRender(); 411 surface.requestRender();
474 } 412 }
475 413
476 // TODO(guoweis): Remove this once chrome code base is updated. 414 // TODO(guoweis): Remove this once chrome code base is updated.
477 @Override 415 @Override
478 public boolean canApplyRotation() { 416 public boolean canApplyRotation() {
479 return true; 417 return true;
480 } 418 }
481 } 419 }
482 420
483 /** Passes GLSurfaceView to video renderer. */ 421 /** Passes GLSurfaceView to video renderer. */
484 public static void setView(GLSurfaceView surface, 422 public static void setView(GLSurfaceView surface,
485 Runnable eglContextReadyCallback) { 423 Runnable eglContextReadyCallback) {
486 Log.d(TAG, "VideoRendererGui.setView"); 424 Log.d(TAG, "VideoRendererGui.setView");
487 instance = new VideoRendererGui(surface); 425 instance = new VideoRendererGui(surface);
488 eglContextReady = eglContextReadyCallback; 426 eglContextReady = eglContextReadyCallback;
489 } 427 }
490 428
491 public static EGLContext getEGLContext() { 429 public static EGLContext getEGLContext() {
492 return eglContext; 430 return eglContext;
493 } 431 }
494 432
495 /** 433 /**
496 * Creates VideoRenderer with top left corner at (x, y) and resolution 434 * Creates VideoRenderer with top left corner at (x, y) and resolution
497 * (width, height). All parameters are in percentage of screen resolution. 435 * (width, height). All parameters are in percentage of screen resolution.
498 */ 436 */
499 public static VideoRenderer createGui(int x, int y, int width, int height, 437 public static VideoRenderer createGui(int x, int y, int width, int height,
500 ScalingType scalingType, boolean mirror) throws Exception { 438 RendererCommon.ScalingType scalingType, boolean mirror) throws Exception {
501 YuvImageRenderer javaGuiRenderer = create( 439 YuvImageRenderer javaGuiRenderer = create(
502 x, y, width, height, scalingType, mirror); 440 x, y, width, height, scalingType, mirror);
503 return new VideoRenderer(javaGuiRenderer); 441 return new VideoRenderer(javaGuiRenderer);
504 } 442 }
505 443
506 public static VideoRenderer.Callbacks createGuiRenderer( 444 public static VideoRenderer.Callbacks createGuiRenderer(
507 int x, int y, int width, int height, 445 int x, int y, int width, int height,
508 ScalingType scalingType, boolean mirror) { 446 RendererCommon.ScalingType scalingType, boolean mirror) {
509 return create(x, y, width, height, scalingType, mirror); 447 return create(x, y, width, height, scalingType, mirror);
510 } 448 }
511 449
512 /** 450 /**
513 * Creates VideoRenderer.Callbacks with top left corner at (x, y) and 451 * Creates VideoRenderer.Callbacks with top left corner at (x, y) and
514 * resolution (width, height). All parameters are in percentage of 452 * resolution (width, height). All parameters are in percentage of
515 * screen resolution. 453 * screen resolution.
516 */ 454 */
517 public static YuvImageRenderer create(int x, int y, int width, int height, 455 public static YuvImageRenderer create(int x, int y, int width, int height,
518 ScalingType scalingType, boolean mirror) { 456 RendererCommon.ScalingType scalingType, boolean mirror) {
519 // Check display region parameters. 457 // Check display region parameters.
520 if (x < 0 || x > 100 || y < 0 || y > 100 || 458 if (x < 0 || x > 100 || y < 0 || y > 100 ||
521 width < 0 || width > 100 || height < 0 || height > 100 || 459 width < 0 || width > 100 || height < 0 || height > 100 ||
522 x + width > 100 || y + height > 100) { 460 x + width > 100 || y + height > 100) {
523 throw new RuntimeException("Incorrect window parameters."); 461 throw new RuntimeException("Incorrect window parameters.");
524 } 462 }
525 463
526 if (instance == null) { 464 if (instance == null) {
527 throw new RuntimeException( 465 throw new RuntimeException(
528 "Attempt to create yuv renderer before setting GLSurfaceView"); 466 "Attempt to create yuv renderer before setting GLSurfaceView");
(...skipping 23 matching lines...) Expand all
552 } 490 }
553 } 491 }
554 // Add yuv renderer to rendering list. 492 // Add yuv renderer to rendering list.
555 instance.yuvImageRenderers.add(yuvImageRenderer); 493 instance.yuvImageRenderers.add(yuvImageRenderer);
556 } 494 }
557 return yuvImageRenderer; 495 return yuvImageRenderer;
558 } 496 }
559 497
560 public static void update( 498 public static void update(
561 VideoRenderer.Callbacks renderer, 499 VideoRenderer.Callbacks renderer,
562 int x, int y, int width, int height, ScalingType scalingType, boolean mirr or) { 500 int x, int y, int width, int height, RendererCommon.ScalingType scalingTyp e, boolean mirror) {
563 Log.d(TAG, "VideoRendererGui.update"); 501 Log.d(TAG, "VideoRendererGui.update");
564 if (instance == null) { 502 if (instance == null) {
565 throw new RuntimeException( 503 throw new RuntimeException(
566 "Attempt to update yuv renderer before setting GLSurfaceView"); 504 "Attempt to update yuv renderer before setting GLSurfaceView");
567 } 505 }
568 synchronized (instance.yuvImageRenderers) { 506 synchronized (instance.yuvImageRenderers) {
569 for (YuvImageRenderer yuvImageRenderer : instance.yuvImageRenderers) { 507 for (YuvImageRenderer yuvImageRenderer : instance.yuvImageRenderers) {
570 if (yuvImageRenderer == renderer) { 508 if (yuvImageRenderer == renderer) {
571 yuvImageRenderer.setPosition(x, y, width, height, scalingType, mirror) ; 509 yuvImageRenderer.setPosition(x, y, width, height, scalingType, mirror) ;
572 } 510 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 GLES20.glViewport(0, 0, screenWidth, screenHeight); 572 GLES20.glViewport(0, 0, screenWidth, screenHeight);
635 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 573 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
636 synchronized (yuvImageRenderers) { 574 synchronized (yuvImageRenderers) {
637 for (YuvImageRenderer yuvImageRenderer : yuvImageRenderers) { 575 for (YuvImageRenderer yuvImageRenderer : yuvImageRenderers) {
638 yuvImageRenderer.draw(drawer); 576 yuvImageRenderer.draw(drawer);
639 } 577 }
640 } 578 }
641 } 579 }
642 580
643 } 581 }
OLDNEW
« no previous file with comments | « talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java ('k') | talk/app/webrtc/java/jni/peerconnection_jni.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698