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

Unified Diff: talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java

Issue 1357923002: wip Move SurfaceTexture.updateTexImage() from video renderers into MediaCodecVideoDecoder (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Manage lifetime of texture frames Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
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 e15b49fab31f1d9f82cb1cafe7ebd2e3ca425b97..75143578e2587e21dcbfa1b2aaed1cda4b6da06d 100644
--- a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
+++ b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java
@@ -99,9 +99,12 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
// |surface| is synchronized on |this|.
private GLSurfaceView surface;
private int id;
- // TODO(magjed): Delete |yuvTextures| in release(). Must be synchronized with draw().
+ // TODO(magjed): Delete GL resources in release(). Must be synchronized with draw(). We are
+ // currently leaking resources to avoid a rare crash in release() where the EGLContext has
+ // become invalid beforehand.
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 +190,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 +233,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,42 +241,47 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
}
if (isNewFrame) {
- final float[] samplingMatrix;
+ rotatedSamplingMatrix = RendererCommon.rotateTextureMatrix(
+ pendingFrame.samplingMatrix, pendingFrame.rotationDegree);
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;
- final SurfaceTexture surfaceTexture = (SurfaceTexture) pendingFrame.textureObject;
- surfaceTexture.updateTexImage();
- samplingMatrix = new float[16];
- surfaceTexture.getTransformMatrix(samplingMatrix);
+ // 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, rotatedSamplingMatrix);
+ rotatedSamplingMatrix = RendererCommon.identityMatrix();
+
+ // Restore normal framebuffer.
+ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
- rotatedSamplingMatrix = RendererCommon.rotateTextureMatrix(
- samplingMatrix, pendingFrame.rotationDegree);
copyTimeNs += (System.nanoTime() - now);
VideoRenderer.renderFrameDone(pendingFrame);
pendingFrame = null;
}
}
+ // OpenGL defaults to lower left origin - flip vertically.
+ GLES20.glViewport(displayLayout.left, screenHeight - displayLayout.bottom,
+ displayLayout.width(), displayLayout.height());
+
updateLayoutMatrix();
final float[] texMatrix =
RendererCommon.multiplyMatrices(rotatedSamplingMatrix, layoutMatrix);
if (rendererType == RendererType.RENDERER_YUV) {
drawer.drawYuv(yuvTextures, texMatrix);
} else {
- drawer.drawOes(oesTexture, texMatrix);
+ drawer.drawRgb(textureCopy.getTextureId(), texMatrix);
}
if (isNewFrame) {
« no previous file with comments | « talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java ('k') | talk/app/webrtc/java/jni/androidmediacodeccommon.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698