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

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

Issue 2938103002: ran git cl format webrtc/sdk/android/
Patch Set: Created 3 years, 6 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.content.Context; 13 import android.content.Context;
14 import android.content.res.Resources.NotFoundException; 14 import android.content.res.Resources.NotFoundException;
15 import android.graphics.Matrix;
15 import android.graphics.Point; 16 import android.graphics.Point;
17 import android.graphics.SurfaceTexture;
16 import android.util.AttributeSet; 18 import android.util.AttributeSet;
19 import android.view.Surface;
17 import android.view.SurfaceHolder; 20 import android.view.SurfaceHolder;
18 import android.view.SurfaceView; 21 import android.view.TextureView;
22 import android.view.TextureView.SurfaceTextureListener;
23
19 import java.util.concurrent.CountDownLatch; 24 import java.util.concurrent.CountDownLatch;
20 25
21 /** 26 /**
22 * Implements org.webrtc.VideoRenderer.Callbacks by displaying the video stream on a SurfaceView. 27 * Implements org.webrtc.VideoRenderer.Callbacks by displaying the video stream on a SurfaceView.
23 * renderFrame() is asynchronous to avoid blocking the calling thread. 28 * renderFrame() is asynchronous to avoid blocking the calling thread.
24 * This class is thread safe and handles access from potentially four different threads: 29 * This class is thread safe and handles access from potentially four different threads:
25 * Interaction from the main app in init, release, setMirror, and setScalingtype . 30 * Interaction from the main app in init, release, setMirror, and setScalingtype .
26 * Interaction from C++ rtc::VideoSinkInterface in renderFrame. 31 * Interaction from C++ rtc::VideoSinkInterface in renderFrame.
27 * Interaction from the Activity lifecycle in surfaceCreated, surfaceChanged, an d surfaceDestroyed. 32 * Interaction from the Activity lifecycle in surfaceCreated, surfaceChanged, an d surfaceDestroyed.
28 * Interaction with the layout framework in onMeasure and onSizeChanged. 33 * Interaction with the layout framework in onMeasure and onSizeChanged.
29 */ 34 */
30 public class SurfaceViewRenderer 35 public class TextureViewRenderer extends TextureView
31 extends SurfaceView implements SurfaceHolder.Callback, VideoRenderer.Callbac ks { 36 implements SurfaceHolder.Callback, SurfaceTextureListener, VideoRenderer.Cal lbacks {
32 private static final String TAG = "SurfaceViewRenderer"; 37 private static final String TAG = "SurfaceViewRenderer";
33 38
34 // Cached resource name. 39 // Cached resource name.
35 private final String resourceName; 40 private final String resourceName;
36 private final RendererCommon.VideoLayoutMeasure videoLayoutMeasure = 41 private final RendererCommon.VideoLayoutMeasure videoLayoutMeasure =
37 new RendererCommon.VideoLayoutMeasure(); 42 new RendererCommon.VideoLayoutMeasure();
38 private final EglRenderer eglRenderer; 43 private final EglRenderer eglRenderer;
39 44
40 // Callback for reporting renderer events. Read-only after initilization so no lock required. 45 // Callback for reporting renderer events. Read-only after initilization so no lock required.
41 private RendererCommon.RendererEvents rendererEvents; 46 private RendererCommon.RendererEvents rendererEvents;
42 47
43 private final Object layoutLock = new Object(); 48 private final Object layoutLock = new Object();
44 private boolean isFirstFrameRendered; 49 private boolean isFirstFrameRendered;
45 private int rotatedFrameWidth; 50 private int rotatedFrameWidth;
46 private int rotatedFrameHeight; 51 private int rotatedFrameHeight;
47 private int frameRotation; 52 private int frameRotation;
48 53
49 // Accessed only on the main thread. 54 // Accessed only on the main thread.
50 private boolean enableFixedSize; 55 private boolean enableFixedSize;
51 private int surfaceWidth; 56 private int surfaceWidth;
52 private int surfaceHeight; 57 private int surfaceHeight;
53 58
54 /** 59 /**
55 * Standard View constructor. In order to render something, you must first cal l init(). 60 * Standard View constructor. In order to render something, you must first cal l init().
56 */ 61 */
57 public SurfaceViewRenderer(Context context) { 62 public TextureViewRenderer(Context context) {
58 super(context); 63 super(context);
59 this.resourceName = getResourceName(); 64 this.resourceName = getResourceName();
60 eglRenderer = new EglRenderer(resourceName); 65 eglRenderer = new EglRenderer(resourceName);
61 getHolder().addCallback(this); 66 setSurfaceTextureListener(this);
62 } 67 }
63 68
64 /** 69 /**
65 * Standard View constructor. In order to render something, you must first cal l init(). 70 * Standard View constructor. In order to render something, you must first cal l init().
66 */ 71 */
67 public SurfaceViewRenderer(Context context, AttributeSet attrs) { 72 public TextureViewRenderer(Context context, AttributeSet attrs) {
68 super(context, attrs); 73 super(context, attrs);
69 this.resourceName = getResourceName(); 74 this.resourceName = getResourceName();
70 eglRenderer = new EglRenderer(resourceName); 75 eglRenderer = new EglRenderer(resourceName);
71 getHolder().addCallback(this); 76 setSurfaceTextureListener(this);
72 } 77 }
73 78
74 /** 79 /**
75 * Initialize this class, sharing resources with |sharedContext|. It is allowe d to call init() to 80 * Initialize this class, sharing resources with |sharedContext|. It is allowe d to call init() to
76 * reinitialize the renderer after a previous init()/release() cycle. 81 * reinitialize the renderer after a previous init()/release() cycle.
77 */ 82 */
78 public void init(EglBase.Context sharedContext, RendererCommon.RendererEvents rendererEvents) { 83 public void init(EglBase.Context sharedContext, RendererCommon.RendererEvents rendererEvents) {
79 init(sharedContext, rendererEvents, EglBase.CONFIG_PLAIN, new GlRectDrawer() ); 84 init(sharedContext, rendererEvents, EglBase.CONFIG_PLAIN, new GlRectDrawer() );
80 } 85 }
81 86
(...skipping 26 matching lines...) Expand all
108 eglRenderer.release(); 113 eglRenderer.release();
109 } 114 }
110 115
111 /** 116 /**
112 * Register a callback to be invoked when a new video frame has been received. 117 * Register a callback to be invoked when a new video frame has been received.
113 * 118 *
114 * @param listener The callback to be invoked. The callback will be invoked on the render thread. 119 * @param listener The callback to be invoked. The callback will be invoked on the render thread.
115 * It should be lightweight and must not call removeFrameListe ner. 120 * It should be lightweight and must not call removeFrameListe ner.
116 * @param scale The scale of the Bitmap passed to the callback, or 0 if no Bitmap is 121 * @param scale The scale of the Bitmap passed to the callback, or 0 if no Bitmap is
117 * required. 122 * required.
118 * @param drawer Custom drawer to use for this frame listener. 123 * @param drawerParam Custom drawer to use for this frame listener.
119 */ 124 */
120 public void addFrameListener( 125 public void addFrameListener(
121 EglRenderer.FrameListener listener, float scale, RendererCommon.GlDrawer d rawerParam) { 126 EglRenderer.FrameListener listener, float scale, RendererCommon.GlDrawer d rawerParam) {
122 eglRenderer.addFrameListener(listener, scale, drawerParam); 127 eglRenderer.addFrameListener(listener, scale, drawerParam);
123 } 128 }
124 129
125 /** 130 /**
126 * Register a callback to be invoked when a new video frame has been received. This version uses 131 * Register a callback to be invoked when a new video frame has been received. This version uses
127 * the drawer of the EglRenderer that was passed in init. 132 * the drawer of the EglRenderer that was passed in init.
128 * 133 *
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 238 }
234 // Aspect ratio of the drawn frame and the view is the same. 239 // Aspect ratio of the drawn frame and the view is the same.
235 final int width = Math.min(getWidth(), drawnFrameWidth); 240 final int width = Math.min(getWidth(), drawnFrameWidth);
236 final int height = Math.min(getHeight(), drawnFrameHeight); 241 final int height = Math.min(getHeight(), drawnFrameHeight);
237 logD("updateSurfaceSize. Layout size: " + getWidth() + "x" + getHeight() + ", frame size: " 242 logD("updateSurfaceSize. Layout size: " + getWidth() + "x" + getHeight() + ", frame size: "
238 + rotatedFrameWidth + "x" + rotatedFrameHeight + ", requested surfac e size: " + width 243 + rotatedFrameWidth + "x" + rotatedFrameHeight + ", requested surfac e size: " + width
239 + "x" + height + ", old surface size: " + surfaceWidth + "x" + surfa ceHeight); 244 + "x" + height + ", old surface size: " + surfaceWidth + "x" + surfa ceHeight);
240 if (width != surfaceWidth || height != surfaceHeight) { 245 if (width != surfaceWidth || height != surfaceHeight) {
241 surfaceWidth = width; 246 surfaceWidth = width;
242 surfaceHeight = height; 247 surfaceHeight = height;
243 getHolder().setFixedSize(width, height); 248 adjustAspectRatio(surfaceWidth, surfaceHeight);
sakal 2017/06/16 07:47:02 This doesn't change the surface size?
244 } 249 }
245 } else { 250 } else {
246 surfaceWidth = surfaceHeight = 0; 251 surfaceWidth = surfaceHeight = 0;
sakal 2017/06/16 07:47:02 We have to somehow reset the surface size
247 getHolder().setSizeFromLayout();
248 } 252 }
249 } 253 }
250 } 254 }
251 255
256 /**
257 * Sets the TextureView transform to preserve the aspect ratio of the video.
258 */
259 private void adjustAspectRatio(int videoWidth, int videoHeight) {
sakal 2017/06/16 07:47:02 This method is not needed if you correctly call se
260 int viewWidth = getWidth();
261 int viewHeight = getHeight();
262 double aspectRatio = (double) videoHeight / videoWidth;
263
264 int newWidth, newHeight;
265 if (viewHeight > (int) (viewWidth * aspectRatio)) {
266 // limited by narrow width; restrict height
267 newWidth = viewWidth;
268 newHeight = (int) (viewWidth * aspectRatio);
269 } else {
270 // limited by short height; restrict width
271 newWidth = (int) (viewHeight / aspectRatio);
272 newHeight = viewHeight;
273 }
274 int xoff = (viewWidth - newWidth) / 2;
275 int yoff = (viewHeight - newHeight) / 2;
276 logD("video=" + videoWidth + "x" + videoHeight + " view=" + viewWidth + "x" + viewHeight
277 + " newView=" + newWidth + "x" + newHeight + " off=" + xoff + "," + yoff );
278
279 Matrix txform = new Matrix();
280 getTransform(txform);
281 txform.setScale((float) newWidth / viewWidth, (float) newHeight / viewHeight );
282 // txform.postRotate(10); // just for fun
283 txform.postTranslate(xoff, yoff);
284 setTransform(txform);
285 }
286
252 // SurfaceHolder.Callback interface. 287 // SurfaceHolder.Callback interface.
253 @Override 288 @Override
254 public void surfaceCreated(final SurfaceHolder holder) { 289 public void surfaceCreated(final SurfaceHolder holder) {
255 ThreadUtils.checkIsOnMainThread(); 290 ThreadUtils.checkIsOnMainThread();
256 eglRenderer.createEglSurface(holder.getSurface()); 291 eglRenderer.createEglSurface(holder.getSurface());
257 surfaceWidth = surfaceHeight = 0; 292 surfaceWidth = surfaceHeight = 0;
258 updateSurfaceSize(); 293 updateSurfaceSize();
259 } 294 }
260 295
261 @Override 296 @Override
262 public void surfaceDestroyed(SurfaceHolder holder) { 297 public void surfaceDestroyed(SurfaceHolder holder) {
263 ThreadUtils.checkIsOnMainThread(); 298 ThreadUtils.checkIsOnMainThread();
264 final CountDownLatch completionLatch = new CountDownLatch(1); 299 final CountDownLatch completionLatch = new CountDownLatch(1);
265 eglRenderer.releaseEglSurface(new Runnable() { 300 eglRenderer.releaseEglSurface(new Runnable() {
266 @Override 301 @Override
267 public void run() { 302 public void run() {
268 completionLatch.countDown(); 303 completionLatch.countDown();
269 } 304 }
270 }); 305 });
271 ThreadUtils.awaitUninterruptibly(completionLatch); 306 ThreadUtils.awaitUninterruptibly(completionLatch);
272 } 307 }
273 308
274 @Override 309 @Override
275 public void surfaceChanged(SurfaceHolder holder, int format, int width, int he ight) { 310 public void surfaceChanged(SurfaceHolder holder, int format, int width, int he ight) {
276 ThreadUtils.checkIsOnMainThread(); 311 ThreadUtils.checkIsOnMainThread();
277 logD("surfaceChanged: format: " + format + " size: " + width + "x" + height) ; 312 logD("surfaceChanged: format: " + format + " size: " + width + "x" + height) ;
278 } 313 }
279 314
315 // TextureView.SurfaceTextureListener implementation
316 @Override
317 public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, in t i1) {
318 ThreadUtils.checkIsOnMainThread();
319 eglRenderer.createEglSurface(new Surface(surfaceTexture));
320 surfaceWidth = surfaceHeight = 0;
321 updateSurfaceSize();
322 }
323
324 @Override
325 public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int wid th, int height) {
326 ThreadUtils.checkIsOnMainThread();
327 logD("surfaceChanged: size: " + width + "x" + height);
328 }
329
330 @Override
331 public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
332 ThreadUtils.checkIsOnMainThread();
333 final CountDownLatch completionLatch = new CountDownLatch(1);
334 eglRenderer.releaseEglSurface(new Runnable() {
335 @Override
336 public void run() {
337 completionLatch.countDown();
338 }
339 });
340 ThreadUtils.awaitUninterruptibly(completionLatch);
341 return true;
342 }
343
344 @Override
345 public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
346
280 private String getResourceName() { 347 private String getResourceName() {
281 try { 348 try {
282 return getResources().getResourceEntryName(getId()) + ": "; 349 return getResources().getResourceEntryName(getId()) + ": ";
283 } catch (NotFoundException e) { 350 } catch (NotFoundException e) {
284 return ""; 351 return "";
285 } 352 }
286 } 353 }
287 354
288 /** 355 /**
289 * Post a task to clear the SurfaceView to a transparent uniform color. 356 * Post a task to clear the SurfaceView to a transparent uniform color.
(...skipping 30 matching lines...) Expand all
320 } 387 }
321 }); 388 });
322 } 389 }
323 } 390 }
324 } 391 }
325 392
326 private void logD(String string) { 393 private void logD(String string) {
327 Logging.d(TAG, resourceName + string); 394 Logging.d(TAG, resourceName + string);
328 } 395 }
329 } 396 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698