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 20 matching lines...) Expand all Loading... |
31 import java.util.concurrent.CountDownLatch; | 31 import java.util.concurrent.CountDownLatch; |
32 | 32 |
33 import javax.microedition.khronos.egl.EGLConfig; | 33 import javax.microedition.khronos.egl.EGLConfig; |
34 import javax.microedition.khronos.egl.EGL10; | 34 import javax.microedition.khronos.egl.EGL10; |
35 import javax.microedition.khronos.egl.EGLContext; | 35 import javax.microedition.khronos.egl.EGLContext; |
36 import javax.microedition.khronos.opengles.GL10; | 36 import javax.microedition.khronos.opengles.GL10; |
37 | 37 |
38 import android.annotation.SuppressLint; | 38 import android.annotation.SuppressLint; |
39 import android.graphics.Point; | 39 import android.graphics.Point; |
40 import android.graphics.Rect; | 40 import android.graphics.Rect; |
| 41 import android.graphics.SurfaceTexture; |
41 import android.opengl.GLES20; | 42 import android.opengl.GLES20; |
42 import android.opengl.GLSurfaceView; | 43 import android.opengl.GLSurfaceView; |
43 | 44 |
44 import org.webrtc.Logging; | 45 import org.webrtc.Logging; |
45 import org.webrtc.VideoRenderer.I420Frame; | 46 import org.webrtc.VideoRenderer.I420Frame; |
46 | 47 |
47 /** | 48 /** |
48 * Efficiently renders YUV frames using the GPU for CSC. | 49 * Efficiently renders YUV frames using the GPU for CSC. |
49 * Clients will want first to call setView() to pass GLSurfaceView | 50 * Clients will want first to call setView() to pass GLSurfaceView |
50 * and then for each video stream either create instance of VideoRenderer using | 51 * and then for each video stream either create instance of VideoRenderer using |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 long now = System.nanoTime(); | 234 long now = System.nanoTime(); |
234 | 235 |
235 final boolean isNewFrame; | 236 final boolean isNewFrame; |
236 synchronized (pendingFrameLock) { | 237 synchronized (pendingFrameLock) { |
237 isNewFrame = (pendingFrame != null); | 238 isNewFrame = (pendingFrame != null); |
238 if (isNewFrame && startTimeNs == -1) { | 239 if (isNewFrame && startTimeNs == -1) { |
239 startTimeNs = now; | 240 startTimeNs = now; |
240 } | 241 } |
241 | 242 |
242 if (isNewFrame) { | 243 if (isNewFrame) { |
243 rotatedSamplingMatrix = RendererCommon.rotateTextureMatrix( | |
244 pendingFrame.samplingMatrix, pendingFrame.rotationDegree); | |
245 if (pendingFrame.yuvFrame) { | 244 if (pendingFrame.yuvFrame) { |
246 rendererType = RendererType.RENDERER_YUV; | 245 rendererType = RendererType.RENDERER_YUV; |
247 drawer.uploadYuvData(yuvTextures, pendingFrame.width, pendingFrame.h
eight, | 246 drawer.uploadYuvData(yuvTextures, pendingFrame.width, pendingFrame.h
eight, |
248 pendingFrame.yuvStrides, pendingFrame.yuvPlanes); | 247 pendingFrame.yuvStrides, pendingFrame.yuvPlanes); |
| 248 // The convention in WebRTC is that the first element in a ByteBuffe
r corresponds to the |
| 249 // top-left corner of the image, but in glTexImage2D() the first ele
ment corresponds to |
| 250 // the bottom-left corner. We correct this discrepancy by setting a
vertical flip as |
| 251 // sampling matrix. |
| 252 final float[] samplingMatrix = RendererCommon.verticalFlipMatrix(); |
| 253 rotatedSamplingMatrix = |
| 254 RendererCommon.rotateTextureMatrix(samplingMatrix, pendingFrame.
rotationDegree); |
249 } else { | 255 } else { |
250 rendererType = RendererType.RENDERER_TEXTURE; | 256 rendererType = RendererType.RENDERER_TEXTURE; |
251 // External texture rendering. Make a deep copy of the external text
ure. | 257 // External texture rendering. Update texture image to latest and ma
ke a deep copy of |
| 258 // the external texture. |
| 259 // TODO(magjed): Move updateTexImage() to the video source instead. |
| 260 final SurfaceTexture surfaceTexture = (SurfaceTexture) pendingFrame.
textureObject; |
| 261 surfaceTexture.updateTexImage(); |
| 262 final float[] samplingMatrix = new float[16]; |
| 263 surfaceTexture.getTransformMatrix(samplingMatrix); |
| 264 rotatedSamplingMatrix = |
| 265 RendererCommon.rotateTextureMatrix(samplingMatrix, pendingFrame.
rotationDegree); |
| 266 |
252 // Reallocate offscreen texture if necessary. | 267 // Reallocate offscreen texture if necessary. |
253 textureCopy.setSize(pendingFrame.rotatedWidth(), pendingFrame.rotate
dHeight()); | 268 textureCopy.setSize(pendingFrame.rotatedWidth(), pendingFrame.rotate
dHeight()); |
254 | 269 |
255 // Bind our offscreen framebuffer. | 270 // Bind our offscreen framebuffer. |
256 GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, textureCopy.getFrame
BufferId()); | 271 GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, textureCopy.getFrame
BufferId()); |
257 GlUtil.checkNoGLES2Error("glBindFramebuffer"); | 272 GlUtil.checkNoGLES2Error("glBindFramebuffer"); |
258 | 273 |
259 // Copy the OES texture content. This will also normalize the sampli
ng matrix. | 274 // Copy the OES texture content. This will also normalize the sampli
ng matrix. |
260 GLES20.glViewport(0, 0, textureCopy.getWidth(), textureCopy.getHeig
ht()); | 275 GLES20.glViewport(0, 0, textureCopy.getWidth(), textureCopy.getHeig
ht()); |
261 drawer.drawOes(pendingFrame.textureId, rotatedSamplingMatrix); | 276 drawer.drawOes(pendingFrame.textureId, rotatedSamplingMatrix); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 GLES20.glViewport(0, 0, screenWidth, screenHeight); | 656 GLES20.glViewport(0, 0, screenWidth, screenHeight); |
642 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); | 657 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); |
643 synchronized (yuvImageRenderers) { | 658 synchronized (yuvImageRenderers) { |
644 for (YuvImageRenderer yuvImageRenderer : yuvImageRenderers) { | 659 for (YuvImageRenderer yuvImageRenderer : yuvImageRenderers) { |
645 yuvImageRenderer.draw(drawer); | 660 yuvImageRenderer.draw(drawer); |
646 } | 661 } |
647 } | 662 } |
648 } | 663 } |
649 | 664 |
650 } | 665 } |
OLD | NEW |