Android GlUtil: Add helper functions generateTexture/deleteTexture
The purpose with this CL is to remove some code bloat. A subtle change is that GL_TEXTURE_MIN_FILTER in MediaCodecVideoDecoder is changed from GL_NEAREST to GL_LINEAR. This may lead to slightly worse performance when the decoded video is rendered minified, but with better visual quality. After reading https://crbug.com/351458 and the fix https://codereview.chromium.org/713603002 I think this is the right choice. BUG=webrtc:4742 R=hbos@webrtc.org, tommi@webrtc.org Review URL: https://codereview.webrtc.org/1303373005 . Cr-Commit-Position: refs/heads/master@{#9845}
This commit is contained in:
@ -70,20 +70,9 @@ public class GlRectDrawerTest extends ActivityTestCase {
|
||||
|
||||
// Generate 3 texture ids for Y/U/V.
|
||||
final int yuvTextures[] = new int[3];
|
||||
GLES20.glGenTextures(3, yuvTextures, 0);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yuvTextures[i]);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
yuvTextures[i] = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D);
|
||||
}
|
||||
GlUtil.checkNoGLES2Error("YUV glGenTextures");
|
||||
|
||||
// Upload the YUV byte buffer data as textures.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
|
||||
@ -58,4 +58,20 @@ public class GlUtil {
|
||||
fb.position(0);
|
||||
return fb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate texture with standard parameters.
|
||||
*/
|
||||
public static int generateTexture(int target) {
|
||||
final int textureArray[] = new int[1];
|
||||
GLES20.glGenTextures(1, textureArray, 0);
|
||||
final int textureId = textureArray[0];
|
||||
GLES20.glBindTexture(target, textureId);
|
||||
GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
checkNoGLES2Error("generateTexture");
|
||||
return textureId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
private int id;
|
||||
private Camera.CameraInfo info;
|
||||
private SurfaceTexture cameraSurfaceTexture;
|
||||
private int[] cameraGlTextures = null;
|
||||
private int cameraGlTexture = 0;
|
||||
private final FramePool videoBuffers = new FramePool();
|
||||
// Remember the requested format in case we want to switch cameras.
|
||||
private int requestedWidth;
|
||||
@ -323,23 +323,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
// it over to Camera, but never listen for frame-ready callbacks,
|
||||
// and never call updateTexImage on it.
|
||||
try {
|
||||
cameraSurfaceTexture = null;
|
||||
|
||||
cameraGlTextures = new int[1];
|
||||
// Generate one texture pointer and bind it as an external texture.
|
||||
GLES20.glGenTextures(1, cameraGlTextures, 0);
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
cameraGlTextures[0]);
|
||||
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
|
||||
cameraSurfaceTexture = new SurfaceTexture(cameraGlTextures[0]);
|
||||
cameraGlTexture = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
||||
cameraSurfaceTexture = new SurfaceTexture(cameraGlTexture);
|
||||
cameraSurfaceTexture.setOnFrameAvailableListener(null);
|
||||
|
||||
camera.setPreviewTexture(cameraSurfaceTexture);
|
||||
@ -473,11 +458,10 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
|
||||
camera.setPreviewTexture(null);
|
||||
cameraSurfaceTexture = null;
|
||||
if (cameraGlTextures != null) {
|
||||
GLES20.glDeleteTextures(1, cameraGlTextures, 0);
|
||||
cameraGlTextures = null;
|
||||
if (cameraGlTexture != 0) {
|
||||
GLES20.glDeleteTextures(1, new int[] {cameraGlTexture}, 0);
|
||||
cameraGlTexture = 0;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Release camera.");
|
||||
camera.release();
|
||||
camera = null;
|
||||
|
||||
@ -98,8 +98,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
||||
// |surface| is synchronized on |this|.
|
||||
private GLSurfaceView surface;
|
||||
private int id;
|
||||
private int[] yuvTextures = { -1, -1, -1 };
|
||||
private int oesTexture = -1;
|
||||
// TODO(magjed): Delete |yuvTextures| in release(). Must be synchronized with draw().
|
||||
private int[] yuvTextures = { 0, 0, 0 };
|
||||
private int oesTexture = 0;
|
||||
|
||||
// Render frame queue - accessed by two threads. renderFrame() call does
|
||||
// an offer (writing I420Frame to render) and early-returns (recording
|
||||
@ -182,20 +183,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
|
||||
Thread.currentThread().getId());
|
||||
|
||||
// Generate 3 texture ids for Y/U/V and place them into |yuvTextures|.
|
||||
GLES20.glGenTextures(3, yuvTextures, 0);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yuvTextures[i]);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
yuvTextures[i] = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D);
|
||||
}
|
||||
GlUtil.checkNoGLES2Error("y/u/v glGenTextures");
|
||||
}
|
||||
|
||||
private void checkAdjustTextureCoords() {
|
||||
|
||||
@ -225,22 +225,7 @@ public class MediaCodecVideoDecoder {
|
||||
eglBase.makeCurrent();
|
||||
|
||||
// Create output surface
|
||||
int[] textures = new int[1];
|
||||
GLES20.glGenTextures(1, textures, 0);
|
||||
GlUtil.checkNoGLES2Error("glGenTextures");
|
||||
textureID = textures[0];
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureID);
|
||||
GlUtil.checkNoGLES2Error("glBindTexture mTextureID");
|
||||
|
||||
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
|
||||
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GlUtil.checkNoGLES2Error("glTexParameter");
|
||||
textureID = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
||||
Log.d(TAG, "Video decoder TextureID = " + textureID);
|
||||
surfaceTexture = new SurfaceTexture(textureID);
|
||||
surface = new Surface(surfaceTexture);
|
||||
@ -284,12 +269,10 @@ public class MediaCodecVideoDecoder {
|
||||
mediaCodecThread = null;
|
||||
if (useSurface) {
|
||||
surface.release();
|
||||
if (textureID >= 0) {
|
||||
int[] textures = new int[1];
|
||||
textures[0] = textureID;
|
||||
if (textureID != 0) {
|
||||
Log.d(TAG, "Delete video decoder TextureID " + textureID);
|
||||
GLES20.glDeleteTextures(1, textures, 0);
|
||||
GlUtil.checkNoGLES2Error("glDeleteTextures");
|
||||
GLES20.glDeleteTextures(1, new int[] {textureID}, 0);
|
||||
textureID = 0;
|
||||
}
|
||||
eglBase.release();
|
||||
eglBase = null;
|
||||
|
||||
Reference in New Issue
Block a user