diff options
Diffstat (limited to 'src/jogl')
4 files changed, 146 insertions, 132 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java index 0d07f69ac..95f7cc8b4 100644 --- a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java +++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.URL; import javax.media.opengl.GL; +import javax.media.opengl.GLException; import jogamp.opengl.Debug; @@ -12,17 +13,19 @@ import com.jogamp.opengl.util.texture.Texture; /** * Lifecycle of an GLMediaPlayer: * <ul> - * <li>{@link #setStream(GL, URL)}</li> - * <li>{@link #start()}</li> - * <li>{@link #stop()}</li> - * <li>{@link #destroy(GL)}</li> + * <li>{@link #initStream(URL)} - UninitializedStream -> UninitializedGL</li> + * <li>{@link #initGL(GL)} - UninitializedGL -> Stopped</li> + * <li>{@link #start()} - Stopped/Paused -> Playing</li> + * <li>{@link #stop()} - Playing/Paused -> Stopped</li> + * <li>{@link #pause()} - Playing -> Paused</li> + * <li>{@link #destroy(GL)} - ANY -> UninitializedStream</li> * </ul> */ public interface GLMediaPlayer { public static final boolean DEBUG = Debug.debug("GLMediaPlayer"); public enum State { - Uninitialized(0), Stopped(1), Playing(2), Paused(3); + UninitializedStream(0), UninitializedGL(1), Stopped(2), Playing(3), Paused(4); public final int id; @@ -61,21 +64,32 @@ public interface GLMediaPlayer { public int[] getTextureWrapST(); /** - * Sets the stream to be used. Initializes all stream related states and GL resources. - * <ul> - * <li>ANY -> Uninitialized - invokes destroy(GL)</li> - * <li>Uninitialized -> Stopped</li> - * </ul> + * Sets the stream to be used. Initializes all stream related states. + * <p> + * UninitializedStream -> UninitializedGL + * </p> + * @throws IOException in case of difficulties to open or process the stream + * @throws IllegalStateException if not invoked in state UninitializedStream */ - public void setStream(GL gl, URL url) throws IOException; + public State initStream(URL url) throws IllegalStateException, IOException; + /** + * Initializes all GL related resources. + * <p> + * UninitializedGL -> Stopped + * </p> + * @throws GLException in case of difficulties to initialize the GL resources + * @throws IllegalStateException if not invoked in state UninitializedGL + */ + public State initGL(GL gl) throws IllegalStateException, GLException; + /** * Releases the GL and stream resources. * <p> * <code>ANY</code> -> Uninitialized * </p> */ - public void destroy(GL gl); + public State destroy(GL gl); public void setPlaySpeed(float rate); @@ -107,6 +121,8 @@ public interface GLMediaPlayer { public long getCurrentPosition(); /** + * Allowed in state Stopped, Playing and Paused, otherwise ignored. + * * @param msec absolute desired time position in milliseconds * @return time current position in milliseconds, after seeking to the desired position **/ @@ -125,8 +141,6 @@ public interface GLMediaPlayer { */ public TextureFrame getNextTexture(); - public boolean isValid(); - public URL getURL(); /** diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java index a2d9b9bf3..037ab779c 100644 --- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java +++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java @@ -54,13 +54,20 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } @Override + public float getPlaySpeed() { + return 0; + } + + @Override protected boolean startImpl() { - try { - mp.start(); - return true; - } catch (IllegalStateException ise) { - if(DEBUG) { - ise.printStackTrace(); + if(null != mp) { + try { + mp.start(); + return true; + } catch (IllegalStateException ise) { + if(DEBUG) { + ise.printStackTrace(); + } } } return false; @@ -68,12 +75,14 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { @Override protected boolean pauseImpl() { - try { - mp.pause(); - return true; - } catch (IllegalStateException ise) { - if(DEBUG) { - ise.printStackTrace(); + if(null != mp) { + try { + mp.pause(); + return true; + } catch (IllegalStateException ise) { + if(DEBUG) { + ise.printStackTrace(); + } } } return false; @@ -81,21 +90,26 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { @Override protected boolean stopImpl() { - try { - mp.stop(); - return true; - } catch (IllegalStateException ise) { - if(DEBUG) { - ise.printStackTrace(); + if(null != mp) { + 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(); + protected long seekImpl(long msec) { + if(null != mp) { + mp.seekTo((int)msec); + return mp.getCurrentPosition(); + } + return 0; } @Override @@ -105,7 +119,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { @Override public TextureFrame getNextTexture() { - if(null != atex) { + if(null != atex && null != mp) { final boolean _updateSurface; synchronized(updateSurfaceLock) { _updateSurface = updateSurface; @@ -127,11 +141,6 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } @Override - public boolean isValid() { - return null != mp; - } - - @Override protected void destroyImpl(GL gl) { if(null != mp) { mp.release(); @@ -140,7 +149,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } @Override - protected void setStreamImplPreGL() throws IOException { + protected void initStreamImplPreGL() throws IOException { if(null!=mp && null!=url) { try { final Uri uri = Uri.parse(url.toExternalForm()); @@ -152,7 +161,11 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } catch (IllegalStateException e) { throw new RuntimeException(e); } - mp.prepare(); + try { + mp.prepare(); + } catch (IOException ioe) { + throw new IOException("MediaPlayer failed to process stream <"+url.toExternalForm()+">: "+ioe.getMessage(), ioe); + } width = mp.getVideoWidth(); height = mp.getVideoHeight(); @@ -166,11 +179,6 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } @Override - protected void setStreamImplPostGL() throws IOException { - - } - - @Override protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) { final AndroidTextureFrame atf = (AndroidTextureFrame) imgTex; atf.getSurfaceTexture().release(); @@ -200,10 +208,5 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } AndroidGLMediaPlayerAPI14.this.newFrameAvailable(atex); } - }; - - @Override - public float getPlaySpeed() { - return 0; - } + }; } diff --git a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java index 793ee2ea3..5ca402196 100644 --- a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java +++ b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java @@ -8,8 +8,8 @@ import java.util.Iterator; import javax.media.opengl.GL; import javax.media.opengl.GLContext; -import javax.media.opengl.GLDrawable; import javax.media.opengl.GLES2; +import javax.media.opengl.GLException; import com.jogamp.opengl.av.GLMediaPlayer; import com.jogamp.opengl.av.GLMediaEventListener; @@ -36,27 +36,25 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { protected int[] texMinMagFilter = { GL.GL_NEAREST, GL.GL_NEAREST }; protected int[] texWrapST = { GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE }; - private int sWidth = 0; - private int sHeight = 0; protected URL url = null; protected float playSpeed = 1.0f; - /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()} method implementation. */ + /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected int width = 0; - /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected int height = 0; - /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected int fps = 0; - /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected long bps = 0; - /** In frames. Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** In frames. Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected long totalFrames = 0; - /** In ms. Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** In ms. Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected long duration = 0; - /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected String acodec = null; - /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */ + /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */ protected String vcodec = null; protected long frameNumber = 0; @@ -68,7 +66,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { protected GLMediaPlayerImpl() { this.textureCount=3; this.textureTarget=GL.GL_TEXTURE_2D; - this.state = State.Uninitialized; + this.state = State.UninitializedStream; } protected final void setTextureCount(int textureCount) { @@ -119,20 +117,34 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } protected abstract boolean stopImpl(); + public final long seek(long msec) { + final long cp; + switch(state) { + case Stopped: + case Playing: + case Paused: + cp = seekImpl(msec); + break; + default: + cp = 0; + } + return cp; + } + protected abstract long seekImpl(long msec); + public final State getState() { return state; } @Override - public final void setStream(GL gl, URL url) throws IOException { - if(State.Uninitialized != state) { - destroy(gl); + public final State initStream(URL url) throws IllegalStateException, IOException { + if(State.UninitializedStream != state) { + throw new IllegalStateException("Instance not in state "+State.UninitializedStream+", but "+state); } this.url = url; if (this.url != null) { - setStreamImplPreGL(); - init(gl); - setStreamImplPostGL(); - state = State.Stopped; + initStreamImplPreGL(); + state = State.UninitializedGL; } + return state; } /** @@ -145,52 +157,44 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { * @see #acodec * @see #vcodec */ - protected abstract void setStreamImplPreGL() throws IOException; + protected abstract void initStreamImplPreGL() throws IOException; - /** - * Implementation shall set the following set of data here or at {@link #setStreamImplPreGL()} - * @see #width - * @see #height - * @see #fps - * @see #bps - * @see #totalFrames - * @see #acodec - * @see #vcodec - */ - protected abstract void setStreamImplPostGL() throws IOException; - - protected final void init(GL gl) { + @Override + public final State initGL(GL gl) throws IllegalStateException, GLException { + if(State.UninitializedGL != state) { + throw new IllegalStateException("Instance not in state "+State.UninitializedGL+", but "+state); + } final GLContext ctx = gl.getContext(); if(!ctx.isCurrent()) { - throw new RuntimeException("Not current: "+ctx); + throw new GLException("Not current: "+ctx); } + + try { + if(null!=texFrames) { + removeAllImageTextures(ctx); + } else { + texFrames = new TextureFrame[textureCount]; + } - final GLDrawable drawable = ctx.getGLDrawable(); - sWidth = drawable.getWidth(); - sHeight = drawable.getHeight(); - System.out.println("surface size: "+sWidth+"x"+sHeight); - System.out.println("Platform Extensions : "+ctx.getPlatformExtensionsString()); - - if(null!=texFrames) { - removeAllImageTextures(ctx); - } else { - texFrames = new TextureFrame[textureCount]; - } - - final int[] tex = new int[textureCount]; - { - gl.glGenTextures(textureCount, tex, 0); - final int err = gl.glGetError(); - if( GL.GL_NO_ERROR != err ) { - throw new RuntimeException("TextureNames creation failed (num: "+textureCount+"): err "+toHexString(err)); + final int[] tex = new int[textureCount]; + { + gl.glGenTextures(textureCount, tex, 0); + final int err = gl.glGetError(); + if( GL.GL_NO_ERROR != err ) { + throw new RuntimeException("TextureNames creation failed (num: "+textureCount+"): err "+toHexString(err)); + } } + + for(int i=0; i<textureCount; i++) { + final TextureFrame tf = createTexImage(ctx, i, tex); + texFrames[i] = tf; + texFrameMap.put(tex[i], tf); + } + state = State.Stopped; + return state; + } catch (Throwable t) { + throw new GLException("Error initializing GL resources", t); } - - for(int i=0; i<textureCount; i++) { - final TextureFrame tf = createTexImage(ctx, i, tex); - texFrames[i] = tf; - texFrameMap.put(tex[i], tf); - } } protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) { @@ -246,11 +250,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } protected void removeAllImageTextures(GLContext ctx) { - for(int i=0; i<textureCount; i++) { - final TextureFrame imgTex = texFrames[i]; - destroyTexImage(ctx, imgTex); - texFrames[i] = null; - } + if(null != texFrames) { + for(int i=0; i<textureCount; i++) { + final TextureFrame imgTex = texFrames[i]; + destroyTexImage(ctx, imgTex); + texFrames[i] = null; + } + } texFrameMap.clear(); } @@ -276,10 +282,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } @Override - public synchronized void destroy(GL gl) { + public synchronized State destroy(GL gl) { destroyImpl(gl); removeAllImageTextures(gl.getContext()); - state = State.Uninitialized; + state = State.UninitializedStream; + return state; } protected abstract void destroyImpl(GL gl); @@ -331,7 +338,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { @Override public synchronized String toString() { final float ct = getCurrentPosition() / 1000.0f, tt = getDuration() / 1000.0f; - return "GLMediaPlayer ["+state+", "+frameNumber+"/"+totalFrames+" frames, "+ct+"/"+tt+"s, stream [video ["+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp]]]"; + return "GLMediaPlayer ["+state+", "+frameNumber+"/"+totalFrames+" frames, "+ct+"/"+tt+"s, stream [video ["+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp], "+url.toExternalForm()+"]]"; } @Override diff --git a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java index 23eadcd27..1005abd80 100644 --- a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java +++ b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java @@ -65,7 +65,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl { } @Override - protected void setStreamImplPreGL() throws IOException { + protected void initStreamImplPreGL() throws IOException { if(0==moviePtr) { throw new GLException("OMX native instance null"); } @@ -96,11 +96,6 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl { } @Override - protected void setStreamImplPostGL() throws IOException { - - } - - @Override public synchronized long getCurrentPosition() { if(0==moviePtr) { throw new GLException("OMX native instance null"); @@ -109,11 +104,6 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl { } @Override - public synchronized boolean isValid() { - return (moviePtr != 0); - } - - @Override public synchronized void setPlaySpeed(float rate) { if(0==moviePtr) { throw new GLException("OMX native instance null"); @@ -153,7 +143,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl { /** @return time position after issuing the command */ @Override - public synchronized long seek(long msec) { + protected long seekImpl(long msec) { if(0==moviePtr) { throw new GLException("OMX native instance null"); } |