package jogamp.opengl.android.av; import java.io.IOException; import javax.media.opengl.GL; import javax.media.opengl.GLContext; import javax.media.opengl.GLES2; import jogamp.common.os.android.StaticContext; import jogamp.opengl.av.GLMediaPlayerImpl; import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture.OnFrameAvailableListener; import android.media.MediaPlayer; import android.net.Uri; import android.view.Surface; import com.jogamp.opengl.util.texture.Texture; /*** * Android API Level 14: {@link MediaPlayer#setSurface(Surface)} * Android API Level 14: {@link Surface#Surface(android.graphics.SurfaceTexture)} */ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { MediaPlayer mp; boolean updateSurface = false; Object updateSurfaceLock = new Object(); AndroidTextureFrame atex = null; public static class AndroidTextureFrame extends TextureFrame { public AndroidTextureFrame(Texture t, SurfaceTexture stex) { super(t); this.stex = stex; } public final SurfaceTexture getSurfaceTexture() { return stex; } public String toString() { return "AndroidTextureFrame[" + texture + ", "+ stex + "]"; } protected SurfaceTexture stex; } public AndroidGLMediaPlayerAPI14() { super(); this.setTextureTarget(GLES2.GL_TEXTURE_EXTERNAL_OES); this.setTextureCount(1); mp = new MediaPlayer(); } @Override public void setPlaySpeed(float rate) { // n/a } @Override protected boolean startImpl() { try { mp.start(); return true; } catch (IllegalStateException ise) { if(DEBUG) { ise.printStackTrace(); } } return false; } @Override protected boolean pauseImpl() { try { mp.pause(); return true; } catch (IllegalStateException ise) { if(DEBUG) { ise.printStackTrace(); } } return false; } @Override protected boolean stopImpl() { try { mp.stop(); return true; } catch (IllegalStateException ise) { if(DEBUG) { ise.printStackTrace(); } } return false; } @Override public long seek(long msec) { mp.seekTo((int)msec); return mp.getCurrentPosition(); } @Override public TextureFrame getLastTexture() { return atex; } @Override public TextureFrame getNextTexture() { if(null != atex) { final boolean _updateSurface; synchronized(updateSurfaceLock) { _updateSurface = updateSurface; updateSurface = false; } if(_updateSurface) { atex.getSurfaceTexture().updateTexImage(); // atex.getSurfaceTexture().getTransformMatrix(atex.getSTMatrix()); } return atex; } else { return null; } } @Override public long getCurrentPosition() { return null != mp ? mp.getCurrentPosition() : 0; } @Override public boolean isValid() { return null != mp; } @Override protected void destroyImpl(GL gl) { if(null != mp) { mp.release(); mp = null; } } @Override protected void setStreamImplPreGL() throws IOException { if(null!=mp && null!=url) { try { final Uri uri = Uri.parse(url.toExternalForm()); mp.setDataSource(StaticContext.getContext(), uri); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (SecurityException e) { throw new RuntimeException(e); } catch (IllegalStateException e) { throw new RuntimeException(e); } mp.prepare(); width = mp.getVideoWidth(); height = mp.getVideoHeight(); fps = 0; bps = 0; totalFrames = 0; duration = mp.getDuration(); acodec = "unknown"; vcodec = "unknown"; } } @Override protected void setStreamImplPostGL() throws IOException { } @Override protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) { final AndroidTextureFrame atf = (AndroidTextureFrame) imgTex; atf.getSurfaceTexture().release(); atex = null; super.destroyTexImage(ctx, imgTex); } @Override protected AndroidTextureFrame createTexImage(GLContext ctx, int idx, int[] tex) { final Texture texture = super.createTexImageImpl(ctx, idx, tex, true); final SurfaceTexture stex = new SurfaceTexture(tex[idx]); stex.setOnFrameAvailableListener(onFrameAvailableListener); final Surface surf = new Surface(stex); mp.setSurface(surf); surf.release(); atex = new AndroidTextureFrame( texture, stex ); return atex; } protected OnFrameAvailableListener onFrameAvailableListener = new OnFrameAvailableListener() { @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { synchronized(updateSurfaceLock) { updateSurface = true; } AndroidGLMediaPlayerAPI14.this.newFrameAvailable(atex); } }; @Override public float getPlaySpeed() { return 0; } }