OLD | NEW |
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 Loading... |
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. |
(...skipping 10 matching lines...) Expand all Loading... |
66 // If true then for every newly created yuv image renderer createTexture() | 65 // If true then for every newly created yuv image renderer createTexture() |
67 // should be called. The variable is accessed on multiple threads and | 66 // should be called. The variable is accessed on multiple threads and |
68 // all accesses are synchronized on yuvImageRenderers' object lock. | 67 // all accesses are synchronized on yuvImageRenderers' object lock. |
69 private boolean onSurfaceCreatedCalled; | 68 private boolean onSurfaceCreatedCalled; |
70 private int screenWidth; | 69 private int screenWidth; |
71 private int screenHeight; | 70 private int screenHeight; |
72 // List of yuv renderers. | 71 // List of yuv renderers. |
73 private final ArrayList<YuvImageRenderer> yuvImageRenderers; | 72 private final ArrayList<YuvImageRenderer> yuvImageRenderers; |
74 // |drawer| is synchronized on |yuvImageRenderers|. | 73 // |drawer| is synchronized on |yuvImageRenderers|. |
75 private GlRectDrawer drawer; | 74 private GlRectDrawer drawer; |
76 // The minimum fraction of the frame content that will be shown for |SCALE_ASP
ECT_BALANCED|. | |
77 // This limits excessive cropping when adjusting display size. | |
78 private static float BALANCED_VISIBLE_FRACTION = 0.56f; | |
79 // Types of video scaling: | |
80 // SCALE_ASPECT_FIT - video frame is scaled to fit the size of the view by | |
81 // maintaining the aspect ratio (black borders may be displayed). | |
82 // SCALE_ASPECT_FILL - video frame is scaled to fill the size of the view by | |
83 // maintaining the aspect ratio. Some portion of the video frame may be | |
84 // clipped. | |
85 // SCALE_ASPECT_BALANCED - Compromise between FIT and FILL. Video frame will f
ill as much as | |
86 // possible of the view while maintaining aspect ratio, under the constraint t
hat at least | |
87 // |BALANCED_VISIBLE_FRACTION| of the frame content will be shown. | |
88 public static enum ScalingType | |
89 { SCALE_ASPECT_FIT, SCALE_ASPECT_FILL, SCALE_ASPECT_BALANCED } | |
90 private static final int EGL14_SDK_VERSION = | 75 private static final int EGL14_SDK_VERSION = |
91 android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; | 76 android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; |
92 // Current SDK version. | 77 // Current SDK version. |
93 private static final int CURRENT_SDK_VERSION = | 78 private static final int CURRENT_SDK_VERSION = |
94 android.os.Build.VERSION.SDK_INT; | 79 android.os.Build.VERSION.SDK_INT; |
95 | 80 |
96 private VideoRendererGui(GLSurfaceView surface) { | 81 private VideoRendererGui(GLSurfaceView surface) { |
97 this.surface = surface; | 82 this.surface = surface; |
98 // Create an OpenGL ES 2.0 context. | 83 // Create an OpenGL ES 2.0 context. |
99 surface.setPreserveEGLContextOnPause(true); | 84 surface.setPreserveEGLContextOnPause(true); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 // an offer (writing I420Frame to render) and early-returns (recording | 124 // an offer (writing I420Frame to render) and early-returns (recording |
140 // a dropped frame) if that queue is full. draw() call does a peek(), | 125 // a dropped frame) if that queue is full. draw() call does a peek(), |
141 // copies frame to texture and then removes it from a queue using poll(). | 126 // copies frame to texture and then removes it from a queue using poll(). |
142 private final LinkedBlockingQueue<I420Frame> frameToRenderQueue; | 127 private final LinkedBlockingQueue<I420Frame> frameToRenderQueue; |
143 // Local copy of incoming video frame. Synchronized on |frameToRenderQueue|. | 128 // Local copy of incoming video frame. Synchronized on |frameToRenderQueue|. |
144 private I420Frame yuvFrameToRender; | 129 private I420Frame yuvFrameToRender; |
145 private I420Frame textureFrameToRender; | 130 private I420Frame textureFrameToRender; |
146 // Type of video frame used for recent frame rendering. | 131 // Type of video frame used for recent frame rendering. |
147 private static enum RendererType { RENDERER_YUV, RENDERER_TEXTURE }; | 132 private static enum RendererType { RENDERER_YUV, RENDERER_TEXTURE }; |
148 private RendererType rendererType; | 133 private RendererType rendererType; |
149 private ScalingType scalingType; | 134 private RendererCommon.ScalingType scalingType; |
150 private boolean mirror; | 135 private boolean mirror; |
151 private RendererEvents rendererEvents; | 136 private RendererCommon.RendererEvents rendererEvents; |
152 // Flag if renderFrame() was ever called. | 137 // Flag if renderFrame() was ever called. |
153 boolean seenFrame; | 138 boolean seenFrame; |
154 // Total number of video frames received in renderFrame() call. | 139 // Total number of video frames received in renderFrame() call. |
155 private int framesReceived; | 140 private int framesReceived; |
156 // Number of video frames dropped by renderFrame() because previous | 141 // Number of video frames dropped by renderFrame() because previous |
157 // frame has not been rendered yet. | 142 // frame has not been rendered yet. |
158 private int framesDropped; | 143 private int framesDropped; |
159 // Number of rendered video frames. | 144 // Number of rendered video frames. |
160 private int framesRendered; | 145 private int framesRendered; |
161 // Time in ns when the first video frame was rendered. | 146 // Time in ns when the first video frame was rendered. |
(...skipping 21 matching lines...) Expand all Loading... |
183 private int videoWidth; | 168 private int videoWidth; |
184 private int videoHeight; | 169 private int videoHeight; |
185 | 170 |
186 // This is the degree that the frame should be rotated clockwisely to have | 171 // This is the degree that the frame should be rotated clockwisely to have |
187 // it rendered up right. | 172 // it rendered up right. |
188 private int rotationDegree; | 173 private int rotationDegree; |
189 | 174 |
190 private YuvImageRenderer( | 175 private YuvImageRenderer( |
191 GLSurfaceView surface, int id, | 176 GLSurfaceView surface, int id, |
192 int x, int y, int width, int height, | 177 int x, int y, int width, int height, |
193 ScalingType scalingType, boolean mirror) { | 178 RendererCommon.ScalingType scalingType, boolean mirror) { |
194 Log.d(TAG, "YuvImageRenderer.Create id: " + id); | 179 Log.d(TAG, "YuvImageRenderer.Create id: " + id); |
195 this.surface = surface; | 180 this.surface = surface; |
196 this.id = id; | 181 this.id = id; |
197 this.scalingType = scalingType; | 182 this.scalingType = scalingType; |
198 this.mirror = mirror; | 183 this.mirror = mirror; |
199 frameToRenderQueue = new LinkedBlockingQueue<I420Frame>(1); | 184 frameToRenderQueue = new LinkedBlockingQueue<I420Frame>(1); |
200 layoutInPercentage = new Rect(x, y, Math.min(100, x + width), Math.min(100
, y + height)); | 185 layoutInPercentage = new Rect(x, y, Math.min(100, x + width), Math.min(100
, y + height)); |
201 updateTextureProperties = false; | 186 updateTextureProperties = false; |
202 rotationDegree = 0; | 187 rotationDegree = 0; |
203 } | 188 } |
(...skipping 21 matching lines...) Expand all Loading... |
225 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, | 210 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, |
226 GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); | 211 GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); |
227 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, | 212 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, |
228 GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); | 213 GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); |
229 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, | 214 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, |
230 GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); | 215 GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); |
231 } | 216 } |
232 GlUtil.checkNoGLES2Error("y/u/v glGenTextures"); | 217 GlUtil.checkNoGLES2Error("y/u/v glGenTextures"); |
233 } | 218 } |
234 | 219 |
235 private static float convertScalingTypeToVisibleFraction(ScalingType scaling
Type) { | |
236 switch (scalingType) { | |
237 case SCALE_ASPECT_FIT: | |
238 return 1.0f; | |
239 case SCALE_ASPECT_FILL: | |
240 return 0.0f; | |
241 case SCALE_ASPECT_BALANCED: | |
242 return BALANCED_VISIBLE_FRACTION; | |
243 default: | |
244 throw new IllegalArgumentException(); | |
245 } | |
246 } | |
247 | |
248 private static Point getDisplaySize(float minVisibleFraction, float videoAsp
ectRatio, | |
249 int maxDisplayWidth, int maxDisplayHeight) { | |
250 // If there is no constraint on the amount of cropping, fill the allowed d
isplay area. | |
251 if (minVisibleFraction == 0) { | |
252 return new Point(maxDisplayWidth, maxDisplayHeight); | |
253 } | |
254 // Each dimension is constrained on max display size and how much we are a
llowed to crop. | |
255 final int width = Math.min(maxDisplayWidth, | |
256 (int) (maxDisplayHeight / minVisibleFraction * videoAspectRatio)); | |
257 final int height = Math.min(maxDisplayHeight, | |
258 (int) (maxDisplayWidth / minVisibleFraction / videoAspectRatio)); | |
259 return new Point(width, height); | |
260 } | |
261 | |
262 private void checkAdjustTextureCoords() { | 220 private void checkAdjustTextureCoords() { |
263 synchronized(updateTextureLock) { | 221 synchronized(updateTextureLock) { |
264 if (!updateTextureProperties) { | 222 if (!updateTextureProperties) { |
265 return; | 223 return; |
266 } | 224 } |
267 // Initialize to maximum allowed area. Round to integer coordinates inwa
rds the layout | 225 // Initialize to maximum allowed area. Round to integer coordinates inwa
rds the layout |
268 // bounding box (ceil left/top and floor right/bottom) to not break cons
traints. | 226 // bounding box (ceil left/top and floor right/bottom) to not break cons
traints. |
269 displayLayout.set( | 227 displayLayout.set( |
270 (screenWidth * layoutInPercentage.left + 99) / 100, | 228 (screenWidth * layoutInPercentage.left + 99) / 100, |
271 (screenHeight * layoutInPercentage.top + 99) / 100, | 229 (screenHeight * layoutInPercentage.top + 99) / 100, |
272 (screenWidth * layoutInPercentage.right) / 100, | 230 (screenWidth * layoutInPercentage.right) / 100, |
273 (screenHeight * layoutInPercentage.bottom) / 100); | 231 (screenHeight * layoutInPercentage.bottom) / 100); |
274 Log.d(TAG, "ID: " + id + ". AdjustTextureCoords. Allowed display size:
" | 232 Log.d(TAG, "ID: " + id + ". AdjustTextureCoords. Allowed display size:
" |
275 + displayLayout.width() + " x " + displayLayout.height() + ". Video:
" + videoWidth | 233 + displayLayout.width() + " x " + displayLayout.height() + ". Video:
" + videoWidth |
276 + " x " + videoHeight + ". Rotation: " + rotationDegree + ". Mirror:
" + mirror); | 234 + " x " + videoHeight + ". Rotation: " + rotationDegree + ". Mirror:
" + mirror); |
277 final float videoAspectRatio = (rotationDegree % 180 == 0) | 235 final float videoAspectRatio = (rotationDegree % 180 == 0) |
278 ? (float) videoWidth / videoHeight | 236 ? (float) videoWidth / videoHeight |
279 : (float) videoHeight / videoWidth; | 237 : (float) videoHeight / videoWidth; |
280 // Adjust display size based on |scalingType|. | 238 // Adjust display size based on |scalingType|. |
281 final float minVisibleFraction = convertScalingTypeToVisibleFraction(sca
lingType); | 239 final Point displaySize = RendererCommon.getDisplaySize(scalingType, |
282 final Point displaySize = getDisplaySize(minVisibleFraction, videoAspect
Ratio, | 240 videoAspectRatio, displayLayout.width(), displayLayout.height()); |
283 displayLayout.width(), displayLayout.height()); | |
284 displayLayout.inset((displayLayout.width() - displaySize.x) / 2, | 241 displayLayout.inset((displayLayout.width() - displaySize.x) / 2, |
285 (displayLayout.height() - displaySize.y) / 2); | 242 (displayLayout.height() - displaySize.y) / 2); |
286 Log.d(TAG, " Adjusted display size: " + displayLayout.width() + " x " | 243 Log.d(TAG, " Adjusted display size: " + displayLayout.width() + " x " |
287 + displayLayout.height()); | 244 + displayLayout.height()); |
288 // The matrix stack is using post-multiplication, which means that matri
x operations: | 245 RendererCommon.getTextureMatrix(texMatrix, rotationDegree, mirror, video
AspectRatio, |
289 // A; B; C; will end up as A * B * C. When you apply this to a vertex, i
t will result in: | 246 (float) displayLayout.width() / displayLayout.height()); |
290 // v' = A * B * C * v, i.e. the last matrix operation is the first thing
that affects the | |
291 // vertex. This is the opposite of what you might expect. | |
292 Matrix.setIdentityM(texMatrix, 0); | |
293 // Move coordinates back to [0,1]x[0,1]. | |
294 Matrix.translateM(texMatrix, 0, 0.5f, 0.5f, 0.0f); | |
295 // Rotate frame clockwise in the XY-plane (around the Z-axis). | |
296 Matrix.rotateM(texMatrix, 0, -rotationDegree, 0, 0, 1); | |
297 // Scale one dimension until video and display size have same aspect rat
io. | |
298 final float displayAspectRatio = (float) displayLayout.width() / display
Layout.height(); | |
299 if (displayAspectRatio > videoAspectRatio) { | |
300 Matrix.scaleM(texMatrix, 0, 1, videoAspectRatio / displayAspectRatio
, 1); | |
301 } else { | |
302 Matrix.scaleM(texMatrix, 0, displayAspectRatio / videoAspectRatio, 1
, 1); | |
303 } | |
304 // TODO(magjed): We currently ignore the texture transform matrix from t
he SurfaceTexture. | |
305 // It contains a vertical flip that is hardcoded here instead. | |
306 Matrix.scaleM(texMatrix, 0, 1, -1, 1); | |
307 // Apply optional horizontal flip. | |
308 if (mirror) { | |
309 Matrix.scaleM(texMatrix, 0, -1, 1, 1); | |
310 } | |
311 // Center coordinates around origin. | |
312 Matrix.translateM(texMatrix, 0, -0.5f, -0.5f, 0.0f); | |
313 updateTextureProperties = false; | 247 updateTextureProperties = false; |
314 Log.d(TAG, " AdjustTextureCoords done"); | 248 Log.d(TAG, " AdjustTextureCoords done"); |
315 } | 249 } |
316 } | 250 } |
317 | 251 |
318 private void draw(GlRectDrawer drawer) { | 252 private void draw(GlRectDrawer drawer) { |
319 if (!seenFrame) { | 253 if (!seenFrame) { |
320 // No frame received yet - nothing to render. | 254 // No frame received yet - nothing to render. |
321 return; | 255 return; |
322 } | 256 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 } | 335 } |
402 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setScreenSize: " + | 336 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setScreenSize: " + |
403 screenWidth + " x " + screenHeight); | 337 screenWidth + " x " + screenHeight); |
404 this.screenWidth = screenWidth; | 338 this.screenWidth = screenWidth; |
405 this.screenHeight = screenHeight; | 339 this.screenHeight = screenHeight; |
406 updateTextureProperties = true; | 340 updateTextureProperties = true; |
407 } | 341 } |
408 } | 342 } |
409 | 343 |
410 public void setPosition(int x, int y, int width, int height, | 344 public void setPosition(int x, int y, int width, int height, |
411 ScalingType scalingType, boolean mirror) { | 345 RendererCommon.ScalingType scalingType, boolean mirror) { |
412 final Rect layoutInPercentage = | 346 final Rect layoutInPercentage = |
413 new Rect(x, y, Math.min(100, x + width), Math.min(100, y + height)); | 347 new Rect(x, y, Math.min(100, x + width), Math.min(100, y + height)); |
414 synchronized(updateTextureLock) { | 348 synchronized(updateTextureLock) { |
415 if (layoutInPercentage.equals(this.layoutInPercentage) && scalingType ==
this.scalingType | 349 if (layoutInPercentage.equals(this.layoutInPercentage) && scalingType ==
this.scalingType |
416 && mirror == this.mirror) { | 350 && mirror == this.mirror) { |
417 return; | 351 return; |
418 } | 352 } |
419 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setPosition: (" + x + ", "
+ y + | 353 Log.d(TAG, "ID: " + id + ". YuvImageRenderer.setPosition: (" + x + ", "
+ y + |
420 ") " + width + " x " + height + ". Scaling: " + scalingType + | 354 ") " + width + " x " + height + ". Scaling: " + scalingType + |
421 ". Mirror: " + mirror); | 355 ". Mirror: " + mirror); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 surface.requestRender(); | 455 surface.requestRender(); |
522 } | 456 } |
523 | 457 |
524 // TODO(guoweis): Remove this once chrome code base is updated. | 458 // TODO(guoweis): Remove this once chrome code base is updated. |
525 @Override | 459 @Override |
526 public boolean canApplyRotation() { | 460 public boolean canApplyRotation() { |
527 return true; | 461 return true; |
528 } | 462 } |
529 } | 463 } |
530 | 464 |
531 /** Interface for reporting rendering events. */ | |
532 public static interface RendererEvents { | |
533 /** | |
534 * Callback fired once first frame is rendered. | |
535 */ | |
536 public void onFirstFrameRendered(); | |
537 | |
538 /** | |
539 * Callback fired when rendered frame resolution or rotation has changed. | |
540 */ | |
541 public void onFrameResolutionChanged(int videoWidth, int videoHeight, int ro
tation); | |
542 } | |
543 | |
544 /** Passes GLSurfaceView to video renderer. */ | 465 /** Passes GLSurfaceView to video renderer. */ |
545 public static synchronized void setView(GLSurfaceView surface, | 466 public static synchronized void setView(GLSurfaceView surface, |
546 Runnable eglContextReadyCallback) { | 467 Runnable eglContextReadyCallback) { |
547 Log.d(TAG, "VideoRendererGui.setView"); | 468 Log.d(TAG, "VideoRendererGui.setView"); |
548 instance = new VideoRendererGui(surface); | 469 instance = new VideoRendererGui(surface); |
549 eglContextReady = eglContextReadyCallback; | 470 eglContextReady = eglContextReadyCallback; |
550 } | 471 } |
551 | 472 |
552 public static synchronized EGLContext getEGLContext() { | 473 public static synchronized EGLContext getEGLContext() { |
553 return eglContext; | 474 return eglContext; |
554 } | 475 } |
555 | 476 |
556 /** | 477 /** |
557 * Creates VideoRenderer with top left corner at (x, y) and resolution | 478 * Creates VideoRenderer with top left corner at (x, y) and resolution |
558 * (width, height). All parameters are in percentage of screen resolution. | 479 * (width, height). All parameters are in percentage of screen resolution. |
559 */ | 480 */ |
560 public static VideoRenderer createGui(int x, int y, int width, int height, | 481 public static VideoRenderer createGui(int x, int y, int width, int height, |
561 ScalingType scalingType, boolean mirror) throws Exception { | 482 RendererCommon.ScalingType scalingType, boolean mirror) throws Exception { |
562 YuvImageRenderer javaGuiRenderer = create( | 483 YuvImageRenderer javaGuiRenderer = create( |
563 x, y, width, height, scalingType, mirror); | 484 x, y, width, height, scalingType, mirror); |
564 return new VideoRenderer(javaGuiRenderer); | 485 return new VideoRenderer(javaGuiRenderer); |
565 } | 486 } |
566 | 487 |
567 public static VideoRenderer.Callbacks createGuiRenderer( | 488 public static VideoRenderer.Callbacks createGuiRenderer( |
568 int x, int y, int width, int height, | 489 int x, int y, int width, int height, |
569 ScalingType scalingType, boolean mirror) { | 490 RendererCommon.ScalingType scalingType, boolean mirror) { |
570 return create(x, y, width, height, scalingType, mirror); | 491 return create(x, y, width, height, scalingType, mirror); |
571 } | 492 } |
572 | 493 |
573 /** | 494 /** |
574 * Creates VideoRenderer.Callbacks with top left corner at (x, y) and | 495 * Creates VideoRenderer.Callbacks with top left corner at (x, y) and |
575 * resolution (width, height). All parameters are in percentage of | 496 * resolution (width, height). All parameters are in percentage of |
576 * screen resolution. | 497 * screen resolution. |
577 */ | 498 */ |
578 public static synchronized YuvImageRenderer create(int x, int y, int width, in
t height, | 499 public static synchronized YuvImageRenderer create(int x, int y, int width, in
t height, |
579 ScalingType scalingType, boolean mirror) { | 500 RendererCommon.ScalingType scalingType, boolean mirror) { |
580 // Check display region parameters. | 501 // Check display region parameters. |
581 if (x < 0 || x > 100 || y < 0 || y > 100 || | 502 if (x < 0 || x > 100 || y < 0 || y > 100 || |
582 width < 0 || width > 100 || height < 0 || height > 100 || | 503 width < 0 || width > 100 || height < 0 || height > 100 || |
583 x + width > 100 || y + height > 100) { | 504 x + width > 100 || y + height > 100) { |
584 throw new RuntimeException("Incorrect window parameters."); | 505 throw new RuntimeException("Incorrect window parameters."); |
585 } | 506 } |
586 | 507 |
587 if (instance == null) { | 508 if (instance == null) { |
588 throw new RuntimeException( | 509 throw new RuntimeException( |
589 "Attempt to create yuv renderer before setting GLSurfaceView"); | 510 "Attempt to create yuv renderer before setting GLSurfaceView"); |
(...skipping 22 matching lines...) Expand all Loading... |
612 throw new RuntimeException(e); | 533 throw new RuntimeException(e); |
613 } | 534 } |
614 } | 535 } |
615 // Add yuv renderer to rendering list. | 536 // Add yuv renderer to rendering list. |
616 instance.yuvImageRenderers.add(yuvImageRenderer); | 537 instance.yuvImageRenderers.add(yuvImageRenderer); |
617 } | 538 } |
618 return yuvImageRenderer; | 539 return yuvImageRenderer; |
619 } | 540 } |
620 | 541 |
621 public static synchronized void update( | 542 public static synchronized void update( |
622 VideoRenderer.Callbacks renderer, | 543 VideoRenderer.Callbacks renderer, int x, int y, int width, int height, |
623 int x, int y, int width, int height, ScalingType scalingType, boolean mirr
or) { | 544 RendererCommon.ScalingType scalingType, boolean mirror) { |
624 Log.d(TAG, "VideoRendererGui.update"); | 545 Log.d(TAG, "VideoRendererGui.update"); |
625 if (instance == null) { | 546 if (instance == null) { |
626 throw new RuntimeException( | 547 throw new RuntimeException( |
627 "Attempt to update yuv renderer before setting GLSurfaceView"); | 548 "Attempt to update yuv renderer before setting GLSurfaceView"); |
628 } | 549 } |
629 synchronized (instance.yuvImageRenderers) { | 550 synchronized (instance.yuvImageRenderers) { |
630 for (YuvImageRenderer yuvImageRenderer : instance.yuvImageRenderers) { | 551 for (YuvImageRenderer yuvImageRenderer : instance.yuvImageRenderers) { |
631 if (yuvImageRenderer == renderer) { | 552 if (yuvImageRenderer == renderer) { |
632 yuvImageRenderer.setPosition(x, y, width, height, scalingType, mirror)
; | 553 yuvImageRenderer.setPosition(x, y, width, height, scalingType, mirror)
; |
633 } | 554 } |
634 } | 555 } |
635 } | 556 } |
636 } | 557 } |
637 | 558 |
638 public static synchronized void setRendererEvents( | 559 public static synchronized void setRendererEvents( |
639 VideoRenderer.Callbacks renderer, RendererEvents rendererEvents) { | 560 VideoRenderer.Callbacks renderer, RendererCommon.RendererEvents rendererEv
ents) { |
640 Log.d(TAG, "VideoRendererGui.setRendererEvents"); | 561 Log.d(TAG, "VideoRendererGui.setRendererEvents"); |
641 if (instance == null) { | 562 if (instance == null) { |
642 throw new RuntimeException( | 563 throw new RuntimeException( |
643 "Attempt to set renderer events before setting GLSurfaceView"); | 564 "Attempt to set renderer events before setting GLSurfaceView"); |
644 } | 565 } |
645 synchronized (instance.yuvImageRenderers) { | 566 synchronized (instance.yuvImageRenderers) { |
646 for (YuvImageRenderer yuvImageRenderer : instance.yuvImageRenderers) { | 567 for (YuvImageRenderer yuvImageRenderer : instance.yuvImageRenderers) { |
647 if (yuvImageRenderer == renderer) { | 568 if (yuvImageRenderer == renderer) { |
648 yuvImageRenderer.rendererEvents = rendererEvents; | 569 yuvImageRenderer.rendererEvents = rendererEvents; |
649 } | 570 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 GLES20.glViewport(0, 0, screenWidth, screenHeight); | 639 GLES20.glViewport(0, 0, screenWidth, screenHeight); |
719 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); | 640 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); |
720 synchronized (yuvImageRenderers) { | 641 synchronized (yuvImageRenderers) { |
721 for (YuvImageRenderer yuvImageRenderer : yuvImageRenderers) { | 642 for (YuvImageRenderer yuvImageRenderer : yuvImageRenderers) { |
722 yuvImageRenderer.draw(drawer); | 643 yuvImageRenderer.draw(drawer); |
723 } | 644 } |
724 } | 645 } |
725 } | 646 } |
726 | 647 |
727 } | 648 } |
OLD | NEW |