| Index: talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| diff --git a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| index 9909bff49246b2ff8502af37417aa06bf884ea15..38672778ce46c0bdedcca4841c810130b601aecd 100644
|
| --- a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| +++ b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
|
| @@ -101,7 +101,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| private int id;
|
| // TODO(magjed): Delete |yuvTextures| in release(). Must be synchronized with draw().
|
| private int[] yuvTextures = { 0, 0, 0 };
|
| - private int oesTexture = 0;
|
| + // Resources for making a deep copy of incoming OES texture frame.
|
| + private GlTextureFrameBuffer textureCopy;
|
|
|
| // Pending frame to render. Serves as a queue with size 1. |pendingFrame| is accessed by two
|
| // threads - frames are received in renderFrame() and consumed in draw(). Frames are dropped in
|
| @@ -187,6 +188,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| for (int i = 0; i < 3; i++) {
|
| yuvTextures[i] = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D);
|
| }
|
| + // Generate texture and framebuffer for offscreen texture copy.
|
| + textureCopy = new GlTextureFrameBuffer(GLES20.GL_RGB);
|
| }
|
|
|
| private void updateLayoutMatrix() {
|
| @@ -228,10 +231,6 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| }
|
| long now = System.nanoTime();
|
|
|
| - // OpenGL defaults to lower left origin.
|
| - GLES20.glViewport(displayLayout.left, screenHeight - displayLayout.bottom,
|
| - displayLayout.width(), displayLayout.height());
|
| -
|
| final boolean isNewFrame;
|
| synchronized (pendingFrameLock) {
|
| isNewFrame = (pendingFrame != null);
|
| @@ -240,37 +239,46 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
| }
|
|
|
| if (isNewFrame) {
|
| + samplingMatrix = RendererCommon.rotateTextureMatrix(
|
| + pendingFrame.samplingMatrix, pendingFrame.rotationDegree);
|
| if (pendingFrame.yuvFrame) {
|
| rendererType = RendererType.RENDERER_YUV;
|
| drawer.uploadYuvData(yuvTextures, pendingFrame.width, pendingFrame.height,
|
| pendingFrame.yuvStrides, pendingFrame.yuvPlanes);
|
| } else {
|
| rendererType = RendererType.RENDERER_TEXTURE;
|
| - // External texture rendering. Copy texture id and update texture image to latest.
|
| - // TODO(magjed): We should not make an unmanaged copy of texture id. Also, this is not
|
| - // the best place to call updateTexImage.
|
| - oesTexture = pendingFrame.textureId;
|
| - if (pendingFrame.textureObject instanceof SurfaceTexture) {
|
| - SurfaceTexture surfaceTexture =
|
| - (SurfaceTexture) pendingFrame.textureObject;
|
| - surfaceTexture.updateTexImage();
|
| - }
|
| + // Make a deep copy of the external texture.
|
| + // Reallocate offscreen texture if necessary.
|
| + textureCopy.setSize(pendingFrame.rotatedWidth(), pendingFrame.rotatedHeight());
|
| +
|
| + // Bind our offscreen framebuffer.
|
| + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, textureCopy.getFrameBufferId());
|
| + GlUtil.checkNoGLES2Error("glBindFramebuffer");
|
| +
|
| + // Copy the OES texture content. This will also normalize the sampling matrix.
|
| + GLES20.glViewport(0, 0, textureCopy.getWidth(), textureCopy.getHeight());
|
| + drawer.drawOes(pendingFrame.textureId, samplingMatrix);
|
| + samplingMatrix = RendererCommon.IDENTITY_MATRIX;
|
| +
|
| + // Restore normal framebuffer.
|
| + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
| }
|
| - samplingMatrix = RendererCommon.getSamplingMatrix(
|
| - (SurfaceTexture) pendingFrame.textureObject, pendingFrame.rotationDegree);
|
| copyTimeNs += (System.nanoTime() - now);
|
| VideoRenderer.renderFrameDone(pendingFrame);
|
| pendingFrame = null;
|
| }
|
| }
|
|
|
| + // OpenGL defaults to lower left origin - flip coordinates vertically.
|
| + GLES20.glViewport(displayLayout.left, screenHeight - displayLayout.bottom,
|
| + displayLayout.width(), displayLayout.height());
|
| updateLayoutMatrix();
|
| final float[] texMatrix = new float[16];
|
| Matrix.multiplyMM(texMatrix, 0, samplingMatrix, 0, layoutMatrix, 0);
|
| if (rendererType == RendererType.RENDERER_YUV) {
|
| drawer.drawYuv(yuvTextures, texMatrix);
|
| } else {
|
| - drawer.drawOes(oesTexture, texMatrix);
|
| + drawer.drawRgb(textureCopy.getTextureId(), texMatrix);
|
| }
|
|
|
| if (isNewFrame) {
|
|
|