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..e15b49fab31f1d9f82cb1cafe7ebd2e3ca425b97 100644 |
--- a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java |
+++ b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java |
@@ -143,7 +143,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
// |screenHeight|, |videoWidth|, |videoHeight|, |rotationDegree|, |scalingType|, and |mirror|. |
private final Object updateLayoutLock = new Object(); |
// Texture sampling matrix. |
- private float[] samplingMatrix; |
+ private float[] rotatedSamplingMatrix; |
// Viewport dimensions. |
private int screenWidth; |
private int screenHeight; |
@@ -240,24 +240,29 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
} |
if (isNewFrame) { |
+ final float[] samplingMatrix; |
if (pendingFrame.yuvFrame) { |
rendererType = RendererType.RENDERER_YUV; |
drawer.uploadYuvData(yuvTextures, pendingFrame.width, pendingFrame.height, |
pendingFrame.yuvStrides, pendingFrame.yuvPlanes); |
+ // The convention in WebRTC is that the first element in a ByteBuffer corresponds to the |
+ // top-left corner of the image, but in glTexImage2D() the first element corresponds to |
+ // the bottom-left corner. We correct this discrepancy by setting a vertical flip as |
+ // sampling matrix. |
+ samplingMatrix = RendererCommon.verticalFlipMatrix(); |
} 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(); |
- } |
+ final SurfaceTexture surfaceTexture = (SurfaceTexture) pendingFrame.textureObject; |
+ surfaceTexture.updateTexImage(); |
+ samplingMatrix = new float[16]; |
+ surfaceTexture.getTransformMatrix(samplingMatrix); |
} |
- samplingMatrix = RendererCommon.getSamplingMatrix( |
- (SurfaceTexture) pendingFrame.textureObject, pendingFrame.rotationDegree); |
+ rotatedSamplingMatrix = RendererCommon.rotateTextureMatrix( |
+ samplingMatrix, pendingFrame.rotationDegree); |
copyTimeNs += (System.nanoTime() - now); |
VideoRenderer.renderFrameDone(pendingFrame); |
pendingFrame = null; |
@@ -265,8 +270,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { |
} |
updateLayoutMatrix(); |
- final float[] texMatrix = new float[16]; |
- Matrix.multiplyMM(texMatrix, 0, samplingMatrix, 0, layoutMatrix, 0); |
+ final float[] texMatrix = |
+ RendererCommon.multiplyMatrices(rotatedSamplingMatrix, layoutMatrix); |
if (rendererType == RendererType.RENDERER_YUV) { |
drawer.drawYuv(yuvTextures, texMatrix); |
} else { |