Q:

Is there a better way to get the Camera pixels than onPreviewFrame on Android?

onPreviewFrame only gets called when the preview frames from the camera get displayed. I'm processing the image as an open gl texture using the same technique here:
http://nhenze.net/?p=172&cpage=1#comment-8424
But it seems like a waste to render the preview to the screen just so I can draw over it with my textured image. Is there a better way to get the pixels from the camera than during the call to onPreviewFrame? 

A:

yes, you can use a SurfaceTexture. There's some mild trickiness here as it needs to be an external texture not the normal 2D texture.
This means that if you render the texture with ES2 you need some like
#extension GL_OES_EGL_image_external : require
uniform samplerExternalOES s_texture;

in the fragment shader.
Example code:
    int[] textures = new int[1];
    // generate one texture pointer and bind it as an external texture.
    GLES20.glGenTextures(1, textures, 0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
    // No mip-mapping with camera source.
    GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
            GL10.GL_TEXTURE_MIN_FILTER,
                            GL10.GL_LINEAR);        
    GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
            GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    // Clamp to edge is only option.
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
            GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
            GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

    int texture_id = textures[0];
    SurfaceTexture mTexture = new SurfaceTexture(texture_id);
    mTexture.setOnFrameAvailableListener(this);

    Camera cam = Camera.open();
    cam.setPreviewTexture(mTexture);

