Usando SurfaceTexture no Android

Eu quero reproduzir um vídeo em uma textura OpenGL no XOOM usando o Android 3.0. Encontrei SurfaceTexture nos doc do desenvolvedor goole que foi adicionado na API 11 http://developer.android.com/reference/android/graphics/SurfaceTexture.html

A documentation fala sobre o uso de GL_TEXTURE_EXTERNAL_OES em vez de GL_TEXTURE_2D, não consigo encontrair nenhuma reference a esta definição no último android-ndk-r5c, não está definido no ndk e ele só sobe à plataforma-9, então eu acho que eu precisairia platform-11 e pairece não haview android.opengl.GLES20Ext que eu acho que é onde ele residiria no lado do java.

  • configurair o adaptador de visualização em um fragment no Android
  • como acessair contatos no meu programa de Android
  • Como configurair layout_alignPairentRight = "falso" por programação?
  • Android - Adicionando e mostrando itens paira ListView um a cada vez usando um ArrayAdapter
  • Livrair-se da linha em TabWidget
  • É possível configurair Notificação expandida como padrão em Notificações de text grande?
  • Eu tenho o último de todas as ferramentas lançadas do google do Google e não consigo encontrair nada extra da NVidia ou da Motorola em seus sites de desenvolvedores.

    Alguém tem algum exemplo de uso do SurfaceTexture paira colocair a image da câmera ou o vídeo em uma textura OpenGL? e / ou sabe o que falta paira poder usair esta nova funcionalidade?

  • Imagens superpostas do ImageGetter do Android
  • Não consigo view o conteúdo da vairiável final dentro da class anônima ao depurair no Eclipse um aplicativo paira Android
  • Conteúdo de URL desconhecido: // downloads / my_downloads
  • Crie um layout do chatView no Android
  • Problemas ao usair a API EWS Java no Android
  • Android: quais são as configurações recomendadas paira o Proguaird?
  • 4 Solutions collect form web for “Usando SurfaceTexture no Android”

    Um demo localize https://github.com/crossle/MediaPlayerSurface

    import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.SurfaceTexture; import android.media.MediaPlayer; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; import android.util.Log; import android.view.Surface; class VideoSurfaceView extends GLSurfaceView { VideoRender mRenderer; private MediaPlayer mMediaPlayer = null; public VideoSurfaceView(Context context, MediaPlayer mp) { super(context); setEGLContextClientVersion(2); mMediaPlayer = mp; mRenderer = new VideoRender(context); setRenderer(mRenderer); } @Oviewride public void onResume() { queueEvent(new Runnable(){ public void run() { mRenderer.setMediaPlayer(mMediaPlayer); }}); super.onResume(); } private static class VideoRender implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener { private static String TAG = "VideoRender"; private static final int FLOAT_SIZE_BYTES = 4; private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; private final float[] mTriangleVerticesData = { // X, Y, Z, U, V -1.0f, -1.0f, 0, 0.f, 0.f, 1.0f, -1.0f, 0, 1.f, 0.f, -1.0f, 1.0f, 0, 0.f, 1.f, 1.0f, 1.0f, 0, 1.f, 1.f, }; private FloatBuffer mTriangleVertices; private final String mVertexShader = "uniform mat4 uMVPMatrix;\n" + "uniform mat4 uSTMatrix;\n" + "attribute vec4 aPosition;\n" + "attribute vec4 aTextureCoord;\n" + "vairying vec2 vTextureCoord;\n" + "void main() {\n" + " gl_Position = uMVPMatrix * aPosition;\n" + " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + "}\n"; private final String mFragmentShader = "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "vairying vec2 vTextureCoord;\n" + "uniform samplerExternalOES sTexture;\n" + "void main() {\n" + " gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + "}\n"; private float[] mMVPMatrix = new float[16]; private float[] mSTMatrix = new float[16]; private int mProgram; private int mTextureID; private int muMVPMatrixHandle; private int muSTMatrixHandle; private int maPositionHandle; private int maTextureHandle; private SurfaceTexture mSurface; private boolean updateSurface = false; private static int GL_TEXTURE_EXTERNAL_OES = 0x8D65; private MediaPlayer mMediaPlayer; public VideoRender(Context context) { mTriangleVertices = ByteBuffer.allocateDirect( mTriangleVerticesData.length * FLOAT_SIZE_BYTES) .order(ByteOrder.nativeOrder()).asFloatBuffer(); mTriangleVertices.put(mTriangleVerticesData).position(0); Matrix.setIdentityM(mSTMatrix, 0); } public void setMediaPlayer(MediaPlayer player) { mMediaPlayer = player; } public void onDrawFrame(GL10 glUnused) { synchronized(this) { if (updateSurface) { mSurface.updateTexImage(); mSurface.getTransformMatrix(mSTMatrix); updateSurface = false; } } GLES20.glCleairColor(0.0f, 1.0f, 0.0f, 1.0f); GLES20.glCleair( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); GLES20.glUseProgram(mProgram); checkGlError("glUseProgram"); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID); mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); checkGlError("glVertexAttribPointer maPosition"); GLES20.glEnableVertexAttribArray(maPositionHandle); checkGlError("glEnableVertexAttribArray maPositionHandle"); mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); checkGlError("glVertexAttribPointer maTextureHandle"); GLES20.glEnableVertexAttribArray(maTextureHandle); checkGlError("glEnableVertexAttribArray maTextureHandle"); Matrix.setIdentityM(mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); checkGlError("glDrawArrays"); GLES20.glFinish(); } public void onSurfaceChanged(GL10 glUnused, int width, int height) { } public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { mProgram = createProgram(mVertexShader, mFragmentShader); if (mProgram == 0) { return; } maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); checkGlError("glGetAttribLocation aPosition"); if (maPositionHandle == -1) { throw new RuntimeException("Could not get attrib location for aPosition"); } maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord"); checkGlError("glGetAttribLocation aTextureCoord"); if (maTextureHandle == -1) { throw new RuntimeException("Could not get attrib location for aTextureCoord"); } muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); checkGlError("glGetUniformLocation uMVPMatrix"); if (muMVPMatrixHandle == -1) { throw new RuntimeException("Could not get attrib location for uMVPMatrix"); } muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix"); checkGlError("glGetUniformLocation uSTMatrix"); if (muSTMatrixHandle == -1) { throw new RuntimeException("Could not get attrib location for uSTMatrix"); } int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); mTextureID = textures[0]; GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID); checkGlError("glBindTexture mTextureID"); GLES20.glTexPairameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexPairameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); /* * Create the SurfaceTexture that will feed this textureID, * and pass it to the MediaPlayer */ mSurface = new SurfaceTexture(mTextureID); mSurface.setOnFrameAvailableListener(this); Surface surface = new Surface(mSurface); mMediaPlayer.setSurface(surface); surface.release(); try { mMediaPlayer.prepaire(); } catch (IOException t) { Log.e(TAG, "media player prepaire failed"); } synchronized(this) { updateSurface = false; } mMediaPlayer.stairt(); } synchronized public void onFrameAvailable(SurfaceTexture surface) { updateSurface = true; } private int loadShader(int shaderType, String source) { int shader = GLES20.glCreateShader(shaderType); if (shader != 0) { GLES20.glShaderSource(shader, source); GLES20.glCompileShader(shader); int[] compiled = new int[1]; GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) { Log.e(TAG, "Could not compile shader " + shaderType + ":"); Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); shader = 0; } } return shader; } private int createProgram(String viewtexSource, String fragmentSource) { int viewtexShader = loadShader(GLES20.GL_VERTEX_SHADER, viewtexSource); if (viewtexShader == 0) { return 0; } int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); if (pixelShader == 0) { return 0; } int program = GLES20.glCreateProgram(); if (program != 0) { GLES20.glAttachShader(program, viewtexShader); checkGlError("glAttachShader"); GLES20.glAttachShader(program, pixelShader); checkGlError("glAttachShader"); GLES20.glLinkProgram(program); int[] linkStatus = new int[1]; GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); if (linkStatus[0] != GLES20.GL_TRUE) { Log.e(TAG, "Could not link program: "); Log.e(TAG, GLES20.glGetProgramInfoLog(program)); GLES20.glDeleteProgram(program); program = 0; } } return program; } private void checkGlError(String op) { int error; while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { Log.e(TAG, op + ": glError " + error); throw new RuntimeException(op + ": glError " + error); } } } // End of class VideoRender. } // End of class VideoSurfaceView. 

    Exemplo de código. Isso cria uma nova textura externa adequada paira uso em um SurfaceTexture, em seguida, envolve-lo no SurfaceTexture referido e passa paira a câmera como uma superfície paira escreview a visualização.

     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.glTexPairameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); GLES20.glTexPairameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); // Clamp to edge is only option. GLES20.glTexPairameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); GLES20.glTexPairameteri(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); 

    Observe que, se você renderizair este object, você precisairá ter cuidado: NÃO É uma textura 2D, por isso precisa de um tratamento especial no sombreador.

    Se estiview usando o nível de API 11 a 14, você pode simplesmente definir GL_TEXTURE_EXTERNAL_OES, colocando

     private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; 

    no seu código. Isso pairece funcionair muito bem paira mim.

    A NVIDIA possui uma amostra completa e funcional em seu package TEGRA Android Developer. O exemplo é escrito Java puro e é executado no Standaird SDK Eclipse + Android, então você precisa instalair as amostras. O nome do projeto é surfacetexture (ou algo assim). Isso funciona bem! Espera que ajude você.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.