summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-04-03 18:49:24 +0200
committerSven Gothel <[email protected]>2012-04-03 18:49:24 +0200
commitc594cf1dc9f37dd1a6d861a1aa5426abbd082d60 (patch)
treef72ea63ca9040b17b6203b63e9c7c3678a1881eb
parent48581e36773e58e20a3e780caf5b1c29b4805285 (diff)
GLMediaPlayer: API and implementation update. First working version on Android API 14
- Introduce states - Customize / Access texture target,count,features. - Expose TextureFrame. - Use 'long' for all time values in msec. - Mark information optional in API doc (fps, bps, ..)
-rw-r--r--src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java112
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java186
-rw-r--r--src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java152
-rw-r--r--src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java50
-rw-r--r--src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c (renamed from src/jogl/native/openmax/jogamp.opengl.omx.OMXGLMediaPlayer.c)8
-rw-r--r--src/jogl/native/openmax/omx_tool.c14
-rw-r--r--src/jogl/native/openmax/omx_tool.h4
7 files changed, 355 insertions, 171 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
index 71e0e16d9..0d07f69ac 100644
--- a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
@@ -5,6 +5,8 @@ import java.net.URL;
import javax.media.opengl.GL;
+import jogamp.opengl.Debug;
+
import com.jogamp.opengl.util.texture.Texture;
/**
@@ -17,63 +19,149 @@ import com.jogamp.opengl.util.texture.Texture;
* </ul>
*/
public interface GLMediaPlayer {
+ public static final boolean DEBUG = Debug.debug("GLMediaPlayer");
+
+ public enum State {
+ Uninitialized(0), Stopped(1), Playing(2), Paused(3);
+
+ public final int id;
+ State(int id){
+ this.id = id;
+ }
+ }
+
public static class TextureFrame {
public TextureFrame(Texture t) {
texture = t;
+ // stMatrix = new float[4*4];
+ // ProjectFloat.makeIdentityf(stMatrix, 0);
}
public final Texture getTexture() { return texture; }
+ // public final float[] getSTMatrix() { return stMatrix; }
public String toString() {
return "TextureFrame[" + texture + "]";
}
protected final Texture texture;
+ // protected final float[] stMatrix;
}
- /** Sets the stream to be used. Initializes all stream related states and GL resources. */
+ public int getTextureCount();
+
+ public int getTextureTarget();
+
+ /** Sets the texture min-mag filter, defaults to {@link GL#GL_NEAREST}. */
+ public void setTextureMinMagFilter(int[] minMagFilter);
+ public int[] getTextureMinMagFilter();
+
+ /** Sets the texture min-mag filter, defaults to {@link GL#GL_CLAMP_TO_EDGE}. */
+ public void setTextureWrapST(int[] wrapST);
+ 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>
+ */
public void setStream(GL gl, URL url) throws IOException;
- /** Releases the GL and stream resources. */
+ /**
+ * Releases the GL and stream resources.
+ * <p>
+ * <code>ANY</code> -> Uninitialized
+ * </p>
+ */
public void destroy(GL gl);
public void setPlaySpeed(float rate);
public float getPlaySpeed();
- public void start();
-
- public void pause();
+ /**
+ * Stopped/Paused -> Playing
+ */
+ public State start();
- public void stop();
+ /**
+ * Playing -> Paused
+ */
+ public State pause();
/**
+ * Playing/Paused -> Stopped
+ */
+ public State stop();
+
+ /**
+ * @return the current state, either Uninitialized, Stopped, Playing, Paused
+ */
+ public State getState();
+
+ /**
* @return time current position in milliseconds
**/
- public int getCurrentPosition();
+ public long getCurrentPosition();
/**
* @param msec absolute desired time position in milliseconds
* @return time current position in milliseconds, after seeking to the desired position
**/
- public int seek(int msec);
-
- public Texture getLastTextureID();
-
- public Texture getNextTextureID();
+ public long seek(long msec);
+ /**
+ * @return the last updated texture. Not blocking.
+ */
+ public TextureFrame getLastTexture();
+
+ /**
+ * @return the next texture, which should be rendered. May block, depending on implementation.
+ *
+ * @see #addEventListener(GLMediaEventListener)
+ * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, TextureFrame)
+ */
+ public TextureFrame getNextTexture();
+
public boolean isValid();
public URL getURL();
+ /**
+ * <i>Warning:</i> Optional information, may not be supported by implementation.
+ * @return the code of the video stream, if available
+ */
public String getVideoCodec();
+ /**
+ * <i>Warning:</i> Optional information, may not be supported by implementation.
+ * @return the code of the audio stream, if available
+ */
public String getAudioCodec();
+ /**
+ * <i>Warning:</i> Optional information, may not be supported by implementation.
+ * @return the total number of video frames
+ */
public long getTotalFrames();
+ /**
+ * @return total duration of stream in msec.
+ */
+ public long getDuration();
+
+ /**
+ * <i>Warning:</i> Optional information, may not be supported by implementation.
+ * @return the overall bitrate of the stream.
+ */
public long getBitrate();
+ /**
+ * <i>Warning:</i> Optional information, may not be supported by implementation.
+ * @return the framerate of the video
+ */
public int getFramerate();
public int getWidth();
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
index adfe2a048..a2d9b9bf3 100644
--- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -1,11 +1,9 @@
package jogamp.opengl.android.av;
import java.io.IOException;
-import java.net.URL;
import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLES2;
import jogamp.common.os.android.StaticContext;
@@ -17,12 +15,7 @@ import android.media.MediaPlayer;
import android.net.Uri;
import android.view.Surface;
-import com.jogamp.opengl.av.GLMediaEventListener;
-import com.jogamp.opengl.av.GLMediaPlayer;
-import com.jogamp.opengl.av.GLMediaPlayer.TextureFrame;
-import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.texture.Texture;
-import com.jogamp.opengl.util.texture.TextureCoords;
/***
* Android API Level 14: {@link MediaPlayer#setSurface(Surface)}
@@ -31,6 +24,8 @@ import com.jogamp.opengl.util.texture.TextureCoords;
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) {
@@ -59,137 +54,156 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
}
@Override
- public void start() {
- mp.start();
+ protected boolean startImpl() {
+ try {
+ mp.start();
+ return true;
+ } catch (IllegalStateException ise) {
+ if(DEBUG) {
+ ise.printStackTrace();
+ }
+ }
+ return false;
}
@Override
- public void pause() {
- mp.pause();
+ protected boolean pauseImpl() {
+ try {
+ mp.pause();
+ return true;
+ } catch (IllegalStateException ise) {
+ if(DEBUG) {
+ ise.printStackTrace();
+ }
+ }
+ return false;
}
@Override
- public void stop() {
- mp.stop();
+ protected boolean stopImpl() {
+ try {
+ mp.stop();
+ return true;
+ } catch (IllegalStateException ise) {
+ if(DEBUG) {
+ ise.printStackTrace();
+ }
+ }
+ return false;
}
-
+
@Override
- public int seek(int msec) {
- mp.seekTo(msec);
+ public long seek(long msec) {
+ mp.seekTo((int)msec);
return mp.getCurrentPosition();
}
@Override
- public Texture getNextTextureID() {
- // TODO Auto-generated method stub
- return null;
+ public TextureFrame getLastTexture() {
+ return atex;
}
@Override
- public int getCurrentPosition() {
- return mp.getCurrentPosition();
+ 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 true;
+ return null != mp;
}
- AndroidTextureFrame androidTextureFrame = null;
-
@Override
protected void destroyImpl(GL gl) {
- mp.release();
- mp = null;
+ if(null != mp) {
+ mp.release();
+ mp = null;
+ }
}
@Override
- protected void setStreamImpl() throws IOException {
- 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);
+ 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";
}
- mp.prepare();
+ }
+
+ @Override
+ protected void setStreamImplPostGL() throws IOException {
- width = mp.getVideoWidth();
- height = mp.getVideoHeight();
- fps = 0;
- bps = 0;
- totalFrames = mp.getDuration();
- acodec = "unknown";
- vcodec = "unknown";
}
@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 GL gl = ctx.getGL();
-
- if( 0 > tex[idx] ) {
- throw new RuntimeException("TextureName "+toHexString(tex[idx])+" invalid.");
- }
- gl.glBindTexture(GLES2.GL_TEXTURE_EXTERNAL_OES, tex[idx]);
- {
- final int err = gl.glGetError();
- if( GL.GL_NO_ERROR != err ) {
- throw new RuntimeException("Couldn't bind textureName "+toHexString(tex[idx])+" to 2D target, err "+toHexString(err));
- }
- }
- // gl.glTexParameterf(GLES2.GL_TEXTURE_EXTERNAL_OES, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
- // gl.glTexParameterf(GLES2.GL_TEXTURE_EXTERNAL_OES, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
- gl.glTexParameterf(GLES2.GL_TEXTURE_EXTERNAL_OES, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
- gl.glTexParameterf(GLES2.GL_TEXTURE_EXTERNAL_OES, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
- // Clamp to edge is only option.
- gl.glTexParameteri(GLES2.GL_TEXTURE_EXTERNAL_OES, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
- gl.glTexParameteri(GLES2.GL_TEXTURE_EXTERNAL_OES, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ final Texture texture = super.createTexImageImpl(ctx, idx, tex, true);
- SurfaceTexture stex = new SurfaceTexture(tex[idx]);
+ final SurfaceTexture stex = new SurfaceTexture(tex[idx]);
stex.setOnFrameAvailableListener(onFrameAvailableListener);
+ final Surface surf = new Surface(stex);
+ mp.setSurface(surf);
+ surf.release();
- return new AndroidTextureFrame( com.jogamp.opengl.util.texture.TextureIO.newTexture(tex[idx],
- GLES2.GL_TEXTURE_EXTERNAL_OES,
- width, height,
- width, height,
- true), stex);
+ atex = new AndroidTextureFrame( texture, stex );
+ return atex;
}
protected OnFrameAvailableListener onFrameAvailableListener = new OnFrameAvailableListener() {
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
- frameNumber++;
- updateSurface = true;
+ synchronized(updateSurfaceLock) {
+ updateSurface = true;
+ }
+ AndroidGLMediaPlayerAPI14.this.newFrameAvailable(atex);
}
};
@Override
public float getPlaySpeed() {
- // TODO Auto-generated method stub
return 0;
}
-
- private float[] mSTMatrix = new float[16];
-
- @Override
- public Texture getLastTextureID() {
- if(updateSurface) {
- androidTextureFrame.getSurfaceTexture().updateTexImage();
- androidTextureFrame.getSurfaceTexture().getTransformMatrix(mSTMatrix);
- TextureCoords tc = androidTextureFrame.getTexture().getImageTexCoords();
- PMVMatrix pmv;
- }
- return androidTextureFrame.getTexture();
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
index 826bb6953..793ee2ea3 100644
--- a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
@@ -29,29 +29,34 @@ import com.jogamp.opengl.util.texture.Texture;
*/
public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
+ protected State state;
protected int textureCount;
protected int textureTarget;
+ 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 Texture texture = null;
protected float playSpeed = 1.0f;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()} method implementation. */
protected int width = 0;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
protected int height = 0;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
protected int fps = 0;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
protected long bps = 0;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** In frames. Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
protected long totalFrames = 0;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** In ms. Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
+ protected long duration = 0;
+ /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
protected String acodec = null;
- /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ /** Shall be set by the {@link #setStreamImplPreGL()} or {@link #setStreamImplPostGL()}method implementation. */
protected String vcodec = null;
protected long frameNumber = 0;
@@ -63,29 +68,75 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected GLMediaPlayerImpl() {
this.textureCount=3;
this.textureTarget=GL.GL_TEXTURE_2D;
+ this.state = State.Uninitialized;
}
protected final void setTextureCount(int textureCount) {
this.textureCount=textureCount;
}
+ public final int getTextureCount() { return textureCount; }
+
protected final void setTextureTarget(int textureTarget) {
this.textureTarget=textureTarget;
}
+ public final int getTextureTarget() { return textureTarget; }
+
+ public final void setTextureMinMagFilter(int[] minMagFilter) { texMinMagFilter[0] = minMagFilter[0]; texMinMagFilter[1] = minMagFilter[1];}
+ public final int[] getTextureMinMagFilter() { return texMinMagFilter; }
+
+ public final void setTextureWrapST(int[] wrapST) { texWrapST[0] = wrapST[0]; texWrapST[1] = wrapST[1];}
+ public final int[] getTextureWrapST() { return texWrapST; }
+
+ public final State start() {
+ switch(state) {
+ case Stopped:
+ case Paused:
+ if(startImpl()) {
+ state = State.Playing;
+ }
+ }
+ return state;
+ }
+ protected abstract boolean startImpl();
+
+ public final State pause() {
+ if(State.Playing == state && pauseImpl()) {
+ state = State.Paused;
+ }
+ return state;
+ }
+ protected abstract boolean pauseImpl();
+
+ public final State stop() {
+ switch(state) {
+ case Playing:
+ case Paused:
+ if(stopImpl()) {
+ state = State.Stopped;
+ }
+ }
+ return state;
+ }
+ protected abstract boolean stopImpl();
+
+ public final State getState() { return state; }
@Override
public final void setStream(GL gl, URL url) throws IOException {
+ if(State.Uninitialized != state) {
+ destroy(gl);
+ }
this.url = url;
- if (this.url == null) {
- System.out.println("setURL (null)");
- stop();
- return;
+ if (this.url != null) {
+ setStreamImplPreGL();
+ init(gl);
+ setStreamImplPostGL();
+ state = State.Stopped;
}
- setStreamImpl();
- init(gl);
}
/**
- * Implementation shall set the following set of data:
+ * Implementation shall set the following set of data here or at {@link #setStreamImplPostGL()}
* @see #width
* @see #height
* @see #fps
@@ -94,8 +145,20 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* @see #acodec
* @see #vcodec
*/
- protected abstract void setStreamImpl() throws IOException;
+ protected abstract void setStreamImplPreGL() 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) {
final GLContext ctx = gl.getContext();
if(!ctx.isCurrent()) {
@@ -147,28 +210,29 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
}
- // create space for buffer with a texture
- gl.glTexImage2D(
- textureTarget, // target
- 0, // level
- GL.GL_RGBA, // internal format
- width, // width
- height, // height
- 0, // border
- GL.GL_RGBA, // format
- GL.GL_UNSIGNED_BYTE, // type
- null); // pixels -- will be provided later
- {
- final int err = gl.glGetError();
- if( GL.GL_NO_ERROR != err ) {
- throw new RuntimeException("Couldn't create TexImage2D RGBA "+width+"x"+height+", err "+toHexString(err));
+ if(GLES2.GL_TEXTURE_EXTERNAL_OES != textureTarget) {
+ // create space for buffer with a texture
+ gl.glTexImage2D(
+ textureTarget, // target
+ 0, // level
+ GL.GL_RGBA, // internal format
+ width, // width
+ height, // height
+ 0, // border
+ GL.GL_RGBA, // format
+ GL.GL_UNSIGNED_BYTE, // type
+ null); // pixels -- will be provided later
+ {
+ final int err = gl.glGetError();
+ if( GL.GL_NO_ERROR != err ) {
+ throw new RuntimeException("Couldn't create TexImage2D RGBA "+width+"x"+height+", err "+toHexString(err));
+ }
}
}
- gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
- gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
- // Clamp to edge is only option.
- gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
- gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, texMinMagFilter[0]);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, texMinMagFilter[0]);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, texWrapST[0]);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, texWrapST[1]);
return com.jogamp.opengl.util.texture.TextureIO.newTexture(tex[idx],
textureTarget,
@@ -182,7 +246,6 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
protected void removeAllImageTextures(GLContext ctx) {
- texture = null;
for(int i=0; i<textureCount; i++) {
final TextureFrame imgTex = texFrames[i];
destroyTexImage(ctx, imgTex);
@@ -199,6 +262,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
}
protected void newFrameAvailable(TextureFrame frame) {
+ frameNumber++;
synchronized(eventListenersLock) {
for(Iterator<GLMediaEventListener> i = eventListeners.iterator(); i.hasNext(); ) {
i.next().newFrameAvailable(this, frame);
@@ -212,14 +276,10 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
@Override
- public synchronized Texture getLastTextureID() {
- return texture;
- }
-
- @Override
public synchronized void destroy(GL gl) {
destroyImpl(gl);
removeAllImageTextures(gl.getContext());
+ state = State.Uninitialized;
}
protected abstract void destroyImpl(GL gl);
@@ -244,6 +304,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
@Override
+ public synchronized long getDuration() {
+ return duration;
+ }
+
+ @Override
public synchronized long getBitrate() {
return bps;
}
@@ -265,7 +330,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public synchronized String toString() {
- return "GLMediaPlayer [ stream [ video [ "+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp, "+totalFrames+"f ] ] ]";
+ 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]]]";
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
index 8f5f9c3ab..23eadcd27 100644
--- a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
@@ -10,7 +10,7 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import com.jogamp.opengl.av.GLMediaEventListener;
-import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.av.GLMediaPlayer.TextureFrame;
import jogamp.opengl.av.EGLMediaPlayerImpl;
import jogamp.opengl.egl.EGL;
@@ -26,7 +26,10 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
protected int o_fps = 0;
protected long o_bps = 0;
protected long o_totalFrames = 0;
+ protected long o_duration = 0;
+ protected TextureFrame lastTex = null;
+
public OMXGLMediaPlayer() {
super(TextureType.KHRImage, true);
initOMX();
@@ -43,6 +46,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
final EGLTextureFrame eglTex = (EGLTextureFrame) super.createTexImage(ctx, idx, tex);
_setStreamEGLImageTexture2D(moviePtr, idx, tex[idx], eglTex.getImage(), eglTex.getSync());
+ lastTex = eglTex;
return eglTex;
}
@@ -61,7 +65,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- protected void setStreamImpl() throws IOException {
+ protected void setStreamImplPreGL() throws IOException {
if(0==moviePtr) {
throw new GLException("OMX native instance null");
}
@@ -91,9 +95,13 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
System.out.println("setURL: p2 "+this);
}
+ @Override
+ protected void setStreamImplPostGL() throws IOException {
+
+ }
@Override
- public synchronized int getCurrentPosition() {
+ public synchronized long getCurrentPosition() {
if(0==moviePtr) {
throw new GLException("OMX native instance null");
}
@@ -114,36 +122,38 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
playSpeed = rate;
}
- /** @return time position after issuing the command */
@Override
- public synchronized void start() {
+ public synchronized boolean startImpl() {
if(0==moviePtr) {
- throw new GLException("OMX native instance null");
+ return false;
}
_play(moviePtr);
+ return true;
}
/** @return time position after issuing the command */
@Override
- public synchronized void pause() {
+ public synchronized boolean pauseImpl() {
if(0==moviePtr) {
- throw new GLException("OMX native instance null");
+ return false;
}
_pause(moviePtr);
+ return true;
}
/** @return time position after issuing the command */
@Override
- public synchronized void stop() {
+ public synchronized boolean stopImpl() {
if(0==moviePtr) {
- throw new GLException("OMX native instance null");
+ return false;
}
_stop(moviePtr);
+ return true;
}
/** @return time position after issuing the command */
@Override
- public synchronized int seek(int msec) {
+ public synchronized long seek(long msec) {
if(0==moviePtr) {
throw new GLException("OMX native instance null");
}
@@ -151,16 +161,21 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- public synchronized Texture getNextTextureID() {
+ public TextureFrame getLastTexture() {
+ return lastTex;
+ }
+
+ @Override
+ public synchronized TextureFrame getNextTexture() {
if(0==moviePtr) {
throw new GLException("OMX native instance null");
}
- texture=null;
+ lastTex=null;
TextureFrame eglImgTex = texFrameMap.get(new Integer(_getNextTextureID(moviePtr)));
if(null!=eglImgTex) {
- texture = eglImgTex.getTexture();
+ lastTex = eglImgTex;
}
- return texture;
+ return lastTex;
}
protected void attributesUpdated() {
@@ -192,6 +207,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
o_fps = fps;
o_bps = bps;
o_totalFrames = totalFrames;
+ o_duration = duration;
}
private String replaceAll(String orig, String search, String repl) {
@@ -227,12 +243,12 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
native void _activateStream(long moviePtr);
native void _setStreamEGLImageTexture2D(long moviePtr, int i, int tex, long image, long sync);
- native int _seek(long moviePtr, int position);
+ native long _seek(long moviePtr, long position);
native void _setPlaySpeed(long moviePtr, float rate);
native void _play(long moviePtr);
native void _pause(long moviePtr);
native void _stop(long moviePtr);
native int _getNextTextureID(long moviePtr);
- native int _getCurrentPosition(long moviePtr);
+ native long _getCurrentPosition(long moviePtr);
}
diff --git a/src/jogl/native/openmax/jogamp.opengl.omx.OMXGLMediaPlayer.c b/src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c
index 00c0ca562..86307ae59 100644
--- a/src/jogl/native/openmax/jogamp.opengl.omx.OMXGLMediaPlayer.c
+++ b/src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c
@@ -115,7 +115,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1createInstance
pOMXAV->jni_env=(intptr_t)env;
pOMXAV->jni_instance=(intptr_t)instance;
- pOMXAV = OMXToolBasicAV_CreateInstance((intptr_t)env, (intptr_t)instance);
+ pOMXAV = OMXToolBasicAV_CreateInstance((EGLDisplay)(intptr_t)env);
if(NULL!=pOMXAV) {
jclass cls = (*env)->GetObjectClass(env, instance);
pOMXAV->jni_mid_saveAttributes = (intptr_t) (*env)->GetMethodID(env, cls, "saveAttributes", "()V");
@@ -213,8 +213,8 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1stop
OMXToolBasicAV_PlayStop(pOMXAV);
}
-JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1seek
- (JNIEnv *env, jobject instance, jlong ptr, jfloat pos)
+JNIEXPORT jlong JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1seek
+ (JNIEnv *env, jobject instance, jlong ptr, jlong pos)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_PlaySeek(pOMXAV, pos);
@@ -232,7 +232,7 @@ JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1getNextTextureI
return textureID;
}
-JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1getCurrentPosition
+JNIEXPORT jlong JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1getCurrentPosition
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
diff --git a/src/jogl/native/openmax/omx_tool.c b/src/jogl/native/openmax/omx_tool.c
index 1f2ce7da7..784d6facf 100644
--- a/src/jogl/native/openmax/omx_tool.c
+++ b/src/jogl/native/openmax/omx_tool.c
@@ -627,14 +627,14 @@ static int StartClock(OMXToolBasicAV_t * pOMXAV, KDboolean start, KDfloat32 time
return (OMX_ErrorNotReady == eError)?-1:0;
}
-static KDint GetClockPosition(OMXToolBasicAV_t * pOMXAV)
+static KDint64 GetClockPosition(OMXToolBasicAV_t * pOMXAV)
{
OMX_TIME_CONFIG_TIMESTAMPTYPE stamp;
INIT_PARAM(stamp);
stamp.nPortIndex = 0;
OMX_GetConfig(pOMXAV->comp[OMXAV_H_CLOCK], OMX_IndexConfigTimeCurrentMediaTime, &stamp);
- return (int) ( stamp.nTimestamp / 1000 );
+ return (KDint64) ( stamp.nTimestamp / 1000L );
}
static KDfloat32 GetClockScale(OMXToolBasicAV_t * pOMXAV)
@@ -656,13 +656,13 @@ static KDint SetClockScale(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale)
return 0;
}
-static int SetMediaPosition(OMXToolBasicAV_t * pOMXAV, KDfloat32 time) {
+static int SetMediaPosition(OMXToolBasicAV_t * pOMXAV, KDint64 time) {
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
int loop=STATE_TIMEOUT_LOOP;
INIT_PARAM(timestamp);
timestamp.nPortIndex = 0;
- timestamp.nTimestamp = (OMX_TICKS) (time * 1000.0 * 1000.0);
+ timestamp.nTimestamp = (OMX_TICKS) (time * 1000L);
eError = OMX_SetConfig(pOMXAV->comp[OMXAV_H_READER], OMX_IndexConfigTimePosition, &timestamp);
while (loop>0 && OMX_ErrorNotReady == eError)
@@ -1334,7 +1334,7 @@ void OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV)
kdThreadMutexUnlock(pOMXAV->mutex);
}
-void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time)
+void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDint64 time)
{
int res;
@@ -1474,8 +1474,8 @@ GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV) {
return texID;
}
-KDint OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV) {
- KDfloat32 res = -1.0f;
+KDint64 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV) {
+ KDint64 res = 0L;
if(NULL==pOMXAV) {
java_throwNewRuntimeException(0, "OMX instance null\n");
return res;
diff --git a/src/jogl/native/openmax/omx_tool.h b/src/jogl/native/openmax/omx_tool.h
index cb0f125ec..be5b8f175 100644
--- a/src/jogl/native/openmax/omx_tool.h
+++ b/src/jogl/native/openmax/omx_tool.h
@@ -138,10 +138,10 @@ void OMXToolBasicAV_SetPlaySpeed(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale);
void OMXToolBasicAV_PlayStart(OMXToolBasicAV_t * pOMXAV); // #5
void OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV);
void OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV);
-void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time);
+void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDint64 time);
GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV);
-KDint OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV);
+KDint64 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV);
void OMXToolBasicAV_DestroyInstance(OMXToolBasicAV_t * pOMXAV);