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

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

Issue 1370063003: Android SurfaceViewRenderer: Enable hardware scaler (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 * This class is thread safe and handles access from potentially four different threads: 49 * This class is thread safe and handles access from potentially four different threads:
50 * Interaction from the main app in init, release, setMirror, and setScalingtype . 50 * Interaction from the main app in init, release, setMirror, and setScalingtype .
51 * Interaction from C++ webrtc::VideoRendererInterface in renderFrame and canApp lyRotation. 51 * Interaction from C++ webrtc::VideoRendererInterface in renderFrame and canApp lyRotation.
52 * Interaction from the Activity lifecycle in surfaceCreated, surfaceChanged, an d surfaceDestroyed. 52 * Interaction from the Activity lifecycle in surfaceCreated, surfaceChanged, an d surfaceDestroyed.
53 * Interaction with the layout framework in onMeasure and onSizeChanged. 53 * Interaction with the layout framework in onMeasure and onSizeChanged.
54 */ 54 */
55 public class SurfaceViewRenderer extends SurfaceView 55 public class SurfaceViewRenderer extends SurfaceView
56 implements SurfaceHolder.Callback, VideoRenderer.Callbacks { 56 implements SurfaceHolder.Callback, VideoRenderer.Callbacks {
57 private static final String TAG = "SurfaceViewRenderer"; 57 private static final String TAG = "SurfaceViewRenderer";
58 58
59 /**
60 * Convenience class for layout plus surface size with equals() and toString() functionality.
61 */
62 private static class LayoutConfiguration {
hbos 2015/11/12 11:35:47 If two objects are considered equal in java they s
63 public int layoutWidth;
64 public int layoutHeight;
65 public int surfaceWidth;
66 public int surfaceHeight;
67
68 public LayoutConfiguration() {}
69
70 public LayoutConfiguration(
71 int layoutWidth, int layoutHeight, int surfaceWidth, int surfaceHeight) {
72 this.layoutWidth = layoutWidth;
73 this.layoutHeight = layoutHeight;
74 this.surfaceWidth = surfaceWidth;
75 this.surfaceHeight = surfaceHeight;
76 }
77
78 @Override
79 public boolean equals(Object that) {
80 if (!(that instanceof LayoutConfiguration)) {
81 return false;
82 }
83 final LayoutConfiguration lc = (LayoutConfiguration) that;
84 return layoutWidth == lc.layoutWidth && layoutHeight == lc.layoutHeight
85 && surfaceWidth == lc.surfaceWidth && surfaceHeight == lc.surfaceHeigh t;
86 }
87
88 @Override
89 public String toString() {
90 return "Layout: " + layoutWidth + "x" + layoutHeight
91 + ", Surface: " + surfaceWidth + "x" + surfaceHeight;
92 }
93 }
94
59 // Dedicated render thread. 95 // Dedicated render thread.
60 private HandlerThread renderThread; 96 private HandlerThread renderThread;
61 // |renderThreadHandler| is a handler for communicating with |renderThread|, a nd is synchronized 97 // |renderThreadHandler| is a handler for communicating with |renderThread|, a nd is synchronized
62 // on |handlerLock|. 98 // on |handlerLock|.
63 private final Object handlerLock = new Object(); 99 private final Object handlerLock = new Object();
64 private Handler renderThreadHandler; 100 private Handler renderThreadHandler;
65 101
66 // EGL and GL resources for drawing YUV/OES textures. After initilization, the se are only accessed 102 // EGL and GL resources for drawing YUV/OES textures. After initilization, the se are only accessed
67 // from the render thread. 103 // from the render thread.
68 private EglBase eglBase; 104 private EglBase eglBase;
69 private GlRectDrawer drawer; 105 private GlRectDrawer drawer;
70 // Texture ids for YUV frames. Allocated on first arrival of a YUV frame. 106 // Texture ids for YUV frames. Allocated on first arrival of a YUV frame.
71 private int[] yuvTextures = null; 107 private int[] yuvTextures = null;
72 108
73 // Pending frame to render. Serves as a queue with size 1. Synchronized on |fr ameLock|. 109 // Pending frame to render. Serves as a queue with size 1. Synchronized on |fr ameLock|.
74 private final Object frameLock = new Object(); 110 private final Object frameLock = new Object();
75 private VideoRenderer.I420Frame pendingFrame; 111 private VideoRenderer.I420Frame pendingFrame;
76 112
77 // These variables are synchronized on |layoutLock|. 113 // These variables are synchronized on |layoutLock|.
78 private final Object layoutLock = new Object(); 114 private final Object layoutLock = new Object();
79 // These three different dimension values are used to keep track of the state in these functions: 115 // |widthSpec|/|heightSpec| is the most recent measurement specification from onMeasure().
80 // requestLayout() -> onMeasure() -> onLayout() -> surfaceChanged().
81 // requestLayout() is triggered internally by frame size changes, but can also be triggered
82 // externally by layout update requests.
83 // Most recent measurement specification from onMeasure().
84 private int widthSpec; 116 private int widthSpec;
85 private int heightSpec; 117 private int heightSpec;
86 // Current size on screen in pixels. Updated in onLayout(), and should be cons istent with 118 // |isBlack| is true if the current surface is completely black. Changing layo ut aspect ratio or
87 // |widthSpec|/|heightSpec| after that. 119 // surface size is only allowed while the surface is black to avoid render art ifacts.
88 private int layoutWidth; 120 private boolean isBlack = true;
89 private int layoutHeight; 121 // |desiredConfig| is the layout configuration we want and are waiting for.
90 // Current surface size of the underlying Surface. Updated in surfaceChanged() , and should be 122 private LayoutConfiguration desiredConfig;
91 // consistent with |layoutWidth|/|layoutHeight| after that. 123 // |currentConfig| is the actual current layout configuration.
92 // TODO(magjed): Enable hardware scaler with SurfaceHolder.setFixedSize(). Thi s will decouple 124 private final LayoutConfiguration currentConfig = new LayoutConfiguration();
93 // layout and surface size.
94 private int surfaceWidth;
95 private int surfaceHeight;
96 // |isSurfaceCreated| keeps track of the current status in surfaceCreated()/su rfaceDestroyed(). 125 // |isSurfaceCreated| keeps track of the current status in surfaceCreated()/su rfaceDestroyed().
97 private boolean isSurfaceCreated; 126 private boolean isSurfaceCreated;
98 // Last rendered frame dimensions, or 0 if no frame has been rendered yet. 127 // Last rendered frame dimensions, or 0 if no frame has been rendered yet.
99 private int frameWidth; 128 private int frameWidth;
100 private int frameHeight; 129 private int frameHeight;
101 private int frameRotation; 130 private int frameRotation;
102 // |scalingType| determines how the video will fill the allowed layout area in onMeasure(). 131 // |scalingType| determines how the video will fill the allowed layout area in onMeasure().
103 private RendererCommon.ScalingType scalingType = RendererCommon.ScalingType.SC ALE_ASPECT_BALANCED; 132 private RendererCommon.ScalingType scalingType = RendererCommon.ScalingType.SC ALE_ASPECT_BALANCED;
104 // If true, mirrors the video stream horizontally. 133 // If true, mirrors the video stream horizontally.
105 private boolean mirror; 134 private boolean mirror;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 VideoRenderer.renderFrameDone(pendingFrame); 318 VideoRenderer.renderFrameDone(pendingFrame);
290 } 319 }
291 pendingFrame = frame; 320 pendingFrame = frame;
292 updateFrameDimensionsAndReportEvents(frame); 321 updateFrameDimensionsAndReportEvents(frame);
293 renderThreadHandler.post(renderFrameRunnable); 322 renderThreadHandler.post(renderFrameRunnable);
294 } 323 }
295 } 324 }
296 } 325 }
297 326
298 // Returns desired layout size given current measure specification and video a spect ratio. 327 // Returns desired layout size given current measure specification and video a spect ratio.
299 private Point getDesiredLayoutSize() { 328 private static Point getDesiredLayoutSize(
300 synchronized (layoutLock) { 329 int widthSpec, int heightSpec,
301 final int maxWidth = getDefaultSize(Integer.MAX_VALUE, widthSpec); 330 RendererCommon.ScalingType scalingType, float frameAspectRatio) {
302 final int maxHeight = getDefaultSize(Integer.MAX_VALUE, heightSpec); 331 final int maxWidth = getDefaultSize(Integer.MAX_VALUE, widthSpec);
303 final Point size = 332 final int maxHeight = getDefaultSize(Integer.MAX_VALUE, heightSpec);
304 RendererCommon.getDisplaySize(scalingType, frameAspectRatio(), maxWidt h, maxHeight); 333 final Point size =
305 if (MeasureSpec.getMode(widthSpec) == MeasureSpec.EXACTLY) { 334 RendererCommon.getDisplaySize(scalingType, frameAspectRatio, maxWidth, m axHeight);
306 size.x = maxWidth; 335 if (MeasureSpec.getMode(widthSpec) == MeasureSpec.EXACTLY) {
307 } 336 size.x = maxWidth;
308 if (MeasureSpec.getMode(heightSpec) == MeasureSpec.EXACTLY) {
309 size.y = maxHeight;
310 }
311 return size;
312 } 337 }
338 if (MeasureSpec.getMode(heightSpec) == MeasureSpec.EXACTLY) {
339 size.y = maxHeight;
340 }
hbos 2015/11/12 11:35:47 What about MeasureSpec.AT_MOST? What if X is restr
341 return size;
342 }
343
344 /**
345 * Calculate desired LayoutConfiguration based on measure specification, scali ng type,
346 * and frame size.
347 */
348 private static LayoutConfiguration getDesiredLayoutConfiguration(int widthSpec , int heightSpec,
349 RendererCommon.ScalingType scalingType, int frameWidth, int frameHeight) {
350 final Point layoutSize = getDesiredLayoutSize(
351 widthSpec, heightSpec, scalingType, (float) frameWidth / frameHeight);
352 // Calculate at what scale we are rendering the frame.
353 final float displayScale =
354 Math.max((float) layoutSize.x / frameWidth, (float) layoutSize.y / frame Height);
hbos 2015/11/12 11:35:47 Do we always want the max scale? Thinking about bl
355 final int surfaceWidth;
356 final int surfaceHeight;
357 if (displayScale > 1) {
358 // Upscaling - decrease surface size and let the HW scaler take care of th e upscaling
359 // instead of the GPU.
360 surfaceWidth = Math.round(layoutSize.x / displayScale);
361 surfaceHeight = Math.round(layoutSize.y / displayScale);
hbos 2015/11/12 11:35:47 How does the HW scaler know to take care of the up
362 } else {
363 // Downscaling - render at layout resolution.
364 surfaceWidth = layoutSize.x;
365 surfaceHeight = layoutSize.y;
366 }
367 return new LayoutConfiguration(layoutSize.x, layoutSize.y, surfaceWidth, sur faceHeight);
313 } 368 }
314 369
315 // View layout interface. 370 // View layout interface.
316 @Override 371 @Override
317 protected void onMeasure(int widthSpec, int heightSpec) { 372 protected void onMeasure(int widthSpec, int heightSpec) {
318 synchronized (layoutLock) { 373 synchronized (layoutLock) {
319 this.widthSpec = widthSpec; 374 this.widthSpec = widthSpec;
320 this.heightSpec = heightSpec; 375 this.heightSpec = heightSpec;
321 final Point size = getDesiredLayoutSize(); 376
377 final RendererCommon.ScalingType scalingType;
378 final float aspectRatio;
379 if (isBlack) {
380 // Unconstrained layout change - update to latest.
381 scalingType = this.scalingType;
382 aspectRatio = frameAspectRatio();
383 } else {
384 // Lock aspect of currently rendered frame with |SCALE_ASPECT_FIT|.
385 scalingType = RendererCommon.ScalingType.SCALE_ASPECT_FIT;
386 aspectRatio = (float) currentConfig.surfaceWidth / currentConfig.surface Height;
387 }
388 final Point size = getDesiredLayoutSize(widthSpec, heightSpec, scalingType , aspectRatio);
322 setMeasuredDimension(size.x, size.y); 389 setMeasuredDimension(size.x, size.y);
323 } 390 }
324 } 391 }
325 392
326 @Override 393 @Override
327 protected void onLayout(boolean changed, int left, int top, int right, int bot tom) { 394 protected void onLayout(boolean changed, int left, int top, int right, int bot tom) {
328 synchronized (layoutLock) { 395 synchronized (layoutLock) {
329 layoutWidth = right - left; 396 currentConfig.layoutWidth = right - left;
330 layoutHeight = bottom - top; 397 currentConfig.layoutHeight = bottom - top;
331 } 398 }
332 // Might have a pending frame waiting for a layout of correct size. 399 // Might have a pending frame waiting for a layout of correct size.
333 runOnRenderThread(renderFrameRunnable); 400 runOnRenderThread(renderFrameRunnable);
334 } 401 }
335 402
336 // SurfaceHolder.Callback interface. 403 // SurfaceHolder.Callback interface.
337 @Override 404 @Override
338 public void surfaceCreated(final SurfaceHolder holder) { 405 public void surfaceCreated(final SurfaceHolder holder) {
339 Logging.d(TAG, getResourceName() + "Surface created."); 406 Logging.d(TAG, getResourceName() + "Surface created.");
340 synchronized (layoutLock) { 407 synchronized (layoutLock) {
341 isSurfaceCreated = true; 408 isSurfaceCreated = true;
342 } 409 }
343 tryCreateEglSurface(); 410 tryCreateEglSurface();
344 } 411 }
345 412
346 @Override 413 @Override
347 public void surfaceDestroyed(SurfaceHolder holder) { 414 public void surfaceDestroyed(SurfaceHolder holder) {
348 Logging.d(TAG, getResourceName() + "Surface destroyed."); 415 Logging.d(TAG, getResourceName() + "Surface destroyed.");
349 synchronized (layoutLock) { 416 synchronized (layoutLock) {
350 isSurfaceCreated = false; 417 isSurfaceCreated = false;
351 surfaceWidth = 0; 418 currentConfig.surfaceWidth = 0;
352 surfaceHeight = 0; 419 currentConfig.surfaceHeight = 0;
353 } 420 }
354 runOnRenderThread(new Runnable() { 421 runOnRenderThread(new Runnable() {
355 @Override public void run() { 422 @Override public void run() {
356 eglBase.releaseSurface(); 423 eglBase.releaseSurface();
357 } 424 }
358 }); 425 });
359 } 426 }
360 427
361 @Override 428 @Override
362 public void surfaceChanged(SurfaceHolder holder, int format, int width, int he ight) { 429 public void surfaceChanged(SurfaceHolder holder, int format, int width, int he ight) {
363 Logging.d(TAG, getResourceName() + "Surface changed: " + width + "x" + heigh t); 430 Logging.d(TAG, getResourceName() + "Surface changed: " + width + "x" + heigh t);
364 synchronized (layoutLock) { 431 synchronized (layoutLock) {
365 surfaceWidth = width; 432 currentConfig.surfaceWidth = width;
366 surfaceHeight = height; 433 currentConfig.surfaceHeight = height;
367 } 434 }
368 // Might have a pending frame waiting for a surface of correct size. 435 // Might have a pending frame waiting for a surface of correct size.
369 runOnRenderThread(renderFrameRunnable); 436 runOnRenderThread(renderFrameRunnable);
370 } 437 }
371 438
372 /** 439 /**
373 * Private helper function to post tasks safely. 440 * Private helper function to post tasks safely.
374 */ 441 */
375 private void runOnRenderThread(Runnable runnable) { 442 private void runOnRenderThread(Runnable runnable) {
376 synchronized (handlerLock) { 443 synchronized (handlerLock) {
(...skipping 11 matching lines...) Expand all
388 } 455 }
389 } 456 }
390 457
391 private void makeBlack() { 458 private void makeBlack() {
392 if (Thread.currentThread() != renderThread) { 459 if (Thread.currentThread() != renderThread) {
393 throw new IllegalStateException(getResourceName() + "Wrong thread."); 460 throw new IllegalStateException(getResourceName() + "Wrong thread.");
394 } 461 }
395 GLES20.glClearColor(0, 0, 0, 0); 462 GLES20.glClearColor(0, 0, 0, 0);
396 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 463 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
397 eglBase.swapBuffers(); 464 eglBase.swapBuffers();
465 isBlack = true;
398 } 466 }
399 467
400 /** 468 /**
401 * Requests new layout if necessary. Returns true if layout and surface size a re consistent. 469 * Requests new layout if necessary. Returns true if layout and surface size a re consistent.
402 */ 470 */
403 private boolean checkConsistentLayout() { 471 private boolean checkConsistentLayout() {
hbos 2015/11/12 11:35:47 if (Thread.currentThread() != renderThread) throw
404 synchronized (layoutLock) { 472 synchronized (layoutLock) {
405 final Point desiredLayoutSize = getDesiredLayoutSize(); 473 final int rotatedFrameWidth = (frameRotation % 180 == 0) ? frameWidth : fr ameHeight;
406 if (desiredLayoutSize.x != layoutWidth || desiredLayoutSize.y != layoutHei ght) { 474 final int rotatedFrameHeight = (frameRotation % 180 == 0) ? frameHeight : frameWidth;
407 Logging.d(TAG, getResourceName() + "Requesting new layout with size: " 475 final LayoutConfiguration newDesiredConfig = getDesiredLayoutConfiguration (
408 + desiredLayoutSize.x + "x" + desiredLayoutSize.y); 476 widthSpec, heightSpec, scalingType, rotatedFrameWidth, rotatedFrameHei ght);
477 if (!newDesiredConfig.equals(this.desiredConfig)) {
478 Logging.d(TAG, getResourceName() + "Requesting new config: " + newDesire dConfig);
479 this.desiredConfig = newDesiredConfig;
480 // Output intermediate black frame while the layout is updated.
481 makeBlack();
409 // Request layout update on UI thread. 482 // Request layout update on UI thread.
410 post(new Runnable() { 483 post(new Runnable() {
411 @Override public void run() { 484 @Override public void run() {
485 getHolder().setFixedSize(newDesiredConfig.surfaceWidth, newDesiredCo nfig.surfaceHeight);
486 // requestLayout() triggers onMeasure() -> onLayout().
412 requestLayout(); 487 requestLayout();
413 } 488 }
414 }); 489 });
415 return false; 490 return false;
416 } 491 }
417 // Wait for requestLayout() to propagate through this sequence before retu rning true: 492 return desiredConfig.equals(currentConfig);
418 // requestLayout() -> onMeasure() -> onLayout() -> surfaceChanged().
419 return surfaceWidth == layoutWidth && surfaceHeight == layoutHeight;
420 } 493 }
421 } 494 }
422 495
423 /** 496 /**
424 * Renders and releases |pendingFrame|. 497 * Renders and releases |pendingFrame|.
425 */ 498 */
426 private void renderFrameOnRenderThread() { 499 private void renderFrameOnRenderThread() {
427 if (Thread.currentThread() != renderThread) { 500 if (Thread.currentThread() != renderThread) {
428 throw new IllegalStateException(getResourceName() + "Wrong thread."); 501 throw new IllegalStateException(getResourceName() + "Wrong thread.");
429 } 502 }
430 if (eglBase == null || !eglBase.hasSurface()) { 503 if (eglBase == null || !eglBase.hasSurface()) {
431 Logging.d(TAG, getResourceName() + "No surface to draw on"); 504 Logging.d(TAG, getResourceName() + "No surface to draw on");
432 return; 505 return;
433 } 506 }
507 synchronized (frameLock) {
508 if (pendingFrame == null) {
509 return;
510 }
511 }
434 if (!checkConsistentLayout()) { 512 if (!checkConsistentLayout()) {
435 // Output intermediate black frames while the layout is updated. 513 // Wait until layout update is done.
436 makeBlack();
437 return; 514 return;
438 } 515 }
439 // After a surface size change, the EGLSurface might still have a buffer of the old size in the 516 // After a surface size change, the EGLSurface might still have a buffer of the old size in the
440 // pipeline. Querying the EGLSurface will show if the underlying buffer dime nsions haven't yet 517 // pipeline. Querying the EGLSurface will show if the underlying buffer dime nsions haven't yet
441 // changed. Such a buffer will be rendered incorrectly, so flush it with a b lack frame. 518 // changed. Such a buffer will be rendered incorrectly, so flush it with a b lack frame.
442 synchronized (layoutLock) { 519 synchronized (layoutLock) {
443 if (eglBase.surfaceWidth() != surfaceWidth || eglBase.surfaceHeight() != s urfaceHeight) { 520 if (eglBase.surfaceWidth() != currentConfig.surfaceWidth
521 || eglBase.surfaceHeight() != currentConfig.surfaceHeight) {
444 makeBlack(); 522 makeBlack();
445 } 523 }
446 } 524 }
447 // Fetch and render |pendingFrame|. 525 // Fetch and render |pendingFrame|.
448 final VideoRenderer.I420Frame frame; 526 final VideoRenderer.I420Frame frame;
449 synchronized (frameLock) { 527 synchronized (frameLock) {
450 if (pendingFrame == null) { 528 if (pendingFrame == null) {
451 return; 529 return;
452 } 530 }
453 frame = pendingFrame; 531 frame = pendingFrame;
454 pendingFrame = null; 532 pendingFrame = null;
455 } 533 }
456 534
457 final long startTimeNs = System.nanoTime(); 535 final long startTimeNs = System.nanoTime();
458 final float[] texMatrix; 536 final float[] texMatrix;
459 synchronized (layoutLock) { 537 synchronized (layoutLock) {
460 final float[] rotatedSamplingMatrix = 538 final float[] rotatedSamplingMatrix =
461 RendererCommon.rotateTextureMatrix(frame.samplingMatrix, frame.rotatio nDegree); 539 RendererCommon.rotateTextureMatrix(frame.samplingMatrix, frame.rotatio nDegree);
462 final float[] layoutMatrix = RendererCommon.getLayoutMatrix( 540 final float[] layoutMatrix = RendererCommon.getLayoutMatrix(mirror, frameA spectRatio(),
463 mirror, frameAspectRatio(), (float) layoutWidth / layoutHeight); 541 (float) currentConfig.surfaceWidth / currentConfig.surfaceHeight);
464 texMatrix = RendererCommon.multiplyMatrices(rotatedSamplingMatrix, layoutM atrix); 542 texMatrix = RendererCommon.multiplyMatrices(rotatedSamplingMatrix, layoutM atrix);
543 isBlack = false;
465 } 544 }
466 545
467 GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight); 546 GLES20.glViewport(0, 0, currentConfig.surfaceWidth, currentConfig.surfaceHei ght);
547 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
468 if (frame.yuvFrame) { 548 if (frame.yuvFrame) {
469 // Make sure YUV textures are allocated. 549 // Make sure YUV textures are allocated.
470 if (yuvTextures == null) { 550 if (yuvTextures == null) {
471 yuvTextures = new int[3]; 551 yuvTextures = new int[3];
472 for (int i = 0; i < 3; i++) { 552 for (int i = 0; i < 3; i++) {
473 yuvTextures[i] = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D); 553 yuvTextures[i] = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D);
474 } 554 }
475 } 555 }
476 drawer.uploadYuvData( 556 drawer.uploadYuvData(
477 yuvTextures, frame.width, frame.height, frame.yuvStrides, frame.yuvPla nes); 557 yuvTextures, frame.width, frame.height, frame.yuvStrides, frame.yuvPla nes);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 if (framesReceived > 0 && framesRendered > 0) { 613 if (framesReceived > 0 && framesRendered > 0) {
534 final long timeSinceFirstFrameNs = System.nanoTime() - firstFrameTimeNs; 614 final long timeSinceFirstFrameNs = System.nanoTime() - firstFrameTimeNs;
535 Logging.d(TAG, getResourceName() + "Duration: " + (int) (timeSinceFirstF rameNs / 1e6) + 615 Logging.d(TAG, getResourceName() + "Duration: " + (int) (timeSinceFirstF rameNs / 1e6) +
536 " ms. FPS: " + (float) framesRendered * 1e9 / timeSinceFirstFrameNs) ; 616 " ms. FPS: " + (float) framesRendered * 1e9 / timeSinceFirstFrameNs) ;
537 Logging.d(TAG, getResourceName() + "Average render time: " 617 Logging.d(TAG, getResourceName() + "Average render time: "
538 + (int) (renderTimeNs / (1000 * framesRendered)) + " us."); 618 + (int) (renderTimeNs / (1000 * framesRendered)) + " us.");
539 } 619 }
540 } 620 }
541 } 621 }
542 } 622 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698